Merge "Document that the component version can be a string" am: de49fca027 am: f82e894f01 am: 35b6a90035
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2513920
Change-Id: I2c535f073f752bc145d8a8f8770b23a5bfa0962d
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/audio/README.md b/audio/README.md
index 1938ad4..3f40d72 100644
--- a/audio/README.md
+++ b/audio/README.md
@@ -2,10 +2,29 @@
Directory structure of the audio HAL related code.
-Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
-based on an existing one.
+## Directory Structure for AIDL audio HAL
-## Directory Structure
+The AIDL version is located inside `aidl` directory. The tree below explains
+the role of each subdirectory:
+
+* `aidl_api` — snapshots of the API created each Android release. Every
+ release, the current version of the API becomes "frozen" and gets assigned
+ the next version number. If the API needs further modifications, they are
+ made on the "current" version. After making modifications, run
+ `m <package name>-update-api` to update the snapshot of the "current"
+ version.
+* `android/hardware/audio/common` — data structures and interfaces shared
+ between various HALs: BT HAL, core and effects audio HALs.
+* `android/hardware/audio/core` — data structures and interfaces of the
+ core audio HAL.
+* `default` — the default, reference implementation of the audio HAL service.
+* `vts` — VTS tests for the AIDL HAL.
+
+## Directory Structure for HIDL audio HAL
+
+Run `common/all-versions/copyHAL.sh` to create a new version of the HIDL audio
+HAL based on an existing one. Note that this isn't possible since Android T
+release. Android U and above uses AIDL audio HAL.
* `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files
can not be moved into the `core` directory because that would change
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
index ad79a0c..fabb93b 100644
--- a/audio/aidl/default/config/audioPolicy/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -274,8 +274,10 @@
method @NonNull public String getRawName();
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT;
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_FAST;
+ enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HOTWORD_TAP;
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC;
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD;
+ enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_HW_LOOKBACK;
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
enum_constant public static final android.audio.policy.configuration.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
index 301c969..d57790a 100644
--- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -191,6 +191,8 @@
<xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
<xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
<xs:enumeration value="AUDIO_INPUT_FLAG_ULTRASOUND" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HOTWORD_TAP" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_HW_LOOKBACK" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="audioInOutFlags">
diff --git a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
index df35bae..7722ccf 100644
--- a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
+++ b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
@@ -71,6 +71,7 @@
std::shared_ptr<ISoundDoseFactory> soundDoseFactory;
};
+// @VsrTest = VSR-5.5-002.001
TEST_P(SoundDoseFactory, GetSoundDoseForSameModule) {
const std::string module = "primary";
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 0ae8cfc..825b865 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -3570,6 +3570,7 @@
return ndk::ScopedAStatus::ok();
}
+// @VsrTest = VSR-5.5-002.001
TEST_P(AudioCoreSoundDose, SameInstance) {
if (soundDose == nullptr) {
GTEST_SKIP() << "SoundDose is not supported";
@@ -3581,6 +3582,7 @@
<< "getSoundDose must return the same interface instance across invocations";
}
+// @VsrTest = VSR-5.5-002.001
TEST_P(AudioCoreSoundDose, GetSetOutputRs2UpperBound) {
if (soundDose == nullptr) {
GTEST_SKIP() << "SoundDose is not supported";
@@ -3595,6 +3597,7 @@
EXPECT_TRUE(isSupported) << "Getting/Setting RS2 upper bound must be supported";
}
+// @VsrTest = VSR-5.5-002.001
TEST_P(AudioCoreSoundDose, CheckDefaultRs2UpperBound) {
if (soundDose == nullptr) {
GTEST_SKIP() << "SoundDose is not supported";
@@ -3605,6 +3608,7 @@
EXPECT_EQ(rs2Value, ISoundDose::DEFAULT_MAX_RS2);
}
+// @VsrTest = VSR-5.5-002.001
TEST_P(AudioCoreSoundDose, RegisterSoundDoseCallbackTwiceThrowsException) {
if (soundDose == nullptr) {
GTEST_SKIP() << "SoundDose is not supported";
@@ -3615,6 +3619,7 @@
<< "Registering sound dose callback twice should throw EX_ILLEGAL_STATE";
}
+// @VsrTest = VSR-5.5-002.001
TEST_P(AudioCoreSoundDose, RegisterSoundDoseNullCallbackThrowsException) {
if (soundDose == nullptr) {
GTEST_SKIP() << "SoundDose is not supported";
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index f6440f2..c4c18a4 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -715,11 +715,9 @@
}
void releasePatchIfNeeded() {
- if (getDevice()) {
- if (areAudioPatchesSupported() && mHasPatch) {
- EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
- mHasPatch = false;
- }
+ if (getDevice() && areAudioPatchesSupported() && mHasPatch) {
+ EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
+ mHasPatch = false;
}
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 8dc5ffe..ffd575d 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -46,4 +46,6 @@
oneway void onAudioFocusChangeWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
oneway void setAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
+ void setModuleChangeCallback(in android.hardware.automotive.audiocontrol.IModuleChangeCallback callback);
+ void clearModuleChangeCallback();
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
new file mode 100644
index 0000000..2bbb936
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IModuleChangeCallback.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.automotive.audiocontrol;
+@VintfStability
+interface IModuleChangeCallback {
+ oneway void onAudioPortsChanged(in android.media.audio.common.AudioPort[] audioPorts);
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 0ffcd5e..9564efc 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -51,6 +51,7 @@
import android.hardware.automotive.audiocontrol.DuckingInfo;
import android.hardware.automotive.audiocontrol.IAudioGainCallback;
import android.hardware.automotive.audiocontrol.IFocusListener;
+import android.hardware.automotive.audiocontrol.IModuleChangeCallback;
import android.hardware.automotive.audiocontrol.MutingInfo;
import android.hardware.automotive.audiocontrol.Reasons;
@@ -183,4 +184,26 @@
* interface.
*/
oneway void registerGainCallback(in IAudioGainCallback callback);
+
+ /**
+ * Sets callback with HAL for notifying changes to hardware module (that is:
+ * {@link android.hardware.audio.core.IModule}) configurations.
+ *
+ * @param callback The {@link android.hardware.automotive.audiocontrol.IModuleChangeCallback}
+ * interface to use use when new updates are available for
+ * {@link android.hardware.audio.core.IModule} configs
+ * @throws EX_UNSUPPORTED_OPERATION if dynamic audio configs are not supported.
+ * @throws EX_ILLEGAL_STATE if a callback already exists
+ * @throws EX_ILLEGAL_ARGUMENT if the passed callback is (@code null}
+ */
+ void setModuleChangeCallback(in IModuleChangeCallback callback);
+
+ /**
+ * Clears module change callback
+ *
+ * If no callback is registered previously, then this call should be a no-op.
+ *
+ * @throws EX_UNSUPPORTED_OPERATION if dynamic audio configs are not supported.
+ */
+ void clearModuleChangeCallback();
}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
new file mode 100644
index 0000000..4282483
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.aidl
@@ -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.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioPort;
+
+/**
+ * Interface definition for asynchronous changes to audio configs defined
+ * for a hardware {@link android.hardware.audio.core.IModule}.
+ */
+@VintfStability
+oneway interface IModuleChangeCallback {
+ /**
+ * Used to indicate that one or more {@link android.media.audio.common.AudioPort}
+ * configs have changed. Implementations MUST return at least one AudioPort.
+ *
+ * Notes for AudioPort:
+ * 1. For V3, the support will be limited to configurable AudioGain stages - per
+ * car audio framework support.
+ * 2. For automotive 'bus' devices, the expected settings are
+ * AudioDevice {
+ * AudioDeviceDescription {type: IN/OUT_DEVICE, connection: CONNECTION_BUS}
+ * AudioDeviceAddress {id: string}}
+ *
+ * Notes for AudioGain:
+ * 1. Car audio framework only supports AudioGainMode::JOINT. Any other mode
+ * selection will be ignored.
+ * See {@link android.media.audio.common.AudioGainMode}
+ * 2. Implementations MUST ensure that the gain stages are identical for buses
+ * that map to the same volume group. Any inconsistencies will result in
+ * inferior volume-change experience to the users.
+ * 3. Implementations MUST ensure that the new gain stages are subset (do not
+ * exceed) of the gain stage definitions provided to audio policy. If they
+ * exceed, it can result in failure when setting value over the range
+ * allowed by the audio policy.
+ *
+ * Other notes:
+ * 1. In case of AudioControl service restart or resume, the implementations MUST
+ * issue an immediate callback following registration.
+ * 2. In case of client restart, the AudioControl service MUST clear all stale
+ * callbacks.
+ *
+ * @param audioPorts list of {@link android.media.audio.common.AudioPort} that
+ * are updated
+ */
+ void onAudioPortsChanged(in AudioPort[] audioPorts);
+}
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index 6bf4b9d..dde05c3 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -31,7 +31,7 @@
"[email protected]",
"android.hardware.audio.common-V1-ndk",
"android.frameworks.automotive.powerpolicy-V1-ndk",
- "android.hardware.automotive.audiocontrol-V2-ndk",
+ "android.hardware.automotive.audiocontrol-V3-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp
index a121f8b..cf7307d 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.cpp
+++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp
@@ -24,6 +24,7 @@
#include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
#include <android-base/logging.h>
+#include <android-base/parsebool.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
@@ -37,6 +38,8 @@
namespace aidl::android::hardware::automotive::audiocontrol {
using ::android::base::EqualsIgnoreCase;
+using ::android::base::ParseBool;
+using ::android::base::ParseBoolResult;
using ::android::base::ParseInt;
using ::std::shared_ptr;
using ::std::string;
@@ -70,6 +73,95 @@
}
} // namespace
+namespace {
+using ::aidl::android::media::audio::common::AudioChannelLayout;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioDeviceType;
+using ::aidl::android::media::audio::common::AudioFormatDescription;
+using ::aidl::android::media::audio::common::AudioFormatType;
+using ::aidl::android::media::audio::common::AudioGain;
+using ::aidl::android::media::audio::common::AudioGainMode;
+using ::aidl::android::media::audio::common::AudioIoFlags;
+using ::aidl::android::media::audio::common::AudioOutputFlags;
+using ::aidl::android::media::audio::common::AudioPort;
+using ::aidl::android::media::audio::common::AudioPortDeviceExt;
+using ::aidl::android::media::audio::common::AudioPortExt;
+using ::aidl::android::media::audio::common::AudioPortMixExt;
+using ::aidl::android::media::audio::common::AudioProfile;
+using ::aidl::android::media::audio::common::PcmType;
+
+// reuse common code artifacts
+void fillProfile(const std::vector<int32_t>& channelLayouts,
+ const std::vector<int32_t>& sampleRates, AudioProfile* profile) {
+ for (auto layout : channelLayouts) {
+ profile->channelMasks.push_back(
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
+ }
+ profile->sampleRates.insert(profile->sampleRates.end(), sampleRates.begin(), sampleRates.end());
+}
+
+AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
+ const std::vector<int32_t>& sampleRates) {
+ AudioProfile profile;
+ profile.format.type = AudioFormatType::PCM;
+ profile.format.pcm = pcmType;
+ fillProfile(channelLayouts, sampleRates, &profile);
+ return profile;
+}
+
+AudioProfile createProfile(const std::string& encodingType,
+ const std::vector<int32_t>& channelLayouts,
+ const std::vector<int32_t>& sampleRates) {
+ AudioProfile profile;
+ profile.format.encoding = encodingType;
+ fillProfile(channelLayouts, sampleRates, &profile);
+ return profile;
+}
+
+AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags,
+ const std::string& connection = "", const std::string& address = "") {
+ AudioPortDeviceExt deviceExt;
+ deviceExt.device.type.type = devType;
+ if (devType == AudioDeviceType::IN_MICROPHONE && connection.empty()) {
+ deviceExt.device.address = "bottom";
+ } else if (devType == AudioDeviceType::IN_MICROPHONE_BACK && connection.empty()) {
+ deviceExt.device.address = "back";
+ } else {
+ deviceExt.device.address = std::move(address);
+ }
+ deviceExt.device.type.connection = std::move(connection);
+ deviceExt.flags = flags;
+ return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
+}
+
+AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
+ const AudioPortExt& ext) {
+ AudioPort port;
+ port.id = id;
+ port.name = name;
+ port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
+ : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
+ port.ext = ext;
+ return port;
+}
+
+AudioGain createGain(int32_t mode, AudioChannelLayout channelMask, int32_t minValue,
+ int32_t maxValue, int32_t defaultValue, int32_t stepValue,
+ int32_t minRampMs = 100, int32_t maxRampMs = 100, bool useForVolume = true) {
+ AudioGain gain;
+ gain.mode = mode;
+ gain.channelMask = channelMask;
+ gain.minValue = minValue;
+ gain.maxValue = maxValue;
+ gain.defaultValue = defaultValue;
+ gain.stepValue = stepValue;
+ gain.minRampMs = minRampMs;
+ gain.maxRampMs = maxRampMs;
+ gain.useForVolume = useForVolume;
+ return gain;
+}
+} // namespace
+
ndk::ScopedAStatus AudioControl::registerFocusListener(
const shared_ptr<IFocusListener>& in_listener) {
LOG(DEBUG) << "registering focus listener";
@@ -190,6 +282,33 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus AudioControl::setModuleChangeCallback(
+ const std::shared_ptr<IModuleChangeCallback>& in_callback) {
+ LOG(DEBUG) << ": " << __func__;
+
+ if (in_callback.get() == nullptr) {
+ LOG(ERROR) << __func__ << ": Callback is nullptr";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (mModuleChangeCallback != nullptr) {
+ LOG(ERROR) << __func__ << ": Module change callback was already registered";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ std::atomic_store(&mModuleChangeCallback, in_callback);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::clearModuleChangeCallback() {
+ if (mModuleChangeCallback != nullptr) {
+ shared_ptr<IModuleChangeCallback> nullCallback = nullptr;
+ std::atomic_store(&mModuleChangeCallback, nullCallback);
+ LOG(DEBUG) << ":" << __func__ << ": Unregistered successfully";
+ } else {
+ LOG(DEBUG) << ":" << __func__ << ": No callback registered, no-op";
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) {
if (numArgs == 0) {
return dumpsys(fd);
@@ -208,6 +327,8 @@
return cmdAbandonFocusWithMetaData(fd, args, numArgs);
} else if (EqualsIgnoreCase(option, "--audioGainCallback")) {
return cmdOnAudioDeviceGainsChanged(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--audioPortsChangedCallback")) {
+ return cmdOnAudioPortsChanged(fd, args, numArgs);
} else {
dprintf(fd, "Invalid option: %s\n", option.c_str());
return STATUS_BAD_VALUE;
@@ -262,7 +383,21 @@
dprintf(fd,
"Tags are optional. If provided, it must follow the <key>=<value> pattern, where the "
"value is namespaced (for example com.google.strategy=VR).\n");
-
+ dprintf(fd,
+ "--audioPortsChangedCallback <ID_1> <NAME_1> <BUS_ADDRESS_1> <CONNECTION_TYPE_1> "
+ "<AUDIO_GAINS_1> [<ID_N> <NAME_N> <BUS_ADDRESS_N> <CONNECTION_TYPE_N> "
+ "<AUDIO_GAINS_N>]: fires audio ports changed callback. Carries list of modified "
+ "AudioPorts. "
+ "For simplicity, this command accepts limited information for each AudioPort: "
+ "id(int), name(string), port address(string), connection type (string), "
+ "audio gain (csv int)\n");
+ dprintf(fd, "Notes: \n");
+ dprintf(fd,
+ "1. AudioGain csv should match definition at "
+ "android/media/audio/common/AudioPort.aidl\n");
+ dprintf(fd,
+ "2. See android/media/audio/common/AudioDeviceDescription.aidl for valid "
+ "<CONNECTION_TYPE> values.\n");
return STATUS_OK;
}
@@ -514,4 +649,166 @@
toEnumString(reasons).c_str(), toString(agcis).c_str());
return STATUS_OK;
}
+
+binder_status_t AudioControl::parseAudioGains(int fd, const std::string& stringGain,
+ std::vector<AudioGain>& gains) {
+ const int kAudioGainSize = 9;
+ std::stringstream csvGain(stringGain);
+ std::vector<std::string> vecGain;
+ std::string value;
+ while (getline(csvGain, value, ',')) {
+ vecGain.push_back(value);
+ }
+
+ if ((vecGain.size() == 0) || ((vecGain.size() % kAudioGainSize) != 0)) {
+ dprintf(fd, "Erroneous input to generate AudioGain: %s\n", stringGain.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ // iterate over injected AudioGains
+ for (int index = 0; index < vecGain.size(); index += kAudioGainSize) {
+ int32_t mode;
+ if (!safelyParseInt(vecGain[index], &mode)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n", vecGain[index].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ // car audio framework only supports JOINT mode.
+ // skip injected AudioGains that are not compliant with this.
+ if (mode != static_cast<int>(AudioGainMode::JOINT)) {
+ LOG(WARNING) << ":" << __func__ << ": skipping gain since it is not JOINT mode!";
+ continue;
+ }
+
+ int32_t layout;
+ if (!safelyParseInt(vecGain[index + 1], &layout)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 1].c_str());
+ return STATUS_BAD_VALUE;
+ }
+ AudioChannelLayout channelMask =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
+
+ int32_t minValue;
+ if (!safelyParseInt(vecGain[index + 2], &minValue)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 2].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int32_t maxValue;
+ if (!safelyParseInt(vecGain[index + 3], &maxValue)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 3].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int32_t defaultValue;
+ if (!safelyParseInt(vecGain[index + 4], &defaultValue)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 4].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int32_t stepValue;
+ if (!safelyParseInt(vecGain[index + 5], &stepValue)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 5].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int32_t minRampMs;
+ if (!safelyParseInt(vecGain[index + 6], &minRampMs)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 6].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int32_t maxRampMs;
+ if (!safelyParseInt(vecGain[index + 7], &maxRampMs)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ vecGain[index + 7].c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ ParseBoolResult useForVolume = ParseBool(vecGain[index + 8]);
+ if (useForVolume == ParseBoolResult::kError) {
+ dprintf(fd, "Non-boolean index provided with request: %s\n",
+ vecGain[index + 8].c_str());
+ return STATUS_BAD_VALUE;
+ } else if (useForVolume == ParseBoolResult::kFalse) {
+ // at this level we only care about gain stages that are relevant
+ // for volume control. skip the gain stage if its flagged as false.
+ LOG(WARNING) << ":" << __func__
+ << ": skipping gain since it is not for volume control!";
+ continue;
+ }
+
+ AudioGain gain = createGain(mode, channelMask, minValue, maxValue, defaultValue, stepValue,
+ minRampMs, maxRampMs, true /*useForVolume*/);
+ gains.push_back(gain);
+ }
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdOnAudioPortsChanged(int fd, const char** args, uint32_t numArgs) {
+ if (!checkCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+
+ if ((numArgs < 6) || ((numArgs - 1) % 5 != 0)) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide\n"
+ "--audioPortsChangedCallback <ID_1> <NAME_1> <BUS_ADDRESS_1> <CONNECTION_TYPE_1> "
+ "<AUDIO_GAINS_1> [<ID_N> <NAME_N> <BUS_ADDRESS_N> <CONNECTION_TYPE_N> "
+ "<AUDIO_GAINS_N>]: triggers audio ports changed callback. Carries list of "
+ "modified AudioPorts. "
+ "For simplicity, this command accepts limited information for each AudioPort: "
+ "id(int), name(string), port address(string), connection type (string), "
+ "audio gain (csv int)\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ std::vector<AudioPort> ports;
+ for (uint32_t i = 1; i < numArgs; i += 5) {
+ binder_status_t status;
+ int32_t id;
+ if (!safelyParseInt(std::string(args[i]), &id)) {
+ dprintf(fd, "Non-integer index provided with request: %s\n",
+ std::string(args[i]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ std::string name = std::string(args[i + 1]);
+ std::string address = std::string(args[i + 2]);
+ std::string connection = std::string(args[i + 3]);
+
+ std::string stringGains = std::string(args[i + 4]);
+ std::vector<AudioGain> gains;
+ status = parseAudioGains(fd, stringGains, gains);
+ if (status != STATUS_OK) {
+ return status;
+ }
+
+ AudioPort port = createPort(
+ id, name, 0 /*flags*/, false /*isInput*/,
+ createDeviceExt(AudioDeviceType::OUT_DEVICE, 0 /*flags*/, connection, address));
+ port.gains.insert(port.gains.begin(), gains.begin(), gains.end());
+
+ ports.push_back(port);
+ }
+
+ if (mModuleChangeCallback == nullptr) {
+ dprintf(fd,
+ "Unable to trigger audio port callback for ports: %s \n"
+ " - no module change callback registered\n",
+ toString(ports).c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ // TODO (b/269139706) fix atomic read issue
+ mModuleChangeCallback->onAudioPortsChanged(ports);
+ dprintf(fd, "SUCCESS audio port callback for ports: %s \n", toString(ports).c_str());
+ return STATUS_OK;
+}
} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h
index 16b80e8..7eca446 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.h
+++ b/automotive/audiocontrol/aidl/default/AudioControl.h
@@ -21,11 +21,20 @@
#include <aidl/android/hardware/automotive/audiocontrol/BnAudioControl.h>
#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
#include <aidl/android/hardware/automotive/audiocontrol/IAudioGainCallback.h>
+#include <aidl/android/hardware/automotive/audiocontrol/IModuleChangeCallback.h>
#include <aidl/android/hardware/automotive/audiocontrol/MutingInfo.h>
#include <aidl/android/hardware/automotive/audiocontrol/Reasons.h>
#include <aidl/android/hardware/audio/common/PlaybackTrackMetadata.h>
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceType.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+#include <aidl/android/media/audio/common/AudioFormatType.h>
+#include <aidl/android/media/audio/common/AudioGainMode.h>
+#include <aidl/android/media/audio/common/AudioIoFlags.h>
+#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+
namespace aidl::android::hardware::automotive::audiocontrol {
namespace audiohalcommon = ::aidl::android::hardware::audio::common;
@@ -51,6 +60,9 @@
const std::vector<AudioGainConfigInfo>& in_gains) override;
ndk::ScopedAStatus registerGainCallback(
const std::shared_ptr<IAudioGainCallback>& in_callback) override;
+ ndk::ScopedAStatus setModuleChangeCallback(
+ const std::shared_ptr<IModuleChangeCallback>& in_callback) override;
+ ndk::ScopedAStatus clearModuleChangeCallback() override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
@@ -67,15 +79,23 @@
*/
std::shared_ptr<IAudioGainCallback> mAudioGainCallback = nullptr;
+ std::shared_ptr<IModuleChangeCallback> mModuleChangeCallback = nullptr;
+
binder_status_t cmdHelp(int fd) const;
binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs);
binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs);
binder_status_t cmdRequestFocusWithMetaData(int fd, const char** args, uint32_t numArgs);
binder_status_t cmdAbandonFocusWithMetaData(int fd, const char** args, uint32_t numArgs);
binder_status_t cmdOnAudioDeviceGainsChanged(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdOnAudioPortsChanged(int fd, const char** args, uint32_t numArgs);
binder_status_t parseMetaData(int fd, const std::string& metadataLiteral,
audiohalcommon::PlaybackTrackMetadata& trackMetadata);
+ binder_status_t parseAudioGains(
+ int fd, const std::string& stringGain,
+ std::vector<::aidl::android::media::audio::common::AudioGain>& gains);
+ binder_status_t parseSampleRates(int fd, const std::string& sampleRates,
+ std::vector<int32_t>& vecSampleRates);
binder_status_t dumpsys(int fd);
};
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
index e82f6fa..95cd7f0 100644
--- a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
@@ -1,6 +1,7 @@
<manifest version="2.0" type="device">
<hal format="aidl">
<name>android.hardware.automotive.audiocontrol</name>
+ <version>3</version>
<fqname>IAudioControl/default</fqname>
</hal>
</manifest>
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index da92d38..cfc2a3e 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -38,8 +38,8 @@
"libxml2",
],
static_libs: [
+ "android.hardware.automotive.audiocontrol-V3-cpp",
"android.hardware.audio.common-V1-cpp",
- "android.hardware.automotive.audiocontrol-V2-cpp",
"libgmock",
],
test_suites: [
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
index f4f5eef..f4e3b5a 100644
--- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -21,6 +21,7 @@
#include <android/hardware/automotive/audiocontrol/BnAudioGainCallback.h>
#include <android/hardware/automotive/audiocontrol/BnFocusListener.h>
+#include <android/hardware/automotive/audiocontrol/BnModuleChangeCallback.h>
#include <android/hardware/automotive/audiocontrol/IAudioControl.h>
#include <android/log.h>
#include <binder/IServiceManager.h>
@@ -34,10 +35,14 @@
using android::hardware::automotive::audiocontrol::AudioGainConfigInfo;
using android::hardware::automotive::audiocontrol::BnAudioGainCallback;
using android::hardware::automotive::audiocontrol::BnFocusListener;
+using android::hardware::automotive::audiocontrol::BnModuleChangeCallback;
using android::hardware::automotive::audiocontrol::DuckingInfo;
using android::hardware::automotive::audiocontrol::IAudioControl;
+using android::hardware::automotive::audiocontrol::IModuleChangeCallback;
using android::hardware::automotive::audiocontrol::MutingInfo;
using android::hardware::automotive::audiocontrol::Reasons;
+using ::testing::AnyOf;
+using ::testing::Eq;
#include "android_audio_policy_configuration_V7_0.h"
@@ -55,6 +60,8 @@
ASSERT_NE(audioControl, nullptr);
}
+ void TearDown() override { audioControl = nullptr; }
+
sp<IAudioControl> audioControl;
int32_t capabilities;
};
@@ -226,6 +233,47 @@
ASSERT_TRUE(audioControl->registerGainCallback(gainCallback2).isOk());
}
+/*
+ * Test Module change Callback registration.
+ *
+ * Verifies that:
+ * - setModuleChangeCallback succeeds
+ * - setting a double callback fails with exception
+ * - clearModuleChangeCallback succeeds
+ * - setting with nullptr callback fails with exception
+ * - closing handle does not crash
+ */
+struct ModuleChangeCallbackMock : BnModuleChangeCallback {
+ MOCK_METHOD(Status, onAudioPortsChanged,
+ (const std::vector<android::media::audio::common::AudioPort>& audioPorts));
+};
+
+TEST_P(AudioControlAidl, RegisterModuleChangeCallbackTwiceThrowsException) {
+ ALOGI("Register Module change callback test");
+ // make sure no stale callbacks.
+ audioControl->clearModuleChangeCallback();
+
+ sp<ModuleChangeCallbackMock> moduleChangeCallback = new ModuleChangeCallbackMock();
+ auto status = audioControl->setModuleChangeCallback(moduleChangeCallback);
+ EXPECT_THAT(status.exceptionCode(),
+ AnyOf(Eq(Status::EX_NONE), Eq(Status::EX_UNSUPPORTED_OPERATION)));
+ if (!status.isOk()) return;
+
+ sp<ModuleChangeCallbackMock> moduleChangeCallback2 = new ModuleChangeCallbackMock();
+ // no need to check for unsupported feature
+ EXPECT_EQ(Status::EX_ILLEGAL_STATE,
+ audioControl->setModuleChangeCallback(moduleChangeCallback2).exceptionCode());
+ ASSERT_TRUE(audioControl->clearModuleChangeCallback().isOk());
+ ASSERT_TRUE(audioControl->setModuleChangeCallback(moduleChangeCallback2).isOk());
+}
+
+TEST_P(AudioControlAidl, RegisterModuleChangeNullCallbackThrowsException) {
+ ALOGI("Register Module change callback with nullptr test");
+ auto status = audioControl->setModuleChangeCallback(nullptr);
+ EXPECT_THAT(status.exceptionCode(),
+ AnyOf(Eq(Status::EX_ILLEGAL_ARGUMENT), Eq(Status::EX_UNSUPPORTED_OPERATION)));
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl);
INSTANTIATE_TEST_SUITE_P(
Audiocontrol, AudioControlAidl,
diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp
index 083f4f0..2a0545a 100644
--- a/automotive/can/1.0/default/libnetdevice/can.cpp
+++ b/automotive/can/1.0/default/libnetdevice/can.cpp
@@ -80,7 +80,7 @@
{
auto linkinfo = req.addNested(IFLA_LINKINFO);
- req.add(IFLA_INFO_KIND, "can");
+ req.addBuffer(IFLA_INFO_KIND, "can");
{
auto infodata = req.addNested(IFLA_INFO_DATA);
/* For CAN FD, it would require to add IFLA_CAN_DATA_BITTIMING
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
index 8df6434..8471173 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
@@ -47,7 +47,7 @@
return params;
}
-bool send(unsigned long request, struct ifreq& ifr) {
+int trySend(unsigned long request, struct ifreq& ifr) {
const auto sp = getSocketParams(socketDomain);
base::unique_fd sock(socket(sp.domain, sp.type, sp.protocol));
if (!sock.ok()) {
@@ -55,7 +55,12 @@
return false;
}
- if (ioctl(sock.get(), request, &ifr) < 0) {
+ if (ioctl(sock.get(), request, &ifr) < 0) return errno;
+ return 0;
+}
+
+bool send(unsigned long request, struct ifreq& ifr) {
+ if (trySend(request, ifr) != 0) {
PLOG(ERROR) << "ioctl(" << std::hex << request << std::dec << ") failed";
return false;
}
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h
index 74e5877..d8d6fe0 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.h
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h
@@ -28,6 +28,15 @@
extern std::atomic_int socketDomain;
/**
+ * Tries to send ioctl interface request.
+ *
+ * \param request Request type (such as SIOCGIFFLAGS)
+ * \param ifr Request data (both input and output)
+ * \return error code of the call (0 for success)
+ */
+int trySend(unsigned long request, struct ifreq& ifr);
+
+/**
* Sends ioctl interface request.
*
* \param request Request type (such as SIOCGIFFLAGS)
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index 70cb688..657f9b2 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -68,20 +68,32 @@
PRESENT_AND_UP,
/**
+ * Interface is up and with IPv4 address configured.
+ */
+ PRESENT_AND_IPV4,
+
+ /**
* Interface is down or not present (disconnected) at all.
*/
DOWN_OR_GONE,
};
+enum class Quantifier {
+ ALL_OF,
+ ANY_OF,
+};
+
/**
* Listens for interface changes until anticipated condition takes place.
*
* \param ifnames List of interfaces to watch for.
* \param cnd Awaited condition.
- * \param allOf true if all interfaces need to satisfy the condition, false if only one satistying
+ * \param quant Whether all interfaces need to satisfy the condition or just one satistying
* interface should stop the wait.
+ * \return name of one interface that satisfied the condition
*/
-void waitFor(std::set<std::string> ifnames, WaitCondition cnd, bool allOf = true);
+std::optional<std::string> waitFor(std::set<std::string> ifnames, WaitCondition cnd,
+ Quantifier quant = Quantifier::ALL_OF);
/**
* Brings network interface up.
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index 4c5b309..aad07de 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -60,7 +60,7 @@
{
auto linkinfo = req.addNested(IFLA_LINKINFO);
- req.add(IFLA_INFO_KIND, type);
+ req.addBuffer(IFLA_INFO_KIND, type);
}
nl::Socket sock(NETLINK_ROUTE);
@@ -100,23 +100,36 @@
return ifr.ifr_flags & IFF_UP;
}
+static bool hasIpv4(std::string ifname) {
+ auto ifr = ifreqs::fromName(ifname);
+ switch (const auto status = ifreqs::trySend(SIOCGIFADDR, ifr)) {
+ case 0:
+ return true;
+ case EADDRNOTAVAIL:
+ case ENODEV:
+ return false;
+ default:
+ PLOG(WARNING) << "Failed checking IPv4 address";
+ return false;
+ }
+}
+
struct WaitState {
bool present;
bool up;
+ bool hasIpv4Addr;
bool satisfied(WaitCondition cnd) const {
switch (cnd) {
case WaitCondition::PRESENT:
- if (present) return true;
- break;
+ return present;
case WaitCondition::PRESENT_AND_UP:
- if (present && up) return true;
- break;
+ return present && up;
+ case WaitCondition::PRESENT_AND_IPV4:
+ return present && up && hasIpv4Addr;
case WaitCondition::DOWN_OR_GONE:
- if (!present || !up) return true;
- break;
+ return !present || !up;
}
- return false;
}
};
@@ -126,11 +139,22 @@
return "become present";
case WaitCondition::PRESENT_AND_UP:
return "come up";
+ case WaitCondition::PRESENT_AND_IPV4:
+ return "get IPv4 address";
case WaitCondition::DOWN_OR_GONE:
return "go down";
}
}
+static std::string toString(Quantifier quant) {
+ switch (quant) {
+ case Quantifier::ALL_OF:
+ return "all of";
+ case Quantifier::ANY_OF:
+ return "any of";
+ }
+}
+
static std::string toString(const std::set<std::string>& ifnames) {
std::stringstream ss;
std::copy(ifnames.begin(), ifnames.end(), std::ostream_iterator<std::string>(ss, ","));
@@ -139,50 +163,73 @@
return str;
}
-void waitFor(std::set<std::string> ifnames, WaitCondition cnd, bool allOf) {
- nl::Socket sock(NETLINK_ROUTE, 0, RTMGRP_LINK);
+std::optional<std::string> waitFor(std::set<std::string> ifnames, WaitCondition cnd,
+ Quantifier quant) {
+ nl::Socket sock(NETLINK_ROUTE, 0, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
using StatesMap = std::map<std::string, WaitState>;
StatesMap states = {};
for (const auto ifname : ifnames) {
const auto present = exists(ifname);
const auto up = present && isUp(ifname).value_or(false);
- states[ifname] = {present, up};
+ const auto hasIpv4Addr = present && hasIpv4(ifname);
+ states[ifname] = {present, up, hasIpv4Addr};
}
const auto mapConditionChecker = [cnd](const StatesMap::iterator::value_type& it) {
return it.second.satisfied(cnd);
};
- const auto isFullySatisfied = [&states, allOf, mapConditionChecker]() {
- if (allOf) {
- return std::all_of(states.begin(), states.end(), mapConditionChecker);
- } else {
- return std::any_of(states.begin(), states.end(), mapConditionChecker);
+ const auto isFullySatisfied = [&states, quant,
+ mapConditionChecker]() -> std::optional<std::string> {
+ if (quant == Quantifier::ALL_OF) {
+ if (!std::all_of(states.begin(), states.end(), mapConditionChecker)) return {};
+ return states.begin()->first;
+ } else { // Quantifier::ANY_OF
+ const auto it = std::find_if(states.begin(), states.end(), mapConditionChecker);
+ if (it == states.end()) return {};
+ return it->first;
}
};
- if (isFullySatisfied()) return;
+ if (const auto iface = isFullySatisfied()) return iface;
- LOG(DEBUG) << "Waiting for " << (allOf ? "" : "any of ") << toString(ifnames) << " to "
+ LOG(DEBUG) << "Waiting for " << toString(quant) << " " << toString(ifnames) << " to "
<< toString(cnd);
for (const auto rawMsg : sock) {
- const auto msg = nl::Message<ifinfomsg>::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK});
- if (!msg.has_value()) continue;
+ if (const auto msg = nl::Message<ifinfomsg>::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK});
+ msg.has_value()) {
+ // Interface added / removed
+ const auto ifname = msg->attributes.get<std::string>(IFLA_IFNAME);
+ if (ifnames.count(ifname) == 0) continue;
- const auto ifname = msg->attributes.get<std::string>(IFLA_IFNAME);
- if (ifnames.count(ifname) == 0) continue;
+ auto& state = states[ifname];
+ state.present = (msg->header.nlmsg_type != RTM_DELLINK);
+ state.up = state.present && (msg->data.ifi_flags & IFF_UP) != 0;
+ if (!state.present) state.hasIpv4Addr = false;
- const bool present = (msg->header.nlmsg_type != RTM_DELLINK);
- const bool up = present && (msg->data.ifi_flags & IFF_UP) != 0;
- states[ifname] = {present, up};
+ } else if (const auto msg =
+ nl::Message<ifaddrmsg>::parse(rawMsg, {RTM_NEWADDR, RTM_DELADDR});
+ msg.has_value()) {
+ // Address added / removed
+ const auto ifname = msg->attributes.get<std::string>(IFLA_IFNAME);
+ if (ifnames.count(ifname) == 0) continue;
- if (isFullySatisfied()) {
- LOG(DEBUG) << "Finished waiting for " << (allOf ? "" : "some of ") << toString(ifnames)
+ if (msg->header.nlmsg_type == RTM_NEWADDR) {
+ states[ifname].hasIpv4Addr = true;
+ } else {
+ // instead of tracking which one got deleted, let's just ask
+ states[ifname].hasIpv4Addr = hasIpv4(ifname);
+ }
+ }
+
+ if (const auto iface = isFullySatisfied()) {
+ LOG(DEBUG) << "Finished waiting for " << toString(quant) << " " << toString(ifnames)
<< " to " << toString(cnd);
- return;
+ return iface;
}
}
LOG(FATAL) << "Can't read Netlink socket";
+ return {};
}
} // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp
index ee02f7b..35b21b8 100644
--- a/automotive/can/1.0/default/libnetdevice/vlan.cpp
+++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp
@@ -40,7 +40,7 @@
{
auto linkinfo = req.addNested(IFLA_LINKINFO);
- req.add(IFLA_INFO_KIND, "vlan");
+ req.addBuffer(IFLA_INFO_KIND, "vlan");
{
auto linkinfo = req.addNested(IFLA_INFO_DATA);
diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp
index 2ebd1b4..01c1e55 100644
--- a/automotive/can/1.0/default/libnl++/Android.bp
+++ b/automotive/can/1.0/default/libnl++/Android.bp
@@ -37,8 +37,10 @@
"protocols/generic/Unknown.cpp",
"protocols/generic/families/Mac80211hwsim.cpp",
"protocols/generic/families/Nl80211.cpp",
+ "protocols/route/Addr.cpp",
"protocols/route/Link.cpp",
"protocols/route/Route.cpp",
+ "protocols/route/attributes.cpp",
"protocols/route/structs.cpp",
"protocols/MessageDefinition.cpp",
"protocols/NetlinkProtocol.cpp",
diff --git a/automotive/can/1.0/default/libnl++/MessageFactory.cpp b/automotive/can/1.0/default/libnl++/MessageFactory.cpp
index 6f35897..eff068e 100644
--- a/automotive/can/1.0/default/libnl++/MessageFactory.cpp
+++ b/automotive/can/1.0/default/libnl++/MessageFactory.cpp
@@ -27,8 +27,8 @@
nlattr* MessageFactoryBase::add(nlmsghdr* msg, size_t maxLen, nlattrtype_t type, const void* data,
size_t dataLen) {
- const auto totalAttrLen = impl::space<nlattr>(dataLen);
- const auto newLen = impl::align(msg->nlmsg_len) + totalAttrLen;
+ const auto totalAttrLen = impl::length<nlattr>(dataLen);
+ const auto newLen = impl::align(msg->nlmsg_len) + impl::align(totalAttrLen);
if (newLen > maxLen) {
LOG(ERROR) << "Can't add attribute of size " << dataLen //
<< " - exceeded maxLen: " << newLen << " > " << maxLen;
diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp
index cc1d839..221063d 100644
--- a/automotive/can/1.0/default/libnl++/Socket.cpp
+++ b/automotive/can/1.0/default/libnl++/Socket.cpp
@@ -47,6 +47,17 @@
}
}
+void Socket::clearPollErr() {
+ sockaddr_nl sa = {};
+ socklen_t saLen = sizeof(sa);
+ const auto bytesReceived = recvfrom(mFd.get(), mReceiveBuffer.data(), mReceiveBuffer.size(), 0,
+ reinterpret_cast<sockaddr*>(&sa), &saLen);
+ if (errno != EINVAL) {
+ PLOG(WARNING) << "clearPollError() caught unexpected error: ";
+ }
+ CHECK_LE(bytesReceived, 0) << "clearPollError() didn't find an error!";
+}
+
bool Socket::send(const Buffer<nlmsghdr>& msg, const sockaddr_nl& sa) {
if constexpr (kSuperVerbose) {
LOG(VERBOSE) << (mFailed ? "(not) " : "") << "sending to " << sa.nl_pid << ": "
@@ -110,6 +121,13 @@
if constexpr (kSuperVerbose) {
LOG(VERBOSE) << "received from " << sa.nl_pid << ": " << toString(msg, mProtocol);
}
+ long headerByteTotal = 0;
+ for (const auto hdr : msg) {
+ headerByteTotal += hdr->nlmsg_len;
+ }
+ if (bytesReceived != headerByteTotal) {
+ LOG(ERROR) << "received " << bytesReceived << " bytes, header claims " << headerByteTotal;
+ }
return {msg, sa};
}
@@ -159,6 +177,7 @@
}
pollfd Socket::preparePoll(short events) {
+ CHECK(mFd.get() > 0) << "Netlink socket fd is invalid!";
return {mFd.get(), events, 0};
}
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
index c3d72c5..a5a425e 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
@@ -106,18 +106,25 @@
*/
template <class A>
void add(nlattrtype_t type, const A& attr) {
- add(type, &attr, sizeof(attr));
+ addInternal(type, &attr, sizeof(attr));
}
+ // It will always send the last null character, otherwise use addBuffer
+ // variant instead
template <>
void add(nlattrtype_t type, const std::string& s) {
- add(type, s.c_str(), s.size() + 1);
+ addInternal(type, s.c_str(), s.size() + 1);
+ }
+
+ void addBuffer(nlattrtype_t type, const std::string_view& s) {
+ addInternal(type, s.data(), s.size());
}
/** Guard class to frame nested attributes. \see addNested(nlattrtype_t). */
class [[nodiscard]] NestedGuard {
public:
- NestedGuard(MessageFactory & req, nlattrtype_t type) : mReq(req), mAttr(req.add(type)) {}
+ NestedGuard(MessageFactory& req, nlattrtype_t type)
+ : mReq(req), mAttr(req.addInternal(type)) {}
~NestedGuard() { closeNested(&mReq.mMessage.header, mAttr); }
private:
@@ -138,7 +145,7 @@
* MessageFactory<ifinfomsg> req(RTM_NEWLINK, NLM_F_REQUEST);
* {
* auto linkinfo = req.addNested(IFLA_LINKINFO);
- * req.add(IFLA_INFO_KIND, "can");
+ * req.addBuffer(IFLA_INFO_KIND, "can");
* {
* auto infodata = req.addNested(IFLA_INFO_DATA);
* req.add(IFLA_CAN_BITTIMING, bitTimingStruct);
@@ -154,7 +161,7 @@
Message mMessage = {};
bool mIsGood = true;
- nlattr* add(nlattrtype_t type, const void* data = nullptr, size_t len = 0) {
+ nlattr* addInternal(nlattrtype_t type, const void* data = nullptr, size_t len = 0) {
if (!mIsGood) return nullptr;
auto attr = MessageFactoryBase::add(&mMessage.header, sizeof(mMessage), type, data, len);
if (attr == nullptr) mIsGood = false;
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
index 7ec0f7b..996a350 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
@@ -55,6 +55,12 @@
Socket(int protocol, unsigned pid = 0, uint32_t groups = 0);
/**
+ * Attempt to clear POLLERR by recv-ing.
+ * TODO(224850481): determine if this is necessary, or if the socket is locked up anyway.
+ */
+ void clearPollErr();
+
+ /**
* Send Netlink message with incremented sequence number to the Kernel.
*
* \param msg Message to send. Its sequence number will be updated.
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/bits.h b/automotive/can/1.0/default/libnl++/include/libnl++/bits.h
index 4c8f1aa..b6573b3 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/bits.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/bits.h
@@ -36,11 +36,19 @@
}
/**
+ * Equivalent to NLMSG_LENGTH(len).
+ */
+template <typename H>
+constexpr size_t length(size_t len) {
+ return align(sizeof(H)) + len;
+}
+
+/**
* Equivalent to NLMSG_SPACE(len).
*/
template <typename H>
constexpr size_t space(size_t len) {
- return align(align(sizeof(H)) + len);
+ return align(length<H>(len));
}
/**
diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
index aaf24a5..158d2a1 100644
--- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp
@@ -34,7 +34,7 @@
MessageDescriptor::MessageDescriptor(const std::string& name,
const MessageDetailsMap&& messageDetails,
- const AttributeMap&& attrTypes, size_t contentsSize)
+ const AttributeMap& attrTypes, size_t contentsSize)
: mName(name),
mContentsSize(contentsSize),
mMessageDetails(messageDetails),
diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
index 8bed5e7..33ded9a 100644
--- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
+++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h
@@ -163,7 +163,7 @@
protected:
MessageDescriptor(const std::string& name, const MessageDetailsMap&& messageDetails,
- const AttributeMap&& attrTypes, size_t contentsSize);
+ const AttributeMap& attrTypes, size_t contentsSize);
private:
const std::string mName;
@@ -183,7 +183,7 @@
MessageDefinition( //
const std::string& name,
const std::initializer_list<MessageDescriptor::MessageDetailsMap::value_type> msgDet,
- const std::initializer_list<AttributeMap::value_type> attrTypes = {})
+ const AttributeMap& attrTypes = {})
: MessageDescriptor(name, msgDet, attrTypes, sizeof(T)) {}
void dataToStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr) const override {
diff --git a/automotive/can/1.0/default/libnl++/protocols/all.cpp b/automotive/can/1.0/default/libnl++/protocols/all.cpp
index a398dc8..72c60f2 100644
--- a/automotive/can/1.0/default/libnl++/protocols/all.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/all.cpp
@@ -33,12 +33,12 @@
return map;
}
-static auto all = toMap({
- std::make_unique<generic::Generic>(),
- std::make_unique<route::Route>(),
-});
-
std::optional<std::reference_wrapper<NetlinkProtocol>> get(int protocol) {
+ static auto all = toMap({
+ std::make_unique<generic::Generic>(),
+ std::make_unique<route::Route>(),
+ });
+
if (all.count(protocol) == 0) return std::nullopt;
return *all.find(protocol)->second.get();
}
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
index 900560e..3ad101e 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
@@ -30,6 +30,7 @@
const auto familyName = msg.attributes.get<std::string>(CTRL_ATTR_FAMILY_NAME);
const auto familyId = msg.attributes.get<uint16_t>(CTRL_ATTR_FAMILY_ID);
+ // TODO(224845900): NETLINK_GENERIC == 16, and (erroneously?) sets off this warning
if (familyId < GENL_START_ALLOC) {
LOG(WARNING) << "Invalid family ID: " << familyId;
return true;
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
new file mode 100644
index 0000000..024d389
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Addr.h"
+
+#include "../structs.h"
+#include "attributes.h"
+#include "structs.h"
+
+namespace android::nl::protocols::route {
+
+using DataType = AttributeDefinition::DataType;
+
+// clang-format off
+Addr::Addr() : MessageDefinition<ifaddrmsg>("addr", {
+ {RTM_NEWADDR, {"NEWADDR", MessageGenre::New}},
+ {RTM_DELADDR, {"DELADDR", MessageGenre::Delete}},
+ {RTM_GETADDR, {"GETADDR", MessageGenre::Get}},
+}, gAttributes) {}
+
+static const FlagsMap ifaFlagsMap {
+ {IFA_F_SECONDARY, "SECONDARY"},
+ {IFA_F_NODAD, "NODAD"},
+ {IFA_F_OPTIMISTIC, "OPTIMISTIC"},
+ {IFA_F_DADFAILED, "DADFAILED"},
+ {IFA_F_HOMEADDRESS, "HOMEADDRESS"},
+ {IFA_F_DEPRECATED, "DEPRECATED"},
+ {IFA_F_TENTATIVE, "TENTATIVE"},
+ {IFA_F_PERMANENT, "PERMANENT"},
+ {IFA_F_MANAGETEMPADDR, "MANAGETEMPADDR"},
+ {IFA_F_NOPREFIXROUTE, "NOPREFIXROUTE"},
+ {IFA_F_MCAUTOJOIN, "MCAUTOJOIN"},
+ {IFA_F_STABLE_PRIVACY, "STABLE_PRIVACY"},
+};
+// clang-format on
+
+void Addr::toStream(std::stringstream& ss, const ifaddrmsg& data) const {
+ ss << "ifaddrmsg{"
+ << "family=" << familyToString(data.ifa_family)
+ << ", prefixlen=" << unsigned(data.ifa_prefixlen) << ", flags=";
+ flagsToStream(ss, ifaFlagsMap, data.ifa_flags);
+ ss << ", scope=" << unsigned(data.ifa_scope) << ", index=" << data.ifa_index << "}";
+}
+
+} // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Addr.h b/automotive/can/1.0/default/libnl++/protocols/route/Addr.h
new file mode 100644
index 0000000..b6b8bdc
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Addr.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../MessageDefinition.h"
+
+#include <linux/rtnetlink.h>
+
+namespace android::nl::protocols::route {
+
+class Addr : public MessageDefinition<ifaddrmsg> {
+ public:
+ Addr();
+ void toStream(std::stringstream& ss, const ifaddrmsg& data) const override;
+};
+
+} // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
index 9cc05da..3dd0066 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp
@@ -16,10 +16,7 @@
#include "Link.h"
-#include "../structs.h"
-#include "structs.h"
-
-#include <net/if.h>
+#include "attributes.h"
namespace android::nl::protocols::route {
@@ -30,83 +27,8 @@
{RTM_NEWLINK, {"NEWLINK", MessageGenre::New}},
{RTM_DELLINK, {"DELLINK", MessageGenre::Delete}},
{RTM_GETLINK, {"GETLINK", MessageGenre::Get}},
-}, {
- {IFLA_ADDRESS, {"ADDRESS"}},
- {IFLA_BROADCAST, {"BROADCAST"}},
- {IFLA_IFNAME, {"IFNAME", DataType::String}},
- {IFLA_MTU, {"MTU", DataType::Uint}},
- {IFLA_LINK, {"LINK", DataType::Uint}},
- {IFLA_QDISC, {"QDISC", DataType::String}},
- {IFLA_STATS, {"STATS", DataType::Struct, statsToStream<rtnl_link_stats>}},
- {IFLA_COST, {"COST"}},
- {IFLA_PRIORITY, {"PRIORITY"}},
- {IFLA_MASTER, {"MASTER", DataType::Uint}},
- {IFLA_WIRELESS, {"WIRELESS"}},
- {IFLA_PROTINFO, {"PROTINFO"}},
- {IFLA_TXQLEN, {"TXQLEN", DataType::Uint}},
- {IFLA_MAP, {"MAP", DataType::Struct, mapToStream}},
- {IFLA_WEIGHT, {"WEIGHT", DataType::Uint}},
- {IFLA_OPERSTATE, {"OPERSTATE", DataType::Uint}},
- {IFLA_LINKMODE, {"LINKMODE", DataType::Uint}},
- {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, AttributeMap{
- {IFLA_INFO_KIND, {"INFO_KIND", DataType::String}},
- {IFLA_INFO_DATA, {"INFO_DATA", DataType::Nested}},
- {IFLA_INFO_XSTATS, {"INFO_XSTATS"}},
- {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND", DataType::String}},
- {IFLA_INFO_SLAVE_DATA, {"INFO_SLAVE_DATA"}},
- }}},
- {IFLA_NET_NS_PID, {"NET_NS_PID", DataType::Uint}},
- {IFLA_IFALIAS, {"IFALIAS", DataType::String}},
- {IFLA_NUM_VF, {"NUM_VF", DataType::Uint}},
- {IFLA_VFINFO_LIST, {"VFINFO_LIST"}},
- {IFLA_STATS64, {"STATS64", DataType::Struct, statsToStream<rtnl_link_stats64>}},
- {IFLA_VF_PORTS, {"VF_PORTS"}},
- {IFLA_PORT_SELF, {"PORT_SELF"}},
- {IFLA_AF_SPEC, {"AF_SPEC", DataType::Nested, AttributeMap{
- {AF_INET, {"AF_INET", DataType::Nested, AttributeMap{
- {IFLA_INET_CONF, {"INET_CONF", DataType::Struct, arrayToStream<int32_t>}},
- }}},
- {AF_INET6, {"AF_INET6", DataType::Nested, AttributeMap{
- {IFLA_INET6_FLAGS, {"INET6_FLAGS", DataType::Uint}},
- {IFLA_INET6_CONF, {"INET6_CONF", DataType::Struct, arrayToStream<int32_t>}},
- {IFLA_INET6_STATS, {"INET6_STATS", DataType::Struct, arrayToStream<uint64_t>}},
- {IFLA_INET6_MCAST, {"INET6_MCAST"}},
- {IFLA_INET6_CACHEINFO, {"INET6_CACHEINFO", DataType::Struct, ifla_cacheinfoToStream}},
- {IFLA_INET6_ICMP6STATS, {"INET6_ICMP6STATS", DataType::Struct, arrayToStream<uint64_t>}},
- {IFLA_INET6_TOKEN, {"INET6_TOKEN"}},
- {IFLA_INET6_ADDR_GEN_MODE, {"INET6_ADDR_GEN_MODE", DataType::Uint}},
- }}},
- }}},
- {IFLA_GROUP, {"GROUP", DataType::Uint}},
- {IFLA_NET_NS_FD, {"NET_NS_FD", DataType::Uint}},
- {IFLA_EXT_MASK, {"EXT_MASK", DataType::Uint}},
- {IFLA_PROMISCUITY, {"PROMISCUITY", DataType::Uint}},
- {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES", DataType::Uint}},
- {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES", DataType::Uint}},
- {IFLA_CARRIER, {"CARRIER", DataType::Uint}},
- {IFLA_PHYS_PORT_ID, {"PHYS_PORT_ID"}},
- {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES", DataType::Uint}},
- {IFLA_PHYS_SWITCH_ID, {"PHYS_SWITCH_ID"}},
- {IFLA_LINK_NETNSID, {"LINK_NETNSID"}}, // NLA_S32
- {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME", DataType::String}},
- {IFLA_PROTO_DOWN, {"PROTO_DOWN", DataType::Uint}},
- {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS", DataType::Uint}},
- {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE", DataType::Uint}},
- {IFLA_PAD, {"PAD"}},
- {IFLA_XDP, {"XDP"}},
- {IFLA_EVENT, {"EVENT", DataType::Uint}},
- {IFLA_NEW_NETNSID, {"NEW_NETNSID"}}, // NLA_S32
- {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}}, // NLA_S32
- {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT", DataType::Uint}},
- {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT", DataType::Uint}},
- {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}}, // NLA_S32
- {IFLA_MIN_MTU, {"MIN_MTU", DataType::Uint}},
- {IFLA_MAX_MTU, {"MAX_MTU", DataType::Uint}},
- {IFLA_PROP_LIST, {"PROP_LIST"}},
- {IFLA_ALT_IFNAME, {"ALT_IFNAME", DataType::String}},
- {IFLA_PERM_ADDRESS, {"PERM_ADDRESS"}},
-}) {}
-// clang-format off
+}, gAttributes) {}
+// clang-format on
void Link::toStream(std::stringstream& ss, const ifinfomsg& data) const {
ss << "ifinfomsg{"
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp
index c134911..51e5b11 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp
@@ -16,10 +16,16 @@
#include "Route.h"
+#include "Addr.h"
#include "Link.h"
namespace android::nl::protocols::route {
-Route::Route() : NetlinkProtocol(NETLINK_ROUTE, "ROUTE", {std::make_shared<Link>()}) {}
+// clang-format off
+Route::Route() : NetlinkProtocol(NETLINK_ROUTE, "ROUTE", {
+ std::make_shared<Addr>(),
+ std::make_shared<Link>(),
+}) {}
+// clang-format on
} // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp b/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
new file mode 100644
index 0000000..69d9b81
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "attributes.h"
+
+#include "../structs.h"
+#include "structs.h"
+
+#include <linux/rtnetlink.h>
+#include <net/if.h>
+
+namespace android::nl::protocols::route {
+
+using DataType = AttributeDefinition::DataType;
+using Flags = AttributeDefinition::Flags;
+
+// clang-format off
+AttributeMap gAttributes = {
+ {IFLA_ADDRESS, {"ADDRESS"}},
+ {IFLA_BROADCAST, {"BROADCAST"}},
+ {IFLA_IFNAME, {"IFNAME", DataType::StringNul}},
+ {IFLA_MTU, {"MTU", DataType::Uint}},
+ {IFLA_LINK, {"LINK", DataType::Uint}},
+ {IFLA_QDISC, {"QDISC", DataType::Raw, AttributeMap{}, Flags::Verbose}}, // should be DataType::String, but looks like binary blob
+ {IFLA_STATS, {"STATS", DataType::Struct, statsToStream<rtnl_link_stats>}},
+ {IFLA_COST, {"COST", DataType::Uint}},
+ {IFLA_PRIORITY, {"PRIORITY"}},
+ {IFLA_MASTER, {"MASTER", DataType::Uint}},
+ {IFLA_WIRELESS, {"WIRELESS"}},
+ {IFLA_PROTINFO, {"PROTINFO"}},
+ {IFLA_TXQLEN, {"TXQLEN", DataType::Uint}},
+ {IFLA_MAP, {"MAP", DataType::Struct, mapToStream}},
+ {IFLA_WEIGHT, {"WEIGHT", DataType::Uint}},
+ {IFLA_OPERSTATE, {"OPERSTATE", DataType::Uint}},
+ {IFLA_LINKMODE, {"LINKMODE", DataType::Uint}},
+ {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, AttributeMap{
+ {IFLA_INFO_KIND, {"INFO_KIND", DataType::String}},
+ {IFLA_INFO_DATA, {"INFO_DATA", DataType::Nested}},
+ {IFLA_INFO_XSTATS, {"INFO_XSTATS"}},
+ {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND", DataType::String}},
+ {IFLA_INFO_SLAVE_DATA, {"INFO_SLAVE_DATA"}},
+ }}},
+ {IFLA_NET_NS_PID, {"NET_NS_PID", DataType::Uint}},
+ {IFLA_IFALIAS, {"IFALIAS", DataType::String}},
+ {IFLA_NUM_VF, {"NUM_VF", DataType::Uint}},
+ {IFLA_VFINFO_LIST, {"VFINFO_LIST"}},
+ {IFLA_STATS64, {"STATS64", DataType::Struct, statsToStream<rtnl_link_stats64>}},
+ {IFLA_VF_PORTS, {"VF_PORTS"}},
+ {IFLA_PORT_SELF, {"PORT_SELF"}},
+ {IFLA_AF_SPEC, {"AF_SPEC", DataType::Nested, AttributeMap{
+ {AF_INET, {"AF_INET", DataType::Nested, AttributeMap{
+ {IFLA_INET_CONF, {"INET_CONF", DataType::Struct, arrayToStream<int32_t>}},
+ }}},
+ {AF_INET6, {"AF_INET6", DataType::Nested, AttributeMap{
+ {IFLA_INET6_FLAGS, {"INET6_FLAGS", DataType::Uint}},
+ {IFLA_INET6_CONF, {"INET6_CONF", DataType::Struct, arrayToStream<int32_t>}},
+ {IFLA_INET6_STATS, {"INET6_STATS", DataType::Struct, arrayToStream<uint64_t>}},
+ {IFLA_INET6_MCAST, {"INET6_MCAST"}},
+ {IFLA_INET6_CACHEINFO, {"INET6_CACHEINFO", DataType::Struct, ifla_cacheinfoToStream}},
+ {IFLA_INET6_ICMP6STATS, {"INET6_ICMP6STATS", DataType::Struct, arrayToStream<uint64_t>}},
+ {IFLA_INET6_TOKEN, {"INET6_TOKEN"}},
+ {IFLA_INET6_ADDR_GEN_MODE, {"INET6_ADDR_GEN_MODE", DataType::Uint}},
+ }}},
+ }}},
+ {IFLA_GROUP, {"GROUP", DataType::Uint}},
+ {IFLA_NET_NS_FD, {"NET_NS_FD", DataType::Uint}},
+ {IFLA_EXT_MASK, {"EXT_MASK", DataType::Uint}},
+ {IFLA_PROMISCUITY, {"PROMISCUITY", DataType::Uint}},
+ {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES", DataType::Uint}},
+ {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES", DataType::Uint}},
+ {IFLA_CARRIER, {"CARRIER", DataType::Uint}},
+ {IFLA_PHYS_PORT_ID, {"PHYS_PORT_ID"}},
+ {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES", DataType::Uint}},
+ {IFLA_PHYS_SWITCH_ID, {"PHYS_SWITCH_ID"}},
+ {IFLA_LINK_NETNSID, {"LINK_NETNSID"}}, // NLA_S32
+ {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME", DataType::String}},
+ {IFLA_PROTO_DOWN, {"PROTO_DOWN", DataType::Uint}},
+ {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS", DataType::Uint}},
+ {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE", DataType::Uint}},
+ {IFLA_PAD, {"PAD"}},
+ {IFLA_XDP, {"XDP"}},
+ {IFLA_EVENT, {"EVENT", DataType::Uint}},
+ {IFLA_NEW_NETNSID, {"NEW_NETNSID"}}, // NLA_S32
+ {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}}, // NLA_S32
+ {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT", DataType::Uint}},
+ {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT", DataType::Uint}},
+ {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}}, // NLA_S32
+ {IFLA_MIN_MTU, {"MIN_MTU", DataType::Uint}},
+ {IFLA_MAX_MTU, {"MAX_MTU", DataType::Uint}},
+ {IFLA_PROP_LIST, {"PROP_LIST"}},
+ {IFLA_ALT_IFNAME, {"ALT_IFNAME", DataType::String}},
+ {IFLA_PERM_ADDRESS, {"PERM_ADDRESS"}},
+};
+// clang-format on
+
+} // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/attributes.h b/automotive/can/1.0/default/libnl++/protocols/route/attributes.h
new file mode 100644
index 0000000..ace9234
--- /dev/null
+++ b/automotive/can/1.0/default/libnl++/protocols/route/attributes.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../MessageDefinition.h"
+
+namespace android::nl::protocols::route {
+
+extern AttributeMap gAttributes;
+
+} // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp
index b62cec3..269771c 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp
@@ -46,4 +46,58 @@
<< data.retrans_time << '}';
}
+// clang-format off
+std::string familyToString(sa_family_t family) {
+ switch (family) {
+ case AF_UNSPEC: return "UNSPEC";
+ case AF_UNIX: return "UNIX";
+ case AF_INET: return "INET";
+ case AF_AX25: return "AX25";
+ case AF_IPX: return "IPX";
+ case AF_APPLETALK: return "APPLETALK";
+ case AF_NETROM: return "NETROM";
+ case AF_BRIDGE: return "BRIDGE";
+ case AF_ATMPVC: return "ATMPVC";
+ case AF_X25: return "X25";
+ case AF_INET6: return "INET6";
+ case AF_ROSE: return "ROSE";
+ case AF_DECnet: return "DECnet";
+ case AF_NETBEUI: return "NETBEUI";
+ case AF_SECURITY: return "SECURITY";
+ case AF_KEY: return "KEY";
+ case AF_NETLINK: return "NETLINK";
+ case AF_PACKET: return "PACKET";
+ case AF_ASH: return "ASH";
+ case AF_ECONET: return "ECONET";
+ case AF_ATMSVC: return "ATMSVC";
+ case AF_RDS: return "RDS";
+ case AF_SNA: return "SNA";
+ case AF_IRDA: return "IRDA";
+ case AF_PPPOX: return "PPPOX";
+ case AF_WANPIPE: return "WANPIPE";
+ case AF_LLC: return "LLC";
+ case 27 /*AF_IB*/: return "IB";
+ case 28 /*AF_MPLS*/: return "MPLS";
+ case AF_CAN: return "CAN";
+ case AF_TIPC: return "TIPC";
+ case AF_BLUETOOTH: return "BLUETOOTH";
+ case AF_IUCV: return "IUCV";
+ case AF_RXRPC: return "RXRPC";
+ case AF_ISDN: return "ISDN";
+ case AF_PHONET: return "PHONET";
+ case AF_IEEE802154: return "IEEE802154";
+ case AF_CAIF: return "CAIF";
+ case AF_ALG: return "ALG";
+ case AF_NFC: return "NFC";
+ case AF_VSOCK: return "VSOCK";
+ case AF_KCM: return "KCM";
+ case AF_QIPCRTR: return "QIPCRTR";
+ case 43 /*AF_SMC*/: return "SMC";
+ case 44 /*AF_XDP*/: return "XDP";
+ default:
+ return std::to_string(family);
+ }
+}
+// clang-format on
+
} // namespace android::nl::protocols::route
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
index fea2ce1..c969a6c 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
@@ -19,6 +19,7 @@
#include <libnl++/Buffer.h>
#include <linux/rtnetlink.h>
+#include <sys/socket.h>
#include <sstream>
@@ -30,6 +31,8 @@
// ifla_cacheinfo
void ifla_cacheinfoToStream(std::stringstream& ss, const Buffer<nlattr> attr);
+std::string familyToString(sa_family_t family);
+
// rtnl_link_stats or rtnl_link_stats64
template <typename T>
void statsToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/structs.cpp
index 8ff71f0..3f896bf 100644
--- a/automotive/can/1.0/default/libnl++/protocols/structs.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.cpp
@@ -22,24 +22,27 @@
AttributeDefinition::ToStream flagsToStream(FlagsMap flags) {
return [flags](std::stringstream& ss, const Buffer<nlattr> attr) {
- auto val = attr.data<uint64_t>().copyFirst();
+ auto value = attr.data<uint64_t>().copyFirst();
+ flagsToStream(ss, flags, value);
+ };
+}
- bool first = true;
- for (const auto& [flag, name] : flags) {
- if ((val & flag) != flag) continue;
- val &= ~flag;
-
- if (!first) ss << '|';
- first = false;
-
- ss << name;
- }
-
- if (val == 0) return;
+void flagsToStream(std::stringstream& ss, const FlagsMap& flags, uint64_t val) {
+ bool first = true;
+ for (const auto& [flag, name] : flags) {
+ if ((val & flag) != flag) continue;
+ val &= ~flag;
if (!first) ss << '|';
- ss << std::hex << val << std::dec;
- };
+ first = false;
+
+ ss << name;
+ }
+
+ if (val == 0) return;
+
+ if (!first) ss << '|';
+ ss << std::hex << val << std::dec;
}
void hwaddrToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.h b/automotive/can/1.0/default/libnl++/protocols/structs.h
index f3a8c44..9cf6f1a 100644
--- a/automotive/can/1.0/default/libnl++/protocols/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/structs.h
@@ -34,6 +34,7 @@
typedef std::map<uint64_t, std::string> FlagsMap;
AttributeDefinition::ToStream flagsToStream(FlagsMap flags);
+void flagsToStream(std::stringstream& ss, const FlagsMap& flags, uint64_t value);
void hwaddrToStream(std::stringstream& ss, const Buffer<nlattr> attr);
diff --git a/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp b/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp
index a100f06..3fb4259 100644
--- a/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp
+++ b/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp
@@ -70,6 +70,9 @@
static bool configuratorStart(const std::string& filepath) {
base::SetDefaultTag("CanConfigurator");
+ LOG(WARNING) << "The HIDL version of CAN HAL has been deprecated, if this tool fails with "
+ << "SIGABRT, you may need canhalconfigurator-aidl instead.";
+
auto pb_cfg = config::parseConfigFile(filepath);
if (!pb_cfg.has_value()) {
return false;
diff --git a/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp b/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp
index 9192e2f..fabe75f 100644
--- a/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp
+++ b/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp
@@ -34,8 +34,8 @@
auto manager = hidl::manager::V1_2::IServiceManager::getService();
hidl_vec<hidl_string> services;
manager->listManifestByInterface(ICanController::descriptor, hidl_utils::fill(&services));
- CHECK(services.size() > 0) << "No ICanController services registered (missing privileges?)"
- << std::endl;
+ CHECK(services.size() > 0) << "No ICanController services registered (missing privileges?). "
+ << "are you using the AIDL CanController?" << std::endl;
return services;
}
diff --git a/automotive/can/aidl/Android.bp b/automotive/can/aidl/Android.bp
new file mode 100644
index 0000000..67333b9
--- /dev/null
+++ b/automotive/can/aidl/Android.bp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // 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.automotive.can",
+ vendor_available: true,
+ srcs: ["android/hardware/automotive/can/*.aidl"],
+ stability: "vintf",
+ host_supported: true,
+ backend: {
+ java: {
+ enabled: false,
+ },
+ rust: {
+ enabled: true,
+ },
+ },
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/BusConfig.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/BusConfig.aidl
new file mode 100644
index 0000000..0212e00
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/BusConfig.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable BusConfig {
+ String name;
+ android.hardware.automotive.can.BusConfig.InterfaceId interfaceId;
+ int bitrate;
+ union InterfaceId {
+ android.hardware.automotive.can.VirtualInterface virtualif;
+ android.hardware.automotive.can.NativeInterface nativeif;
+ android.hardware.automotive.can.SlcanInterface slcan;
+ android.hardware.automotive.can.IndexedInterface indexed;
+ }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/ICanController.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/ICanController.aidl
new file mode 100644
index 0000000..5d032f2
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/ICanController.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+interface ICanController {
+ android.hardware.automotive.can.InterfaceType[] getSupportedInterfaceTypes();
+ String getInterfaceName(in String busName);
+ String upBus(in android.hardware.automotive.can.BusConfig config);
+ void downBus(in String name);
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/IndexedInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/IndexedInterface.aidl
new file mode 100644
index 0000000..1b00adf
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/IndexedInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable IndexedInterface {
+ byte index;
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/InterfaceType.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/InterfaceType.aidl
new file mode 100644
index 0000000..44865aa
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/InterfaceType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@Backing(type="byte") @VintfStability
+enum InterfaceType {
+ VIRTUAL = 0,
+ NATIVE = 1,
+ SLCAN = 2,
+ INDEXED = 3,
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/NativeInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/NativeInterface.aidl
new file mode 100644
index 0000000..5d6c119
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/NativeInterface.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable NativeInterface {
+ android.hardware.automotive.can.NativeInterface.InterfaceId interfaceId;
+ union InterfaceId {
+ String ifname;
+ String[] serialno;
+ }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/Result.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/Result.aidl
new file mode 100644
index 0000000..010792a
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@Backing(type="int") @VintfStability
+enum Result {
+ OK = 0,
+ UNKNOWN_ERROR = 1,
+ INVALID_STATE = 2,
+ NOT_SUPPORTED = 3,
+ BAD_INTERFACE_ID = 4,
+ BAD_BITRATE = 5,
+ BAD_BUS_NAME = 6,
+ INTERFACE_DOWN = 7,
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/SlcanInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/SlcanInterface.aidl
new file mode 100644
index 0000000..af0c07d
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/SlcanInterface.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable SlcanInterface {
+ android.hardware.automotive.can.SlcanInterface.InterfaceId interfaceId;
+ union InterfaceId {
+ String ttyname;
+ String[] serialno;
+ }
+}
diff --git a/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/VirtualInterface.aidl b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/VirtualInterface.aidl
new file mode 100644
index 0000000..c870612
--- /dev/null
+++ b/automotive/can/aidl/aidl_api/android.hardware.automotive.can/current/android/hardware/automotive/can/VirtualInterface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.can;
+@VintfStability
+parcelable VirtualInterface {
+ String ifname;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/BusConfig.aidl b/automotive/can/aidl/android/hardware/automotive/can/BusConfig.aidl
new file mode 100644
index 0000000..4e1027b
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/BusConfig.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+import android.hardware.automotive.can.IndexedInterface;
+import android.hardware.automotive.can.NativeInterface;
+import android.hardware.automotive.can.SlcanInterface;
+import android.hardware.automotive.can.VirtualInterface;
+
+/**
+ * Configuration of the (physical or virtual) CAN bus.
+ *
+ * ISO TP and CAN FD support is dependent upon the hardware.
+ */
+@VintfStability
+parcelable BusConfig {
+ /**
+ * Name by which a given bus may be referenced.
+ *
+ * It must consist of only alphanumeric characters and underscore
+ * (a-z, A-Z, 0-9, '_'), at least 1 and at most 32 characters long.
+ *
+ * This field is *not* meant to distinguish between hardware interfaces
+ * nor preselect parameters like bitrate.
+ *
+ * This field represents a more human-friendly name for a CAN bus:
+ * e.x. rather than /some/dev/can1234, "name" might be "BodyCAN" or "CCAN"
+ */
+ String name;
+
+ /**
+ * Hardware interface configuration.
+ *
+ * This union's discriminator has an equivalent enum {@see InterfaceType} to
+ * express compatibility via getSupportedInterfaceTypes().
+ */
+ union InterfaceId {
+ /** Virtual SocketCAN interface. */
+ VirtualInterface virtualif;
+
+ /** Native SocketCAN interface. */
+ NativeInterface nativeif;
+
+ /** Serial line CAN interface. */
+ SlcanInterface slcan;
+
+ /**
+ * Proprietary, device-specific interface.
+ *
+ * Non-SocketCAN interfaces should use this variant.
+ */
+ IndexedInterface indexed;
+ }
+
+ InterfaceId interfaceId;
+
+ /**
+ * Bit rate for CAN communication.
+ *
+ * Typical bit rates are: 100000, 125000, 250000, 500000.
+ *
+ * For {@see interfaceId#virtual} interfaces, this value is ignored.
+ */
+ int bitrate;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/ICanController.aidl b/automotive/can/aidl/android/hardware/automotive/can/ICanController.aidl
new file mode 100644
index 0000000..97c2674
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/ICanController.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+import android.hardware.automotive.can.BusConfig;
+import android.hardware.automotive.can.InterfaceType;
+import android.hardware.automotive.can.Result;
+
+/**
+ * Represents a CAN controller that's capable of configuring CAN bus interfaces.
+ *
+ * The goal of this service is to configure and manage CAN interfaces.
+ *
+ * Providing an ICanController interface to configure CAN buses is optional.
+ * A system can elect to configure CAN buses manually if the hardware is
+ * dedicated to a specific application.
+ */
+@VintfStability
+interface ICanController {
+ /**
+ * Fetches the list of interface types supported by this HAL server.
+ *
+ * @return iftypes The list of supported interface types.
+ */
+ InterfaceType[] getSupportedInterfaceTypes();
+
+ /**
+ * Gets the interface name given the name of the bus. This will
+ *
+ * @param busName Name of the CAN bus who's interface name we would like
+ * (e.x. BCAN, CCAN, HS3, BodyCAN, ...)
+ * @return name of the socketcan network interface corresponding to busName
+ * (e.x. can0, vcan5, ...)
+ */
+ String getInterfaceName(in String busName);
+
+ /**
+ * Bring up a CAN bus.
+ *
+ * @param config Configuration for the CAN bus.
+ * @return name of iface if successful
+ */
+ String upBus(in BusConfig config);
+
+ /**
+ * Bring down a CAN bus.
+ *
+ * @param name Name of the bus (@see BusConfig#name} to bring down.
+ */
+ void downBus(in String name);
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/IndexedInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/IndexedInterface.aidl
new file mode 100644
index 0000000..13e223f
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/IndexedInterface.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable IndexedInterface {
+ /** Interface number, 0-based. */
+ byte index;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/InterfaceType.aidl b/automotive/can/aidl/android/hardware/automotive/can/InterfaceType.aidl
new file mode 100644
index 0000000..b13648a
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/InterfaceType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+/**
+ * Type of an interface, an equivalent to BusConfig::InterfaceId
+ * union discriminator. Defines a number of specific standard hardware
+ * families and a generic catch-all type of {@see INDEXED}.
+ */
+@VintfStability
+@Backing(type="byte")
+enum InterfaceType {
+ /** Virtual SocketCAN interface. */
+ VIRTUAL,
+
+ /** Native SocketCAN interface. */
+ NATIVE,
+
+ /** Serial line CAN interface. */
+ SLCAN,
+
+ /** Proprietary, device-specific interface. */
+ INDEXED,
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/NativeInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/NativeInterface.aidl
new file mode 100644
index 0000000..30c24c3
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/NativeInterface.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable NativeInterface {
+ union InterfaceId {
+ /** Interface name, such as can0. */
+ String ifname;
+
+ /**
+ * Alternatively to providing {@see ifname}, one may provide a list of
+ * interface serial number suffixes. If there happens to be a device
+ * (like USB2CAN) with a matching serial number suffix, the HAL service
+ * will locate it.
+ *
+ * Client may utilize this in two ways: by matching against the
+ * entire serial number, or the last few characters (usually
+ * one). The former is better for small-scale test deployments
+ * (with just a handful of vehicles), the latter is good for
+ * larger scale (where a small suffix list may support large
+ * test fleet).
+ */
+ String[] serialno;
+ }
+
+ InterfaceId interfaceId;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/Result.aidl b/automotive/can/aidl/android/hardware/automotive/can/Result.aidl
new file mode 100644
index 0000000..cdd0066
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/Result.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+/**
+ * Possible error codes (or OK) for ICanController.
+ */
+@VintfStability
+@Backing(type="int")
+enum Result {
+ OK,
+
+ /**
+ * General error class, if others are not applicable.
+ */
+ UNKNOWN_ERROR,
+
+ /**
+ * Up request was called out of order (i.e. trying to up the interface
+ * twice).
+ */
+ INVALID_STATE,
+
+ /** Interface type is not supported. */
+ NOT_SUPPORTED,
+
+ /**
+ * Provided interface ID (index, name, device path) doesn't exist or there
+ * is no device with a given serial number.
+ */
+ BAD_INTERFACE_ID,
+
+ /** Provided bit rate is not supported by the hardware. */
+ BAD_BITRATE,
+
+ /**
+ * Provided bus name ({@see BusConfig#name}) has invalid format or doesn't exist.
+ */
+ BAD_BUS_NAME,
+
+ /**
+ * The interface for the bus you are trying to interact with is currently
+ * down. As opposed to INVALID_STATE, this serves to warn the caller
+ * _before_ they attempt an invalid operation.
+ */
+ INTERFACE_DOWN,
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/SlcanInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/SlcanInterface.aidl
new file mode 100644
index 0000000..4ed8583
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/SlcanInterface.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable SlcanInterface {
+ union InterfaceId {
+ /** Path to a device, such as /dev/ttyUSB0. */
+ String ttyname;
+
+ /**
+ * List of interface serial number suffixes.
+ * {@see Socketcan::serialno}
+ */
+ String[] serialno;
+ }
+
+ InterfaceId interfaceId;
+}
diff --git a/automotive/can/aidl/android/hardware/automotive/can/VirtualInterface.aidl b/automotive/can/aidl/android/hardware/automotive/can/VirtualInterface.aidl
new file mode 100644
index 0000000..7e1e5e1
--- /dev/null
+++ b/automotive/can/aidl/android/hardware/automotive/can/VirtualInterface.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can;
+
+@VintfStability
+parcelable VirtualInterface {
+ /**
+ * Interface name, such as vcan0. If the interface doesn't
+ * exist, HAL server must create it.
+ */
+ String ifname;
+}
diff --git a/automotive/can/aidl/default/Android.bp b/automotive/can/aidl/default/Android.bp
new file mode 100644
index 0000000..d44cb91
--- /dev/null
+++ b/automotive/can/aidl/default/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "android.hardware.automotive.can-service",
+ init_rc: ["android.hardware.automotive.can.rc"],
+ defaults: ["android.hardware.automotive.can@defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "CanBus.cpp",
+ "CanBusSlcan.cpp",
+ "CanBusNative.cpp",
+ "CanBusVirtual.cpp",
+ "CanController.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.automotive.can-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.automotive.can@libnetdevice",
+ "android.hardware.automotive@libc++fs",
+ "libnl++",
+ ],
+ vintf_fragments: ["android.hardware.automotive.can.xml"],
+}
diff --git a/automotive/can/aidl/default/CanBus.cpp b/automotive/can/aidl/default/CanBus.cpp
new file mode 100644
index 0000000..d1f9b78
--- /dev/null
+++ b/automotive/can/aidl/default/CanBus.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBus.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/libnetdevice.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+CanBus::CanBus(std::string_view ifname) : mIfname(ifname) {}
+
+CanBus::~CanBus() {
+ std::lock_guard<std::mutex> lck(mIsUpGuard);
+ CHECK(!mIsUp) << "Interface is still up while being destroyed";
+}
+
+Result CanBus::preUp() {
+ return Result::OK;
+}
+
+bool CanBus::postDown() {
+ return true;
+}
+
+std::string CanBus::getIfaceName() {
+ return mIfname;
+}
+
+Result CanBus::up() {
+ std::lock_guard<std::mutex> lck(mIsUpGuard);
+
+ if (mIsUp) {
+ LOG(WARNING) << "Interface is already up";
+ return Result::INVALID_STATE;
+ }
+
+ const auto preResult = preUp();
+ if (preResult != Result::OK) return preResult;
+
+ const auto isUp = ::android::netdevice::isUp(mIfname);
+ if (!isUp.has_value()) {
+ // preUp() should prepare the interface (either create or make sure it's there)
+ LOG(ERROR) << "Interface " << mIfname << " didn't get prepared";
+ return Result::BAD_INTERFACE_ID;
+ }
+
+ if (!*isUp && !::android::netdevice::up(mIfname)) {
+ LOG(ERROR) << "Can't bring " << mIfname << " up";
+ return Result::UNKNOWN_ERROR;
+ }
+ mDownAfterUse = !*isUp;
+
+ mIsUp = true;
+ return Result::OK;
+}
+
+Result CanBus::down() {
+ std::lock_guard<std::mutex> lck(mIsUpGuard);
+
+ if (!mIsUp) {
+ LOG(WARNING) << "Interface is already down";
+ return Result::INVALID_STATE;
+ }
+ mIsUp = false;
+
+ Result success = Result::OK;
+
+ if (mDownAfterUse && !::android::netdevice::down(mIfname)) {
+ LOG(ERROR) << "Can't bring " << mIfname << " down";
+ // don't return yet, let's try to do best-effort cleanup
+ success = Result::UNKNOWN_ERROR;
+ }
+
+ if (!postDown()) success = Result::UNKNOWN_ERROR;
+
+ return success;
+}
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBus.h b/automotive/can/aidl/default/CanBus.h
new file mode 100644
index 0000000..abdbe51
--- /dev/null
+++ b/automotive/can/aidl/default/CanBus.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/automotive/can/Result.h>
+
+#include <android-base/macros.h>
+#include <utils/Mutex.h>
+
+#include <atomic>
+#include <mutex>
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBus {
+ public:
+ /**
+ * Some interface types (such as SLCAN) don't get an interface name until after being
+ * initialized, hence ifname is optional.
+ *
+ * You MUST ensure mIfname is initialized prior to the completion of preUp().
+ */
+ CanBus(std::string_view ifname = std::string_view{""});
+
+ virtual ~CanBus();
+
+ Result up();
+ Result down();
+ std::string getIfaceName();
+
+ protected:
+ /**
+ * Prepare the SocketCAN interface.
+ *
+ * After calling this method, mIfname network interface is available and ready to be brought up.
+ *
+ * \return true upon success and false upon failure
+ */
+ virtual Result preUp();
+
+ /**
+ * Cleanup after bringing the interface down.
+ *
+ * This is a counterpart to preUp().
+ *
+ * \return true upon success and false upon failure
+ */
+ virtual bool postDown();
+
+ /** Network interface name. */
+ std::string mIfname;
+
+ private:
+ /**
+ * Guard for up flag is required to be held for entire time when the interface is being used
+ * because we don't want the interface to be torn down while executing that operation.
+ */
+ std::mutex mIsUpGuard;
+ bool mIsUp GUARDED_BY(mIsUpGuard) = false;
+
+ bool mDownAfterUse;
+};
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusNative.cpp b/automotive/can/aidl/default/CanBusNative.cpp
new file mode 100644
index 0000000..8a7de99
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusNative.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusNative.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/can.h>
+#include <libnetdevice/libnetdevice.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+using namespace ::android;
+
+CanBusNative::CanBusNative(const std::string& ifname, uint32_t bitrate)
+ : CanBus(ifname), mBitrate(bitrate) {}
+
+Result CanBusNative::preUp() {
+ if (!netdevice::exists(mIfname)) {
+ LOG(ERROR) << "Interface " << mIfname << " doesn't exist";
+ return Result::BAD_INTERFACE_ID;
+ }
+
+ if (mBitrate == 0) {
+ // interface is already up and we just want to register it
+ return Result::OK;
+ }
+
+ if (!netdevice::down(mIfname)) {
+ LOG(ERROR) << "Can't bring " << mIfname << " down (to configure it)";
+ return Result::UNKNOWN_ERROR;
+ }
+
+ if (!netdevice::can::setBitrate(mIfname, mBitrate)) {
+ LOG(ERROR) << "Can't set bitrate " << mBitrate << " for " << mIfname;
+ return Result::BAD_BITRATE;
+ }
+
+ return Result::OK;
+}
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusNative.h b/automotive/can/aidl/default/CanBusNative.h
new file mode 100644
index 0000000..32846c7
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusNative.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "CanBus.h"
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBusNative : public CanBus {
+ public:
+ CanBusNative(const std::string& ifname, uint32_t bitrate);
+
+ protected:
+ virtual Result preUp() override;
+
+ private:
+ const uint32_t mBitrate;
+};
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusSlcan.cpp b/automotive/can/aidl/default/CanBusSlcan.cpp
new file mode 100644
index 0000000..6060419
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusSlcan.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusSlcan.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <libnetdevice/libnetdevice.h>
+
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <net/if.h>
+#include <termios.h>
+
+#include <map>
+
+namespace aidl::android::hardware::automotive::can {
+
+using namespace std::string_view_literals;
+using namespace ::android::base;
+
+namespace slcanprotocol {
+static constexpr std::string_view kOpenCommand = "O\r"sv;
+static constexpr std::string_view kCloseCommand = "C\r"sv;
+static constexpr int kSlcanDiscipline = N_SLCAN;
+static constexpr int kDefaultDiscipline = N_TTY;
+
+static const std::map<uint32_t, std::string_view> kBitrateCommands = {
+ {10000, "C\rS0\r"sv}, {20000, "C\rS1\r"sv}, {50000, "C\rS2\r"sv},
+ {100000, "C\rS3\r"sv}, {125000, "C\rS4\r"sv}, {250000, "C\rS5\r"sv},
+ {500000, "C\rS6\r"sv}, {800000, "C\rS7\r"sv}, {1000000, "C\rS8\r"sv}};
+} // namespace slcanprotocol
+
+/**
+ * Serial Line CAN constructor
+ * \param string uartName - name of slcan device (e.x. /dev/ttyUSB0)
+ * \param uint32_t bitrate - speed of the CAN bus (125k = MSCAN, 500k = HSCAN)
+ */
+CanBusSlcan::CanBusSlcan(const std::string& uartName, uint32_t bitrate)
+ : CanBus(), mTtyPath(uartName), kBitrate(bitrate) {}
+
+/** helper function to update CanBusSlcan object's iface name */
+Result CanBusSlcan::updateIfaceName(unique_fd& uartFd) {
+ struct ifreq ifrequest = {};
+ /*
+ * Fetching the iface name with an ioctl won't interfere with an open socketCAN iface attached
+ * to this tty. This is important in the event we are trying to register a SLCAN based iface
+ * that has already been configured and brought up.
+ */
+ if (ioctl(uartFd.get(), SIOCGIFNAME, ifrequest.ifr_name) < 0) {
+ PLOG(ERROR) << "Failed to get the name of the created device";
+ return Result::UNKNOWN_ERROR;
+ }
+
+ // Update the CanBus object with name that was assigned to it
+ mIfname = ifrequest.ifr_name;
+ return Result::OK;
+}
+
+Result CanBusSlcan::preUp() {
+ // verify valid bitrate and translate to serial command format
+ std::optional<std::string_view> canBitrateCommand = std::nullopt;
+ if (kBitrate != 0) {
+ const auto lookupIt = slcanprotocol::kBitrateCommands.find(kBitrate);
+ if (lookupIt == slcanprotocol::kBitrateCommands.end()) {
+ return Result::BAD_BITRATE;
+ }
+ canBitrateCommand = lookupIt->second;
+ }
+
+ /* Attempt to open the uart in r/w without blocking or becoming the
+ * controlling terminal */
+ mFd = unique_fd(open(mTtyPath.c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC));
+ if (!mFd.ok()) {
+ PLOG(ERROR) << "SLCAN Failed to open " << mTtyPath;
+ return Result::BAD_INTERFACE_ID;
+ }
+
+ // If the device is already up, update the iface name in our CanBusSlcan object
+ if (kBitrate == 0) {
+ return updateIfaceName(mFd);
+ }
+
+ // blank terminal settings and pull them from the device
+ struct termios terminalSettings = {};
+ if (tcgetattr(mFd.get(), &terminalSettings) < 0) {
+ PLOG(ERROR) << "Failed to read attrs of" << mTtyPath;
+ return Result::UNKNOWN_ERROR;
+ }
+
+ // change settings to raw mode
+ cfmakeraw(&terminalSettings);
+
+ // disable software flow control
+ terminalSettings.c_iflag &= ~IXOFF;
+ // enable hardware flow control
+ terminalSettings.c_cflag |= CRTSCTS;
+
+ struct serial_struct serialSettings;
+ // get serial settings
+ if (ioctl(mFd.get(), TIOCGSERIAL, &serialSettings) < 0) {
+ PLOG(ERROR) << "Failed to read serial settings from " << mTtyPath;
+ return Result::UNKNOWN_ERROR;
+ }
+ // set low latency mode
+ serialSettings.flags |= ASYNC_LOW_LATENCY;
+ // apply serial settings
+ if (ioctl(mFd.get(), TIOCSSERIAL, &serialSettings) < 0) {
+ PLOG(ERROR) << "Failed to set low latency mode on " << mTtyPath;
+ return Result::UNKNOWN_ERROR;
+ }
+
+ /* TCSADRAIN applies settings after we finish writing the rest of our
+ * changes (as opposed to TCSANOW, which changes immediately) */
+ if (tcsetattr(mFd.get(), TCSADRAIN, &terminalSettings) < 0) {
+ PLOG(ERROR) << "Failed to apply terminal settings to " << mTtyPath;
+ return Result::UNKNOWN_ERROR;
+ }
+
+ // apply speed setting for CAN
+ if (!WriteStringToFd(*canBitrateCommand, mFd)) {
+ PLOG(ERROR) << "Failed to apply CAN bitrate";
+ return Result::UNKNOWN_ERROR;
+ }
+
+ // TODO(b/144775286): set open flag & support listen only
+ if (!WriteStringToFd(slcanprotocol::kOpenCommand, mFd)) {
+ PLOG(ERROR) << "Failed to set open flag";
+ return Result::UNKNOWN_ERROR;
+ }
+
+ // set line discipline to slcan
+ if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kSlcanDiscipline) < 0) {
+ PLOG(ERROR) << "Failed to set line discipline to slcan";
+ return Result::UNKNOWN_ERROR;
+ }
+
+ // Update the CanBus object with name that was assigned to it
+ return updateIfaceName(mFd);
+}
+
+bool CanBusSlcan::postDown() {
+ // reset the line discipline to TTY mode
+ if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kDefaultDiscipline) < 0) {
+ LOG(ERROR) << "Failed to reset line discipline!";
+ return false;
+ }
+
+ // issue the close command
+ if (!WriteStringToFd(slcanprotocol::kCloseCommand, mFd)) {
+ LOG(ERROR) << "Failed to close tty!";
+ return false;
+ }
+
+ // close our unique_fd
+ mFd.reset();
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusSlcan.h b/automotive/can/aidl/default/CanBusSlcan.h
new file mode 100644
index 0000000..a1c908c
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusSlcan.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "CanBus.h"
+
+#include <android-base/unique_fd.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBusSlcan : public CanBus {
+ public:
+ CanBusSlcan(const std::string& uartName, uint32_t bitrate);
+
+ protected:
+ virtual Result preUp() override;
+ virtual bool postDown() override;
+
+ private:
+ Result updateIfaceName(::android::base::unique_fd& uartFd);
+
+ const std::string mTtyPath;
+ const uint32_t kBitrate;
+ ::android::base::unique_fd mFd;
+};
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusVirtual.cpp b/automotive/can/aidl/default/CanBusVirtual.cpp
new file mode 100644
index 0000000..28a1258
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusVirtual.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanBusVirtual.h"
+
+#include <android-base/logging.h>
+#include <libnetdevice/libnetdevice.h>
+
+namespace aidl::android::hardware::automotive::can {
+
+using namespace ::android;
+
+CanBusVirtual::CanBusVirtual(const std::string& ifname) : CanBus(ifname) {}
+
+Result CanBusVirtual::preUp() {
+ if (netdevice::exists(mIfname)) return Result::OK;
+
+ LOG(DEBUG) << "Virtual interface " << mIfname << " doesn't exist, creating...";
+ mWasCreated = true;
+ if (!netdevice::add(mIfname, "vcan")) {
+ LOG(ERROR) << "Can't create vcan interface " << mIfname;
+ return Result::UNKNOWN_ERROR;
+ }
+
+ return Result::OK;
+}
+
+bool CanBusVirtual::postDown() {
+ if (mWasCreated) {
+ mWasCreated = false;
+ if (!netdevice::del(mIfname)) {
+ LOG(ERROR) << "Couldn't remove vcan interface " << mIfname;
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanBusVirtual.h b/automotive/can/aidl/default/CanBusVirtual.h
new file mode 100644
index 0000000..9c5d35d
--- /dev/null
+++ b/automotive/can/aidl/default/CanBusVirtual.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "CanBus.h"
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanBusVirtual : public CanBus {
+ public:
+ CanBusVirtual(const std::string& ifname);
+
+ protected:
+ virtual Result preUp() override;
+ virtual bool postDown() override;
+
+ private:
+ bool mWasCreated = false;
+};
+
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanController.cpp b/automotive/can/aidl/default/CanController.cpp
new file mode 100644
index 0000000..e4b5306
--- /dev/null
+++ b/automotive/can/aidl/default/CanController.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanController.h"
+
+#include "CanBusNative.h"
+#include "CanBusSlcan.h"
+#include "CanBusVirtual.h"
+
+#include <android-base/format.h>
+#include <android-base/logging.h>
+
+#include <automotive/filesystem>
+#include <fstream>
+#include <regex>
+
+namespace aidl::android::hardware::automotive::can {
+
+namespace fs = ::android::hardware::automotive::filesystem;
+
+namespace fsErrors {
+static const std::error_code ok;
+static const std::error_code eperm(EPERM, std::generic_category());
+static const std::error_code enoent(ENOENT, std::generic_category());
+static const std::error_code eacces(EACCES, std::generic_category());
+} // namespace fsErrors
+
+/* In the /sys/devices tree, there are files called "serial", which contain the serial numbers
+ * for various devices. The exact location inside of this directory is dependent upon the
+ * hardware we are running on, so we have to start from /sys/devices and work our way down. */
+static const fs::path kDevPath("/sys/devices/");
+static const std::regex kTtyRe("^tty[A-Z]+[0-9]+$");
+static constexpr auto kOpts = ~(fs::directory_options::follow_directory_symlink |
+ fs::directory_options::skip_permission_denied);
+
+constexpr auto ok = &ndk::ScopedAStatus::ok;
+
+/**
+ * A helper object to associate the interface name and type of a USB to CAN adapter.
+ */
+struct UsbCanIface {
+ InterfaceType iftype;
+ std::string ifaceName;
+};
+
+static bool isValidName(const std::string& name) {
+ static const std::regex nameRE("^[a-zA-Z0-9_]{1,32}$");
+ return std::regex_match(name, nameRE);
+}
+
+/**
+ * Given a path, get the last element from it.
+ *
+ * \param itrPath - the path we want the last element of
+ * \return - the last element in the path (in string form).
+ */
+static std::string getLeaf(const fs::path& itrPath) {
+ /* end() returns an iterator one past the leaf of the path, so we've overshot
+ decrement (--) to go back one to the leaf
+ dereference and now we have our leaf. */
+ return *(--(itrPath.end()));
+}
+
+static ndk::ScopedAStatus resultToStatus(Result res, const std::string& msg = "") {
+ if (msg.empty()) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(static_cast<int>(res)));
+ }
+ return ndk::ScopedAStatus(
+ AStatus_fromServiceSpecificErrorWithMessage(static_cast<int>(res), msg.c_str()));
+}
+
+/**
+ * Given a UsbCanIface object, get the ifaceName given the serialPath.
+ *
+ * \param serialPath - Absolute path to a "serial" file for a given device in /sys.
+ * \return A populated UsbCanIface. On failure, nullopt is returned.
+ */
+static std::optional<UsbCanIface> getIfaceName(const fs::path& serialPath) {
+ std::error_code fsStatus;
+ // Since the path is to a file called "serial", we need to search its parent directory.
+ fs::recursive_directory_iterator fsItr(serialPath.parent_path(), kOpts, fsStatus);
+ if (fsStatus != fsErrors::ok) {
+ LOG(ERROR) << "Failed to open " << serialPath.parent_path();
+ return std::nullopt;
+ }
+
+ for (; fsStatus == fsErrors::ok && fsItr != fs::recursive_directory_iterator();
+ fsItr.increment(fsStatus)) {
+ /* We want either a directory called "net" or a directory that looks like tty<something>, so
+ * skip files. */
+ bool isDir = fsItr->is_directory(fsStatus);
+ if (fsStatus != fsErrors::ok || !isDir) continue;
+
+ std::string currentDir = getLeaf(fsItr->path());
+ if (currentDir == "net") {
+ /* This device is a SocketCAN device. The iface name is the only directory under
+ * net/. Multiple directories under net/ is an error.*/
+ fs::directory_iterator netItr(fsItr->path(), kOpts, fsStatus);
+ if (fsStatus != fsErrors::ok) {
+ LOG(ERROR) << "Failed to open " << fsItr->path() << " to get net name!";
+ return std::nullopt;
+ }
+
+ // The leaf of our path should be the interface name.
+ std::string netName = getLeaf(netItr->path());
+
+ // Check if there is more than one item in net/
+ netItr.increment(fsStatus);
+ if (fsStatus != fsErrors::ok) {
+ // It's possible we have a valid net name, but this is most likely an error.
+ LOG(ERROR) << "Failed to verify " << fsItr->path() << " has valid net name!";
+ return std::nullopt;
+ }
+ if (netItr != fs::directory_iterator()) {
+ // There should never be more than one name under net/
+ LOG(ERROR) << "Found more than one net name in " << fsItr->path() << "!";
+ return std::nullopt;
+ }
+ return {{InterfaceType::NATIVE, netName}};
+ } else if (std::regex_match(currentDir, kTtyRe)) {
+ // This device is a USB serial device, and currentDir is the tty name.
+ return {{InterfaceType::SLCAN, "/dev/" + currentDir}};
+ }
+ }
+
+ // check if the loop above exited due to a c++fs error.
+ if (fsStatus != fsErrors::ok) {
+ LOG(ERROR) << "Failed search filesystem: " << fsStatus;
+ }
+ return std::nullopt;
+}
+
+/**
+ * A helper function to read the serial number from a "serial" file in /sys/devices/
+ *
+ * \param serialnoPath - path to the file to read.
+ * \return the serial number, or nullopt on failure.
+ */
+static std::optional<std::string> readSerialNo(const std::string& serialnoPath) {
+ std::ifstream serialnoStream(serialnoPath);
+ std::string serialno;
+ if (!serialnoStream.good()) {
+ LOG(ERROR) << "Failed to read serial number from " << serialnoPath;
+ return std::nullopt;
+ }
+ std::getline(serialnoStream, serialno);
+ return serialno;
+}
+
+/**
+ * Searches for USB devices found in /sys/devices/, and attempts to find a device matching the
+ * provided list of serial numbers.
+ *
+ * \param configSerialnos - a list of serial number (suffixes) from the HAL config.
+ * \param iftype - the type of the interface to be located.
+ * \return a matching USB device. On failure, std::nullopt is returned.
+ */
+static std::optional<UsbCanIface> findUsbDevice(const std::vector<std::string>& configSerialnos) {
+ std::error_code fsStatus;
+ fs::recursive_directory_iterator fsItr(kDevPath, kOpts, fsStatus);
+ if (fsStatus != fsErrors::ok) {
+ LOG(ERROR) << "Failed to open " << kDevPath;
+ return std::nullopt;
+ }
+
+ for (; fsStatus == fsErrors::ok && fsItr != fs::recursive_directory_iterator();
+ fsItr.increment(fsStatus)) {
+ // We want to find a file called "serial", which is in a directory somewhere. Skip files.
+ bool isDir = fsItr->is_directory(fsStatus);
+ if (fsStatus != fsErrors::ok) {
+ LOG(ERROR) << "Failed check if " << fsStatus;
+ return std::nullopt;
+ }
+ if (!isDir) continue;
+
+ auto serialnoPath = fsItr->path() / "serial";
+ bool isReg = fs::is_regular_file(serialnoPath, fsStatus);
+
+ /* Make sure we have permissions to this directory, ignore enoent, since the file
+ * "serial" may not exist, which is ok. */
+ if (fsStatus == fsErrors::eperm || fsStatus == fsErrors::eacces) {
+ /* This means we don't have access to this directory. If we recurse into it, this
+ * will cause the iterator to loose its state and we'll crash. */
+ fsItr.disable_recursion_pending();
+ continue;
+ }
+ if (fsStatus == fsErrors::enoent) continue;
+ if (fsStatus != fsErrors::ok) {
+ LOG(WARNING) << "An unexpected error occurred while checking for serialno: "
+ << fsStatus;
+ continue;
+ }
+ if (!isReg) continue;
+
+ // we found a serial number
+ auto serialno = readSerialNo(serialnoPath);
+ if (!serialno.has_value()) continue;
+
+ // see if the serial number exists in the config
+ for (auto&& cfgSn : configSerialnos) {
+ if (serialno->ends_with(std::string(cfgSn))) {
+ auto ifaceInfo = getIfaceName(serialnoPath);
+ if (!ifaceInfo.has_value()) break;
+ return ifaceInfo;
+ }
+ }
+ }
+ if (fsStatus != fsErrors::ok) {
+ LOG(ERROR) << "Error searching filesystem: " << fsStatus;
+ return std::nullopt;
+ }
+ return std::nullopt;
+}
+
+ndk::ScopedAStatus CanController::getSupportedInterfaceTypes(
+ std::vector<InterfaceType>* supportedTypes) {
+ *supportedTypes = {InterfaceType::VIRTUAL, InterfaceType::NATIVE, InterfaceType::SLCAN};
+ return ok();
+}
+
+ndk::ScopedAStatus CanController::getInterfaceName(const std::string& busName,
+ std::string* ifaceName) {
+ *ifaceName = {};
+ if (mBusesByName.find(busName) == mBusesByName.end()) {
+ return resultToStatus(Result::BAD_BUS_NAME, fmt::format("{} doesn't exist", busName));
+ }
+ *ifaceName = std::string(mBusesByName[busName]->getIfaceName());
+ return ok();
+}
+
+ndk::ScopedAStatus CanController::upBus(const BusConfig& config, std::string* ifaceName) {
+ if (!isValidName(config.name)) {
+ LOG(ERROR) << "Bus name " << config.name << " is invalid";
+ return resultToStatus(Result::BAD_BUS_NAME,
+ fmt::format("{} is not a valid bus name", config.name));
+ } else if (mBusesByName.find(config.name) != mBusesByName.end()) {
+ LOG(ERROR) << "A bus named " << config.name << " already exists!";
+ return resultToStatus(Result::INVALID_STATE,
+ fmt::format("A bus named {} already exists", config.name));
+ }
+
+ if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::virtualif) {
+ auto& virtualif = config.interfaceId.get<BusConfig::InterfaceId::Tag::virtualif>();
+ mBusesByName[config.name] = std::make_unique<CanBusVirtual>(virtualif.ifname);
+ }
+
+ else if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::nativeif) {
+ auto& nativeif = config.interfaceId.get<BusConfig::InterfaceId::Tag::nativeif>();
+ std::string ifaceName;
+ if (nativeif.interfaceId.getTag() == NativeInterface::InterfaceId::Tag::serialno) {
+ // Configure by serial number.
+ auto selectedDevice = findUsbDevice(
+ nativeif.interfaceId.get<NativeInterface::InterfaceId::Tag::serialno>());
+ // verify the returned device is the correct one
+ if (!selectedDevice.has_value() || selectedDevice->iftype != InterfaceType::NATIVE) {
+ return resultToStatus(
+ Result::BAD_INTERFACE_ID,
+ "Couldn't find a native socketcan device with the given serial number(s)");
+ }
+ ifaceName = selectedDevice->ifaceName;
+ } else {
+ // configure by iface name.
+ ifaceName = nativeif.interfaceId.get<NativeInterface::InterfaceId::Tag::ifname>();
+ }
+ mBusesByName[config.name] = std::make_unique<CanBusNative>(ifaceName, config.bitrate);
+ }
+
+ else if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::slcan) {
+ auto& slcanif = config.interfaceId.get<BusConfig::InterfaceId::Tag::slcan>();
+ std::string ttyName;
+ if (slcanif.interfaceId.getTag() == SlcanInterface::InterfaceId::Tag::serialno) {
+ // Configure by serial number.
+ auto selectedDevice = findUsbDevice(
+ slcanif.interfaceId.get<SlcanInterface::InterfaceId::Tag::serialno>());
+ if (!selectedDevice.has_value() || selectedDevice->iftype != InterfaceType::SLCAN) {
+ return resultToStatus(
+ Result::BAD_INTERFACE_ID,
+ "Couldn't find a slcan device with the given serial number(s)");
+ }
+ ttyName = selectedDevice->ifaceName;
+ } else {
+ // Configure by tty name.
+ ttyName = slcanif.interfaceId.get<SlcanInterface::InterfaceId::Tag::ttyname>();
+ }
+ mBusesByName[config.name] = std::make_unique<CanBusSlcan>(ttyName, config.bitrate);
+ }
+
+ else if (config.interfaceId.getTag() == BusConfig::InterfaceId::Tag::indexed) {
+ return resultToStatus(Result::NOT_SUPPORTED,
+ "Indexed devices are not supported in this implementation");
+ } else {
+ // this shouldn't happen.
+ return resultToStatus(Result::UNKNOWN_ERROR, "Unknown interface id type");
+ }
+
+ Result result = mBusesByName[config.name]->up();
+ if (result != Result::OK) {
+ // the bus failed to come up, don't leave a broken entry in the map.
+ mBusesByName.erase(config.name);
+ return resultToStatus(result, fmt::format("CanBus::up failed for {}", config.name));
+ }
+
+ *ifaceName = mBusesByName[config.name]->getIfaceName();
+ return ok();
+}
+
+ndk::ScopedAStatus CanController::downBus(const std::string& busName) {
+ if (mBusesByName.find(busName) == mBusesByName.end()) {
+ return resultToStatus(
+ Result::UNKNOWN_ERROR,
+ fmt::format("Couldn't bring down {}, because it doesn't exist", busName));
+ }
+ Result result = mBusesByName[busName]->down();
+ if (result != Result::OK) {
+ return resultToStatus(result, fmt::format("Couldn't bring down {}!", busName));
+ }
+ mBusesByName.erase(busName);
+ return ok();
+}
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/CanController.h b/automotive/can/aidl/default/CanController.h
new file mode 100644
index 0000000..784906e
--- /dev/null
+++ b/automotive/can/aidl/default/CanController.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/can/BnCanController.h>
+
+#include "CanBus.h"
+
+#include <aidl/android/hardware/automotive/can/Result.h>
+
+#include <map>
+#include <string>
+
+namespace aidl::android::hardware::automotive::can {
+
+class CanController : public BnCanController {
+ public:
+ ndk::ScopedAStatus getSupportedInterfaceTypes(
+ std::vector<InterfaceType>* supportedTypes) override;
+
+ ndk::ScopedAStatus getInterfaceName(const std::string& busName,
+ std::string* ifaceName) override;
+
+ ndk::ScopedAStatus upBus(const BusConfig& config, std::string* ifaceName) override;
+
+ ndk::ScopedAStatus downBus(const std::string& busName) override;
+
+ private:
+ std::map<std::string, std::unique_ptr<CanBus>> mBusesByName = {};
+};
+} // namespace aidl::android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/android.hardware.automotive.can.rc b/automotive/can/aidl/default/android.hardware.automotive.can.rc
new file mode 100644
index 0000000..f843752
--- /dev/null
+++ b/automotive/can/aidl/default/android.hardware.automotive.can.rc
@@ -0,0 +1,5 @@
+service android.hardware.automotive.can /vendor/bin/hw/android.hardware.automotive.can-service
+ class hal
+ capabilities NET_ADMIN
+ user vehicle_network
+ group system inet
diff --git a/automotive/can/aidl/default/android.hardware.automotive.can.xml b/automotive/can/aidl/default/android.hardware.automotive.can.xml
new file mode 100644
index 0000000..873f333
--- /dev/null
+++ b/automotive/can/aidl/default/android.hardware.automotive.can.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.can</name>
+ <version>1</version>
+ <interface>
+ <name>ICanController</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/automotive/can/aidl/default/service.cpp b/automotive/can/aidl/default/service.cpp
new file mode 100644
index 0000000..eb45167
--- /dev/null
+++ b/automotive/can/aidl/default/service.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CanController.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+namespace android::hardware::automotive::can {
+
+using namespace std::string_literals;
+using ::aidl::android::hardware::automotive::can::CanController;
+
+extern "C" int main() {
+ base::SetDefaultTag("CanController");
+ base::SetMinimumLogSeverity(base::VERBOSE);
+
+ LOG(VERBOSE) << "Starting up...";
+ auto service = ndk::SharedRefBase::make<CanController>();
+ const auto instance = CanController::descriptor + "/default"s;
+ const auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance;
+ LOG(VERBOSE) << "Started successfully!";
+
+ ABinderProcess_joinThreadPool();
+ LOG(FATAL) << "CanController exited unexpectedly!";
+ return EXIT_FAILURE;
+}
+} // namespace android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/tools/configurator/Android.bp b/automotive/can/aidl/default/tools/configurator/Android.bp
new file mode 100644
index 0000000..4c569e6
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/Android.bp
@@ -0,0 +1,44 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "canhalconfigurator-aidl",
+ init_rc: ["canhalconfigurator-aidl.rc"],
+ defaults: ["android.hardware.automotive.can@defaults"],
+ srcs: [
+ "canhalconfigurator.cpp",
+ "canprototools.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libprotobuf-cpp-full",
+ ],
+ static_libs: [
+ "android.hardware.automotive.can-V1-ndk",
+ "android.hardware.automotive.can-aidl-config-format",
+ ],
+ system_ext_specific: true,
+}
diff --git a/automotive/can/aidl/default/tools/configurator/canhalconfigurator-aidl.rc b/automotive/can/aidl/default/tools/configurator/canhalconfigurator-aidl.rc
new file mode 100644
index 0000000..08b1e7b
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canhalconfigurator-aidl.rc
@@ -0,0 +1,3 @@
+service canhalconfigurator /system_ext/bin/canhalconfigurator-aidl
+ class core
+ oneshot
diff --git a/automotive/can/aidl/default/tools/configurator/canhalconfigurator.cpp b/automotive/can/aidl/default/tools/configurator/canhalconfigurator.cpp
new file mode 100644
index 0000000..94e77b4
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canhalconfigurator.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "canbus_config.pb.h"
+#include "canprototools.h"
+
+#include <aidl/android/hardware/automotive/can/ICanController.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include <chrono>
+#include <thread>
+
+namespace android::hardware::automotive::can {
+
+using namespace std::string_literals;
+using ::aidl::android::hardware::automotive::can::ICanController;
+
+static constexpr std::string_view kDefaultConfigPath = "/etc/canbus_config.pb";
+
+/**
+ * Takes output from parsed protobuf config and uses it to configure the CAN HAL.
+ *
+ * \param pb_cfg is an instance of the autogenerated protobuf object for our configuration.
+ * \return boolean status, true on success, false on failure.
+ */
+static bool processPbCfg(const config::CanBusConfig& pb_cfg) {
+ for (auto const& bus : pb_cfg.buses()) {
+ if (bus.name().empty()) {
+ LOG(ERROR) << "Invalid config: Bus config must have a valid name field";
+ return false;
+ }
+
+ auto busCfgMaybe = config::fromPbBus(bus);
+ if (!busCfgMaybe.has_value()) {
+ return false;
+ }
+ auto busCfg = *busCfgMaybe;
+
+ const auto instance = ICanController::descriptor + "/default"s;
+ const auto service = ICanController::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
+ if (service == nullptr) {
+ LOG(FATAL) << "Can't find CAN HAL! (has it started yet?)";
+ return false;
+ }
+
+ LOG(VERBOSE) << "Bringing up a " << busCfg.name << " @ " << busCfg.bitrate;
+
+ std::string ifaceName;
+ const auto status = service->upBus(busCfg, &ifaceName);
+ if (!status.isOk() && status.getExceptionCode() != EX_SERVICE_SPECIFIC) {
+ LOG(FATAL) << "Binder transaction failed!" << status.getStatus();
+ return false;
+ } else if (!status.isOk()) {
+ LOG(ERROR) << "upBus failed: " << config::resultStringFromStatus(status) << ": "
+ << status.getMessage();
+ continue;
+ }
+
+ LOG(INFO) << bus.name() << " has been successfully configured on " << ifaceName;
+ }
+ return true;
+}
+
+/**
+ * This kicks off the CAN HAL configuration process. This starts the following:
+ * 1. Reading the config file
+ * 2. Setting up CAN buses
+ * 3. Handling services
+ * \param filepath is a string specifying the absolute path of the config file
+ * \return boolean status, true on success, false on failure
+ */
+static bool configuratorStart(const std::string& filepath) {
+ base::SetDefaultTag("CanConfigurator");
+ auto pbCfg = config::parseConfigFile(filepath);
+ if (!pbCfg.has_value()) {
+ return false;
+ }
+ // process the rest of the config file data and configure the CAN buses.
+ if (!processPbCfg(*pbCfg)) {
+ return false;
+ }
+ LOG(INFO) << "CAN HAL has been configured!";
+ return true;
+}
+
+extern "C" int main(int argc, char* argv[]) {
+ std::string configFilepath = static_cast<std::string>(kDefaultConfigPath);
+
+ // allow for CLI specification of a config file.
+ if (argc == 2) {
+ configFilepath = argv[1];
+ } else if (argc > 2) {
+ std::cerr << "usage: " << argv[0] << " [optional config filepath]";
+ return 1;
+ }
+
+ if (!configuratorStart(configFilepath)) {
+ return 1;
+ }
+ return 0;
+}
+
+} // namespace android::hardware::automotive::can
diff --git a/automotive/can/aidl/default/tools/configurator/canprototools.cpp b/automotive/can/aidl/default/tools/configurator/canprototools.cpp
new file mode 100644
index 0000000..84edd94
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canprototools.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "canprototools.h"
+
+#include <aidl/android/hardware/automotive/can/IndexedInterface.h>
+#include <aidl/android/hardware/automotive/can/NativeInterface.h>
+#include <aidl/android/hardware/automotive/can/SlcanInterface.h>
+#include <aidl/android/hardware/automotive/can/VirtualInterface.h>
+
+#include <android-base/logging.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/text_format.h>
+
+#include <fstream>
+
+namespace android::hardware::automotive::can::config {
+
+using ::aidl::android::hardware::automotive::can::BusConfig;
+using ::aidl::android::hardware::automotive::can::IndexedInterface;
+using ::aidl::android::hardware::automotive::can::InterfaceType;
+using ::aidl::android::hardware::automotive::can::NativeInterface;
+using ::aidl::android::hardware::automotive::can::Result;
+using ::aidl::android::hardware::automotive::can::SlcanInterface;
+using ::aidl::android::hardware::automotive::can::VirtualInterface;
+
+/**
+ * Helper function for parseConfigFile. readString is used to get the fist n characters (n) from an
+ * istream object (s) and return it as a string object.
+ *
+ * \param s istream of the file you intend to read.
+ * \param n streamsize object of the number of characters you'd like.
+ * \return optional string containing up to n characters from the stream(s) you provided.
+ */
+static std::optional<std::string> readString(std::istream& s, std::streamsize n) {
+ char buff[n];
+ auto got = s.read(buff, n).gcount();
+ if (!s.good() && !s.eof()) return std::nullopt;
+ return std::string(buff, 0, std::min(n, got));
+}
+
+/*
+ parseConfigFile *used to* contain the body of parseConfigStream. However, it seems there's some
+ sort of odd behavior with IstreamInputStream and/or TextFormat::Parse, which causes HW Address
+ Sanitizer to flag a "tag-mismatch" in this function. Having the ifstream defined in a wrapper
+ function seems to solve this problem. The exact cause of this problem is yet unknown, but probably
+ lies somewhere in the protobuf implementation.
+*/
+static __attribute__((noinline)) std::optional<CanBusConfig> parseConfigStream(
+ std::ifstream& cfg_stream) {
+ static const std::array<std::string, 3> text_headers = {"buses", "#", "controller"};
+ auto cfg_file_snippet = readString(cfg_stream, 10);
+
+ if (!cfg_file_snippet.has_value()) {
+ LOG(ERROR) << "Can't read config from stream (maybe failed to open file?)";
+ return std::nullopt;
+ }
+ cfg_stream.seekg(0);
+
+ // check if any of the textHeaders are at the start of the config file.
+ bool text_format = false;
+ for (auto const& header : text_headers) {
+ if (cfg_file_snippet->compare(0, header.length(), header) == 0) {
+ text_format = true;
+ break;
+ }
+ }
+
+ CanBusConfig config;
+ if (text_format) {
+ google::protobuf::io::IstreamInputStream pb_stream(&cfg_stream);
+ if (!google::protobuf::TextFormat::Parse(&pb_stream, &config)) {
+ LOG(ERROR) << "Parsing text format config failed";
+ return std::nullopt;
+ }
+ } else if (!config.ParseFromIstream(&cfg_stream)) {
+ LOG(ERROR) << "Parsing binary format config failed";
+ return std::nullopt;
+ }
+ return config;
+}
+
+std::optional<CanBusConfig> parseConfigFile(const std::string& filepath) {
+ std::ifstream cfg_stream(filepath);
+ auto cfg_maybe = parseConfigStream(cfg_stream);
+ if (!cfg_maybe.has_value()) {
+ LOG(ERROR) << "Failed to parse " << filepath;
+ }
+ return cfg_maybe;
+}
+
+std::optional<BusConfig> fromPbBus(const Bus& pb_bus) {
+ BusConfig bus_cfg = {};
+ bus_cfg.name = pb_bus.name();
+
+ switch (pb_bus.iface_type_case()) {
+ case Bus::kNative: {
+ const std::string ifname = pb_bus.native().ifname();
+ const std::vector<std::string> serials = {pb_bus.native().serialno().begin(),
+ pb_bus.native().serialno().end()};
+ if (ifname.empty() == serials.empty()) {
+ LOG(ERROR) << "Invalid config: native type bus must have an iface name xor a "
+ << "serial number";
+ return std::nullopt;
+ }
+ bus_cfg.bitrate = pb_bus.bitrate();
+ NativeInterface nativeif = {};
+ if (!ifname.empty())
+ nativeif.interfaceId.set<NativeInterface::InterfaceId::Tag::ifname>(ifname);
+ if (!serials.empty())
+ nativeif.interfaceId.set<NativeInterface::InterfaceId::Tag::serialno>(serials);
+ bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::nativeif>(nativeif);
+ break;
+ }
+ case Bus::kSlcan: {
+ const std::string ttyname = pb_bus.slcan().ttyname();
+ const std::vector<std::string> serials = {pb_bus.slcan().serialno().begin(),
+ pb_bus.slcan().serialno().end()};
+ if (ttyname.empty() == serials.empty()) {
+ LOG(ERROR) << "Invalid config: slcan type bus must have a tty name xor a serial "
+ << "number";
+ return std::nullopt;
+ }
+ bus_cfg.bitrate = pb_bus.bitrate();
+ SlcanInterface slcan = {};
+ if (!ttyname.empty())
+ slcan.interfaceId.set<SlcanInterface::InterfaceId::Tag::ttyname>(ttyname);
+ if (!serials.empty())
+ slcan.interfaceId.set<SlcanInterface::InterfaceId::Tag::serialno>(serials);
+ bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::slcan>(slcan);
+ break;
+ }
+ case Bus::kVirtual: {
+ // Theoretically, we could just create the next available vcan iface.
+ const std::string ifname = pb_bus.virtual_().ifname();
+ if (ifname.empty()) {
+ LOG(ERROR) << "Invalid config: native type bus must have an iface name";
+ return std::nullopt;
+ }
+ VirtualInterface virtualif = {};
+ virtualif.ifname = ifname;
+ bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::virtualif>(virtualif);
+ break;
+ }
+ case Bus::kIndexed: {
+ const uint8_t index = pb_bus.indexed().index();
+ if (index > UINT8_MAX) {
+ LOG(ERROR) << "Interface index out of range: " << index;
+ return std::nullopt;
+ }
+ IndexedInterface indexedif = {};
+ indexedif.index = index;
+ bus_cfg.interfaceId.set<BusConfig::InterfaceId::Tag::indexed>(indexedif);
+ break;
+ }
+ default:
+ LOG(ERROR) << "Invalid config: bad interface type for " << bus_cfg.name;
+ return std::nullopt;
+ }
+ return bus_cfg;
+}
+
+std::optional<InterfaceType> getHalIftype(const Bus& pb_bus) {
+ switch (pb_bus.iface_type_case()) {
+ case Bus::kNative:
+ return InterfaceType::NATIVE;
+ case Bus::kSlcan:
+ return InterfaceType::SLCAN;
+ case Bus::kVirtual:
+ return InterfaceType::VIRTUAL;
+ case Bus::kIndexed:
+ return InterfaceType::INDEXED;
+ default:
+ return std::nullopt;
+ }
+}
+
+std::string resultStringFromStatus(const ndk::ScopedAStatus& status) {
+ const auto res = static_cast<Result>(status.getServiceSpecificError());
+ switch (res) {
+ case Result::OK:
+ return "OK";
+ case Result::UNKNOWN_ERROR:
+ return "UNKNOWN_ERROR";
+ case Result::INVALID_STATE:
+ return "INVALID_STATE";
+ case Result::NOT_SUPPORTED:
+ return "NOT_SUPPORTED";
+ case Result::BAD_INTERFACE_ID:
+ return "BAD_INTERFACE_ID";
+ case Result::BAD_BITRATE:
+ return "BAD_BITRATE";
+ case Result::BAD_BUS_NAME:
+ return "BAD_BUS_NAME";
+ case Result::INTERFACE_DOWN:
+ return "INTERFACE_DOWN";
+ default:
+ return "Invalid Result!";
+ }
+}
+
+} // namespace android::hardware::automotive::can::config
diff --git a/automotive/can/aidl/default/tools/configurator/canprototools.h b/automotive/can/aidl/default/tools/configurator/canprototools.h
new file mode 100644
index 0000000..377ee7f
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/canprototools.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "canbus_config.pb.h"
+
+#include <aidl/android/hardware/automotive/can/BusConfig.h>
+#include <aidl/android/hardware/automotive/can/InterfaceType.h>
+#include <aidl/android/hardware/automotive/can/Result.h>
+
+namespace android::hardware::automotive::can::config {
+
+/**
+ * This reads the protobuf config file into a protobuf object. Both text based protobuf files as
+ * well as binary format protobuf files are supported.
+ *
+ * \param filepath string containing the name of the config file to read.
+ * \return a CanBusConfig protobuf object constructed from the config file.
+ */
+std::optional<CanBusConfig> parseConfigFile(const std::string& filepath);
+
+/**
+ * Converts protobuf format single-bus config object to a HAL bus config object.
+ *
+ * \param pb_bus is the protobuf object representing a the configuration of one CAN bus.
+ * \return a converted HAL bus config object.
+ */
+std::optional<::aidl::android::hardware::automotive::can::BusConfig> fromPbBus(const Bus& pb_bus);
+
+/**
+ * Get the CAN HAL interface type specified by a given protobuf config object.
+ *
+ * \param pb_bus is the protobuf object representing a the configuration of one CAN bus.
+ * \return the CAN HAL interface type.
+ */
+std::optional<::aidl::android::hardware::automotive::can::InterfaceType> getHalIftype(
+ const Bus& pb_bus);
+
+std::string resultStringFromStatus(const ndk::ScopedAStatus& status);
+
+} // namespace android::hardware::automotive::can::config
diff --git a/automotive/can/aidl/default/tools/configurator/proto/Android.bp b/automotive/can/aidl/default/tools/configurator/proto/Android.bp
new file mode 100644
index 0000000..da1b37c
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/proto/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+ name: "android.hardware.automotive.can-aidl-config-format",
+ defaults: ["android.hardware.automotive.can@defaults"],
+ proto: {
+ export_proto_headers: true,
+ type: "full",
+ },
+ strip: {
+ keep_symbols: true,
+ },
+ srcs: ["canbus_config.proto"],
+}
diff --git a/automotive/can/aidl/default/tools/configurator/proto/canbus_config.proto b/automotive/can/aidl/default/tools/configurator/proto/canbus_config.proto
new file mode 100644
index 0000000..b03b035
--- /dev/null
+++ b/automotive/can/aidl/default/tools/configurator/proto/canbus_config.proto
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.can.config;
+
+message IfaceNative {
+ string ifname = 1;
+ repeated string serialno = 2;
+};
+
+message IfaceSlcan {
+ string ttyname = 1;
+ repeated string serialno = 2;
+};
+
+message IfaceVirtual {
+ string ifname = 1;
+};
+
+message IfaceIndexed {
+ uint32 index = 1;
+};
+
+message Bus {
+ string name = 1; // this is the name presented in the HAL
+ oneof iface_type {
+ IfaceNative native = 2;
+ IfaceSlcan slcan = 3;
+ IfaceVirtual virtual = 4;
+ IfaceIndexed indexed = 5;
+ }
+ uint32 bitrate = 6;
+};
+
+message CanBusConfig {
+ repeated Bus buses = 1;
+};
diff --git a/automotive/can/aidl/vts/functional/Android.bp b/automotive/can/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..b816a49
--- /dev/null
+++ b/automotive/can/aidl/vts/functional/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalCanControllerV1_0Test",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "android.hardware.automotive.can@defaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ cpp_std: "experimental",
+ srcs: [
+ "CanControllerAidlTest.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.automotive.can-V1-ndk",
+ "android.hardware.automotive.can@libnetdevice",
+ "libnl++",
+ "libgmock",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/automotive/can/aidl/vts/functional/CanControllerAidlTest.cpp b/automotive/can/aidl/vts/functional/CanControllerAidlTest.cpp
new file mode 100644
index 0000000..c2b2879
--- /dev/null
+++ b/automotive/can/aidl/vts/functional/CanControllerAidlTest.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/automotive/can/BusConfig.h>
+#include <aidl/android/hardware/automotive/can/ICanController.h>
+#include <aidl/android/hardware/automotive/can/Result.h>
+#include <aidl/android/hardware/automotive/can/VirtualInterface.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <libnetdevice/libnetdevice.h>
+#include <libnl++/MessageFactory.h>
+#include <libnl++/Socket.h>
+#include <libnl++/printer.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <chrono>
+#include <thread>
+
+using aidl::android::hardware::automotive::can::BusConfig;
+using aidl::android::hardware::automotive::can::ICanController;
+using aidl::android::hardware::automotive::can::VirtualInterface;
+using namespace std::chrono_literals;
+using namespace std::string_literals;
+
+class CanControllerAidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ android::base::SetDefaultTag("CAN_HAL_VTS");
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ const auto instance = ICanController::descriptor + "/default"s;
+ mCanControllerService = ICanController::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(instance.c_str())));
+
+ ASSERT_NE(mCanControllerService, nullptr);
+ }
+ virtual void TearDown() override {}
+
+ static bool mTestCaseInitialized;
+ std::shared_ptr<ICanController> mCanControllerService;
+};
+
+// we can't test a real bus, since we can't make any assumptions about hardware
+// this checks upBus, getInterfaceName, and downBus
+TEST_P(CanControllerAidlTest, ToggleBus) {
+ const std::string_view canIface = "vcan50";
+ const std::string busName = "VTS_CAN";
+
+ std::string upBusReturn; // should be vcan50
+ BusConfig config = {};
+ VirtualInterface iface = {};
+ iface.ifname = canIface;
+ config.interfaceId.set<BusConfig::InterfaceId::Tag::virtualif>(iface);
+ config.name = busName;
+ auto aidlStatus = mCanControllerService->upBus(config, &upBusReturn);
+ ASSERT_TRUE(aidlStatus.isOk());
+ EXPECT_EQ(upBusReturn, canIface);
+
+ std::string ifaceName;
+ aidlStatus = mCanControllerService->getInterfaceName(busName, &ifaceName);
+ ASSERT_TRUE(aidlStatus.isOk());
+ EXPECT_EQ(ifaceName, canIface);
+
+ aidlStatus = mCanControllerService->downBus(busName);
+ ASSERT_TRUE(aidlStatus.isOk());
+}
+
+TEST_P(CanControllerAidlTest, GetSupported) {
+ LOG(VERBOSE) << "Get the supported iface types";
+ std::vector<::aidl::android::hardware::automotive::can::InterfaceType> supportedTypes;
+ auto aidlStatus = mCanControllerService->getSupportedInterfaceTypes(&supportedTypes);
+ ASSERT_TRUE(aidlStatus.isOk());
+ EXPECT_FALSE(supportedTypes.empty());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanControllerAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, CanControllerAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(ICanController::descriptor)),
+ android::PrintInstanceNameToString);
diff --git a/automotive/can/aidl/vts/functional/OWNERS b/automotive/can/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..85257a3
--- /dev/null
+++ b/automotive/can/aidl/vts/functional/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 533426
[email protected]
[email protected]
diff --git a/automotive/evs/1.1/default/Android.bp b/automotive/evs/1.1/default/Android.bp
index 4c08ef3..4172e63 100644
--- a/automotive/evs/1.1/default/Android.bp
+++ b/automotive/evs/1.1/default/Android.bp
@@ -13,6 +13,7 @@
proprietary: true,
relative_install_path: "hw",
srcs: [
+ ":libgui_frame_event_aidl",
"*.cpp",
],
init_rc: ["[email protected]"],
diff --git a/automotive/evs/1.1/default/GlWrapper.cpp b/automotive/evs/1.1/default/GlWrapper.cpp
index 357b67c..9ad5729 100644
--- a/automotive/evs/1.1/default/GlWrapper.cpp
+++ b/automotive/evs/1.1/default/GlWrapper.cpp
@@ -37,28 +37,23 @@
constexpr float kDisplayAreaRatio = 0.8f;
constexpr const char vertexShaderSource[] =
- ""
- "#version 300 es \n"
- "layout(location = 0) in vec4 pos; \n"
- "layout(location = 1) in vec2 tex; \n"
- "out vec2 uv; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = pos; \n"
- " uv = tex; \n"
- "} \n";
+ "attribute vec4 pos; \n"
+ "attribute vec2 tex; \n"
+ "varying vec2 uv; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = pos; \n"
+ " uv = tex; \n"
+ "} \n";
constexpr const char pixelShaderSource[] =
- "#version 300 es \n"
- "precision mediump float; \n"
- "uniform sampler2D tex; \n"
- "in vec2 uv; \n"
- "out vec4 color; \n"
- "void main() \n"
- "{ \n"
- " vec4 texel = texture(tex, uv); \n"
- " color = texel; \n"
- "} \n";
+ "precision mediump float; \n"
+ "uniform sampler2D tex; \n"
+ "varying vec2 uv; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = texture2D(tex, uv); \n"
+ "} \n";
const char* getEGLError(void) {
switch (eglGetError()) {
@@ -157,6 +152,9 @@
glAttachShader(program, vertexShader);
glAttachShader(program, pixelShader);
+ glBindAttribLocation(program, 0, "pos");
+ glBindAttribLocation(program, 1, "tex");
+
// Link the program
glLinkProgram(program);
GLint linked = 0;
@@ -235,7 +233,7 @@
return false;
}
- EGLint major = 3;
+ EGLint major = 2;
EGLint minor = 0;
if (!eglInitialize(mDisplay, &major, &minor)) {
LOG(ERROR) << "Failed to initialize EGL: " << getEGLError();
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl
index 31acdb8..332aca3 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/BufferDesc.aidl
@@ -40,4 +40,8 @@
@utf8InCpp String deviceId;
long timestamp;
byte[] metadata;
+ @nullable android.hardware.automotive.evs.ExposureParameters[] exposureSettings;
+ @nullable android.hardware.automotive.evs.Histogram[] histograms;
+ @nullable android.hardware.automotive.evs.GridStatistics[] grids;
+ @nullable android.hardware.automotive.evs.EmbeddedData embeddedData;
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl
index ae4ce77..21207b3 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/CameraParam.aidl
@@ -34,16 +34,16 @@
package android.hardware.automotive.evs;
@Backing(type="int") @VintfStability
enum CameraParam {
- BRIGHTNESS = 0,
- CONTRAST = 1,
- AUTOGAIN = 2,
- GAIN = 3,
- AUTO_WHITE_BALANCE = 4,
- WHITE_BALANCE_TEMPERATURE = 5,
- SHARPNESS = 6,
- AUTO_EXPOSURE = 7,
- ABSOLUTE_EXPOSURE = 8,
- ABSOLUTE_FOCUS = 9,
- AUTO_FOCUS = 10,
- ABSOLUTE_ZOOM = 11,
+ BRIGHTNESS,
+ CONTRAST,
+ AUTOGAIN,
+ GAIN,
+ AUTO_WHITE_BALANCE,
+ WHITE_BALANCE_TEMPERATURE,
+ SHARPNESS,
+ AUTO_EXPOSURE,
+ ABSOLUTE_EXPOSURE,
+ ABSOLUTE_FOCUS,
+ AUTO_FOCUS,
+ ABSOLUTE_ZOOM,
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ColorChannel.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ColorChannel.aidl
new file mode 100644
index 0000000..e59db4c
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ColorChannel.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.automotive.evs;
+@Backing(type="int") @VintfStability
+enum ColorChannel {
+ R,
+ G_EVEN,
+ B,
+ G_ODD_OR_Y,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl
index d0f1d8e..92c2247 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DeviceStatusType.aidl
@@ -34,8 +34,8 @@
package android.hardware.automotive.evs;
@Backing(type="int") @VintfStability
enum DeviceStatusType {
- CAMERA_AVAILABLE = 0,
- CAMERA_NOT_AVAILABLE = 1,
- DISPLAY_AVAILABLE = 2,
- DISPLAY_NOT_AVAILABLE = 3,
+ CAMERA_AVAILABLE,
+ CAMERA_NOT_AVAILABLE,
+ DISPLAY_AVAILABLE,
+ DISPLAY_NOT_AVAILABLE,
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl
index a5f4309..5f03f43 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/DisplayState.aidl
@@ -35,8 +35,8 @@
@Backing(type="int") @VintfStability
enum DisplayState {
NOT_OPEN = 0,
- NOT_VISIBLE = 1,
- VISIBLE_ON_NEXT_FRAME = 2,
- VISIBLE = 3,
- DEAD = 4,
+ NOT_VISIBLE,
+ VISIBLE_ON_NEXT_FRAME,
+ VISIBLE,
+ DEAD,
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EmbeddedData.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EmbeddedData.aidl
new file mode 100644
index 0000000..e1f50d2
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EmbeddedData.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.evs;
+@VintfStability
+parcelable EmbeddedData {
+ int widthInBytes;
+ int heightInLines;
+ android.hardware.common.Ashmem data;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl
index 052a6b3..2e75a25 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsEventType.aidl
@@ -35,10 +35,10 @@
@Backing(type="int") @VintfStability
enum EvsEventType {
STREAM_STARTED = 0,
- STREAM_STOPPED = 1,
- FRAME_DROPPED = 2,
- TIMEOUT = 3,
- PARAMETER_CHANGED = 4,
- MASTER_RELEASED = 5,
- STREAM_ERROR = 6,
+ STREAM_STOPPED,
+ FRAME_DROPPED,
+ TIMEOUT,
+ PARAMETER_CHANGED,
+ MASTER_RELEASED,
+ STREAM_ERROR,
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl
index a0418a9..1f04750 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/EvsResult.aidl
@@ -35,14 +35,14 @@
@Backing(type="int") @VintfStability
enum EvsResult {
OK = 0,
- INVALID_ARG = 1,
- STREAM_ALREADY_RUNNING = 2,
- BUFFER_NOT_AVAILABLE = 3,
- OWNERSHIP_LOST = 4,
- UNDERLYING_SERVICE_ERROR = 5,
- PERMISSION_DENIED = 6,
- RESOURCE_NOT_AVAILABLE = 7,
- RESOURCE_BUSY = 8,
- NOT_IMPLEMENTED = 9,
- NOT_SUPPORTED = 10,
+ INVALID_ARG,
+ STREAM_ALREADY_RUNNING,
+ BUFFER_NOT_AVAILABLE,
+ OWNERSHIP_LOST,
+ UNDERLYING_SERVICE_ERROR,
+ PERMISSION_DENIED,
+ RESOURCE_NOT_AVAILABLE,
+ RESOURCE_BUSY,
+ NOT_IMPLEMENTED,
+ NOT_SUPPORTED,
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ExposureParameters.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ExposureParameters.aidl
new file mode 100644
index 0000000..28289ae
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/ExposureParameters.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.automotive.evs;
+@VintfStability
+parcelable ExposureParameters {
+ float[4] analogGain;
+ float[4] digitalGain;
+ long coarseIntegrationTimeInLines;
+ long fineIntegrationTimeInPixelClocks;
+ int coarseIntegrationTimeLShift;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticDesc.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticDesc.aidl
new file mode 100644
index 0000000..f9fadd9
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticDesc.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.automotive.evs;
+@VintfStability
+parcelable GridStatisticDesc {
+ android.hardware.automotive.evs.ColorChannel channel;
+ android.hardware.automotive.evs.GridStatisticType type;
+ android.hardware.graphics.common.Rect roi;
+ android.hardware.automotive.evs.Size cellSize;
+ int bitDepth;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticType.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticType.aidl
new file mode 100644
index 0000000..c2b2d66
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatisticType.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.automotive.evs;
+@Backing(type="int") @VintfStability
+enum GridStatisticType {
+ USER_DEFINED,
+ AVERAGE,
+ SUM,
+ SATURATION_COUNT,
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatistics.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatistics.aidl
new file mode 100644
index 0000000..d87cff3
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/GridStatistics.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.automotive.evs;
+@VintfStability
+parcelable GridStatistics {
+ android.hardware.automotive.evs.GridStatisticDesc[] descriptors;
+ android.hardware.common.Ashmem data;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Histogram.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Histogram.aidl
new file mode 100644
index 0000000..cb73eba
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Histogram.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.automotive.evs;
+@VintfStability
+parcelable Histogram {
+ android.hardware.automotive.evs.ColorChannel channel;
+ android.hardware.graphics.common.Rect roi;
+ int size;
+ int capacity;
+ long[] bins;
+}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl
index 225b504..4cefdf2 100644
--- a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/IEvsEnumerator.aidl
@@ -47,4 +47,5 @@
android.hardware.automotive.evs.IEvsDisplay openDisplay(in int id);
android.hardware.automotive.evs.IEvsUltrasonicsArray openUltrasonicsArray(in String ultrasonicsArrayId);
void registerStatusCallback(in android.hardware.automotive.evs.IEvsEnumeratorStatusCallback callback);
+ android.hardware.automotive.evs.DisplayState getDisplayStateById(in int id);
}
diff --git a/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Size.aidl b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Size.aidl
new file mode 100644
index 0000000..aa113f7
--- /dev/null
+++ b/automotive/evs/aidl/aidl_api/android.hardware.automotive.evs/current/android/hardware/automotive/evs/Size.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.automotive.evs;
+@VintfStability
+parcelable Size {
+ int widthInPixels = (-1) /* -1 */;
+ int heightInPixels = (-1) /* -1 */;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl
index 0604abe..b6c697d 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/BufferDesc.aidl
@@ -16,7 +16,12 @@
package android.hardware.automotive.evs;
+import android.hardware.automotive.evs.EmbeddedData;
+import android.hardware.automotive.evs.ExposureParameters;
+import android.hardware.automotive.evs.GridStatistics;
+import android.hardware.automotive.evs.Histogram;
import android.hardware.graphics.common.HardwareBuffer;
+import android.hardware.graphics.common.Rect;
/**
* Structure representing an image buffer through our APIs
@@ -57,4 +62,28 @@
* Frame metadata. This is opaque to EvsManager.
*/
byte[] metadata;
+ /**
+ * ExposureParameters are expected to be in the ascending
+ * order of their exposure time; from the shortest to the
+ * longest. For example, if the imaging sensor output has
+ * two exposures, a shorter exposure setting is at index 0
+ * and a longer exposure setting is at index 1.
+ */
+ @nullable ExposureParameters[] exposureSettings;
+ /**
+ * Histogram statistics calculated on this buffer. This
+ * may contain zero or more histograms.
+ */
+ @nullable Histogram[] histograms;
+ /**
+ * Grid statistics calculated on this buffer. This field
+ * also may contain zero or more grid statistics.
+ */
+ @nullable GridStatistics[] grids;
+ /**
+ * This may contain raw embedded data lines and can be
+ * used to share data other than exposure parameters,
+ * histograms, or grid statistics.
+ */
+ @nullable EmbeddedData embeddedData;
}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/ColorChannel.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/ColorChannel.aidl
new file mode 100644
index 0000000..9aba465
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/ColorChannel.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.evs;
+
+/**
+ * Color channels.
+ */
+@VintfStability
+@Backing(type="int")
+enum ColorChannel {
+ R,
+ G_EVEN, // The green channel in even lines.
+ B,
+ G_ODD_OR_Y, // The green channel in odd lines of
+ // color formats that have two green (or
+ // equivalent) channels, or the luminance
+ // if it exists in associated data.
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/EmbeddedData.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/EmbeddedData.aidl
new file mode 100644
index 0000000..422cef2
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/EmbeddedData.aidl
@@ -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 android.hardware.automotive.evs;
+
+import android.hardware.common.Ashmem;
+
+/**
+ * This structure contains raw embedded data lines and can
+ * used to share sensor embedded data that is not a type of
+ * histogram or grid statistics.
+ */
+@VintfStability
+parcelable EmbeddedData {
+ /** Width of the embedded data lines. */
+ int widthInBytes;
+ /** Number of the embedded data lines. */
+ int heightInLines;
+ /** Raw embedded data lines. */
+ Ashmem data;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/ExposureParameters.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/ExposureParameters.aidl
new file mode 100644
index 0000000..e644fed
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/ExposureParameters.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.
+ */
+
+package android.hardware.automotive.evs;
+
+/**
+ * Parameters that determine the exposure value.
+ *
+ * This data structure assumes that the imaging sensor has 4 channels at most.
+ */
+@VintfStability
+parcelable ExposureParameters {
+ /**
+ * Analog gain applied on each channel.
+ *
+ * A value for each channel will be indexed by android.hardware.automotive.evs.ColorChannel
+ * enum type.
+ */
+ float[4] analogGain;
+ /**
+ * Digital gain applied on each channel.
+ *
+ * A value for each channel will be indexed by android.hardware.automotive.evs.ColorChannel
+ * enum type.
+ */
+ float[4] digitalGain;
+ /** Exposure time in lines. */
+ long coarseIntegrationTimeInLines;
+ /** Remainder exposure time in clocks. */
+ long fineIntegrationTimeInPixelClocks;
+ /**
+ * Logarithm value of coarse integration time multiplier.
+ */
+ int coarseIntegrationTimeLShift;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticDesc.aidl
new file mode 100644
index 0000000..1cd8a1c
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticDesc.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.automotive.evs;
+
+import android.hardware.automotive.evs.ColorChannel;
+import android.hardware.automotive.evs.GridStatisticType;
+import android.hardware.automotive.evs.Size;
+import android.hardware.graphics.common.Rect;
+
+/**
+ * This data structure describes a grid statistic such as the low resolution luminance map.
+ */
+@VintfStability
+parcelable GridStatisticDesc {
+ /** Source color channel this statistics is calculated from. */
+ ColorChannel channel;
+ /** Type of this grad statistics. */
+ GridStatisticType type;
+ /** Region this statistics is calculated from. */
+ Rect roi;
+ /** Size of a grid cell. */
+ Size cellSize;
+ /** Bit-depth of a single value. */
+ int bitDepth;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticType.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticType.aidl
new file mode 100644
index 0000000..1b307c7
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatisticType.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.automotive.evs;
+
+/**
+ * Type of grid statistics.
+ */
+@VintfStability
+@Backing(type="int")
+enum GridStatisticType {
+ /** Custom statistics type. */
+ USER_DEFINED,
+ /** Average pixel values of each cell. */
+ AVERAGE,
+ /** Sum of pixel values in each cell. */
+ SUM,
+ /** Number of saturated pixels in each cell. */
+ SATURATION_COUNT,
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/GridStatistics.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatistics.aidl
new file mode 100644
index 0000000..57f72ea
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/GridStatistics.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.automotive.evs;
+
+import android.hardware.automotive.evs.GridStatisticDesc;
+import android.hardware.common.Ashmem;
+
+/**
+ * This data type represents grid-type statistics such as
+ * the luminance map in low-resolution.
+ */
+@VintfStability
+parcelable GridStatistics {
+ /** Descriptors of grid statistics in shared memory. */
+ GridStatisticDesc[] descriptors;
+ /**
+ * Shared memory object containing one or more grid statistics.
+ *
+ * When multiple statistics exist, they are in the same order with descriptors. For example,
+ * if the first descriptor represents a statistic whose size is in VGA resolution (640x480)
+ * and bitdepth (or precision) is 8-bit, the offset to the second statistic is 640x480x1-byte
+ * = 307200 bytes.
+ */
+ Ashmem data;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/Histogram.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/Histogram.aidl
new file mode 100644
index 0000000..3f3c5a3
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/Histogram.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.
+ */
+
+package android.hardware.automotive.evs;
+
+import android.hardware.automotive.evs.ColorChannel;
+import android.hardware.graphics.common.Rect;
+
+/**
+ * This data type represents 1D histogram statistics.
+ */
+@VintfStability
+parcelable Histogram {
+ /**
+ * Source color channel this histogram is calculated from.
+ */
+ ColorChannel channel;
+ /** A region of interests, where this histogram is calculated from. */
+ Rect roi;
+ /** Size of each histogram bin. */
+ int size;
+ /** Capacity of each histogram bin. */
+ int capacity;
+ /**
+ * Histogram bins; each bin contains values calculated from each ColorChannel.
+ *
+ * The size of the histogram data is inversely proportional to the size of a histogram bin.
+ * When a bin is sized as 1, a histogram has pow(2, bitdepth of the source data) and
+ * therefore could occupy more than a few kilobytes of 1 megabyte buffer that is shared with
+ * other processes. To avoid influencing other processes, we strongly recommend keeping the
+ * number of histogram bins less than 128. If a higher resolution is needed, please consider
+ * using android.hardware.automotive.evs.EmbeddedData instead.
+ */
+ long[] bins;
+}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl
index 8698700..37b8ea5 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsEnumerator.aidl
@@ -78,12 +78,12 @@
byte[] getDisplayIdList();
/**
- * This call requests the current state of the display
+ * This call requests the current state of the primary display
*
* If there is no open display, this returns DisplayState::NOT_OPEN. otherwise, it returns
- * the actual state of the active display. This call is replicated on the IEvsEnumerator
- * interface in order to allow secondary clients to monitor the state of the EVS display
- * without acquiring exclusive ownership of the display.
+ * the actual state of the active primary display. This call is replicated on the
+ * IEvsEnumerator interface in order to allow secondary clients to monitor the state of the EVS
+ * display without acquiring exclusive ownership of the display.
*
* @return Current DisplayState of this Display.
* @throws EvsResult::OWNERSHIP_LOST if current display is inactive
@@ -163,4 +163,19 @@
* @param in callback IEvsEnumeratorStatusCallback implementation
*/
void registerStatusCallback(in IEvsEnumeratorStatusCallback callback);
+
+ /**
+ * This call requests the current state of the display
+ *
+ * If the requested display is not active, this returns DisplayState::NOT_OPEN. otherwise, it
+ * returns the actual state of the active display. This call is replicated on the
+ * IEvsEnumerator interface in order to allow secondary clients to monitor the state of the EVS
+ * display without acquiring exclusive ownership of the display.
+ *
+ * @param in id ID of the requested display.
+ * @return Current DisplayState of this Display.
+ * @throws EvsResult::OWNERSHIP_LOST if current display is inactive
+ * EvsResult::PERMISSION_DENIED if the process is not permitted to do this operation.
+ */
+ DisplayState getDisplayStateById(in int id);
}
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/Size.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/Size.aidl
new file mode 100644
index 0000000..4924ec8
--- /dev/null
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/Size.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.evs;
+
+/**
+ * This type represents the size of the 2D area.
+ */
+@VintfStability
+parcelable Size {
+ /** Width of a target 2D area in pixels. */
+ int widthInPixels = -1;
+ /** Width of a target 2D area in pixels. */
+ int heightInPixels = -1;
+}
diff --git a/automotive/evs/aidl/impl/Android.bp b/automotive/evs/aidl/impl/Android.bp
index d907047..fa44ebb 100644
--- a/automotive/evs/aidl/impl/Android.bp
+++ b/automotive/evs/aidl/impl/Android.bp
@@ -20,10 +20,10 @@
cc_defaults {
name: "EvsHalDefaults",
+ defaults: ["android.hardware.graphics.common-ndk_static"],
static_libs: [
- "android.hardware.automotive.evs-V1-ndk",
+ "android.hardware.automotive.evs-V2-ndk",
"android.hardware.common-V2-ndk",
- "android.hardware.graphics.common-V4-ndk",
],
shared_libs: [
"libbase",
diff --git a/automotive/evs/aidl/impl/default/Android.bp b/automotive/evs/aidl/impl/default/Android.bp
index dbe0314..70c523b 100644
--- a/automotive/evs/aidl/impl/default/Android.bp
+++ b/automotive/evs/aidl/impl/default/Android.bp
@@ -24,13 +24,56 @@
cc_binary {
name: "android.hardware.automotive.evs-aidl-default-service",
defaults: ["EvsHalDefaults"],
- local_include_dirs: ["include"],
- vintf_fragments: ["evs-default-service.xml"],
+ vintf_fragments: ["manifest_evs-default-service.xml"],
init_rc: ["evs-default-service.rc"],
vendor: true,
relative_install_path: "hw",
- srcs: ["src/*.cpp"],
- shared_libs: [
- "libbinder_ndk",
+ cflags: [
+ "-DGL_GLEXT_PROTOTYPES",
+ "-DEGL_EGLEXT_PROTOTYPES",
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wthread-safety",
],
+ srcs: [
+ ":libgui_frame_event_aidl",
+ "src/*.cpp",
+ ],
+ shared_libs: [
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "libEGL",
+ "libGLESv2",
+ "libbase",
+ "libbinder_ndk",
+ "libbufferqueueconverter",
+ "libcamera_metadata",
+ "libhardware_legacy",
+ "libhidlbase",
+ "liblog",
+ "libnativewindow",
+ "libtinyxml2",
+ "libui",
+ "libutils",
+ "libyuv",
+ ],
+ static_libs: [
+ "android.frameworks.automotive.display-V1-ndk",
+ "android.hardware.automotive.evs-V2-ndk",
+ "android.hardware.common-V2-ndk",
+ "libaidlcommonsupport",
+ "libcutils",
+ ],
+ local_include_dirs: ["include"],
+ include_dirs: ["frameworks/native/include/"],
+ required: ["evs_mock_hal_configuration.xml"],
+}
+
+prebuilt_etc {
+ name: "evs_mock_hal_configuration.xml",
+ soc_specific: true,
+ src: "resources/evs_mock_configuration.xml",
+ sub_dir: "automotive/evs",
}
diff --git a/automotive/evs/aidl/impl/default/evs-default-service.rc b/automotive/evs/aidl/impl/default/evs-default-service.rc
index ea8e689..3da41ff 100644
--- a/automotive/evs/aidl/impl/default/evs-default-service.rc
+++ b/automotive/evs/aidl/impl/default/evs-default-service.rc
@@ -1,5 +1,8 @@
service vendor.evs-hal-default /vendor/bin/hw/android.hardware.automotive.evs-aidl-default-service
class early_hal
- user automotive_evs
- group automotive_evs
+ priority -20
+ user graphics
+ group automotive_evs camera
+ onrestart restart cardisplayproxyd
+ onrestart restart evsmanagerd
disabled
diff --git a/automotive/evs/aidl/impl/default/evs-default-service.xml b/automotive/evs/aidl/impl/default/evs-default-service.xml
deleted file mode 100644
index 96ff9f6..0000000
--- a/automotive/evs/aidl/impl/default/evs-default-service.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.automotive.evs</name>
- <transport>hwbinder</transport>
- <version>1</version>
- <interface>
- <name>IEvsEnumerator</name>
- <instance>hw/0</instance>
- </interface>
- </hal>
-</manifest>
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManager.h b/automotive/evs/aidl/impl/default/include/ConfigManager.h
new file mode 100644
index 0000000..1d5fe77
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/ConfigManager.h
@@ -0,0 +1,384 @@
+/*
+ * 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 "ConfigManagerUtil.h"
+
+#include <aidl/android/hardware/automotive/evs/CameraParam.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <android-base/logging.h>
+#include <system/camera_metadata.h>
+
+#include <tinyxml2.h>
+
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+/*
+ * Please note that this is different from what is defined in
+ * libhardware/modules/camera/3_4/metadata/types.h; this has one additional
+ * field to store a framerate.
+ */
+typedef struct {
+ int id;
+ int width;
+ int height;
+ ::aidl::android::hardware::graphics::common::PixelFormat format;
+ int type;
+ int framerate;
+} StreamConfiguration;
+
+class ConfigManager final {
+ public:
+ static std::unique_ptr<ConfigManager> Create();
+ ConfigManager(const ConfigManager&) = delete;
+ ConfigManager& operator=(const ConfigManager&) = delete;
+
+ /* Camera device's capabilities and metadata */
+ class CameraInfo {
+ public:
+ CameraInfo() : characteristics(nullptr) {}
+
+ virtual ~CameraInfo();
+
+ /* Allocate memory for camera_metadata_t */
+ bool allocate(size_t entry_cap, size_t data_cap) {
+ if (characteristics != nullptr) {
+ LOG(ERROR) << "Camera metadata is already allocated";
+ return false;
+ }
+
+ characteristics = allocate_camera_metadata(entry_cap, data_cap);
+ return characteristics != nullptr;
+ }
+
+ /*
+ * List of supported controls that the primary client can program.
+ * Paraemters are stored with its valid range
+ */
+ std::unordered_map<::aidl::android::hardware::automotive::evs::CameraParam,
+ std::tuple<int32_t, int32_t, int32_t>>
+ controls;
+
+ /*
+ * List of supported output stream configurations.
+ */
+ std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
+
+ /*
+ * Internal storage for camera metadata. Each entry holds a pointer to
+ * data and number of elements
+ */
+ std::unordered_map<camera_metadata_tag_t, std::pair<void*, size_t>> cameraMetadata;
+
+ /* Camera module characteristics */
+ camera_metadata_t* characteristics;
+ };
+
+ class CameraGroupInfo : public CameraInfo {
+ public:
+ CameraGroupInfo() {}
+
+ /* ID of member camera devices */
+ std::unordered_set<std::string> devices;
+
+ /* The capture operation of member camera devices are synchronized */
+ int32_t synchronized = 0;
+ };
+
+ class SystemInfo {
+ public:
+ /* number of available cameras */
+ int32_t numCameras = 0;
+ };
+
+ class DisplayInfo {
+ public:
+ /*
+ * List of supported input stream configurations.
+ */
+ std::unordered_map<int32_t, StreamConfiguration> streamConfigurations;
+ };
+
+ /*
+ * Return system information
+ *
+ * @return SystemInfo
+ * Constant reference of SystemInfo.
+ */
+ const SystemInfo& getSystemInfo() {
+ std::unique_lock<std::mutex> lock(mConfigLock);
+ mConfigCond.wait(lock, [this] { return mIsReady; });
+ return mSystemInfo;
+ }
+
+ /*
+ * Return a list of camera identifiers
+ *
+ * This function assumes that it is not being called frequently.
+ *
+ * @return std::vector<std::string>
+ * A vector that contains unique camera device identifiers.
+ */
+ std::vector<std::string> getCameraIdList() {
+ std::unique_lock<std::mutex> lock(mConfigLock);
+ mConfigCond.wait(lock, [this] { return mIsReady; });
+
+ std::vector<std::string> aList;
+ aList.reserve(mCameraInfo.size());
+ for (auto&& v : mCameraInfo) {
+ aList.push_back(v.first);
+ }
+
+ return aList;
+ }
+
+ /*
+ * Return a list of camera group identifiers
+ *
+ * This function assumes that it is not being called frequently.
+ *
+ * @return std::vector<std::string>
+ * A vector that contains unique camera device identifiers.
+ */
+ std::vector<std::string> getCameraGroupIdList() {
+ std::unique_lock<std::mutex> lock(mConfigLock);
+ mConfigCond.wait(lock, [this] { return mIsReady; });
+
+ std::vector<std::string> aList;
+ aList.reserve(mCameraGroups.size());
+ for (auto&& v : mCameraGroups) {
+ aList.push_back(v.first);
+ }
+
+ return aList;
+ }
+
+ /*
+ * Return a pointer to the camera group
+ *
+ * @return CameraGroup
+ * A pointer to a camera group identified by a given id.
+ */
+ std::unique_ptr<CameraGroupInfo>& getCameraGroupInfo(const std::string& gid) {
+ std::unique_lock<std::mutex> lock(mConfigLock);
+ mConfigCond.wait(lock, [this] { return mIsReady; });
+
+ return mCameraGroups[gid];
+ }
+
+ /*
+ * Return a camera metadata
+ *
+ * @param cameraId
+ * Unique camera node identifier in string
+ *
+ * @return unique_ptr<CameraInfo>
+ * A pointer to CameraInfo that is associated with a given camera
+ * ID. This returns a null pointer if this does not recognize a
+ * given camera identifier.
+ */
+ std::unique_ptr<CameraInfo>& getCameraInfo(const std::string& cameraId) noexcept {
+ std::unique_lock<std::mutex> lock(mConfigLock);
+ mConfigCond.wait(lock, [this] { return mIsReady; });
+
+ return mCameraInfo[cameraId];
+ }
+
+ /*
+ * Tell whether the configuration data is ready to be used
+ *
+ * @return bool
+ * True if configuration data is ready to be consumed.
+ */
+ bool isReady() const { return mIsReady; }
+
+ private:
+ /* Constructors */
+ ConfigManager() : mBinaryFilePath("") {}
+
+ static std::string_view sConfigDefaultPath;
+ static std::string_view sConfigOverridePath;
+
+ /* System configuration */
+ SystemInfo mSystemInfo;
+
+ /* Internal data structure for camera device information */
+ std::unordered_map<std::string, std::unique_ptr<CameraInfo>> mCameraInfo;
+
+ /* Internal data structure for camera device information */
+ std::unordered_map<std::string, std::unique_ptr<DisplayInfo>> mDisplayInfo;
+
+ /* Camera groups are stored in <groud id, CameraGroup> hash map */
+ std::unordered_map<std::string, std::unique_ptr<CameraGroupInfo>> mCameraGroups;
+
+ /*
+ * Camera positions are stored in <position, camera id set> hash map.
+ * The position must be one of front, rear, left, and right.
+ */
+ std::unordered_map<std::string, std::unordered_set<std::string>> mCameraPosition;
+
+ /* Configuration data lock */
+ mutable std::mutex mConfigLock;
+
+ /*
+ * This condition is signalled when it completes a configuration data
+ * preparation.
+ */
+ std::condition_variable mConfigCond;
+
+ /* A path to a binary configuration file */
+ const char* mBinaryFilePath;
+
+ /* Configuration data readiness */
+ bool mIsReady = false;
+
+ /*
+ * Parse a given EVS configuration file and store the information
+ * internally.
+ *
+ * @return bool
+ * True if it completes parsing a file successfully.
+ */
+ bool readConfigDataFromXML() noexcept;
+
+ /*
+ * read the information of the vehicle
+ *
+ * @param aSysElem
+ * A pointer to "system" XML element.
+ */
+ void readSystemInfo(const tinyxml2::XMLElement* const aSysElem);
+
+ /*
+ * read the information of camera devices
+ *
+ * @param aCameraElem
+ * A pointer to "camera" XML element that may contain multiple
+ * "device" elements.
+ */
+ void readCameraInfo(const tinyxml2::XMLElement* const aCameraElem);
+
+ /*
+ * read display device information
+ *
+ * @param aDisplayElem
+ * A pointer to "display" XML element that may contain multiple
+ * "device" elements.
+ */
+ void readDisplayInfo(const tinyxml2::XMLElement* const aDisplayElem);
+
+ /*
+ * read camera device information
+ *
+ * @param aCamera
+ * A pointer to CameraInfo that will be completed by this
+ * method.
+ * aDeviceElem
+ * A pointer to "device" XML element that contains camera module
+ * capability info and its characteristics.
+ *
+ * @return bool
+ * Return false upon any failure in reading and processing camera
+ * device information.
+ */
+ bool readCameraDeviceInfo(CameraInfo* aCamera, const tinyxml2::XMLElement* aDeviceElem);
+
+ /*
+ * read camera metadata
+ *
+ * @param aCapElem
+ * A pointer to "cap" XML element.
+ * @param aCamera
+ * A pointer to CameraInfo that is being filled by this method.
+ * @param dataSize
+ * Required size of memory to store camera metadata found in this
+ * method. This is calculated in this method and returned to the
+ * caller for camera_metadata allocation.
+ *
+ * @return size_t
+ * Number of camera metadata entries
+ */
+ size_t readCameraCapabilities(const tinyxml2::XMLElement* const aCapElem, CameraInfo* aCamera,
+ size_t& dataSize);
+
+ /*
+ * read camera metadata
+ *
+ * @param aParamElem
+ * A pointer to "characteristics" XML element.
+ * @param aCamera
+ * A pointer to CameraInfo that is being filled by this method.
+ * @param dataSize
+ * Required size of memory to store camera metadata found in this
+ * method.
+ *
+ * @return size_t
+ * Number of camera metadata entries
+ */
+ size_t readCameraMetadata(const tinyxml2::XMLElement* const aParamElem, CameraInfo* aCamera,
+ size_t& dataSize);
+
+ /*
+ * construct camera_metadata_t from camera capabilities and metadata
+ *
+ * @param aCamera
+ * A pointer to CameraInfo that is being filled by this method.
+ * @param totalEntries
+ * Number of camera metadata entries to be added.
+ * @param totalDataSize
+ * Sum of sizes of camera metadata entries to be added.
+ *
+ * @return bool
+ * False if either it fails to allocate memory for camera metadata
+ * or its size is not large enough to add all found camera metadata
+ * entries.
+ */
+ bool constructCameraMetadata(CameraInfo* aCamera, const size_t totalEntries,
+ const size_t totalDataSize);
+
+ /*
+ * Read configuration data from the binary file
+ *
+ * @return bool
+ * True if it succeeds to read configuration data from a binary
+ * file.
+ */
+ bool readConfigDataFromBinary();
+
+ /*
+ * Store configuration data to the file
+ *
+ * @return bool
+ * True if it succeeds to serialize mCameraInfo to the file.
+ */
+ bool writeConfigDataToBinary();
+
+ /*
+ * debugging method to print out all XML elements and their attributes in
+ * logcat message.
+ *
+ * @param aNode
+ * A pointer to the root XML element to navigate.
+ * @param prefix
+ * A prefix to XML string.
+ */
+ void printElementNames(const tinyxml2::XMLElement* aNode, const std::string& prefix = "") const;
+};
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h b/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h
new file mode 100644
index 0000000..32b50d3
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/ConfigManagerUtil.h
@@ -0,0 +1,62 @@
+/*
+ * 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/automotive/evs/CameraParam.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <android-base/macros.h>
+#include <system/camera_metadata.h>
+
+#include <string>
+#include <utility>
+
+class ConfigManagerUtil final {
+ public:
+ /**
+ * Convert a given string into V4L2_CID_*
+ */
+ static bool convertToEvsCameraParam(
+ const std::string& id,
+ ::aidl::android::hardware::automotive::evs::CameraParam& camParam);
+ /**
+ * Convert a given string into android.hardware.graphics.common.PixelFormat
+ */
+ static bool convertToPixelFormat(const std::string& in,
+ ::aidl::android::hardware::graphics::common::PixelFormat& out);
+ /**
+ * Convert a given string into corresponding camera metadata data tag defined in
+ * system/media/camera/include/system/camera_metadata_tags.h
+ */
+ static bool convertToMetadataTag(const char* name, camera_metadata_tag& aTag);
+ /**
+ * Convert a given string into a floating value array
+ */
+ static float* convertFloatArray(const char* sz, const char* vals, size_t& count,
+ const char delimiter = ',');
+ /**
+ * Trim a string
+ */
+ static std::string trimString(const std::string& src, const std::string& ws = " \n\r\t\f\v");
+
+ /**
+ * Convert a given string to corresponding camera capabilities
+ */
+ static bool convertToCameraCapability(
+ const char* name, camera_metadata_enum_android_request_available_capabilities_t& cap);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ConfigManagerUtil);
+};
diff --git a/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h b/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h
deleted file mode 100644
index 03a578d..0000000
--- a/automotive/evs/aidl/impl/default/include/DefaultEvsEnumerator.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
-#define android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
-
-#include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-class DefaultEvsEnumerator final
- : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator {
- ::ndk::ScopedAStatus isHardware(bool* flag) override;
- ::ndk::ScopedAStatus openCamera(
- const std::string& cameraId,
- const ::aidl::android::hardware::automotive::evs::Stream& streamConfig,
- std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera>* obj) override;
- ::ndk::ScopedAStatus closeCamera(
- const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera>& obj)
- override;
- ::ndk::ScopedAStatus getCameraList(
- std::vector<::aidl::android::hardware::automotive::evs::CameraDesc>* list) override;
- ::ndk::ScopedAStatus getStreamList(
- const ::aidl::android::hardware::automotive::evs::CameraDesc& desc,
- std::vector<::aidl::android::hardware::automotive::evs::Stream>* _aidl_return) override;
- ::ndk::ScopedAStatus openDisplay(
- int32_t displayId,
- std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>* obj) override;
- ::ndk::ScopedAStatus closeDisplay(
- const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay>& obj)
- override;
- ::ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
- ::ndk::ScopedAStatus getDisplayState(
- ::aidl::android::hardware::automotive::evs::DisplayState* state) override;
- ::ndk::ScopedAStatus registerStatusCallback(
- const std::shared_ptr<
- ::aidl::android::hardware::automotive::evs::IEvsEnumeratorStatusCallback>&
- callback) override;
- ::ndk::ScopedAStatus openUltrasonicsArray(
- const std::string& id,
- std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray>* obj)
- override;
- ::ndk::ScopedAStatus closeUltrasonicsArray(
- const std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsUltrasonicsArray>&
- arr) override;
- ::ndk::ScopedAStatus getUltrasonicsArrayList(
- std::vector<::aidl::android::hardware::automotive::evs::UltrasonicsArrayDesc>* list)
- override;
-};
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
-
-#endif // android_hardware_automotive_evs_aidl_impl_evshal_include_DefaultEvsHal_H_
diff --git a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
new file mode 100644
index 0000000..259c266
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
@@ -0,0 +1,137 @@
+/*
+ * 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 "ConfigManager.h"
+#include "EvsGlDisplay.h"
+#include "EvsMockCamera.h"
+
+#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
+#include <aidl/android/hardware/automotive/evs/BnEvsEnumerator.h>
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/DeviceStatusType.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/IEvsEnumeratorStatusCallback.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+#include <utils/Thread.h>
+
+#include <atomic>
+#include <mutex>
+#include <optional>
+#include <thread>
+#include <unordered_map>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsEnumerator final : public ::aidl::android::hardware::automotive::evs::BnEvsEnumerator {
+ public:
+ // Methods from ::aidl::android::hardware::automotive::evs::IEvsEnumerator
+ ndk::ScopedAStatus isHardware(bool* flag) override;
+ ndk::ScopedAStatus openCamera(const std::string& cameraId, const evs::Stream& streamConfig,
+ std::shared_ptr<evs::IEvsCamera>* obj) override;
+ ndk::ScopedAStatus closeCamera(const std::shared_ptr<evs::IEvsCamera>& obj) override;
+ ndk::ScopedAStatus getCameraList(std::vector<evs::CameraDesc>* _aidl_return) override;
+ ndk::ScopedAStatus getStreamList(const evs::CameraDesc& desc,
+ std::vector<evs::Stream>* _aidl_return) override;
+ ndk::ScopedAStatus openDisplay(int32_t displayId,
+ std::shared_ptr<evs::IEvsDisplay>* obj) override;
+ ndk::ScopedAStatus closeDisplay(const std::shared_ptr<evs::IEvsDisplay>& obj) override;
+ ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
+ ndk::ScopedAStatus getDisplayState(evs::DisplayState* state) override;
+ ndk::ScopedAStatus getDisplayStateById(int32_t displayId, evs::DisplayState* state) override;
+ ndk::ScopedAStatus registerStatusCallback(
+ const std::shared_ptr<evs::IEvsEnumeratorStatusCallback>& callback) override;
+ ndk::ScopedAStatus openUltrasonicsArray(
+ const std::string& id, std::shared_ptr<evs::IEvsUltrasonicsArray>* obj) override;
+ ndk::ScopedAStatus closeUltrasonicsArray(
+ const std::shared_ptr<evs::IEvsUltrasonicsArray>& obj) override;
+ ndk::ScopedAStatus getUltrasonicsArrayList(
+ std::vector<evs::UltrasonicsArrayDesc>* list) override;
+
+ // Implementation details
+ EvsEnumerator(const std::shared_ptr<
+ ::aidl::android::frameworks::automotive::display::ICarDisplayProxy>&
+ proxyService);
+
+ void notifyDeviceStatusChange(const std::string_view& deviceName, evs::DeviceStatusType type);
+
+ private:
+ struct CameraRecord {
+ evs::CameraDesc desc;
+ std::weak_ptr<EvsMockCamera> activeInstance;
+
+ CameraRecord(const char* cameraId) : desc() { desc.id = cameraId; }
+ };
+
+ class ActiveDisplays {
+ public:
+ struct DisplayInfo {
+ int32_t id{-1};
+ std::weak_ptr<EvsGlDisplay> displayWeak;
+ uintptr_t internalDisplayRawAddr;
+ };
+
+ std::optional<DisplayInfo> popDisplay(int32_t id);
+
+ std::optional<DisplayInfo> popDisplay(const std::shared_ptr<IEvsDisplay>& display);
+
+ std::unordered_map<int32_t, DisplayInfo> getAllDisplays();
+
+ bool tryInsert(int32_t id, const std::shared_ptr<EvsGlDisplay>& display);
+
+ private:
+ std::mutex mMutex;
+ std::unordered_map<int32_t, DisplayInfo> mIdToDisplay GUARDED_BY(mMutex);
+ std::unordered_map<uintptr_t, int32_t> mDisplayToId GUARDED_BY(mMutex);
+ };
+
+ bool checkPermission();
+ void closeCamera_impl(const std::shared_ptr<evs::IEvsCamera>& pCamera,
+ const std::string& cameraId);
+ ndk::ScopedAStatus getDisplayStateImpl(std::optional<int32_t> displayId,
+ evs::DisplayState* state);
+
+ static bool qualifyCaptureDevice(const char* deviceName);
+ static CameraRecord* findCameraById(const std::string& cameraId);
+ static void enumerateCameras();
+ static bool addCaptureDevice(const std::string& deviceName);
+ static bool removeCaptureDevice(const std::string& deviceName);
+ // Enumerate available displays and return an id of the internal display
+ static uint64_t enumerateDisplays();
+
+ static ActiveDisplays& mutableActiveDisplays();
+
+ // NOTE: All members values are static so that all clients operate on the same state
+ // That is to say, this is effectively a singleton despite the fact that HIDL
+ // constructs a new instance for each client.
+ // Because our server has a single thread in the thread pool, these values are
+ // never accessed concurrently despite potentially having multiple instance objects
+ // using them.
+ static std::unordered_map<std::string, CameraRecord> sCameraList;
+ // Object destructs if client dies.
+ static std::mutex sLock; // Mutex on shared camera device list.
+ static std::condition_variable sCameraSignal; // Signal on camera device addition.
+ static std::unique_ptr<ConfigManager> sConfigManager; // ConfigManager
+ static std::shared_ptr<::aidl::android::frameworks::automotive::display::ICarDisplayProxy>
+ sDisplayProxy;
+ static std::unordered_map<uint8_t, uint64_t> sDisplayPortList;
+
+ uint64_t mInternalDisplayId;
+ std::shared_ptr<evs::IEvsEnumeratorStatusCallback> mCallback;
+};
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
new file mode 100644
index 0000000..ceabd9e
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsGlDisplay.h
@@ -0,0 +1,89 @@
+/*
+ * 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 "GlWrapper.h"
+
+#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
+#include <aidl/android/hardware/automotive/evs/BnEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/DisplayDesc.h>
+#include <aidl/android/hardware/automotive/evs/DisplayState.h>
+
+#include <thread>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsGlDisplay final : public BnEvsDisplay {
+ public:
+ // Methods from ::aidl::android::hardware::automotive::evs::IEvsDisplay
+ // follow.
+ ndk::ScopedAStatus getDisplayInfo(evs::DisplayDesc* _aidl_return) override;
+ ndk::ScopedAStatus getDisplayState(evs::DisplayState* _aidl_return) override;
+ ndk::ScopedAStatus getTargetBuffer(evs::BufferDesc* _aidl_return) override;
+ ndk::ScopedAStatus returnTargetBufferForDisplay(const evs::BufferDesc& buffer) override;
+ ndk::ScopedAStatus setDisplayState(evs::DisplayState state) override;
+
+ // Implementation details
+ EvsGlDisplay(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& service,
+ uint64_t displayId);
+ virtual ~EvsGlDisplay() override;
+
+ // This gets called if another caller "steals" ownership of the display
+ void forceShutdown();
+
+ private:
+ // A graphics buffer into which we'll store images. This member variable
+ // will be protected by semaphores.
+ struct BufferRecord {
+ ::aidl::android::hardware::graphics::common::HardwareBufferDescription description;
+ buffer_handle_t handle;
+ int fingerprint;
+ } mBuffer;
+
+ // State of a rendering thread
+ enum RenderThreadStates {
+ STOPPED = 0,
+ STOPPING = 1,
+ RUN = 2,
+ };
+
+ uint64_t mDisplayId;
+ evs::DisplayDesc mInfo;
+ evs::DisplayState mRequestedState GUARDED_BY(mLock) = evs::DisplayState::NOT_VISIBLE;
+ std::shared_ptr<automotivedisplay::ICarDisplayProxy> mDisplayProxy;
+
+ GlWrapper mGlWrapper;
+ mutable std::mutex mLock;
+
+ // This tells us whether or not our buffer is in use. Protected by
+ // semaphores.
+ bool mBufferBusy = false;
+
+ // Variables to synchronize a rendering thread w/ main and binder threads
+ std::thread mRenderThread;
+ RenderThreadStates mState GUARDED_BY(mLock) = STOPPED;
+ bool mBufferReady = false;
+ void renderFrames();
+ bool initializeGlContextLocked() REQUIRES(mLock);
+
+ std::condition_variable mBufferReadyToUse;
+ std::condition_variable mBufferReadyToRender;
+ std::condition_variable mBufferDone;
+};
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
new file mode 100644
index 0000000..7e010a2
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
@@ -0,0 +1,166 @@
+/*
+ * 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 "ConfigManager.h"
+
+#include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <aidl/android/hardware/automotive/evs/CameraDesc.h>
+#include <aidl/android/hardware/automotive/evs/CameraParam.h>
+#include <aidl/android/hardware/automotive/evs/EvsResult.h>
+#include <aidl/android/hardware/automotive/evs/IEvsCameraStream.h>
+#include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
+#include <aidl/android/hardware/automotive/evs/ParameterRange.h>
+#include <aidl/android/hardware/automotive/evs/Stream.h>
+// #include <android-base/result.h>
+#include <android/hardware_buffer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <functional>
+#include <thread>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+class EvsMockCamera : public evs::BnEvsCamera {
+ // This prevents constructors from direct access while it allows this class to
+ // be instantiated via ndk::SharedRefBase::make<>.
+ private:
+ struct Sigil {
+ explicit Sigil() = default;
+ };
+
+ public:
+ // Methods from ::android::hardware::automotive::evs::IEvsCamera follow.
+ ndk::ScopedAStatus doneWithFrame(const std::vector<evs::BufferDesc>& buffers) override;
+ ndk::ScopedAStatus forcePrimaryClient(
+ const std::shared_ptr<evs::IEvsDisplay>& display) override;
+ ndk::ScopedAStatus getCameraInfo(evs::CameraDesc* _aidl_return) override;
+ ndk::ScopedAStatus getExtendedInfo(int32_t opaqueIdentifier,
+ std::vector<uint8_t>* value) override;
+ ndk::ScopedAStatus getIntParameter(evs::CameraParam id, std::vector<int32_t>* value) override;
+ ndk::ScopedAStatus getIntParameterRange(evs::CameraParam id,
+ evs::ParameterRange* _aidl_return) override;
+ ndk::ScopedAStatus getParameterList(std::vector<evs::CameraParam>* _aidl_return) override;
+ ndk::ScopedAStatus getPhysicalCameraInfo(const std::string& deviceId,
+ evs::CameraDesc* _aidl_return) override;
+ ndk::ScopedAStatus importExternalBuffers(const std::vector<evs::BufferDesc>& buffers,
+ int32_t* _aidl_return) override;
+ ndk::ScopedAStatus pauseVideoStream() override;
+ ndk::ScopedAStatus resumeVideoStream() override;
+ ndk::ScopedAStatus setExtendedInfo(int32_t opaqueIdentifier,
+ const std::vector<uint8_t>& opaqueValue) override;
+ ndk::ScopedAStatus setIntParameter(evs::CameraParam id, int32_t value,
+ std::vector<int32_t>* effectiveValue) override;
+ ndk::ScopedAStatus setPrimaryClient() override;
+ ndk::ScopedAStatus setMaxFramesInFlight(int32_t bufferCount) override;
+ ndk::ScopedAStatus startVideoStream(
+ const std::shared_ptr<evs::IEvsCameraStream>& receiver) override;
+ ndk::ScopedAStatus stopVideoStream() override;
+ ndk::ScopedAStatus unsetPrimaryClient() override;
+
+ static std::shared_ptr<EvsMockCamera> Create(const char* deviceName);
+ static std::shared_ptr<EvsMockCamera> Create(
+ const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
+ const evs::Stream* streamCfg = nullptr);
+ EvsMockCamera(const EvsMockCamera&) = delete;
+ EvsMockCamera& operator=(const EvsMockCamera&) = delete;
+
+ virtual ~EvsMockCamera() override;
+ void shutdown();
+
+ const evs::CameraDesc& getDesc() { return mDescription; }
+
+ // Constructors
+ EvsMockCamera(Sigil sigil, const char* deviceName,
+ std::unique_ptr<ConfigManager::CameraInfo>& camInfo);
+
+ private:
+ // These three functions are expected to be called while mAccessLock is held
+ bool setAvailableFrames_Locked(unsigned bufferCount);
+ unsigned increaseAvailableFrames_Locked(unsigned numToAdd);
+ unsigned decreaseAvailableFrames_Locked(unsigned numToRemove);
+
+ void generateFrames();
+ void fillMockFrame(buffer_handle_t handle, const AHardwareBuffer_Desc* pDesc);
+ void returnBufferLocked(const uint32_t bufferId);
+ ndk::ScopedAStatus stopVideoStream_impl();
+
+ CameraDesc mDescription = {}; // The properties of this camera
+
+ std::thread mCaptureThread; // The thread we'll use to synthesize frames
+
+ // The callback used to deliver each frame
+ std::shared_ptr<evs::IEvsCameraStream> mStream;
+
+ // Horizontal pixel count in the buffers
+ uint32_t mWidth = 0;
+ // Vertical pixel count in the buffers
+ uint32_t mHeight = 0;
+ // Values from android_pixel_format_t
+ uint32_t mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ // Values from from Gralloc.h
+ uint64_t mUsage =
+ GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
+ // Bytes per line in the buffers
+ uint32_t mStride = 0;
+
+ struct BufferRecord {
+ buffer_handle_t handle;
+ bool inUse;
+
+ explicit BufferRecord(buffer_handle_t h) : handle(h), inUse(false){};
+ };
+
+ std::vector<BufferRecord> mBuffers; // Graphics buffers to transfer images
+ unsigned mFramesAllowed; // How many buffers are we currently using
+ unsigned mFramesInUse; // How many buffers are currently outstanding
+
+ enum StreamStateValues {
+ STOPPED,
+ RUNNING,
+ STOPPING,
+ DEAD,
+ };
+ StreamStateValues mStreamState;
+
+ // Synchronization necessary to deconflict mCaptureThread from the main service thread
+ std::mutex mAccessLock;
+
+ // Static camera module information
+ std::unique_ptr<ConfigManager::CameraInfo>& mCameraInfo;
+
+ // For the extended info
+ std::unordered_map<uint32_t, std::vector<uint8_t>> mExtInfo;
+
+ // For the camera parameters.
+ struct CameraParameterDesc {
+ CameraParameterDesc(int min = 0, int max = 0, int step = 0, int value = 0) {
+ this->range.min = min;
+ this->range.max = max;
+ this->range.step = step;
+ this->value = value;
+ }
+
+ ParameterRange range;
+ int32_t value;
+ };
+ std::unordered_map<CameraParam, std::shared_ptr<CameraParameterDesc>> mParams;
+ void initializeParameters();
+};
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/include/GlWrapper.h b/automotive/evs/aidl/impl/default/include/GlWrapper.h
new file mode 100644
index 0000000..adb250c
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/include/GlWrapper.h
@@ -0,0 +1,79 @@
+/*
+ * 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 <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#include <aidl/android/frameworks/automotive/display/ICarDisplayProxy.h>
+#include <aidl/android/hardware/automotive/evs/BufferDesc.h>
+#include <android-base/logging.h>
+#include <bufferqueueconverter/BufferQueueConverter.h>
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+namespace automotivedisplay = ::aidl::android::frameworks::automotive::display;
+
+class GlWrapper {
+ public:
+ GlWrapper() : mSurfaceHolder(::android::SurfaceHolderUniquePtr(nullptr, nullptr)) {}
+ bool initialize(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
+ uint64_t displayId);
+ void shutdown();
+
+ bool updateImageTexture(
+ buffer_handle_t handle,
+ const ::aidl::android::hardware::graphics::common::HardwareBufferDescription&
+ description);
+ void renderImageToScreen();
+
+ void showWindow(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
+ uint64_t displayId);
+ void hideWindow(const std::shared_ptr<automotivedisplay::ICarDisplayProxy>& svc,
+ uint64_t displayId);
+
+ unsigned getWidth() { return mWidth; };
+ unsigned getHeight() { return mHeight; };
+
+ private:
+ ::android::sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
+ mGfxBufferProducer;
+
+ EGLDisplay mDisplay;
+ EGLSurface mSurface;
+ EGLContext mContext;
+
+ unsigned mWidth = 0;
+ unsigned mHeight = 0;
+
+ EGLImageKHR mKHRimage = EGL_NO_IMAGE_KHR;
+
+ GLuint mTextureMap = 0;
+ GLuint mShaderProgram = 0;
+
+ // Opaque handle for a native hardware buffer defined in
+ // frameworks/native/opengl/include/EGL/eglplatform.h
+ ANativeWindow* mWindow;
+
+ // Pointer to a Surface wrapper.
+ ::android::SurfaceHolderUniquePtr mSurfaceHolder;
+};
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
new file mode 100644
index 0000000..50692f7
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.evs</name>
+ <fqname>IEvsEnumerator/hw/0</fqname>
+ <version>1</version>
+ </hal>
+</manifest>
diff --git a/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
new file mode 100644
index 0000000..6cbc18e
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
@@ -0,0 +1,68 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Exterior View System Example Configuration
+
+ Android Automotive axes are used to define coordinates.
+ See https://source.android.com/devices/sensors/sensor-types#auto_axes
+
+ Use evs_configuration.dtd with xmllint tool, to validate XML configuration file
+-->
+
+<configuration>
+ <!-- system configuration -->
+ <system>
+ <!-- number of cameras available to EVS -->
+ <num_cameras value='1'/>
+ </system>
+
+ <!-- camera information -->
+ <camera>
+ <!-- camera device starts -->
+ <device id='/dev/video10' position='rear'>
+ <caps>
+ <!-- list of supported controls -->
+ <supported_controls>
+ <control name='BRIGHTNESS' min='0' max='255'/>
+ <control name='CONTRAST' min='0' max='255'/>
+ </supported_controls>
+
+ <stream id='0' width='640' height='360' format='RGBA_8888' framerate='30'/>
+ </caps>
+
+ <!-- list of parameters -->
+ <characteristics>
+ <!-- Camera intrinsic calibration matrix. See
+ https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#LENS_INTRINSIC_CALIBRATION
+ -->
+ <parameter
+ name='LENS_INTRINSIC_CALIBRATION'
+ type='float'
+ size='5'
+ value='0.0,0.0,0.0,0.0,0.0'
+ />
+ </characteristics>
+ </device>
+ </camera>
+ <display>
+ <device id='display0' position='driver'>
+ <caps>
+ <!-- list of supported inpu stream configurations -->
+ <stream id='0' width='1280' height='720' format='RGBA_8888' framerate='30'/>
+ </caps>
+ </device>
+ </display>
+</configuration>
+
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
new file mode 100644
index 0000000..da791ed
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -0,0 +1,992 @@
+/*
+ * 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 "ConfigManager.h"
+
+#include <android-base/parseint.h>
+#include <hardware/gralloc.h>
+#include <utils/SystemClock.h>
+
+#include <fstream>
+#include <sstream>
+#include <string_view>
+#include <thread>
+
+namespace {
+
+using ::aidl::android::hardware::automotive::evs::CameraParam;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::tinyxml2::XMLAttribute;
+using ::tinyxml2::XMLDocument;
+using ::tinyxml2::XMLElement;
+
+} // namespace
+
+std::string_view ConfigManager::sConfigDefaultPath =
+ "/vendor/etc/automotive/evs/evs_mock_hal_configuration.xml";
+std::string_view ConfigManager::sConfigOverridePath =
+ "/vendor/etc/automotive/evs/evs_configuration_override.xml";
+
+void ConfigManager::printElementNames(const XMLElement* rootElem, const std::string& prefix) const {
+ const XMLElement* curElem = rootElem;
+
+ while (curElem != nullptr) {
+ LOG(VERBOSE) << "[ELEM] " << prefix << curElem->Name();
+ const XMLAttribute* curAttr = curElem->FirstAttribute();
+ while (curAttr) {
+ LOG(VERBOSE) << "[ATTR] " << prefix << curAttr->Name() << ": " << curAttr->Value();
+ curAttr = curAttr->Next();
+ }
+
+ /* recursively go down to descendants */
+ printElementNames(curElem->FirstChildElement(), prefix + "\t");
+
+ curElem = curElem->NextSiblingElement();
+ }
+}
+
+void ConfigManager::readCameraInfo(const XMLElement* const aCameraElem) {
+ if (aCameraElem == nullptr) {
+ LOG(WARNING) << "XML file does not have required camera element";
+ return;
+ }
+
+ const XMLElement* curElem = aCameraElem->FirstChildElement();
+ while (curElem != nullptr) {
+ if (!strcmp(curElem->Name(), "group")) {
+ /* camera group identifier */
+ const char* id = curElem->FindAttribute("id")->Value();
+
+ /* create a camera group to be filled */
+ CameraGroupInfo* aCamera = new CameraGroupInfo();
+
+ /* read camera device information */
+ if (!readCameraDeviceInfo(aCamera, curElem)) {
+ LOG(WARNING) << "Failed to read a camera information of " << id;
+ delete aCamera;
+ continue;
+ }
+
+ /* camera group synchronization */
+ const char* sync = curElem->FindAttribute("synchronized")->Value();
+ if (!strcmp(sync, "CALIBRATED")) {
+ aCamera->synchronized = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED;
+ } else if (!strcmp(sync, "APPROXIMATE")) {
+ aCamera->synchronized = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE;
+ } else {
+ aCamera->synchronized = 0; // Not synchronized
+ }
+
+ /* add a group to hash map */
+ mCameraGroups.insert_or_assign(id, std::unique_ptr<CameraGroupInfo>(aCamera));
+ } else if (!std::strcmp(curElem->Name(), "device")) {
+ /* camera unique identifier */
+ const char* id = curElem->FindAttribute("id")->Value();
+
+ /* camera mount location */
+ const char* pos = curElem->FindAttribute("position")->Value();
+
+ /* create a camera device to be filled */
+ CameraInfo* aCamera = new CameraInfo();
+
+ /* read camera device information */
+ if (!readCameraDeviceInfo(aCamera, curElem)) {
+ LOG(WARNING) << "Failed to read a camera information of " << id;
+ delete aCamera;
+ continue;
+ }
+
+ /* store read camera module information */
+ mCameraInfo.insert_or_assign(id, std::unique_ptr<CameraInfo>(aCamera));
+
+ /* assign a camera device to a position group */
+ mCameraPosition[pos].insert(id);
+ } else {
+ /* ignore other device types */
+ LOG(DEBUG) << "Unknown element " << curElem->Name() << " is ignored";
+ }
+
+ curElem = curElem->NextSiblingElement();
+ }
+}
+
+bool ConfigManager::readCameraDeviceInfo(CameraInfo* aCamera, const XMLElement* aDeviceElem) {
+ if (aCamera == nullptr || aDeviceElem == nullptr) {
+ return false;
+ }
+
+ /* size information to allocate camera_metadata_t */
+ size_t totalEntries = 0;
+ size_t totalDataSize = 0;
+
+ /* read device capabilities */
+ totalEntries +=
+ readCameraCapabilities(aDeviceElem->FirstChildElement("caps"), aCamera, totalDataSize);
+
+ /* read camera metadata */
+ totalEntries += readCameraMetadata(aDeviceElem->FirstChildElement("characteristics"), aCamera,
+ totalDataSize);
+
+ /* construct camera_metadata_t */
+ if (!constructCameraMetadata(aCamera, totalEntries, totalDataSize)) {
+ LOG(WARNING) << "Either failed to allocate memory or "
+ << "allocated memory was not large enough";
+ }
+
+ return true;
+}
+
+size_t ConfigManager::readCameraCapabilities(const XMLElement* const aCapElem, CameraInfo* aCamera,
+ size_t& dataSize) {
+ if (aCapElem == nullptr || aCamera == nullptr) {
+ return 0;
+ }
+
+ std::string token;
+ const XMLElement* curElem = nullptr;
+
+ /* a list of supported camera parameters/controls */
+ curElem = aCapElem->FirstChildElement("supported_controls");
+ if (curElem != nullptr) {
+ const XMLElement* ctrlElem = curElem->FirstChildElement("control");
+ while (ctrlElem != nullptr) {
+ const char* nameAttr = ctrlElem->FindAttribute("name")->Value();
+ int32_t minVal = INT32_MIN, maxVal = INT32_MAX;
+ if (!android::base::ParseInt(ctrlElem->FindAttribute("min")->Value(), &minVal)) {
+ LOG(WARNING) << "Failed to parse " << ctrlElem->FindAttribute("min")->Value();
+ }
+
+ if (!android::base::ParseInt(ctrlElem->FindAttribute("max")->Value(), &maxVal)) {
+ LOG(WARNING) << "Failed to parse " << ctrlElem->FindAttribute("max")->Value();
+ }
+
+ int32_t stepVal = 1;
+ const XMLAttribute* stepAttr = ctrlElem->FindAttribute("step");
+ if (stepAttr != nullptr) {
+ if (!android::base::ParseInt(stepAttr->Value(), &stepVal)) {
+ LOG(WARNING) << "Failed to parse " << stepAttr->Value();
+ }
+ }
+
+ CameraParam aParam;
+ if (ConfigManagerUtil::convertToEvsCameraParam(nameAttr, aParam)) {
+ aCamera->controls.insert_or_assign(
+ aParam, std::move(std::make_tuple(minVal, maxVal, stepVal)));
+ }
+
+ ctrlElem = ctrlElem->NextSiblingElement("control");
+ }
+ }
+
+ /* a list of camera stream configurations */
+ curElem = aCapElem->FirstChildElement("stream");
+ while (curElem != nullptr) {
+ /* read 5 attributes */
+ const XMLAttribute* idAttr = curElem->FindAttribute("id");
+ const XMLAttribute* widthAttr = curElem->FindAttribute("width");
+ const XMLAttribute* heightAttr = curElem->FindAttribute("height");
+ const XMLAttribute* fmtAttr = curElem->FindAttribute("format");
+ const XMLAttribute* fpsAttr = curElem->FindAttribute("framerate");
+
+ int32_t id = -1;
+ int32_t framerate = 0;
+ if (!android::base::ParseInt(idAttr->Value(), &id)) {
+ LOG(WARNING) << "Failed to parse " << idAttr->Value();
+ }
+ if (fpsAttr != nullptr) {
+ if (!android::base::ParseInt(fpsAttr->Value(), &framerate)) {
+ LOG(WARNING) << "Failed to parse " << fpsAttr->Value();
+ }
+ }
+
+ PixelFormat format = PixelFormat::UNSPECIFIED;
+ if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), format)) {
+ StreamConfiguration cfg = {
+ .id = id,
+ .format = format,
+ .type = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+ .framerate = framerate,
+ };
+
+ if (!android::base::ParseInt(widthAttr->Value(), &cfg.width) ||
+ !android::base::ParseInt(heightAttr->Value(), &cfg.height)) {
+ LOG(WARNING) << "Failed to parse " << widthAttr->Value() << " and "
+ << heightAttr->Value();
+ }
+ aCamera->streamConfigurations.insert_or_assign(id, cfg);
+ }
+
+ curElem = curElem->NextSiblingElement("stream");
+ }
+
+ dataSize = calculate_camera_metadata_entry_data_size(
+ get_camera_metadata_tag_type(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS),
+ aCamera->streamConfigurations.size() * sizeof(StreamConfiguration));
+
+ /* a single camera metadata entry contains multiple stream configurations */
+ return dataSize > 0 ? 1 : 0;
+}
+
+size_t ConfigManager::readCameraMetadata(const XMLElement* const aParamElem, CameraInfo* aCamera,
+ size_t& dataSize) {
+ if (aParamElem == nullptr || aCamera == nullptr) {
+ return 0;
+ }
+
+ const XMLElement* curElem = aParamElem->FirstChildElement("parameter");
+ size_t numEntries = 0;
+ camera_metadata_tag_t tag;
+ while (curElem != nullptr) {
+ if (ConfigManagerUtil::convertToMetadataTag(curElem->FindAttribute("name")->Value(), tag)) {
+ switch (tag) {
+ case ANDROID_LENS_DISTORTION:
+ case ANDROID_LENS_POSE_ROTATION:
+ case ANDROID_LENS_POSE_TRANSLATION:
+ case ANDROID_LENS_INTRINSIC_CALIBRATION: {
+ /* float[] */
+ size_t count = 0;
+ void* data = ConfigManagerUtil::convertFloatArray(
+ curElem->FindAttribute("size")->Value(),
+ curElem->FindAttribute("value")->Value(), count);
+
+ aCamera->cameraMetadata.insert_or_assign(tag, std::make_pair(data, count));
+
+ ++numEntries;
+ dataSize += calculate_camera_metadata_entry_data_size(
+ get_camera_metadata_tag_type(tag), count);
+
+ break;
+ }
+
+ case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: {
+ camera_metadata_enum_android_request_available_capabilities_t* data =
+ new camera_metadata_enum_android_request_available_capabilities_t[1];
+ if (ConfigManagerUtil::convertToCameraCapability(
+ curElem->FindAttribute("value")->Value(), *data)) {
+ aCamera->cameraMetadata.insert_or_assign(tag,
+ std::make_pair((void*)data, 1));
+
+ ++numEntries;
+ dataSize += calculate_camera_metadata_entry_data_size(
+ get_camera_metadata_tag_type(tag), 1);
+ }
+ break;
+ }
+
+ case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: {
+ /* a comma-separated list of physical camera devices */
+ size_t len = strlen(curElem->FindAttribute("value")->Value());
+ char* data = new char[len + 1];
+ memcpy(data, curElem->FindAttribute("value")->Value(), len * sizeof(char));
+
+ /* replace commas with null char */
+ char* p = data;
+ while (*p != '\0') {
+ if (*p == ',') {
+ *p = '\0';
+ }
+ ++p;
+ }
+
+ aCamera->cameraMetadata.insert_or_assign(tag,
+ std::make_pair((void*)data, len + 1));
+
+ ++numEntries;
+ dataSize += calculate_camera_metadata_entry_data_size(
+ get_camera_metadata_tag_type(tag), len);
+ break;
+ }
+
+ /* TODO(b/140416878): add vendor-defined/custom tag support */
+ default:
+ LOG(WARNING) << "Parameter " << curElem->FindAttribute("name")->Value()
+ << " is not supported";
+ break;
+ }
+ } else {
+ LOG(WARNING) << "Unsupported metadata tag " << curElem->FindAttribute("name")->Value()
+ << " is found.";
+ }
+
+ curElem = curElem->NextSiblingElement("parameter");
+ }
+
+ return numEntries;
+}
+
+bool ConfigManager::constructCameraMetadata(CameraInfo* aCamera, size_t totalEntries,
+ size_t totalDataSize) {
+ if (aCamera == nullptr || !aCamera->allocate(totalEntries, totalDataSize)) {
+ LOG(ERROR) << "Failed to allocate memory for camera metadata";
+ return false;
+ }
+
+ const size_t numStreamConfigs = aCamera->streamConfigurations.size();
+ std::unique_ptr<int32_t[]> data(new int32_t[sizeof(StreamConfiguration) * numStreamConfigs]);
+ int32_t* ptr = data.get();
+ for (auto& cfg : aCamera->streamConfigurations) {
+ memcpy(ptr, &cfg.second, sizeof(StreamConfiguration));
+ ptr += sizeof(StreamConfiguration);
+ }
+ int32_t err = add_camera_metadata_entry(
+ aCamera->characteristics, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, data.get(),
+ numStreamConfigs * sizeof(StreamConfiguration));
+
+ if (err) {
+ LOG(ERROR) << "Failed to add stream configurations to metadata, ignored";
+ return false;
+ }
+
+ bool success = true;
+ for (auto& [tag, entry] : aCamera->cameraMetadata) {
+ /* try to add new camera metadata entry */
+ int32_t err =
+ add_camera_metadata_entry(aCamera->characteristics, tag, entry.first, entry.second);
+ if (err) {
+ LOG(ERROR) << "Failed to add an entry with a tag, " << std::hex << tag;
+
+ /* may exceed preallocated capacity */
+ LOG(ERROR) << "Camera metadata has "
+ << get_camera_metadata_entry_count(aCamera->characteristics) << " / "
+ << get_camera_metadata_entry_capacity(aCamera->characteristics)
+ << " entries and "
+ << get_camera_metadata_data_count(aCamera->characteristics) << " / "
+ << get_camera_metadata_data_capacity(aCamera->characteristics)
+ << " bytes are filled.";
+ LOG(ERROR) << "\tCurrent metadata entry requires "
+ << calculate_camera_metadata_entry_data_size(tag, entry.second) << " bytes.";
+
+ success = false;
+ }
+ }
+
+ LOG(VERBOSE) << "Camera metadata has "
+ << get_camera_metadata_entry_count(aCamera->characteristics) << " / "
+ << get_camera_metadata_entry_capacity(aCamera->characteristics) << " entries and "
+ << get_camera_metadata_data_count(aCamera->characteristics) << " / "
+ << get_camera_metadata_data_capacity(aCamera->characteristics)
+ << " bytes are filled.";
+ return success;
+}
+
+void ConfigManager::readSystemInfo(const XMLElement* const aSysElem) {
+ if (aSysElem == nullptr) {
+ return;
+ }
+
+ /*
+ * Please note that this function assumes that a given system XML element
+ * and its child elements follow DTD. If it does not, it will cause a
+ * segmentation fault due to the failure of finding expected attributes.
+ */
+
+ /* read number of cameras available in the system */
+ const XMLElement* xmlElem = aSysElem->FirstChildElement("num_cameras");
+ if (xmlElem != nullptr) {
+ if (!android::base::ParseInt(xmlElem->FindAttribute("value")->Value(),
+ &mSystemInfo.numCameras)) {
+ LOG(WARNING) << "Failed to parse " << xmlElem->FindAttribute("value")->Value();
+ }
+ }
+}
+
+void ConfigManager::readDisplayInfo(const XMLElement* const aDisplayElem) {
+ if (aDisplayElem == nullptr) {
+ LOG(WARNING) << "XML file does not have required camera element";
+ return;
+ }
+
+ const XMLElement* curDev = aDisplayElem->FirstChildElement("device");
+ while (curDev != nullptr) {
+ const char* id = curDev->FindAttribute("id")->Value();
+ std::unique_ptr<DisplayInfo> dpy(new DisplayInfo());
+ if (dpy == nullptr) {
+ LOG(ERROR) << "Failed to allocate memory for DisplayInfo";
+ return;
+ }
+
+ const XMLElement* cap = curDev->FirstChildElement("caps");
+ if (cap != nullptr) {
+ const XMLElement* curStream = cap->FirstChildElement("stream");
+ while (curStream != nullptr) {
+ /* read 4 attributes */
+ const XMLAttribute* idAttr = curStream->FindAttribute("id");
+ const XMLAttribute* widthAttr = curStream->FindAttribute("width");
+ const XMLAttribute* heightAttr = curStream->FindAttribute("height");
+ const XMLAttribute* fmtAttr = curStream->FindAttribute("format");
+
+ int32_t id = -1;
+ if (!android::base::ParseInt(idAttr->Value(), &id)) {
+ LOG(WARNING) << "Failed to parse " << idAttr->Value();
+ }
+ PixelFormat format = PixelFormat::UNSPECIFIED;
+ if (ConfigManagerUtil::convertToPixelFormat(fmtAttr->Value(), format)) {
+ StreamConfiguration cfg = {
+ .id = id,
+ .format = format,
+ .type = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
+ };
+ if (!android::base::ParseInt(widthAttr->Value(), &cfg.width) ||
+ !android::base::ParseInt(heightAttr->Value(), &cfg.height)) {
+ LOG(WARNING) << "Failed to parse " << widthAttr->Value() << " and "
+ << heightAttr->Value();
+ }
+ dpy->streamConfigurations.insert_or_assign(id, cfg);
+ }
+
+ curStream = curStream->NextSiblingElement("stream");
+ }
+ }
+
+ mDisplayInfo.insert_or_assign(id, std::move(dpy));
+ curDev = curDev->NextSiblingElement("device");
+ }
+
+ return;
+}
+
+bool ConfigManager::readConfigDataFromXML() noexcept {
+ XMLDocument xmlDoc;
+
+ const int64_t parsingStart = android::elapsedRealtimeNano();
+
+ /* load and parse a configuration file */
+ xmlDoc.LoadFile(sConfigOverridePath.data());
+ if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
+ xmlDoc.LoadFile(sConfigDefaultPath.data());
+ if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
+ LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
+ return false;
+ }
+ }
+
+ /* retrieve the root element */
+ const XMLElement* rootElem = xmlDoc.RootElement();
+ if (std::strcmp(rootElem->Name(), "configuration") != 0) {
+ LOG(ERROR) << "A configuration file is not in the required format. "
+ << "See /etc/automotive/evs/evs_configuration.dtd";
+ return false;
+ }
+
+ std::unique_lock<std::mutex> lock(mConfigLock);
+
+ /*
+ * parse camera information; this needs to be done before reading system
+ * information
+ */
+ readCameraInfo(rootElem->FirstChildElement("camera"));
+
+ /* parse system information */
+ readSystemInfo(rootElem->FirstChildElement("system"));
+
+ /* parse display information */
+ readDisplayInfo(rootElem->FirstChildElement("display"));
+
+ /* configuration data is ready to be consumed */
+ mIsReady = true;
+
+ /* notify that configuration data is ready */
+ lock.unlock();
+ mConfigCond.notify_all();
+
+ const int64_t parsingEnd = android::elapsedRealtimeNano();
+ LOG(INFO) << "Parsing configuration file takes " << std::scientific
+ << (double)(parsingEnd - parsingStart) / 1000000.0 << " ms.";
+
+ return true;
+}
+
+bool ConfigManager::readConfigDataFromBinary() {
+ /* Temporary buffer to hold configuration data read from a binary file */
+ char mBuffer[1024];
+
+ std::fstream srcFile;
+ const int64_t readStart = android::elapsedRealtimeNano();
+
+ srcFile.open(mBinaryFilePath, std::fstream::in | std::fstream::binary);
+ if (!srcFile) {
+ LOG(ERROR) << "Failed to open a source binary file, " << mBinaryFilePath;
+ return false;
+ }
+
+ std::unique_lock<std::mutex> lock(mConfigLock);
+ mIsReady = false;
+
+ /* read configuration data into the internal buffer */
+ srcFile.read(mBuffer, sizeof(mBuffer));
+ LOG(VERBOSE) << __FUNCTION__ << ": " << srcFile.gcount() << " bytes are read.";
+ char* p = mBuffer;
+ size_t sz = 0;
+
+ /* read number of camera group information entries */
+ const size_t ngrps = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+
+ /* read each camera information entry */
+ for (size_t cidx = 0; cidx < ngrps; ++cidx) {
+ /* read camera identifier */
+ std::string cameraId = *(reinterpret_cast<std::string*>(p));
+ p += sizeof(std::string);
+
+ /* size of camera_metadata_t */
+ const size_t num_entry = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+ const size_t num_data = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+
+ /* create CameraInfo and add it to hash map */
+ std::unique_ptr<ConfigManager::CameraGroupInfo> aCamera;
+ if (aCamera == nullptr || !aCamera->allocate(num_entry, num_data)) {
+ LOG(ERROR) << "Failed to create new CameraInfo object";
+ mCameraInfo.clear();
+ return false;
+ }
+
+ /* controls */
+ typedef struct {
+ CameraParam cid;
+ int32_t min;
+ int32_t max;
+ int32_t step;
+ } CameraCtrl;
+ sz = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+ CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
+ for (size_t idx = 0; idx < sz; ++idx) {
+ CameraCtrl temp = *ptr++;
+ aCamera->controls.insert_or_assign(
+ temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+ }
+ p = reinterpret_cast<char*>(ptr);
+
+ /* stream configurations */
+ sz = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+ int32_t* i32_ptr = reinterpret_cast<int32_t*>(p);
+ for (size_t idx = 0; idx < sz; ++idx) {
+ const int32_t id = *i32_ptr++;
+
+ StreamConfiguration temp;
+ memcpy(&temp, i32_ptr, sizeof(StreamConfiguration));
+ i32_ptr += sizeof(StreamConfiguration);
+ aCamera->streamConfigurations.insert_or_assign(id, temp);
+ }
+ p = reinterpret_cast<char*>(i32_ptr);
+
+ /* synchronization */
+ aCamera->synchronized = *(reinterpret_cast<int32_t*>(p));
+ p += sizeof(int32_t);
+
+ for (size_t idx = 0; idx < num_entry; ++idx) {
+ /* Read camera metadata entries */
+ camera_metadata_tag_t tag = *reinterpret_cast<camera_metadata_tag_t*>(p);
+ p += sizeof(camera_metadata_tag_t);
+ const size_t count = *reinterpret_cast<size_t*>(p);
+ p += sizeof(size_t);
+
+ const int32_t type = get_camera_metadata_tag_type(tag);
+ switch (type) {
+ case TYPE_BYTE: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(uint8_t);
+ break;
+ }
+ case TYPE_INT32: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(int32_t);
+ break;
+ }
+ case TYPE_FLOAT: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(float);
+ break;
+ }
+ case TYPE_INT64: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(int64_t);
+ break;
+ }
+ case TYPE_DOUBLE: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(double);
+ break;
+ }
+ case TYPE_RATIONAL:
+ p += count * sizeof(camera_metadata_rational_t);
+ break;
+ default:
+ LOG(WARNING) << "Type " << type << " is unknown; "
+ << "data may be corrupted.";
+ break;
+ }
+ }
+
+ mCameraInfo.insert_or_assign(cameraId, std::move(aCamera));
+ }
+
+ /* read number of camera information entries */
+ const size_t ncams = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+
+ /* read each camera information entry */
+ for (size_t cidx = 0; cidx < ncams; ++cidx) {
+ /* read camera identifier */
+ std::string cameraId = *(reinterpret_cast<std::string*>(p));
+ p += sizeof(std::string);
+
+ /* size of camera_metadata_t */
+ const size_t num_entry = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+ const size_t num_data = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+
+ /* create CameraInfo and add it to hash map */
+ std::unique_ptr<ConfigManager::CameraInfo> aCamera;
+ if (aCamera == nullptr || !aCamera->allocate(num_entry, num_data)) {
+ LOG(ERROR) << "Failed to create new CameraInfo object";
+ mCameraInfo.clear();
+ return false;
+ }
+
+ /* controls */
+ typedef struct {
+ CameraParam cid;
+ int32_t min;
+ int32_t max;
+ int32_t step;
+ } CameraCtrl;
+ sz = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+ CameraCtrl* ptr = reinterpret_cast<CameraCtrl*>(p);
+ for (size_t idx = 0; idx < sz; ++idx) {
+ CameraCtrl temp = *ptr++;
+ aCamera->controls.insert_or_assign(
+ temp.cid, std::move(std::make_tuple(temp.min, temp.max, temp.step)));
+ }
+ p = reinterpret_cast<char*>(ptr);
+
+ /* stream configurations */
+ sz = *(reinterpret_cast<size_t*>(p));
+ p += sizeof(size_t);
+ int32_t* i32_ptr = reinterpret_cast<int32_t*>(p);
+ for (size_t idx = 0; idx < sz; ++idx) {
+ const int32_t id = *i32_ptr++;
+
+ StreamConfiguration temp;
+ memcpy(&temp, i32_ptr, sizeof(StreamConfiguration));
+ i32_ptr += sizeof(StreamConfiguration);
+ aCamera->streamConfigurations.insert_or_assign(id, temp);
+ }
+ p = reinterpret_cast<char*>(i32_ptr);
+
+ for (size_t idx = 0; idx < num_entry; ++idx) {
+ /* Read camera metadata entries */
+ camera_metadata_tag_t tag = *reinterpret_cast<camera_metadata_tag_t*>(p);
+ p += sizeof(camera_metadata_tag_t);
+ const size_t count = *reinterpret_cast<size_t*>(p);
+ p += sizeof(size_t);
+
+ const int32_t type = get_camera_metadata_tag_type(tag);
+ switch (type) {
+ case TYPE_BYTE: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(uint8_t);
+ break;
+ }
+ case TYPE_INT32: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(int32_t);
+ break;
+ }
+ case TYPE_FLOAT: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(float);
+ break;
+ }
+ case TYPE_INT64: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(int64_t);
+ break;
+ }
+ case TYPE_DOUBLE: {
+ add_camera_metadata_entry(aCamera->characteristics, tag, p, count);
+ p += count * sizeof(double);
+ break;
+ }
+ case TYPE_RATIONAL:
+ p += count * sizeof(camera_metadata_rational_t);
+ break;
+ default:
+ LOG(WARNING) << "Type " << type << " is unknown; "
+ << "data may be corrupted.";
+ break;
+ }
+ }
+
+ mCameraInfo.insert_or_assign(cameraId, std::move(aCamera));
+ }
+
+ mIsReady = true;
+
+ /* notify that configuration data is ready */
+ lock.unlock();
+ mConfigCond.notify_all();
+
+ int64_t readEnd = android::elapsedRealtimeNano();
+ LOG(INFO) << __FUNCTION__ << " takes " << std::scientific
+ << (double)(readEnd - readStart) / 1000000.0 << " ms.";
+
+ return true;
+}
+
+bool ConfigManager::writeConfigDataToBinary() {
+ std::fstream outFile;
+
+ const int64_t writeStart = android::elapsedRealtimeNano();
+
+ outFile.open(mBinaryFilePath, std::fstream::out | std::fstream::binary);
+ if (!outFile) {
+ LOG(ERROR) << "Failed to open a destination binary file, " << mBinaryFilePath;
+ return false;
+ }
+
+ /* lock a configuration data while it's being written to the filesystem */
+ std::lock_guard<std::mutex> lock(mConfigLock);
+
+ /* write camera group information */
+ size_t sz = mCameraGroups.size();
+ outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+ for (auto&& [camId, camInfo] : mCameraGroups) {
+ LOG(INFO) << "Storing camera group " << camId;
+
+ /* write a camera identifier string */
+ outFile.write(reinterpret_cast<const char*>(&camId), sizeof(std::string));
+
+ /* controls */
+ sz = camInfo->controls.size();
+ outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+ for (auto&& [ctrl, range] : camInfo->controls) {
+ outFile.write(reinterpret_cast<const char*>(&ctrl), sizeof(CameraParam));
+ outFile.write(reinterpret_cast<const char*>(&std::get<0>(range)), sizeof(int32_t));
+ outFile.write(reinterpret_cast<const char*>(&std::get<1>(range)), sizeof(int32_t));
+ outFile.write(reinterpret_cast<const char*>(&std::get<2>(range)), sizeof(int32_t));
+ }
+
+ /* stream configurations */
+ sz = camInfo->streamConfigurations.size();
+ outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+ for (auto&& [sid, cfg] : camInfo->streamConfigurations) {
+ outFile.write(reinterpret_cast<const char*>(sid), sizeof(int32_t));
+ outFile.write(reinterpret_cast<const char*>(&cfg), sizeof(cfg));
+ }
+
+ /* synchronization */
+ outFile.write(reinterpret_cast<const char*>(&camInfo->synchronized), sizeof(int32_t));
+
+ /* size of camera_metadata_t */
+ size_t num_entry = 0;
+ size_t num_data = 0;
+ if (camInfo->characteristics != nullptr) {
+ num_entry = get_camera_metadata_entry_count(camInfo->characteristics);
+ num_data = get_camera_metadata_data_count(camInfo->characteristics);
+ }
+ outFile.write(reinterpret_cast<const char*>(&num_entry), sizeof(size_t));
+ outFile.write(reinterpret_cast<const char*>(&num_data), sizeof(size_t));
+
+ /* write each camera metadata entry */
+ if (num_entry > 0) {
+ camera_metadata_entry_t entry;
+ for (size_t idx = 0; idx < num_entry; ++idx) {
+ if (get_camera_metadata_entry(camInfo->characteristics, idx, &entry)) {
+ LOG(ERROR) << "Failed to retrieve camera metadata entry " << idx;
+ outFile.close();
+ return false;
+ }
+
+ outFile.write(reinterpret_cast<const char*>(&entry.tag), sizeof(entry.tag));
+ outFile.write(reinterpret_cast<const char*>(&entry.count), sizeof(entry.count));
+
+ int32_t type = get_camera_metadata_tag_type(entry.tag);
+ switch (type) {
+ case TYPE_BYTE:
+ outFile.write(reinterpret_cast<const char*>(entry.data.u8),
+ sizeof(uint8_t) * entry.count);
+ break;
+ case TYPE_INT32:
+ outFile.write(reinterpret_cast<const char*>(entry.data.i32),
+ sizeof(int32_t) * entry.count);
+ break;
+ case TYPE_FLOAT:
+ outFile.write(reinterpret_cast<const char*>(entry.data.f),
+ sizeof(float) * entry.count);
+ break;
+ case TYPE_INT64:
+ outFile.write(reinterpret_cast<const char*>(entry.data.i64),
+ sizeof(int64_t) * entry.count);
+ break;
+ case TYPE_DOUBLE:
+ outFile.write(reinterpret_cast<const char*>(entry.data.d),
+ sizeof(double) * entry.count);
+ break;
+ case TYPE_RATIONAL:
+ [[fallthrough]];
+ default:
+ LOG(WARNING) << "Type " << type << " is not supported.";
+ break;
+ }
+ }
+ }
+ }
+
+ /* write camera device information */
+ sz = mCameraInfo.size();
+ outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+ for (auto&& [camId, camInfo] : mCameraInfo) {
+ LOG(INFO) << "Storing camera " << camId;
+
+ /* write a camera identifier string */
+ outFile.write(reinterpret_cast<const char*>(&camId), sizeof(std::string));
+
+ /* controls */
+ sz = camInfo->controls.size();
+ outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+ for (auto& [ctrl, range] : camInfo->controls) {
+ outFile.write(reinterpret_cast<const char*>(&ctrl), sizeof(CameraParam));
+ outFile.write(reinterpret_cast<const char*>(&std::get<0>(range)), sizeof(int32_t));
+ outFile.write(reinterpret_cast<const char*>(&std::get<1>(range)), sizeof(int32_t));
+ outFile.write(reinterpret_cast<const char*>(&std::get<2>(range)), sizeof(int32_t));
+ }
+
+ /* stream configurations */
+ sz = camInfo->streamConfigurations.size();
+ outFile.write(reinterpret_cast<const char*>(&sz), sizeof(size_t));
+ for (auto&& [sid, cfg] : camInfo->streamConfigurations) {
+ outFile.write(reinterpret_cast<const char*>(sid), sizeof(int32_t));
+ outFile.write(reinterpret_cast<const char*>(&cfg), sizeof(cfg));
+ }
+
+ /* size of camera_metadata_t */
+ size_t num_entry = 0;
+ size_t num_data = 0;
+ if (camInfo->characteristics != nullptr) {
+ num_entry = get_camera_metadata_entry_count(camInfo->characteristics);
+ num_data = get_camera_metadata_data_count(camInfo->characteristics);
+ }
+ outFile.write(reinterpret_cast<const char*>(&num_entry), sizeof(size_t));
+ outFile.write(reinterpret_cast<const char*>(&num_data), sizeof(size_t));
+
+ /* write each camera metadata entry */
+ if (num_entry > 0) {
+ camera_metadata_entry_t entry;
+ for (size_t idx = 0; idx < num_entry; ++idx) {
+ if (get_camera_metadata_entry(camInfo->characteristics, idx, &entry)) {
+ LOG(ERROR) << "Failed to retrieve camera metadata entry " << idx;
+ outFile.close();
+ return false;
+ }
+
+ outFile.write(reinterpret_cast<const char*>(&entry.tag), sizeof(entry.tag));
+ outFile.write(reinterpret_cast<const char*>(&entry.count), sizeof(entry.count));
+
+ int32_t type = get_camera_metadata_tag_type(entry.tag);
+ switch (type) {
+ case TYPE_BYTE:
+ outFile.write(reinterpret_cast<const char*>(entry.data.u8),
+ sizeof(uint8_t) * entry.count);
+ break;
+ case TYPE_INT32:
+ outFile.write(reinterpret_cast<const char*>(entry.data.i32),
+ sizeof(int32_t) * entry.count);
+ break;
+ case TYPE_FLOAT:
+ outFile.write(reinterpret_cast<const char*>(entry.data.f),
+ sizeof(float) * entry.count);
+ break;
+ case TYPE_INT64:
+ outFile.write(reinterpret_cast<const char*>(entry.data.i64),
+ sizeof(int64_t) * entry.count);
+ break;
+ case TYPE_DOUBLE:
+ outFile.write(reinterpret_cast<const char*>(entry.data.d),
+ sizeof(double) * entry.count);
+ break;
+ case TYPE_RATIONAL:
+ [[fallthrough]];
+ default:
+ LOG(WARNING) << "Type " << type << " is not supported.";
+ break;
+ }
+ }
+ }
+ }
+
+ outFile.close();
+ int64_t writeEnd = android::elapsedRealtimeNano();
+ LOG(INFO) << __FUNCTION__ << " takes " << std::scientific
+ << (double)(writeEnd - writeStart) / 1000000.0 << " ms.";
+
+ return true;
+}
+
+std::unique_ptr<ConfigManager> ConfigManager::Create() {
+ std::unique_ptr<ConfigManager> cfgMgr(new ConfigManager());
+
+ /*
+ * Read a configuration from XML file
+ *
+ * If this is too slow, ConfigManager::readConfigDataFromBinary() and
+ * ConfigManager::writeConfigDataToBinary()can serialize CameraInfo object
+ * to the filesystem and construct CameraInfo instead; this was
+ * evaluated as 10x faster.
+ */
+ if (!cfgMgr->readConfigDataFromXML()) {
+ return nullptr;
+ } else {
+ return cfgMgr;
+ }
+}
+
+ConfigManager::CameraInfo::~CameraInfo() {
+ free_camera_metadata(characteristics);
+
+ for (auto&& [tag, val] : cameraMetadata) {
+ switch (tag) {
+ case ANDROID_LENS_DISTORTION:
+ case ANDROID_LENS_POSE_ROTATION:
+ case ANDROID_LENS_POSE_TRANSLATION:
+ case ANDROID_LENS_INTRINSIC_CALIBRATION: {
+ delete[] reinterpret_cast<float*>(val.first);
+ break;
+ }
+
+ case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: {
+ delete[] reinterpret_cast<
+ camera_metadata_enum_android_request_available_capabilities_t*>(val.first);
+ break;
+ }
+
+ case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: {
+ delete[] reinterpret_cast<char*>(val.first);
+ break;
+ }
+
+ default:
+ LOG(WARNING) << "Tag " << std::hex << tag << " is not supported. "
+ << "Data may be corrupted?";
+ break;
+ }
+ }
+}
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp b/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp
new file mode 100644
index 0000000..e5fe6ef
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/ConfigManagerUtil.cpp
@@ -0,0 +1,155 @@
+/*
+ * 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 "ConfigManagerUtil.h"
+
+#include <android-base/logging.h>
+#include <android-base/parsedouble.h>
+#include <android-base/parseint.h>
+#include <linux/videodev2.h>
+
+#include <sstream>
+#include <string>
+
+#include <system/graphics-base-v1.0.h>
+
+using ::aidl::android::hardware::automotive::evs::CameraParam;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+
+bool ConfigManagerUtil::convertToEvsCameraParam(const std::string& id, CameraParam& camParam) {
+ std::string trimmed = ConfigManagerUtil::trimString(id);
+ bool success = true;
+
+ if (!trimmed.compare("BRIGHTNESS")) {
+ camParam = CameraParam::BRIGHTNESS;
+ } else if (!trimmed.compare("CONTRAST")) {
+ camParam = CameraParam::CONTRAST;
+ } else if (!trimmed.compare("AUTOGAIN")) {
+ camParam = CameraParam::AUTOGAIN;
+ } else if (!trimmed.compare("GAIN")) {
+ camParam = CameraParam::GAIN;
+ } else if (!trimmed.compare("AUTO_WHITE_BALANCE")) {
+ camParam = CameraParam::AUTO_WHITE_BALANCE;
+ } else if (!trimmed.compare("WHITE_BALANCE_TEMPERATURE")) {
+ camParam = CameraParam::WHITE_BALANCE_TEMPERATURE;
+ } else if (!trimmed.compare("SHARPNESS")) {
+ camParam = CameraParam::SHARPNESS;
+ } else if (!trimmed.compare("AUTO_EXPOSURE")) {
+ camParam = CameraParam::AUTO_EXPOSURE;
+ } else if (!trimmed.compare("ABSOLUTE_EXPOSURE")) {
+ camParam = CameraParam::ABSOLUTE_EXPOSURE;
+ } else if (!trimmed.compare("ABSOLUTE_FOCUS")) {
+ camParam = CameraParam::ABSOLUTE_FOCUS;
+ } else if (!trimmed.compare("AUTO_FOCUS")) {
+ camParam = CameraParam::AUTO_FOCUS;
+ } else if (!trimmed.compare("ABSOLUTE_ZOOM")) {
+ camParam = CameraParam::ABSOLUTE_ZOOM;
+ } else {
+ success = false;
+ }
+
+ return success;
+}
+
+bool ConfigManagerUtil::convertToPixelFormat(const std::string& in, PixelFormat& out) {
+ std::string trimmed = ConfigManagerUtil::trimString(in);
+ bool success = true;
+
+ if (!trimmed.compare("RGBA_8888")) {
+ out = PixelFormat::RGBA_8888;
+ } else if (!trimmed.compare("YCRCB_420_SP")) {
+ out = PixelFormat::YCRCB_420_SP;
+ } else if (!trimmed.compare("YCBCR_422_I")) {
+ out = PixelFormat::YCBCR_422_I;
+ } else {
+ out = PixelFormat::UNSPECIFIED;
+ success = false;
+ }
+
+ return success;
+}
+
+bool ConfigManagerUtil::convertToMetadataTag(const char* name, camera_metadata_tag& aTag) {
+ if (!std::strcmp(name, "LENS_DISTORTION")) {
+ aTag = ANDROID_LENS_DISTORTION;
+ } else if (!std::strcmp(name, "LENS_INTRINSIC_CALIBRATION")) {
+ aTag = ANDROID_LENS_INTRINSIC_CALIBRATION;
+ } else if (!std::strcmp(name, "LENS_POSE_ROTATION")) {
+ aTag = ANDROID_LENS_POSE_ROTATION;
+ } else if (!std::strcmp(name, "LENS_POSE_TRANSLATION")) {
+ aTag = ANDROID_LENS_POSE_TRANSLATION;
+ } else if (!std::strcmp(name, "REQUEST_AVAILABLE_CAPABILITIES")) {
+ aTag = ANDROID_REQUEST_AVAILABLE_CAPABILITIES;
+ } else if (!std::strcmp(name, "LOGICAL_MULTI_CAMERA_PHYSICAL_IDS")) {
+ aTag = ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+bool ConfigManagerUtil::convertToCameraCapability(
+ const char* name, camera_metadata_enum_android_request_available_capabilities_t& cap) {
+ if (!std::strcmp(name, "DEPTH_OUTPUT")) {
+ cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT;
+ } else if (!std::strcmp(name, "LOGICAL_MULTI_CAMERA")) {
+ cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA;
+ } else if (!std::strcmp(name, "MONOCHROME")) {
+ cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME;
+ } else if (!std::strcmp(name, "SECURE_IMAGE_DATA")) {
+ cap = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+float* ConfigManagerUtil::convertFloatArray(const char* sz, const char* vals, size_t& count,
+ const char delimiter) {
+ std::string size_string(sz);
+ std::string value_string(vals);
+
+ if (!android::base::ParseUint(size_string, &count)) {
+ LOG(ERROR) << "Failed to parse " << size_string;
+ return nullptr;
+ }
+ float* result = new float[count];
+ std::stringstream values(value_string);
+
+ int32_t idx = 0;
+ std::string token;
+ while (getline(values, token, delimiter)) {
+ if (!android::base::ParseFloat(token, &result[idx++])) {
+ LOG(WARNING) << "Failed to parse " << token;
+ }
+ }
+
+ return result;
+}
+
+std::string ConfigManagerUtil::trimString(const std::string& src, const std::string& ws) {
+ const auto s = src.find_first_not_of(ws);
+ if (s == std::string::npos) {
+ return "";
+ }
+
+ const auto e = src.find_last_not_of(ws);
+ const auto r = e - s + 1;
+
+ return src.substr(s, r);
+}
diff --git a/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp
deleted file mode 100644
index 5a81d05..0000000
--- a/automotive/evs/aidl/impl/default/src/DefaultEvsEnumerator.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/203661081): Remove below lines to disable compiler warnings.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-parameter"
-
-#define LOG_TAG "DefaultEvsEnumerator"
-
-#include <DefaultEvsEnumerator.h>
-
-namespace aidl::android::hardware::automotive::evs::implementation {
-
-using ::ndk::ScopedAStatus;
-
-ScopedAStatus DefaultEvsEnumerator::isHardware(bool* flag) {
- // This returns true always.
- *flag = true;
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::openCamera(const std::string& cameraId,
- const Stream& streamConfig,
- std::shared_ptr<IEvsCamera>* obj) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& obj) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getCameraList(std::vector<CameraDesc>* list) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getStreamList(const CameraDesc& desc,
- std::vector<Stream>* _aidl_return) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::openDisplay(int32_t displayId,
- std::shared_ptr<IEvsDisplay>* obj) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& state) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getDisplayState(DisplayState* state) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::registerStatusCallback(
- const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::openUltrasonicsArray(
- const std::string& id, std::shared_ptr<IEvsUltrasonicsArray>* obj) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::closeUltrasonicsArray(
- const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
- return ScopedAStatus::ok();
-}
-
-ScopedAStatus DefaultEvsEnumerator::getUltrasonicsArrayList(
- std::vector<UltrasonicsArrayDesc>* list) {
- return ScopedAStatus::ok();
-}
-
-} // namespace aidl::android::hardware::automotive::evs::implementation
-
-#pragma clang diagnostic pop
diff --git a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
new file mode 100644
index 0000000..5178958
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
@@ -0,0 +1,560 @@
+/*
+ * 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 "EvsEnumerator.h"
+
+#include "ConfigManager.h"
+#include "EvsGlDisplay.h"
+#include "EvsMockCamera.h"
+
+#include <aidl/android/hardware/automotive/evs/EvsResult.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <cutils/android_filesystem_config.h>
+
+#include <set>
+#include <string_view>
+
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::ndk::ScopedAStatus;
+using std::chrono_literals::operator""s;
+
+// Constants
+constexpr std::chrono::seconds kEnumerationTimeout = 10s;
+constexpr uint64_t kInvalidDisplayId = std::numeric_limits<uint64_t>::max();
+const std::set<uid_t> kAllowedUids = {AID_AUTOMOTIVE_EVS, AID_SYSTEM, AID_ROOT};
+
+} // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+// NOTE: All members values are static so that all clients operate on the same state
+// That is to say, this is effectively a singleton despite the fact that HIDL
+// constructs a new instance for each client.
+std::unordered_map<std::string, EvsEnumerator::CameraRecord> EvsEnumerator::sCameraList;
+std::mutex EvsEnumerator::sLock;
+std::condition_variable EvsEnumerator::sCameraSignal;
+std::unique_ptr<ConfigManager> EvsEnumerator::sConfigManager;
+std::shared_ptr<ICarDisplayProxy> EvsEnumerator::sDisplayProxy;
+std::unordered_map<uint8_t, uint64_t> EvsEnumerator::sDisplayPortList;
+
+EvsEnumerator::ActiveDisplays& EvsEnumerator::mutableActiveDisplays() {
+ static ActiveDisplays active_displays;
+ return active_displays;
+}
+
+EvsEnumerator::EvsEnumerator(const std::shared_ptr<ICarDisplayProxy>& proxyService) {
+ LOG(DEBUG) << "EvsEnumerator is created.";
+
+ if (!sConfigManager) {
+ /* loads and initializes ConfigManager in a separate thread */
+ sConfigManager = ConfigManager::Create();
+ }
+
+ if (!sDisplayProxy) {
+ /* sets a car-window service handle */
+ sDisplayProxy = proxyService;
+ }
+
+ // Enumerate existing devices
+ enumerateCameras();
+ mInternalDisplayId = enumerateDisplays();
+}
+
+bool EvsEnumerator::checkPermission() {
+ const auto uid = AIBinder_getCallingUid();
+ if (kAllowedUids.find(uid) == kAllowedUids.end()) {
+ LOG(ERROR) << "EVS access denied: "
+ << "pid = " << AIBinder_getCallingPid() << ", uid = " << uid;
+ return false;
+ }
+
+ return true;
+}
+
+void EvsEnumerator::enumerateCameras() {
+ if (!sConfigManager) {
+ return;
+ }
+
+ for (auto id : sConfigManager->getCameraIdList()) {
+ CameraRecord rec(id.data());
+ std::unique_ptr<ConfigManager::CameraInfo>& pInfo = sConfigManager->getCameraInfo(id);
+ if (pInfo) {
+ uint8_t* ptr = reinterpret_cast<uint8_t*>(pInfo->characteristics);
+ const size_t len = get_camera_metadata_size(pInfo->characteristics);
+ rec.desc.metadata.insert(rec.desc.metadata.end(), ptr, ptr + len);
+ }
+ sCameraList.insert_or_assign(id, std::move(rec));
+ }
+}
+
+uint64_t EvsEnumerator::enumerateDisplays() {
+ LOG(INFO) << __FUNCTION__ << ": Starting display enumeration";
+ uint64_t internalDisplayId = kInvalidDisplayId;
+ if (!sDisplayProxy) {
+ LOG(ERROR) << "ICarDisplayProxy is not available!";
+ return internalDisplayId;
+ }
+
+ std::vector<int64_t> displayIds;
+ if (auto status = sDisplayProxy->getDisplayIdList(&displayIds); !status.isOk()) {
+ LOG(ERROR) << "Failed to retrieve a display id list"
+ << ::android::statusToString(status.getStatus());
+ return internalDisplayId;
+ }
+
+ if (displayIds.size() > 0) {
+ // The first entry of the list is the internal display. See
+ // SurfaceFlinger::getPhysicalDisplayIds() implementation.
+ internalDisplayId = displayIds[0];
+ for (const auto& id : displayIds) {
+ const auto port = id & 0xFF;
+ LOG(INFO) << "Display " << std::hex << id << " is detected on the port, " << port;
+ sDisplayPortList.insert_or_assign(port, id);
+ }
+ }
+
+ LOG(INFO) << "Found " << sDisplayPortList.size() << " displays";
+ return internalDisplayId;
+}
+
+// Methods from ::android::hardware::automotive::evs::IEvsEnumerator follow.
+ScopedAStatus EvsEnumerator::getCameraList(std::vector<CameraDesc>* _aidl_return) {
+ LOG(DEBUG) << __FUNCTION__;
+ if (!checkPermission()) {
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::PERMISSION_DENIED));
+ }
+
+ {
+ std::unique_lock<std::mutex> lock(sLock);
+ if (sCameraList.size() < 1) {
+ // No qualified device has been found. Wait until new device is ready,
+ // for 10 seconds.
+ if (!sCameraSignal.wait_for(lock, kEnumerationTimeout,
+ [] { return sCameraList.size() > 0; })) {
+ LOG(DEBUG) << "Timer expired. No new device has been added.";
+ }
+ }
+ }
+
+ // Build up a packed array of CameraDesc for return
+ _aidl_return->resize(sCameraList.size());
+ unsigned i = 0;
+ for (const auto& [key, cam] : sCameraList) {
+ (*_aidl_return)[i++] = cam.desc;
+ }
+
+ if (sConfigManager) {
+ // Adding camera groups that represent logical camera devices
+ auto camGroups = sConfigManager->getCameraGroupIdList();
+ for (auto&& id : camGroups) {
+ if (sCameraList.find(id) != sCameraList.end()) {
+ // Already exists in the _aidl_return
+ continue;
+ }
+
+ std::unique_ptr<ConfigManager::CameraGroupInfo>& tempInfo =
+ sConfigManager->getCameraGroupInfo(id);
+ CameraRecord cam(id.data());
+ if (tempInfo) {
+ uint8_t* ptr = reinterpret_cast<uint8_t*>(tempInfo->characteristics);
+ const size_t len = get_camera_metadata_size(tempInfo->characteristics);
+ cam.desc.metadata.insert(cam.desc.metadata.end(), ptr, ptr + len);
+ }
+
+ sCameraList.insert_or_assign(id, cam);
+ _aidl_return->push_back(cam.desc);
+ }
+ }
+
+ // Send back the results
+ LOG(DEBUG) << "Reporting " << sCameraList.size() << " cameras available";
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::getStreamList(const CameraDesc& desc,
+ std::vector<Stream>* _aidl_return) {
+ using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
+
+ camera_metadata_t* pMetadata = const_cast<camera_metadata_t*>(
+ reinterpret_cast<const camera_metadata_t*>(desc.metadata.data()));
+ camera_metadata_entry_t streamConfig;
+ if (!find_camera_metadata_entry(pMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+ &streamConfig)) {
+ const unsigned numStreamConfigs = streamConfig.count / sizeof(StreamConfiguration);
+ _aidl_return->resize(numStreamConfigs);
+ const StreamConfiguration* pCurrentConfig =
+ reinterpret_cast<StreamConfiguration*>(streamConfig.data.i32);
+ for (unsigned i = 0; i < numStreamConfigs; ++i, ++pCurrentConfig) {
+ // Build ::aidl::android::hardware::automotive::evs::Stream from
+ // StreamConfiguration.
+ Stream current = {
+ .id = pCurrentConfig->id,
+ .streamType =
+ pCurrentConfig->type ==
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT
+ ? StreamType::INPUT
+ : StreamType::OUTPUT,
+ .width = pCurrentConfig->width,
+ .height = pCurrentConfig->height,
+ .format = static_cast<AidlPixelFormat>(pCurrentConfig->format),
+ .usage = BufferUsage::CAMERA_INPUT,
+ .rotation = Rotation::ROTATION_0,
+ };
+
+ (*_aidl_return)[i] = current;
+ }
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::openCamera(const std::string& id, const Stream& cfg,
+ std::shared_ptr<IEvsCamera>* obj) {
+ LOG(DEBUG) << __FUNCTION__;
+ if (!checkPermission()) {
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::PERMISSION_DENIED));
+ }
+
+ // Is this a recognized camera id?
+ CameraRecord* pRecord = findCameraById(id);
+ if (!pRecord) {
+ LOG(ERROR) << id << " does not exist!";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ // Has this camera already been instantiated by another caller?
+ std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
+ if (pActiveCamera) {
+ LOG(WARNING) << "Killing previous camera because of new caller";
+ closeCamera(pActiveCamera);
+ }
+
+ // Construct a camera instance for the caller
+ if (!sConfigManager) {
+ pActiveCamera = EvsMockCamera::Create(id.data());
+ } else {
+ pActiveCamera = EvsMockCamera::Create(id.data(), sConfigManager->getCameraInfo(id), &cfg);
+ }
+
+ pRecord->activeInstance = pActiveCamera;
+ if (!pActiveCamera) {
+ LOG(ERROR) << "Failed to create new EvsMockCamera object for " << id;
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+ }
+
+ *obj = pActiveCamera;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::closeCamera(const std::shared_ptr<IEvsCamera>& cameraObj) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ if (!cameraObj) {
+ LOG(ERROR) << "Ignoring call to closeCamera with null camera ptr";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ // Get the camera id so we can find it in our list
+ CameraDesc desc;
+ auto status = cameraObj->getCameraInfo(&desc);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Failed to read a camera descriptor";
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+ }
+ auto cameraId = desc.id;
+ closeCamera_impl(cameraObj, cameraId);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::openDisplay(int32_t id, std::shared_ptr<IEvsDisplay>* displayObj) {
+ LOG(DEBUG) << __FUNCTION__;
+ if (!checkPermission()) {
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::PERMISSION_DENIED));
+ }
+
+ auto& displays = mutableActiveDisplays();
+
+ if (auto existing_display_search = displays.popDisplay(id)) {
+ // If we already have a display active, then we need to shut it down so we can
+ // give exclusive access to the new caller.
+ std::shared_ptr<EvsGlDisplay> pActiveDisplay = existing_display_search->displayWeak.lock();
+ if (pActiveDisplay) {
+ LOG(WARNING) << "Killing previous display because of new caller";
+ pActiveDisplay->forceShutdown();
+ }
+ }
+
+ // Create a new display interface and return it
+ uint64_t targetDisplayId = mInternalDisplayId;
+ auto it = sDisplayPortList.find(id);
+ if (it != sDisplayPortList.end()) {
+ targetDisplayId = it->second;
+ } else {
+ LOG(WARNING) << "No display is available on the port " << static_cast<int32_t>(id)
+ << ". The main display " << mInternalDisplayId << " will be used instead";
+ }
+
+ // Create a new display interface and return it.
+ std::shared_ptr<EvsGlDisplay> pActiveDisplay =
+ ndk::SharedRefBase::make<EvsGlDisplay>(sDisplayProxy, targetDisplayId);
+
+ if (auto insert_result = displays.tryInsert(id, pActiveDisplay); !insert_result) {
+ LOG(ERROR) << "Display ID " << id << " has been used by another caller.";
+ pActiveDisplay->forceShutdown();
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::RESOURCE_BUSY));
+ }
+
+ LOG(DEBUG) << "Returning new EvsGlDisplay object " << pActiveDisplay.get();
+ *displayObj = pActiveDisplay;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::closeDisplay(const std::shared_ptr<IEvsDisplay>& obj) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ auto& displays = mutableActiveDisplays();
+ const auto display_search = displays.popDisplay(obj);
+
+ if (!display_search) {
+ LOG(WARNING) << "Ignoring close of previously orphaned display - why did a client steal?";
+ return ScopedAStatus::ok();
+ }
+
+ auto pActiveDisplay = display_search->displayWeak.lock();
+
+ if (!pActiveDisplay) {
+ LOG(ERROR) << "Somehow a display is being destroyed "
+ << "when the enumerator didn't know one existed";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ pActiveDisplay->forceShutdown();
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::getDisplayState(DisplayState* state) {
+ LOG(DEBUG) << __FUNCTION__;
+ return getDisplayStateImpl(std::nullopt, state);
+}
+
+ScopedAStatus EvsEnumerator::getDisplayStateById(int32_t displayId, DisplayState* state) {
+ LOG(DEBUG) << __FUNCTION__;
+ return getDisplayStateImpl(displayId, state);
+}
+
+ScopedAStatus EvsEnumerator::getDisplayStateImpl(std::optional<int32_t> displayId,
+ DisplayState* state) {
+ if (!checkPermission()) {
+ *state = DisplayState::DEAD;
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::PERMISSION_DENIED));
+ }
+
+ const auto& all_displays = mutableActiveDisplays().getAllDisplays();
+
+ const auto display_search = displayId ? all_displays.find(*displayId) : all_displays.begin();
+
+ if (display_search == all_displays.end()) {
+ *state = DisplayState::NOT_OPEN;
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ std::shared_ptr<IEvsDisplay> pActiveDisplay = display_search->second.displayWeak.lock();
+ if (pActiveDisplay) {
+ return pActiveDisplay->getDisplayState(state);
+ } else {
+ *state = DisplayState::NOT_OPEN;
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+}
+
+ScopedAStatus EvsEnumerator::getDisplayIdList(std::vector<uint8_t>* list) {
+ std::vector<uint8_t>& output = *list;
+ if (sDisplayPortList.size() > 0) {
+ output.resize(sDisplayPortList.size());
+ unsigned i = 0;
+ output[i++] = mInternalDisplayId & 0xFF;
+ for (const auto& [port, id] : sDisplayPortList) {
+ if (mInternalDisplayId != id) {
+ output[i++] = port;
+ }
+ }
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::isHardware(bool* flag) {
+ *flag = true;
+ return ScopedAStatus::ok();
+}
+
+void EvsEnumerator::notifyDeviceStatusChange(const std::string_view& deviceName,
+ DeviceStatusType type) {
+ std::lock_guard lock(sLock);
+ if (!mCallback) {
+ return;
+ }
+
+ std::vector<DeviceStatus> status{{.id = std::string(deviceName), .status = type}};
+ if (!mCallback->deviceStatusChanged(status).isOk()) {
+ LOG(WARNING) << "Failed to notify a device status change, name = " << deviceName
+ << ", type = " << static_cast<int>(type);
+ }
+}
+
+ScopedAStatus EvsEnumerator::registerStatusCallback(
+ const std::shared_ptr<IEvsEnumeratorStatusCallback>& callback) {
+ std::lock_guard lock(sLock);
+ if (mCallback) {
+ LOG(INFO) << "Replacing an existing device status callback";
+ }
+ mCallback = callback;
+ return ScopedAStatus::ok();
+}
+
+void EvsEnumerator::closeCamera_impl(const std::shared_ptr<IEvsCamera>& pCamera,
+ const std::string& cameraId) {
+ // Find the named camera
+ CameraRecord* pRecord = findCameraById(cameraId);
+
+ // Is the display being destroyed actually the one we think is active?
+ if (!pRecord) {
+ LOG(ERROR) << "Asked to close a camera whose name isn't recognized";
+ } else {
+ std::shared_ptr<EvsMockCamera> pActiveCamera = pRecord->activeInstance.lock();
+ if (!pActiveCamera) {
+ LOG(WARNING) << "Somehow a camera is being destroyed "
+ << "when the enumerator didn't know one existed";
+ } else if (pActiveCamera != pCamera) {
+ // This can happen if the camera was aggressively reopened,
+ // orphaning this previous instance
+ LOG(WARNING) << "Ignoring close of previously orphaned camera "
+ << "- why did a client steal?";
+ } else {
+ // Shutdown the active camera
+ pActiveCamera->shutdown();
+ }
+ }
+
+ return;
+}
+
+EvsEnumerator::CameraRecord* EvsEnumerator::findCameraById(const std::string& cameraId) {
+ // Find the named camera
+ auto found = sCameraList.find(cameraId);
+ if (found != sCameraList.end()) {
+ // Found a match!
+ return &found->second;
+ }
+
+ // We didn't find a match
+ return nullptr;
+}
+
+std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
+ int32_t id) {
+ std::lock_guard lck(mMutex);
+ const auto search = mIdToDisplay.find(id);
+ if (search == mIdToDisplay.end()) {
+ return std::nullopt;
+ }
+ const auto display_info = search->second;
+ mIdToDisplay.erase(search);
+ mDisplayToId.erase(display_info.internalDisplayRawAddr);
+ return display_info;
+}
+
+std::optional<EvsEnumerator::ActiveDisplays::DisplayInfo> EvsEnumerator::ActiveDisplays::popDisplay(
+ const std::shared_ptr<IEvsDisplay>& display) {
+ const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
+ std::lock_guard lck(mMutex);
+ const auto display_to_id_search = mDisplayToId.find(display_ptr_val);
+ if (display_to_id_search == mDisplayToId.end()) {
+ LOG(ERROR) << "Unknown display.";
+ return std::nullopt;
+ }
+ const auto id = display_to_id_search->second;
+ const auto id_to_display_search = mIdToDisplay.find(id);
+ mDisplayToId.erase(display_to_id_search);
+ if (id_to_display_search == mIdToDisplay.end()) {
+ LOG(ERROR) << "No correspsonding ID for the display, probably orphaned.";
+ return std::nullopt;
+ }
+ const auto display_info = id_to_display_search->second;
+ mIdToDisplay.erase(id);
+ return display_info;
+}
+
+std::unordered_map<int32_t, EvsEnumerator::ActiveDisplays::DisplayInfo>
+EvsEnumerator::ActiveDisplays::getAllDisplays() {
+ std::lock_guard lck(mMutex);
+ auto id_to_display_map_copy = mIdToDisplay;
+ return id_to_display_map_copy;
+}
+
+bool EvsEnumerator::ActiveDisplays::tryInsert(int32_t id,
+ const std::shared_ptr<EvsGlDisplay>& display) {
+ std::lock_guard lck(mMutex);
+ const auto display_ptr_val = reinterpret_cast<uintptr_t>(display.get());
+
+ auto id_to_display_insert_result =
+ mIdToDisplay.emplace(id, DisplayInfo{
+ .id = id,
+ .displayWeak = display,
+ .internalDisplayRawAddr = display_ptr_val,
+ });
+ if (!id_to_display_insert_result.second) {
+ return false;
+ }
+ auto display_to_id_insert_result = mDisplayToId.emplace(display_ptr_val, id);
+ if (!display_to_id_insert_result.second) {
+ mIdToDisplay.erase(id);
+ return false;
+ }
+ return true;
+}
+
+ScopedAStatus EvsEnumerator::getUltrasonicsArrayList(
+ [[maybe_unused]] std::vector<UltrasonicsArrayDesc>* list) {
+ // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::openUltrasonicsArray(
+ [[maybe_unused]] const std::string& id,
+ [[maybe_unused]] std::shared_ptr<IEvsUltrasonicsArray>* obj) {
+ // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsEnumerator::closeUltrasonicsArray(
+ [[maybe_unused]] const std::shared_ptr<IEvsUltrasonicsArray>& obj) {
+ // TODO(b/149874793): Add implementation for EVS Manager and Sample driver
+ return ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
new file mode 100644
index 0000000..e5f8e4c
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/EvsGlDisplay.cpp
@@ -0,0 +1,417 @@
+/*
+ * 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 "EvsGlDisplay.h"
+
+#include <aidl/android/hardware/automotive/evs/EvsResult.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android-base/thread_annotations.h>
+#include <linux/time.h>
+#include <ui/DisplayMode.h>
+#include <ui/DisplayState.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/SystemClock.h>
+
+#include <chrono>
+
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::android::base::ScopedLockAssertion;
+using ::ndk::ScopedAStatus;
+
+constexpr auto kTimeout = std::chrono::seconds(1);
+
+bool debugFirstFrameDisplayed = false;
+
+int generateFingerPrint(buffer_handle_t handle) {
+ return static_cast<int>(reinterpret_cast<long>(handle) & 0xFFFFFFFF);
+}
+
+} // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+EvsGlDisplay::EvsGlDisplay(const std::shared_ptr<ICarDisplayProxy>& pDisplayProxy,
+ uint64_t displayId)
+ : mDisplayId(displayId), mDisplayProxy(pDisplayProxy) {
+ LOG(DEBUG) << "EvsGlDisplay instantiated";
+
+ // Set up our self description
+ // NOTE: These are arbitrary values chosen for testing
+ mInfo.id = std::to_string(displayId);
+ mInfo.vendorFlags = 3870;
+
+ // Start a thread to render images on this display
+ {
+ std::lock_guard lock(mLock);
+ mState = RUN;
+ }
+ mRenderThread = std::thread([this]() { renderFrames(); });
+}
+
+EvsGlDisplay::~EvsGlDisplay() {
+ LOG(DEBUG) << "EvsGlDisplay being destroyed";
+ forceShutdown();
+}
+
+/**
+ * This gets called if another caller "steals" ownership of the display
+ */
+void EvsGlDisplay::forceShutdown() {
+ LOG(DEBUG) << "EvsGlDisplay forceShutdown";
+ {
+ std::lock_guard lock(mLock);
+
+ // If the buffer isn't being held by a remote client, release it now as an
+ // optimization to release the resources more quickly than the destructor might
+ // get called.
+ if (mBuffer.handle != nullptr) {
+ // Report if we're going away while a buffer is outstanding
+ if (mBufferBusy || mState == RUN) {
+ LOG(ERROR) << "EvsGlDisplay going down while client is holding a buffer";
+ }
+ mState = STOPPING;
+ }
+
+ // Put this object into an unrecoverable error state since somebody else
+ // is going to own the display now.
+ mRequestedState = DisplayState::DEAD;
+ }
+ mBufferReadyToRender.notify_all();
+
+ if (mRenderThread.joinable()) {
+ mRenderThread.join();
+ }
+}
+
+/**
+ * Initialize GL in the context of a caller's thread and prepare a graphic
+ * buffer to use.
+ */
+bool EvsGlDisplay::initializeGlContextLocked() {
+ // Initialize our display window
+ // NOTE: This will cause the display to become "VISIBLE" before a frame is actually
+ // returned, which is contrary to the spec and will likely result in a black frame being
+ // (briefly) shown.
+ if (!mGlWrapper.initialize(mDisplayProxy, mDisplayId)) {
+ // Report the failure
+ LOG(ERROR) << "Failed to initialize GL display";
+ return false;
+ }
+
+ // Assemble the buffer description we'll use for our render target
+ static_assert(::aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888 ==
+ static_cast<::aidl::android::hardware::graphics::common::PixelFormat>(
+ HAL_PIXEL_FORMAT_RGBA_8888));
+ mBuffer.description = {
+ .width = static_cast<int>(mGlWrapper.getWidth()),
+ .height = static_cast<int>(mGlWrapper.getHeight()),
+ .layers = 1,
+ .format = PixelFormat::RGBA_8888,
+ // FIXME: Below line is not using
+ // ::aidl::android::hardware::graphics::common::BufferUsage because
+ // BufferUsage enum does not support a bitwise-OR operation; they
+ // should be BufferUsage::GPU_RENDER_TARGET |
+ // BufferUsage::COMPOSER_OVERLAY
+ .usage = static_cast<BufferUsage>(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER),
+ };
+
+ ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+ uint32_t stride = static_cast<uint32_t>(mBuffer.description.stride);
+ buffer_handle_t handle = nullptr;
+ const ::android::status_t result =
+ alloc.allocate(mBuffer.description.width, mBuffer.description.height,
+ static_cast<::android::PixelFormat>(mBuffer.description.format),
+ mBuffer.description.layers,
+ static_cast<uint64_t>(mBuffer.description.usage), &handle, &stride,
+ /* requestorName= */ "EvsGlDisplay");
+ mBuffer.description.stride = stride;
+ mBuffer.fingerprint = generateFingerPrint(mBuffer.handle);
+ if (result != ::android::NO_ERROR) {
+ LOG(ERROR) << "Error " << result << " allocating " << mBuffer.description.width << " x "
+ << mBuffer.description.height << " graphics buffer.";
+ mGlWrapper.shutdown();
+ return false;
+ }
+
+ mBuffer.handle = handle;
+ if (mBuffer.handle == nullptr) {
+ LOG(ERROR) << "We didn't get a buffer handle back from the allocator";
+ mGlWrapper.shutdown();
+ return false;
+ }
+
+ LOG(DEBUG) << "Allocated new buffer " << mBuffer.handle << " with stride "
+ << mBuffer.description.stride;
+ return true;
+}
+
+/**
+ * This method runs in a separate thread and renders the contents of the buffer.
+ */
+void EvsGlDisplay::renderFrames() {
+ {
+ std::lock_guard lock(mLock);
+
+ if (!initializeGlContextLocked()) {
+ LOG(ERROR) << "Failed to initialize GL context";
+ return;
+ }
+
+ // Display buffer is ready.
+ mBufferBusy = false;
+ }
+ mBufferReadyToUse.notify_all();
+
+ while (true) {
+ {
+ std::unique_lock lock(mLock);
+ ScopedLockAssertion lock_assertion(mLock);
+ mBufferReadyToRender.wait(
+ lock, [this]() REQUIRES(mLock) { return mBufferReady || mState != RUN; });
+ if (mState != RUN) {
+ LOG(DEBUG) << "A rendering thread is stopping";
+ break;
+ }
+ mBufferReady = false;
+ }
+
+ // Update the texture contents with the provided data
+ if (!mGlWrapper.updateImageTexture(mBuffer.handle, mBuffer.description)) {
+ LOG(WARNING) << "Failed to update the image texture";
+ continue;
+ }
+
+ // Put the image on the screen
+ mGlWrapper.renderImageToScreen();
+ if (!debugFirstFrameDisplayed) {
+ LOG(DEBUG) << "EvsFirstFrameDisplayTiming start time: " << ::android::elapsedRealtime()
+ << " ms.";
+ debugFirstFrameDisplayed = true;
+ }
+
+ // Mark current frame is consumed.
+ {
+ std::lock_guard lock(mLock);
+ mBufferBusy = false;
+ }
+ mBufferDone.notify_all();
+ }
+
+ LOG(DEBUG) << "A rendering thread is stopped.";
+
+ // Drop the graphics buffer we've been using
+ ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+ alloc.free(mBuffer.handle);
+ mBuffer.handle = nullptr;
+
+ mGlWrapper.hideWindow(mDisplayProxy, mDisplayId);
+ mGlWrapper.shutdown();
+
+ std::lock_guard lock(mLock);
+ mState = STOPPED;
+}
+
+/**
+ * Returns basic information about the EVS display provided by the system.
+ * See the description of the DisplayDesc structure for details.
+ */
+ScopedAStatus EvsGlDisplay::getDisplayInfo(DisplayDesc* _aidl_return) {
+ if (!mDisplayProxy) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+ }
+
+ ::aidl::android::frameworks::automotive::display::DisplayDesc proxyDisplay;
+ auto status = mDisplayProxy->getDisplayInfo(mDisplayId, &proxyDisplay);
+ if (!status.isOk()) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+ }
+
+ _aidl_return->width = proxyDisplay.width;
+ _aidl_return->height = proxyDisplay.height;
+ _aidl_return->orientation = static_cast<Rotation>(proxyDisplay.orientation);
+ _aidl_return->id = mInfo.id; // FIXME: what should be ID here?
+ _aidl_return->vendorFlags = mInfo.vendorFlags;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+/**
+ * Clients may set the display state to express their desired state.
+ * The HAL implementation must gracefully accept a request for any state
+ * while in any other state, although the response may be to ignore the request.
+ * The display is defined to start in the NOT_VISIBLE state upon initialization.
+ * The client is then expected to request the VISIBLE_ON_NEXT_FRAME state, and
+ * then begin providing video. When the display is no longer required, the client
+ * is expected to request the NOT_VISIBLE state after passing the last video frame.
+ */
+ScopedAStatus EvsGlDisplay::setDisplayState(DisplayState state) {
+ LOG(DEBUG) << __FUNCTION__;
+ std::lock_guard lock(mLock);
+
+ if (mRequestedState == DisplayState::DEAD) {
+ // This object no longer owns the display -- it's been superceeded!
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ // Ensure we recognize the requested state so we don't go off the rails
+ static constexpr ::ndk::enum_range<DisplayState> kDisplayStateRange;
+ if (std::find(kDisplayStateRange.begin(), kDisplayStateRange.end(), state) ==
+ kDisplayStateRange.end()) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ switch (state) {
+ case DisplayState::NOT_VISIBLE:
+ mGlWrapper.hideWindow(mDisplayProxy, mDisplayId);
+ break;
+ case DisplayState::VISIBLE:
+ mGlWrapper.showWindow(mDisplayProxy, mDisplayId);
+ break;
+ default:
+ break;
+ }
+
+ // Record the requested state
+ mRequestedState = state;
+
+ return ScopedAStatus::ok();
+}
+
+/**
+ * The HAL implementation should report the actual current state, which might
+ * transiently differ from the most recently requested state. Note, however, that
+ * the logic responsible for changing display states should generally live above
+ * the device layer, making it undesirable for the HAL implementation to
+ * spontaneously change display states.
+ */
+ScopedAStatus EvsGlDisplay::getDisplayState(DisplayState* _aidl_return) {
+ LOG(DEBUG) << __FUNCTION__;
+ std::lock_guard lock(mLock);
+ *_aidl_return = mRequestedState;
+ return ScopedAStatus::ok();
+}
+
+/**
+ * This call returns a handle to a frame buffer associated with the display.
+ * This buffer may be locked and written to by software and/or GL. This buffer
+ * must be returned via a call to returnTargetBufferForDisplay() even if the
+ * display is no longer visible.
+ */
+ScopedAStatus EvsGlDisplay::getTargetBuffer(BufferDesc* _aidl_return) {
+ LOG(DEBUG) << __FUNCTION__;
+ std::unique_lock lock(mLock);
+ ScopedLockAssertion lock_assertion(mLock);
+ if (mRequestedState == DisplayState::DEAD) {
+ LOG(ERROR) << "Rejecting buffer request from object that lost ownership of the display.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ // If we don't already have a buffer, allocate one now
+ // mBuffer.memHandle is a type of buffer_handle_t, which is equal to
+ // native_handle_t*.
+ mBufferReadyToUse.wait(lock, [this]() REQUIRES(mLock) { return !mBufferBusy; });
+
+ // Do we have a frame available?
+ if (mBufferBusy) {
+ // This means either we have a 2nd client trying to compete for buffers
+ // (an unsupported mode of operation) or else the client hasn't returned
+ // a previously issued buffer yet (they're behaving badly).
+ // NOTE: We have to make the callback even if we have nothing to provide
+ LOG(ERROR) << "getTargetBuffer called while no buffers available.";
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
+ }
+
+ // Mark our buffer as busy
+ mBufferBusy = true;
+
+ // Send the buffer to the client
+ LOG(VERBOSE) << "Providing display buffer handle " << mBuffer.handle;
+
+ BufferDesc bufferDescToSend = {
+ .buffer =
+ {
+ .handle = std::move(::android::dupToAidl(mBuffer.handle)),
+ .description = mBuffer.description,
+ },
+ .pixelSizeBytes = 4, // RGBA_8888 is 4-byte-per-pixel format
+ .bufferId = mBuffer.fingerprint,
+ };
+ *_aidl_return = std::move(bufferDescToSend);
+
+ return ScopedAStatus::ok();
+}
+
+/**
+ * This call tells the display that the buffer is ready for display.
+ * The buffer is no longer valid for use by the client after this call.
+ */
+ScopedAStatus EvsGlDisplay::returnTargetBufferForDisplay(const BufferDesc& buffer) {
+ LOG(VERBOSE) << __FUNCTION__;
+ std::unique_lock lock(mLock);
+ ScopedLockAssertion lock_assertion(mLock);
+
+ // Nobody should call us with a null handle
+ if (buffer.buffer.handle.fds.size() < 1) {
+ LOG(ERROR) << __FUNCTION__ << " called without a valid buffer handle.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+ if (buffer.bufferId != mBuffer.fingerprint) {
+ LOG(ERROR) << "Got an unrecognized frame returned.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+ if (!mBufferBusy) {
+ LOG(ERROR) << "A frame was returned with no outstanding frames.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ // If we've been displaced by another owner of the display, then we can't do anything else
+ if (mRequestedState == DisplayState::DEAD) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ // If we were waiting for a new frame, this is it!
+ if (mRequestedState == DisplayState::VISIBLE_ON_NEXT_FRAME) {
+ mRequestedState = DisplayState::VISIBLE;
+ mGlWrapper.showWindow(mDisplayProxy, mDisplayId);
+ }
+
+ // Validate we're in an expected state
+ if (mRequestedState != DisplayState::VISIBLE) {
+ // Not sure why a client would send frames back when we're not visible.
+ LOG(WARNING) << "Got a frame returned while not visible - ignoring.";
+ return ScopedAStatus::ok();
+ }
+ mBufferReady = true;
+ mBufferReadyToRender.notify_all();
+
+ if (!mBufferDone.wait_for(lock, kTimeout, [this]() REQUIRES(mLock) { return !mBufferBusy; })) {
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::UNDERLYING_SERVICE_ERROR));
+ }
+
+ return ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp
new file mode 100644
index 0000000..797b221
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/EvsMockCamera.cpp
@@ -0,0 +1,735 @@
+/*
+ * 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 "EvsMockCamera.h"
+#include "ConfigManager.h"
+#include "EvsEnumerator.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/SystemClock.h>
+
+#include <memory>
+
+namespace {
+
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::ndk::ScopedAStatus;
+
+// Arbitrary limit on number of graphics buffers allowed to be allocated
+// Safeguards against unreasonable resource consumption and provides a testable limit
+constexpr unsigned kMaxBuffersInFlight = 100;
+
+// Minimum number of buffers to run a video stream
+constexpr int kMinimumBuffersInFlight = 1;
+
+// Colors for the colorbar test pattern in ABGR format
+constexpr uint32_t kColors[] = {
+ 0xFFFFFFFF, // white
+ 0xFF00FFFF, // yellow
+ 0xFFFFFF00, // cyan
+ 0xFF00FF00, // green
+ 0xFFFF00FF, // fuchsia
+ 0xFF0000FF, // red
+ 0xFFFF0000, // blue
+ 0xFF000000, // black
+};
+constexpr size_t kNumColors = sizeof(kColors) / sizeof(kColors[0]);
+
+} // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+EvsMockCamera::EvsMockCamera([[maybe_unused]] Sigil sigil, const char* id,
+ std::unique_ptr<ConfigManager::CameraInfo>& camInfo)
+ : mFramesAllowed(0), mFramesInUse(0), mStreamState(STOPPED), mCameraInfo(camInfo) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ /* set a camera id */
+ mDescription.id = id;
+
+ /* set camera metadata */
+ if (camInfo) {
+ uint8_t* ptr = reinterpret_cast<uint8_t*>(camInfo->characteristics);
+ const size_t len = get_camera_metadata_size(camInfo->characteristics);
+ mDescription.metadata.insert(mDescription.metadata.end(), ptr, ptr + len);
+ }
+
+ // Initialize parameters.
+ initializeParameters();
+}
+
+EvsMockCamera::~EvsMockCamera() {
+ LOG(DEBUG) << __FUNCTION__;
+ shutdown();
+}
+
+void EvsMockCamera::initializeParameters() {
+ mParams.emplace(
+ CameraParam::BRIGHTNESS,
+ new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
+ mParams.emplace(
+ CameraParam::CONTRAST,
+ new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
+ mParams.emplace(
+ CameraParam::SHARPNESS,
+ new CameraParameterDesc(/* min= */ 0, /* max= */ 255, /* step= */ 1, /* value= */ 255));
+}
+
+// This gets called if another caller "steals" ownership of the camera
+void EvsMockCamera::shutdown() {
+ LOG(DEBUG) << __FUNCTION__;
+
+ // Make sure our output stream is cleaned up
+ // (It really should be already)
+ stopVideoStream_impl();
+
+ // Claim the lock while we work on internal state
+ std::lock_guard lock(mAccessLock);
+
+ // Drop all the graphics buffers we've been using
+ if (mBuffers.size() > 0) {
+ ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+ for (auto&& rec : mBuffers) {
+ if (rec.inUse) {
+ LOG(WARNING) << "WARNING: releasing a buffer remotely owned.";
+ }
+ alloc.free(rec.handle);
+ rec.handle = nullptr;
+ }
+ mBuffers.clear();
+ }
+
+ // Put this object into an unrecoverable error state since somebody else
+ // is going to own the underlying camera now
+ mStreamState = DEAD;
+}
+
+// Methods from ::aidl::android::hardware::automotive::evs::IEvsCamera follow.
+ScopedAStatus EvsMockCamera::getCameraInfo(CameraDesc* _aidl_return) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ // Send back our self description
+ *_aidl_return = mDescription;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::setMaxFramesInFlight(int32_t bufferCount) {
+ LOG(DEBUG) << __FUNCTION__ << ", bufferCount = " << bufferCount;
+ ;
+
+ std::lock_guard lock(mAccessLock);
+
+ // If we've been displaced by another owner of the camera, then we can't do anything else
+ if (mStreamState == DEAD) {
+ LOG(ERROR) << "Ignoring setMaxFramesInFlight call when camera has been lost.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ // We cannot function without at least one video buffer to send data
+ if (bufferCount < 1) {
+ LOG(ERROR) << "Ignoring setMaxFramesInFlight with less than one buffer requested.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ // Update our internal state
+ if (!setAvailableFrames_Locked(bufferCount)) {
+ LOG(ERROR) << "Failed to adjust the maximum number of frames in flight.";
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::startVideoStream(const std::shared_ptr<IEvsCameraStream>& cb) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ if (!cb) {
+ LOG(ERROR) << "A given stream callback is invalid.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ std::lock_guard lock(mAccessLock);
+
+ // If we've been displaced by another owner of the camera, then we can't do anything else
+ if (mStreamState == DEAD) {
+ LOG(ERROR) << "Ignoring startVideoStream call when camera has been lost.";
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
+ }
+
+ if (mStreamState != STOPPED) {
+ LOG(ERROR) << "Ignoring startVideoStream call when a stream is already running.";
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::STREAM_ALREADY_RUNNING));
+ }
+
+ // If the client never indicated otherwise, configure ourselves for a single streaming buffer
+ if (mFramesAllowed < kMinimumBuffersInFlight &&
+ !setAvailableFrames_Locked(kMinimumBuffersInFlight)) {
+ LOG(ERROR) << "Failed to start stream because we couldn't get a graphics buffer";
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int>(EvsResult::BUFFER_NOT_AVAILABLE));
+ }
+
+ // Record the user's callback for use when we have a frame ready
+ mStream = cb;
+
+ // Start the frame generation thread
+ mStreamState = RUNNING;
+ mCaptureThread = std::thread([this]() { generateFrames(); });
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::doneWithFrame(const std::vector<BufferDesc>& list) {
+ std::lock_guard lock(mAccessLock);
+ for (const auto& desc : list) {
+ returnBufferLocked(desc.bufferId);
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::stopVideoStream() {
+ LOG(DEBUG) << __FUNCTION__;
+ return stopVideoStream_impl();
+}
+
+ScopedAStatus EvsMockCamera::stopVideoStream_impl() {
+ std::unique_lock lock(mAccessLock);
+
+ if (mStreamState != RUNNING) {
+ // Safely return here because a stream is not running.
+ return ScopedAStatus::ok();
+ }
+
+ // Tell the GenerateFrames loop we want it to stop
+ mStreamState = STOPPING;
+
+ // Block outside the mutex until the "stop" flag has been acknowledged
+ // We won't send any more frames, but the client might still get some already in flight
+ LOG(DEBUG) << "Waiting for stream thread to end...";
+ lock.unlock();
+ if (mCaptureThread.joinable()) {
+ mCaptureThread.join();
+ }
+ lock.lock();
+
+ mStreamState = STOPPED;
+ mStream = nullptr;
+ LOG(DEBUG) << "Stream marked STOPPED.";
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getExtendedInfo(int32_t opaqueIdentifier,
+ std::vector<uint8_t>* opaqueValue) {
+ const auto it = mExtInfo.find(opaqueIdentifier);
+ if (it == mExtInfo.end()) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ } else {
+ *opaqueValue = mExtInfo[opaqueIdentifier];
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::setExtendedInfo(int32_t opaqueIdentifier,
+ const std::vector<uint8_t>& opaqueValue) {
+ mExtInfo.insert_or_assign(opaqueIdentifier, opaqueValue);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getPhysicalCameraInfo([[maybe_unused]] const std::string& id,
+ CameraDesc* _aidl_return) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ // This method works exactly same as getCameraInfo() in EVS HW module.
+ *_aidl_return = mDescription;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::pauseVideoStream() {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+}
+
+ScopedAStatus EvsMockCamera::resumeVideoStream() {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+}
+
+ScopedAStatus EvsMockCamera::setPrimaryClient() {
+ /* Because EVS HW module reference implementation expects a single client at
+ * a time, this returns a success code always.
+ */
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::forcePrimaryClient(const std::shared_ptr<IEvsDisplay>&) {
+ /* Because EVS HW module reference implementation expects a single client at
+ * a time, this returns a success code always.
+ */
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::unsetPrimaryClient() {
+ /* Because EVS HW module reference implementation expects a single client at
+ * a time, there is no chance that this is called by the secondary client and
+ * therefore returns a success code always.
+ */
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getParameterList(std::vector<CameraParam>* _aidl_return) {
+ if (mCameraInfo) {
+ _aidl_return->resize(mCameraInfo->controls.size());
+ auto idx = 0;
+ for (auto& [name, range] : mCameraInfo->controls) {
+ (*_aidl_return)[idx++] = name;
+ }
+ }
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getIntParameterRange(CameraParam id, ParameterRange* _aidl_return) {
+ auto it = mParams.find(id);
+ if (it == mParams.end()) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+ }
+
+ _aidl_return->min = it->second->range.min;
+ _aidl_return->max = it->second->range.max;
+ _aidl_return->step = it->second->range.step;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::setIntParameter(CameraParam id, int32_t value,
+ std::vector<int32_t>* effectiveValue) {
+ auto it = mParams.find(id);
+ if (it == mParams.end()) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+ }
+
+ // Rounding down to the closest value.
+ int32_t candidate = value / it->second->range.step * it->second->range.step;
+ if (candidate < it->second->range.min || candidate > it->second->range.max) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::INVALID_ARG));
+ }
+
+ it->second->value = candidate;
+ effectiveValue->push_back(candidate);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::getIntParameter(CameraParam id, std::vector<int32_t>* value) {
+ auto it = mParams.find(id);
+ if (it == mParams.end()) {
+ return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::NOT_SUPPORTED));
+ }
+
+ value->push_back(it->second->value);
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus EvsMockCamera::importExternalBuffers(const std::vector<BufferDesc>& buffers,
+ int32_t* _aidl_return) {
+ size_t numBuffersToAdd = buffers.size();
+ if (numBuffersToAdd < 1) {
+ LOG(DEBUG) << "Ignoring a request to import external buffers with an empty list.";
+ return ScopedAStatus::ok();
+ }
+
+ std::lock_guard lock(mAccessLock);
+ if (numBuffersToAdd > (kMaxBuffersInFlight - mFramesAllowed)) {
+ numBuffersToAdd -= (kMaxBuffersInFlight - mFramesAllowed);
+ LOG(WARNING) << "Exceed the limit on the number of buffers. " << numBuffersToAdd
+ << " buffers will be imported only.";
+ }
+
+ ::android::GraphicBufferMapper& mapper = ::android::GraphicBufferMapper::get();
+ const size_t before = mFramesAllowed;
+ for (size_t i = 0; i < numBuffersToAdd; ++i) {
+ auto& b = buffers[i];
+ const AHardwareBuffer_Desc* pDesc =
+ reinterpret_cast<const AHardwareBuffer_Desc*>(&b.buffer.description);
+
+ buffer_handle_t handleToImport = ::android::dupFromAidl(b.buffer.handle);
+ buffer_handle_t handleToStore = nullptr;
+ if (handleToImport == nullptr) {
+ LOG(WARNING) << "Failed to duplicate a memory handle. Ignoring a buffer " << b.bufferId;
+ continue;
+ }
+
+ ::android::status_t result =
+ mapper.importBuffer(handleToImport, pDesc->width, pDesc->height, pDesc->layers,
+ pDesc->format, pDesc->usage, pDesc->stride, &handleToStore);
+ if (result != ::android::NO_ERROR || handleToStore == nullptr) {
+ LOG(WARNING) << "Failed to import a buffer " << b.bufferId;
+ continue;
+ }
+
+ bool stored = false;
+ for (auto&& rec : mBuffers) {
+ if (rec.handle != nullptr) {
+ continue;
+ }
+
+ // Use this existing entry.
+ rec.handle = handleToStore;
+ rec.inUse = false;
+ stored = true;
+ break;
+ }
+
+ if (!stored) {
+ // Add a BufferRecord wrapping this handle to our set of available buffers.
+ mBuffers.push_back(BufferRecord(handleToStore));
+ }
+ ++mFramesAllowed;
+ }
+
+ *_aidl_return = mFramesAllowed - before;
+ return ScopedAStatus::ok();
+}
+
+bool EvsMockCamera::setAvailableFrames_Locked(unsigned bufferCount) {
+ if (bufferCount < 1) {
+ LOG(ERROR) << "Ignoring request to set buffer count to zero";
+ return false;
+ }
+ if (bufferCount > kMaxBuffersInFlight) {
+ LOG(ERROR) << "Rejecting buffer request in excess of internal limit";
+ return false;
+ }
+
+ // Is an increase required?
+ if (mFramesAllowed < bufferCount) {
+ // An increase is required
+ auto needed = bufferCount - mFramesAllowed;
+ LOG(INFO) << "Allocating " << needed << " buffers for camera frames";
+
+ auto added = increaseAvailableFrames_Locked(needed);
+ if (added != needed) {
+ // If we didn't add all the frames we needed, then roll back to the previous state
+ LOG(ERROR) << "Rolling back to previous frame queue size";
+ decreaseAvailableFrames_Locked(added);
+ return false;
+ }
+ } else if (mFramesAllowed > bufferCount) {
+ // A decrease is required
+ auto framesToRelease = mFramesAllowed - bufferCount;
+ LOG(INFO) << "Returning " << framesToRelease << " camera frame buffers";
+
+ auto released = decreaseAvailableFrames_Locked(framesToRelease);
+ if (released != framesToRelease) {
+ // This shouldn't happen with a properly behaving client because the client
+ // should only make this call after returning sufficient outstanding buffers
+ // to allow a clean resize.
+ LOG(ERROR) << "Buffer queue shrink failed -- too many buffers currently in use?";
+ }
+ }
+
+ return true;
+}
+
+unsigned EvsMockCamera::increaseAvailableFrames_Locked(unsigned numToAdd) {
+ // Acquire the graphics buffer allocator
+ ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+
+ unsigned added = 0;
+ while (added < numToAdd) {
+ unsigned pixelsPerLine = 0;
+ buffer_handle_t memHandle = nullptr;
+ auto result = alloc.allocate(mWidth, mHeight, mFormat, 1, mUsage, &memHandle,
+ &pixelsPerLine, 0, "EvsMockCamera");
+ if (result != ::android::NO_ERROR) {
+ LOG(ERROR) << "Error " << result << " allocating " << mWidth << " x " << mHeight
+ << " graphics buffer";
+ break;
+ }
+ if (memHandle == nullptr) {
+ LOG(ERROR) << "We didn't get a buffer handle back from the allocator";
+ break;
+ }
+ if (mStride > 0) {
+ if (mStride != pixelsPerLine) {
+ LOG(ERROR) << "We did not expect to get buffers with different strides!";
+ }
+ } else {
+ // Gralloc defines stride in terms of pixels per line
+ mStride = pixelsPerLine;
+ }
+
+ // Find a place to store the new buffer
+ auto stored = false;
+ for (auto&& rec : mBuffers) {
+ if (rec.handle == nullptr) {
+ // Use this existing entry
+ rec.handle = memHandle;
+ rec.inUse = false;
+ stored = true;
+ break;
+ }
+ }
+ if (!stored) {
+ // Add a BufferRecord wrapping this handle to our set of available buffers
+ mBuffers.push_back(BufferRecord(memHandle));
+ }
+
+ ++mFramesAllowed;
+ ++added;
+ }
+
+ return added;
+}
+
+unsigned EvsMockCamera::decreaseAvailableFrames_Locked(unsigned numToRemove) {
+ // Acquire the graphics buffer allocator
+ ::android::GraphicBufferAllocator& alloc(::android::GraphicBufferAllocator::get());
+
+ unsigned removed = 0;
+ for (auto&& rec : mBuffers) {
+ // Is this record not in use, but holding a buffer that we can free?
+ if ((rec.inUse == false) && (rec.handle != nullptr)) {
+ // Release buffer and update the record so we can recognize it as "empty"
+ alloc.free(rec.handle);
+ rec.handle = nullptr;
+
+ --mFramesAllowed;
+ ++removed;
+
+ if (removed == numToRemove) {
+ break;
+ }
+ }
+ }
+
+ return removed;
+}
+
+// This is the asynchronous frame generation thread that runs in parallel with the
+// main serving thread. There is one for each active camera instance.
+void EvsMockCamera::generateFrames() {
+ LOG(DEBUG) << "Frame generation loop started.";
+
+ unsigned idx = 0;
+ while (true) {
+ bool timeForFrame = false;
+ const nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ // Lock scope for updating shared state
+ {
+ std::lock_guard lock(mAccessLock);
+
+ if (mStreamState != RUNNING) {
+ // Break out of our main thread loop
+ break;
+ }
+
+ // Are we allowed to issue another buffer?
+ if (mFramesInUse >= mFramesAllowed) {
+ // Can't do anything right now -- skip this frame
+ LOG(WARNING) << "Skipped a frame because too many are in flight.";
+ } else {
+ // Identify an available buffer to fill
+ for (idx = 0; idx < mBuffers.size(); idx++) {
+ if (!mBuffers[idx].inUse) {
+ if (mBuffers[idx].handle != nullptr) {
+ // Found an available record, so stop looking
+ break;
+ }
+ }
+ }
+ if (idx >= mBuffers.size()) {
+ // This shouldn't happen since we already checked mFramesInUse vs mFramesAllowed
+ ALOGE("Failed to find an available buffer slot\n");
+ } else {
+ // We're going to make the frame busy
+ mBuffers[idx].inUse = true;
+ mFramesInUse++;
+ timeForFrame = true;
+ }
+ }
+ }
+
+ if (timeForFrame) {
+ using AidlPixelFormat = ::aidl::android::hardware::graphics::common::PixelFormat;
+
+ // Assemble the buffer description we'll transmit below
+ buffer_handle_t memHandle = mBuffers[idx].handle;
+ BufferDesc newBuffer = {
+ .buffer =
+ {
+ .description =
+ {
+ .width = static_cast<int32_t>(mWidth),
+ .height = static_cast<int32_t>(mHeight),
+ .layers = 1,
+ .format = static_cast<AidlPixelFormat>(mFormat),
+ .usage = static_cast<BufferUsage>(mUsage),
+ .stride = static_cast<int32_t>(mStride),
+ },
+ .handle = ::android::dupToAidl(memHandle),
+ },
+ .bufferId = static_cast<int32_t>(idx),
+ .deviceId = mDescription.id,
+ .timestamp = static_cast<int64_t>(::android::elapsedRealtimeNano() *
+ 1e+3), // timestamps is in microseconds
+ };
+
+ // Write test data into the image buffer
+ fillMockFrame(memHandle, reinterpret_cast<const AHardwareBuffer_Desc*>(
+ &newBuffer.buffer.description));
+
+ // Issue the (asynchronous) callback to the client -- can't be holding the lock
+ auto flag = false;
+ if (mStream) {
+ std::vector<BufferDesc> frames;
+ frames.push_back(std::move(newBuffer));
+ flag = mStream->deliverFrame(frames).isOk();
+ }
+
+ if (flag) {
+ LOG(DEBUG) << "Delivered " << memHandle << ", id = " << mBuffers[idx].handle;
+ } else {
+ // This can happen if the client dies and is likely unrecoverable.
+ // To avoid consuming resources generating failing calls, we stop sending
+ // frames. Note, however, that the stream remains in the "STREAMING" state
+ // until cleaned up on the main thread.
+ LOG(ERROR) << "Frame delivery call failed in the transport layer.";
+
+ // Since we didn't actually deliver it, mark the frame as available
+ std::lock_guard<std::mutex> lock(mAccessLock);
+ mBuffers[idx].inUse = false;
+ mFramesInUse--;
+ }
+ }
+
+ // We arbitrarily choose to generate frames at 15 fps to ensure we pass the 10fps test
+ // requirement
+ static const int kTargetFrameRate = 15;
+ static const nsecs_t kTargetFrameIntervalUs = 1000 * 1000 / kTargetFrameRate;
+ const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ const nsecs_t elapsedTimeUs = (now - startTime) / 1000;
+ const nsecs_t sleepDurationUs = kTargetFrameIntervalUs - elapsedTimeUs;
+ if (sleepDurationUs > 0) {
+ usleep(sleepDurationUs);
+ }
+ }
+
+ // If we've been asked to stop, send an event to signal the actual end of stream
+ EvsEventDesc event = {
+ .aType = EvsEventType::STREAM_STOPPED,
+ };
+ if (!mStream->notify(event).isOk()) {
+ ALOGE("Error delivering end of stream marker");
+ }
+
+ return;
+}
+
+void EvsMockCamera::fillMockFrame(buffer_handle_t handle, const AHardwareBuffer_Desc* pDesc) {
+ // Lock our output buffer for writing
+ uint32_t* pixels = nullptr;
+ ::android::GraphicBufferMapper& mapper = ::android::GraphicBufferMapper::get();
+ mapper.lock(handle, GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_SW_READ_NEVER,
+ ::android::Rect(pDesc->width, pDesc->height), (void**)&pixels);
+
+ // If we failed to lock the pixel buffer, we're about to crash, but log it first
+ if (!pixels) {
+ ALOGE("Camera failed to gain access to image buffer for writing");
+ return;
+ }
+
+ // Fill in the test pixels; the colorbar in ABGR format
+ for (unsigned row = 0; row < pDesc->height; row++) {
+ for (unsigned col = 0; col < pDesc->width; col++) {
+ const uint32_t index = col * kNumColors / pDesc->width;
+ pixels[col] = kColors[index];
+ }
+ // Point to the next row
+ // NOTE: stride retrieved from gralloc is in units of pixels
+ pixels = pixels + pDesc->stride;
+ }
+
+ // Release our output buffer
+ mapper.unlock(handle);
+}
+
+void EvsMockCamera::returnBufferLocked(const uint32_t bufferId) {
+ if (bufferId >= mBuffers.size()) {
+ ALOGE("ignoring doneWithFrame called with invalid bufferId %d (max is %zu)", bufferId,
+ mBuffers.size() - 1);
+ return;
+ }
+
+ if (!mBuffers[bufferId].inUse) {
+ ALOGE("ignoring doneWithFrame called on frame %d which is already free", bufferId);
+ return;
+ }
+
+ // Mark the frame as available
+ mBuffers[bufferId].inUse = false;
+ mFramesInUse--;
+
+ // If this frame's index is high in the array, try to move it down
+ // to improve locality after mFramesAllowed has been reduced.
+ if (bufferId >= mFramesAllowed) {
+ // Find an empty slot lower in the array (which should always exist in this case)
+ for (auto&& rec : mBuffers) {
+ if (rec.handle == nullptr) {
+ rec.handle = mBuffers[bufferId].handle;
+ mBuffers[bufferId].handle = nullptr;
+ break;
+ }
+ }
+ }
+}
+
+std::shared_ptr<EvsMockCamera> EvsMockCamera::Create(const char* deviceName) {
+ std::unique_ptr<ConfigManager::CameraInfo> nullCamInfo = nullptr;
+
+ return Create(deviceName, nullCamInfo);
+}
+
+std::shared_ptr<EvsMockCamera> EvsMockCamera::Create(
+ const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
+ [[maybe_unused]] const Stream* streamCfg) {
+ std::shared_ptr<EvsMockCamera> c =
+ ndk::SharedRefBase::make<EvsMockCamera>(Sigil{}, deviceName, camInfo);
+ if (!c) {
+ LOG(ERROR) << "Failed to instantiate EvsMockCamera.";
+ return nullptr;
+ }
+
+ // Use the first resolution from the list for the testing
+ // TODO(b/214835237): Uses a given Stream configuration to choose the best
+ // stream configuration.
+ auto it = camInfo->streamConfigurations.begin();
+ c->mWidth = it->second.width;
+ c->mHeight = it->second.height;
+ c->mDescription.vendorFlags = 0xFFFFFFFF; // Arbitrary test value
+
+ c->mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+ c->mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE |
+ GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY;
+
+ return c;
+}
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/GlWrapper.cpp b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
new file mode 100644
index 0000000..0ee5ecb
--- /dev/null
+++ b/automotive/evs/aidl/impl/default/src/GlWrapper.cpp
@@ -0,0 +1,465 @@
+/*
+ * 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 "GlWrapper.h"
+
+#include <aidl/android/frameworks/automotive/display/DisplayDesc.h>
+#include <aidl/android/hardware/graphics/common/HardwareBufferDescription.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <ui/DisplayMode.h>
+#include <ui/DisplayState.h>
+#include <ui/GraphicBuffer.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+
+#include <utility>
+
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::DisplayDesc;
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::frameworks::automotive::display::Rotation;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::graphics::common::HardwareBufferDescription;
+using ::android::GraphicBuffer;
+using ::android::sp;
+
+constexpr const char vertexShaderSource[] =
+ "attribute vec4 pos; \n"
+ "attribute vec2 tex; \n"
+ "varying vec2 uv; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = pos; \n"
+ " uv = tex; \n"
+ "} \n";
+
+constexpr const char pixelShaderSource[] =
+ "precision mediump float; \n"
+ "uniform sampler2D tex; \n"
+ "varying vec2 uv; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = texture2D(tex, uv);\n"
+ "} \n";
+
+const char* getEGLError(void) {
+ switch (eglGetError()) {
+ case EGL_SUCCESS:
+ return "EGL_SUCCESS";
+ case EGL_NOT_INITIALIZED:
+ return "EGL_NOT_INITIALIZED";
+ case EGL_BAD_ACCESS:
+ return "EGL_BAD_ACCESS";
+ case EGL_BAD_ALLOC:
+ return "EGL_BAD_ALLOC";
+ case EGL_BAD_ATTRIBUTE:
+ return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_CONTEXT:
+ return "EGL_BAD_CONTEXT";
+ case EGL_BAD_CONFIG:
+ return "EGL_BAD_CONFIG";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "EGL_BAD_CURRENT_SURFACE";
+ case EGL_BAD_DISPLAY:
+ return "EGL_BAD_DISPLAY";
+ case EGL_BAD_SURFACE:
+ return "EGL_BAD_SURFACE";
+ case EGL_BAD_MATCH:
+ return "EGL_BAD_MATCH";
+ case EGL_BAD_PARAMETER:
+ return "EGL_BAD_PARAMETER";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "EGL_BAD_NATIVE_WINDOW";
+ case EGL_CONTEXT_LOST:
+ return "EGL_CONTEXT_LOST";
+ default:
+ return "Unknown error";
+ }
+}
+
+// Given shader source, load and compile it
+GLuint loadShader(GLenum type, const char* shaderSrc) {
+ // Create the shader object
+ GLuint shader = glCreateShader(type);
+ if (shader == 0) {
+ return 0;
+ }
+
+ // Load and compile the shader
+ glShaderSource(shader, 1, &shaderSrc, nullptr);
+ glCompileShader(shader);
+
+ // Verify the compilation worked as expected
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ LOG(ERROR) << "Error compiling shader";
+
+ GLint size = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size);
+ if (size > 0) {
+ // Get and report the error message
+ char* infoLog = (char*)malloc(size);
+ glGetShaderInfoLog(shader, size, nullptr, infoLog);
+ LOG(ERROR) << " msg:" << std::endl << infoLog;
+ free(infoLog);
+ }
+
+ glDeleteShader(shader);
+ return 0;
+ }
+
+ return shader;
+}
+
+// Create a program object given vertex and pixels shader source
+GLuint buildShaderProgram(const char* vtxSrc, const char* pxlSrc) {
+ GLuint program = glCreateProgram();
+ if (program == 0) {
+ LOG(ERROR) << "Failed to allocate program object";
+ return 0;
+ }
+
+ // Compile the shaders and bind them to this program
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vtxSrc);
+ if (vertexShader == 0) {
+ LOG(ERROR) << "Failed to load vertex shader";
+ glDeleteProgram(program);
+ return 0;
+ }
+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pxlSrc);
+ if (pixelShader == 0) {
+ LOG(ERROR) << "Failed to load pixel shader";
+ glDeleteProgram(program);
+ glDeleteShader(vertexShader);
+ return 0;
+ }
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, pixelShader);
+
+ glBindAttribLocation(program, 0, "pos");
+ glBindAttribLocation(program, 1, "tex");
+
+ // Link the program
+ glLinkProgram(program);
+ GLint linked = 0;
+ glGetProgramiv(program, GL_LINK_STATUS, &linked);
+ if (!linked) {
+ LOG(ERROR) << "Error linking program";
+ GLint size = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &size);
+ if (size > 0) {
+ // Get and report the error message
+ char* infoLog = (char*)malloc(size);
+ glGetProgramInfoLog(program, size, nullptr, infoLog);
+ LOG(ERROR) << " msg: " << infoLog;
+ free(infoLog);
+ }
+
+ glDeleteProgram(program);
+ glDeleteShader(vertexShader);
+ glDeleteShader(pixelShader);
+ return 0;
+ }
+
+ return program;
+}
+
+::android::sp<HGraphicBufferProducer> convertNativeHandleToHGBP(const NativeHandle& aidlHandle) {
+ native_handle_t* handle = ::android::dupFromAidl(aidlHandle);
+ if (handle->numFds != 0 || handle->numInts < std::ceil(sizeof(size_t) / sizeof(int))) {
+ LOG(ERROR) << "Invalid native handle";
+ return nullptr;
+ }
+ ::android::hardware::hidl_vec<uint8_t> halToken;
+ halToken.setToExternal(reinterpret_cast<uint8_t*>(const_cast<int*>(&(handle->data[1]))),
+ handle->data[0]);
+ ::android::sp<HGraphicBufferProducer> hgbp =
+ HGraphicBufferProducer::castFrom(::android::retrieveHalInterface(halToken));
+ return std::move(hgbp);
+}
+
+} // namespace
+
+namespace aidl::android::hardware::automotive::evs::implementation {
+
+// Main entry point
+bool GlWrapper::initialize(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy,
+ uint64_t displayId) {
+ LOG(DEBUG) << __FUNCTION__;
+
+ if (!pWindowProxy) {
+ LOG(ERROR) << "Could not get ICarDisplayProxy.";
+ return false;
+ }
+
+ DisplayDesc displayDesc;
+ auto status = pWindowProxy->getDisplayInfo(displayId, &displayDesc);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Failed to read the display information";
+ return false;
+ }
+
+ mWidth = displayDesc.width;
+ mHeight = displayDesc.height;
+ if ((displayDesc.orientation != Rotation::ROTATION_0) &&
+ (displayDesc.orientation != Rotation::ROTATION_180)) {
+ std::swap(mWidth, mHeight);
+ }
+ LOG(INFO) << "Display resolution is " << mWidth << "x" << mHeight;
+
+ NativeHandle aidlHandle;
+ status = pWindowProxy->getHGraphicBufferProducer(displayId, &aidlHandle);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Failed to get IGraphicBufferProducer from ICarDisplayProxy.";
+ return false;
+ }
+
+ mGfxBufferProducer = convertNativeHandleToHGBP(aidlHandle);
+ if (!mGfxBufferProducer) {
+ LOG(ERROR) << "Failed to convert a NativeHandle to HGBP.";
+ return false;
+ }
+
+ mSurfaceHolder = getSurfaceFromHGBP(mGfxBufferProducer);
+ if (mSurfaceHolder == nullptr) {
+ LOG(ERROR) << "Failed to get a Surface from HGBP.";
+ return false;
+ }
+
+ mWindow = getNativeWindow(mSurfaceHolder.get());
+ if (mWindow == nullptr) {
+ LOG(ERROR) << "Failed to get a native window from Surface.";
+ return false;
+ }
+
+ // Set up our OpenGL ES context associated with the default display
+ mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (mDisplay == EGL_NO_DISPLAY) {
+ LOG(ERROR) << "Failed to get egl display";
+ return false;
+ }
+
+ EGLint major = 2;
+ EGLint minor = 0;
+ if (!eglInitialize(mDisplay, &major, &minor)) {
+ LOG(ERROR) << "Failed to initialize EGL: " << getEGLError();
+ return false;
+ }
+
+ const EGLint config_attribs[] = {
+ // clang-format off
+ // Tag Value
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_DEPTH_SIZE, 0,
+ EGL_NONE
+ // clang-format on
+ };
+
+ // Pick the default configuration without constraints (is this good enough?)
+ EGLConfig egl_config = {0};
+ EGLint numConfigs = -1;
+ eglChooseConfig(mDisplay, config_attribs, &egl_config, 1, &numConfigs);
+ if (numConfigs != 1) {
+ LOG(ERROR) << "Didn't find a suitable format for our display window, " << getEGLError();
+ return false;
+ }
+
+ // Create the EGL render target surface
+ mSurface = eglCreateWindowSurface(mDisplay, egl_config, mWindow, nullptr);
+ if (mSurface == EGL_NO_SURFACE) {
+ LOG(ERROR) << "eglCreateWindowSurface failed, " << getEGLError();
+ return false;
+ }
+
+ // Create the EGL context
+ // NOTE: Our shader is (currently at least) written to require version 3, so this
+ // is required.
+ const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
+ mContext = eglCreateContext(mDisplay, egl_config, EGL_NO_CONTEXT, context_attribs);
+ if (mContext == EGL_NO_CONTEXT) {
+ LOG(ERROR) << "Failed to create OpenGL ES Context: " << getEGLError();
+ return false;
+ }
+
+ // Activate our render target for drawing
+ if (!eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)) {
+ LOG(ERROR) << "Failed to make the OpenGL ES Context current: " << getEGLError();
+ return false;
+ }
+
+ // Create the shader program for our simple pipeline
+ mShaderProgram = buildShaderProgram(vertexShaderSource, pixelShaderSource);
+ if (!mShaderProgram) {
+ LOG(ERROR) << "Failed to build shader program: " << getEGLError();
+ return false;
+ }
+
+ // Create a GL texture that will eventually wrap our externally created texture surface(s)
+ glGenTextures(1, &mTextureMap);
+ if (mTextureMap <= 0) {
+ LOG(ERROR) << "Didn't get a texture handle allocated: " << getEGLError();
+ return false;
+ }
+
+ // Turn off mip-mapping for the created texture surface
+ // (the inbound camera imagery doesn't have MIPs)
+ glBindTexture(GL_TEXTURE_2D, mTextureMap);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+void GlWrapper::shutdown() {
+ // Drop our device textures
+ if (mKHRimage != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mDisplay, mKHRimage);
+ mKHRimage = EGL_NO_IMAGE_KHR;
+ }
+
+ // Release all GL resources
+ if (eglGetCurrentContext() == mContext) {
+ eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ }
+ eglDestroySurface(mDisplay, mSurface);
+ eglDestroyContext(mDisplay, mContext);
+ eglTerminate(mDisplay);
+ mSurface = EGL_NO_SURFACE;
+ mContext = EGL_NO_CONTEXT;
+ mDisplay = EGL_NO_DISPLAY;
+
+ // Release the window
+ mSurfaceHolder = nullptr;
+}
+
+void GlWrapper::showWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
+ if (pWindowProxy) {
+ pWindowProxy->showWindow(id);
+ } else {
+ LOG(ERROR) << "ICarDisplayProxy is not available.";
+ }
+}
+
+void GlWrapper::hideWindow(const std::shared_ptr<ICarDisplayProxy>& pWindowProxy, uint64_t id) {
+ if (pWindowProxy) {
+ pWindowProxy->hideWindow(id);
+ } else {
+ LOG(ERROR) << "ICarDisplayProxy is not available.";
+ }
+}
+
+bool GlWrapper::updateImageTexture(buffer_handle_t handle,
+ const HardwareBufferDescription& description) {
+ if (mKHRimage != EGL_NO_IMAGE_KHR) {
+ return true;
+ }
+
+ // Create a temporary GraphicBuffer to wrap the provided handle.
+ sp<GraphicBuffer> pGfxBuffer =
+ new GraphicBuffer(description.width, description.height,
+ static_cast<::android::PixelFormat>(description.format),
+ description.layers, static_cast<uint32_t>(description.usage),
+ description.stride, const_cast<native_handle_t*>(handle),
+ /* keepOwnership= */ false);
+ if (!pGfxBuffer) {
+ LOG(ERROR) << "Failed to allocate GraphicBuffer to wrap our native handle";
+ return false;
+ }
+
+ // Get a GL compatible reference to the graphics buffer we've been given
+ EGLint eglImageAttributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
+ EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(pGfxBuffer->getNativeBuffer());
+ mKHRimage = eglCreateImageKHR(mDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf,
+ eglImageAttributes);
+ if (mKHRimage == EGL_NO_IMAGE_KHR) {
+ LOG(ERROR) << "Error creating EGLImage: " << getEGLError();
+ return false;
+ }
+
+ // Update the texture handle we already created to refer to this gralloc buffer
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mTextureMap);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(mKHRimage));
+
+ return true;
+}
+
+void GlWrapper::renderImageToScreen() {
+ // Set the viewport
+ glViewport(0, 0, mWidth, mHeight);
+
+ // Clear the color buffer
+ glClearColor(0.1f, 0.5f, 0.1f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Select our screen space simple texture shader
+ glUseProgram(mShaderProgram);
+
+ // Bind the texture and assign it to the shader's sampler
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mTextureMap);
+ GLint sampler = glGetUniformLocation(mShaderProgram, "tex");
+ glUniform1i(sampler, 0);
+
+ // We want our image to show up opaque regardless of alpha values
+ glDisable(GL_BLEND);
+
+ // Draw a rectangle on the screen
+ GLfloat vertsCarPos[] = {
+ // clang-format off
+ -0.8, 0.8, 0.0f, // left top in window space
+ 0.8, 0.8, 0.0f, // right top
+ -0.8, -0.8, 0.0f, // left bottom
+ 0.8, -0.8, 0.0f // right bottom
+ // clang-format on
+ };
+
+ // NOTE: We didn't flip the image in the texture, so V=0 is actually the top of the image
+ GLfloat vertsCarTex[] = {
+ // clang-format off
+ 0.0f, 0.0f, // left top
+ 1.0f, 0.0f, // right top
+ 0.0f, 1.0f, // left bottom
+ 1.0f, 1.0f // right bottom
+ // clang-format on
+ };
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertsCarPos);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertsCarTex);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ // Clean up and flip the rendered result to the front so it is visible
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+
+ glFinish();
+
+ if (eglSwapBuffers(mDisplay, mSurface) == EGL_FALSE) {
+ LOG(WARNING) << "Failed to swap EGL buffers, " << getEGLError();
+ }
+}
+
+} // namespace aidl::android::hardware::automotive::evs::implementation
diff --git a/automotive/evs/aidl/impl/default/src/service.cpp b/automotive/evs/aidl/impl/default/src/service.cpp
index 0a0913f..7532d87 100644
--- a/automotive/evs/aidl/impl/default/src/service.cpp
+++ b/automotive/evs/aidl/impl/default/src/service.cpp
@@ -14,38 +14,75 @@
* limitations under the License.
*/
-#define LOG_TAG "EvsService"
-
-#include <DefaultEvsEnumerator.h>
+#include "EvsEnumerator.h"
+#include "EvsGlDisplay.h"
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <utils/Log.h>
-using ::aidl::android::hardware::automotive::evs::implementation::DefaultEvsEnumerator;
+#include <unistd.h>
-int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
- std::shared_ptr<DefaultEvsEnumerator> vhal = ndk::SharedRefBase::make<DefaultEvsEnumerator>();
+#include <atomic>
+#include <cstdlib>
+#include <string_view>
- ALOGI("Registering as service...");
- binder_exception_t err =
- AServiceManager_addService(vhal->asBinder().get(), "android.hardware.automotive.evs");
+namespace {
+
+using ::aidl::android::frameworks::automotive::display::ICarDisplayProxy;
+using ::aidl::android::hardware::automotive::evs::implementation::EvsEnumerator;
+
+constexpr std::string_view kDisplayServiceInstanceName = "/default";
+constexpr std::string_view kHwInstanceName = "/hw/0";
+constexpr int kNumBinderThreads = 1;
+
+} // namespace
+
+int main() {
+ LOG(INFO) << "EVS Hardware Enumerator service is starting";
+
+ const std::string displayServiceInstanceName =
+ std::string(ICarDisplayProxy::descriptor) + std::string(kDisplayServiceInstanceName);
+ if (!AServiceManager_isDeclared(displayServiceInstanceName.data())) {
+ // TODO: We may just want to disable EVS display.
+ LOG(ERROR) << displayServiceInstanceName << " is required.";
+ return EXIT_FAILURE;
+ }
+
+ std::shared_ptr<ICarDisplayProxy> displayService = ICarDisplayProxy::fromBinder(
+ ::ndk::SpAIBinder(AServiceManager_waitForService(displayServiceInstanceName.data())));
+ if (!displayService) {
+ LOG(ERROR) << "Cannot use " << displayServiceInstanceName << ". Exiting.";
+ return EXIT_FAILURE;
+ }
+
+ // Register our service -- if somebody is already registered by our name,
+ // they will be killed (their thread pool will throw an exception).
+ std::shared_ptr<EvsEnumerator> service =
+ ndk::SharedRefBase::make<EvsEnumerator>(displayService);
+ if (!service) {
+ LOG(ERROR) << "Failed to instantiate the service";
+ return EXIT_FAILURE;
+ }
+
+ const std::string instanceName =
+ std::string(EvsEnumerator::descriptor) + std::string(kHwInstanceName);
+ auto err = AServiceManager_addService(service->asBinder().get(), instanceName.data());
if (err != EX_NONE) {
- ALOGE("failed to register android.hardware.automotive.evs service, exception: %d", err);
- return 1;
+ LOG(ERROR) << "Failed to register " << instanceName << ", exception = " << err;
+ return EXIT_FAILURE;
}
- if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
- ALOGE("%s", "failed to set thread pool max thread count");
- return 1;
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(kNumBinderThreads)) {
+ LOG(ERROR) << "Failed to set thread pool";
+ return EXIT_FAILURE;
}
+
ABinderProcess_startThreadPool();
-
- ALOGI("Evs Service Ready");
+ LOG(INFO) << "EVS Hardware Enumerator is ready";
ABinderProcess_joinThreadPool();
-
- ALOGI("Evs Service Exiting");
-
- return 0;
+ // In normal operation, we don't expect the thread pool to exit
+ LOG(INFO) << "EVS Hardware Enumerator is shutting down";
+ return EXIT_SUCCESS;
}
diff --git a/automotive/evs/aidl/vts/Android.bp b/automotive/evs/aidl/vts/Android.bp
index e2e5b93..e50c913 100644
--- a/automotive/evs/aidl/vts/Android.bp
+++ b/automotive/evs/aidl/vts/Android.bp
@@ -30,6 +30,7 @@
],
defaults: [
"VtsHalTargetTestDefaults",
+ "android.hardware.graphics.common-ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
shared_libs: [
@@ -40,9 +41,8 @@
],
static_libs: [
"android.hardware.automotive.evs@common-default-lib",
- "android.hardware.automotive.evs-V1-ndk",
+ "android.hardware.automotive.evs-V2-ndk",
"android.hardware.common-V2-ndk",
- "android.hardware.graphics.common-V4-ndk",
"libaidlcommonsupport",
],
test_suites: [
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 3cab204..a6d99ad 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -51,6 +51,7 @@
#include <ui/GraphicBufferAllocator.h>
#include <utils/Timers.h>
+#include <chrono>
#include <deque>
#include <thread>
#include <unordered_set>
@@ -619,6 +620,7 @@
getPhysicalCameraIds(cam.id, isLogicalCam);
if (mIsHwModule && isLogicalCam) {
LOG(INFO) << "Skip a logical device " << cam.id << " for HW target.";
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
continue;
}
@@ -1437,7 +1439,8 @@
ASSERT_TRUE(pCam1->getParameterList(&cam1Cmds).isOk());
if (cam0Cmds.size() < 1 || cam1Cmds.size() < 1) {
// Cannot execute this test.
- return;
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+ continue;
}
// Set up a frame receiver object which will fire up its own thread.
@@ -2195,6 +2198,203 @@
}
}
+/*
+ * DisplayOpen:
+ * Test both clean shut down and "aggressive open" device stealing behavior.
+ */
+TEST_P(EvsAidlTest, DisplayOpen) {
+ LOG(INFO) << "Starting DisplayOpen test";
+
+ // Request available display IDs.
+ std::vector<uint8_t> displayIds;
+ ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
+ EXPECT_GT(displayIds.size(), 0);
+
+ for (const auto displayId : displayIds) {
+ std::shared_ptr<IEvsDisplay> pDisplay;
+
+ // Request exclusive access to each EVS display, then let it go.
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+
+ {
+ // Ask the display what its name is.
+ DisplayDesc desc;
+ ASSERT_TRUE(pDisplay->getDisplayInfo(&desc).isOk());
+ LOG(DEBUG) << "Found display " << desc.id;
+ }
+
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+
+ // Ensure we can reopen the display after it has been closed.
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+
+ // Open the display while its already open -- ownership should be transferred.
+ std::shared_ptr<IEvsDisplay> pDisplay2;
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay2).isOk());
+ ASSERT_NE(pDisplay2, nullptr);
+
+ {
+ // Ensure the old display properly reports its assassination.
+ DisplayState badState;
+ EXPECT_TRUE(pDisplay->getDisplayState(&badState).isOk());
+ EXPECT_EQ(badState, DisplayState::DEAD);
+ }
+
+ // Close only the newest display instance -- the other should already be a zombie.
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay2).isOk());
+
+ // Finally, validate that we can open the display after the provoked failure above.
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+ }
+}
+
+/*
+ * DisplayStates:
+ * Validate that display states transition as expected and can be queried from either the display
+ * object itself or the owning enumerator.
+ */
+TEST_P(EvsAidlTest, DisplayStates) {
+ using std::literals::chrono_literals::operator""ms;
+
+ LOG(INFO) << "Starting DisplayStates test";
+
+ // Request available display IDs.
+ std::vector<uint8_t> displayIds;
+ ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
+ EXPECT_GT(displayIds.size(), 0);
+
+ for (const auto displayId : displayIds) {
+ // Ensure the display starts in the expected state.
+ {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+
+ // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object.
+ {
+ // Request exclusive access to the EVS display.
+ std::shared_ptr<IEvsDisplay> pDisplay;
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Activate the display.
+ EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+ }
+ {
+ DisplayState state;
+ EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Get the output buffer we'd use to display the imagery.
+ BufferDesc tgtBuffer;
+ ASSERT_TRUE(pDisplay->getTargetBuffer(&tgtBuffer).isOk());
+
+ // Send the target buffer back for display (we didn't actually fill anything).
+ EXPECT_TRUE(pDisplay->returnTargetBufferForDisplay(tgtBuffer).isOk());
+
+ // Sleep for a tenth of a second to ensure the driver has time to get the image
+ // displayed.
+ std::this_thread::sleep_for(100ms);
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE);
+ }
+ {
+ DisplayState state;
+ EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Turn off the display.
+ EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());
+ std::this_thread::sleep_for(100ms);
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ }
+ {
+ DisplayState state;
+ EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Close the display.
+ mEnumerator->closeDisplay(pDisplay);
+ }
+
+ // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
+ // object to be destroyed, we should be back to the "not open" state.
+ // NOTE: If we want this to pass without the sleep above, we'd have to add the
+ // (now recommended) closeDisplay() call instead of relying on the smarter pointer
+ // going out of scope. I've not done that because I want to verify that the deletion
+ // of the object does actually clean up (eventually).
+ {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, EvsAidlTest,
diff --git a/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp b/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
index 58423c8..7f90501 100644
--- a/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
+++ b/automotive/evs/common/utils/default/test/fuzz/FormatConvertFuzzer.cpp
@@ -32,9 +32,10 @@
// API have a requirement that width must be divied by 16 except yuyvtorgb
int min_height = 2;
- int max_height = (image_pixel_size / 16) & ~(1); // must be even number
+ int max_height = (image_pixel_size / 16);
int height = fdp.ConsumeIntegralInRange<uint32_t>(min_height, max_height);
- int width = (image_pixel_size / height) & ~(16); // must be divisible by 16
+ height &= ~(1); // must be even number
+ int width = (image_pixel_size / height) & ~(0xF); // must be divisible by 16
uint8_t* src = (uint8_t*)(data + 4);
uint32_t* tgt = (uint32_t*)malloc(sizeof(uint32_t) * image_pixel_size);
diff --git a/automotive/ivn_android_device/aidl/Android.bp b/automotive/ivn_android_device/aidl/Android.bp
new file mode 100644
index 0000000..95a0c73
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/Android.bp
@@ -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 {
+ // 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.automotive.ivn",
+ vendor_available: true,
+ srcs: [
+ "android/hardware/automotive/ivn/*.aidl",
+ ],
+ frozen: false,
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.car.framework",
+ ],
+ },
+ },
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/ConnectProtocol.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/ConnectProtocol.aidl
new file mode 100644
index 0000000..80d7a2a
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/ConnectProtocol.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.automotive.ivn;
+@Backing(type="int") @VintfStability
+enum ConnectProtocol {
+ TCP_IP = 0,
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/EndpointInfo.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/EndpointInfo.aidl
new file mode 100644
index 0000000..5693520
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/EndpointInfo.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.automotive.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable EndpointInfo {
+ android.hardware.automotive.ivn.ConnectProtocol connectProtocol;
+ String ipAddress;
+ int portNumber;
+ android.hardware.automotive.ivn.HardwareIdentifiers hardwareId;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/HardwareIdentifiers.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
new file mode 100644
index 0000000..1a8b21d
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/HardwareIdentifiers.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.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable HardwareIdentifiers {
+ @nullable String brandName;
+ @nullable String deviceName;
+ @nullable String productName;
+ @nullable String manufacturerName;
+ @nullable String modelName;
+ @nullable String serialNumber;
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
new file mode 100644
index 0000000..a04d829
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/IIvnAndroidDevice.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.ivn;
+@VintfStability
+interface IIvnAndroidDevice {
+ int getMyDeviceId();
+ int[] getOtherDeviceIds();
+ int getDeviceIdForOccupantZone(int zoneId);
+ android.hardware.automotive.ivn.OccupantZoneInfo[] getOccupantZonesForDevice(int androidDeviceId);
+ android.hardware.automotive.ivn.EndpointInfo getMyEndpointInfo();
+ android.hardware.automotive.ivn.EndpointInfo getEndpointInfoForDevice(int androidDeviceId);
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantType.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantType.aidl
new file mode 100644
index 0000000..6dd0c07
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantType.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.ivn;
+@Backing(type="int") @VintfStability
+enum OccupantType {
+ DRIVER = 1,
+ FRONT_PASSENGER = 2,
+ REAR_PASSENGER = 3,
+}
diff --git a/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantZoneInfo.aidl b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
new file mode 100644
index 0000000..41108e9
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/aidl_api/android.hardware.automotive.ivn/current/android/hardware/automotive/ivn/OccupantZoneInfo.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.ivn;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable OccupantZoneInfo {
+ int zoneId;
+ android.hardware.automotive.ivn.OccupantType occupantType;
+ int seat;
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/ConnectProtocol.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/ConnectProtocol.aidl
new file mode 100644
index 0000000..9f621b3
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/ConnectProtocol.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.ivn;
+
+/**
+ * Connect protocol for In-vehicle network Android device.
+ */
+@VintfStability
+@Backing(type="int")
+enum ConnectProtocol {
+ TCP_IP = 0,
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/EndpointInfo.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/EndpointInfo.aidl
new file mode 100644
index 0000000..32f6971
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/EndpointInfo.aidl
@@ -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.
+ */
+
+package android.hardware.automotive.ivn;
+
+import android.hardware.automotive.ivn.ConnectProtocol;
+import android.hardware.automotive.ivn.HardwareIdentifiers;
+
+/**
+ * Network endpoint information for an Android instance running on a difference device.
+ *
+ * The device is in the same vehicle as this device.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable EndpointInfo {
+ /**
+ * The connection protocol. Only supports TCP/IP for now.
+ */
+ ConnectProtocol connectProtocol;
+ /**
+ * The IP address.
+ */
+ String ipAddress;
+ /**
+ * The port number exposed for connecting.
+ */
+ int portNumber;
+ /**
+ * Hardware identifiers.
+ *
+ * The hardware identifiers for the endpoint as defined in [Attestation Hardware Identifiers]
+ * {@link
+ * https://source.android.com/docs/security/features/keystore/attestation#hardware-identifiers}
+ */
+ HardwareIdentifiers hardwareId;
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/HardwareIdentifiers.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
new file mode 100644
index 0000000..ffa09e6
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/HardwareIdentifiers.aidl
@@ -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.
+ */
+
+package android.hardware.automotive.ivn;
+
+/**
+ * Hardware Identifiers for an Android device.
+ *
+ * <p>These identifiers are embedded in the ID attestation certificate and are
+ * used to restrict what devices this device can connect to. All fields are
+ * optional but at least one of the fields must be specified.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable HardwareIdentifiers {
+ /**
+ * Optional brand name, as returned by {@code Build.BRAND} in Android.
+ *
+ * If unspecified, we assume the other device has the same brand name as this device.
+ */
+ @nullable String brandName;
+ /**
+ * Optional brand name, as returned by {@code Build.DEVICE} in Android.
+ *
+ * If unspecified, we assume the other device has the same device name as this device.
+ */
+ @nullable String deviceName;
+ /**
+ * Optional model name, as returned by {@code Build.PRODUCT} in Android.
+ *
+ * If unspecified, we assume the other device has the same product name as this device.
+ */
+ @nullable String productName;
+ /**
+ * Optional manufacturer name, as returned by {@code Build.MANUFACTURER} in Android.
+ *
+ * If unspecified, we assume the other device has the same manufacturer name as this device.
+ */
+ @nullable String manufacturerName;
+ /**
+ * Optional model name, as returned by {@code Build.MODEL} in Android.
+ *
+ * If unspecified, we assume the other device has the same model name as this device.
+ */
+ @nullable String modelName;
+ /**
+ * Optional serial number.
+ *
+ * If unspecified, we allow the endpoint to have any serial number.
+ */
+ @nullable String serialNumber;
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
new file mode 100644
index 0000000..107b7a6
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/IIvnAndroidDevice.aidl
@@ -0,0 +1,81 @@
+/*
+ * 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.ivn;
+
+import android.hardware.automotive.ivn.EndpointInfo;
+import android.hardware.automotive.ivn.OccupantZoneInfo;
+
+/**
+ * Interface for In-Vehicle Network(IVN) Android devices.
+ *
+ * This is used in a multi-zone multi-SoC environment where there are multiple
+ * SoCs running Android in a vehicle. Each support one or multiple occupant
+ * zones. E.g., one SoC for front passenger, one SoC for backseat left-zone
+ * and middle/right zone passengers.
+ */
+@VintfStability
+interface IIvnAndroidDevice {
+ /**
+ * Returns the unique ID for this Android device.
+ *
+ * <p>This ID has to be unique among all the android devices in the whole vehicle. It is usually
+ * a hard-coded value, e.g. serial number.
+ *
+ * @return an ID representing this device.
+ */
+ int getMyDeviceId();
+
+ /**
+ * Returns a list of unique IDs for other IVN Android devices.
+ *
+ * The returned list does not contain the current Android device ID. This list is usually
+ * pre-configured for this HAL, either hard-coded or read from configuration file.
+ *
+ * @return A list of IDs representing connected Android devices.
+ */
+ int[] getOtherDeviceIds();
+
+ /**
+ * Returns the Android device ID for a specified occupant zone.
+ *
+ * @pararm zoneID the occupant zone ID returned from {@link android.car.CarOccupantZoneManager}.
+ * @return an ID representing an Android device.
+ */
+ int getDeviceIdForOccupantZone(int zoneId);
+
+ /**
+ * Returns all the occupant zones supported for a specified IVN Android device.
+ *
+ * @param androidDeviceId the android device ID.
+ * @return A list of supported occupant zone info.
+ */
+ OccupantZoneInfo[] getOccupantZonesForDevice(int androidDeviceId);
+
+ /**
+ * Returns the connection endpoint info for this android device.
+ *
+ * @return The endpoint info.
+ */
+ EndpointInfo getMyEndpointInfo();
+
+ /**
+ * Returns the connection endpoint info for the specified IVN Android device.
+ *
+ * @return The endpoint info.
+ */
+ EndpointInfo getEndpointInfoForDevice(int androidDeviceId);
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantType.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantType.aidl
new file mode 100644
index 0000000..72542a7
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantType.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.automotive.ivn;
+
+/**
+ * Occupant type.
+ *
+ * This enum might be extended in the future.
+ */
+@VintfStability
+@Backing(type="int")
+enum OccupantType {
+ /**
+ * Represents the driver. There can be one or zero driver for the system. Zero driver situation
+ * can happen if the system is configured to support only passengers.
+ */
+ DRIVER = 1,
+ /**
+ * Represents front passengers who sit in front side of car. Most cars will have only
+ * one passenger of this type but this can be multiple.
+ */
+ FRONT_PASSENGER = 2,
+ /** Represents passengers in rear seats. There can be multiple passengers of this type. */
+ REAR_PASSENGER = 3,
+}
diff --git a/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantZoneInfo.aidl b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
new file mode 100644
index 0000000..af45444
--- /dev/null
+++ b/automotive/ivn_android_device/aidl/android/hardware/automotive/ivn/OccupantZoneInfo.aidl
@@ -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.
+ */
+
+package android.hardware.automotive.ivn;
+
+import android.hardware.automotive.ivn.OccupantType;
+
+/**
+ * Represents an occupant zone in a car.
+ *
+ * <p>Each occupant does not necessarily represent single person but it is for mapping to one
+ * set of displays. For example, for display located in center rear seat, both left and right
+ * side passengers may use it but it is abstracted as a single occupant zone.</p>
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable OccupantZoneInfo {
+ /**
+ * This is an unique id to distinguish each occupant zone.
+ *
+ * <p>This can be helpful to distinguish different zones when {@link #occupantType} and
+ * {@link #seat} are the same for multiple occupant / passenger zones.</p>
+ *
+ * <p>This id will remain the same for the same zone across configuration changes like
+ * user switching or display changes</p>
+ */
+ int zoneId;
+ /** Represents type of passenger */
+ OccupantType occupantType;
+ /**
+ * Represents seat assigned for the occupant. In some system, this can have value of
+ * {@code VehicleAreaSeat#SEAT_UNKNOWN}.
+ *
+ * <p>This might be one of {@code VehicleAreaSeat} or a combination of {@code VehicleAreaSeat}.
+ */
+ int seat;
+}
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
index 1ae8689..dc280df 100644
--- a/automotive/occupant_awareness/aidl/default/Android.bp
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -40,3 +40,21 @@
"android.hardware.automotive.occupant_awareness-V1-ndk",
],
}
+
+cc_fuzz {
+ name: "android.hardware.automotive.occupant_awareness-service.fuzzer",
+ defaults: ["service_fuzzer_defaults"],
+ static_libs: [
+ "android.hardware.automotive.occupant_awareness-V1-ndk",
+ "liblog",
+ ],
+ srcs: [
+ "fuzzer.cpp",
+ "OccupantAwareness.cpp",
+ ],
+ fuzz_config: {
+ cc: [
+ "[email protected]",
+ ],
+ },
+}
diff --git a/automotive/occupant_awareness/aidl/default/fuzzer.cpp b/automotive/occupant_awareness/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..551b83a
--- /dev/null
+++ b/automotive/occupant_awareness/aidl/default/fuzzer.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "OccupantAwareness.h"
+
+using ::aidl::android::hardware::automotive::occupant_awareness::IOccupantAwareness;
+using ::android::fuzzService;
+using ::android::hardware::automotive::occupant_awareness::V1_0::implementation::OccupantAwareness;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ auto occupantAwareness = SharedRefBase::make<OccupantAwareness>();
+
+ fuzzService(occupantAwareness->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index 9b6eb2f..b0935c2 100644
--- a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -34,8 +34,9 @@
package android.hardware.automotive.remoteaccess;
@VintfStability
interface IRemoteAccess {
- String getDeviceId();
+ String getVehicleId();
String getWakeupServiceName();
+ String getProcessorId();
void setRemoteTaskCallback(android.hardware.automotive.remoteaccess.IRemoteTaskCallback callback);
void clearRemoteTaskCallback();
void notifyApStateChange(in android.hardware.automotive.remoteaccess.ApState state);
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index a198b03..0f4125f 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -28,19 +28,19 @@
@VintfStability
interface IRemoteAccess {
/**
- * Gets a unique device ID that could be recognized by wake up server.
+ * Gets a unique vehicle ID that could be recognized by wake up server.
*
- * This device ID is provisioned during car production and is registered
+ * <p>This vehicle ID is provisioned during car production and is registered
* with the wake up server.
*
- * @return a unique device ID.
+ * @return a unique vehicle ID.
*/
- String getDeviceId();
+ String getVehicleId();
/**
* Gets the name for the remote wakeup server.
*
- * This name will be provided to remote task server during registration
+ * <p>This name will be provided to remote task server during registration
* and used by remote task server to find the remote wakeup server to
* use for waking up the device. This name must be pre-negotiated between
* the remote wakeup server/client and the remote task server/client and
@@ -51,6 +51,17 @@
String getWakeupServiceName();
/**
+ * Gets a unique processor ID that could be recognized by wake up client.
+ *
+ * <p>This processor ID is used to identify each processor in the vehicle.
+ * The wake up client which handles many processors determines which
+ * processor to wake up from the processor ID.
+ *
+ * <p> The processor ID must be unique in the vehicle.
+ */
+ String getProcessorId();
+
+ /**
* Sets a callback to be called when a remote task is requested.
*
* @param callback A callback to be called when a remote task is requested.
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
index 7a1616f..2cd7a5d 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.aidl
@@ -24,6 +24,10 @@
/**
* A callback that is called when a remote task is requested.
*
+ * The data is passed down from the remote server to the remote task client
+ * which is an Android application, and is not interpreted/parsed by the
+ * Android system.
+ *
* @param clientId An ID to uniquely identify a remote task client.
* @param data Opaque task data passed to the remote task client.
*/
diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp b/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp
new file mode 100644
index 0000000..113b14e
--- /dev/null
+++ b/automotive/remoteaccess/bind_to_device_socket_mutator/Android.bp
@@ -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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+ name: "BindToDeviceSocketMutatorDefaults",
+ static_libs: [
+ "android.hardware.automotive.can@libnetdevice",
+ "libnl++",
+ ],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libgrpc++",
+ ],
+ cflags: [
+ "-Wno-unused-parameter",
+ ],
+}
+
+cc_library {
+ name: "BindToDeviceSocketMutatorLib",
+ vendor_available: true,
+ srcs: ["src/*"],
+ export_include_dirs: ["include"],
+ defaults: ["BindToDeviceSocketMutatorDefaults"],
+}
diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h b/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h
new file mode 100644
index 0000000..bafcc65
--- /dev/null
+++ b/automotive/remoteaccess/bind_to_device_socket_mutator/include/BindToDeviceSocketMutator.h
@@ -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.
+ */
+
+#pragma once
+
+#include <grpc++/grpc++.h>
+#include <src/core/lib/iomgr/socket_mutator.h>
+#include <string>
+
+namespace android::hardware::automotive::remoteaccess {
+
+class BindToDeviceSocketMutator final : public grpc_socket_mutator {
+ public:
+ BindToDeviceSocketMutator(const std::string_view& interface_name);
+
+ bool mutateFd(int fd);
+
+ private:
+ std::string mIfname;
+};
+
+} // namespace android::hardware::automotive::remoteaccess
diff --git a/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp b/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp
new file mode 100644
index 0000000..c6a96de
--- /dev/null
+++ b/automotive/remoteaccess/bind_to_device_socket_mutator/src/BindToDeviceSocketMutator.cpp
@@ -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.
+ */
+
+#include "BindToDeviceSocketMutator.h"
+
+#include <android-base/logging.h>
+#include <errno.h>
+#include <sys/socket.h>
+
+namespace android::hardware::automotive::remoteaccess {
+
+bool BindToDeviceSocketMutator::mutateFd(int fd) {
+ int ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, mIfname.c_str(), mIfname.size());
+ if (ret != 0) {
+ PLOG(ERROR) << "Can't bind socket to interface " << mIfname;
+ return false;
+ }
+ return true;
+}
+
+bool bind_to_device_mutator_mutate_fd(int fd, grpc_socket_mutator* mutator) {
+ BindToDeviceSocketMutator* bsm = (BindToDeviceSocketMutator*)mutator;
+ return bsm->mutateFd(fd);
+}
+
+int bind_to_device_mutator_compare(grpc_socket_mutator* a, grpc_socket_mutator* b) {
+ return ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0));
+}
+
+void bind_to_device_mutator_destroy(grpc_socket_mutator* mutator) {
+ BindToDeviceSocketMutator* bsm = (BindToDeviceSocketMutator*)mutator;
+ delete bsm;
+}
+
+grpc_socket_mutator_vtable bind_to_device_mutator_vtable = {bind_to_device_mutator_mutate_fd,
+ bind_to_device_mutator_compare,
+ bind_to_device_mutator_destroy};
+
+BindToDeviceSocketMutator::BindToDeviceSocketMutator(const std::string_view& interface_name) {
+ mIfname = interface_name;
+ grpc_socket_mutator_init(this, &bind_to_device_mutator_vtable);
+}
+
+} // namespace android::hardware::automotive::remoteaccess
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index f27b8f8..0155667 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -22,22 +22,27 @@
name: "remote-access-hal-defaults",
vendor: true,
relative_install_path: "hw",
- srcs: ["src/RemoteAccessImpl.cpp"],
+ srcs: [
+ "src/RemoteAccessImpl.cpp",
+ ],
whole_static_libs: [
"RemoteAccessService",
],
+ static_libs: [
+ "BindToDeviceSocketMutatorLib",
+ ],
shared_libs: [
- "libbase",
"libbinder_ndk",
- "liblog",
"libutils",
- "libgrpc++",
"libprotobuf-cpp-full",
],
defaults: [
"vhalclient_defaults",
+ "BindToDeviceSocketMutatorDefaults",
],
cflags: [
+ // This is already included in BindToDeviceSocketMutatorDefaults but
+ // might be overridden by vhalclient_defaults.
"-Wno-unused-parameter",
],
}
@@ -59,6 +64,7 @@
init_rc: ["remoteaccess-tcu-test-service.rc"],
cflags: [
"-DGRPC_SERVICE_ADDRESS=\"10.10.10.1:50051\"",
+ "-DGRPC_SERVICE_IFNAME=\"eth1\"",
],
}
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
index 74c2af4..9aabad6 100644
--- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -62,7 +62,9 @@
~RemoteAccessService();
- ndk::ScopedAStatus getDeviceId(std::string* deviceId) override;
+ ndk::ScopedAStatus getVehicleId(std::string* vehicleId) override;
+
+ ndk::ScopedAStatus getProcessorId(std::string* processorId) override;
ndk::ScopedAStatus getWakeupServiceName(std::string* wakeupServiceName) override;
@@ -95,7 +97,10 @@
bool mTaskWaitStopped GUARDED_BY(mLock);
// A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
std::mutex mStartStopTaskLoopLock;
- bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock);
+ bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
+ bool mGrpcConnected GUARDED_BY(mLock) = false;
+ std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);
+
// Default wait time before retry connecting to remote access client is 10s.
size_t mRetryWaitInMs = 10'000;
std::shared_ptr<DebugRemoteTaskCallback> mDebugCallback;
@@ -103,11 +108,17 @@
void runTaskLoop();
void maybeStartTaskLoop();
void maybeStopTaskLoop();
- ndk::ScopedAStatus getDeviceIdWithClient(
- android::frameworks::automotive::vhal::IVhalClient& client, std::string* deviceId);
+ ndk::ScopedAStatus getVehicleIdWithClient(
+ android::frameworks::automotive::vhal::IVhalClient& client, std::string* vehicleId);
void setRetryWaitInMs(size_t retryWaitInMs) { mRetryWaitInMs = retryWaitInMs; }
void dumpHelp(int fd);
+ void printCurrentStatus(int fd);
+ std::string clientIdToTaskCountToStringLocked() REQUIRES(mLock);
+ void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
+ void updateGrpcConnected(bool connected);
+ android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
+ std::string_view taskData);
};
} // namespace remoteaccess
diff --git a/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc b/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc
index 6437d70..59315eb 100644
--- a/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc
+++ b/automotive/remoteaccess/hal/default/remoteaccess-tcu-test-service.rc
@@ -2,3 +2,4 @@
class hal
user vehicle_network
group system inet
+ capabilities NET_RAW
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
index 8720c2f..d525141 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessImpl.cpp
@@ -18,45 +18,60 @@
#include "RemoteAccessService.h"
+#include "BindToDeviceSocketMutator.h"
+
+#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <grpcpp/create_channel.h>
+#include <libnetdevice/libnetdevice.h>
#include <stdlib.h>
-#include <utils/Log.h>
constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";
int main(int /* argc */, char* /* argv */[]) {
- ALOGI("Registering RemoteAccessService as service...");
+ LOG(INFO) << "Registering RemoteAccessService as service...";
#ifndef GRPC_SERVICE_ADDRESS
- ALOGE("GRPC_SERVICE_ADDRESS is not defined, exiting");
+ LOG(ERROR) << "GRPC_SERVICE_ADDRESS is not defined, exiting";
exit(1);
#endif
- auto channel = grpc::CreateChannel(GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
+ grpc::ChannelArguments grpcargs = {};
+
+#ifdef GRPC_SERVICE_IFNAME
+ grpcargs.SetSocketMutator(
+ new android::hardware::automotive::remoteaccess::BindToDeviceSocketMutator(
+ GRPC_SERVICE_IFNAME));
+ LOG(DEBUG) << "GRPC_SERVICE_IFNAME specified as: " << GRPC_SERVICE_IFNAME;
+ LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME;
+ android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
+ android::netdevice::WaitCondition::PRESENT_AND_UP);
+ LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
+#endif
+ auto channel = grpc::CreateCustomChannel(GRPC_SERVICE_ADDRESS,
+ grpc::InsecureChannelCredentials(), grpcargs);
auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
auto service = ndk::SharedRefBase::make<
android::hardware::automotive::remoteaccess::RemoteAccessService>(clientStub.get());
binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
if (err != EX_NONE) {
- ALOGE("failed to register android.hardware.automotive.remote.IRemoteAccess service, "
- "exception: %d",
- err);
+ LOG(ERROR) << "failed to register android.hardware.automotive.remote.IRemoteAccess service"
+ << ", exception: " << err;
exit(1);
}
if (!ABinderProcess_setThreadPoolMaxThreadCount(1)) {
- ALOGE("%s", "failed to set thread pool max thread count");
+ LOG(ERROR) << "failed to set thread pool max thread count";
exit(1);
}
ABinderProcess_startThreadPool();
- ALOGI("RemoteAccess service Ready");
+ LOG(INFO) << "RemoteAccess service Ready";
ABinderProcess_joinThreadPool();
- ALOGW("Should not reach here");
+ LOG(ERROR) << "Should not reach here";
return 0;
}
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 4be30a2..bbda9df 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -36,6 +36,8 @@
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::android::base::Error;
+using ::android::base::Result;
using ::android::base::ScopedLockAssertion;
using ::android::base::StringAppendF;
using ::android::base::StringPrintf;
@@ -48,13 +50,16 @@
using ::ndk::ScopedAStatus;
const std::string WAKEUP_SERVICE_NAME = "com.google.vehicle.wakeup";
+const std::string PROCESSOR_ID = "application_processor";
constexpr char COMMAND_SET_AP_STATE[] = "--set-ap-state";
constexpr char COMMAND_START_DEBUG_CALLBACK[] = "--start-debug-callback";
constexpr char COMMAND_STOP_DEBUG_CALLBACK[] = "--stop-debug-callback";
constexpr char COMMAND_SHOW_TASK[] = "--show-task";
-constexpr char COMMAND_GET_DEVICE_ID[] = "--get-device-id";
+constexpr char COMMAND_GET_VEHICLE_ID[] = "--get-vehicle-id";
+constexpr char COMMAND_INJECT_TASK[] = "--inject-task";
+constexpr char COMMAND_STATUS[] = "--status";
-std::vector<uint8_t> stringToBytes(const std::string& s) {
+std::vector<uint8_t> stringToBytes(std::string_view s) {
const char* data = s.data();
return std::vector<uint8_t>(data, data + s.size());
}
@@ -80,6 +85,10 @@
dprintf(fd, "%s, code: %d, error: %s\n", detail, status.getStatus(), status.getMessage());
}
+std::string boolToString(bool x) {
+ return x ? "true" : "false";
+}
+
} // namespace
RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
@@ -125,6 +134,33 @@
mTaskLoopRunning = false;
}
+void RemoteAccessService::updateGrpcConnected(bool connected) {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ mGrpcConnected = connected;
+}
+
+Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
+ std::string_view taskData) {
+ std::shared_ptr<IRemoteTaskCallback> callback;
+ {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ callback = mRemoteTaskCallback;
+ mClientIdToTaskCount[clientId] += 1;
+ }
+ if (callback == nullptr) {
+ return Error() << "No callback registered, task ignored";
+ }
+ ALOGD("Calling onRemoteTaskRequested callback for client ID: %s", clientId.c_str());
+ ScopedAStatus callbackStatus =
+ callback->onRemoteTaskRequested(clientId, stringToBytes(taskData));
+ if (!callbackStatus.isOk()) {
+ return Error() << "Failed to call onRemoteTaskRequested callback, status: "
+ << callbackStatus.getStatus()
+ << ", message: " << callbackStatus.getMessage();
+ }
+ return {};
+}
+
void RemoteAccessService::runTaskLoop() {
GetRemoteTasksRequest request = {};
std::unique_ptr<ClientReaderInterface<GetRemoteTasksResponse>> reader;
@@ -134,28 +170,19 @@
mGetRemoteTasksContext.reset(new ClientContext());
reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
}
+ updateGrpcConnected(true);
GetRemoteTasksResponse response;
while (reader->Read(&response)) {
ALOGI("Receiving one task from remote task client");
- std::shared_ptr<IRemoteTaskCallback> callback;
- {
- std::lock_guard<std::mutex> lockGuard(mLock);
- callback = mRemoteTaskCallback;
- }
- if (callback == nullptr) {
- ALOGD("No callback registered, task ignored");
+ if (auto result =
+ deliverRemoteTaskThroughCallback(response.clientid(), response.data());
+ !result.ok()) {
+ ALOGE("%s", result.error().message().c_str());
continue;
}
- ALOGD("Calling onRemoteTaskRequested callback for client ID: %s",
- response.clientid().c_str());
- ScopedAStatus callbackStatus = callback->onRemoteTaskRequested(
- response.clientid(), stringToBytes(response.data()));
- if (!callbackStatus.isOk()) {
- ALOGE("Failed to call onRemoteTaskRequested callback, status: %d, message: %s",
- callbackStatus.getStatus(), callbackStatus.getMessage());
- }
}
+ updateGrpcConnected(false);
Status status = reader->Finish();
mGetRemoteTasksContext.reset();
@@ -176,23 +203,23 @@
}
}
-ScopedAStatus RemoteAccessService::getDeviceId(std::string* deviceId) {
+ScopedAStatus RemoteAccessService::getVehicleId(std::string* vehicleId) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
auto vhalClient = IVhalClient::tryCreate();
if (vhalClient == nullptr) {
ALOGE("Failed to connect to VHAL");
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- /*errorCode=*/0, "Failed to connect to VHAL to get device ID");
+ /*errorCode=*/0, "Failed to connect to VHAL to get vehicle ID");
}
- return getDeviceIdWithClient(*vhalClient.get(), deviceId);
+ return getVehicleIdWithClient(*vhalClient.get(), vehicleId);
#else
// Don't use VHAL client in fuzzing since IPC is not allowed.
return ScopedAStatus::ok();
#endif
}
-ScopedAStatus RemoteAccessService::getDeviceIdWithClient(IVhalClient& vhalClient,
- std::string* deviceId) {
+ScopedAStatus RemoteAccessService::getVehicleIdWithClient(IVhalClient& vhalClient,
+ std::string* vehicleId) {
auto result = vhalClient.getValueSync(
*vhalClient.createHalPropValue(toInt(VehicleProperty::INFO_VIN)));
if (!result.ok()) {
@@ -200,7 +227,12 @@
/*errorCode=*/0,
("failed to get INFO_VIN from VHAL: " + result.error().message()).c_str());
}
- *deviceId = (*result)->getStringValue();
+ *vehicleId = (*result)->getStringValue();
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus RemoteAccessService::getProcessorId(std::string* processorId) {
+ *processorId = PROCESSOR_ID;
return ScopedAStatus::ok();
}
@@ -246,15 +278,17 @@
}
void RemoteAccessService::dumpHelp(int fd) {
- dprintf(fd, "%s",
- (std::string("RemoteAccess HAL debug interface, Usage: \n") + COMMAND_SET_AP_STATE +
- " [0/1](isReadyForRemoteTask) [0/1](isWakeupRequired) Set the new AP state\n" +
- COMMAND_START_DEBUG_CALLBACK +
- " Start a debug callback that will record the received tasks\n" +
- COMMAND_STOP_DEBUG_CALLBACK + " Stop the debug callback\n" + COMMAND_SHOW_TASK +
- " Show tasks received by debug callback\n" + COMMAND_GET_DEVICE_ID +
- " Get device id\n")
- .c_str());
+ dprintf(fd,
+ "RemoteAccess HAL debug interface, Usage: \n"
+ "%s [0/1](isReadyForRemoteTask) [0/1](isWakeupRequired): Set the new AP state\n"
+ "%s: Start a debug callback that will record the received tasks\n"
+ "%s: Stop the debug callback\n"
+ "%s: Show tasks received by debug callback\n"
+ "%s: Get vehicle id\n"
+ "%s [client_id] [task_data]: Inject a task\n"
+ "%s: Show status\n",
+ COMMAND_SET_AP_STATE, COMMAND_START_DEBUG_CALLBACK, COMMAND_STOP_DEBUG_CALLBACK,
+ COMMAND_SHOW_TASK, COMMAND_GET_VEHICLE_ID, COMMAND_INJECT_TASK, COMMAND_STATUS);
}
binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t numArgs) {
@@ -265,6 +299,7 @@
if (numArgs == 0) {
dumpHelp(fd);
+ printCurrentStatus(fd);
return STATUS_OK;
}
@@ -316,14 +351,22 @@
dprintf(fd, "Debug callback is not currently used, use \"%s\" first.\n",
COMMAND_START_DEBUG_CALLBACK);
}
- } else if (!strcmp(args[0], COMMAND_GET_DEVICE_ID)) {
- std::string deviceId;
- auto status = getDeviceId(&deviceId);
+ } else if (!strcmp(args[0], COMMAND_GET_VEHICLE_ID)) {
+ std::string vehicleId;
+ auto status = getVehicleId(&vehicleId);
if (!status.isOk()) {
- dprintErrorStatus(fd, "Failed to get device ID", status);
+ dprintErrorStatus(fd, "Failed to get vehicle ID", status);
} else {
- dprintf(fd, "Device Id: %s\n", deviceId.c_str());
+ dprintf(fd, "Vehicle Id: %s\n", vehicleId.c_str());
}
+ } else if (!strcmp(args[0], COMMAND_INJECT_TASK)) {
+ if (numArgs < 3) {
+ dumpHelp(fd);
+ return STATUS_OK;
+ }
+ debugInjectTask(fd, args[1], args[2]);
+ } else if (!strcmp(args[0], COMMAND_STATUS)) {
+ printCurrentStatus(fd);
} else {
dumpHelp(fd);
}
@@ -331,6 +374,37 @@
return STATUS_OK;
}
+void RemoteAccessService::printCurrentStatus(int fd) {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ dprintf(fd,
+ "\nRemoteAccess HAL status \n"
+ "Remote task callback registered: %s\n"
+ "Task receiving GRPC connection established: %s\n"
+ "Received task count by clientId: \n%s\n",
+ boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcConnected).c_str(),
+ clientIdToTaskCountToStringLocked().c_str());
+}
+
+void RemoteAccessService::debugInjectTask(int fd, std::string_view clientId,
+ std::string_view taskData) {
+ std::string clientIdCopy = std::string(clientId);
+ if (auto result = deliverRemoteTaskThroughCallback(clientIdCopy, taskData); !result.ok()) {
+ dprintf(fd, "Failed to inject task: %s", result.error().message().c_str());
+ return;
+ }
+ dprintf(fd, "Task for client: %s, data: [%s] successfully injected\n", clientId.data(),
+ taskData.data());
+}
+
+std::string RemoteAccessService::clientIdToTaskCountToStringLocked() {
+ // Print the table header
+ std::string output = "| ClientId | Count |\n";
+ for (const auto& [clientId, taskCount] : mClientIdToTaskCount) {
+ output += StringPrintf(" %-9s %-6zu\n", clientId.c_str(), taskCount);
+ }
+ return output;
+}
+
ScopedAStatus DebugRemoteTaskCallback::onRemoteTaskRequested(const std::string& clientId,
const std::vector<uint8_t>& data) {
std::lock_guard<std::mutex> lockGuard(mLock);
diff --git a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
index a220aeb..c5afd63 100644
--- a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
+++ b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
@@ -42,6 +42,7 @@
using ::android::frameworks::automotive::vhal::ISubscriptionCallback;
using ::android::frameworks::automotive::vhal::ISubscriptionClient;
using ::android::frameworks::automotive::vhal::IVhalClient;
+using ::android::frameworks::automotive::vhal::VhalClientResult;
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback;
@@ -91,9 +92,6 @@
class FakeVhalClient final : public android::frameworks::automotive::vhal::IVhalClient {
public:
- template <class T>
- using VhalClientResult = android::hardware::automotive::vehicle::VhalResult<T>;
-
inline bool isAidlVhal() { return true; }
VhalClientResult<std::unique_ptr<IHalPropValue>> getValueSync(
@@ -189,8 +187,8 @@
void setRetryWaitInMs(size_t retryWaitInMs) { mService->setRetryWaitInMs(retryWaitInMs); }
- ScopedAStatus getDeviceIdWithClient(IVhalClient& vhalClient, std::string* deviceId) {
- return mService->getDeviceIdWithClient(vhalClient, deviceId);
+ ScopedAStatus getVehicleIdWithClient(IVhalClient& vhalClient, std::string* vehicleId) {
+ return mService->getVehicleIdWithClient(vhalClient, vehicleId);
}
private:
@@ -360,13 +358,13 @@
std::this_thread::sleep_for(std::chrono::milliseconds(150));
}
-TEST_F(RemoteAccessServiceUnitTest, testGetDeviceId) {
- std::string deviceId;
+TEST_F(RemoteAccessServiceUnitTest, testGetVehicleId) {
+ std::string vehicleId;
FakeVhalClient vhalClient;
- ASSERT_TRUE(getDeviceIdWithClient(vhalClient, &deviceId).isOk());
- ASSERT_EQ(deviceId, kTestVin);
+ ASSERT_TRUE(getVehicleIdWithClient(vhalClient, &vehicleId).isOk());
+ ASSERT_EQ(vehicleId, kTestVin);
}
} // namespace remoteaccess
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 55a7720..cfa3b0c 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -144,7 +144,7 @@
(int)VehicleUnit::MILES_PER_HOUR,
(int)VehicleUnit::KILOMETERS_PER_HOUR},
},
- .initialValue = {.int32Values = {(int)VehicleUnit::KILOMETERS_PER_HOUR}}},
+ .initialValue = {.int32Values = {(int)VehicleUnit::MILES_PER_HOUR}}},
{.config =
{
@@ -374,6 +374,15 @@
{.config =
{
+ .prop = toInt(VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS),
+ .access = VehiclePropertyAccess::READ_WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .configArray = {(int)VehicleUnit::LITER, (int)VehicleUnit::US_GALLON},
+ },
+ .initialValue = {.int32Values = {(int)VehicleUnit::US_GALLON}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::HW_KEY_INPUT),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -1174,13 +1183,14 @@
{
.config =
{
- // VHAL_SUPPORTED_PROPERTY_IDS
+ // SUPPORTED_PROPERTY_IDS
.prop = 289476424,
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
// Fetch 100 configs in one request. This number is just arbitrarily
// chosen here. But some HAL impl with bigger config data may need a
- // smaller number.
+ // smaller number to make sure the configs returned in one request
+ // fits the binder data size limitation.
.configArray = {100},
},
// All supported property IDs. This list is checked by
@@ -1192,22 +1202,22 @@
289408517, 356518832, 356516106, 291504644, 291504649, 291504656,
291504901, 291504903, 287310600, 291504905, 287310602, 287310603,
291504908, 291504904, 392168201, 392168202, 289408514, 289408001,
- 287310850, 287310851, 287310853, 289475088, 289475104, 289475120,
- 354419984, 320865540, 320865556, 354419975, 354419976, 354419986,
- 354419973, 354419974, 354419978, 354419977, 356517120, 356517121,
- 356582673, 356517139, 289408269, 356517131, 358614275, 291570965,
- 291505923, 289408270, 289408512, 287310855, 289408000, 289408008,
- 289408009, 289407747, 291504900, 568332561, 371198722, 373295872,
- 320867268, 322964416, 290521862, 287310858, 287310859, 289475072,
- 289475073, 289409539, 299896064, 299896065, 299896066, 299896067,
- 289410560, 289410561, 289410562, 289410563, 289410576, 289410577,
- 289410578, 289410579, 289476368, 299895808, 639631617, 627048706,
- 591397123, 554696964, 289410873, 289410874, 287313669, 299896583,
- 299896584, 299896585, 299896586, 299896587, 286265121, 286265122,
- 286265123, 290457094, 290459441, 299896626, 290459443, 289410868,
- 289476405, 299896630, 289410871, 292556600, 557853201, 559950353,
- 555756049, 554707473, 289410887, 557846324, 557911861, 568332086,
- 557846327, 560992056, 289476424}},
+ 287310850, 287310851, 287310853, 289408513, 289475088, 289475104,
+ 289475120, 354419984, 320865540, 320865556, 354419975, 354419976,
+ 354419986, 354419973, 354419974, 354419978, 354419977, 356517120,
+ 356517121, 356582673, 356517139, 289408269, 356517131, 358614275,
+ 291570965, 291505923, 289408270, 289408512, 287310855, 289408000,
+ 289408008, 289408009, 289407747, 291504900, 568332561, 371198722,
+ 373295872, 320867268, 322964416, 290521862, 287310858, 287310859,
+ 289475072, 289475073, 289409539, 299896064, 299896065, 299896066,
+ 299896067, 289410560, 289410561, 289410562, 289410563, 289410576,
+ 289410577, 289410578, 289410579, 289476368, 299895808, 639631617,
+ 627048706, 591397123, 554696964, 289410873, 289410874, 287313669,
+ 299896583, 299896584, 299896585, 299896586, 299896587, 286265121,
+ 286265122, 286265123, 290457094, 290459441, 299896626, 290459443,
+ 289410868, 289476405, 299896630, 289410871, 292556600, 557853201,
+ 559950353, 555756049, 554707473, 289410887, 557846324, 557911861,
+ 568332086, 557846327, 560992056, 289476424}},
},
#endif // ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
};
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
index 9be9ea7..503afd2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
@@ -28,11 +28,18 @@
namespace impl {
-GeneratorHub::GeneratorHub(const OnHalEvent& onHalEvent)
- : mOnHalEvent(onHalEvent), mThread(&GeneratorHub::run, this) {}
+GeneratorHub::GeneratorHub(const OnHalEvent& onHalEvent) : mOnHalEvent(onHalEvent) {
+ mThread = std::thread(&GeneratorHub::run, this);
+}
GeneratorHub::~GeneratorHub() {
- mShuttingDownFlag.store(true);
+ {
+ // Even if the shared variable is atomic, it must be modified under the
+ // mutex in order to correctly publish the modification to the waiting
+ // thread.
+ std::unique_lock<std::mutex> g(mLock);
+ mShuttingDownFlag.store(true);
+ }
mCond.notify_all();
if (mThread.joinable()) {
mThread.join();
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 25a1940..edd4484 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
@@ -124,6 +124,17 @@
android::ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
android::ConcurrentQueue<VehiclePropValuePtr> mHeartBeatQueue;
+ // Wait until receive enough events in receivedEvents.
+ void waitForEvents(std::vector<VehiclePropValuePtr>* receivedEvents, size_t count) {
+ while (receivedEvents->size() < count) {
+ mEventQueue.waitForItems();
+ auto newEvents = mEventQueue.flush();
+ for (size_t i = 0; i < newEvents.size(); i++) {
+ receivedEvents->push_back(std::move(newEvents[i]));
+ }
+ }
+ }
+
private:
void onHalEvent(VehiclePropValuePtr v) {
if (v->prop != toInt(VehicleProperty::VHAL_HEARTBEAT)) {
@@ -141,7 +152,7 @@
TEST_F(DefaultVhalImplTest, testListProperties) {
std::vector<VehiclePropConfig> configs = mHal->listProperties();
- EXPECT_EQ((size_t)123, configs.size());
+ EXPECT_EQ((size_t)124, configs.size());
}
TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
@@ -314,26 +325,25 @@
ASSERT_EQ(StatusCode::OK, status);
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ std::vector<VehiclePropValuePtr> receivedEvents;
+ waitForEvents(&receivedEvents, 5);
- // Modify the speed after 0.5 seconds.
+ // Modify the speed after 5 events arrive.
VehiclePropValue value;
value.prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
value.value.floatValues.resize(1);
value.value.floatValues[0] = 1.0f;
ASSERT_EQ(StatusCode::OK, mHal->set(value));
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
-
- auto events = mEventQueue.flush();
- ASSERT_LE((size_t)10, events.size());
+ waitForEvents(&receivedEvents, 10);
// The first event should be the default value.
- ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
- EXPECT_EQ(0.0f, events[0]->value.floatValues[0]);
+ ASSERT_EQ((size_t)1, receivedEvents[0]->value.floatValues.size());
+ EXPECT_EQ(0.0f, receivedEvents[0]->value.floatValues[0]);
// The last event should be the value after update.
- ASSERT_EQ((size_t)1, events[events.size() - 1]->value.floatValues.size());
- EXPECT_EQ(1.0f, events[events.size() - 1]->value.floatValues[0]);
+ const auto& lastEvent = receivedEvents[receivedEvents.size() - 1];
+ ASSERT_EQ((size_t)1, lastEvent->value.floatValues.size());
+ EXPECT_EQ(1.0f, lastEvent->value.floatValues[0]);
}
TEST_F(DefaultVhalImplTest, testSubscribeInvalidProp) {
@@ -402,7 +412,7 @@
gotValue->timestamp = 0;
std::string infoMake = toString(*gotValue);
- EXPECT_THAT(std::string(buf), HasSubstr(infoMake));
+ EXPECT_THAT(std::string(buf, sizeof(buf)), HasSubstr(infoMake));
}
TEST_F(DefaultVhalImplTest, testSetPropInvalidAreaId) {
@@ -746,8 +756,9 @@
// Clear existing events.
mEventQueue.flush();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
- // There should be no new events generated.
- EXPECT_EQ((size_t)0, mEventQueue.flush().size());
+ // Technically there should be no new events generated, however, there might still be one event
+ // in the queue while we are stopping the generator.
+ EXPECT_LE(mEventQueue.flush().size(), 1u);
}
std::string getTestFilePath(const char* filename) {
diff --git a/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp b/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
index d7547f6..2e59dbf 100644
--- a/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
+++ b/automotive/vehicle/2.0/default/tests/RecurrentTimer_test.cpp
@@ -69,7 +69,7 @@
std::this_thread::sleep_for(milliseconds(100));
// This test is unstable, so set the tolerance to 50.
ASSERT_EQ_WITH_TOLERANCE(100, counter1ms.load(), 50);
- ASSERT_EQ_WITH_TOLERANCE(20, counter5ms.load(), 5);
+ ASSERT_EQ_WITH_TOLERANCE(20, counter5ms.load(), 10);
}
} // anonymous namespace
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 9e4f252..5b0a505 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -57,46 +57,25 @@
};
/**
- * Vehicle Areas
+ * List of different supported area types for vehicle properties.
* Used to construct property IDs in the VehicleProperty enum.
*
- * Some properties may be associated with particular vehicle areas. For
- * example, VehicleProperty:DOOR_LOCK property must be associated with
- * particular door, thus this property must be marked with
- * VehicleArea:DOOR flag.
+ * Some properties may be associated with particular areas in the vehicle. For example,
+ * VehicleProperty#DOOR_LOCK property must be associated with a particular door, thus this property
+ * must be of the VehicleArea#DOOR area type.
*
- * Other properties may not be associated with particular vehicle area.
- * These kinds of properties must have VehicleArea:GLOBAL flag.
+ * Other properties may not be associated with a particular area in the vehicle. These kinds of
+ * properties must be of the VehicleArea#GLOBAL area type.
*
- * [Definition] Area: An area represents a unique element of an AreaType.
- * For instance, if AreaType is WINDOW, then an area may be FRONT_WINDSHIELD.
- *
- * [Definition] AreaID: An AreaID is a combination of one or more areas,
- * and is represented using a bitmask of Area enums. Different AreaTypes may
- * not be mixed in a single AreaID. For instance, a window area cannot be
- * combined with a seat area in an AreaID.
- *
- * Rules for mapping a zoned property to AreaIDs:
- * - A property must be mapped to an array of AreaIDs that are impacted when
- * the property value changes.
- * - Each element in the array must represent an AreaID, in which the
- * property value can only be changed together in all the areas within
- * the AreaID and never independently. That is, when the property value
- * changes in one of the areas in an AreaID in the array, then it must
- * automatically change in all other areas in the AreaID.
- * - The property value must be independently controllable in any two
- * different AreaIDs in the array.
- * - An area must only appear once in the array of AreaIDs. That is, an
- * area must only be part of a single AreaID in the array.
- *
- * [Definition] Global Property: A property that applies to the entire car
- * and is not associated with a specific area. For example, FUEL_LEVEL,
- * HVAC_STEERING_WHEEL_HEAT.
- *
- * Rules for mapping a global property to AreaIDs:
- * - A global property must not be mapped to AreaIDs.
-*/
+ * Note: This is not the same as areaId used in VehicleAreaConfig. E.g. for a global property, the
+ * property ID is of the VehicleArea#GLOBAL area type, however, the area ID must be 0.
+ */
+// A better name would be VehicleAreaType
enum VehicleArea : int32_t {
+ /**
+ * A global property is a property that applies to the entire vehicle and is not associated with
+ * a specific area. For example, FUEL_LEVEL, HVAC_STEERING_WHEEL_HEAT are global properties.
+ */
GLOBAL = 0x01000000,
/** WINDOW maps to enum VehicleAreaWindow */
WINDOW = 0x03000000,
@@ -829,10 +808,10 @@
/*
* HVAC Properties
*
- * Additional rules for mapping a zoned HVAC property (except
- * HVAC_MAX_DEFROST_ON) to AreaIDs:
- * - Every seat in VehicleAreaSeat that is available in the car, must be
- * part of an AreaID in the AreaID array.
+ * Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
+ * to AreaIDs:
+ * - Every “area” for a specific VehicleArea type that is affected by the
+ * property, must be included in an area ID for that property.
*
* Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
* back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
@@ -860,6 +839,16 @@
* - ROW_1_LEFT
* - ROW_1_RIGHT
* - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+ *
+ * Example 3: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+ * back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). Suppose the car
+ * supports HVAC_AUTO_ON for just the two front seats.
+ * - A valid mapping set of AreaIDs for HVAC_AUTO_ON would be:
+ * - ROW_1_LEFT | ROW_1_RIGHT
+ * - If HVAC_AUTO_ON had two separate control units for the driver side
+ * and passenger side, an alternative mapping would be:
+ * - ROW_1_LEFT
+ * - ROW_1_RIGHT
*/
/**
@@ -1800,11 +1789,11 @@
*
* This parameter selects the memory preset to use to select the seat
* position. The minValue is always 0, and the maxValue determines the
- * number of seat positions available.
+ * number of seat positions available (i.e. numSeatPositions - 1).
*
* For instance, if the driver's seat has 3 memory presets, the maxValue
- * will be 3. When the user wants to select a preset, the desired preset
- * number (1, 2, or 3) is set.
+ * will be 2. When the user wants to select a preset, the desired preset
+ * number (0, 1, or 2) is set.
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:WRITE
@@ -2117,6 +2106,12 @@
| VehicleArea:SEAT),
/**
+ * DO NOT USE
+ *
+ * This property is defined as type VehicleArea:GLOBAL, which means all seats use the same
+ * value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by being defined as
+ * type VehicleArea:SEAT.
+ *
* Headrest height position
*
* Sets the headrest height.
diff --git a/automotive/vehicle/Android.bp b/automotive/vehicle/Android.bp
new file mode 100644
index 0000000..c0d71d7
--- /dev/null
+++ b/automotive/vehicle/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * 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_defaults {
+ name: "VehicleHalInterfaceDefaults",
+ static_libs: [
+ "android.hardware.automotive.vehicle-V2-ndk",
+ "android.hardware.automotive.vehicle.property-V2-ndk",
+ ],
+}
diff --git a/automotive/vehicle/README.md b/automotive/vehicle/README.md
new file mode 100644
index 0000000..e0f03e2
--- /dev/null
+++ b/automotive/vehicle/README.md
@@ -0,0 +1,26 @@
+# Vehicle Hardware Abstraction Layer (VHAL)
+---
+
+This directory stores the VHAL interface definition and VHAL reference
+implementation.
+
+## 2.0 (deprecated)
+
+HIDL based VHAL interface and reference implementation.
+
+## aidl
+
+AIDL based VHAL interfadce and reference implementation.
+
+## proto
+
+Protobuf used to pass message between emulator VHAL and emulator.
+
+## tools
+
+Dev tools related to VHAL.
+
+## vts
+
+VTS test for VHAL. The VTS test works for both AIDL and HIDL VHAL
+implementation. Vendor implementation of VHAL must passes VTS.
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 7e42554..da8416c 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -7,9 +7,24 @@
"name": "VehicleHalDefaultConfigTest"
},
{
+ "name": "VehicleHalDefaultConfigTestEnableTestProperties"
+ },
+ {
+ "name": "JsonConfigLoaderUnitTest"
+ },
+ {
+ "name": "JsonConfigLoaderUnitTestEnableTestProperties"
+ },
+ {
"name": "VehicleHalVehicleUtilsTest"
},
{
+ "name": "VehiclePropertyAnnotationCppTest"
+ },
+ {
+ "name": "VehiclePropertyAnnotationJavaTest"
+ },
+ {
"name": "FakeVehicleHardwareTest"
},
{
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
index 88d1c74..9c8d9c5 100644
--- a/automotive/vehicle/aidl/Android.bp
+++ b/automotive/vehicle/aidl/Android.bp
@@ -25,9 +25,9 @@
name: "android.hardware.automotive.vehicle",
vendor_available: true,
srcs: [
- "android/hardware/automotive/vehicle/**/*.aidl",
+ "android/hardware/automotive/vehicle/*.aidl",
],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
cpp: {
diff --git a/automotive/vehicle/aidl/README.md b/automotive/vehicle/aidl/README.md
new file mode 100644
index 0000000..09f03b4
--- /dev/null
+++ b/automotive/vehicle/aidl/README.md
@@ -0,0 +1,23 @@
+# AIDL Vehicle Hardware Abstraction Layer (VHAL)
+---
+
+This directory stores the AIDL VHAL interface and reference implementation.
+
+## aidl_api
+
+Auto-generated current and previous versions of AIDL VHAL api.
+
+## aidl_test
+
+Contains a test to test that all HIDL VHAL properties are supported in
+AIDL VHAL.
+
+## android
+
+Contains AIDL VHAL interface definition. The main interface file is
+`android/hardware/automotive/vehicle/IVehicle.aidl`.
+
+## impl
+
+Reference implementation for AIDL VHAL and useful libraries for implementing
+vendor AIDL VHAL.
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash
index f478504..d9fd5ad 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/.hash
@@ -1 +1,2 @@
8610b651e162c614a97542d6f4ed039c969823e5
+0678e142246842695c1ba0524592fe2c3b789fc6
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
deleted file mode 100644
index 1363a64..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum EvsServiceType {
- REARVIEW = 0,
- SURROUNDVIEW = 1,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
deleted file mode 100644
index 73d4a14..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum Obd2CommonIgnitionMonitors {
- COMPONENTS_AVAILABLE = 1,
- COMPONENTS_INCOMPLETE = 2,
- FUEL_SYSTEM_AVAILABLE = 4,
- FUEL_SYSTEM_INCOMPLETE = 8,
- MISFIRE_AVAILABLE = 16,
- MISFIRE_INCOMPLETE = 32,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
deleted file mode 100644
index 01104c1..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum Obd2CompressionIgnitionMonitors {
- COMPONENTS_AVAILABLE = 1,
- COMPONENTS_INCOMPLETE = 2,
- FUEL_SYSTEM_AVAILABLE = 4,
- FUEL_SYSTEM_INCOMPLETE = 8,
- MISFIRE_AVAILABLE = 16,
- MISFIRE_INCOMPLETE = 32,
- EGR_OR_VVT_AVAILABLE = 64,
- EGR_OR_VVT_INCOMPLETE = 128,
- PM_FILTER_AVAILABLE = 256,
- PM_FILTER_INCOMPLETE = 512,
- EXHAUST_GAS_SENSOR_AVAILABLE = 1024,
- EXHAUST_GAS_SENSOR_INCOMPLETE = 2048,
- BOOST_PRESSURE_AVAILABLE = 4096,
- BOOST_PRESSURE_INCOMPLETE = 8192,
- NOx_SCR_AVAILABLE = 16384,
- NOx_SCR_INCOMPLETE = 32768,
- NMHC_CATALYST_AVAILABLE = 65536,
- NMHC_CATALYST_INCOMPLETE = 131072,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
deleted file mode 100644
index badc29c..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum Obd2SparkIgnitionMonitors {
- COMPONENTS_AVAILABLE = 1,
- COMPONENTS_INCOMPLETE = 2,
- FUEL_SYSTEM_AVAILABLE = 4,
- FUEL_SYSTEM_INCOMPLETE = 8,
- MISFIRE_AVAILABLE = 16,
- MISFIRE_INCOMPLETE = 32,
- EGR_AVAILABLE = 64,
- EGR_INCOMPLETE = 128,
- OXYGEN_SENSOR_HEATER_AVAILABLE = 256,
- OXYGEN_SENSOR_HEATER_INCOMPLETE = 512,
- OXYGEN_SENSOR_AVAILABLE = 1024,
- OXYGEN_SENSOR_INCOMPLETE = 2048,
- AC_REFRIGERANT_AVAILABLE = 4096,
- AC_REFRIGERANT_INCOMPLETE = 8192,
- SECONDARY_AIR_SYSTEM_AVAILABLE = 16384,
- SECONDARY_AIR_SYSTEM_INCOMPLETE = 32768,
- EVAPORATIVE_SYSTEM_AVAILABLE = 65536,
- EVAPORATIVE_SYSTEM_INCOMPLETE = 131072,
- HEATED_CATALYST_AVAILABLE = 262144,
- HEATED_CATALYST_INCOMPLETE = 524288,
- CATALYST_AVAILABLE = 1048576,
- CATALYST_INCOMPLETE = 2097152,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
index 9b72412..f7e8c5a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -40,4 +40,9 @@
NOT_AVAILABLE = 3,
ACCESS_DENIED = 4,
INTERNAL_ERROR = 5,
+ NOT_AVAILABLE_DISABLED = 6,
+ NOT_AVAILABLE_SPEED_LOW = 7,
+ NOT_AVAILABLE_SPEED_HIGH = 8,
+ NOT_AVAILABLE_POOR_VISIBILITY = 9,
+ NOT_AVAILABLE_SAFETY = 10,
}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
deleted file mode 100644
index f47d5e7..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserInfo.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable UserInfo {
- int userId = 0;
- int flags;
- const int USER_FLAG_SYSTEM = 1;
- const int USER_FLAG_GUEST = 2;
- const int USER_FLAG_EPHEMERAL = 4;
- const int USER_FLAG_ADMIN = 8;
- const int USER_FLAG_DISABLED = 16;
- const int USER_FLAG_PROFILE = 32;
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
deleted file mode 100644
index d7b874a..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleApPowerStateConfigFlag {
- ENABLE_DEEP_SLEEP_FLAG = 1,
- CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 2,
- ENABLE_HIBERNATION_FLAG = 4,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
deleted file mode 100644
index fc669ec..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleApPowerStateReport {
- WAIT_FOR_VHAL = 1,
- DEEP_SLEEP_ENTRY = 2,
- DEEP_SLEEP_EXIT = 3,
- SHUTDOWN_POSTPONE = 4,
- SHUTDOWN_START = 5,
- ON = 6,
- SHUTDOWN_PREPARE = 7,
- SHUTDOWN_CANCELLED = 8,
- HIBERNATION_ENTRY = 9,
- HIBERNATION_EXIT = 10,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleArea.aidl
deleted file mode 100644
index 4f8b917..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleArea {
- GLOBAL = 16777216,
- WINDOW = 50331648,
- MIRROR = 67108864,
- SEAT = 83886080,
- DOOR = 100663296,
- WHEEL = 117440512,
- MASK = 251658240,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b93a11b..6960894 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -41,4 +41,5 @@
long maxInt64Value;
float minFloatValue;
float maxFloatValue;
+ @nullable long[] supportedEnumValues;
}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
deleted file mode 100644
index 11139f9..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaDoor {
- ROW_1_LEFT = 1,
- ROW_1_RIGHT = 4,
- ROW_2_LEFT = 16,
- ROW_2_RIGHT = 64,
- ROW_3_LEFT = 256,
- ROW_3_RIGHT = 1024,
- HOOD = 268435456,
- REAR = 536870912,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
deleted file mode 100644
index c1e2fbd..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaMirror {
- DRIVER_LEFT = 1,
- DRIVER_RIGHT = 2,
- DRIVER_CENTER = 4,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
deleted file mode 100644
index e76de32..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaSeat {
- ROW_1_LEFT = 1,
- ROW_1_CENTER = 2,
- ROW_1_RIGHT = 4,
- ROW_2_LEFT = 16,
- ROW_2_CENTER = 32,
- ROW_2_RIGHT = 64,
- ROW_3_LEFT = 256,
- ROW_3_CENTER = 512,
- ROW_3_RIGHT = 1024,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
deleted file mode 100644
index 9e83434..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaWheel {
- UNKNOWN = 0,
- LEFT_FRONT = 1,
- RIGHT_FRONT = 2,
- LEFT_REAR = 4,
- RIGHT_REAR = 8,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
deleted file mode 100644
index 6ec26fe..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleAreaWindow {
- FRONT_WINDSHIELD = 1,
- REAR_WINDSHIELD = 2,
- ROW_1_LEFT = 16,
- ROW_1_RIGHT = 64,
- ROW_2_LEFT = 256,
- ROW_2_RIGHT = 1024,
- ROW_3_LEFT = 4096,
- ROW_3_RIGHT = 16384,
- ROOF_TOP_1 = 65536,
- ROOF_TOP_2 = 131072,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
deleted file mode 100644
index 5aeafa4..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleDisplay {
- MAIN = 0,
- INSTRUMENT_CLUSTER = 1,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleGear.aidl
deleted file mode 100644
index db4760d..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleGear.aidl
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleGear {
- GEAR_UNKNOWN = 0,
- GEAR_NEUTRAL = 1,
- GEAR_REVERSE = 2,
- GEAR_PARK = 4,
- GEAR_DRIVE = 8,
- GEAR_1 = 16,
- GEAR_2 = 32,
- GEAR_3 = 64,
- GEAR_4 = 128,
- GEAR_5 = 256,
- GEAR_6 = 512,
- GEAR_7 = 1024,
- GEAR_8 = 2048,
- GEAR_9 = 4096,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
deleted file mode 100644
index a85751f..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleHvacFanDirection {
- UNKNOWN = 0,
- FACE = 1,
- FLOOR = 2,
- FACE_AND_FLOOR = 3,
- DEFROST = 4,
- DEFROST_AND_FLOOR = 6,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
deleted file mode 100644
index 09d5423..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleIgnitionState {
- UNDEFINED = 0,
- LOCK = 1,
- OFF = 2,
- ACC = 3,
- ON = 4,
- START = 5,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
deleted file mode 100644
index 0d3c636..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleLightSwitch {
- OFF = 0,
- ON = 1,
- DAYTIME_RUNNING = 2,
- AUTOMATIC = 256,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
deleted file mode 100644
index 04f8fa3..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleProperty {
- INVALID = 0,
- INFO_VIN = 286261504,
- INFO_MAKE = 286261505,
- INFO_MODEL = 286261506,
- INFO_MODEL_YEAR = 289407235,
- INFO_FUEL_CAPACITY = 291504388,
- INFO_FUEL_TYPE = 289472773,
- INFO_EV_BATTERY_CAPACITY = 291504390,
- INFO_EV_CONNECTOR_TYPE = 289472775,
- INFO_FUEL_DOOR_LOCATION = 289407240,
- INFO_EV_PORT_LOCATION = 289407241,
- INFO_DRIVER_SEAT = 356516106,
- INFO_EXTERIOR_DIMENSIONS = 289472779,
- INFO_MULTI_EV_PORT_LOCATIONS = 289472780,
- PERF_ODOMETER = 291504644,
- PERF_VEHICLE_SPEED = 291504647,
- PERF_VEHICLE_SPEED_DISPLAY = 291504648,
- PERF_STEERING_ANGLE = 291504649,
- PERF_REAR_STEERING_ANGLE = 291504656,
- ENGINE_COOLANT_TEMP = 291504897,
- ENGINE_OIL_LEVEL = 289407747,
- ENGINE_OIL_TEMP = 291504900,
- ENGINE_RPM = 291504901,
- WHEEL_TICK = 290521862,
- FUEL_LEVEL = 291504903,
- FUEL_DOOR_OPEN = 287310600,
- EV_BATTERY_LEVEL = 291504905,
- EV_CHARGE_PORT_OPEN = 287310602,
- EV_CHARGE_PORT_CONNECTED = 287310603,
- EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 291504908,
- RANGE_REMAINING = 291504904,
- TIRE_PRESSURE = 392168201,
- CRITICALLY_LOW_TIRE_PRESSURE = 392168202,
- GEAR_SELECTION = 289408000,
- CURRENT_GEAR = 289408001,
- PARKING_BRAKE_ON = 287310850,
- PARKING_BRAKE_AUTO_APPLY = 287310851,
- FUEL_LEVEL_LOW = 287310853,
- NIGHT_MODE = 287310855,
- TURN_SIGNAL_STATE = 289408008,
- IGNITION_STATE = 289408009,
- ABS_ACTIVE = 287310858,
- TRACTION_CONTROL_ACTIVE = 287310859,
- HVAC_FAN_SPEED = 356517120,
- HVAC_FAN_DIRECTION = 356517121,
- HVAC_TEMPERATURE_CURRENT = 358614274,
- HVAC_TEMPERATURE_SET = 358614275,
- HVAC_DEFROSTER = 320865540,
- HVAC_AC_ON = 354419973,
- HVAC_MAX_AC_ON = 354419974,
- HVAC_MAX_DEFROST_ON = 354419975,
- HVAC_RECIRC_ON = 354419976,
- HVAC_DUAL_ON = 354419977,
- HVAC_AUTO_ON = 354419978,
- HVAC_SEAT_TEMPERATURE = 356517131,
- HVAC_SIDE_MIRROR_HEAT = 339739916,
- HVAC_STEERING_WHEEL_HEAT = 289408269,
- HVAC_TEMPERATURE_DISPLAY_UNITS = 289408270,
- HVAC_ACTUAL_FAN_SPEED_RPM = 356517135,
- HVAC_POWER_ON = 354419984,
- HVAC_FAN_DIRECTION_AVAILABLE = 356582673,
- HVAC_AUTO_RECIRC_ON = 354419986,
- HVAC_SEAT_VENTILATION = 356517139,
- HVAC_ELECTRIC_DEFROSTER_ON = 320865556,
- HVAC_TEMPERATURE_VALUE_SUGGESTION = 291570965,
- DISTANCE_DISPLAY_UNITS = 289408512,
- FUEL_VOLUME_DISPLAY_UNITS = 289408513,
- TIRE_PRESSURE_DISPLAY_UNITS = 289408514,
- EV_BATTERY_DISPLAY_UNITS = 289408515,
- FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 287311364,
- VEHICLE_SPEED_DISPLAY_UNITS = 289408517,
- EXTERNAL_CAR_TIME = 290457096,
- ANDROID_EPOCH_TIME = 290457094,
- STORAGE_ENCRYPTION_BINDING_SEED = 292554247,
- ENV_OUTSIDE_TEMPERATURE = 291505923,
- AP_POWER_STATE_REQ = 289475072,
- AP_POWER_STATE_REPORT = 289475073,
- AP_POWER_BOOTUP_REASON = 289409538,
- DISPLAY_BRIGHTNESS = 289409539,
- HW_KEY_INPUT = 289475088,
- HW_ROTARY_INPUT = 289475104,
- HW_CUSTOM_INPUT = 289475120,
- DOOR_POS = 373295872,
- DOOR_MOVE = 373295873,
- DOOR_LOCK = 371198722,
- MIRROR_Z_POS = 339741504,
- MIRROR_Z_MOVE = 339741505,
- MIRROR_Y_POS = 339741506,
- MIRROR_Y_MOVE = 339741507,
- MIRROR_LOCK = 287312708,
- MIRROR_FOLD = 287312709,
- SEAT_MEMORY_SELECT = 356518784,
- SEAT_MEMORY_SET = 356518785,
- SEAT_BELT_BUCKLED = 354421634,
- SEAT_BELT_HEIGHT_POS = 356518787,
- SEAT_BELT_HEIGHT_MOVE = 356518788,
- SEAT_FORE_AFT_POS = 356518789,
- SEAT_FORE_AFT_MOVE = 356518790,
- SEAT_BACKREST_ANGLE_1_POS = 356518791,
- SEAT_BACKREST_ANGLE_1_MOVE = 356518792,
- SEAT_BACKREST_ANGLE_2_POS = 356518793,
- SEAT_BACKREST_ANGLE_2_MOVE = 356518794,
- SEAT_HEIGHT_POS = 356518795,
- SEAT_HEIGHT_MOVE = 356518796,
- SEAT_DEPTH_POS = 356518797,
- SEAT_DEPTH_MOVE = 356518798,
- SEAT_TILT_POS = 356518799,
- SEAT_TILT_MOVE = 356518800,
- SEAT_LUMBAR_FORE_AFT_POS = 356518801,
- SEAT_LUMBAR_FORE_AFT_MOVE = 356518802,
- SEAT_LUMBAR_SIDE_SUPPORT_POS = 356518803,
- SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 356518804,
- SEAT_HEADREST_HEIGHT_POS = 289409941,
- SEAT_HEADREST_HEIGHT_MOVE = 356518806,
- SEAT_HEADREST_ANGLE_POS = 356518807,
- SEAT_HEADREST_ANGLE_MOVE = 356518808,
- SEAT_HEADREST_FORE_AFT_POS = 356518809,
- SEAT_HEADREST_FORE_AFT_MOVE = 356518810,
- SEAT_OCCUPANCY = 356518832,
- WINDOW_POS = 322964416,
- WINDOW_MOVE = 322964417,
- WINDOW_LOCK = 320867268,
- VEHICLE_MAP_SERVICE = 299895808,
- OBD2_LIVE_FRAME = 299896064,
- OBD2_FREEZE_FRAME = 299896065,
- OBD2_FREEZE_FRAME_INFO = 299896066,
- OBD2_FREEZE_FRAME_CLEAR = 299896067,
- HEADLIGHTS_STATE = 289410560,
- HIGH_BEAM_LIGHTS_STATE = 289410561,
- FOG_LIGHTS_STATE = 289410562,
- HAZARD_LIGHTS_STATE = 289410563,
- HEADLIGHTS_SWITCH = 289410576,
- HIGH_BEAM_LIGHTS_SWITCH = 289410577,
- FOG_LIGHTS_SWITCH = 289410578,
- HAZARD_LIGHTS_SWITCH = 289410579,
- CABIN_LIGHTS_STATE = 289410817,
- CABIN_LIGHTS_SWITCH = 289410818,
- READING_LIGHTS_STATE = 356519683,
- READING_LIGHTS_SWITCH = 356519684,
- SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 287313669,
- DISABLED_OPTIONAL_FEATURES = 286265094,
- INITIAL_USER_INFO = 299896583,
- SWITCH_USER = 299896584,
- CREATE_USER = 299896585,
- REMOVE_USER = 299896586,
- USER_IDENTIFICATION_ASSOCIATION = 299896587,
- EVS_SERVICE_REQUEST = 289476368,
- POWER_POLICY_REQ = 286265121,
- POWER_POLICY_GROUP_REQ = 286265122,
- CURRENT_POWER_POLICY = 286265123,
- WATCHDOG_ALIVE = 290459441,
- WATCHDOG_TERMINATED_PROCESS = 299896626,
- VHAL_HEARTBEAT = 290459443,
- CLUSTER_SWITCH_UI = 289410868,
- CLUSTER_DISPLAY_STATE = 289476405,
- CLUSTER_REPORT_STATE = 299896630,
- CLUSTER_REQUEST_DISPLAY = 289410871,
- CLUSTER_NAVIGATION_STATE = 292556600,
- ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 289410873,
- ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 289410874,
- FRONT_FOG_LIGHTS_STATE = 289410875,
- FRONT_FOG_LIGHTS_SWITCH = 289410876,
- REAR_FOG_LIGHTS_STATE = 289410877,
- REAR_FOG_LIGHTS_SWITCH = 289410878,
- EV_CHARGE_CURRENT_DRAW_LIMIT = 291508031,
- EV_CHARGE_PERCENT_LIMIT = 291508032,
- EV_CHARGE_STATE = 289410881,
- EV_CHARGE_SWITCH = 287313730,
- EV_CHARGE_TIME_REMAINING = 289410883,
- EV_REGENERATIVE_BRAKING_STATE = 289410884,
- TRAILER_PRESENT = 289410885,
- VEHICLE_CURB_WEIGHT = 289410886,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
index ec9587f..dde9a88 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyAccess.aidl
@@ -34,8 +34,8 @@
package android.hardware.automotive.vehicle;
@Backing(type="int") @VintfStability
enum VehiclePropertyAccess {
- NONE = 0,
- READ = 1,
- WRITE = 2,
- READ_WRITE = 3,
+ NONE = 0x00,
+ READ = 0x01,
+ WRITE = 0x02,
+ READ_WRITE = 0x03,
}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
index 5455fdd..2f9d107 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.aidl
@@ -34,7 +34,7 @@
package android.hardware.automotive.vehicle;
@Backing(type="int") @VintfStability
enum VehiclePropertyChangeMode {
- STATIC = 0,
- ON_CHANGE = 1,
- CONTINUOUS = 2,
+ STATIC = 0x00,
+ ON_CHANGE = 0x01,
+ CONTINUOUS = 0x02,
}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
deleted file mode 100644
index 0c049c4..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehiclePropertyGroup {
- SYSTEM = 268435456,
- VENDOR = 536870912,
- MASK = -268435456,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
index 6d0e041..642ce83 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
@@ -34,7 +34,7 @@
package android.hardware.automotive.vehicle;
@Backing(type="int") @VintfStability
enum VehiclePropertyStatus {
- AVAILABLE = 0,
- UNAVAILABLE = 1,
- ERROR = 2,
+ AVAILABLE = 0x00,
+ UNAVAILABLE = 0x01,
+ ERROR = 0x02,
}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
deleted file mode 100644
index da6d2c2..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehiclePropertyType {
- STRING = 1048576,
- BOOLEAN = 2097152,
- INT32 = 4194304,
- INT32_VEC = 4259840,
- INT64 = 5242880,
- INT64_VEC = 5308416,
- FLOAT = 6291456,
- FLOAT_VEC = 6356992,
- BYTES = 7340032,
- MIXED = 14680064,
- MASK = 16711680,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
deleted file mode 100644
index 78c1795..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleTurnSignal {
- NONE = 0,
- RIGHT = 1,
- LEFT = 2,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
deleted file mode 100644
index c80fdbb..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleUnit {
- SHOULD_NOT_USE = 0,
- METER_PER_SEC = 1,
- RPM = 2,
- HERTZ = 3,
- PERCENTILE = 16,
- MILLIMETER = 32,
- METER = 33,
- KILOMETER = 35,
- MILE = 36,
- CELSIUS = 48,
- FAHRENHEIT = 49,
- KELVIN = 50,
- MILLILITER = 64,
- LITER = 65,
- GALLON = 66,
- US_GALLON = 66,
- IMPERIAL_GALLON = 67,
- NANO_SECS = 80,
- SECS = 83,
- YEAR = 89,
- WATT_HOUR = 96,
- MILLIAMPERE = 97,
- MILLIVOLT = 98,
- MILLIWATTS = 99,
- AMPERE_HOURS = 100,
- KILOWATT_HOUR = 101,
- AMPERE = 102,
- KILOPASCAL = 112,
- PSI = 113,
- BAR = 114,
- DEGREES = 128,
- MILES_PER_HOUR = 144,
- KILOMETERS_PER_HOUR = 145,
-}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
deleted file mode 100644
index 58524f3..0000000
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.automotive.vehicle;
-@Backing(type="int") @VintfStability
-enum VehicleVendorPermission {
- PERMISSION_DEFAULT = 0,
- PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 1,
- PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 2,
- PERMISSION_SET_VENDOR_CATEGORY_DOOR = 3,
- PERMISSION_GET_VENDOR_CATEGORY_DOOR = 4,
- PERMISSION_SET_VENDOR_CATEGORY_SEAT = 5,
- PERMISSION_GET_VENDOR_CATEGORY_SEAT = 6,
- PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 7,
- PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 8,
- PERMISSION_SET_VENDOR_CATEGORY_INFO = 9,
- PERMISSION_GET_VENDOR_CATEGORY_INFO = 10,
- PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 11,
- PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 12,
- PERMISSION_SET_VENDOR_CATEGORY_HVAC = 13,
- PERMISSION_GET_VENDOR_CATEGORY_HVAC = 14,
- PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 15,
- PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 16,
- PERMISSION_SET_VENDOR_CATEGORY_1 = 65536,
- PERMISSION_GET_VENDOR_CATEGORY_1 = 69632,
- PERMISSION_SET_VENDOR_CATEGORY_2 = 131072,
- PERMISSION_GET_VENDOR_CATEGORY_2 = 135168,
- PERMISSION_SET_VENDOR_CATEGORY_3 = 196608,
- PERMISSION_GET_VENDOR_CATEGORY_3 = 200704,
- PERMISSION_SET_VENDOR_CATEGORY_4 = 262144,
- PERMISSION_GET_VENDOR_CATEGORY_4 = 266240,
- PERMISSION_SET_VENDOR_CATEGORY_5 = 327680,
- PERMISSION_GET_VENDOR_CATEGORY_5 = 331776,
- PERMISSION_SET_VENDOR_CATEGORY_6 = 393216,
- PERMISSION_GET_VENDOR_CATEGORY_6 = 397312,
- PERMISSION_SET_VENDOR_CATEGORY_7 = 458752,
- PERMISSION_GET_VENDOR_CATEGORY_7 = 462848,
- PERMISSION_SET_VENDOR_CATEGORY_8 = 524288,
- PERMISSION_GET_VENDOR_CATEGORY_8 = 528384,
- PERMISSION_SET_VENDOR_CATEGORY_9 = 589824,
- PERMISSION_GET_VENDOR_CATEGORY_9 = 593920,
- PERMISSION_SET_VENDOR_CATEGORY_10 = 655360,
- PERMISSION_GET_VENDOR_CATEGORY_10 = 659456,
- PERMISSION_NOT_ACCESSIBLE = -268435456,
-}
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index 5284a0a..44d7445 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -20,7 +20,7 @@
cc_test {
name: "VehicleHalAidlHidlCompatibilityTest",
- srcs: ["*.cpp"],
+ srcs: ["AidlHidlCompatibilityTest.cpp"],
shared_libs: [
"libbinder_ndk",
"libhidlbase",
@@ -35,3 +35,26 @@
test_suites: ["device-tests"],
vendor: true,
}
+
+cc_test {
+ name: "VehiclePropertyAnnotationCppTest",
+ srcs: ["VehiclePropertyAnnotationCppTest.cpp"],
+ header_libs: ["IVehicleGeneratedHeaders"],
+ defaults: ["VehicleHalInterfaceDefaults"],
+ test_suites: ["general-tests"],
+}
+
+android_test {
+ name: "VehiclePropertyAnnotationJavaTest",
+ srcs: [
+ "VehiclePropertyAnnotationJavaTest.java",
+ ":IVehicleGeneratedJavaFiles",
+ ],
+ static_libs: [
+ "android.hardware.automotive.vehicle-V2-java",
+ "android.hardware.automotive.vehicle.property-V2-java",
+ "androidx.test.runner",
+ "truth-prebuilt",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/automotive/vehicle/aidl/aidl_test/AndroidManifest.xml b/automotive/vehicle/aidl/aidl_test/AndroidManifest.xml
new file mode 100644
index 0000000..00fdf50
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_test/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.hardware.automotive.vehicle" >
+
+ <application/>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.hardware.automotive.vehicle"
+ android:label="test to verify VHAL annotation"/>
+
+</manifest>
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationCppTest.cpp b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationCppTest.cpp
new file mode 100644
index 0000000..a4bbbe8
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationCppTest.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <AccessForVehicleProperty.h>
+#include <ChangeModeForVehicleProperty.h>
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <gtest/gtest.h>
+#include <unordered_set>
+
+namespace aidl_vehicle = ::aidl::android::hardware::automotive::vehicle;
+using aidl_vehicle::AccessForVehicleProperty;
+using aidl_vehicle::ChangeModeForVehicleProperty;
+using aidl_vehicle::VehicleProperty;
+
+namespace {
+ template<class T>
+ bool doesAnnotationMapContainsAllProps(std::unordered_map<VehicleProperty, T> annotationMap) {
+ for (const VehicleProperty& v : ::ndk::enum_range<VehicleProperty>()) {
+ std::string name = aidl_vehicle::toString(v);
+ if (name == "INVALID") {
+ continue;
+ }
+ if (annotationMap.find(v) == annotationMap.end()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+} // namespace
+
+TEST(VehiclePropertyAnnotationCppTest, testChangeMode) {
+ ASSERT_TRUE(doesAnnotationMapContainsAllProps(ChangeModeForVehicleProperty))
+ << "Outdated annotation-generated AIDL files. Please run "
+ << "generate_annotation_enums.py to update.";
+}
+
+TEST(VehiclePropertyAnnotationCppTest, testAccess) {
+ ASSERT_TRUE(doesAnnotationMapContainsAllProps(AccessForVehicleProperty))
+ << "Outdated annotation-generated AIDL files. Please run "
+ << "generate_annotation_enums.py to update.";
+}
diff --git a/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationJavaTest.java b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationJavaTest.java
new file mode 100644
index 0000000..ef49299
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_test/VehiclePropertyAnnotationJavaTest.java
@@ -0,0 +1,60 @@
+package android.hardware.automotive.vehicle;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.fail;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Map;
+
+@RunWith(JUnit4.class)
+public class VehiclePropertyAnnotationJavaTest {
+
+ private boolean doesAnnotationMapContainsAllProps(Map<Integer, Integer> annotationMap) {
+ for (Field field : VehicleProperty.class.getDeclaredFields()) {
+ int modifiers = field.getModifiers();
+ try {
+ if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)
+ && Modifier.isPublic(modifiers) && field.getType().equals(int.class)) {
+ int propId = field.getInt(/* obj= */ null);
+ if (propId == VehicleProperty.INVALID) {
+ // Skip INVALID_PROP.
+ continue;
+ }
+ if (annotationMap.get(propId) == null) {
+ return false;
+ }
+ }
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException(
+ "Cannot access a member for VehicleProperty.class", e);
+ }
+ }
+ return true;
+ }
+
+ @Test
+ @SmallTest
+ public void testChangeMode() {
+ assertWithMessage("Outdated annotation-generated AIDL files. Please run "
+ + "generate_annotation_enums.py to update.")
+ .that(doesAnnotationMapContainsAllProps(ChangeModeForVehicleProperty.values))
+ .isTrue();
+ }
+
+ @Test
+ @SmallTest
+ public void testAccess() {
+ assertWithMessage("Outdated annotation-generated AIDL files. Please run "
+ + "generate_annotation_enums.py to update.")
+ .that(doesAnnotationMapContainsAllProps(AccessForVehicleProperty.values))
+ .isTrue();
+ }
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl
deleted file mode 100644
index 6c621f7..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceType.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-/**
- * Used by EVS_SERVICE_REQUEST to enumerate the service's type.
- */
-@VintfStability
-@Backing(type="int")
-enum EvsServiceType {
- REARVIEW = 0,
- SURROUNDVIEW = 1,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
index 47fc54b..c896d14 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -190,6 +190,14 @@
* what the sampleRate specified in {@code options}, the timestamp for
* the timestamp is updated 10 times/s.
*
+ * If a property is unavailable for reading because it depends on some power
+ * state which is off, property change event may not be generated until the
+ * property becomes available. For ON_CHANGE property, if the property
+ * changes from NOT_AVAILABLE to OKAY for reading some or all area(s), for
+ * each area that becomes available for reading, one property change event
+ * must be generated. The event must contain the current value for the area
+ * and must have {@code AVAILABLE} status.
+ *
* @param callback The subscription callbacks.
* {@link IVehicleCallback#onPropertyEvent} would be called when a new
* property event arrives.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
index 9c6875b..28ccc1d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -20,8 +20,8 @@
@JavaDerive(equals=true, toString=true)
parcelable RawPropValues {
/**
- * This is used for properties of types VehiclePropertyType#INT
- * and VehiclePropertyType#INT_VEC
+ * This is used for properties of types VehiclePropertyType#INT32,
+ * VehiclePropertyType#BOOLEAN and VehiclePropertyType#INT32_VEC
*/
int[] int32Values = {};
@@ -31,7 +31,10 @@
*/
float[] floatValues;
- /** This is used for properties of type VehiclePropertyType#INT64 */
+ /**
+ * This is used for properties of type VehiclePropertyType#INT64 and
+ * VehiclePropertyType#INT64_VEC
+ */
long[] int64Values;
/** This is used for properties of type VehiclePropertyType#BYTES */
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
index 23019ca..fd4b199 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -17,14 +17,21 @@
package android.hardware.automotive.vehicle;
/**
- * Error codes used in vehicle HAL interface.
+ * Error codes used in vehicle HAL interface. System defined error codes will have the range from
+ * 0x0000 to 0xffff and vendor error codes will have the range from 0x0001 to 0xffff. The error code
+ * is formatted as [VENDOR_ERROR] << 16 | [SYSTEM_ERROR]. A vendor error code of 0 indicates vendor
+ * code not set.
*/
@VintfStability
@Backing(type="int")
enum StatusCode {
OK = 0,
/**
- * Try again.
+ * Caller should try again.
+ *
+ * This code must be returned when an ephemeral error happens and a retry
+ * will likely succeed. E.g., when the device is currently booting up
+ * and the property is not ready yet.
*/
TRY_AGAIN = 1,
/**
@@ -32,9 +39,22 @@
*/
INVALID_ARG = 2,
/**
+ * The property is currently unavailable and will be unavailable unless
+ * some other state changes.
+ *
* This code must be returned when device that associated with the vehicle
* property is not available. For example, when client tries to set HVAC
* temperature when the whole HVAC unit is turned OFF.
+ *
+ * The difference between this and TRY_AGAIN is that if NOT_AVAILABLE is
+ * returned for a property, it will remain NOT_AVAILABLE unless some other
+ * state changes. This means a retry will likely still return NOT_AVAILABLE.
+ * However, for TRY_AGAIN error, a retry will likely return OK.
+ *
+ * When subscribing to a property that is currently unavailable for getting.
+ * VHAL must return OK even if getting/setting must return NOT_AVAILABLE.
+ * VHAL must not generate property change event when the property is not
+ * available for getting.
*/
NOT_AVAILABLE = 3,
/**
@@ -45,4 +65,35 @@
* Something unexpected has happened in Vehicle HAL
*/
INTERNAL_ERROR = 5,
+
+ /**
+ * The following error codes were added in version 2 of this interface.
+ */
+
+ /**
+ * For features that are not available because the underlying feature is
+ * disabled.
+ */
+ NOT_AVAILABLE_DISABLED = 6,
+ /**
+ * For features that are not available because the vehicle speed is too low.
+ */
+ NOT_AVAILABLE_SPEED_LOW = 7,
+ /**
+ * For features that are not available because the vehicle speed is too
+ * high.
+ */
+ NOT_AVAILABLE_SPEED_HIGH = 8,
+ /**
+ * For features that are not available because of bad camera or sensor
+ * visibility. Examples might be bird poop blocking the camera or a bumper
+ * cover blocking an ultrasonic sensor.
+ */
+ NOT_AVAILABLE_POOR_VISIBILITY = 9,
+ /**
+ * The feature cannot be accessed due to safety reasons. Eg. System could be
+ * in a faulty state, an object or person could be blocking the requested
+ * operation such as closing a trunk door, etc.
+ */
+ NOT_AVAILABLE_SAFETY = 10,
}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/TrailerState.aidl
deleted file mode 100644
index fd42062..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/TrailerState.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-/**
- * Used by the trailer present property to enumerate the current state
- * of the trailer.
- */
-@VintfStability
-@Backing(type="int")
-enum TrailerState {
- UNKNOWN = 0,
- NOT_PRESENT = 1,
- PRESENT = 2,
- ERROR = 3,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl
deleted file mode 100644
index dab0349..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-@VintfStability
-@Backing(type="int")
-enum VehicleArea {
- GLOBAL = 0x01000000,
- /** WINDOW maps to enum VehicleAreaWindow */
- WINDOW = 0x03000000,
- /** MIRROR maps to enum VehicleAreaMirror */
- MIRROR = 0x04000000,
- /** SEAT maps to enum VehicleAreaSeat */
- SEAT = 0x05000000,
- /** DOOR maps to enum VehicleAreaDoor */
- DOOR = 0x06000000,
- /** WHEEL maps to enum VehicleAreaWheel */
- WHEEL = 0x07000000,
-
- MASK = 0x0f000000,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b44996d..20c046d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -20,7 +20,7 @@
@JavaDerive(equals=true, toString=true)
parcelable VehicleAreaConfig {
/**
- * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
+ * Area id is always 0 for VehicleArea#GLOBAL properties.
*/
int areaId;
@@ -40,4 +40,11 @@
float minFloatValue;
float maxFloatValue;
+
+ /**
+ * If the property has a @data_enum, then it is possible to specify a supported subset of the
+ * @data_enum. If the property has a @data_enum and supportedEnumValues is null, then it is
+ * assumed all @data_enum values are supported unless specified through another mechanism.
+ */
+ @nullable long[] supportedEnumValues;
}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl
deleted file mode 100644
index 1759a90..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleDisplay.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-@VintfStability
-@Backing(type="int")
-enum VehicleDisplay {
- /**
- * The primary Android display (for example, center console)
- */
- MAIN = 0,
- INSTRUMENT_CLUSTER = 1,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
deleted file mode 100644
index fa5d711..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-/**
- * Bit flags for fan direction
- */
-@VintfStability
-@Backing(type="int")
-enum VehicleHvacFanDirection {
- UNKNOWN = 0x0,
- FACE = 0x1,
- FLOOR = 0x2,
- /**
- * FACE_AND_FLOOR = FACE | FLOOR
- */
- FACE_AND_FLOOR = 0x3,
- DEFROST = 0x4,
- /**
- * DEFROST_AND_FLOOR = DEFROST | FLOOR
- */
- DEFROST_AND_FLOOR = 0x06,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
deleted file mode 100644
index bf3c858..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-@VintfStability
-@Backing(type="int")
-enum VehicleOilLevel {
- /**
- * Oil level values
- */
- CRITICALLY_LOW = 0,
- LOW = 1,
- NORMAL = 2,
- HIGH = 3,
- ERROR = 4,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 1b48f0b..61b9369 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -37,7 +37,25 @@
VehiclePropertyChangeMode changeMode = VehiclePropertyChangeMode.STATIC;
/**
- * Contains per-area configuration.
+ * Contains per-areaId configuration.
+ *
+ * [Definition] area: An area represents a unique element of a VehicleArea. For instance, if the
+ * VehicleArea is WINDOW, then an example area is FRONT_WINDSHIELD.
+ *
+ * [Definition] area ID: An area ID is a combination of one or more areas, and is created by
+ * bitwise "OR"ing the areas together. Areas from different VehicleArea values may not be
+ * mixed in a single area ID. For example, a VehicleAreaWindow area cannot be combined with a
+ * VehicleAreaSeat area in an area ID.
+ *
+ * For VehicleArea#GLOBAL properties, they must map only to a single area ID of 0.
+ *
+ * Rules for mapping a non VehicleArea#GLOBAL property to area IDs:
+ * - A property must be mapped to a set of area IDs that are impacted when the property value
+ * changes.
+ * - An area cannot be part of multiple area IDs, it must only be part of a single area ID.
+ * - When the property value changes in one of the areas in an area ID, then it must
+ * automatically change in all other areas in the area ID.
+ * - The property value must be independently controllable in any two different area IDs.
*/
VehicleAreaConfig[] areaConfigs;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
deleted file mode 100644
index 727b949..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ /dev/null
@@ -1,2843 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-import android.hardware.automotive.vehicle.VehiclePropertyType;
-/**
- * Declares all vehicle properties. VehicleProperty has a bitwise structure.
- * Each property must have:
- * - a unique id from range 0x0100 - 0xffff
- * - associated data type using VehiclePropertyType
- * - property group (VehiclePropertyGroup)
- * - vehicle area (VehicleArea)
- *
- * Vendors are allowed to extend this enum with their own properties. In this
- * case they must use VehiclePropertyGroup:VENDOR flag when the property is
- * declared.
- *
- * When a property's status field is not set to AVAILABLE:
- * - IVehicle#set may return StatusCode::NOT_AVAILABLE.
- * - IVehicle#get is not guaranteed to work.
- *
- * Properties set to values out of range must be ignored and no action taken
- * in response to such ill formed requests.
- */
-@VintfStability
-@Backing(type="int")
-enum VehicleProperty {
- /**
- * Undefined property.
- */
- INVALID = 0x00000000,
- /**
- * VIN of vehicle
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- */
- INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Manufacturer of vehicle
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- */
- INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Model of vehicle
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- */
- INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Model year of vehicle.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:YEAR
- */
- INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Fuel capacity of the vehicle in milliliters
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:MILLILITER
- */
- INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * List of fuels the vehicle may use
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @data_enum FuelType
- */
- INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Battery capacity of the vehicle, if EV or hybrid. This is the nominal
- * battery capacity when the vehicle is new.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:WH
- */
- INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * List of connectors this EV may use
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @data_enum EvConnectorType
- * @access VehiclePropertyAccess:READ
- */
- INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Fuel door location
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @data_enum PortLocationType
- * @access VehiclePropertyAccess:READ
- */
- INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * EV port location
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @data_enum PortLocationType
- */
- INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Driver's seat location
- * VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @data_enum VehicleAreaSeat
- * @access VehiclePropertyAccess:READ
- */
- INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Exterior dimensions of vehicle.
- *
- * int32Values[0] = height
- * int32Values[1] = length
- * int32Values[2] = width
- * int32Values[3] = width including mirrors
- * int32Values[4] = wheel base
- * int32Values[5] = track width front
- * int32Values[6] = track width rear
- * int32Values[7] = curb to curb turning radius
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:MILLIMETER
- */
- INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Multiple EV port locations
- *
- * Implement this property if the vehicle has multiple EV ports.
- * Port locations are defined in PortLocationType.
- * For example, a car has one port in front left and one port in rear left:
- * int32Values[0] = PortLocationType::FRONT_LEFT
- * int32Values[0] = PortLocationType::REAR_LEFT
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @data_enum PortLocationType
- */
- INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Current odometer value of the vehicle
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:KILOMETER
- */
- PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Speed of the vehicle
- *
- * The value must be positive when the vehicle is moving forward and negative when
- * the vehicle is moving backward. This value is independent of gear value
- * (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL,
- * PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving
- * backward, and zero when not moving.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:METER_PER_SEC
- */
- PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Speed of the vehicle for displays
- *
- * Some cars display a slightly slower speed than the actual speed. This is
- * usually displayed on the speedometer.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:METER_PER_SEC
- */
- PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Front bicycle model steering angle for vehicle
- *
- * Angle is in degrees. Left is negative.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:DEGREES
- */
- PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Rear bicycle model steering angle for vehicle
- *
- * Angle is in degrees. Left is negative.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:DEGREES
- */
- PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Temperature of engine coolant
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELSIUS
- */
- ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Engine oil level
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleOilLevel
- */
- ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Temperature of engine oil
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELSIUS
- */
- ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Engine rpm
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:RPM
- */
- ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Reports wheel ticks
- *
- * The first element in the vector is a reset count. A reset indicates
- * previous tick counts are not comparable with this and future ones. Some
- * sort of discontinuity in tick counting has occurred.
- *
- * The next four elements represent ticks for individual wheels in the
- * following order: front left, front right, rear right, rear left. All
- * tick counts are cumulative. Tick counts increment when the vehicle
- * moves forward, and decrement when vehicles moves in reverse. The ticks
- * should be reset to 0 when the vehicle is started by the user.
- *
- * int64Values[0] = reset count
- * int64Values[1] = front left ticks
- * int64Values[2] = front right ticks
- * int64Values[3] = rear right ticks
- * int64Values[4] = rear left ticks
- *
- * configArray is used to indicate the micrometers-per-wheel-tick value and
- * which wheels are supported. configArray is set as follows:
- *
- * configArray[0], bits [0:3] = supported wheels. Uses enum Wheel.
- * configArray[1] = micrometers per front left wheel tick
- * configArray[2] = micrometers per front right wheel tick
- * configArray[3] = micrometers per rear right wheel tick
- * configArray[4] = micrometers per rear left wheel tick
- *
- * NOTE: If a wheel is not supported, its value shall always be set to 0.
- *
- * VehiclePropValue.timestamp must be correctly filled in.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- */
- WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
- + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
- /**
- * Fuel remaining in the vehicle, in milliliters
- *
- * Value may not exceed INFO_FUEL_CAPACITY
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:MILLILITER
- */
- FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Fuel door open
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * EV battery level in WH, if EV or hybrid
- *
- * Value may not exceed INFO_EV_BATTERY_CAPACITY
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:WH
- */
- EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * EV charge port open
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * EV charge port connected
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * EV instantaneous charge rate in milliwatts
- *
- * Positive value indicates battery is being charged.
- * Negative value indicates battery being discharged.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:MW
- */
- EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Range remaining
- *
- * Meters remaining of fuel and charge. Range remaining shall account for
- * all energy sources in a vehicle. For example, a hybrid car's range will
- * be the sum of the ranges based on fuel and battery.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ_WRITE
- * @unit VehicleUnit:METER
- */
- RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Tire pressure
- *
- * Each tires is identified by its areaConfig.areaId config and their
- * minFloatValue/maxFloatValue are used to store OEM recommended pressure
- * range.
- * The Min value in the areaConfig data represents the lower bound of
- * the recommended tire pressure.
- * The Max value in the areaConfig data represents the upper bound of
- * the recommended tire pressure.
- * For example:
- * The following areaConfig indicates the recommended tire pressure
- * of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
- * .areaConfigs = {
- * VehicleAreaConfig {
- * .areaId = VehicleAreaWheel::LEFT_FRONT,
- * .minFloatValue = 200.0,
- * .maxFloatValue = 240.0,
- * }
- * },
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:KILOPASCAL
- */
- TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
- /**
- * Critically low tire pressure
- *
- * This property indicates the critically low pressure threshold for each tire.
- * It indicates when it is time for tires to be replaced or fixed. The value
- * must be less than or equal to minFloatValue in TIRE_PRESSURE.
- * Minimum and maximum property values (that is, minFloatValue, maxFloatValue)
- * are not applicable to this property.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:KILOPASCAL
- */
- CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
- /**
- * Currently selected gear
- *
- * This is the gear selected by the user.
- *
- * Values in the config data must represent the list of supported gears
- * for this vehicle. For example, config data for an automatic transmission
- * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE,
- * GEAR_1, GEAR_2,...} and for manual transmission the list must be
- * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleGear
- */
- GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Current gear. In non-manual case, selected gear may not
- * match the current gear. For example, if the selected gear is GEAR_DRIVE,
- * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
- * the actual gear the transmission is currently running in.
- *
- * Values in the config data must represent the list of supported gears
- * for this vehicle. For example, config data for an automatic transmission
- * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
- * and for manual transmission the list must be
- * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
- * same as that of the supported gears reported in GEAR_SELECTION.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleGear
- */
- CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Parking brake state.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Auto-apply parking brake.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Warning for fuel low level.
- *
- * This property corresponds to the low fuel warning on the dashboard.
- * Once FUEL_LEVEL_LOW is set, it should not be cleared until more fuel is
- * added to the vehicle. This property may take into account all fuel
- * sources for a vehicle - for example:
- *
- * For a gas powered vehicle, this property is based soley on gas level.
- * For a battery powered vehicle, this property is based solely on battery level.
- * For a hybrid vehicle, this property may be based on the combination of gas and battery
- * levels, at the OEM's discretion.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Night mode
- *
- * True indicates that the night mode sensor has detected that the car cabin environment has
- * low light. The platform could use this, for example, to enable appropriate UI for
- * better viewing in dark or low light environments.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * State of the vehicles turn signals
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleTurnSignal
- */
- TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Represents ignition state
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleIgnitionState
- */
- IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * ABS is active
- *
- * Set to true when ABS is active. Reset to false when ABS is off. This
- * property may be intermittently set (pulsing) based on the real-time
- * state of the ABS system.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Traction Control is active
- *
- * Set to true when traction control (TC) is active. Reset to false when
- * TC is off. This property may be intermittently set (pulsing) based on
- * the real-time state of the TC system.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /*
- * HVAC Properties
- *
- * Additional rules for mapping a zoned HVAC property (except
- * HVAC_MAX_DEFROST_ON) to AreaIDs:
- * - Every seat in VehicleAreaSeat that is available in the car, must be
- * part of an AreaID in the AreaID array.
- *
- * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
- * back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
- * temperature control units -- driver side and passenger side.
- * - A valid mapping set of AreaIDs for HVAC_TEMPERATURE_SET would be a
- * two element array:
- * - ROW_1_LEFT | ROW_2_LEFT
- * - ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT
- * - An alternative mapping for the same hardware configuration would be:
- * - ROW_1_LEFT | ROW_2_CENTER | ROW_2_LEFT
- * - ROW_1_RIGHT | ROW_2_RIGHT
- * The temperature controllers are assigned to the seats which they
- * "most influence", but every seat must be included exactly once. The
- * assignment of the center rear seat to the left or right AreaID may seem
- * arbitrary, but the inclusion of every seat in exactly one AreaID ensures
- * that the seats in the car are all expressed and that a "reasonable" way
- * to affect each seat is available.
- *
- * Example 2: A car has three seat rows with two seats in the front row (ROW_1_LEFT,
- * ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER,
- * ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). There
- * are three temperature control units -- driver side, passenger side, and rear.
- * - A reasonable way to map HVAC_TEMPERATURE_SET to AreaIDs is a three
- * element array:
- * - ROW_1_LEFT
- * - ROW_1_RIGHT
- * - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
- *
- *
- * Fan speed setting
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Fan direction setting
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleHvacFanDirection
- */
- HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * HVAC current temperature.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELSIUS
- */
- HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
- /**
- * HVAC, target temperature set.
- *
- * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
- * Android might use it in the HVAC app UI.
- * The configArray is set as follows:
- * configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
- * configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
- * configArray[2] = [the increment in Celsius] * 10.
- * configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
- * configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
- * configArray[5] = [the increment in Fahrenheit] * 10.
- * For example, if the vehicle supports temperature values as:
- * [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
- * [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
- * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
- *
- * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
- * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
- * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @unit VehicleUnit:CELSIUS
- */
- HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
- /**
- * Fan-based defrost for designated window.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
- /**
- * On/off AC for designated areaId
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @config_flags Supported areaIds
- */
- HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * On/off max AC
- *
- * When MAX AC is on, the ECU may adjust the vent position, fan speed,
- * temperature, etc as necessary to cool the vehicle as quickly as possible.
- * Any parameters modified as a side effect of turning on/off the MAX AC
- * parameter shall generate onPropertyEvent() callbacks to the VHAL.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * On/off max defrost
- *
- * When MAX DEFROST is on, the ECU may adjust the vent position, fan speed,
- * temperature, etc as necessary to defrost the windows as quickly as
- * possible. Any parameters modified as a side effect of turning on/off
- * the MAX DEFROST parameter shall generate onPropertyEvent() callbacks to
- * the VHAL.
- * The AreaIDs for HVAC_MAX_DEFROST_ON indicate MAX DEFROST can be controlled
- * in the area.
- * For example:
- * areaConfig.areaId = {ROW_1_LEFT | ROW_1_RIGHT} indicates HVAC_MAX_DEFROST_ON
- * only can be controlled for the front rows.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * Recirculation on/off
- *
- * Controls the supply of exterior air to the cabin. Recirc “on” means the
- * majority of the airflow into the cabin is originating in the cabin.
- * Recirc “off” means the majority of the airflow into the cabin is coming
- * from outside the car.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * Enable temperature coupling between areas.
- *
- * The AreaIDs for HVAC_DUAL_ON property shall contain a combination of
- * HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If
- * HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if
- * HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON
- * property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also
- * be coupled together separately then HVAC_DUAL_ON must be mapped to
- * [a_i | a_j, a_k | a_l].
- *
- * Example: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
- * back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
- * temperature control units -- driver side and passenger side -- which can
- * be optionally synchronized. This may be expressed in the AreaIDs this way:
- * - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
- * - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
- *
- * When the property is enabled, the ECU must synchronize the temperature
- * for the affected areas. Any parameters modified as a side effect
- * of turning on/off the DUAL_ON parameter shall generate
- * onPropertyEvent() callbacks to the VHAL. In addition, if setting
- * a temperature (i.e. driver's temperature) changes another temperature
- * (i.e. front passenger's temperature), then the appropriate
- * onPropertyEvent() callbacks must be generated. If a user changes a
- * temperature that breaks the coupling (e.g. setting the passenger
- * temperature independently) then the VHAL must send the appropriate
- * onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false,
- * HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * On/off automatic mode
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * Seat heating/cooling
- *
- * Negative values indicate cooling.
- * 0 indicates off.
- * Positive values indicate heating.
- *
- * Some vehicles may have multiple levels of heating and cooling. The
- * min/max range defines the allowable range and number of steps in each
- * direction.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Side Mirror Heat
- *
- * Increasing values denote higher heating levels for side mirrors.
- * The Max value in the config data represents the highest heating level.
- * The Min value in the config data MUST be zero and indicates no heating.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
- /**
- * Steering Wheel Heating/Cooling
- *
- * Sets the amount of heating/cooling for the steering wheel
- * config data Min and Max MUST be set appropriately.
- * Positive value indicates heating.
- * Negative value indicates cooling.
- * 0 indicates temperature control is off.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Temperature units for display
- *
- * Indicates whether the vehicle is displaying temperature to the user as
- * Celsius or Fahrenheit.
- * VehiclePropConfig.configArray is used to indicate the supported temperature display units.
- * For example: configArray[0] = CELSIUS
- * configArray[1] = FAHRENHEIT
- *
- * This parameter MAY be used for displaying any HVAC temperature in the system.
- * Values must be one of VehicleUnit::CELSIUS or VehicleUnit::FAHRENHEIT
- * Note that internally, all temperatures are represented in floating point Celsius.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleUnit
- */
- HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Actual fan speed
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Represents global power state for HVAC. Setting this property to false
- * MAY mark some properties that control individual HVAC features/subsystems
- * to UNAVAILABLE state. Setting this property to true MAY mark some
- * properties that control individual HVAC features/subsystems to AVAILABLE
- * state (unless any/all of them are UNAVAILABLE on their own individual
- * merits).
- *
- * [Definition] HvacPower_DependentProperties: Properties that need HVAC to be
- * powered on in order to enable their functionality. For example, in some cars,
- * in order to turn on the AC, HVAC must be powered on first.
- *
- * HvacPower_DependentProperties list must be set in the
- * VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain
- * properties that are associated with VehicleArea:SEAT. Properties that are not
- * associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never
- * depend on HVAC_POWER_ON property and must never be part of
- * HvacPower_DependentProperties list.
- *
- * AreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that
- * HvacPower_DependentProperties are mapped to.
- *
- * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back
- * seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC,
- * Temperature etc.) throughout the car are dependent on a single HVAC power
- * controller then HVAC_POWER_ON must be mapped to
- * [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].
- *
- * Example 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and
- * three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third
- * rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature
- * controllers in the front row which can operate entirely independently of
- * temperature controllers in the back of the vehicle, then HVAC_POWER_ON
- * must be mapped to a two element array:
- * - ROW_1_LEFT | ROW_1_RIGHT
- * - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * Fan Positions Available
- *
- * This is a bit mask of fan positions available for the zone. Each
- * available fan direction is denoted by a separate entry in the vector. A
- * fan direction may have multiple bits from vehicle_hvac_fan_direction set.
- * For instance, a typical car may have the following fan positions:
- * - FAN_DIRECTION_FACE (0x1)
- * - FAN_DIRECTION_FLOOR (0x2)
- * - FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR (0x3)
- * - FAN_DIRECTION_DEFROST (0x4)
- * - FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST (0x6)
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleHvacFanDirection
- */
- HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
- /**
- * Automatic recirculation on/off
- *
- * When automatic recirculation is ON, the HVAC system may automatically
- * switch to recirculation mode if the vehicle detects poor incoming air
- * quality.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * Seat ventilation
- *
- * 0 indicates off.
- * Positive values indicates ventilation level.
- *
- * Used by HVAC apps and Assistant to enable, change, or read state of seat
- * ventilation. This is different than seating cooling. It can be on at the
- * same time as cooling, or not.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Electric defrosters' status
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
- /**
- * Suggested values for setting HVAC temperature.
- *
- * Implement the property to help applications understand the closest supported temperature
- * value in Celsius or Fahrenheit.
- *
- * floatValues[0] = the requested value that an application wants to set a temperature to.
- * floatValues[1] = the unit for floatValues[0]. It should be one of
- * {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}.
- * floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included
- * in the request.
- * floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included
- * in the request.
- *
- * An application calls set(VehiclePropValue propValue) with the requested value and unit for
- * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
- * onPropertyEvent() callbacks.
- *
- * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
- * Fahrenheit.
- * First, an application will set this property with the value
- * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0].
- * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL
- * must generate a callback with property value
- * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the
- * callback, it will inform the user and set HVAC temperature to the suggested value.
- *
- * Another example, an application receives 21 Celsius as the current temperature value by
- * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on
- * the car's UI in Fahrenheit.
- * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If
- * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a
- * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0].
- * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
- + 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
- /**
- * Distance units for display
- *
- * Indicates which units the car is using to display distances to the user. Eg. Mile, Meter
- * Kilometer.
- *
- * Distance units are defined in VehicleUnit.
- * VehiclePropConfig.configArray is used to indicate the supported distance display units.
- * For example: configArray[0] = METER
- * configArray[1] = KILOMETER
- * configArray[2] = MILE
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleUnit
- */
- DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Fuel volume units for display
- *
- * Indicates which units the car is using to display fuel volume to the user. Eg. Liter or
- * Gallon.
- *
- * VehiclePropConfig.configArray is used to indicate the supported fuel volume display units.
- * Volume units are defined in VehicleUnit.
- * For example: configArray[0] = LITER
- * configArray[1] = GALLON
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleUnit
- */
- FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Tire pressure units for display
- *
- * Indicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or
- * Kilopascal.
- *
- * VehiclePropConfig.configArray is used to indicate the supported pressure display units.
- * Pressure units are defined in VehicleUnit.
- * For example: configArray[0] = KILOPASCAL
- * configArray[1] = PSI
- * configArray[2] = BAR
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleUnit
- */
- TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * EV battery units for display
- *
- * Indicates which units the car is using to display EV battery information to the user. Eg.
- * watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).
- *
- * VehiclePropConfig.configArray is used to indicate the supported electrical energy units.
- * Electrical energy units are defined in VehicleUnit.
- * For example: configArray[0] = WATT_HOUR
- * configArray[1] = AMPERE_HOURS
- * configArray[2] = KILOWATT_HOUR
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleUnit
- */
- EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Fuel consumption units for display
- *
- * Indicates type of units the car is using to display fuel consumption information to user
- * True indicates units are distance over volume such as MPG.
- * False indicates units are volume over distance such as L/100KM.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Speed units for display
- *
- * Indicates type of units the car is using to display speed to user. Eg. m/s, km/h, or mph.
- *
- * VehiclePropConfig.configArray is used to indicate the supported speed display units.
- * Pressure units are defined in VehicleUnit.
- * For example: configArray[0] = METER_PER_SEC
- * configArray[1] = MILES_PER_HOUR
- * configArray[2] = KILOMETERS_PER_HOUR
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Current date and time suggestion for the Car, encoded as Epoch time
- * (in milliseconds). This value denotes the number of milliseconds seconds
- * that have elapsed since 1/1/1970 UTC.
- *
- * This property signals a change in CarTime to Android. If the property is supported, VHAL
- * must report the most accurate current CarTime when this property is read, and publish a
- * change to this property when the CarTime value has changed. An on-change event for this
- * property must be published when CarTime changes for any reason other than the natural elapse
- * of time (time delta smaller than 500ms should not trigger an on change event). Android will
- * read and subscribe to this property to fetch time from VHAL. This can be useful to
- * synchronize Android's time with other vehicle systems (dash clock etc).
- * int64Values[0] = provided Epoch time (in milliseconds)
- *
- * Whenever a new Value for the property is received, AAOS will create
- * and send an "ExternalTimeSuggestion" to the "TimeDetectorService".
- * If other sources do not have a higher priority, Android will use this
- * to set the system time. For information on how to adjust time source
- * priorities and how time suggestions are handled (including how Android
- * handles gitter, drift, and minimum resolution) see Time Detector Service
- * documentation.
- *
- * Note that the property may take >0 ms to get propagated through the stack
- * and, having a timestamped property helps reduce any time drift. So,
- * for all reads to the property, the timestamp can be used to negate this
- * drift:
- * drift = elapsedTime - PropValue.timestamp
- * effectiveTime = PropValue.value.int64Values[0] + drift
- *
- * It is strongly recommended that this property must not be used to retrieve
- * time from ECUs using protocols (GNSS, NTP, Telephony etc). Since these
- * protocols are already supported by Android, it is recommended to use
- * Android’s own systems for them instead of wiring those through the VHAL
- * using this property.
- *
- * WARNING: The value available through this property should not be dependent
- * on value written by Android to ANDROID_EPOCH_TIME property in any way.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_ONLY
- * @unit VehicleUnit:MILLI_SECS
- */
- EXTERNAL_CAR_TIME = 0x0608 + 0x10000000 // VehiclePropertyGroup:SYSTEM
- + 0x01000000 // VehicleArea:GLOBAL
- + 0x00500000, // VehiclePropertyType:INT64
- /**
- * Current date and time, encoded as Epoch time (in milliseconds).
- * This value denotes the number of milliseconds seconds that have
- * elapsed since 1/1/1970 UTC.
- *
- * CarServices will write to this value to give VHAL the Android system's
- * time, if the VHAL supports this property. This can be useful to
- * synchronize other vehicle systems (dash clock etc) with Android's time.
- *
- * AAOS writes to this property once during boot, and
- * will thereafter write only when some time-source changes are propagated.
- * AAOS will fill in VehiclePropValue.timestamp correctly.
- * Note that AAOS will not send updates for natural elapse of time.
- * int64Values[0] = provided Unix time (in milliseconds)
- *
- * Note that the property may take >0 ms to get propagated through the stack
- * and, having a timestamped property helps reduce any time drift. So,
- * for all writes to the property, the timestamp can be used to negate this
- * drift:
- * drift = elapsedTime - PropValue.timestamp
- * effectiveTime = PropValue.value.int64Values[0] + drift
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE_ONLY
- * @unit VehicleUnit:MILLI_SECS
- */
- ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
- + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
- /**
- * External encryption binding seed.
- *
- * This value is mixed with the local key storage encryption key.
- * This property holds 16 bytes, and is expected to be persisted on an ECU separate from
- * the IVI. The property is initially set by AAOS, who generates it using a CSRNG.
- * AAOS will then read the property on subsequent boots. The binding seed is expected to be
- * reliably persisted. Any loss of the seed results in a factory reset of the IVI.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
- + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
- /**
- * Outside temperature
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:CELSIUS
- */
- ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
- /**
- * Property to control power state of application processor
- *
- * It is assumed that AP's power state is controlled by a separate power
- * controller.
- *
- * For configuration information, VehiclePropConfig.configArray can have bit flag combining
- * values in VehicleApPowerStateConfigFlag.
- *
- * int32Values[0] : VehicleApPowerStateReq enum value
- * int32Values[1] : additional parameter relevant for each state,
- * 0 if not used.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Property to report power state of application processor
- *
- * It is assumed that AP's power state is controller by separate power
- * controller.
- *
- * int32Values[0] : VehicleApPowerStateReport enum value
- * int32Values[1] : Time in ms to wake up, if necessary. Otherwise 0.
-
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Property to report bootup reason for the current power on. This is a
- * static property that will not change for the whole duration until power
- * off. For example, even if user presses power on button after automatic
- * power on with door unlock, bootup reason must stay with
- * VehicleApPowerBootupReason#USER_UNLOCK.
- *
- * int32Values[0] must be VehicleApPowerBootupReason.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- */
- AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Property to represent brightness of the display. Some cars have single
- * control for the brightness of all displays and this property is to share
- * change in that control.
- *
- * If this is writable, android side can set this value when user changes
- * display brightness from Settings. If this is read only, user may still
- * change display brightness from Settings, but that must not be reflected
- * to other displays.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Property to feed H/W input events to android
- *
- * int32Values[0] : action defined by VehicleHwKeyInputAction
- * int32Values[1] : key code, must use standard android key code
- * int32Values[2] : target display defined in VehicleDisplay. Events not
- * tied to specific display must be sent to
- * VehicleDisplay#MAIN.
- * int32Values[3] : [optional] Number of ticks. The value must be equal or
- * greater than 1. When omitted, Android will default to 1.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @config_flags
- */
- HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Property to feed H/W rotary events to android
- *
- * int32Values[0] : RotaryInputType identifying which rotary knob rotated
- * int32Values[1] : number of detents (clicks), positive for clockwise,
- * negative for counterclockwise
- * int32Values[2] : target display defined in VehicleDisplay. Events not
- * tied to specific display must be sent to
- * VehicleDisplay#MAIN.
- * int32values[3 .. 3 + abs(number of detents) - 2]:
- * nanosecond deltas between pairs of consecutive detents,
- * if the number of detents is > 1 or < -1
- *
- * VehiclePropValue.timestamp: when the rotation occurred. If the number of
- * detents is > 1 or < -1, this is when the
- * first detent of rotation occurred.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @data_enum RotaryInputType
- * @access VehiclePropertyAccess:READ
- */
- HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Defines a custom OEM partner input event.
- *
- * This input event must be used by OEM partners who wish to propagate events not supported
- * by Android. It is composed by an array of int32 values only.
- *
- * The Android properties are:
- *
- * int32Values[0] : Input code identifying the function representing this event. Valid event
- * types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
- * CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
- * defined by OEM partners.
- * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
- * display must be sent to VehicleDisplay#MAIN.
- * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
- * how many times this event repeated.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @data_enum CustomInputType
- * @access VehiclePropertyAccess:READ
- */
- HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /***************************************************************************
- * Most Car Cabin properties have both a POSition and MOVE parameter. These
- * are used to control the various movements for seats, doors, and windows
- * in a vehicle.
- *
- * A POS parameter allows the user to set the absolution position. For
- * instance, for a door, 0 indicates fully closed and max value indicates
- * fully open. Thus, a value halfway between min and max must indicate
- * the door is halfway open.
- *
- * A MOVE parameter moves the device in a particular direction. The sign
- * indicates direction, and the magnitude indicates speed (if multiple
- * speeds are available). For a door, a move of -1 will close the door, and
- * a move of +1 will open it. Once a door reaches the limit of open/close,
- * the door should automatically stop moving. The user must NOT need to
- * send a MOVE(0) command to stop the door at the end of its range.
- **************************************************************************/
-
- /**
- * Door position
- *
- * This is an integer in case a door may be set to a particular position.
- * Max value indicates fully open, min value (0) indicates fully closed.
- *
- * Some vehicles (minivans) can open the door electronically. Hence, the
- * ability to write this property.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
- /**
- * Door move
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
- /**
- * Door lock
- *
- * 'true' indicates door is locked
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
- /**
- * Mirror Z Position
- *
- * Positive value indicates tilt upwards, negative value is downwards
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
- /**
- * Mirror Z Move
- *
- * Positive value indicates tilt upwards, negative value is downwards
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
- /**
- * Mirror Y Position
- *
- * Positive value indicate tilt right, negative value is left
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
- /**
- * Mirror Y Move
- *
- * Positive value indicate tilt right, negative value is left
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
- /**
- * Mirror Lock
- *
- * True indicates mirror positions are locked and not changeable
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Mirror Fold
- *
- * True indicates mirrors are folded
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Seat memory select
- *
- * This parameter selects the memory preset to use to select the seat
- * position. The minValue is always 0, and the maxValue determines the
- * number of seat positions available.
- *
- * For instance, if the driver's seat has 3 memory presets, the maxValue
- * will be 3. When the user wants to select a preset, the desired preset
- * number (1, 2, or 3) is set.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat memory set
- *
- * This setting allows the user to save the current seat position settings
- * into the selected preset slot. The maxValue for each seat position
- * must match the maxValue for SEAT_MEMORY_SELECT.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seatbelt buckled
- *
- * True indicates belt is buckled.
- *
- * Write access indicates automatic seat buckling capabilities. There are
- * no known cars at this time, but you never know...
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
- /**
- * Seatbelt height position
- *
- * Adjusts the shoulder belt anchor point.
- * Max value indicates highest position
- * Min value indicates lowest position
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seatbelt height move
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat fore/aft position
- *
- * Sets the seat position forward (closer to steering wheel) and backwards.
- * Max value indicates closest to wheel, min value indicates most rearward
- * position.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat fore/aft move
- *
- * Moves the seat position forward and aft.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat backrest angle 1 position
- *
- * Backrest angle 1 is the actuator closest to the bottom of the seat.
- * Max value indicates angling forward towards the steering wheel.
- * Min value indicates full recline.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat backrest angle 1 move
- *
- * Moves the backrest forward or recline.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat backrest angle 2 position
- *
- * Backrest angle 2 is the next actuator up from the bottom of the seat.
- * Max value indicates angling forward towards the steering wheel.
- * Min value indicates full recline.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat backrest angle 2 move
- *
- * Moves the backrest forward or recline.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat height position
- *
- * Sets the seat height.
- * Max value indicates highest position.
- * Min value indicates lowest position.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat height move
- *
- * Moves the seat height.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat depth position
- *
- * Sets the seat depth, distance from back rest to front edge of seat.
- * Max value indicates longest depth position.
- * Min value indicates shortest position.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat depth move
- *
- * Adjusts the seat depth.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat tilt position
- *
- * Sets the seat tilt.
- * Max value indicates front edge of seat higher than back edge.
- * Min value indicates front edge of seat lower than back edge.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat tilt move
- *
- * Tilts the seat.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Lumber fore/aft position
- *
- * Pushes the lumbar support forward and backwards
- * Max value indicates most forward position.
- * Min value indicates most rearward position.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Lumbar fore/aft move
- *
- * Adjusts the lumbar support.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Lumbar side support position
- *
- * Sets the amount of lateral lumbar support.
- * Max value indicates widest lumbar setting (i.e. least support)
- * Min value indicates thinnest lumbar setting.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Lumbar side support move
- *
- * Adjusts the amount of lateral lumbar support.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Headrest height position
- *
- * Sets the headrest height.
- * Max value indicates tallest setting.
- * Min value indicates shortest setting.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Headrest height move
- *
- * Moves the headrest up and down.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Headrest angle position
- *
- * Sets the angle of the headrest.
- * Max value indicates most upright angle.
- * Min value indicates shallowest headrest angle.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Headrest angle move
- *
- * Adjusts the angle of the headrest
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Headrest fore/aft position
- *
- * Adjusts the headrest forwards and backwards.
- * Max value indicates position closest to front of car.
- * Min value indicates position closest to rear of car.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Headrest fore/aft move
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Seat Occupancy
- *
- * Indicates whether a particular seat is occupied or not, to the best of the car's ability
- * to determine. Valid values are from the VehicleSeatOccupancyState enum.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleSeatOccupancyState
- */
- SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Window Position
- *
- * Min = window up / closed
- * Max = window down / open
- *
- * For a window that may open out of plane (i.e. vent mode of sunroof) this
- * parameter will work with negative values as follows:
- * Max = sunroof completely open
- * 0 = sunroof closed.
- * Min = sunroof vent completely open
- *
- * Note that in this mode, 0 indicates the window is closed.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
- /**
- * Window Move
- *
- * Max = Open the window as fast as possible
- * Min = Close the window as fast as possible
- * Magnitude denotes relative speed. I.e. +2 is faster than +1 in closing
- * the window.
- *
- * For a window that may open out of plane (i.e. vent mode of sunroof) this
- * parameter will work as follows:
- *
- * If sunroof is open:
- * Max = open the sunroof further, automatically stop when fully open.
- * Min = close the sunroof, automatically stop when sunroof is closed.
- *
- * If vent is open:
- * Max = close the vent, automatically stop when vent is closed.
- * Min = open the vent further, automatically stop when vent is fully open.
- *
- * If sunroof is in the closed position:
- * Max = open the sunroof, automatically stop when sunroof is fully open.
- * Min = open the vent, automatically stop when vent is fully open.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
- /**
- * Window Lock
- *
- * True indicates windows are locked and can't be moved.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
- /**
- * Vehicle Maps Service (VMS) message
- *
- * This property uses MIXED data to communicate vms messages.
- *
- * Its contents are to be interpreted as follows:
- * the indices defined in VmsMessageIntegerValuesIndex are to be used to
- * read from int32Values;
- * bytes is a serialized VMS message as defined in the vms protocol
- * which is opaque to the framework;
- *
- * IVehicle#get must always return StatusCode::NOT_AVAILABLE.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * OBD2 Live Sensor Data
- *
- * Reports a snapshot of the current (live) values of the OBD2 sensors available.
- *
- * The configArray is set as follows:
- * configArray[0] = number of vendor-specific integer-valued sensors
- * configArray[1] = number of vendor-specific float-valued sensors
- *
- * The values of this property are to be interpreted as in the following example.
- * Considering a configArray = {2,3}
- * int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2
- * elements (that is, 33 elements);
- * floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3
- * elements (that is, 73 elements);
- *
- * It is possible for each frame to contain a different subset of sensor values, both system
- * provided sensors, and vendor-specific ones. In order to support that, the bytes element
- * of the property value is used as a bitmask,.
- *
- * bytes must have a sufficient number of bytes to represent the total number of possible
- * sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as
- * a contiguous bitmask such that each bit indicates the presence or absence of a sensor
- * from the frame, starting with as many bits as the size of int32Values, immediately
- * followed by as many bits as the size of floatValues.
- *
- * For example, should bytes[0] = 0x4C (0b01001100) it would mean that:
- * int32Values[0 and 1] are not valid sensor values
- * int32Values[2 and 3] are valid sensor values
- * int32Values[4 and 5] are not valid sensor values
- * int32Values[6] is a valid sensor value
- * int32Values[7] is not a valid sensor value
- * Should bytes[5] = 0x61 (0b01100001) it would mean that:
- * int32Values[32] is a valid sensor value
- * floatValues[0 thru 3] are not valid sensor values
- * floatValues[4 and 5] are valid sensor values
- * floatValues[6] is not a valid sensor value
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * OBD2 Freeze Frame Sensor Data
- *
- * Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
- * occurred and was detected.
- *
- * A configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.
- *
- * The values of this property are to be interpreted in a similar fashion as those for
- * OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty
- * diagnostic troubleshooting code (DTC).
- *
- * A IVehicle#get request of this property must provide a value for int64Values[0].
- * This will be interpreted as the timestamp of the freeze frame to retrieve. A list of
- * timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.
- *
- * Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
- * must be returned by the implementation. Because vehicles may have limited storage for
- * freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if
- * the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * OBD2 Freeze Frame Information
- *
- * This property describes the current freeze frames stored in vehicle
- * memory and available for retrieval via OBD2_FREEZE_FRAME.
- *
- * The values are to be interpreted as follows:
- * each element of int64Values must be the timestamp at which a a fault code
- * has been detected and the corresponding freeze frame stored, and each
- * such element can be used as the key to OBD2_FREEZE_FRAME to retrieve
- * the corresponding freeze frame.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * OBD2 Freeze Frame Clear
- *
- * This property allows deletion of any of the freeze frames stored in
- * vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
- *
- * The configArray is set as follows:
- * configArray[0] = 1 if the implementation is able to clear individual freeze frames
- * by timestamp, 0 otherwise
- *
- * IVehicle#set of this property is to be interpreted as follows:
- * if int64Values contains no elements, then all frames stored must be cleared;
- * if int64Values contains one or more elements, then frames at the timestamps
- * stored in int64Values must be cleared, and the others not cleared. Should the
- * vehicle not support selective clearing of freeze frames, this latter mode must
- * return NOT_AVAILABLE.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Headlights State
- *
- * Return the current state of headlights.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * High beam lights state
- *
- * Return the current state of high beam lights.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Fog light state
- *
- * Return the current state of fog lights.
- *
- * If the car has both front and rear fog lights:
- * If front and rear fog lights can only be controlled together: FOG_LIGHTS_STATE must be
- * implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must not be implemented.
- *
- * If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_STATE
- * must not be implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must be
- * implemented.
- *
- * If the car has only front fog lights:
- * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented and not both.
- * REAR_FOG_LIGHTS_STATE must not be implemented.
- *
- * If the car has only rear fog lights:
- * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented and not both.
- * FRONT_FOG_LIGHTS_STATE must not be implemented.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Hazard light status
- *
- * Return the current status of hazard lights.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Headlight switch
- *
- * The setting that the user wants.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * High beam light switch
- *
- * The setting that the user wants.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Fog light switch
- *
- * The setting that the user wants.
- *
- * If the car has both front and rear fog lights:
- * If front and rear fog lights can only be controlled together: FOG_LIGHTS_SWITCH must be
- * implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must not be implemented.
- *
- * If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_SWITCH
- * must not be implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must be
- * implemented.
- *
- * If the car has only front fog lights:
- * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented and not both.
- * REAR_FOG_LIGHTS_SWITCH must not be implemented.
- *
- * If the car has only rear fog lights:
- * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented and not both.
- * FRONT_FOG_LIGHTS_SWITCH must not be implemented.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Hazard light switch
- *
- * The setting that the user wants.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Cabin lights
- *
- * Return current status of cabin lights.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Cabin lights switch
- *
- * The position of the physical switch which controls the cabin lights.
- * This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door
- * is open or because of a voice command.
- * For example, while the switch is in the "off" or "automatic" position.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Reading lights
- *
- * Return current status of reading lights.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Reading lights switch
- *
- * The position of the physical switch which controls the reading lights.
- * This might be different than the READING_LIGHTS_STATE if the lights are on because a door
- * is open or because of a voice command.
- * For example, while the switch is in the "off" or "automatic" position.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
- /**
- * Support customize permissions for vendor properties
- *
- * Implement this property if vehicle hal support customize vendor permissions feature.
- * VehiclePropConfig.configArray is used to indicate vendor properties and permissions
- * which selected for this vendor property. The permission must be one of enum in
- * VehicleVendorPermission.
- * The configArray is set as follows:
- * configArray[n] = propId : property ID for the vendor property
- * configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission
- * for reading value of the property.
- * configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission
- * for writing value of the property.
- *
- * For example:
- * configArray = {
- * vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE,
- * vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE,
- * }
- * If vendor properties are not in this array, they will have the default vendor permission.
- * If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In
- * the example, Android can not write value for vendor_prop_2.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- */
- SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
- /**
- * Allow disabling optional featurs from vhal.
- *
- * This property reports optional features that should be disabled.
- * All allowed optional features for the system is declared in Car service overlay,
- * config_allowed_optional_car_features.
- * This property allows disabling features defined in the overlay. Without this property,
- * all the features declared in the overlay will be enabled.
- *
- * Value read should include all features disabled with ',' separation.
- * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- */
- DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Defines the initial Android user to be used during initialization.
- *
- * This property is called by the Android system when it initializes and it lets the HAL
- * define which Android user should be started.
- *
- * This request is made by setting a VehiclePropValue (defined by InitialUserInfoRequest),
- * and the HAL must respond with a property change event (defined by InitialUserInfoResponse).
- * If the HAL doesn't respond after some time (defined by the Android system), the Android
- * system will proceed as if HAL returned a response of action
- * InitialUserInfoResponseAction:DEFAULT.
- *
- * For example, on first boot, the request could be:
- *
- * int32[0]: 42 // request id (arbitrary number set by Android system)
- * int32[1]: 1 // InitialUserInfoRequestType::FIRST_BOOT
- * int32[2]: 0 // id of current user (usersInfo.currentUser.userId)
- * int32[3]: 1 // flag of current user (usersInfo.currentUser.flags = SYSTEM)
- * int32[4]: 1 // number of existing users (usersInfo.numberUsers);
- * int32[5]: 0 // user #0 (usersInfo.existingUsers[0].userId)
- * int32[6]: 1 // flags of user #0 (usersInfo.existingUsers[0].flags)
- *
- * And if the HAL want to respond with the creation of an admin user called "Owner", the
- * response would be:
- *
- * int32[0]: 42 // must match the request id from the request
- * int32[1]: 2 // action = InitialUserInfoResponseAction::CREATE
- * int32[2]: -10000 // userToSwitchOrCreate.userId (not used as user will be created)
- * int32[3]: 8 // userToSwitchOrCreate.flags = ADMIN
- * string: "||Owner" // userLocales + separator + userNameToCreate
- *
- * Notice the string value represents multiple values, separated by ||. The first value is the
- * (optional) system locales for the user to be created (in this case, it's empty, meaning it
- * will use Android's default value), while the second value is the (also optional) name of the
- * to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE).
- * For example, to create the same "Owner" user with "en-US" and "pt-BR" locales, the string
- * value of the response would be "en-US,pt-BR||Owner". As such, neither the locale nor the
- * name can have || on it, although a single | is fine.
- *
- * NOTE: if the HAL doesn't support user management, then it should not define this property,
- * which in turn would disable the other user-related properties (for example, the Android
- * system would never issue them and user-related requests from the HAL layer would be ignored
- * by the Android System). But if it supports user management, then it must support all core
- * user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER).
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Defines a request to switch the foreground Android user.
- *
- * This property is used primarily by the Android System to inform the HAL that the
- * current foreground Android user is switching, but it could also be used by the HAL to request
- * the Android system to switch users - the
- *
- * When the request is made by Android, it sets a VehiclePropValue and the HAL must responde
- * with a property change event; when the HAL is making the request, it must also do it through
- * a property change event (the main difference is that the request id will be positive in the
- * former case, and negative in the latter; the SwitchUserMessageType will also be different).
- *
- * The format of both request is defined by SwitchUserRequest and the format of the response
- * (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should
- * proceed depends on the message type (which is defined by the SwitchUserMessageType
- * parameter), as defined below.
- *
- * 1.LEGACY_ANDROID_SWITCH
- * -----------------------
- *
- * Called by the Android System to indicate the Android user is about to change, when the change
- * request was made in a way that is not integrated with the HAL (for example, through
- * adb shell am switch-user).
- *
- * The HAL can switch its internal user once it receives this request, but it doesn't need to
- * reply back to the Android System. If its internal user cannot be changed for some reason,
- * then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover
- * (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to
- * the previous user), but ideally it should never fail (as switching back could result in a
- * confusing experience for the end user).
- *
- * For example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none
- * of them have any special flag), the request would be:
- *
- * int32[0]: 42 // request id
- * int32[1]: 1 // SwitchUserMessageType::LEGACY_ANDROID_SWITCH
- * int32[2]: 11 // target user id
- * int32[3]: 0 // target user flags (none)
- * int32[4]: 10 // current user
- * int32[5]: 0 // current user flags (none)
- * int32[6]: 3 // number of users
- * int32[7]: 0 // user #0 (Android user id 0)
- * int32[8]: 0 // flags of user #0 (none)
- * int32[9]: 10 // user #1 (Android user id 10)
- * int32[10]: 0 // flags of user #1 (none)
- * int32[11]: 11 // user #2 (Android user id 11)
- * int32[12]: 0 // flags of user #2 (none)
- *
- * 2.ANDROID_SWITCH
- * ----------------
- * Called by the Android System to indicate the Android user is about to change, but Android
- * will wait for the HAL's response (up to some time) before proceeding.
- *
- * The HAL must switch its internal user once it receives this request, then respond back to
- * Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal
- * user was switched or not (through the SwitchUserStatus enum).
- *
- * For example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where
- * none of them have any special flag), the request would be:
- *
- * int32[0]: 42 // request id
- * int32[1]: 2 // SwitchUserMessageType::ANDROID_SWITCH
- * int32[2]: 11 // target user id
- * int32[3]: 0 // target user flags (none)
- * int32[4]: 10 // current user
- * int32[5]: 0 // current user flags (none)
- * int32[6]: 3 // number of users
- * int32[7]: 0 // 1st user (user 0)
- * int32[8]: 1 // 1st user flags (SYSTEM)
- * int32[9]: 10 // 2nd user (user 10)
- * int32[10]: 0 // 2nd user flags (none)
- * int32[11]: 11 // 3rd user (user 11)
- * int32[12]: 0 // 3rd user flags (none)
- *
- * If the request succeeded, the HAL must update the property with:
- *
- * int32[0]: 42 // request id
- * int32[1]: 3 // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
- * int32[2]: 1 // status = SwitchUserStatus::SUCCESS
- *
- * But if it failed, the response would be something like:
- *
- * int32[0]: 42 // request id
- * int32[1]: 3 // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
- * int32[2]: 2 // status = SwitchUserStatus::FAILURE
- * string: "108-D'OH!" // OEM-specific error message
- *
- * 3.VEHICLE_RESPONSE
- * ------------------
- * Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or
- * abort - see the ANDROID_SWITCH section above for more info.
- *
- * 4.VEHICLE_REQUEST
- * ------------------
- * Called by the HAL to request that the current foreground Android user is switched.
- *
- * This is useful in situations where Android started as one user, but the vehicle identified
- * the driver as another user. For example, user A unlocked the car using the key fob of user B;
- * the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem
- * identified the user as A.
- *
- * The HAL makes this request by a property change event (passing a negative request id), and
- * the Android system will response by issue an ANDROID_POST_SWITCH call which the same
- * request id.
- *
- * For example, if the current foreground Android user is 10 and the HAL asked it to switch to
- * 11, the request would be:
- *
- * int32[0]: -108 // request id
- * int32[1]: 4 // messageType = SwitchUserMessageType::VEHICLE_REQUEST
- * int32[2]: 11 // Android user id
- *
- * If the request succeeded and Android has 3 users (0, 10, 11), the response would be:
- *
- * int32[0]: -108 // request id
- * int32[1]: 5 // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH
- * int32[2]: 11 // target user id
- * int32[3]: 0 // target user id flags (none)
- * int32[4]: 11 // current user
- * int32[5]: 0 // current user flags (none)
- * int32[6]: 3 // number of users
- * int32[7]: 0 // 1st user (user 0)
- * int32[8]: 0 // 1st user flags (none)
- * int32[9]: 10 // 2nd user (user 10)
- * int32[10]: 4 // 2nd user flags (none)
- * int32[11]: 11 // 3rd user (user 11)
- * int32[12]: 3 // 3rd user flags (none)
- *
- * Notice that both the current and target user ids are the same - if the request failed, then
- * they would be different (i.e, target user would be 11, but current user would still be 10).
- *
- * 5.ANDROID_POST_SWITCH
- * ---------------------
- * Called by the Android System after a request to switch a user was made.
- *
- * This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH,
- * ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or
- * failed:
- *
- * 1. When it succeeded, it's called when the Android user is in the unlocked state and the
- * value of the current and target users ids in the response are the same. This would be
- * equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app.
- * 2. When it failed it's called right away and the value of the current and target users ids
- * in the response are different (as the current user didn't change to the target).
- * 3. If a new switch request is made before the HAL responded to the previous one or before
- * the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
- * the driver could accidentally switch to the wrong user which has lock credentials, then
- * switch to the right one before entering the credentials.
- *
- * The HAL can update its internal state once it receives this request, but it doesn't need to
- * reply back to the Android System.
- *
- * Request: the first N values as defined by INITIAL_USER_INFO (where the request-specific
- * value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the
- * target user id (i.e., the Android user id that was requested to be switched to) and its flags
- * (as defined by UserFlags).
- *
- * Response: none.
- *
- * Example: see VEHICLE_REQUEST section above.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Called by the Android System after an Android user was created.
- *
- * The HAL can use this property to create its equivalent user.
- *
- * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
- * must respond with a property change indicating whether the request succeeded or failed. If
- * it failed, the Android system will remove the user.
- *
- * The format of the request is defined by CreateUserRequest and the format of the response by
- * CreateUserResponse.
- *
- * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
- * created, the request would be:
- *
- * int32[0]: 42 // request id
- * int32[1]: 11 // Android id of the created user
- * int32[2]: 6 // Android flags (ephemeral guest) of the created user
- * int32[3]: 10 // current user
- * int32[4]: 0 // current user flags (none)
- * int32[5]: 3 // number of users
- * int32[6]: 0 // 1st user (user 0)
- * int32[7]: 0 // 1st user flags (none)
- * int32[8]: 10 // 2nd user (user 10)
- * int32[9]: 0 // 2nd user flags (none)
- * int32[19]: 11 // 3rd user (user 11)
- * int32[11]: 6 // 3rd user flags (ephemeral guest)
- * string: "ElGuesto" // name of the new user
- *
- * Then if the request succeeded, the HAL would return:
- *
- * int32[0]: 42 // request id
- * int32[1]: 1 // CreateUserStatus::SUCCESS
- *
- * But if it failed:
- *
- * int32[0]: 42 // request id
- * int32[1]: 2 // CreateUserStatus::FAILURE
- * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
- * // which in turn can take the proper action.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Called by the Android System after an Android user was removed.
- *
- * The HAL can use this property to remove its equivalent user.
- *
- * This is write-only call - the Android System is not expecting a reply from the HAL. Hence,
- * this request should not fail - if the equivalent HAL user cannot be removed, then HAL should
- * mark it as inactive or recover in some other way.
- *
- * The request is made by setting the VehiclePropValue with the contents defined by
- * RemoveUserRequest.
- *
- * For example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request
- * would be:
- *
- * int32[0]: 42 // request id
- * int32[1]: 11 // (Android user id of the removed user)
- * int32[2]: 0 // (Android user flags of the removed user)
- * int32[3]: 10 // current user
- * int32[4]: 0 // current user flags (none)
- * int32[5]: 2 // number of users
- * int32[6]: 0 // 1st user (user 0)
- * int32[7]: 0 // 1st user flags (none)
- * int32[8]: 10 // 2nd user (user 10)
- * int32[9]: 0 // 2nd user flags (none)
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:WRITE
- */
- REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Property used to associate (or query the association) the current user with vehicle-specific
- * identification mechanisms (such as key FOB).
- *
- * This is an optional user management property - the OEM could still support user management
- * without defining it. In fact, this property could be used without supporting the core
- * user-related functions described on INITIAL_USER_INFO.
- *
- * To query the association, the Android system gets the property, passing a VehiclePropValue
- * containing the types of associations are being queried, as defined by
- * UserIdentificationGetRequest. The HAL must return right away, returning a VehiclePropValue
- * with a UserIdentificationResponse. Notice that user identification should have already
- * happened while system is booting up and the VHAL implementation should only return the
- * already identified association (like the key FOB used to unlock the car), instead of starting
- * a new association from the get call.
- *
- * To associate types, the Android system sets the property, passing a VehiclePropValue
- * containing the types and values of associations being set, as defined by the
- * UserIdentificationSetRequest. The HAL will then use a property change event (whose
- * VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of
- * the types after the request.
- *
- * For example, to query if the current user (10) is associated with the FOB that unlocked the
- * car and a custom mechanism provided by the OEM, the request would be:
- *
- * int32[0]: 42 // request id
- * int32[1]: 10 (Android user id)
- * int32[2]: 0 (Android user flags)
- * int32[3]: 2 (number of types queried)
- * int32[4]: 1 (1st type queried, UserIdentificationAssociationType::KEY_FOB)
- * int32[5]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)
- *
- * If the user is associated with the FOB but not with the custom mechanism, the response would
- * be:
- *
- * int32[0]: 42 // request id
- * int32[1]: 2 (number of associations in the response)
- * int32[2]: 1 (1st type: UserIdentificationAssociationType::KEY_FOB)
- * int32[3]: 2 (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
- * int32[4]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1)
- * int32[5]: 4 (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)
- *
- * Then to associate the user with the custom mechanism, a set request would be made:
- *
- * int32[0]: 43 // request id
- * int32[1]: 10 (Android user id)
- * int32[2]: 0 (Android user flags)
- * int32[3]: 1 (number of associations being set)
- * int32[4]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
- * int32[5]: 1 (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)
- *
- * If the request succeeded, the response would be simply:
- *
- * int32[0]: 43 // request id
- * int32[1]: 1 (number of associations in the response)
- * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
- * int32[3]: 1 (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
- *
- * Notice that the set request adds associations, but doesn't remove the existing ones. In the
- * example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to
- * associate the user with just CUSTOM_1 but not FOB, then the request should have been:
- *
- * int32[0]: 43 // request id
- * int32[1]: 10 (Android user id)
- * int32[2]: 2 (number of types set)
- * int32[3]: 1 (1st type: UserIdentificationAssociationType::KEY_FOB)
- * int32[4]: 2 (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER)
- * int32[5]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1)
- * int32[6]: 1 (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Enable/request an EVS service.
- *
- * The property provides a generalized way to trigger EVS services. VHAL
- * should use this property to request Android to start or stop EVS service.
- *
- * int32Values[0] = a type of the EVS service. The value must be one of enums in
- * EvsServiceType.
- * int32Values[1] = the state of the EVS service. The value must be one of enums in
- * EvsServiceState.
- *
- * For example, to enable rear view EVS service, android side can set the property value as
- * [EvsServiceType::REAR_VIEW, EvsServiceState::ON].
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Defines a request to apply power policy.
- *
- * VHAL sets this property to change car power policy. Car power policy service subscribes to
- * this property and actually changes the power policy.
- * The request is made by setting the VehiclePropValue with the ID of a power policy which is
- * defined at /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy
- * service ignores the request and the current power policy is maintained.
- *
- * string: "sample_policy_id" // power policy ID
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Defines a request to set the power polic group used to decide a default power policy per
- * power status transition.
- *
- * VHAL sets this property with the ID of a power policy group in order to set the default power
- * policy applied at power status transition. Power policy groups are defined at
- * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service
- * ignores the request.
- * Car power policy service subscribes to this property and sets the power policy group.
- * The actual application of power policy takes place when the system power status changes and
- * there is a valid mapped power policy for the new power status.
- *
- * string: "sample_policy_group_id" // power policy group ID
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Notifies the current power policy to VHAL layer.
- *
- * Car power policy service sets this property when the current power policy is changed.
- *
- * string: "sample_policy_id" // power policy ID
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
- + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
- /**
- * Defines an event that car watchdog updates to tell it's alive.
- *
- * Car watchdog sets this property to system uptime in milliseconds at every 3 second.
- * During the boot, the update may take longer time.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
- + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
- /**
- * Defines a process terminated by car watchdog and the reason of termination.
- *
- * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated.
- * string: "/system/bin/log" // Process execution command.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Defines an event that VHAL signals to car watchdog as a heartbeat.
- *
- * If VHAL supports this property, VHAL should write system uptime to this property at every 3
- * second. Car watchdog subscribes to this property and checks if the property is updated at
- * every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be
- * signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers
- * VHAL unhealthy and terminates it.
- * If this property is not supported by VHAL, car watchdog doesn't check VHAL health status.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
- + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
- /**
- * Starts the ClusterUI in cluster display.
- *
- * int32: the type of ClusterUI to show
- * 0 indicates ClusterHome, that is a home screen of cluster display, and provides
- * the default UI and a kind of launcher functionality for cluster display.
- * the other values are followed by OEM's definition.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Changes the state of the cluster display.
- *
- * Bounds: the area to render the cluster Activity.
- * Inset: the area which Activity should avoid from placing any important
- * information.
- *
- * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
- * int32[1]: Bounds - left: positive number - left position in pixels
- -1 - don't care (should set all Bounds fields)
- * int32[2]: Bounds - top: same format with 'left'
- * int32[3]: Bounds - right: same format with 'left'
- * int32[4]: Bounds - bottom: same format with 'left'
- * int32[5]: Inset - left: positive number - actual left inset value in pixels
- -1 - don't care (should set "don't care" all Inset fields)
- * int32[6]: Inset - top: same format with 'left'
- * int32[7]: Inset - right: same format with 'left'
- * int32[8]: Inset - bottom: same format with 'left'
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- */
- CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
- + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
- /**
- * Reports the current display state and ClusterUI state.
- *
- * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.
- *
- * In addition, ClusterHome should send this message when it starts for the first time.
- * When ClusterOS receives this message and if the internal expectation is different with the
- * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to
- * match the state.
- *
- * int32[0]: on/off: 0 - off, 1 - on
- * int32[1]: Bounds - left
- * int32[2]: Bounds - top
- * int32[3]: Bounds - right
- * int32[4]: Bounds - bottom
- * int32[5]: Inset - left
- * int32[6]: Inset - top
- * int32[7]: Inset - right
- * int32[8]: Inset - bottom
- * int32[9]: the type of ClusterUI in the fullscreen or main screen.
- * 0 indicates ClusterHome.
- * the other values are followed by OEM's definition.
- * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown.
- * -1 indicates the area isn't used any more.
- * bytes: the array to represent the availability of ClusterUI.
- * 0 indicates non-available and 1 indicates available.
- * For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
- * and it only supports CALL UI only when the cellular network is available. Then, if the
- * nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
- + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
- /**
- * Requests to change the cluster display state to show some ClusterUI.
- *
- * When the current display state is off and ClusterHome sends this message to ClusterOS to
- * request to turn the display on to show some specific ClusterUI.
- * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
- *
- * int32: the type of ClusterUI to show
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Informs the current navigation state.
- *
- * bytes: the serialized message of NavigationStateProto.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
- + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
- /**
- * Electronic Toll Collection card type.
- *
- * This property indicates the type of ETC card in this vehicle.
- * If the head unit is aware of an ETC card attached to the vehicle, this property should
- * return the type of card attached; otherwise, this property should be UNAVAILABLE.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum ElectronicTollCollectionCardType
- */
- ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Electronic Toll Collection card status.
- *
- * This property indicates the status of ETC card in this vehicle.
- * If the head unit is aware of an ETC card attached to the vehicle,
- * ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise,
- * this property should be UNAVAILABLE.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum ElectronicTollCollectionCardStatus
- */
- ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
- /**
- * Front fog lights state
- *
- * Return the current state of the front fog lights.
- * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented. Please refer to
- * the documentation on FOG_LIGHTS_STATE for more information.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- FRONT_FOG_LIGHTS_STATE = 0x0F3B + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Front fog lights switch
- *
- * The setting that the user wants.
- * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented. Please refer to
- * the documentation on FOG_LIGHTS_SWITCH for more information.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- FRONT_FOG_LIGHTS_SWITCH = 0x0F3C + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Rear fog lights state
- *
- * Return the current state of the rear fog lights.
- * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented. Please refer to
- * the documentation on FOG_LIGHTS_STATE for more information.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum VehicleLightState
- */
- REAR_FOG_LIGHTS_STATE = 0x0F3D + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Rear fog lights switch
- *
- * The setting that the user wants.
- * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented. Please refer to
- * the documentation on FOG_LIGHTS_SWITCH for more information.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @data_enum VehicleLightSwitch
- */
- REAR_FOG_LIGHTS_SWITCH = 0x0F3E + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Indicates the maximum current draw threshold for charging set by the user
- *
- * configArray[0] is used to specify the max current draw allowed by
- * the vehicle in Amperes.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @unit VehicleUnit:AMPERE
- */
- EV_CHARGE_CURRENT_DRAW_LIMIT = 0x0F3F + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-
- /**
- * Indicates the maximum charge percent threshold set by the user
- *
- * Returns a float value from 0 to 100.
- *
- * configArray is used to specify the valid values.
- * For example, if the vehicle supports the following charge percent limit values:
- * [20, 40, 60, 80, 100]
- * then the configArray should be {20, 40, 60, 80, 100}
- * If the configArray is empty then all values from 0 to 100 must be valid.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- EV_CHARGE_PERCENT_LIMIT = 0x0F40 + 0x10000000 + 0x01000000
- + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
-
- /**
- * Charging state of the car
- *
- * Returns the current charging state of the car.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum EvChargeState
- */
- EV_CHARGE_STATE = 0x0F41 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Start or stop charging the EV battery
- *
- * The setting that the user wants. Setting this property to true starts the battery charging
- * and setting to false stops charging.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- EV_CHARGE_SWITCH = 0x0F42 + 0x10000000 + 0x01000000
- + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
-
- /**
- * Estimated charge time remaining in seconds
- *
- * Returns 0 if the vehicle is not charging.
- *
- * @change_mode VehiclePropertyChangeMode:CONTINUOUS
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:SECS
- */
- EV_CHARGE_TIME_REMAINING = 0x0F43 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Regenerative braking or one-pedal drive state of the car
- *
- * Returns the current state associated with the regenerative braking
- * setting in the car
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum EvRegenerativeBrakingState
- */
- EV_REGENERATIVE_BRAKING_STATE = 0x0F44 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Indicates if there is a trailer present or not.
- *
- * Returns the trailer state of the car.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ
- * @data_enum TrailerState
- */
- TRAILER_PRESENT = 0x0F45 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
- /**
- * Vehicle’s curb weight
- *
- * Returns the vehicle's curb weight in kilograms. Curb weight is
- * the total weight of the vehicle with standard equipment and all
- * necessary operating consumables such as motor oil,transmission oil,
- * brake fluid, coolant, air conditioning refrigerant, and weight of
- * fuel at nominal tank capacity, while not loaded with either passengers
- * or cargo.
- *
- * configArray[0] is used to specify the vehicle’s gross weight in kilograms.
- * The vehicle’s gross weight is the maximum operating weight of the vehicle
- * as specified by the manufacturer including the vehicle's chassis, body, engine,
- * engine fluids, fuel, accessories, driver, passengers and cargo but excluding
- * that of any trailers.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @unit VehicleUnit:KILOGRAM
- */
-
- VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
- + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
deleted file mode 100644
index 62d26de..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-/**
- * Enumerates supported data type for VehicleProperty.
- *
- * Used to create property ID in VehicleProperty enum.
- */
-@VintfStability
-@Backing(type="int")
-enum VehiclePropertyType {
- STRING = 0x00100000,
- BOOLEAN = 0x00200000,
- INT32 = 0x00400000,
- INT32_VEC = 0x00410000,
- INT64 = 0x00500000,
- INT64_VEC = 0x00510000,
- FLOAT = 0x00600000,
- FLOAT_VEC = 0x00610000,
- BYTES = 0x00700000,
-
- /**
- * Any combination of scalar or vector types. The exact format must be
- * provided in the description of the property.
- *
- * For vendor MIXED type properties, configArray needs to be formatted in this
- * structure.
- * configArray[0], 1 indicates the property has a String value
- * configArray[1], 1 indicates the property has a Boolean value .
- * configArray[2], 1 indicates the property has an Integer value.
- * configArray[3], the number indicates the size of Integer[] in the property.
- * configArray[4], 1 indicates the property has a Long value.
- * configArray[5], the number indicates the size of Long[] in the property.
- * configArray[6], 1 indicates the property has a Float value.
- * configArray[7], the number indicates the size of Float[] in the property.
- * configArray[8], the number indicates the size of byte[] in the property.
- * For example:
- * {@code configArray = {1, 1, 1, 3, 0, 0, 0, 0, 0}} indicates the property has
- * a String value, a Boolean value, an Integer value and an array with 3 integers.
- */
- MIXED = 0x00e00000,
-
- MASK = 0x00ff0000,
-}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl
deleted file mode 100644
index 3817b74..0000000
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleUnit.aidl
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.automotive.vehicle;
-
-/**
- * Units used for int or float type with no attached enum types.
- */
-@VintfStability
-@Backing(type="int")
-enum VehicleUnit {
- SHOULD_NOT_USE = 0x000,
- METER_PER_SEC = 0x01,
- RPM = 0x02,
- HERTZ = 0x03,
- PERCENTILE = 0x10,
- MILLIMETER = 0x20,
- METER = 0x21,
- KILOMETER = 0x23,
- MILE = 0x24,
- CELSIUS = 0x30,
- FAHRENHEIT = 0x31,
- KELVIN = 0x32,
- MILLILITER = 0x40,
- LITER = 0x41,
- /**
- * deprecated. Use US_GALLON instead.
- */
- GALLON = 0x42,
- US_GALLON = 0x42,
- IMPERIAL_GALLON = 0x43,
- NANO_SECS = 0x50,
- SECS = 0x53,
- YEAR = 0x59,
- WATT_HOUR = 0x60,
- MILLIAMPERE = 0x61,
- MILLIVOLT = 0x62,
- MILLIWATTS = 0x63,
- AMPERE_HOURS = 0x64,
- KILOWATT_HOUR = 0x65,
- AMPERE = 0x66,
- KILOPASCAL = 0x70,
- PSI = 0x71,
- BAR = 0x72,
- DEGREES = 0x80,
- MILES_PER_HOUR = 0x90,
- KILOMETERS_PER_HOUR = 0x91,
-}
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
new file mode 100644
index 0000000..d0c6e83
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -0,0 +1,283 @@
+/*
+ * 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.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
+ {VehicleProperty::INFO_VIN, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_MAKE, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_MODEL, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_MODEL_YEAR, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_FUEL_CAPACITY, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_FUEL_TYPE, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_EV_BATTERY_CAPACITY, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_EV_CONNECTOR_TYPE, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_FUEL_DOOR_LOCATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_EV_PORT_LOCATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess::READ},
+ {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess::READ},
+ {VehicleProperty::PERF_ODOMETER, VehiclePropertyAccess::READ},
+ {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyAccess::READ},
+ {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess::READ},
+ {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyAccess::READ},
+ {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess::READ},
+ {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyAccess::READ},
+ {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyAccess::READ},
+ {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyAccess::READ},
+ {VehicleProperty::ENGINE_RPM, VehiclePropertyAccess::READ},
+ {VehicleProperty::WHEEL_TICK, VehiclePropertyAccess::READ},
+ {VehicleProperty::FUEL_LEVEL, VehiclePropertyAccess::READ},
+ {VehicleProperty::FUEL_DOOR_OPEN, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_BATTERY_LEVEL, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_CHARGE_PORT_OPEN, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::RANGE_REMAINING, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::TIRE_PRESSURE, VehiclePropertyAccess::READ},
+ {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess::READ},
+ {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::GEAR_SELECTION, VehiclePropertyAccess::READ},
+ {VehicleProperty::CURRENT_GEAR, VehiclePropertyAccess::READ},
+ {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyAccess::READ},
+ {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::FUEL_LEVEL_LOW, VehiclePropertyAccess::READ},
+ {VehicleProperty::NIGHT_MODE, VehiclePropertyAccess::READ},
+ {VehicleProperty::TURN_SIGNAL_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::IGNITION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
+ {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
+ {VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_DEFROSTER, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_AC_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_MAX_AC_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_MAX_DEFROST_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_RECIRC_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_DUAL_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_AUTO_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_SEAT_TEMPERATURE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyAccess::READ},
+ {VehicleProperty::HVAC_POWER_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyAccess::READ},
+ {VehicleProperty::HVAC_AUTO_RECIRC_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_SEAT_VENTILATION, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DISTANCE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EXTERNAL_CAR_TIME, VehiclePropertyAccess::READ},
+ {VehicleProperty::ANDROID_EPOCH_TIME, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, VehiclePropertyAccess::READ},
+ {VehicleProperty::AP_POWER_STATE_REQ, VehiclePropertyAccess::READ},
+ {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyAccess::READ},
+ {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
+ {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
+ {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
+ {VehicleProperty::HW_ROTARY_INPUT, VehiclePropertyAccess::READ},
+ {VehicleProperty::HW_CUSTOM_INPUT, VehiclePropertyAccess::READ},
+ {VehicleProperty::DOOR_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DOOR_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DOOR_LOCK, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_Z_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_Z_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_Y_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_Y_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_LOCK, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_FOLD, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_MEMORY_SELECT, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::SEAT_MEMORY_SET, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::SEAT_BELT_BUCKLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BELT_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_DEPTH_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_TILT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_TILT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {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_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_OCCUPANCY, VehiclePropertyAccess::READ},
+ {VehicleProperty::WINDOW_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::WINDOW_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::WINDOW_LOCK, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess::READ},
+ {VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ},
+ {VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
+ {VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
+ {VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess::READ},
+ {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::HEADLIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::HAZARD_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::HEADLIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HAZARD_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::CABIN_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess::READ},
+ {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess::READ},
+ {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SWITCH_USER, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::CREATE_USER, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::REMOVE_USER, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyAccess::READ},
+ {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyAccess::READ},
+ {VehicleProperty::POWER_POLICY_GROUP_REQ, VehiclePropertyAccess::READ},
+ {VehicleProperty::CURRENT_POWER_POLICY, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::WATCHDOG_ALIVE, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::VHAL_HEARTBEAT, VehiclePropertyAccess::READ},
+ {VehicleProperty::CLUSTER_SWITCH_UI, VehiclePropertyAccess::READ},
+ {VehicleProperty::CLUSTER_DISPLAY_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::CLUSTER_REPORT_STATE, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::CLUSTER_REQUEST_DISPLAY, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::CLUSTER_NAVIGATION_STATE, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyAccess::READ},
+ {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyAccess::READ},
+ {VehicleProperty::FRONT_FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::REAR_FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_CHARGE_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_CHARGE_SWITCH, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_CHARGE_TIME_REMAINING, VehiclePropertyAccess::READ},
+ {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::TRAILER_PRESENT, VehiclePropertyAccess::READ},
+ {VehicleProperty::VEHICLE_CURB_WEIGHT, VehiclePropertyAccess::READ},
+ {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess::READ},
+ {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess::READ},
+ {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess::READ},
+ {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
+ {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ},
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // aidl
+
+#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
new file mode 100644
index 0000000..11d3693
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_headers {
+ name: "IVehicleGeneratedHeaders",
+ vendor_available: true,
+ local_include_dirs: ["."],
+ export_include_dirs: ["."],
+ defaults: ["VehicleHalInterfaceDefaults"],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
new file mode 100644
index 0000000..48532c9
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -0,0 +1,283 @@
+/*
+ * 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.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
+ {VehicleProperty::INFO_VIN, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_MAKE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_MODEL, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_MODEL_YEAR, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_FUEL_CAPACITY, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_FUEL_TYPE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_EV_BATTERY_CAPACITY, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_EV_CONNECTOR_TYPE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_FUEL_DOOR_LOCATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_EV_PORT_LOCATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::PERF_ODOMETER, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::ENGINE_RPM, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::WHEEL_TICK, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::FUEL_LEVEL, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::FUEL_DOOR_OPEN, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_BATTERY_LEVEL, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_PORT_OPEN, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::RANGE_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::TIRE_PRESSURE, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::GEAR_SELECTION, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CURRENT_GEAR, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FUEL_LEVEL_LOW, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::NIGHT_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::TURN_SIGNAL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::IGNITION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ABS_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_DEFROSTER, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_AC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_MAX_AC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_MAX_DEFROST_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_RECIRC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_DUAL_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_AUTO_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_SEAT_TEMPERATURE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_POWER_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::HVAC_AUTO_RECIRC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_SEAT_VENTILATION, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DISTANCE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EXTERNAL_CAR_TIME, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ANDROID_EPOCH_TIME, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::AP_POWER_STATE_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::PER_DISPLAY_BRIGHTNESS, 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},
+ {VehicleProperty::HW_ROTARY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HW_CUSTOM_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DOOR_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DOOR_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DOOR_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_Z_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_Z_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_Y_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_Y_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_FOLD, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_MEMORY_SELECT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_MEMORY_SET, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BELT_BUCKLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BELT_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_DEPTH_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_DEPTH_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_TILT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_TILT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {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_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_OCCUPANCY, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WINDOW_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WINDOW_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WINDOW_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HEADLIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HAZARD_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HEADLIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::HAZARD_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CABIN_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SWITCH_USER, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CREATE_USER, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::POWER_POLICY_GROUP_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CURRENT_POWER_POLICY, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WATCHDOG_ALIVE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VHAL_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CLUSTER_SWITCH_UI, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CLUSTER_DISPLAY_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CLUSTER_REPORT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CLUSTER_REQUEST_DISPLAY, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CLUSTER_NAVIGATION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FRONT_FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::REAR_FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EV_CHARGE_TIME_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::TRAILER_PRESENT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode::STATIC},
+ {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VEHICLE_IN_USE, 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},
+ {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
+ {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},
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // aidl
+
+#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
new file mode 100644
index 0000000..758670d
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class AccessForVehicleProperty {
+
+ public static final Map<Integer, Integer> values = Map.ofEntries(
+ Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_MODEL, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_FUEL_TYPE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_EV_CONNECTOR_TYPE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_FUEL_DOOR_LOCATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ENGINE_RPM, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.WHEEL_TICK, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.FUEL_LEVEL, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.FUEL_DOOR_OPEN, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.EV_CHARGE_PORT_OPEN, VehiclePropertyAccess.READ_WRITE),
+ 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.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.GEAR_SELECTION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.PARKING_BRAKE_AUTO_APPLY, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.FUEL_LEVEL_LOW, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.NIGHT_MODE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.TURN_SIGNAL_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyAccess.READ),
+ 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.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_DEFROSTER, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_AC_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_MAX_AC_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_MAX_DEFROST_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_RECIRC_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_DUAL_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_AUTO_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_SEAT_TEMPERATURE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_SIDE_MIRROR_HEAT, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_STEERING_WHEEL_HEAT, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HVAC_POWER_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HVAC_AUTO_RECIRC_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_SEAT_VENTILATION, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DISTANCE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.AP_POWER_STATE_REQ, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyAccess.READ_WRITE),
+ 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.HW_KEY_INPUT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HW_ROTARY_INPUT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HW_CUSTOM_INPUT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DOOR_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DOOR_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DOOR_LOCK, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_Z_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_Z_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_Y_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_Y_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_LOCK, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_FOLD, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_MEMORY_SELECT, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.SEAT_MEMORY_SET, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.SEAT_BELT_BUCKLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_DEPTH_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_DEPTH_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_TILT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_TILT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ 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_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_OCCUPANCY, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.WINDOW_LOCK, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.GLOVE_BOX_DOOR_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.HEADLIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HAZARD_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HEADLIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.HAZARD_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.CABIN_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.POWER_POLICY_GROUP_REQ, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CURRENT_POWER_POLICY, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.WATCHDOG_ALIVE, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.WATCHDOG_TERMINATED_PROCESS, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.VHAL_HEARTBEAT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CLUSTER_SWITCH_UI, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CLUSTER_DISPLAY_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CLUSTER_REPORT_STATE, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.CLUSTER_REQUEST_DISPLAY, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.CLUSTER_NAVIGATION_STATE, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.REAR_FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.REAR_FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_CHARGE_PERCENT_LIMIT, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_CHARGE_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.EV_CHARGE_SWITCH, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.TRAILER_PRESENT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
+ 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),
+ Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_TYPE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyAccess.READ_WRITE),
+ 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)
+ );
+
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/Android.bp b/automotive/vehicle/aidl/generated_lib/java/Android.bp
new file mode 100644
index 0000000..1d612e8
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/java/Android.bp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+ name: "IVehicleGeneratedJavaFiles",
+ srcs: [
+ "*.java",
+ ],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
new file mode 100644
index 0000000..29069f8
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class ChangeModeForVehicleProperty {
+
+ public static final Map<Integer, Integer> values = Map.ofEntries(
+ Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_MODEL, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_FUEL_TYPE, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_EV_CONNECTOR_TYPE, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_FUEL_DOOR_LOCATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.ENGINE_RPM, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.WHEEL_TICK, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.FUEL_LEVEL, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.FUEL_DOOR_OPEN, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_CHARGE_PORT_OPEN, VehiclePropertyChangeMode.ON_CHANGE),
+ 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.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.GEAR_SELECTION, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.PARKING_BRAKE_AUTO_APPLY, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FUEL_LEVEL_LOW, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.NIGHT_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.TURN_SIGNAL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ 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.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_DEFROSTER, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_AC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_MAX_AC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_MAX_DEFROST_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_RECIRC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_DUAL_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_AUTO_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_SEAT_TEMPERATURE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_SIDE_MIRROR_HEAT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_STEERING_WHEEL_HEAT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_POWER_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.HVAC_AUTO_RECIRC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_SEAT_VENTILATION, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DISTANCE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.AP_POWER_STATE_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyChangeMode.ON_CHANGE),
+ 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.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),
+ Map.entry(VehicleProperty.HW_ROTARY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HW_CUSTOM_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DOOR_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DOOR_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DOOR_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_Z_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_Z_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_Y_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_Y_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_FOLD, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.MIRROR_AUTO_TILT_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_MEMORY_SELECT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_MEMORY_SET, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BELT_BUCKLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_DEPTH_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_DEPTH_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_TILT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_TILT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ 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_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_OCCUPANCY, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WINDOW_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.GLOVE_BOX_DOOR_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HEADLIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HAZARD_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HEADLIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.HAZARD_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CABIN_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.POWER_POLICY_GROUP_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CURRENT_POWER_POLICY, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WATCHDOG_ALIVE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.WATCHDOG_TERMINATED_PROCESS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VHAL_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CLUSTER_SWITCH_UI, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CLUSTER_DISPLAY_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CLUSTER_REPORT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CLUSTER_REQUEST_DISPLAY, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CLUSTER_NAVIGATION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.REAR_FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.REAR_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_CHARGE_PERCENT_LIMIT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_CHARGE_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_CHARGE_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.TRAILER_PRESENT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode.STATIC),
+ Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VEHICLE_IN_USE, 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),
+ Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_TYPE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyChangeMode.ON_CHANGE),
+ 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)
+ );
+
+}
diff --git a/automotive/vehicle/aidl/impl/Android.bp b/automotive/vehicle/aidl/impl/Android.bp
index d24a739..d2c5145 100644
--- a/automotive/vehicle/aidl/impl/Android.bp
+++ b/automotive/vehicle/aidl/impl/Android.bp
@@ -22,7 +22,6 @@
name: "VehicleHalDefaults",
static_libs: [
"android-automotive-large-parcelable-lib",
- "android.hardware.automotive.vehicle-V1-ndk",
"libmath",
],
shared_libs: [
@@ -37,6 +36,7 @@
"-Wthread-safety",
],
defaults: [
+ "VehicleHalInterfaceDefaults",
"android-automotive-large-parcelable-defaults",
],
}
diff --git a/automotive/vehicle/aidl/impl/README.md b/automotive/vehicle/aidl/impl/README.md
new file mode 100644
index 0000000..121ffd1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/README.md
@@ -0,0 +1,58 @@
+# AIDL VHAL libraries and reference implementation.
+---
+
+This directory stores the libraries useful for implementing vendor AIDL VHAL.
+This directory also stores a reference fake implementation for AIDL VHAL.
+
+## default_config
+
+Stores the default vehicle property configurations for reference vehicle HAL.
+Vendor implementation could copy this library but must update the configuration
+to meet their own requirements, e.g. enable or disable certain properties or
+update the initial value for certain properties.
+
+## fake_impl
+
+Contains libraries used specifically for the fake reference VHAL implementation.
+These libraries are for test only and must not be directly used for vendor
+VHAL implementation.
+
+These libraries contain test-spcific logic and must not run directly on a real
+vehicle.
+
+## grpc
+
+Stores code for GRPC based VHAL implementation.
+
+## hardware
+
+Defines an interface `IVehicleHardware.h` which vendor must implement for
+vehicle-specific logic if they want to follow our reference VHAL design.
+
+## proto
+
+Stores Some protobuf files translated from AIDL VHAL interface types. These
+files are used in GRPC VHAL implementation.
+
+## utils
+
+Defines a library `VehicleHalUtils` which provides useful utility functions for
+VHAL implementation. Vendor VHAL could use this library.
+
+## vhal
+
+Defines a library `DefaultVehicleHal` which provides generic logic for all VHAL
+implementations (including reference VHAL). Vendor VHAL implementation could
+use this library, along with their own implementation for `IVehicleHardware`
+interface.
+
+Also defines a binary `android.hardware.automotive.vehicle@V1-default-service`
+which is the reference VHAL implementation. It implements `IVehicle.aidl`
+interface. It uses `DefaultVehicleHal`, along with `FakeVehicleHardware`
+(in fake_impl). It simulates the vehicle bus interaction by using an
+in-memory map. Meaning that all properties (except for some special ones) are
+just written into a hash map and read from a hash map without relying on any
+hardware. As a result, the reference implementation can run on emulator or
+any host environment.
+
+Vendor must not directly use the reference implementation for a real vehicle.
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/Android.bp b/automotive/vehicle/aidl/impl/default_config/Android.bp
deleted file mode 100644
index 0feaf23..0000000
--- a/automotive/vehicle/aidl/impl/default_config/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_library_headers {
- name: "VehicleHalDefaultConfig",
- vendor: true,
- local_include_dirs: ["include"],
- export_include_dirs: ["include"],
- defaults: ["VehicleHalDefaults"],
- static_libs: ["VehicleHalUtils"],
- header_libs: ["VehicleHalTestUtilHeaders"],
- export_static_lib_headers: ["VehicleHalUtils"],
- export_header_lib_headers: ["VehicleHalTestUtilHeaders"],
-}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
new file mode 100644
index 0000000..6984d5e
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+ name: "VehicleHalJsonConfigLoader",
+ vendor: true,
+ srcs: ["src/*.cpp"],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ defaults: ["VehicleHalDefaults"],
+ static_libs: ["VehicleHalUtils"],
+ header_libs: [
+ "IVehicleGeneratedHeaders",
+ ],
+ shared_libs: ["libjsoncpp"],
+}
+
+cc_library {
+ name: "VehicleHalJsonConfigLoaderEnableTestProperties",
+ vendor: true,
+ srcs: ["src/*.cpp"],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ defaults: ["VehicleHalDefaults"],
+ static_libs: ["VehicleHalUtils"],
+ header_libs: [
+ "VehicleHalTestUtilHeaders",
+ "IVehicleGeneratedHeaders",
+ ],
+ cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
+ shared_libs: ["libjsoncpp"],
+}
+
+cc_library_headers {
+ name: "VehicleHalJsonConfigLoaderHeaders",
+ vendor: true,
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ defaults: ["VehicleHalDefaults"],
+ static_libs: ["VehicleHalUtils"],
+ header_libs: [
+ "IVehicleGeneratedHeaders",
+ ],
+ shared_libs: ["libjsoncpp"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h
new file mode 100644
index 0000000..40ac129
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_ConfigDeclaration_H_
+#define android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_ConfigDeclaration_H_
+
+#include <VehicleHalTypes.h>
+
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// ConfigDeclaration represents one property config, its optional initial value and its optional
+// area configs and initial values for each area.
+struct ConfigDeclaration {
+ aidl::android::hardware::automotive::vehicle::VehiclePropConfig config;
+
+ // This value will be used as an initial value for the property. If this field is specified for
+ // property that supports multiple areas then it will be used for all areas unless particular
+ // area is overridden in initialAreaValue field.
+ aidl::android::hardware::automotive::vehicle::RawPropValues initialValue;
+ // Use initialAreaValues if it is necessary to specify different values per each area.
+ std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::RawPropValues>
+ initialAreaValues;
+
+ inline bool operator==(const ConfigDeclaration& other) const {
+ return (config == other.config && initialValue == other.initialValue &&
+ initialAreaValues == other.initialAreaValues);
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, const ConfigDeclaration& c) {
+ return os << "Config Declaration for property: "
+ << aidl::android::hardware::automotive::vehicle::toString(
+ static_cast<
+ aidl::android::hardware::automotive::vehicle::VehicleProperty>(
+ c.config.prop));
+ }
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_ConfigDeclaration_H_
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
new file mode 100644
index 0000000..f3bdbd2
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_JsonConfigLoader_H_
+#define android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_JsonConfigLoader_H_
+
+#include <ConfigDeclaration.h>
+#include <VehicleHalTypes.h>
+
+#include <android-base/result.h>
+#include <json/json.h>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// private namespace
+namespace jsonconfigloader_impl {
+
+// An abstract interface that represents a ValueParser for any constant value types.
+class ConstantParserInterface {
+ public:
+ // Parses a constant variable name to its actual value.
+ virtual android::base::Result<int> parseValue(const std::string& name) const = 0;
+ virtual ~ConstantParserInterface() = default;
+};
+
+// A class to parse a value field in JSON config file.
+// If the field is a string and the field is in the format of "XX::XX", the value will be parsed
+// as a constant value in the format of "TYPE::NAME". Otherwise, the field will be return as is
+// converted to the expected type.
+class JsonValueParser final {
+ public:
+ JsonValueParser();
+
+ android::base::Result<std::string> parseStringValue(const std::string& fieldName,
+ const Json::Value& value) const;
+
+ template <class T>
+ android::base::Result<std::vector<T>> parseArray(const std::string& fieldName,
+ const Json::Value& value) const;
+
+ template <class T>
+ android::base::Result<T> parseValue(const std::string& fieldName,
+ const Json::Value& value) const;
+
+ private:
+ template <class T>
+ static android::base::Result<T> convertValueToType(const std::string& fieldName,
+ const Json::Value& value);
+
+ std::optional<std::pair<std::string, std::string>> maybeGetTypeAndValueName(
+ const std::string& jsonFieldValue) const;
+
+ android::base::Result<int> parseConstantValue(
+ const std::pair<std::string, std::string>& typeValueName) const;
+
+ const ConstantParserInterface* getParser(const std::string& type) const {
+ auto it = mConstantParsersByType.find(type);
+ if (it == mConstantParsersByType.end()) {
+ return nullptr;
+ }
+ return it->second.get();
+ }
+
+ private:
+ inline static const std::string DELIMITER = "::";
+ std::unordered_map<std::string, std::unique_ptr<ConstantParserInterface>>
+ mConstantParsersByType;
+};
+
+// The main class to parse a VHAL config file in JSON format.
+class JsonConfigParser {
+ public:
+ android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>> parseJsonConfig(
+ std::istream& is);
+
+ private:
+ JsonValueParser mValueParser;
+
+ // Parses configuration for each property.
+ std::optional<ConfigDeclaration> parseEachProperty(const Json::Value& propJsonValue,
+ std::vector<std::string>* errors);
+ // Tries to parse a JSON value to a specific type.
+ //
+ // If fieldIsOptional is True, then if the field specified by "fieldName" does not exist,
+ // this method will return true without doing anything, otherwise, it will return false.
+ //
+ // @param parentJsonNode The parent node of the field you are going to parse.
+ // @param fieldName The name for the field.
+ // @param fieldIsOptional Whether the field is optional.
+ // @param outPtr The pointer to output to if the field exists and parsing succeeded.
+ // @param errors The error array to append error to if errors are found.
+ // @return true if the field is optional and does not exist or parsed successfully.
+ template <class T>
+ bool tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
+ const std::string& fieldName, bool fieldIsOptional, T* outPtr,
+ std::vector<std::string>* errors);
+ // Tries to parse a JSON value to an array of specific type.
+ //
+ // If fieldIsOptional is True, then if the field specified by "fieldName" does not exist,
+ // this method will return true without doing anything, otherwise, it will return false.
+ //
+ // @param parentJsonNode The parent node of the field you are going to parse.
+ // @param fieldName The name for the field.
+ // @param fieldIsOptional Whether the field is optional.
+ // @param outPtr The pointer to output to if the field exists and parsing succeeded.
+ // @param errors The error array to append error to if errors are found.
+ // @return true if the field is optional and does not exist or parsed successfully.
+ template <class T>
+ bool tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
+ const std::string& fieldName, bool fieldIsOptional,
+ std::vector<T>* outPtr, std::vector<std::string>* errors);
+ // Parses a JSON field to VehiclePropertyAccess or VehiclePropertyChangeMode.
+ template <class T>
+ void parseAccessChangeMode(
+ const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
+ const std::string& propStr,
+ const std::unordered_map<aidl::android::hardware::automotive::vehicle::VehicleProperty,
+ T>& defaultMap,
+ T* outPtr, std::vector<std::string>* errors);
+
+ // Parses a JSON field to RawPropValues.
+ //
+ // @return True if the field exist and can be parsed to a RawPropValues.
+ bool parsePropValues(const Json::Value& parentJsonNode, const std::string& fieldName,
+ aidl::android::hardware::automotive::vehicle::RawPropValues* outPtr,
+ std::vector<std::string>* errors);
+
+ // Prase a JSON field as an array of area configs.
+ void parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
+ ConfigDeclaration* outPtr, std::vector<std::string>* errors);
+};
+
+} // namespace jsonconfigloader_impl
+
+// A class to load vehicle property configs and initial values in JSON format.
+class JsonConfigLoader final {
+ public:
+ JsonConfigLoader();
+
+ // Loads a JSON file stream and parses it to a map from propId to ConfigDeclarations.
+ android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>> loadPropConfig(
+ std::istream& is);
+
+ // Loads a JSON config file and parses it to a map from propId to ConfigDeclarations.
+ android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>> loadPropConfig(
+ const std::string& configPath);
+
+ private:
+ std::unique_ptr<jsonconfigloader_impl::JsonConfigParser> mParser;
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_aidl_impl_default_config_JsonConfigLoader_include_JsonConfigLoader_H_
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
new file mode 100644
index 0000000..ec0d310
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <JsonConfigLoader.h>
+
+#include <AccessForVehicleProperty.h>
+#include <ChangeModeForVehicleProperty.h>
+#include <PropertyUtils.h>
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+#include <TestPropertyUtils.h>
+#endif // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+#include <android-base/strings.h>
+#include <fstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace jsonconfigloader_impl {
+
+using ::aidl::android::hardware::automotive::vehicle::AccessForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::AutomaticEmergencyBrakingState;
+using ::aidl::android::hardware::automotive::vehicle::BlindSpotWarningState;
+using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
+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::EmergencyLaneKeepAssistState;
+using ::aidl::android::hardware::automotive::vehicle::ErrorState;
+using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
+using ::aidl::android::hardware::automotive::vehicle::EvsServiceState;
+using ::aidl::android::hardware::automotive::vehicle::EvsServiceType;
+using ::aidl::android::hardware::automotive::vehicle::ForwardCollisionWarningState;
+using ::aidl::android::hardware::automotive::vehicle::FuelType;
+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::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::RawPropValues;
+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::VehicleGear;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
+using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleOilLevel;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+using ::aidl::android::hardware::automotive::vehicle::VehicleSeatOccupancyState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
+using ::aidl::android::hardware::automotive::vehicle::VehicleVendorPermission;
+using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersState;
+using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersSwitch;
+
+using ::android::base::Error;
+using ::android::base::Result;
+
+// Defines a map from constant names to constant values, the values defined here corresponds to
+// the "Constants::XXXX" used in JSON config file.
+const std::unordered_map<std::string, int> CONSTANTS_BY_NAME = {
+ {"DOOR_1_RIGHT", DOOR_1_RIGHT},
+ {"DOOR_1_LEFT", DOOR_1_LEFT},
+ {"DOOR_2_RIGHT", DOOR_2_RIGHT},
+ {"DOOR_2_LEFT", DOOR_2_LEFT},
+ {"DOOR_REAR", DOOR_REAR},
+ {"HVAC_ALL", HVAC_ALL},
+ {"HVAC_LEFT", HVAC_LEFT},
+ {"HVAC_RIGHT", HVAC_RIGHT},
+ {"VENDOR_EXTENSION_INT_PROPERTY", VENDOR_EXTENSION_INT_PROPERTY},
+ {"VENDOR_EXTENSION_BOOLEAN_PROPERTY", VENDOR_EXTENSION_BOOLEAN_PROPERTY},
+ {"VENDOR_EXTENSION_STRING_PROPERTY", VENDOR_EXTENSION_STRING_PROPERTY},
+ {"VENDOR_EXTENSION_FLOAT_PROPERTY", VENDOR_EXTENSION_FLOAT_PROPERTY},
+ {"WINDOW_1_LEFT", WINDOW_1_LEFT},
+ {"WINDOW_1_RIGHT", WINDOW_1_RIGHT},
+ {"WINDOW_2_LEFT", WINDOW_2_LEFT},
+ {"WINDOW_2_RIGHT", WINDOW_2_RIGHT},
+ {"WINDOW_ROOF_TOP_1", WINDOW_ROOF_TOP_1},
+ {"WINDOW_1_RIGHT_2_LEFT_2_RIGHT", WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT},
+ {"SEAT_1_LEFT", SEAT_1_LEFT},
+ {"SEAT_1_RIGHT", SEAT_1_RIGHT},
+ {"SEAT_2_LEFT", SEAT_2_LEFT},
+ {"SEAT_2_RIGHT", SEAT_2_RIGHT},
+ {"SEAT_2_CENTER", SEAT_2_CENTER},
+ {"SEAT_2_LEFT_2_RIGHT_2_CENTER", SEAT_2_LEFT | SEAT_2_RIGHT | SEAT_2_CENTER},
+ {"WHEEL_REAR_RIGHT", WHEEL_REAR_RIGHT},
+ {"WHEEL_REAR_LEFT", WHEEL_REAR_LEFT},
+ {"WHEEL_FRONT_RIGHT", WHEEL_FRONT_RIGHT},
+ {"WHEEL_FRONT_LEFT", WHEEL_FRONT_LEFT},
+ {"CHARGE_PORT_FRONT_LEFT", CHARGE_PORT_FRONT_LEFT},
+ {"CHARGE_PORT_REAR_LEFT", CHARGE_PORT_REAR_LEFT},
+ {"FAN_DIRECTION_FLOOR", FAN_DIRECTION_FLOOR},
+ {"FAN_DIRECTION_FACE", FAN_DIRECTION_FACE},
+ {"FAN_DIRECTION_DEFROST", FAN_DIRECTION_DEFROST},
+ {"FAN_DIRECTION_FACE_FLOOR", FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR},
+ {"FAN_DIRECTION_FACE_DEFROST", FAN_DIRECTION_FACE | FAN_DIRECTION_DEFROST},
+ {"FAN_DIRECTION_FLOOR_DEFROST", FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST},
+ {"FAN_DIRECTION_FLOOR_DEFROST_FACE",
+ FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST | FAN_DIRECTION_FACE},
+ {"FUEL_DOOR_REAR_LEFT", FUEL_DOOR_REAR_LEFT},
+ {"LIGHT_STATE_ON", LIGHT_STATE_ON},
+ {"LIGHT_STATE_OFF", LIGHT_STATE_OFF},
+ {"LIGHT_SWITCH_OFF", LIGHT_SWITCH_OFF},
+ {"LIGHT_SWITCH_ON", LIGHT_SWITCH_ON},
+ {"LIGHT_SWITCH_AUTO", LIGHT_SWITCH_AUTO},
+ {"EV_STOPPING_MODE_CREEP", EV_STOPPING_MODE_CREEP},
+ {"EV_STOPPING_MODE_ROLL", EV_STOPPING_MODE_ROLL},
+ {"EV_STOPPING_MODE_HOLD", EV_STOPPING_MODE_HOLD},
+ {"MIRROR_DRIVER_LEFT_RIGHT",
+ toInt(VehicleAreaMirror::DRIVER_LEFT) | toInt(VehicleAreaMirror::DRIVER_RIGHT)},
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+ // Following are test properties:
+ {"ECHO_REVERSE_BYTES", ECHO_REVERSE_BYTES},
+ {"VENDOR_PROPERTY_ID", VENDOR_PROPERTY_ID},
+ {"kMixedTypePropertyForTest", kMixedTypePropertyForTest},
+ {"VENDOR_CLUSTER_NAVIGATION_STATE", VENDOR_CLUSTER_NAVIGATION_STATE},
+ {"VENDOR_CLUSTER_REQUEST_DISPLAY", VENDOR_CLUSTER_REQUEST_DISPLAY},
+ {"VENDOR_CLUSTER_SWITCH_UI", VENDOR_CLUSTER_SWITCH_UI},
+ {"VENDOR_CLUSTER_DISPLAY_STATE", VENDOR_CLUSTER_DISPLAY_STATE},
+ {"VENDOR_CLUSTER_REPORT_STATE", VENDOR_CLUSTER_REPORT_STATE},
+ {"PLACEHOLDER_PROPERTY_INT", PLACEHOLDER_PROPERTY_INT},
+ {"PLACEHOLDER_PROPERTY_FLOAT", PLACEHOLDER_PROPERTY_FLOAT},
+ {"PLACEHOLDER_PROPERTY_BOOLEAN", PLACEHOLDER_PROPERTY_BOOLEAN},
+ {"PLACEHOLDER_PROPERTY_STRING", PLACEHOLDER_PROPERTY_STRING}
+#endif // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+};
+
+// A class to parse constant values for type T.
+template <class T>
+class ConstantParser final : public ConstantParserInterface {
+ public:
+ ConstantParser() {
+ for (const T& v : ndk::enum_range<T>()) {
+ std::string name = aidl::android::hardware::automotive::vehicle::toString(v);
+ // We use the same constant for both VehicleUnit::GALLON and VehicleUnit::US_GALLON,
+ // which caused toString() not work properly for US_GALLON. So we explicitly add the
+ // map here.
+ if (name == "GALLON") {
+ mValueByName["US_GALLON"] = toInt(v);
+ }
+ mValueByName[name] = toInt(v);
+ }
+ }
+
+ ~ConstantParser() = default;
+
+ Result<int> parseValue(const std::string& name) const override {
+ auto it = mValueByName.find(name);
+ if (it == mValueByName.end()) {
+ return Error() << "Constant name: " << name << " is not defined";
+ }
+ return it->second;
+ }
+
+ private:
+ std::unordered_map<std::string, int> mValueByName;
+};
+
+// A class to parse constant values defined in CONSTANTS_BY_NAME map.
+class LocalVariableParser final : public ConstantParserInterface {
+ public:
+ ~LocalVariableParser() = default;
+
+ Result<int> parseValue(const std::string& name) const override {
+ auto constantsIt = CONSTANTS_BY_NAME.find(name);
+ if (constantsIt == CONSTANTS_BY_NAME.end()) {
+ return Error() << "Constant variable name: " << name << " is not defined";
+ }
+ return constantsIt->second;
+ }
+};
+
+JsonValueParser::JsonValueParser() {
+ mConstantParsersByType["VehiclePropertyAccess"] =
+ std::make_unique<ConstantParser<VehiclePropertyAccess>>();
+ mConstantParsersByType["VehiclePropertyChangeMode"] =
+ std::make_unique<ConstantParser<VehiclePropertyChangeMode>>();
+ mConstantParsersByType["LocationCharacterization"] =
+ std::make_unique<ConstantParser<LocationCharacterization>>();
+ mConstantParsersByType["VehicleGear"] = std::make_unique<ConstantParser<VehicleGear>>();
+ mConstantParsersByType["VehicleAreaWindow"] =
+ std::make_unique<ConstantParser<VehicleAreaWindow>>();
+ mConstantParsersByType["VehicleAreaMirror"] =
+ std::make_unique<ConstantParser<VehicleAreaMirror>>();
+ mConstantParsersByType["VehicleOilLevel"] = std::make_unique<ConstantParser<VehicleOilLevel>>();
+ mConstantParsersByType["VehicleUnit"] = std::make_unique<ConstantParser<VehicleUnit>>();
+ mConstantParsersByType["VehicleSeatOccupancyState"] =
+ std::make_unique<ConstantParser<VehicleSeatOccupancyState>>();
+ mConstantParsersByType["VehicleHvacFanDirection"] =
+ std::make_unique<ConstantParser<VehicleHvacFanDirection>>();
+ mConstantParsersByType["VehicleApPowerStateReport"] =
+ std::make_unique<ConstantParser<VehicleApPowerStateReport>>();
+ mConstantParsersByType["VehicleTurnSignal"] =
+ std::make_unique<ConstantParser<VehicleTurnSignal>>();
+ mConstantParsersByType["VehicleVendorPermission"] =
+ std::make_unique<ConstantParser<VehicleVendorPermission>>();
+ mConstantParsersByType["EvsServiceType"] = std::make_unique<ConstantParser<EvsServiceType>>();
+ mConstantParsersByType["EvsServiceState"] = std::make_unique<ConstantParser<EvsServiceState>>();
+ mConstantParsersByType["EvConnectorType"] = std::make_unique<ConstantParser<EvConnectorType>>();
+ mConstantParsersByType["VehicleProperty"] = std::make_unique<ConstantParser<VehicleProperty>>();
+ mConstantParsersByType["GsrComplianceRequirementType"] =
+ std::make_unique<ConstantParser<GsrComplianceRequirementType>>();
+ mConstantParsersByType["VehicleIgnitionState"] =
+ std::make_unique<ConstantParser<VehicleIgnitionState>>();
+ mConstantParsersByType["FuelType"] = std::make_unique<ConstantParser<FuelType>>();
+ mConstantParsersByType["WindshieldWipersState"] =
+ std::make_unique<ConstantParser<WindshieldWipersState>>();
+ mConstantParsersByType["WindshieldWipersSwitch"] =
+ std::make_unique<ConstantParser<WindshieldWipersSwitch>>();
+ mConstantParsersByType["EmergencyLaneKeepAssistState"] =
+ std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
+ mConstantParsersByType["CruiseControlType"] =
+ std::make_unique<ConstantParser<CruiseControlType>>();
+ mConstantParsersByType["CruiseControlState"] =
+ std::make_unique<ConstantParser<CruiseControlState>>();
+ mConstantParsersByType["CruiseControlCommand"] =
+ std::make_unique<ConstantParser<CruiseControlCommand>>();
+ mConstantParsersByType["HandsOnDetectionDriverState"] =
+ std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
+ mConstantParsersByType["HandsOnDetectionWarning"] =
+ std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
+ mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
+ mConstantParsersByType["AutomaticEmergencyBrakingState"] =
+ std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
+ mConstantParsersByType["ForwardCollisionWarningState"] =
+ std::make_unique<ConstantParser<ForwardCollisionWarningState>>();
+ mConstantParsersByType["BlindSpotWarningState"] =
+ std::make_unique<ConstantParser<BlindSpotWarningState>>();
+ mConstantParsersByType["LaneDepartureWarningState"] =
+ std::make_unique<ConstantParser<LaneDepartureWarningState>>();
+ mConstantParsersByType["LaneKeepAssistState"] =
+ std::make_unique<ConstantParser<LaneKeepAssistState>>();
+ mConstantParsersByType["LaneCenteringAssistCommand"] =
+ std::make_unique<ConstantParser<LaneCenteringAssistCommand>>();
+ mConstantParsersByType["LaneCenteringAssistState"] =
+ std::make_unique<ConstantParser<LaneCenteringAssistState>>();
+ mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
+}
+
+template <>
+Result<int32_t> JsonValueParser::convertValueToType<int32_t>(const std::string& fieldName,
+ const Json::Value& value) {
+ if (!value.isInt()) {
+ return Error() << "The value: " << value << " for field: " << fieldName
+ << " is not in correct type, expect int";
+ }
+ return static_cast<int32_t>(value.asInt());
+}
+
+template <>
+Result<float> JsonValueParser::convertValueToType<float>(const std::string& fieldName,
+ const Json::Value& value) {
+ // isFloat value does not exist, so we use isDouble here.
+ if (!value.isDouble()) {
+ return Error() << "The value: " << value << " for field: " << fieldName
+ << " is not in correct type, expect float";
+ }
+ return value.asFloat();
+}
+
+template <>
+Result<int64_t> JsonValueParser::convertValueToType<int64_t>(const std::string& fieldName,
+ const Json::Value& value) {
+ if (!value.isInt64()) {
+ return Error() << "The value: " << value << " for field: " << fieldName
+ << " is not in correct type, expect int64";
+ }
+ return static_cast<int64_t>(value.asInt64());
+}
+
+template <>
+Result<std::string> JsonValueParser::convertValueToType<std::string>(const std::string& fieldName,
+ const Json::Value& value) {
+ if (!value.isString()) {
+ return Error() << "The value: " << value << " for field: " << fieldName
+ << " is not in correct type, expect string";
+ }
+ return value.asString();
+}
+
+Result<std::string> JsonValueParser::parseStringValue(const std::string& fieldName,
+ const Json::Value& value) const {
+ return convertValueToType<std::string>(fieldName, value);
+}
+
+template <class T>
+Result<T> JsonValueParser::parseValue(const std::string& fieldName,
+ const Json::Value& value) const {
+ if (!value.isString()) {
+ return convertValueToType<T>(fieldName, value);
+ }
+ auto maybeTypeAndValue = maybeGetTypeAndValueName(value.asString());
+ if (!maybeTypeAndValue.has_value()) {
+ return Error() << "Invalid constant value: " << value << " for field: " << fieldName;
+ }
+ auto constantParseResult = parseConstantValue(maybeTypeAndValue.value());
+ if (!constantParseResult.ok()) {
+ return constantParseResult.error();
+ }
+ int constantValue = constantParseResult.value();
+ return static_cast<T>(constantValue);
+}
+
+template <>
+Result<std::string> JsonValueParser::parseValue<std::string>(const std::string& fieldName,
+ const Json::Value& value) const {
+ return parseStringValue(fieldName, value);
+}
+
+template <class T>
+Result<std::vector<T>> JsonValueParser::parseArray(const std::string& fieldName,
+ const Json::Value& value) const {
+ if (!value.isArray()) {
+ return Error() << "The value: " << value << " for field: " << fieldName
+ << " is not in correct type, expect array";
+ }
+ std::vector<T> parsedValues;
+ for (unsigned int i = 0; i < value.size(); i++) {
+ auto result = parseValue<T>(fieldName, value[i]);
+ if (!result.ok()) {
+ return result.error();
+ }
+ parsedValues.push_back(result.value());
+ }
+ return std::move(parsedValues);
+}
+
+std::optional<std::pair<std::string, std::string>> JsonValueParser::maybeGetTypeAndValueName(
+ const std::string& jsonFieldValue) const {
+ size_t pos = jsonFieldValue.find(DELIMITER);
+ if (pos == std::string::npos) {
+ return {};
+ }
+ std::string type = jsonFieldValue.substr(0, pos);
+ std::string valueName = jsonFieldValue.substr(pos + DELIMITER.length(), std::string::npos);
+ if (type != "Constants" && mConstantParsersByType.find(type) == mConstantParsersByType.end()) {
+ return {};
+ }
+ return std::make_pair(type, valueName);
+}
+
+Result<int> JsonValueParser::parseConstantValue(
+ const std::pair<std::string, std::string>& typeValueName) const {
+ const std::string& type = typeValueName.first;
+ const std::string& valueName = typeValueName.second;
+ auto it = mConstantParsersByType.find(type);
+ if (it == mConstantParsersByType.end()) {
+ return Error() << "Unrecognized type: " << type;
+ }
+ auto result = it->second->parseValue(valueName);
+ if (!result.ok()) {
+ return Error() << type << "::" << valueName << " undefined";
+ }
+ return result;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
+ const std::string& fieldName,
+ bool fieldIsOptional, T* outPtr,
+ std::vector<std::string>* errors) {
+ if (!parentJsonNode.isObject()) {
+ errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+ return false;
+ }
+ if (!parentJsonNode.isMember(fieldName)) {
+ if (!fieldIsOptional) {
+ errors->push_back("Missing required field: " + fieldName +
+ " in node: " + parentJsonNode.toStyledString());
+ return false;
+ }
+ return true;
+ }
+ auto result = mValueParser.parseValue<T>(fieldName, parentJsonNode[fieldName]);
+ if (!result.ok()) {
+ errors->push_back(result.error().message());
+ return false;
+ }
+ *outPtr = std::move(result.value());
+ return true;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
+ const std::string& fieldName,
+ bool fieldIsOptional, std::vector<T>* outPtr,
+ std::vector<std::string>* errors) {
+ if (!parentJsonNode.isObject()) {
+ errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+ return false;
+ }
+ if (!parentJsonNode.isMember(fieldName)) {
+ if (!fieldIsOptional) {
+ errors->push_back("Missing required field: " + fieldName +
+ " in node: " + parentJsonNode.toStyledString());
+ return false;
+ }
+ return true;
+ }
+ auto result = mValueParser.parseArray<T>(fieldName, parentJsonNode[fieldName]);
+ if (!result.ok()) {
+ errors->push_back(result.error().message());
+ return false;
+ }
+ *outPtr = std::move(result.value());
+ return true;
+}
+
+template <class T>
+void JsonConfigParser::parseAccessChangeMode(
+ const Json::Value& parentJsonNode, const std::string& fieldName, int propId,
+ const std::string& propStr, const std::unordered_map<VehicleProperty, T>& defaultMap,
+ T* outPtr, std::vector<std::string>* errors) {
+ if (!parentJsonNode.isObject()) {
+ errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+ return;
+ }
+ if (parentJsonNode.isMember(fieldName)) {
+ auto result = mValueParser.parseValue<int32_t>(fieldName, parentJsonNode[fieldName]);
+ if (!result.ok()) {
+ errors->push_back(result.error().message());
+ return;
+ }
+ *outPtr = static_cast<T>(result.value());
+ return;
+ }
+ auto it = defaultMap.find(static_cast<VehicleProperty>(propId));
+ if (it == defaultMap.end()) {
+ errors->push_back("No " + fieldName + " specified for property: " + propStr);
+ return;
+ }
+ *outPtr = it->second;
+ return;
+}
+
+bool JsonConfigParser::parsePropValues(const Json::Value& parentJsonNode,
+ const std::string& fieldName, RawPropValues* outPtr,
+ std::vector<std::string>* errors) {
+ if (!parentJsonNode.isObject()) {
+ errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+ return false;
+ }
+ if (!parentJsonNode.isMember(fieldName)) {
+ return false;
+ }
+ const Json::Value& jsonValue = parentJsonNode[fieldName];
+ bool success = true;
+ success &= tryParseJsonArrayToVariable(jsonValue, "int32Values",
+ /*optional=*/true, &(outPtr->int32Values), errors);
+ success &= tryParseJsonArrayToVariable(jsonValue, "floatValues",
+ /*optional=*/true, &(outPtr->floatValues), errors);
+ success &= tryParseJsonArrayToVariable(jsonValue, "int64Values",
+ /*optional=*/true, &(outPtr->int64Values), errors);
+ // We don't support "byteValues" yet.
+ success &= tryParseJsonValueToVariable(jsonValue, "stringValue",
+ /*optional=*/true, &(outPtr->stringValue), errors);
+ return success;
+}
+
+void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
+ ConfigDeclaration* config, std::vector<std::string>* errors) {
+ if (!parentJsonNode.isObject()) {
+ errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+ return;
+ }
+ if (!parentJsonNode.isMember(fieldName)) {
+ return;
+ }
+ const Json::Value& jsonValue = parentJsonNode[fieldName];
+
+ if (!jsonValue.isArray()) {
+ errors->push_back("Field: " + fieldName + " is not an array");
+ return;
+ }
+ for (unsigned int i = 0; i < jsonValue.size(); i++) {
+ int32_t areaId;
+ const Json::Value& jsonAreaConfig = jsonValue[i];
+ if (!tryParseJsonValueToVariable(jsonAreaConfig, "areaId",
+ /*optional=*/false, &areaId, errors)) {
+ continue;
+ }
+ VehicleAreaConfig areaConfig = {};
+ areaConfig.areaId = areaId;
+ tryParseJsonValueToVariable(jsonAreaConfig, "minInt32Value", /*optional=*/true,
+ &areaConfig.minInt32Value, errors);
+ tryParseJsonValueToVariable(jsonAreaConfig, "maxInt32Value", /*optional=*/true,
+ &areaConfig.maxInt32Value, errors);
+ tryParseJsonValueToVariable(jsonAreaConfig, "minInt64Value", /*optional=*/true,
+ &areaConfig.minInt64Value, errors);
+ tryParseJsonValueToVariable(jsonAreaConfig, "maxInt64Value", /*optional=*/true,
+ &areaConfig.maxInt64Value, errors);
+ tryParseJsonValueToVariable(jsonAreaConfig, "minFloatValue", /*optional=*/true,
+ &areaConfig.minFloatValue, errors);
+ tryParseJsonValueToVariable(jsonAreaConfig, "maxFloatValue", /*optional=*/true,
+ &areaConfig.maxFloatValue, errors);
+
+ std::vector<int64_t> supportedEnumValues;
+ tryParseJsonArrayToVariable(jsonAreaConfig, "supportedEnumValues", /*optional=*/true,
+ &supportedEnumValues, errors);
+ if (!supportedEnumValues.empty()) {
+ areaConfig.supportedEnumValues = std::move(supportedEnumValues);
+ }
+ config->config.areaConfigs.push_back(std::move(areaConfig));
+
+ RawPropValues areaValue = {};
+ if (parsePropValues(jsonAreaConfig, "defaultValue", &areaValue, errors)) {
+ config->initialAreaValues[areaId] = std::move(areaValue);
+ }
+ }
+}
+
+std::optional<ConfigDeclaration> JsonConfigParser::parseEachProperty(
+ const Json::Value& propJsonValue, std::vector<std::string>* errors) {
+ size_t initialErrorCount = errors->size();
+ ConfigDeclaration configDecl = {};
+ int32_t propId;
+
+ if (!tryParseJsonValueToVariable(propJsonValue, "property", /*optional=*/false, &propId,
+ errors)) {
+ return std::nullopt;
+ }
+
+ configDecl.config.prop = propId;
+ std::string propStr = propJsonValue["property"].toStyledString();
+
+ parseAccessChangeMode(propJsonValue, "access", propId, propStr, AccessForVehicleProperty,
+ &configDecl.config.access, errors);
+
+ parseAccessChangeMode(propJsonValue, "changeMode", propId, propStr,
+ ChangeModeForVehicleProperty, &configDecl.config.changeMode, errors);
+
+ tryParseJsonValueToVariable(propJsonValue, "configString", /*optional=*/true,
+ &configDecl.config.configString, errors);
+
+ tryParseJsonArrayToVariable(propJsonValue, "configArray", /*optional=*/true,
+ &configDecl.config.configArray, errors);
+
+ parsePropValues(propJsonValue, "defaultValue", &configDecl.initialValue, errors);
+
+ tryParseJsonValueToVariable(propJsonValue, "minSampleRate", /*optional=*/true,
+ &configDecl.config.minSampleRate, errors);
+
+ tryParseJsonValueToVariable(propJsonValue, "maxSampleRate", /*optional=*/true,
+ &configDecl.config.maxSampleRate, errors);
+
+ parseAreas(propJsonValue, "areas", &configDecl, errors);
+
+ if (errors->size() != initialErrorCount) {
+ return std::nullopt;
+ }
+ return configDecl;
+}
+
+Result<std::unordered_map<int32_t, ConfigDeclaration>> JsonConfigParser::parseJsonConfig(
+ std::istream& is) {
+ Json::CharReaderBuilder builder;
+ Json::Value root;
+ std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
+ std::string errs;
+ if (!Json::parseFromStream(builder, is, &root, &errs)) {
+ return Error() << "Failed to parse property config file as JSON, error: " << errs;
+ }
+ if (!root.isObject()) {
+ return Error() << "root element must be an object";
+ }
+ if (!root.isMember("properties") || !root["properties"].isArray()) {
+ return Error() << "Missing 'properties' field in root or the field is not an array";
+ }
+ Json::Value properties = root["properties"];
+ std::vector<std::string> errors;
+ for (unsigned int i = 0; i < properties.size(); i++) {
+ if (auto maybeConfig = parseEachProperty(properties[i], &errors); maybeConfig.has_value()) {
+ configsByPropId[maybeConfig.value().config.prop] = std::move(maybeConfig.value());
+ }
+ }
+ if (!errors.empty()) {
+ return Error() << android::base::Join(errors, '\n');
+ }
+ return configsByPropId;
+}
+
+} // namespace jsonconfigloader_impl
+
+JsonConfigLoader::JsonConfigLoader() {
+ mParser = std::make_unique<jsonconfigloader_impl::JsonConfigParser>();
+}
+
+android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
+JsonConfigLoader::loadPropConfig(std::istream& is) {
+ return mParser->parseJsonConfig(is);
+}
+
+android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
+JsonConfigLoader::loadPropConfig(const std::string& configPath) {
+ std::ifstream ifs(configPath.c_str());
+ if (!ifs) {
+ return android::base::Error() << "couldn't open " << configPath << " for parsing.";
+ }
+
+ return loadPropConfig(ifs);
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
new file mode 100644
index 0000000..dae37b9
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "JsonConfigLoaderUnitTest",
+ vendor: true,
+ srcs: ["*.cpp"],
+ static_libs: [
+ "VehicleHalJsonConfigLoader",
+ "VehicleHalUtils",
+ "libgtest",
+ ],
+ shared_libs: [
+ "libjsoncpp",
+ ],
+ defaults: ["VehicleHalDefaults"],
+ test_suites: ["device-tests"],
+}
+
+cc_test {
+ name: "JsonConfigLoaderUnitTestEnableTestProperties",
+ vendor: true,
+ srcs: ["*.cpp"],
+ static_libs: [
+ "VehicleHalJsonConfigLoaderEnableTestProperties",
+ "VehicleHalUtils",
+ "libgtest",
+ ],
+ shared_libs: [
+ "libjsoncpp",
+ ],
+ defaults: ["VehicleHalDefaults"],
+ test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
new file mode 100644
index 0000000..9882653
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
@@ -0,0 +1,705 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <JsonConfigLoader.h>
+
+#include <PropertyUtils.h>
+
+#include <gtest/gtest.h>
+#include <sstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+
+class JsonConfigLoaderUnitTest : public ::testing::Test {
+ protected:
+ JsonConfigLoader mLoader;
+};
+
+TEST_F(JsonConfigLoaderUnitTest, testBasic) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": 291504388
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.prop, 291504388);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testRootNotObject) {
+ std::istringstream iss(R"(
+ []
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok()) << "root is not an object must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMissingPropertiesField) {
+ std::istringstream iss(R"(
+ {
+ "abcd": 1234
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok()) << "Missing 'properties' field must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertiesFieldNotArray) {
+ std::istringstream iss(R"(
+ {
+ "properties': {'a': 'b'}
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "'properties' field is not an array must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertyIsEnum) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.prop, toInt(VehicleProperty::INFO_FUEL_CAPACITY));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertyEnum_FailInvalidEnum) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::BLAH"
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Invalid VehicleProperty enum must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testPropertyEnum_FailInvalidType) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "test"
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Invalid VehicleProperty type must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testProperty_FailInvalidJson) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok()) << "Invalid JSON format must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArray) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configArray": [1, 2, 3]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.configArray, std::vector<int>({1, 2, 3}));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArrayConstants) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configArray": [1, 2, "Constants::FUEL_DOOR_REAR_LEFT"]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.configArray,
+ std::vector<int>({1, 2, FUEL_DOOR_REAR_LEFT}));
+}
+
+// We have special logic to deal with GALLON and US_GALLON since they share the same value.
+TEST_F(JsonConfigLoaderUnitTest, testConfigArrayUnitGallon) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configArray": [1, 2, "VehicleUnit::GALLON"]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArrayUnitUsGallon) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configArray": [1, 2, "VehicleUnit::US_GALLON"]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArray_FailInvalidEnum) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configArray": [1, 2, "VehicleUnits::BLAH"]
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Invalid enum in ConfigArray must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigArray_FailNotArray) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configArray": "123"
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "ConfigArray is not an array must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigString) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configString": "test"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.configString, "test");
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testConfigString_FailNotString) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "configString": 1234
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "ConfigString is not a String must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCheckDefaultAccessChangeMode) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& propConfig = configs.begin()->second.config;
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAccessOverride) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "access": "VehiclePropertyAccess::WRITE"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& propConfig = configs.begin()->second.config;
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
+ ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testChangeModeOverride) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& propConfig = configs.begin()->second.config;
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+ ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCustomProp) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": 1234,
+ "access": "VehiclePropertyAccess::WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& propConfig = configs.begin()->second.config;
+ ASSERT_EQ(propConfig.access, VehiclePropertyAccess::WRITE);
+ ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::ON_CHANGE);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCustomProp_FailMissingAccess) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": 1234,
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Missing access for custom property must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testCustomProp_FailMissingChangeMode) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": 1234,
+ "access": "VehiclePropertyAccess::WRITE"
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Missing change mode for custom property must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMinSampleRate) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "minSampleRate": 1,
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.minSampleRate, 1);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMinSampleRate_FailInvalidType) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "minSampleRate": "abcd",
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Wrong type for MinSampleRate must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMaxSampleRate) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "maxSampleRate": 1,
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.config.maxSampleRate, 1);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testMaxSampleRate_FailInvalidType) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "maxSampleRate": "abcd",
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Wrong type for MaxSampleRate must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_Simple) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "defaultValue": {
+ "int32Values": [1, 2]
+ }
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+ ASSERT_EQ(configs.begin()->second.initialValue.int32Values, std::vector<int32_t>({1, 2}));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_Mixed) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "defaultValue": {
+ "int32Values": [1, "Constants::FUEL_DOOR_REAR_LEFT"],
+ "int64Values": [2, "Constants::FUEL_DOOR_REAR_LEFT"],
+ "floatValues": [3.0, "Constants::FUEL_DOOR_REAR_LEFT"],
+ "stringValue": "abcd"
+ }
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const RawPropValues& initialValue = configs.begin()->second.initialValue;
+ ASSERT_EQ(initialValue.int32Values, std::vector<int32_t>({1, FUEL_DOOR_REAR_LEFT}));
+ ASSERT_EQ(initialValue.int64Values,
+ std::vector<int64_t>({2, static_cast<int64_t>(FUEL_DOOR_REAR_LEFT)}));
+ ASSERT_EQ(initialValue.floatValues,
+ std::vector<float>({3.0, static_cast<float>(FUEL_DOOR_REAR_LEFT)}));
+ ASSERT_EQ(initialValue.stringValue, "abcd");
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_FailNotObject) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "defaultValue": []
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "DefaultValue is not an object must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testDefaultValue_FailInvalidType) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "defaultValue": {
+ "int32Values": [1.1]
+ }
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Wrong type for DefaultValue must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_Simple) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "areas": [{
+ "areaId": "Constants::HVAC_ALL",
+ "minInt32Value": 1,
+ "maxInt32Value": 7
+ }]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.areaConfigs.size(), 1u);
+ const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.minInt32Value, 1);
+ ASSERT_EQ(areaConfig.maxInt32Value, 7);
+ ASSERT_EQ(areaConfig.areaId, HVAC_ALL);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_DefaultValueForEachArea) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "areas": [{
+ "areaId": "Constants::HVAC_LEFT",
+ "defaultValue": {
+ "int32Values": [1]
+ }
+ }, {
+ "areaId": "Constants::HVAC_RIGHT",
+ "defaultValue": {
+ "int32Values": [2]
+ }
+ }]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.areaConfigs.size(), 2u);
+ ASSERT_EQ(config.areaConfigs[0].areaId, HVAC_LEFT);
+ ASSERT_EQ(config.areaConfigs[1].areaId, HVAC_RIGHT);
+ ASSERT_EQ(configs.begin()->second.initialAreaValues[HVAC_LEFT],
+ RawPropValues{.int32Values = {1}});
+ ASSERT_EQ(configs.begin()->second.initialAreaValues[HVAC_RIGHT],
+ RawPropValues{.int32Values = {2}});
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_FailInvalidTypeForOneAreaValue) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "areas": [{
+ "areaId": "Constants::HVAC_LEFT",
+ "defaultValue": {
+ "int32Values": [1]
+ }
+ }, {
+ "areaId": "Constants::HVAC_RIGHT",
+ "defaultValue": {
+ "int32Values": [2.1]
+ }
+ }]
+ }]
+ }
+ )");
+
+ ASSERT_FALSE(mLoader.loadPropConfig(iss).ok())
+ << "Wrong type for DefaultValue for one area must cause error";
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesNoSupportedEnumValuesDeclared) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+ "areas": [{
+ "areaId": 0,
+ }]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+ ASSERT_TRUE(result.ok());
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+ const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.areaId, 0);
+ ASSERT_FALSE(areaConfig.supportedEnumValues);
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesSupportedEnumValues) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+ "areas": [{
+ "areaId": 0,
+ "supportedEnumValues": ["Constants::LIGHT_STATE_ON", "Constants::LIGHT_STATE_OFF"]
+ }]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+ ASSERT_TRUE(result.ok());
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+ const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.areaId, 0);
+ ASSERT_TRUE(areaConfig.supportedEnumValues);
+ ASSERT_EQ(areaConfig.supportedEnumValues.value().size(), 2u);
+ ASSERT_EQ(areaConfig.supportedEnumValues.value(),
+ std::vector<int64_t>({LIGHT_STATE_ON, LIGHT_STATE_OFF}));
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_HandlesEmptySupportedEnumValues) {
+ std::istringstream iss(R"(
+ {
+ "properties": [{
+ "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+ "areas": [{
+ "areaId": 0,
+ "supportedEnumValues": []
+ }]
+ }]
+ }
+ )");
+
+ auto result = mLoader.loadPropConfig(iss);
+ ASSERT_TRUE(result.ok());
+
+ auto configs = result.value();
+ ASSERT_EQ(configs.size(), 1u);
+
+ const VehiclePropConfig& config = configs.begin()->second.config;
+ ASSERT_EQ(config.areaConfigs.size(), 1u);
+
+ const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+ ASSERT_EQ(areaConfig.areaId, 0);
+ ASSERT_FALSE(areaConfig.supportedEnumValues);
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/default_config/config/Android.bp b/automotive/vehicle/aidl/impl/default_config/config/Android.bp
new file mode 100644
index 0000000..8f1c7d1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/Android.bp
@@ -0,0 +1,47 @@
+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"],
+}
+
+filegroup {
+ name: "VehicleHalDefaultProperties_JSON",
+ srcs: ["DefaultProperties.json"],
+}
+
+filegroup {
+ name: "VehicleHalTestProperties_JSON",
+ srcs: ["TestProperties.json"],
+}
+
+filegroup {
+ name: "VehicleHalVendorClusterTestProperties_JSON",
+ srcs: ["VendorClusterTestProperties.json"],
+}
+
+prebuilt_etc {
+ name: "Prebuilt_VehicleHalDefaultProperties_JSON",
+ filename_from_src: true,
+ src: "DefaultProperties.json",
+ sub_dir: "automotive/vhalconfig/",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "Prebuilt_VehicleHalTestProperties_JSON",
+ filename_from_src: true,
+ src: "TestProperties.json",
+ sub_dir: "automotive/vhalconfig/",
+ vendor: true,
+}
+
+prebuilt_etc {
+ name: "Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
+ filename_from_src: true,
+ src: "VendorClusterTestProperties.json",
+ sub_dir: "automotive/vhalconfig/",
+ vendor: true,
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
new file mode 100644
index 0000000..ae36290
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -0,0 +1,3818 @@
+{
+ "apiVersion": 1,
+ "properties": [
+ {
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ "defaultValue": {
+ "floatValues": [
+ 15000.0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_FUEL_TYPE",
+ "defaultValue": {
+ "int32Values": [
+ "FuelType::FUEL_TYPE_UNLEADED"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_EV_BATTERY_CAPACITY",
+ "defaultValue": {
+ "floatValues": [
+ 150000.0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_EV_CONNECTOR_TYPE",
+ "defaultValue": {
+ "int32Values": [
+ "EvConnectorType::IEC_TYPE_1_AC"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_FUEL_DOOR_LOCATION",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::FUEL_DOOR_REAR_LEFT"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_EV_PORT_LOCATION",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::CHARGE_PORT_FRONT_LEFT"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::CHARGE_PORT_FRONT_LEFT",
+ "Constants::CHARGE_PORT_REAR_LEFT"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_VIN",
+ "defaultValue": {
+ "stringValue": "1GCARVIN123456789"
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_MAKE",
+ "defaultValue": {
+ "stringValue": "Toy Vehicle"
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_MODEL",
+ "defaultValue": {
+ "stringValue": "Speedy Model"
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_MODEL_YEAR",
+ "defaultValue": {
+ "int32Values": [
+ 2023
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::INFO_EXTERIOR_DIMENSIONS",
+ "defaultValue": {
+ "int32Values": [
+ 1776,
+ 4950,
+ 2008,
+ 2140,
+ 2984,
+ 1665,
+ 1667,
+ 11800
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::PERF_VEHICLE_SPEED",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleUnit::MILES_PER_HOUR"
+ ]
+ },
+ "configArray": [
+ "VehicleUnit::METER_PER_SEC",
+ "VehicleUnit::MILES_PER_HOUR",
+ "VehicleUnit::KILOMETERS_PER_HOUR"
+ ]
+ },
+ {
+ "property": "VehicleProperty::EV_BATTERY_DISPLAY_UNITS",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleUnit::KILOWATT_HOUR"
+ ]
+ },
+ "configArray": [
+ "VehicleUnit::WATT_HOUR",
+ "VehicleUnit::AMPERE_HOURS",
+ "VehicleUnit::KILOWATT_HOUR"
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_MEMORY_SELECT",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_MEMORY_SET",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BELT_BUCKLED",
+ "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_BELT_HEIGHT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 10
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BELT_HEIGHT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_FORE_AFT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_FORE_AFT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEIGHT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEIGHT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_DEPTH_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_DEPTH_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_TILT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_TILT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEADREST_ANGLE_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEADREST_ANGLE_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_OFF"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "supportedEnumValues": [
+ "Constants::LIGHT_STATE_OFF",
+ "Constants::LIGHT_STATE_ON"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "supportedEnumValues": [
+ "Constants::LIGHT_STATE_OFF",
+ "Constants::LIGHT_STATE_ON"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+ "supportedEnumValues": [
+ "Constants::LIGHT_STATE_OFF",
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_OFF"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "supportedEnumValues": [
+ "Constants::LIGHT_SWITCH_OFF",
+ "Constants::LIGHT_SWITCH_ON",
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "supportedEnumValues": [
+ "Constants::LIGHT_SWITCH_OFF",
+ "Constants::LIGHT_SWITCH_ON",
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+ "supportedEnumValues": [
+ "Constants::LIGHT_SWITCH_OFF",
+ "Constants::LIGHT_SWITCH_ON",
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_EASY_ACCESS_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT"
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_AIRBAG_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT"
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_WALK_IN_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 5
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 5
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_OCCUPANCY",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleSeatOccupancyState::VACANT"
+ ]
+ },
+ "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::INFO_DRIVER_SEAT",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::SEAT_1_LEFT"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::PERF_ODOMETER",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::PERF_STEERING_ANGLE",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::PERF_REAR_STEERING_ANGLE",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::ENGINE_RPM",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::FUEL_LEVEL",
+ "defaultValue": {
+ "floatValues": [
+ 15000.0
+ ]
+ },
+ "maxSampleRate": 100.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::FUEL_DOOR_OPEN",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_BATTERY_LEVEL",
+ "defaultValue": {
+ "floatValues": [
+ 150000.0
+ ]
+ },
+ "maxSampleRate": 100.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::EV_CURRENT_BATTERY_CAPACITY",
+ "defaultValue": {
+ "floatValues": [
+ 150000.0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_PORT_OPEN",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_PORT_CONNECTED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT",
+ "defaultValue": {
+ "floatValues": [
+ 12.5
+ ]
+ },
+ "comment": "ConfigArray specifies Max current draw allowed by vehicle in amperes",
+ "configArray": [
+ 20
+ ]
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_PERCENT_LIMIT",
+ "defaultValue": {
+ "floatValues": [
+ 40.0
+ ]
+ },
+ "configArray": [
+ 20,
+ 40,
+ 60,
+ 80,
+ 100
+ ]
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_STATE",
+ "defaultValue": {
+ "int32Values": [
+ 2
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_CHARGE_TIME_REMAINING",
+ "defaultValue": {
+ "int32Values": [
+ 20
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::EV_REGENERATIVE_BRAKING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ 2
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::TRAILER_PRESENT",
+ "defaultValue": {
+ "int32Values": [
+ 2
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::VEHICLE_CURB_WEIGHT",
+ "defaultValue": {
+ "int32Values": [
+ 2211
+ ]
+ },
+ "configArray": [
+ 2948
+ ],
+ "comment": "unit is kg"
+ },
+ {
+ "property": "VehicleProperty::RANGE_REMAINING",
+ "defaultValue": {
+ "floatValues": [
+ 50000.0
+ ]
+ },
+ "comment": "units in meter",
+ "maxSampleRate": 2.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::TIRE_PRESSURE",
+ "defaultValue": {
+ "floatValues": [
+ 200.0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::WHEEL_FRONT_LEFT",
+ "minFloatValue": 193.0,
+ "maxFloatValue": 300.0
+ },
+ {
+ "areaId": "Constants::WHEEL_FRONT_RIGHT",
+ "minFloatValue": 193.0,
+ "maxFloatValue": 300.0
+ },
+ {
+ "areaId": "Constants::WHEEL_REAR_LEFT",
+ "minFloatValue": 193.0,
+ "maxFloatValue": 300.0
+ },
+ {
+ "areaId": "Constants::WHEEL_REAR_RIGHT",
+ "minFloatValue": 193.0,
+ "maxFloatValue": 300.0
+ }
+ ],
+ "comment": "Units in kpa",
+ "maxSampleRate": 2.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE",
+ "areas": [
+ {
+ "defaultValue": {
+ "floatValues": [
+ 137.0
+ ]
+ },
+ "areaId": "Constants::WHEEL_FRONT_LEFT"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 137.0
+ ]
+ },
+ "areaId": "Constants::WHEEL_FRONT_RIGHT"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 137.0
+ ]
+ },
+ "areaId": "Constants::WHEEL_REAR_RIGHT"
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 137.0
+ ]
+ },
+ "areaId": "Constants::WHEEL_REAR_LEFT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleUnit::PSI"
+ ]
+ },
+ "configArray": [
+ "VehicleUnit::KILOPASCAL",
+ "VehicleUnit::PSI",
+ "VehicleUnit::BAR"
+ ]
+ },
+ {
+ "property": "VehicleProperty::CURRENT_GEAR",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleGear::GEAR_PARK"
+ ]
+ },
+ "configArray": [
+ "VehicleGear::GEAR_PARK",
+ "VehicleGear::GEAR_NEUTRAL",
+ "VehicleGear::GEAR_REVERSE",
+ "VehicleGear::GEAR_1",
+ "VehicleGear::GEAR_2",
+ "VehicleGear::GEAR_3",
+ "VehicleGear::GEAR_4",
+ "VehicleGear::GEAR_5"
+ ]
+ },
+ {
+ "property": "VehicleProperty::PARKING_BRAKE_ON",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::PARKING_BRAKE_AUTO_APPLY",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EV_BRAKE_REGENERATION_LEVEL",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::EV_STOPPING_MODE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::EV_STOPPING_MODE_CREEP"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "Constants::EV_STOPPING_MODE_CREEP",
+ "Constants::EV_STOPPING_MODE_ROLL",
+ "Constants::EV_STOPPING_MODE_HOLD"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::FUEL_LEVEL_LOW",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleUnit::US_GALLON"
+ ]
+ },
+ "configArray": [
+ "VehicleUnit::LITER",
+ "VehicleUnit::US_GALLON"
+ ]
+ },
+ {
+ "property": "VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HW_KEY_INPUT",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HW_KEY_INPUT_V2",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "int64Values": [
+ 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::HW_MOTION_INPUT",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0
+ ],
+ "floatValues": [
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "int64Values": [
+ 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::HW_ROTARY_INPUT",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HW_CUSTOM_INPUT",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "configArray": [
+ 0,
+ 0,
+ 0,
+ 3,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]
+ },
+ {
+ "property": "VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM",
+ "defaultValue": {
+ "int32Values": [
+ 50
+ ]
+ },
+ "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::HVAC_POWER_ON",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "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"
+ }
+ ],
+ "configArray": [
+ "VehicleProperty::HVAC_FAN_SPEED",
+ "VehicleProperty::HVAC_FAN_DIRECTION"
+ ]
+ },
+ {
+ "property": "VehicleProperty::HVAC_DEFROSTER",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
+ },
+ {
+ "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
+ }
+ ],
+ "comment": "0 means using for all areas"
+ },
+ {
+ "property": "VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
+ },
+ {
+ "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
+ }
+ ],
+ "comment": "0 means using for all areas"
+ },
+ {
+ "property": "VehicleProperty::HVAC_MAX_DEFROST_ON",
+ "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::HVAC_RECIRC_ON",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "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::HVAC_AUTO_RECIRC_ON",
+ "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::HVAC_AC_ON",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "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::HVAC_MAX_AC_ON",
+ "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::HVAC_AUTO_ON",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "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::HVAC_DUAL_ON",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::HVAC_ALL"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::HVAC_FAN_SPEED",
+ "defaultValue": {
+ "int32Values": [
+ 3
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 1,
+ "maxInt32Value": 7
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 1,
+ "maxInt32Value": 7
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": 1,
+ "maxInt32Value": 7
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": 1,
+ "maxInt32Value": 7
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": 1,
+ "maxInt32Value": 7
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::HVAC_FAN_DIRECTION",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleHvacFanDirection::FACE"
+ ]
+ },
+ "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::HVAC_FAN_DIRECTION_AVAILABLE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::FAN_DIRECTION_FACE",
+ "Constants::FAN_DIRECTION_FLOOR",
+ "Constants::FAN_DIRECTION_FACE_FLOOR",
+ "Constants::FAN_DIRECTION_DEFROST",
+ "Constants::FAN_DIRECTION_FACE_DEFROST",
+ "Constants::FAN_DIRECTION_FLOOR_DEFROST",
+ "Constants::FAN_DIRECTION_FLOOR_DEFROST_FACE"
+ ]
+ },
+ "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::HVAC_SEAT_VENTILATION",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": 0,
+ "maxInt32Value": 3
+ }
+ ],
+ "comment": "0 is off and +ve values indicate ventilation level."
+ },
+ {
+ "property": "VehicleProperty::HVAC_STEERING_WHEEL_HEAT",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ }
+ ],
+ "comment": "+ve values for heating and -ve for cooling"
+ },
+ {
+ "property": "VehicleProperty::HVAC_SEAT_TEMPERATURE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ }
+ ],
+ "comment": "+ve values for heating and -ve for cooling"
+ },
+ {
+ "property": "VehicleProperty::HVAC_SIDE_MIRROR_HEAT",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 2
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
+ "defaultValue": {
+ "floatValues": [
+ 19.1
+ ]
+ },
+ "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::HVAC_TEMPERATURE_SET",
+ "defaultValue": {
+ "floatValues": [
+ 17.0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "minFloatValue": 16.0,
+ "maxFloatValue": 28.0
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minFloatValue": 16.0,
+ "maxFloatValue": 28.0
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "minFloatValue": 16.0,
+ "maxFloatValue": 28.0
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "minFloatValue": 16.0,
+ "maxFloatValue": 28.0
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER",
+ "minFloatValue": 16.0,
+ "maxFloatValue": 28.0
+ }
+ ],
+ "comment":
+ "minFloatValue and maxFloatValue in area config should match corresponding values in configArray",
+ "configArray": [
+ 160,
+ 280,
+ 5,
+ 600,
+ 840,
+ 10
+ ]
+ },
+ {
+ "property": "VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION",
+ "defaultValue": {
+ "floatValues": [
+ 66.19999694824219,
+ "VehicleUnit::FAHRENHEIT",
+ 19.0,
+ 66.0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::ENV_OUTSIDE_TEMPERATURE",
+ "defaultValue": {
+ "floatValues": [
+ 25.0
+ ]
+ },
+ "maxSampleRate": 2.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleUnit::FAHRENHEIT"
+ ]
+ },
+ "configArray": [
+ "VehicleUnit::FAHRENHEIT",
+ "VehicleUnit::CELSIUS"
+ ]
+ },
+ {
+ "property": "VehicleProperty::DISTANCE_DISPLAY_UNITS",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleUnit::MILE"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0
+ }
+ ],
+ "configArray": [
+ "VehicleUnit::KILOMETER",
+ "VehicleUnit::MILE"
+ ]
+ },
+ {
+ "property": "VehicleProperty::NIGHT_MODE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::GEAR_SELECTION",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleGear::GEAR_PARK"
+ ]
+ },
+ "configArray": [
+ "VehicleGear::GEAR_PARK",
+ "VehicleGear::GEAR_NEUTRAL",
+ "VehicleGear::GEAR_REVERSE",
+ "VehicleGear::GEAR_DRIVE",
+ "VehicleGear::GEAR_1",
+ "VehicleGear::GEAR_2",
+ "VehicleGear::GEAR_3",
+ "VehicleGear::GEAR_4",
+ "VehicleGear::GEAR_5"
+ ]
+ },
+ {
+ "property": "VehicleProperty::TURN_SIGNAL_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleTurnSignal::NONE"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::IGNITION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleIgnitionState::ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::ENGINE_COOLANT_TEMP",
+ "defaultValue": {
+ "floatValues": [
+ 75.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::ENGINE_OIL_LEVEL",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleOilLevel::NORMAL"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::ENGINE_OIL_TEMP",
+ "defaultValue": {
+ "floatValues": [
+ 101.0
+ ]
+ },
+ "maxSampleRate": 10.0,
+ "minSampleRate": 0.10000000149011612
+ },
+ {
+ "property": "VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DOOR_LOCK",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "Constants::DOOR_1_LEFT"
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "Constants::DOOR_1_RIGHT"
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "Constants::DOOR_2_LEFT"
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "Constants::DOOR_2_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DOOR_CHILD_LOCK_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::DOOR_2_LEFT"
+ },
+ {
+ "areaId": "Constants::DOOR_2_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DOOR_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::DOOR_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_REAR",
+ "minInt32Value": 0,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DOOR_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::DOOR_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::DOOR_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::MIRROR_Z_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+ "minInt32Value": -3,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+ "minInt32Value": -3,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+ "minInt32Value": -3,
+ "maxInt32Value": 3
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::MIRROR_Z_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::MIRROR_Y_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+ "minInt32Value": -3,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+ "minInt32Value": -3,
+ "maxInt32Value": 3
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+ "minInt32Value": -3,
+ "maxInt32Value": 3
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::MIRROR_Y_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::MIRROR_LOCK",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::MIRROR_FOLD",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::MIRROR_AUTO_FOLD_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::MIRROR_AUTO_TILT_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WINDOW_LOCK",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areaId": "Constants::WINDOW_1_RIGHT_2_LEFT_2_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WINDOW_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::WINDOW_1_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::WINDOW_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::WINDOW_2_LEFT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::WINDOW_2_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ },
+ {
+ "areaId": "Constants::WINDOW_ROOF_TOP_1",
+ "minInt32Value": -10,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WINDOW_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::WINDOW_1_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::WINDOW_1_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::WINDOW_2_LEFT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::WINDOW_2_RIGHT",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ },
+ {
+ "areaId": "Constants::WINDOW_ROOF_TOP_1",
+ "minInt32Value": -1,
+ "maxInt32Value": 1
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WINDSHIELD_WIPERS_PERIOD",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+ "minInt32Value": 0,
+ "maxInt32Value": 3000
+ },
+ {
+ "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+ "minInt32Value": 0,
+ "maxInt32Value": 3000
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WINDSHIELD_WIPERS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "WindshieldWipersState::OFF"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+ "supportedEnumValues": [
+ "WindshieldWipersState::OFF",
+ "WindshieldWipersState::ON",
+ "WindshieldWipersState::SERVICE"
+ ]
+ },
+ {
+ "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+ "supportedEnumValues": [
+ "WindshieldWipersState::OFF",
+ "WindshieldWipersState::ON"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WINDSHIELD_WIPERS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "WindshieldWipersSwitch::OFF"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+ "supportedEnumValues": [
+ "WindshieldWipersSwitch::OFF",
+ "WindshieldWipersSwitch::MIST",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_1",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_2",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_3",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_4",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_5",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_1",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_3",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_4",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_5",
+ "WindshieldWipersSwitch::AUTO",
+ "WindshieldWipersSwitch::SERVICE"
+ ]
+ },
+ {
+ "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+ "supportedEnumValues": [
+ "WindshieldWipersSwitch::OFF",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_1",
+ "WindshieldWipersSwitch::INTERMITTENT_LEVEL_2",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_1",
+ "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
+ "WindshieldWipersSwitch::AUTO",
+ "WindshieldWipersSwitch::SERVICE"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_DEPTH_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_DEPTH_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": -2,
+ "maxInt32Value": 2
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_LOCKED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::GLOVE_BOX_DOOR_POS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "minInt32Value": 0,
+ "maxInt32Value": 10
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::GLOVE_BOX_LOCKED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_RIGHT"
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::WHEEL_TICK",
+ "defaultValue": {
+ "int64Values": [
+ 0,
+ 100000,
+ 200000,
+ 300000,
+ 400000
+ ]
+ },
+ "configArray": [
+ 15,
+ 50000,
+ 50000,
+ 50000,
+ 50000
+ ],
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::ABS_ACTIVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::TRACTION_CONTROL_ACTIVE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::AP_POWER_STATE_REQ",
+ "configArray": [
+ 0
+ ]
+ },
+ {
+ "property": "VehicleProperty::AP_POWER_STATE_REPORT",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleApPowerStateReport::WAIT_FOR_VHAL",
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DISPLAY_BRIGHTNESS",
+ "defaultValue": {
+ "int32Values": [
+ 100
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": 0,
+ "maxInt32Value": 100
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::OBD2_LIVE_FRAME",
+ "configArray": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "property": "VehicleProperty::OBD2_FREEZE_FRAME",
+ "configArray": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "property": "VehicleProperty::OBD2_FREEZE_FRAME_INFO"
+ },
+ {
+ "property": "VehicleProperty::OBD2_FREEZE_FRAME_CLEAR",
+ "configArray": [
+ 1
+ ]
+ },
+ {
+ "property": "VehicleProperty::HEADLIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HIGH_BEAM_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::FRONT_FOG_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::REAR_FOG_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HAZARD_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::READING_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ },
+ "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::STEERING_WHEEL_LIGHTS_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_STATE_ON"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "Constants::LIGHT_STATE_OFF",
+ "Constants::LIGHT_STATE_ON"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::HEADLIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::FRONT_FOG_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::REAR_FOG_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HAZARD_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_OFF"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::READING_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_OFF"
+ ]
+ },
+ "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::STEERING_WHEEL_LIGHTS_SWITCH",
+ "defaultValue": {
+ "int32Values": [
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "Constants::LIGHT_SWITCH_OFF",
+ "Constants::LIGHT_SWITCH_ON",
+ "Constants::LIGHT_SWITCH_AUTO"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::EVS_SERVICE_REQUEST",
+ "defaultValue": {
+ "int32Values": [
+ "EvsServiceType::REARVIEW",
+ "EvsServiceState::OFF"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::VEHICLE_MAP_SERVICE"
+ },
+ {
+ "property": "VehicleProperty::LOCATION_CHARACTERIZATION",
+ "defaultValue": {
+ "int32Values": [
+ "LocationCharacterization::RAW_GNSS_ONLY"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "EmergencyLaneKeepAssistState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "EmergencyLaneKeepAssistState::ENABLED",
+ "EmergencyLaneKeepAssistState::WARNING_LEFT",
+ "EmergencyLaneKeepAssistState::WARNING_RIGHT",
+ "EmergencyLaneKeepAssistState::ACTIVATED_STEER_LEFT",
+ "EmergencyLaneKeepAssistState::ACTIVATED_STEER_RIGHT",
+ "EmergencyLaneKeepAssistState::USER_OVERRIDE"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::CRUISE_CONTROL_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::CRUISE_CONTROL_TYPE",
+ "defaultValue": {
+ "int32Values": [
+ "CruiseControlType::STANDARD"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "CruiseControlType::STANDARD",
+ "CruiseControlType::ADAPTIVE",
+ "CruiseControlType::PREDICTIVE"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::CRUISE_CONTROL_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "CruiseControlState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "CruiseControlState::ENABLED",
+ "CruiseControlState::ACTIVATED",
+ "CruiseControlState::USER_OVERRIDE",
+ "CruiseControlState::SUSPENDED",
+ "CruiseControlState::FORCED_DEACTIVATION_WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::CRUISE_CONTROL_COMMAND",
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "CruiseControlCommand::ACTIVATE",
+ "CruiseControlCommand::SUSPEND",
+ "CruiseControlCommand::INCREASE_TARGET_SPEED",
+ "CruiseControlCommand::DECREASE_TARGET_SPEED",
+ "CruiseControlCommand::INCREASE_TARGET_TIME_GAP",
+ "CruiseControlCommand::DECREASE_TARGET_TIME_GAP"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::CRUISE_CONTROL_TARGET_SPEED",
+ "defaultValue": {
+ "floatValues": [
+ 25.0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minFloatValue": 20.0,
+ "maxFloatValue": 35.0
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
+ "defaultValue": {
+ "int32Values": [
+ 1200
+ ]
+ },
+ "configArray": [
+ 1200,
+ 1400,
+ 1600,
+ 1800,
+ 2000,
+ 2200
+ ]
+ },
+ {
+ "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE",
+ "defaultValue": {
+ "int32Values": [
+ 100000
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "minInt32Value": 0,
+ "maxInt32Value": 200000
+ }
+ ],
+ "maxSampleRate": 10.0,
+ "minSampleRate": 1.0
+ },
+ {
+ "property": "VehicleProperty::HANDS_ON_DETECTION_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "HandsOnDetectionDriverState::HANDS_ON"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "HandsOnDetectionDriverState::HANDS_ON",
+ "HandsOnDetectionDriverState::HANDS_OFF"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::HANDS_ON_DETECTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "HandsOnDetectionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "HandsOnDetectionWarning::NO_WARNING",
+ "HandsOnDetectionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::INITIAL_USER_INFO"
+ },
+ {
+ "property": "VehicleProperty::SWITCH_USER"
+ },
+ {
+ "property": "VehicleProperty::CREATE_USER"
+ },
+ {
+ "property": "VehicleProperty::REMOVE_USER"
+ },
+ {
+ "property": "VehicleProperty::USER_IDENTIFICATION_ASSOCIATION"
+ },
+ {
+ "property": "VehicleProperty::POWER_POLICY_REQ"
+ },
+ {
+ "property": "VehicleProperty::POWER_POLICY_GROUP_REQ"
+ },
+ {
+ "property": "VehicleProperty::CURRENT_POWER_POLICY"
+ },
+ {
+ "property": "VehicleProperty::ANDROID_EPOCH_TIME"
+ },
+ {
+ "property": "VehicleProperty::WATCHDOG_ALIVE"
+ },
+ {
+ "property": "VehicleProperty::WATCHDOG_TERMINATED_PROCESS"
+ },
+ {
+ "property": "VehicleProperty::VHAL_HEARTBEAT"
+ },
+ {
+ "property": "VehicleProperty::CLUSTER_SWITCH_UI",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "comment": "0 means ClusterHome"
+ },
+ {
+ "property": "VehicleProperty::CLUSTER_DISPLAY_STATE",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1
+ ]
+ },
+ "comment":
+ "Value means: 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */"
+ },
+ {
+ "property": "VehicleProperty::CLUSTER_REPORT_STATE",
+ "configArray": [
+ 0,
+ 0,
+ 0,
+ 11,
+ 0,
+ 0,
+ 0,
+ 0,
+ 16
+ ]
+ },
+ {
+ "property": "VehicleProperty::CLUSTER_REQUEST_DISPLAY"
+ },
+ {
+ "property": "VehicleProperty::CLUSTER_NAVIGATION_STATE"
+ },
+ {
+ "property": "VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
+ "defaultValue": {
+ "int32Values": [
+ "GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1"
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "ErrorState::NOT_AVAILABLE_DISABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "AutomaticEmergencyBrakingState::ENABLED",
+ "AutomaticEmergencyBrakingState::ACTIVATED",
+ "AutomaticEmergencyBrakingState::USER_OVERRIDE"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::FORWARD_COLLISION_WARNING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "ForwardCollisionWarningState::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "ForwardCollisionWarningState::NO_WARNING",
+ "ForwardCollisionWarningState::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::BLIND_SPOT_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::BLIND_SPOT_WARNING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "BlindSpotWarningState::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "BlindSpotWarningState::NO_WARNING",
+ "BlindSpotWarningState::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LANE_DEPARTURE_WARNING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LaneDepartureWarningState::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LaneDepartureWarningState::NO_WARNING",
+ "LaneDepartureWarningState::WARNING_LEFT",
+ "LaneDepartureWarningState::WARNING_RIGHT"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::LANE_KEEP_ASSIST_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LANE_KEEP_ASSIST_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LaneKeepAssistState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LaneKeepAssistState::ENABLED",
+ "LaneKeepAssistState::ACTIVATED_STEER_LEFT",
+ "LaneKeepAssistState::ACTIVATED_STEER_RIGHT",
+ "LaneKeepAssistState::USER_OVERRIDE"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::LANE_CENTERING_ASSIST_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LANE_CENTERING_ASSIST_COMMAND"
+ },
+ {
+ "property": "VehicleProperty::LANE_CENTERING_ASSIST_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LaneCenteringAssistState::ENABLED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LaneCenteringAssistState::ENABLED",
+ "LaneCenteringAssistState::ACTIVATION_REQUESTED",
+ "LaneCenteringAssistState::ACTIVATED",
+ "LaneCenteringAssistState::USER_OVERRIDE",
+ "LaneCenteringAssistState::FORCED_DEACTIVATION_WARNING"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/config/README.md b/automotive/vehicle/aidl/impl/default_config/config/README.md
new file mode 100644
index 0000000..6e82de5
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/README.md
@@ -0,0 +1,171 @@
+# Property Configuration Files
+
+Each JSON file in this folder is a property configuration file for reference
+Vehicle HAL. They contain VehiclePropConfig information along with initial
+value information.
+
+## JSON schema
+
+Each JSON file must be in a schema like the following example:
+(The comment starting with "//" is for documentation only and must be removed
+from the actual JSON file. The "comment" field is used for comment in the
+actual JSON file and will be ignored by the parser)
+
+```
+{
+ // (number) The version for the JSON schema.
+ "apiVersion": 1,
+ // (non-empty array of objects) The property configuration list.
+ //
+ // Each object is a configuration for one property.
+ "properties": [
+ {
+ // (number/string) The ID for the property.
+ // This value is defined in a string value
+ // which represents a constant value, see the "JSON Number-type
+ // Field Values" section for detail.
+ "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+ // (optional, number/string) The access mode for the property.
+ // If specified, this overwrite the default access mode specified in
+ // VehicleProperty.aidl. Must be specified for vendor properties.
+ "access": "VehiclePropertyAccess::READ",
+ // (optional, number/string) The change mode for the property.
+ // If specified, this overwrite the default change mode specified in
+ // VehicleProperty.aidl. Must be specified for vendor properties.
+ "changeMode": "VehiclePropertyChangeMode::STATIC",
+ // (optional, string) The config string.
+ "configString": "blahblah",
+ // (optional, array of number/string) The config array.
+ "configArray": [1, 2, "Constants::HVAC_ALL"],
+ // (optional, object) The default value for the property.
+ // If not specified, the property will be shown as unavailable
+ // until its value is set.
+ "defaultValue": {
+ // (optional, array of int number/string) Int values.
+ "int32Values": [1, 2, "Constants::HVAC_ALL"],
+ // (optional, array of int number/string) Long values.
+ "int64Values": [1, 2],
+ // (optional, array of float number/string) Float values.
+ "floatValues": [1.1, 2.2],
+ // (optional, string) String value.
+ "stringValue": "test"
+ },
+ // (optional, number/string) The minimum sample rate in HZ.
+ // Only work for VehiclePropertyChangeMode::CONTINUOUS property.
+ // Must be specified for continuous property.
+ "minSampleRate": 1,
+ // (optional, number/string) The maximum sample rate in HZ.
+ // Only work for VehiclePropertyChangeMode::CONTINUOUS property.
+ // Must be specified for continuous property.
+ "maxSampleRate": 10,
+ // (optional, array of objects) The area configs.
+ "areas:" [
+ {
+ // (number/string) The area ID.
+ "areaId": "Constants::DOOR_1_LEFT",
+ // (optional number/string) The minimum int value.
+ "minInt32Value": 1,
+ // (optional number/string) The maximum int value.
+ "maxInt32Value": 10,
+ // (optional number/string) The minimum long value.
+ "minInt64Value": 1,
+ // (optional number/string) The maximum long value.
+ "maxInt64Value": 10,
+ // (optional number/string) The minimum float value.
+ "minFloatValue": 1,
+ // (optional number/string) The maximum float value.
+ "maxFloatValue": 10,
+ // (optional object) The default value for this area.
+ // Uses the same format as the "defaultValue" field for
+ // property object. If specified, this overwrite the global
+ // defaultValue.
+ "defaultValue": {
+ "int32Values": [1, 2, "Constants::HVAC_ALL"],
+ "int64Values": [1, 2],
+ "floatValues": [1.1, 2.2],
+ "stringValue": "test"
+ }
+ }
+ ]
+ }
+ ]
+}
+```
+
+## JSON Number-type Field Values
+
+For number type field values, they can either be defined as a numeric number,
+e.g., `{"minInt32Value": 1}` or be defined as a string which represents a
+defined constant value, e.g.,
+`{"property": "VehicleProperty::INFO_FUEL_CAPACITY"}`.
+
+For constant values, they must be a string in the format of `XXX::XXX`, where
+the field before `::` is the constant type, and the field after `::` is the
+variable name.
+
+We support the following constant types:
+
+* VehiclePropertyAccess
+
+* VehiclePropertyChangeMode
+
+* VehicleGear
+
+* VehicleAreaWindow
+
+* VehicleOilLevel
+
+* VehicleUnit
+
+* VehicleSeatOccupancyState
+
+* VehicleHvacFanDirection
+
+* VehicleApPowerStateReport
+
+* VehicleTurnSignal
+
+* VehicleVendorPermission
+
+* EvsServiceType
+
+* EvsServiceState
+
+* EvConnectorType
+
+* VehicleProperty
+
+* GsrComplianceRequirementType
+
+* VehicleIgnitionState
+
+* FuelType
+
+* AutomaticEmergencyBrakingState
+
+* ForwardCollisionWarningState
+
+* BlindSpotWarningState
+
+* LaneDepartureWarningState
+
+* LaneKeepAssistState
+
+* LaneCenteringAssistCommand
+
+* LaneCenteringAssistState
+
+* ErrorState
+
+* WindshieldWipersState
+
+* WindshieldWipersSwitch
+
+* Constants
+
+Every constant type except "Constants" corresponds to a enum defined in Vehicle
+HAL interfac. E.g. "VehicleProperty" corresponds to the enums defined in
+"VehicleProperty.aidl".
+
+"Constants" type refers to the constant variables defined in the paresr.
+Specifically, the "CONSTANTS_BY_NAME" map defined in "JsonConfigLoader.cpp".
diff --git a/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json b/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
new file mode 100644
index 0000000..fd4b002
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
@@ -0,0 +1,209 @@
+{
+ "properties": [
+ {
+ "property": "Constants::kMixedTypePropertyForTest",
+ "defaultValue": {
+ "floatValues": [
+ 4.5
+ ],
+ "int32Values": [
+ 1,
+ 2,
+ 3
+ ],
+ "stringValue": "MIXED property"
+ },
+ "configArray": [
+ 1,
+ 1,
+ 0,
+ 2,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0
+ ],
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_EXTENSION_BOOLEAN_PROPERTY",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "Constants::DOOR_1_LEFT"
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "Constants::DOOR_1_RIGHT"
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areaId": "Constants::DOOR_2_LEFT"
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areaId": "Constants::DOOR_2_RIGHT"
+ }
+ ],
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_EXTENSION_FLOAT_PROPERTY",
+ "areas": [
+ {
+ "defaultValue": {
+ "floatValues": [
+ 1.0
+ ]
+ },
+ "areaId": "Constants::HVAC_LEFT",
+ "minFloatValue": -10.0,
+ "maxFloatValue": 10.0
+ },
+ {
+ "defaultValue": {
+ "floatValues": [
+ 2.0
+ ]
+ },
+ "areaId": "Constants::HVAC_RIGHT",
+ "minFloatValue": -10.0,
+ "maxFloatValue": 10.0
+ }
+ ],
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_EXTENSION_INT_PROPERTY",
+ "areas": [
+ {
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+ "minInt32Value": -100,
+ "maxInt32Value": 100
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+ "minInt32Value": -100,
+ "maxInt32Value": 100
+ },
+ {
+ "defaultValue": {
+ "int32Values": [
+ -1
+ ]
+ },
+ "areaId": "VehicleAreaWindow::ROOF_TOP_1",
+ "minInt32Value": -100,
+ "maxInt32Value": 100
+ }
+ ],
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_EXTENSION_STRING_PROPERTY",
+ "defaultValue": {
+ "stringValue": "Vendor String Property"
+ },
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::PLACEHOLDER_PROPERTY_INT",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::PLACEHOLDER_PROPERTY_FLOAT",
+ "defaultValue": {
+ "floatValues": [
+ 0.0
+ ]
+ },
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::PLACEHOLDER_PROPERTY_BOOLEAN",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::PLACEHOLDER_PROPERTY_STRING",
+ "defaultValue": {
+ "stringValue": "Test"
+ },
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::ECHO_REVERSE_BYTES",
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_PROPERTY_ID",
+ "access": "VehiclePropertyAccess::READ_WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ },
+ "configArray": [
+ "Constants::kMixedTypePropertyForTest",
+ "VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_INFO",
+ "VehicleVendorPermission::PERMISSION_SET_VENDOR_CATEGORY_INFO",
+ "Constants::VENDOR_EXTENSION_INT_PROPERTY",
+ "VehicleVendorPermission::PERMISSION_GET_VENDOR_CATEGORY_SEAT",
+ "VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE",
+ "Constants::VENDOR_EXTENSION_FLOAT_PROPERTY",
+ "VehicleVendorPermission::PERMISSION_DEFAULT",
+ "VehicleVendorPermission::PERMISSION_DEFAULT"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json b/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json
new file mode 100644
index 0000000..3a1a783
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json
@@ -0,0 +1,63 @@
+{
+ "properties": [
+ {
+ "property": "Constants::VENDOR_CLUSTER_SWITCH_UI",
+ "access": "VehiclePropertyAccess::WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_CLUSTER_DISPLAY_STATE",
+ "access": "VehiclePropertyAccess::WRITE",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ },
+ {
+ "property": "Constants::VENDOR_CLUSTER_REPORT_STATE",
+ "defaultValue": {
+ "int32Values": [
+ 0,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ 0,
+ -1
+ ]
+ },
+ "configArray": [
+ 0,
+ 0,
+ 0,
+ 11,
+ 0,
+ 0,
+ 0,
+ 0,
+ 16
+ ],
+ "access": "VehiclePropertyAccess::READ",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE",
+ "comment":
+ "Value means 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */, 0 /* ClusterHome */, -1 /* ClusterNone */"
+ },
+ {
+ "property": "Constants::VENDOR_CLUSTER_REQUEST_DISPLAY",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "access": "VehiclePropertyAccess::READ",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE",
+ "comment": "0 means ClusterHome"
+ },
+ {
+ "property": "Constants::VENDOR_CLUSTER_NAVIGATION_STATE",
+ "access": "VehiclePropertyAccess::READ",
+ "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
deleted file mode 100644
index f023fd2..0000000
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ /dev/null
@@ -1,2040 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef android_hardware_automotive_vehicle_aidl_impl_default_config_include_DefaultConfig_H_
-#define android_hardware_automotive_vehicle_aidl_impl_default_config_include_DefaultConfig_H_
-
-#include <PropertyUtils.h>
-#include <TestPropertyUtils.h>
-#include <VehicleHalTypes.h>
-
-#include <map>
-#include <vector>
-
-namespace android {
-namespace hardware {
-namespace automotive {
-namespace vehicle {
-
-// Types used in configs, not to be exposed as public API.
-namespace defaultconfig_impl {
-
-using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
-using ::aidl::android::hardware::automotive::vehicle::EvsServiceState;
-using ::aidl::android::hardware::automotive::vehicle::EvsServiceType;
-using ::aidl::android::hardware::automotive::vehicle::FuelType;
-using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
-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::VehicleGear;
-using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
-using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
-using ::aidl::android::hardware::automotive::vehicle::VehicleOilLevel;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
-using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
-using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
-using ::aidl::android::hardware::automotive::vehicle::VehicleSeatOccupancyState;
-using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
-using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
-using ::aidl::android::hardware::automotive::vehicle::VehicleVendorPermission;
-
-struct ConfigDeclaration {
- VehiclePropConfig config;
-
- // This value will be used as an initial value for the property. If this field is specified for
- // property that supports multiple areas then it will be used for all areas unless particular
- // area is overridden in initialAreaValue field.
- RawPropValues initialValue;
- // Use initialAreaValues if it is necessary to specify different values per each area.
- std::map<int32_t, RawPropValues> initialAreaValues;
-};
-
-const std::vector<ConfigDeclaration> kVehicleProperties = {
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.floatValues = {15000.0f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_FUEL_TYPE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {toInt(FuelType::FUEL_TYPE_UNLEADED)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_EV_BATTERY_CAPACITY),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.floatValues = {150000.0f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_EV_CONNECTOR_TYPE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {toInt(EvConnectorType::IEC_TYPE_1_AC)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_FUEL_DOOR_LOCATION),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {FUEL_DOOR_REAR_LEFT}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_EV_PORT_LOCATION),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {CHARGE_PORT_FRONT_LEFT}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {CHARGE_PORT_FRONT_LEFT, CHARGE_PORT_REAR_LEFT}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_VIN),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.stringValue = "1GCARVIN123456789"}},
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_MAKE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.stringValue = "Toy Vehicle"}},
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_MODEL),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.stringValue = "Speedy Model"}},
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_MODEL_YEAR),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {2020}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_EXTERIOR_DIMENSIONS),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- },
- .initialValue = {.int32Values = {1776, 4950, 2008, 2140, 2984, 1665, 1667, 11800}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {toInt(VehicleUnit::METER_PER_SEC),
- toInt(VehicleUnit::MILES_PER_HOUR),
- toInt(VehicleUnit::KILOMETERS_PER_HOUR)},
- },
- .initialValue = {.int32Values = {toInt(VehicleUnit::MILES_PER_HOUR)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_BATTERY_DISPLAY_UNITS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {toInt(VehicleUnit::WATT_HOUR),
- toInt(VehicleUnit::AMPERE_HOURS),
- toInt(VehicleUnit::KILOWATT_HOUR)},
- },
- .initialValue = {.int32Values = {toInt(VehicleUnit::KILOWATT_HOUR)}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_MEMORY_SELECT),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 3}}},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_MEMORY_SET),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 3}}},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_BUCKLED),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = 0,
- .maxInt32Value = 10}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {10}}},
- {SEAT_1_RIGHT, {.int32Values = {10}}},
- {SEAT_2_LEFT, {.int32Values = {10}}},
- {SEAT_2_RIGHT, {.int32Values = {10}}},
- {SEAT_2_CENTER, {.int32Values = {10}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
- {SEAT_1_RIGHT, {.int32Values = {0}}},
- {SEAT_2_LEFT, {.int32Values = {0}}},
- {SEAT_2_RIGHT, {.int32Values = {0}}},
- {SEAT_2_CENTER, {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEIGHT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEIGHT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_DEPTH_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_DEPTH_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_TILT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_TILT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -10,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = 0,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_ANGLE_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = 0,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_ANGLE_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_FORE_AFT_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = 0,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::SEAT_OCCUPANCY),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = (SEAT_1_LEFT)},
- VehicleAreaConfig{.areaId = (SEAT_1_RIGHT)}},
- },
- .initialAreaValues = {{SEAT_1_LEFT,
- {.int32Values = {toInt(VehicleSeatOccupancyState::VACANT)}}},
- {SEAT_1_RIGHT,
- {.int32Values = {toInt(VehicleSeatOccupancyState::VACANT)}}}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::INFO_DRIVER_SEAT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- // this was a zoned property on an old vhal, but it is meant to be global
- .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
- },
- .initialValue = {.int32Values = {SEAT_1_LEFT}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::PERF_ODOMETER),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::PERF_STEERING_ANGLE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}}},
- {.config =
- {
- .prop = toInt(VehicleProperty::PERF_REAR_STEERING_ANGLE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}}},
- {
- .config =
- {
- .prop = toInt(VehicleProperty::ENGINE_RPM),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}},
- },
-
- {.config =
- {
- .prop = toInt(VehicleProperty::FUEL_LEVEL),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 100.0f,
- },
- .initialValue = {.floatValues = {15000.0f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::FUEL_DOOR_OPEN),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_BATTERY_LEVEL),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 100.0f,
- },
- .initialValue = {.floatValues = {150000.0f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_PORT_OPEN),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_PORT_CONNECTED),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {0.0f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {/*max current draw allowed by vehicle in amperes=*/20},
- },
- .initialValue = {.floatValues = {(float)12.5}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_PERCENT_LIMIT),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {20, 40, 60, 80, 100},
- },
- .initialValue = {.floatValues = {40}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {2}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0 /* false */}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_CHARGE_TIME_REMAINING),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.int32Values = {20}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EV_REGENERATIVE_BRAKING_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {2}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::TRAILER_PRESENT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {2}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::VEHICLE_CURB_WEIGHT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- .configArray = {/*gross weight kg=*/2948},
- },
- .initialValue = {.int32Values = {2211 /*kg*/}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::RANGE_REMAINING),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 2.0f,
- },
- .initialValue = {.floatValues = {50000.0f}}}, // units in meters
-
- {.config =
- {
- .prop = toInt(VehicleProperty::TIRE_PRESSURE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = WHEEL_FRONT_LEFT,
- .minFloatValue = 193.0f,
- .maxFloatValue = 300.0f,
- },
- VehicleAreaConfig{
- .areaId = WHEEL_FRONT_RIGHT,
- .minFloatValue = 193.0f,
- .maxFloatValue = 300.0f,
- },
- VehicleAreaConfig{
- .areaId = WHEEL_REAR_LEFT,
- .minFloatValue = 193.0f,
- .maxFloatValue = 300.0f,
- },
- VehicleAreaConfig{
- .areaId = WHEEL_REAR_RIGHT,
- .minFloatValue = 193.0f,
- .maxFloatValue = 300.0f,
- }},
- .minSampleRate = 1.0f,
- .maxSampleRate = 2.0f,
- },
- .initialValue = {.floatValues = {200.0f}}}, // units in kPa
-
- {.config =
- {
- .prop = toInt(VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- .areaConfigs = {VehicleAreaConfig{.areaId = WHEEL_FRONT_LEFT},
- VehicleAreaConfig{.areaId = WHEEL_FRONT_RIGHT},
- VehicleAreaConfig{.areaId = WHEEL_REAR_RIGHT},
- VehicleAreaConfig{.areaId = WHEEL_REAR_LEFT}},
- },
- .initialAreaValues = {{WHEEL_FRONT_LEFT, {.floatValues = {137.0f}}},
- {WHEEL_FRONT_RIGHT, {.floatValues = {137.0f}}},
- {WHEEL_REAR_RIGHT, {.floatValues = {137.0f}}},
- {WHEEL_REAR_LEFT, {.floatValues = {137.0f}}}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {toInt(VehicleUnit::KILOPASCAL), toInt(VehicleUnit::PSI),
- toInt(VehicleUnit::BAR)},
- },
- .initialValue = {.int32Values = {toInt(VehicleUnit::PSI)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::CURRENT_GEAR),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {toInt(VehicleGear::GEAR_PARK),
- toInt(VehicleGear::GEAR_NEUTRAL),
- toInt(VehicleGear::GEAR_REVERSE),
- toInt(VehicleGear::GEAR_1), toInt(VehicleGear::GEAR_2),
- toInt(VehicleGear::GEAR_3), toInt(VehicleGear::GEAR_4),
- toInt(VehicleGear::GEAR_5)},
- },
- .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::PARKING_BRAKE_ON),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {1}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::PARKING_BRAKE_AUTO_APPLY),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {1}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {(int)VehicleUnit::LITER, (int)VehicleUnit::US_GALLON},
- },
- .initialValue = {.int32Values = {(int)VehicleUnit::US_GALLON}}},
-
- {.config =
- {
- .prop = toInt(
- VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {1}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HW_KEY_INPUT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0, 0, 0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HW_ROTARY_INPUT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0, 0, 0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HW_CUSTOM_INPUT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {0, 0, 0, 3, 0, 0, 0, 0, 0},
- },
- .initialValue =
- {
- .int32Values = {0, 0, 0},
- }},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {50}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_POWER_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}},
- // TODO(bryaneyler): Ideally, this is generated dynamically from
- // kHvacPowerProperties.
- .configArray = {toInt(VehicleProperty::HVAC_FAN_SPEED),
- toInt(VehicleProperty::HVAC_FAN_DIRECTION)}},
- .initialValue = {.int32Values = {1}}},
-
- {
- .config = {.prop = toInt(VehicleProperty::HVAC_DEFROSTER),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{
- .areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD)},
- VehicleAreaConfig{
- .areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD)}}},
- .initialValue = {.int32Values = {0}} // Will be used for all areas.
- },
- {
- .config = {.prop = toInt(VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{
- .areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD)},
- VehicleAreaConfig{
- .areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD)}}},
- .initialValue = {.int32Values = {0}} // Will be used for all areas.
- },
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_MAX_DEFROST_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_RECIRC_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_AC_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_MAX_AC_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_AUTO_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = HVAC_ALL, .minInt32Value = 1, .maxInt32Value = 7}}},
- .initialValue = {.int32Values = {3}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {toInt(VehicleHvacFanDirection::FACE)}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::STATIC,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
- .initialValue = {.int32Values = {FAN_DIRECTION_FACE, FAN_DIRECTION_FLOOR,
- FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR,
- FAN_DIRECTION_DEFROST,
- FAN_DIRECTION_FACE | FAN_DIRECTION_DEFROST,
- FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST,
- FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST |
- FAN_DIRECTION_FACE}}},
- {.config = {.prop = toInt(VehicleProperty::HVAC_SEAT_VENTILATION),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = SEAT_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 3,
- },
- VehicleAreaConfig{
- .areaId = SEAT_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 3,
- }}},
- .initialValue =
- {.int32Values = {0}}}, // 0 is off and +ve values indicate ventilation level.
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_STEERING_WHEEL_HEAT),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = (0), .minInt32Value = -2, .maxInt32Value = 2}}},
- .initialValue = {.int32Values = {0}}}, // +ve values for heating and -ve for cooling
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_SEAT_TEMPERATURE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = SEAT_1_LEFT,
- .minInt32Value = -2,
- .maxInt32Value = 2,
- },
- VehicleAreaConfig{
- .areaId = SEAT_1_RIGHT,
- .minInt32Value = -2,
- .maxInt32Value = 2,
- }}},
- .initialValue = {.int32Values = {0}}}, // +ve values for heating and -ve for cooling
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_SIDE_MIRROR_HEAT),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{
- .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT) |
- toInt(VehicleAreaMirror::DRIVER_RIGHT),
- .minInt32Value = 0,
- .maxInt32Value = 2,
- }}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_CURRENT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_LEFT},
- VehicleAreaConfig{.areaId = HVAC_RIGHT}}},
- .initialAreaValues = {{HVAC_LEFT, {.floatValues = {17.3f}}},
- {HVAC_RIGHT, {.floatValues = {19.1f}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {160, 280, 5, 605, 825, 10},
- .areaConfigs = {VehicleAreaConfig{
- .areaId = HVAC_LEFT,
- .minFloatValue = 16,
- .maxFloatValue = 32,
- },
- VehicleAreaConfig{
- .areaId = HVAC_RIGHT,
- .minFloatValue = 16,
- .maxFloatValue = 32,
- }}},
- .initialAreaValues = {{HVAC_LEFT, {.floatValues = {16}}},
- {HVAC_RIGHT, {.floatValues = {20}}}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.floatValues = {66.2f, (float)VehicleUnit::FAHRENHEIT, 19.0f, 66.5f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
- .access = VehiclePropertyAccess::READ,
- // TODO(bryaneyler): Support ON_CHANGE as well.
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 2.0f,
- },
- .initialValue = {.floatValues = {25.0f}}},
-
- {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {toInt(VehicleUnit::FAHRENHEIT), toInt(VehicleUnit::CELSIUS)}},
- .initialValue = {.int32Values = {toInt(VehicleUnit::FAHRENHEIT)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::DISTANCE_DISPLAY_UNITS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
- .configArray = {toInt(VehicleUnit::KILOMETER), toInt(VehicleUnit::MILE)},
- },
- .initialValue = {.int32Values = {toInt(VehicleUnit::MILE)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::NIGHT_MODE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::GEAR_SELECTION),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {toInt(VehicleGear::GEAR_PARK),
- toInt(VehicleGear::GEAR_NEUTRAL),
- toInt(VehicleGear::GEAR_REVERSE),
- toInt(VehicleGear::GEAR_DRIVE), toInt(VehicleGear::GEAR_1),
- toInt(VehicleGear::GEAR_2), toInt(VehicleGear::GEAR_3),
- toInt(VehicleGear::GEAR_4), toInt(VehicleGear::GEAR_5)},
- },
- .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::TURN_SIGNAL_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {toInt(VehicleTurnSignal::NONE)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::IGNITION_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {toInt(VehicleIgnitionState::ON)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::ENGINE_COOLANT_TEMP),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.floatValues = {75.0f}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::ENGINE_OIL_LEVEL),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {toInt(VehicleOilLevel::NORMAL)}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::ENGINE_OIL_TEMP),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .minSampleRate = 0.1, // 0.1 Hz, every 10 seconds
- .maxSampleRate = 10, // 10 Hz, every 100 ms
- },
- .initialValue = {.floatValues = {101.0f}}},
-
- {
- .config = {.prop = kMixedTypePropertyForTest,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {1, 1, 0, 2, 0, 0, 1, 0, 0}},
- .initialValue =
- {
- .int32Values = {1 /* indicate TRUE boolean value */, 2, 3},
- .floatValues = {4.5f},
- .stringValue = "MIXED property",
- },
- },
-
- {.config = {.prop = toInt(VehicleProperty::DOOR_LOCK),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = DOOR_1_LEFT},
- VehicleAreaConfig{.areaId = DOOR_1_RIGHT},
- VehicleAreaConfig{.areaId = DOOR_2_LEFT},
- VehicleAreaConfig{.areaId = DOOR_2_RIGHT}}},
- .initialAreaValues = {{DOOR_1_LEFT, {.int32Values = {1}}},
- {DOOR_1_RIGHT, {.int32Values = {1}}},
- {DOOR_2_LEFT, {.int32Values = {1}}},
- {DOOR_2_RIGHT, {.int32Values = {1}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::DOOR_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{
- .areaId = DOOR_1_LEFT, .minInt32Value = 0, .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = DOOR_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 1},
- VehicleAreaConfig{
- .areaId = DOOR_2_LEFT, .minInt32Value = 0, .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = DOOR_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 1},
- VehicleAreaConfig{
- .areaId = DOOR_REAR, .minInt32Value = 0, .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::MIRROR_Z_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
- .minInt32Value = -3,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
- .minInt32Value = -3,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
- .minInt32Value = -3,
- .maxInt32Value = 3}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::MIRROR_Z_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::MIRROR_Y_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
- .minInt32Value = -3,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
- .minInt32Value = -3,
- .maxInt32Value = 3},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
- .minInt32Value = -3,
- .maxInt32Value = 3}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::MIRROR_Y_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::MIRROR_LOCK),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::MIRROR_FOLD),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {1}}},
-
- {.config = {.prop = toInt(VehicleProperty::WINDOW_LOCK),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_RIGHT | WINDOW_2_LEFT |
- WINDOW_2_RIGHT}}},
- .initialAreaValues = {{WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT,
- {.int32Values = {0}}}}},
-
- {.config = {.prop = toInt(VehicleProperty::WINDOW_POS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = WINDOW_1_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = WINDOW_2_LEFT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = WINDOW_2_RIGHT,
- .minInt32Value = 0,
- .maxInt32Value = 10},
- VehicleAreaConfig{.areaId = WINDOW_ROOF_TOP_1,
- .minInt32Value = -10,
- .maxInt32Value = 10}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::WINDOW_MOVE),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = WINDOW_1_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = WINDOW_2_LEFT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = WINDOW_2_RIGHT,
- .minInt32Value = -1,
- .maxInt32Value = 1},
- VehicleAreaConfig{.areaId = WINDOW_ROOF_TOP_1,
- .minInt32Value = -1,
- .maxInt32Value = 1}}},
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = WHEEL_TICK,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
- .configArray = {ALL_WHEELS, 50000, 50000, 50000, 50000},
- .minSampleRate = 1.0f,
- .maxSampleRate = 10.0f,
- },
- .initialValue = {.int64Values = {0, 100000, 200000, 300000, 400000}}},
-
- {.config = {.prop = ABS_ACTIVE,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = TRACTION_CONTROL_ACTIVE,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {3}}},
-
- {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL), 0}}},
-
- {.config = {.prop = toInt(VehicleProperty::DISPLAY_BRIGHTNESS),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.minInt32Value = 0, .maxInt32Value = 100}}},
- .initialValue = {.int32Values = {100}}},
-
- {
- .config = {.prop = OBD2_LIVE_FRAME,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {0, 0}},
- },
-
- {
- .config = {.prop = OBD2_FREEZE_FRAME,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {0, 0}},
- },
-
- {
- .config = {.prop = OBD2_FREEZE_FRAME_INFO,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- },
-
- {
- .config = {.prop = OBD2_FREEZE_FRAME_CLEAR,
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {1}},
- },
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HEADLIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HIGH_BEAM_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HAZARD_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::CABIN_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config = {.prop = toInt(VehicleProperty::READING_LIGHTS_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HEADLIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
- // FOG_LIGHTS_SWITCH must not be implemented when FRONT_FOG_LIGHTS_SWITCH is implemented
- {.config =
- {
- .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
- // FOG_LIGHTS_SWITCH must not be implemented when REAR_FOG_LIGHTS_SWITCH is implemented
- {.config =
- {
- .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::HAZARD_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::CABIN_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config = {.prop = toInt(VehicleProperty::READING_LIGHTS_SWITCH),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
- VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
- VehicleAreaConfig{.areaId = SEAT_2_LEFT},
- VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
- VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
- .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::EVS_SERVICE_REQUEST),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {toInt(EvsServiceType::REARVIEW),
- toInt(EvsServiceState::OFF)}}},
-
- {.config = {.prop = VEHICLE_MAP_SERVICE,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE}},
-
- // Example Vendor Extension properties for testing
- {.config = {.prop = VENDOR_EXTENSION_BOOLEAN_PROPERTY,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = DOOR_1_LEFT},
- VehicleAreaConfig{.areaId = DOOR_1_RIGHT},
- VehicleAreaConfig{.areaId = DOOR_2_LEFT},
- VehicleAreaConfig{.areaId = DOOR_2_RIGHT}}},
- .initialAreaValues = {{DOOR_1_LEFT, {.int32Values = {1}}},
- {DOOR_1_RIGHT, {.int32Values = {1}}},
- {DOOR_2_LEFT, {.int32Values = {0}}},
- {DOOR_2_RIGHT, {.int32Values = {0}}}}},
-
- {.config = {.prop = VENDOR_EXTENSION_FLOAT_PROPERTY,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_LEFT,
- .minFloatValue = -10,
- .maxFloatValue = 10},
- VehicleAreaConfig{.areaId = HVAC_RIGHT,
- .minFloatValue = -10,
- .maxFloatValue = 10}}},
- .initialAreaValues = {{HVAC_LEFT, {.floatValues = {1}}},
- {HVAC_RIGHT, {.floatValues = {2}}}}},
-
- {.config = {.prop = VENDOR_EXTENSION_INT_PROPERTY,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .areaConfigs =
- {VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD),
- .minInt32Value = -100,
- .maxInt32Value = 100},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::REAR_WINDSHIELD),
- .minInt32Value = -100,
- .maxInt32Value = 100},
- VehicleAreaConfig{.areaId = toInt(VehicleAreaWindow::ROOF_TOP_1),
- .minInt32Value = -100,
- .maxInt32Value = 100}}},
- .initialAreaValues = {{toInt(VehicleAreaWindow::FRONT_WINDSHIELD), {.int32Values = {1}}},
- {toInt(VehicleAreaWindow::REAR_WINDSHIELD), {.int32Values = {0}}},
- {toInt(VehicleAreaWindow::ROOF_TOP_1), {.int32Values = {-1}}}}},
-
- {.config = {.prop = VENDOR_EXTENSION_STRING_PROPERTY,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.stringValue = "Vendor String Property"}},
-
- {.config = {.prop = toInt(VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {0}}},
-
- {.config = {.prop = toInt(VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
- .initialValue = {.int32Values = {0}}},
-
- {.config =
- {
- .prop = toInt(VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {kMixedTypePropertyForTest,
- toInt(VehicleVendorPermission::
- PERMISSION_GET_VENDOR_CATEGORY_INFO),
- toInt(VehicleVendorPermission::
- PERMISSION_SET_VENDOR_CATEGORY_INFO),
- VENDOR_EXTENSION_INT_PROPERTY,
- toInt(VehicleVendorPermission::
- PERMISSION_GET_VENDOR_CATEGORY_SEAT),
- toInt(VehicleVendorPermission::PERMISSION_NOT_ACCESSIBLE),
- VENDOR_EXTENSION_FLOAT_PROPERTY,
- toInt(VehicleVendorPermission::PERMISSION_DEFAULT),
- toInt(VehicleVendorPermission::PERMISSION_DEFAULT)},
- },
- .initialValue = {.int32Values = {1}}},
-
- {
- .config =
- {
- .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::SWITCH_USER),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CREATE_USER),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::REMOVE_USER),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::POWER_POLICY_REQ),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::POWER_POLICY_GROUP_REQ),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CURRENT_POWER_POLICY),
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::ANDROID_EPOCH_TIME),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::WATCHDOG_ALIVE),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::WATCHDOG_TERMINATED_PROCESS),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::VHAL_HEARTBEAT),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CLUSTER_SWITCH_UI),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0 /* ClusterHome */}},
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CLUSTER_DISPLAY_STATE),
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1,
- -1, -1 /* Insets */}},
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CLUSTER_REPORT_STATE),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16},
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE),
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = PLACEHOLDER_PROPERTY_INT,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0}},
- },
- {
- .config =
- {
- .prop = PLACEHOLDER_PROPERTY_FLOAT,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.floatValues = {0.0f}},
- },
- {
- .config =
- {
- .prop = PLACEHOLDER_PROPERTY_BOOLEAN,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0 /* false */}},
- },
- {
- .config =
- {
- .prop = PLACEHOLDER_PROPERTY_STRING,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.stringValue = {"Test"}},
- },
- {
- .config =
- {
- .prop = ECHO_REVERSE_BYTES,
- .access = VehiclePropertyAccess::READ_WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
- // Vendor propetry for E2E ClusterHomeService testing.
- {
- .config =
- {
- .prop = VENDOR_CLUSTER_SWITCH_UI,
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = VENDOR_CLUSTER_DISPLAY_STATE,
- .access = VehiclePropertyAccess::WRITE,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
- {
- .config =
- {
- .prop = VENDOR_CLUSTER_REPORT_STATE,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16},
- },
- .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1,
- -1, -1 /* Insets */, 0 /* ClusterHome */,
- -1 /* ClusterNone */}},
- },
- {
- .config =
- {
- .prop = VENDOR_CLUSTER_REQUEST_DISPLAY,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- .initialValue = {.int32Values = {0 /* ClusterHome */}},
- },
- {
- .config =
- {
- .prop = VENDOR_CLUSTER_NAVIGATION_STATE,
- .access = VehiclePropertyAccess::READ,
- .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- },
- },
-#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
-};
-
-} // namespace defaultconfig_impl
-
-// public namespace
-namespace defaultconfig {
-
-typedef defaultconfig_impl::ConfigDeclaration ConfigDeclaration;
-
-inline constexpr const std::vector<ConfigDeclaration>& getDefaultConfigs() {
- return defaultconfig_impl::kVehicleProperties;
-}
-
-} // namespace defaultconfig
-
-} // namespace vehicle
-} // namespace automotive
-} // namespace hardware
-} // namespace android
-
-#endif // android_hardware_automotive_vehicle_aidl_impl_default_config_include_DefaultConfig_H_
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 771472c..8702eae 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -24,11 +24,47 @@
defaults: ["VehicleHalDefaults"],
srcs: ["*.cpp"],
static_libs: [
+ "VehicleHalJsonConfigLoader",
"VehicleHalUtils",
+ "libgmock",
"libgtest",
],
header_libs: [
- "VehicleHalDefaultConfig",
+ "IVehicleGeneratedHeaders",
+ ],
+ shared_libs: [
+ "libjsoncpp",
+ ],
+ data: [
+ ":VehicleHalDefaultProperties_JSON",
+ ],
+ test_suites: ["device-tests"],
+}
+
+cc_test {
+ name: "VehicleHalDefaultConfigTestEnableTestProperties",
+ vendor: true,
+ defaults: ["VehicleHalDefaults"],
+ srcs: ["*.cpp"],
+ static_libs: [
+ "VehicleHalJsonConfigLoaderEnableTestProperties",
+ "VehicleHalUtils",
+ "libgmock",
+ "libgtest",
+ ],
+ cflags: [
+ "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
+ ],
+ header_libs: [
+ "IVehicleGeneratedHeaders",
+ ],
+ shared_libs: [
+ "libjsoncpp",
+ ],
+ data: [
+ ":VehicleHalDefaultProperties_JSON",
+ ":VehicleHalTestProperties_JSON",
+ ":VehicleHalVendorClusterTestProperties_JSON",
],
test_suites: ["device-tests"],
}
diff --git a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp b/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
index baaae75..95fecfe 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
@@ -14,27 +14,75 @@
* limitations under the License.
*/
-#include <DefaultConfig.h>
+#include <JsonConfigLoader.h>
#include <VehicleUtils.h>
+#include <android-base/file.h>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <fstream>
+#include <unordered_map>
namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
-namespace defaultconfig {
namespace test {
-TEST(DefaultConfigTest, loadDefaultConfigs) {
- for (ConfigDeclaration config : getDefaultConfigs()) {
- ASSERT_NE(0, config.config.prop);
- }
+using ::android::base::Error;
+using ::android::base::Result;
+using ::testing::UnorderedElementsAreArray;
+
+constexpr char kDefaultPropertiesConfigFile[] = "DefaultProperties.json";
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+constexpr char kTestPropertiesConfigFile[] = "TestProperties.json";
+constexpr char kVendorClusterTestPropertiesConfigFile[] = "VendorClusterTestProperties.json";
+#endif // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+std::string getTestFilePath(const char* filename) {
+ static std::string baseDir = android::base::GetExecutableDirectory();
+ return baseDir + "/" + filename;
}
+Result<std::unordered_map<int32_t, ConfigDeclaration>> loadConfig(JsonConfigLoader& loader,
+ const char* path) {
+ std::string configPath = getTestFilePath(path);
+ std::ifstream ifs(configPath.c_str());
+ if (!ifs) {
+ return Error() << "couldn't open %s for parsing." << configPath;
+ }
+
+ return loader.loadPropConfig(ifs);
+}
+
+TEST(DefaultConfigTest, TestloadDefaultProperties) {
+ JsonConfigLoader loader;
+ auto result = loadConfig(loader, kDefaultPropertiesConfigFile);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+TEST(DefaultConfigTest, TestloadTestProperties) {
+ JsonConfigLoader loader;
+ auto result = loadConfig(loader, kTestPropertiesConfigFile);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+TEST(DefaultConfigTest, TestloadVendorClusterTestProperties) {
+ JsonConfigLoader loader;
+ auto result = loadConfig(loader, kVendorClusterTestPropertiesConfigFile);
+
+ ASSERT_TRUE(result.ok()) << result.error().message();
+}
+
+#endif // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
} // namespace test
-} // namespace defaultconfig
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
index 9f112ae..f96b6ec 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
@@ -54,8 +54,8 @@
void registerGenerator(int32_t generatorId, std::unique_ptr<FakeValueGenerator> generator);
// Unregister a generator with the generatorId. If no registered generator is found, this
- // function does nothing.
- void unregisterGenerator(int32_t generatorId);
+ // function does nothing. Returns true if the generator is unregistered.
+ bool unregisterGenerator(int32_t generatorId);
private:
struct VhalEvent {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
index d421ac5..42b1bd3 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
@@ -45,6 +45,9 @@
// Create a new JSON fake value generator using the specified JSON file path. All the events
// in the JSON file would be generated once.
explicit JsonFakeValueGenerator(const std::string& path);
+ // Create a new JSON fake value generator using the JSON content. The first argument is just
+ // used to differentiate this function with the one that takes path as input.
+ explicit JsonFakeValueGenerator(bool unused, const std::string& content, int32_t iteration);
~JsonFakeValueGenerator() = default;
@@ -53,6 +56,9 @@
const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
getAllEvents();
+ // Whether there are events left to replay for this generator.
+ bool hasNext();
+
private:
size_t mEventIndex = 0;
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> mEvents;
@@ -60,7 +66,8 @@
int32_t mNumOfIterations = 0;
void setBit(std::vector<uint8_t>& bytes, size_t idx);
- void init(const std::string& path, int32_t iteration);
+ void initWithPath(const std::string& path, int32_t iteration);
+ void initWithStream(std::istream& is, int32_t iteration);
};
} // namespace fake
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
index 0c182d9..d815456 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
@@ -29,11 +29,18 @@
using ::android::base::ScopedLockAssertion;
-GeneratorHub::GeneratorHub(OnHalEvent&& onHalEvent)
- : mOnHalEvent(onHalEvent), mThread(&GeneratorHub::run, this) {}
+GeneratorHub::GeneratorHub(OnHalEvent&& onHalEvent) : mOnHalEvent(onHalEvent) {
+ mThread = std::thread(&GeneratorHub::run, this);
+}
GeneratorHub::~GeneratorHub() {
- mShuttingDownFlag.store(true);
+ {
+ // Even if the shared variable is atomic, it must be modified under the
+ // mutex in order to correctly publish the modification to the waiting
+ // thread.
+ std::unique_lock<std::mutex> lock(mGeneratorsLock);
+ mShuttingDownFlag.store(true);
+ }
mCond.notify_all();
if (mThread.joinable()) {
mThread.join();
@@ -58,13 +65,15 @@
mCond.notify_one();
}
-void GeneratorHub::unregisterGenerator(int32_t id) {
+bool GeneratorHub::unregisterGenerator(int32_t id) {
+ bool removed;
{
std::scoped_lock<std::mutex> lockGuard(mGeneratorsLock);
- mGenerators.erase(id);
+ removed = mGenerators.erase(id);
}
mCond.notify_one();
ALOGI("%s: Unregistered generator, id: %d", __func__, id);
+ return removed;
}
void GeneratorHub::run() {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
index d4d52a5..cb42317 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
@@ -173,12 +173,11 @@
} // namespace
-JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path) {
- init(path, 1);
-}
+JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path)
+ : JsonFakeValueGenerator(path, /*iteration=*/1) {}
JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path, int32_t iteration) {
- init(path, iteration);
+ initWithPath(path, iteration);
}
JsonFakeValueGenerator::JsonFakeValueGenerator(const VehiclePropValue& request) {
@@ -186,16 +185,26 @@
// Iterate infinitely if iteration number is not provided
int32_t numOfIterations = v.int32Values.size() < 2 ? -1 : v.int32Values[1];
- init(v.stringValue, numOfIterations);
+ initWithPath(v.stringValue, numOfIterations);
}
-void JsonFakeValueGenerator::init(const std::string& path, int32_t iteration) {
+JsonFakeValueGenerator::JsonFakeValueGenerator([[maybe_unused]] bool unused,
+ const std::string& content, int32_t iteration) {
+ std::istringstream iss(content);
+ initWithStream(iss, iteration);
+}
+
+void JsonFakeValueGenerator::initWithPath(const std::string& path, int32_t iteration) {
std::ifstream ifs(path);
if (!ifs) {
ALOGE("%s: couldn't open %s for parsing.", __func__, path.c_str());
return;
}
- mEvents = parseFakeValueJson(ifs);
+ initWithStream(ifs, iteration);
+}
+
+void JsonFakeValueGenerator::initWithStream(std::istream& is, int32_t iteration) {
+ mEvents = parseFakeValueJson(is);
mNumOfIterations = iteration;
}
@@ -235,12 +244,15 @@
mNumOfIterations--;
}
}
-
generatedValue.timestamp = mLastEventTimestamp;
return generatedValue;
}
+bool JsonFakeValueGenerator::hasNext() {
+ return mNumOfIterations != 0 && mEvents.size() > 0;
+}
+
} // namespace fake
} // namespace vehicle
} // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/fake_impl/README.md b/automotive/vehicle/aidl/impl/fake_impl/README.md
new file mode 100644
index 0000000..e86dcee
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/README.md
@@ -0,0 +1,28 @@
+# Fake reference AIDL VHAL implementation libraries
+---
+
+This directory stores libraries for implementing a fake reference AIDL VHAL.
+
+WARNING: All the libraries here are for TEST ONLY.
+
+## GeneratorHub
+
+Defines a library `FakeVehicleHalValueGenerators` that could generate fake
+vehicle property values for testing.
+
+## hardware
+
+Defines a fake implementation for device-specifc interface `IVehicleHardware`:
+`FakeVehicleHardware`. This implementation uses a in-memory map for storing
+property values and does not communicate with or depending on any specific
+vehicle bus.
+
+## obd2frame
+
+Defines a library `FakeObd2Frame` that generates fake OBD2 frame for OBD2
+properties.
+
+## userhal
+
+Defines a library `FakeUserHal` that emulates a real User HAL behavior by
+parsing debug commands.
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index dcd9208..4c17cde 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -24,6 +24,7 @@
srcs: ["src/*.cpp"],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
+ cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
defaults: [
"VehicleHalDefaults",
"FakeVehicleHardwareDefaults",
@@ -32,18 +33,23 @@
cc_defaults {
name: "FakeVehicleHardwareDefaults",
- cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
header_libs: [
"IVehicleHardware",
- "VehicleHalDefaultConfig",
+ "VehicleHalTestUtilHeaders",
],
export_header_lib_headers: ["IVehicleHardware"],
static_libs: [
+ "VehicleHalJsonConfigLoaderEnableTestProperties",
"VehicleHalUtils",
"FakeVehicleHalValueGenerators",
"FakeObd2Frame",
"FakeUserHal",
],
+ required: [
+ "Prebuilt_VehicleHalDefaultProperties_JSON",
+ "Prebuilt_VehicleHalTestProperties_JSON",
+ "Prebuilt_VehicleHalVendorClusterTestProperties_JSON",
+ ],
shared_libs: [
"libjsoncpp",
],
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 34b2b24..7b74092 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -18,21 +18,24 @@
#define android_hardware_automotive_vehicle_aidl_impl_fake_impl_hardware_include_FakeVehicleHardware_H_
#include <ConcurrentQueue.h>
-#include <DefaultConfig.h>
+#include <ConfigDeclaration.h>
#include <FakeObd2Frame.h>
#include <FakeUserHal.h>
+#include <GeneratorHub.h>
#include <IVehicleHardware.h>
+#include <JsonConfigLoader.h>
#include <RecurrentTimer.h>
#include <VehicleHalTypes.h>
#include <VehiclePropertyStore.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.h>
#include <android-base/parseint.h>
#include <android-base/result.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
-#include <map>
#include <memory>
#include <mutex>
+#include <unordered_map>
#include <vector>
namespace android {
@@ -47,7 +50,8 @@
FakeVehicleHardware();
- explicit FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool);
+ FakeVehicleHardware(std::string defaultConfigDir, std::string overrideConfigDir,
+ bool forceOverride);
~FakeVehicleHardware();
@@ -132,11 +136,18 @@
const std::unique_ptr<FakeUserHal> mFakeUserHal;
// RecurrentTimer is thread-safe.
std::unique_ptr<RecurrentTimer> mRecurrentTimer;
+ // GeneratorHub is thread-safe.
+ std::unique_ptr<GeneratorHub> mGeneratorHub;
+
+ // Only allowed to set once.
+ std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback;
+ std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
+
std::mutex mLock;
- std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback GUARDED_BY(mLock);
- std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback GUARDED_BY(mLock);
std::unordered_map<PropIdAreaId, std::shared_ptr<RecurrentTimer::Callback>, PropIdAreaIdHash>
mRecurrentActions GUARDED_BY(mLock);
+ std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
+ mSavedProps GUARDED_BY(mLock);
// PendingRequestHandler is thread-safe.
mutable PendingRequestHandler<GetValuesCallback,
aidl::android::hardware::automotive::vehicle::GetValueRequest>
@@ -145,18 +156,35 @@
aidl::android::hardware::automotive::vehicle::SetValueRequest>
mPendingSetValueRequests;
+ const std::string mDefaultConfigDir;
+ const std::string mOverrideConfigDir;
+ const bool mForceOverride;
+
+ // Only used during initialization.
+ JsonConfigLoader mLoader;
+
void init();
// Stores the initial value to property store.
- void storePropInitialValue(const defaultconfig::ConfigDeclaration& config);
+ void storePropInitialValue(const ConfigDeclaration& config);
// The callback that would be called when a vehicle property value change happens.
void onValueChangeCallback(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
- // If property "persist.vendor.vhal_init_value_override" is set to true, override the properties
- // using config files in 'overrideDir'.
- void maybeOverrideProperties(const char* overrideDir);
- // Override the properties using config files in 'overrideDir'.
- void overrideProperties(const char* overrideDir);
+ // 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,
+ std::unordered_map<int32_t, ConfigDeclaration>* configs);
+ // Function to be called when a value change event comes from vehicle bus. In our fake
+ // implementation, this function is only called during "--inject-event" dump command.
+ void eventFromVehicleBus(
+ const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value);
+ int getHvacTempNumIncrements(int requestedTemp, int minTemp, int maxTemp, int increment);
+ void updateHvacTemperatureValueSuggestionInput(
+ const std::vector<int>& hvacTemperatureSetConfigArray,
+ std::vector<float>* hvacTemperatureValueSuggestionInput);
+ VhalResult<void> setHvacTemperatureValueSuggestion(
+ const aidl::android::hardware::automotive::vehicle::VehiclePropValue&
+ hvacTemperatureValueSuggestion);
VhalResult<void> maybeSetSpecialValue(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
bool* isSpecialValue);
@@ -173,7 +201,9 @@
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
ValueResultType getEchoReverseBytes(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
- bool isHvacPropAndHvacNotAvailable(int32_t propId);
+ bool isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const;
+
+ std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
std::string dumpAllProperties();
std::string dumpOnePropertyByConfig(
@@ -184,6 +214,10 @@
std::string dumpListProperties();
std::string dumpSpecificProperty(const std::vector<std::string>& options);
std::string dumpSetProperties(const std::vector<std::string>& options);
+ std::string dumpGetPropertyWithArg(const std::vector<std::string>& options);
+ std::string dumpSaveProperty(const std::vector<std::string>& options);
+ std::string dumpRestoreProperty(const std::vector<std::string>& options);
+ std::string dumpInjectEvent(const std::vector<std::string>& options);
template <typename T>
android::base::Result<T> safelyParseInt(int index, const std::string& s) {
@@ -198,7 +232,7 @@
std::vector<std::string> getOptionValues(const std::vector<std::string>& options,
size_t* index);
android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropValue>
- parseSetPropOptions(const std::vector<std::string>& options);
+ parsePropOptions(const std::vector<std::string>& options);
android::base::Result<std::vector<uint8_t>> parseHexString(const std::string& s);
android::base::Result<void> checkArgumentsSize(const std::vector<std::string>& options,
@@ -207,6 +241,23 @@
const aidl::android::hardware::automotive::vehicle::GetValueRequest& request);
aidl::android::hardware::automotive::vehicle::SetValueResult handleSetValueRequest(
const aidl::android::hardware::automotive::vehicle::SetValueRequest& request);
+
+ std::string genFakeDataCommand(const std::vector<std::string>& options);
+ void sendHvacPropertiesCurrentValues(int32_t areaId);
+
+ static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
+ aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
+ int32_t keyCode, int32_t targetDisplay);
+ static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwKeyInputV2Prop(
+ int32_t area, int32_t targetDisplay, int32_t keyCode, int32_t action,
+ int32_t repeatCount);
+ static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwMotionInputProp(
+ int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
+ int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[],
+ float yData[], float pressure[], float size[]);
+
+ static std::string genFakeDataHelp();
+ static std::string parseErrMsg(std::string fieldName, std::string value, std::string type);
};
} // namespace fake
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 20c34aa..4544389 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -15,24 +15,29 @@
*/
#define LOG_TAG "FakeVehicleHardware"
+#define ATRACE_TAG ATRACE_TAG_HAL
#define FAKE_VEHICLEHARDWARE_DEBUG false // STOPSHIP if true.
#include "FakeVehicleHardware.h"
-#include <DefaultConfig.h>
#include <FakeObd2Frame.h>
#include <JsonFakeValueGenerator.h>
+#include <LinearFakeValueGenerator.h>
#include <PropertyUtils.h>
#include <TestPropertyUtils.h>
#include <VehicleHalTypes.h>
#include <VehicleUtils.h>
+
+#include <android-base/file.h>
#include <android-base/parsedouble.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
+#include <utils/Trace.h>
#include <dirent.h>
+#include <inttypes.h>
#include <sys/types.h>
#include <fstream>
#include <regex>
@@ -55,24 +60,36 @@
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
using ::android::base::EqualsIgnoreCase;
using ::android::base::Error;
+using ::android::base::GetIntProperty;
using ::android::base::ParseFloat;
using ::android::base::Result;
using ::android::base::ScopedLockAssertion;
using ::android::base::StartsWith;
using ::android::base::StringPrintf;
-const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
-const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override";
-
+// The directory for default property configuration file.
+// For config file format, see impl/default_config/config/README.md.
+constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/";
+// The directory for property configuration file that overrides the default configuration file.
+// For config file format, see impl/default_config/config/README.md.
+constexpr char OVERRIDE_CONFIG_DIR[] = "/vendor/etc/automotive/vhaloverride/";
+// If OVERRIDE_PROPERTY is set, we will use the configuration files from OVERRIDE_CONFIG_DIR to
+// overwrite the default configs.
+constexpr char OVERRIDE_PROPERTY[] = "persist.vendor.vhal_init_value_override";
+constexpr char POWER_STATE_REQ_CONFIG_PROPERTY[] = "ro.vendor.fake_vhal.ap_power_state_req.config";
+// The value to be returned if VENDOR_PROPERTY_ID is set as the property
+constexpr int VENDOR_ERROR_CODE = 0x00ab0005;
// A list of supported options for "--set" command.
const std::unordered_set<std::string> SET_PROP_OPTIONS = {
// integer.
@@ -86,11 +103,13 @@
// bytes in hex format, e.g. 0xDEADBEEF.
"-b",
// Area id in integer.
- "-a"};
+ "-a",
+ // Timestamp in int64.
+ "-t"};
} // namespace
-void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) {
+void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
const VehiclePropConfig& vehiclePropConfig = config.config;
int propId = vehiclePropConfig.prop;
@@ -132,30 +151,50 @@
}
FakeVehicleHardware::FakeVehicleHardware()
- : FakeVehicleHardware(std::make_unique<VehiclePropValuePool>()) {}
+ : FakeVehicleHardware(DEFAULT_CONFIG_DIR, OVERRIDE_CONFIG_DIR, false) {}
-FakeVehicleHardware::FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool)
- : mValuePool(std::move(valuePool)),
+FakeVehicleHardware::FakeVehicleHardware(std::string defaultConfigDir,
+ std::string overrideConfigDir, bool forceOverride)
+ : mValuePool(std::make_unique<VehiclePropValuePool>()),
mServerSidePropStore(new VehiclePropertyStore(mValuePool)),
mFakeObd2Frame(new obd2frame::FakeObd2Frame(mServerSidePropStore)),
mFakeUserHal(new FakeUserHal(mValuePool)),
mRecurrentTimer(new RecurrentTimer()),
+ mGeneratorHub(new GeneratorHub(
+ [this](const VehiclePropValue& value) { eventFromVehicleBus(value); })),
mPendingGetValueRequests(this),
- mPendingSetValueRequests(this) {
+ mPendingSetValueRequests(this),
+ mDefaultConfigDir(defaultConfigDir),
+ mOverrideConfigDir(overrideConfigDir),
+ mForceOverride(forceOverride) {
init();
}
FakeVehicleHardware::~FakeVehicleHardware() {
mPendingGetValueRequests.stop();
mPendingSetValueRequests.stop();
+ mGeneratorHub.reset();
+}
+
+std::unordered_map<int32_t, ConfigDeclaration> FakeVehicleHardware::loadConfigDeclarations() {
+ std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
+ loadPropConfigsFromDir(mDefaultConfigDir, &configsByPropId);
+ if (mForceOverride ||
+ android::base::GetBoolProperty(OVERRIDE_PROPERTY, /*default_value=*/false)) {
+ loadPropConfigsFromDir(mOverrideConfigDir, &configsByPropId);
+ }
+ return configsByPropId;
}
void FakeVehicleHardware::init() {
- for (auto& it : defaultconfig::getDefaultConfigs()) {
- VehiclePropConfig cfg = it.config;
+ for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
+ VehiclePropConfig cfg = configDeclaration.config;
VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
- if (cfg.prop == OBD2_FREEZE_FRAME) {
+ if (cfg.prop == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
+ int config = GetIntProperty(POWER_STATE_REQ_CONFIG_PROPERTY, /*default_value=*/0);
+ cfg.configArray[0] = config;
+ } else if (cfg.prop == OBD2_FREEZE_FRAME) {
tokenFunction = [](const VehiclePropValue& propValue) { return propValue.timestamp; };
}
@@ -165,15 +204,18 @@
// logic.
continue;
}
- storePropInitialValue(it);
+ storePropInitialValue(configDeclaration);
}
- maybeOverrideProperties(VENDOR_OVERRIDE_DIR);
-
// OBD2_LIVE_FRAME and OBD2_FREEZE_FRAME must be configured in default configs.
- mFakeObd2Frame->initObd2LiveFrame(*mServerSidePropStore->getConfig(OBD2_LIVE_FRAME).value());
- mFakeObd2Frame->initObd2FreezeFrame(
- *mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME).value());
+ auto maybeObd2LiveFrame = mServerSidePropStore->getConfig(OBD2_LIVE_FRAME);
+ if (maybeObd2LiveFrame.has_value()) {
+ mFakeObd2Frame->initObd2LiveFrame(*maybeObd2LiveFrame.value());
+ }
+ auto maybeObd2FreezeFrame = mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME);
+ if (maybeObd2FreezeFrame.has_value()) {
+ mFakeObd2Frame->initObd2FreezeFrame(*maybeObd2FreezeFrame.value());
+ }
mServerSidePropStore->setOnValueChangeCallback(
[this](const VehiclePropValue& value) { return onValueChangeCallback(value); });
@@ -257,16 +299,115 @@
return {};
}
-bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) {
+int FakeVehicleHardware::getHvacTempNumIncrements(int requestedTemp, int minTemp, int maxTemp,
+ int increment) {
+ requestedTemp = std::max(requestedTemp, minTemp);
+ requestedTemp = std::min(requestedTemp, maxTemp);
+ int numIncrements = (requestedTemp - minTemp) / increment;
+ return numIncrements;
+}
+
+void FakeVehicleHardware::updateHvacTemperatureValueSuggestionInput(
+ const std::vector<int>& hvacTemperatureSetConfigArray,
+ std::vector<float>* hvacTemperatureValueSuggestionInput) {
+ int minTempInCelsius = hvacTemperatureSetConfigArray[0];
+ int maxTempInCelsius = hvacTemperatureSetConfigArray[1];
+ int incrementInCelsius = hvacTemperatureSetConfigArray[2];
+
+ int minTempInFahrenheit = hvacTemperatureSetConfigArray[3];
+ int maxTempInFahrenheit = hvacTemperatureSetConfigArray[4];
+ int incrementInFahrenheit = hvacTemperatureSetConfigArray[5];
+
+ // The HVAC_TEMPERATURE_SET config array values are temperature values that have been multiplied
+ // by 10 and converted to integers. Therefore, requestedTemp must also be multiplied by 10 and
+ // converted to an integer in order for them to be the same units.
+ int requestedTemp = static_cast<int>((*hvacTemperatureValueSuggestionInput)[0] * 10.0f);
+ int numIncrements =
+ (*hvacTemperatureValueSuggestionInput)[1] == toInt(VehicleUnit::CELSIUS)
+ ? getHvacTempNumIncrements(requestedTemp, minTempInCelsius, maxTempInCelsius,
+ incrementInCelsius)
+ : getHvacTempNumIncrements(requestedTemp, minTempInFahrenheit,
+ maxTempInFahrenheit, incrementInFahrenheit);
+
+ int suggestedTempInCelsius = minTempInCelsius + incrementInCelsius * numIncrements;
+ int suggestedTempInFahrenheit = minTempInFahrenheit + incrementInFahrenheit * numIncrements;
+ // HVAC_TEMPERATURE_VALUE_SUGGESTION specifies the temperature values to be in the original
+ // floating point form so we divide by 10 and convert to float.
+ (*hvacTemperatureValueSuggestionInput)[2] = static_cast<float>(suggestedTempInCelsius) / 10.0f;
+ (*hvacTemperatureValueSuggestionInput)[3] =
+ static_cast<float>(suggestedTempInFahrenheit) / 10.0f;
+}
+
+VhalResult<void> FakeVehicleHardware::setHvacTemperatureValueSuggestion(
+ const VehiclePropValue& hvacTemperatureValueSuggestion) {
+ auto hvacTemperatureSetConfigResult =
+ mServerSidePropStore->getConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
+
+ if (!hvacTemperatureSetConfigResult.ok()) {
+ return StatusError(getErrorCode(hvacTemperatureSetConfigResult)) << StringPrintf(
+ "Failed to set HVAC_TEMPERATURE_VALUE_SUGGESTION because"
+ " HVAC_TEMPERATURE_SET could not be retrieved. Error: %s",
+ getErrorMsg(hvacTemperatureSetConfigResult).c_str());
+ }
+
+ const auto& originalInput = hvacTemperatureValueSuggestion.value.floatValues;
+ if (originalInput.size() != 4) {
+ return StatusError(StatusCode::INVALID_ARG) << StringPrintf(
+ "Failed to set HVAC_TEMPERATURE_VALUE_SUGGESTION because float"
+ " array value is not size 4.");
+ }
+
+ bool isTemperatureUnitSpecified = originalInput[1] == toInt(VehicleUnit::CELSIUS) ||
+ originalInput[1] == toInt(VehicleUnit::FAHRENHEIT);
+ if (!isTemperatureUnitSpecified) {
+ return StatusError(StatusCode::INVALID_ARG) << StringPrintf(
+ "Failed to set HVAC_TEMPERATURE_VALUE_SUGGESTION because float"
+ " value at index 1 is not any of %d or %d, which corresponds to"
+ " VehicleUnit#CELSIUS and VehicleUnit#FAHRENHEIT respectively.",
+ toInt(VehicleUnit::CELSIUS), toInt(VehicleUnit::FAHRENHEIT));
+ }
+
+ auto updatedValue = mValuePool->obtain(hvacTemperatureValueSuggestion);
+ const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value()->configArray;
+ auto& hvacTemperatureValueSuggestionInput = updatedValue->value.floatValues;
+
+ updateHvacTemperatureValueSuggestionInput(hvacTemperatureSetConfigArray,
+ &hvacTemperatureValueSuggestionInput);
+
+ updatedValue->timestamp = elapsedRealtimeNano();
+ auto writeResult = mServerSidePropStore->writeValue(std::move(updatedValue),
+ /* updateStatus = */ true,
+ VehiclePropertyStore::EventMode::ALWAYS);
+ if (!writeResult.ok()) {
+ return StatusError(getErrorCode(writeResult))
+ << StringPrintf("failed to write value into property store, error: %s",
+ getErrorMsg(writeResult).c_str());
+ }
+
+ return {};
+}
+
+bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId, int32_t areaId) const {
std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
std::end(HVAC_POWER_PROPERTIES));
if (powerProps.count(propId)) {
- auto hvacPowerOnResult =
- mServerSidePropStore->readValue(toInt(VehicleProperty::HVAC_POWER_ON), HVAC_ALL);
-
- if (hvacPowerOnResult.ok() && hvacPowerOnResult.value()->value.int32Values.size() == 1 &&
- hvacPowerOnResult.value()->value.int32Values[0] == 0) {
- return true;
+ auto hvacPowerOnResults =
+ mServerSidePropStore->readValuesForProperty(toInt(VehicleProperty::HVAC_POWER_ON));
+ if (!hvacPowerOnResults.ok()) {
+ ALOGW("failed to get HVAC_POWER_ON 0x%x, error: %s",
+ toInt(VehicleProperty::HVAC_POWER_ON), getErrorMsg(hvacPowerOnResults).c_str());
+ return false;
+ }
+ auto& hvacPowerOnValues = hvacPowerOnResults.value();
+ for (size_t j = 0; j < hvacPowerOnValues.size(); j++) {
+ auto hvacPowerOnValue = std::move(hvacPowerOnValues[j]);
+ if ((hvacPowerOnValue->areaId & areaId) == areaId) {
+ if (hvacPowerOnValue->value.int32Values.size() == 1 &&
+ hvacPowerOnValue->value.int32Values[0] == 0) {
+ return true;
+ }
+ break;
+ }
}
}
return false;
@@ -282,7 +423,11 @@
if (updatedValue != nullptr) {
ALOGI("onSetProperty(): updating property returned by HAL: %s",
updatedValue->toString().c_str());
- if (auto writeResult = mServerSidePropStore->writeValue(std::move(result.value()));
+ // Update timestamp otherwise writeValue might fail because the timestamp is outdated.
+ updatedValue->timestamp = elapsedRealtimeNano();
+ if (auto writeResult = mServerSidePropStore->writeValue(
+ std::move(result.value()),
+ /*updateStatus=*/true, VehiclePropertyStore::EventMode::ALWAYS);
!writeResult.ok()) {
return StatusError(getErrorCode(writeResult))
<< "failed to write value into property store, error: "
@@ -324,6 +469,11 @@
return getUserHalProp(value);
}
+ if (isHvacPropAndHvacNotAvailable(propId, value.areaId)) {
+ *isSpecialValue = true;
+ return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
+ }
+
switch (propId) {
case OBD2_FREEZE_FRAME:
*isSpecialValue = true;
@@ -342,6 +492,9 @@
case ECHO_REVERSE_BYTES:
*isSpecialValue = true;
return getEchoReverseBytes(value);
+ case VENDOR_PROPERTY_ID:
+ *isSpecialValue = true;
+ return StatusError((StatusCode)VENDOR_ERROR_CODE);
default:
// Do nothing.
break;
@@ -366,6 +519,29 @@
return std::move(gotValue);
}
+void FakeVehicleHardware::sendHvacPropertiesCurrentValues(int32_t areaId) {
+ for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+ int powerPropId = HVAC_POWER_PROPERTIES[i];
+ auto powerPropResults = mServerSidePropStore->readValuesForProperty(powerPropId);
+ if (!powerPropResults.ok()) {
+ ALOGW("failed to get power prop 0x%x, error: %s", powerPropId,
+ getErrorMsg(powerPropResults).c_str());
+ continue;
+ }
+ auto& powerPropValues = powerPropResults.value();
+ for (size_t j = 0; j < powerPropValues.size(); j++) {
+ auto powerPropValue = std::move(powerPropValues[j]);
+ if ((powerPropValue->areaId & areaId) == powerPropValue->areaId) {
+ powerPropValue->status = VehiclePropertyStatus::AVAILABLE;
+ powerPropValue->timestamp = elapsedRealtimeNano();
+ // This will trigger a property change event for the current hvac property value.
+ mServerSidePropStore->writeValue(std::move(powerPropValue), /*updateStatus=*/true,
+ VehiclePropertyStore::EventMode::ALWAYS);
+ }
+ }
+ }
+}
+
VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
bool* isSpecialValue) {
*isSpecialValue = false;
@@ -377,7 +553,14 @@
return setUserHalProp(value);
}
- if (isHvacPropAndHvacNotAvailable(propId)) {
+ if (propId == toInt(VehicleProperty::HVAC_POWER_ON) && value.value.int32Values.size() == 1 &&
+ value.value.int32Values[0] == 1) {
+ // If we are turning HVAC power on, send current hvac property values through on change
+ // event.
+ sendHvacPropertiesCurrentValues(value.areaId);
+ }
+
+ if (isHvacPropAndHvacNotAvailable(propId, value.areaId)) {
*isSpecialValue = true;
return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
}
@@ -394,8 +577,14 @@
case OBD2_FREEZE_FRAME_CLEAR:
*isSpecialValue = true;
return mFakeObd2Frame->clearObd2FreezeFrames(value);
+ case VENDOR_PROPERTY_ID:
+ *isSpecialValue = true;
+ return StatusError((StatusCode)VENDOR_ERROR_CODE);
+ case toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION):
+ *isSpecialValue = true;
+ return setHvacTemperatureValueSuggestion(value);
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
case toInt(VehicleProperty::CLUSTER_REPORT_STATE):
[[fallthrough]];
case toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY):
@@ -423,7 +612,7 @@
<< getErrorMsg(writeResult);
}
return {};
-#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#endif // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
default:
break;
@@ -574,34 +763,423 @@
result.buffer = dumpListProperties();
} else if (EqualsIgnoreCase(option, "--get")) {
result.buffer = dumpSpecificProperty(options);
+ } else if (EqualsIgnoreCase(option, "--getWithArg")) {
+ result.buffer = dumpGetPropertyWithArg(options);
} else if (EqualsIgnoreCase(option, "--set")) {
result.buffer = dumpSetProperties(options);
+ } else if (EqualsIgnoreCase(option, "--save-prop")) {
+ result.buffer = dumpSaveProperty(options);
+ } else if (EqualsIgnoreCase(option, "--restore-prop")) {
+ result.buffer = dumpRestoreProperty(options);
+ } else if (EqualsIgnoreCase(option, "--inject-event")) {
+ result.buffer = dumpInjectEvent(options);
} else if (EqualsIgnoreCase(option, kUserHalDumpOption)) {
- if (options.size() == 1) {
- result.buffer = mFakeUserHal->showDumpHelp();
- } else {
- result.buffer = mFakeUserHal->dump(options[1]);
- }
+ result.buffer = mFakeUserHal->dump();
+ } else if (EqualsIgnoreCase(option, "--genfakedata")) {
+ result.buffer = genFakeDataCommand(options);
} else {
result.buffer = StringPrintf("Invalid option: %s\n", option.c_str());
}
return result;
}
+std::string FakeVehicleHardware::genFakeDataHelp() {
+ return R"(
+Generate Fake Data Usage:
+--genfakedata --startlinear [propID] [mValue] [cValue] [dispersion] [increment] [interval]: "
+Start a linear generator that generates event with floatValue within range:
+[mValue - disperson, mValue + dispersion].
+propID(int32): ID for the property to generate event for.
+mValue(float): The middle of the possible values for the property.
+cValue(float): The start value for the property, must be within the range.
+dispersion(float): The range the value can change.
+increment(float): The step the value would increase by for each generated event,
+if exceed the range, the value would loop back.
+interval(int64): The interval in nanoseconds the event would generate by.
+
+--genfakedata --stoplinear [propID(int32)]: Stop a linear generator
+
+--genfakedata --startjson --path [jsonFilePath] [repetition]:
+Start a JSON generator that would generate events according to a JSON file.
+jsonFilePath(string): The path to a JSON file. The JSON content must be in the format of
+[{
+ "timestamp": 1000000,
+ "areaId": 0,
+ "value": 8,
+ "prop": 289408000
+}, {...}]
+Each event in the JSON file would be generated by the same interval their timestamp is relative to
+the first event's timestamp.
+repetition(int32, optional): how many iterations the events would be generated. If it is not
+provided, it would iterate indefinitely.
+
+--genfakedata --startjson --content [jsonContent]: Start a JSON generator using the content.
+
+--genfakedata --stopjson [generatorID(string)]: Stop a JSON generator.
+
+--genfakedata --keypress [keyCode(int32)] [display[int32]]: Generate key press.
+
+--genfakedata --keyinputv2 [area(int32)] [display(int32)] [keyCode[int32]] [action[int32]]
+ [repeatCount(int32)]
+
+--genfakedata --motioninput [area(int32)] [display(int32)] [inputType[int32]] [action[int32]]
+ [buttonState(int32)] --pointer [pointerId(int32)] [toolType(int32)] [xData(float)] [yData(float)]
+ [pressure(float)] [size(float)]
+ Generate a motion input event. --pointer option can be specified multiple times.
+
+)";
+}
+
+std::string FakeVehicleHardware::parseErrMsg(std::string fieldName, std::string value,
+ std::string type) {
+ return StringPrintf("failed to parse %s as %s: \"%s\"\n%s", fieldName.c_str(), type.c_str(),
+ value.c_str(), genFakeDataHelp().c_str());
+}
+
+std::string FakeVehicleHardware::genFakeDataCommand(const std::vector<std::string>& options) {
+ if (options.size() < 2) {
+ return "No subcommand specified for genfakedata\n" + genFakeDataHelp();
+ }
+
+ std::string command = options[1];
+ if (command == "--startlinear") {
+ // --genfakedata --startlinear [propID(int32)] [middleValue(float)]
+ // [currentValue(float)] [dispersion(float)] [increment(float)] [interval(int64)]
+ if (options.size() != 8) {
+ return "incorrect argument count, need 8 arguments for --genfakedata --startlinear\n" +
+ genFakeDataHelp();
+ }
+ int32_t propId;
+ float middleValue;
+ float currentValue;
+ float dispersion;
+ float increment;
+ int64_t interval;
+ if (!android::base::ParseInt(options[2], &propId)) {
+ return parseErrMsg("propId", options[2], "int");
+ }
+ if (!android::base::ParseFloat(options[3], &middleValue)) {
+ return parseErrMsg("middleValue", options[3], "float");
+ }
+ if (!android::base::ParseFloat(options[4], ¤tValue)) {
+ return parseErrMsg("currentValue", options[4], "float");
+ }
+ if (!android::base::ParseFloat(options[5], &dispersion)) {
+ return parseErrMsg("dispersion", options[5], "float");
+ }
+ if (!android::base::ParseFloat(options[6], &increment)) {
+ return parseErrMsg("increment", options[6], "float");
+ }
+ if (!android::base::ParseInt(options[7], &interval)) {
+ return parseErrMsg("interval", options[7], "int");
+ }
+ auto generator = std::make_unique<LinearFakeValueGenerator>(
+ propId, middleValue, currentValue, dispersion, increment, interval);
+ mGeneratorHub->registerGenerator(propId, std::move(generator));
+ return "Linear event generator started successfully";
+ } else if (command == "--stoplinear") {
+ // --genfakedata --stoplinear [propID(int32)]
+ if (options.size() != 3) {
+ return "incorrect argument count, need 3 arguments for --genfakedata --stoplinear\n" +
+ genFakeDataHelp();
+ }
+ int32_t propId;
+ if (!android::base::ParseInt(options[2], &propId)) {
+ return parseErrMsg("propId", options[2], "int");
+ }
+ if (mGeneratorHub->unregisterGenerator(propId)) {
+ return "Linear event generator stopped successfully";
+ }
+ return StringPrintf("No linear event generator found for property: %d", propId);
+ } else if (command == "--startjson") {
+ // --genfakedata --startjson --path path repetition
+ // or
+ // --genfakedata --startjson --content content repetition.
+ if (options.size() != 4 && options.size() != 5) {
+ return "incorrect argument count, need 4 or 5 arguments for --genfakedata "
+ "--startjson\n";
+ }
+ // Iterate infinitely if repetition number is not provided
+ int32_t repetition = -1;
+ if (options.size() == 5) {
+ if (!android::base::ParseInt(options[4], &repetition)) {
+ return parseErrMsg("repetition", options[4], "int");
+ }
+ }
+ std::unique_ptr<JsonFakeValueGenerator> generator;
+ if (options[2] == "--path") {
+ const std::string& fileName = options[3];
+ generator = std::make_unique<JsonFakeValueGenerator>(fileName, repetition);
+ if (!generator->hasNext()) {
+ return "invalid JSON file, no events";
+ }
+ } else if (options[2] == "--content") {
+ const std::string& content = options[3];
+ generator =
+ std::make_unique<JsonFakeValueGenerator>(/*unused=*/true, content, repetition);
+ if (!generator->hasNext()) {
+ return "invalid JSON content, no events";
+ }
+ }
+ int32_t cookie = std::hash<std::string>()(options[3]);
+ mGeneratorHub->registerGenerator(cookie, std::move(generator));
+ return StringPrintf("JSON event generator started successfully, ID: %" PRId32, cookie);
+ } else if (command == "--stopjson") {
+ // --genfakedata --stopjson [generatorID(string)]
+ if (options.size() != 3) {
+ return "incorrect argument count, need 3 arguments for --genfakedata --stopjson\n";
+ }
+ int32_t cookie;
+ if (!android::base::ParseInt(options[2], &cookie)) {
+ return parseErrMsg("cookie", options[2], "int");
+ }
+ if (mGeneratorHub->unregisterGenerator(cookie)) {
+ return "JSON event generator stopped successfully";
+ } else {
+ return StringPrintf("No JSON event generator found for ID: %s", options[2].c_str());
+ }
+ } else if (command == "--keypress") {
+ int32_t keyCode;
+ int32_t display;
+ // --genfakedata --keypress [keyCode(int32)] [display[int32]]
+ if (options.size() != 4) {
+ return "incorrect argument count, need 4 arguments for --genfakedata --keypress\n";
+ }
+ if (!android::base::ParseInt(options[2], &keyCode)) {
+ return parseErrMsg("keyCode", options[2], "int");
+ }
+ if (!android::base::ParseInt(options[3], &display)) {
+ return parseErrMsg("display", options[3], "int");
+ }
+ // Send back to HAL
+ onValueChangeCallback(
+ createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display));
+ onValueChangeCallback(
+ createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
+ return "keypress event generated successfully";
+ } else if (command == "--keyinputv2") {
+ int32_t area;
+ int32_t display;
+ int32_t keyCode;
+ int32_t action;
+ int32_t repeatCount;
+ // --genfakedata --keyinputv2 [area(int32)] [display(int32)] [keyCode[int32]]
+ // [action[int32]] [repeatCount(int32)]
+ if (options.size() != 7) {
+ return "incorrect argument count, need 7 arguments for --genfakedata --keyinputv2\n";
+ }
+ if (!android::base::ParseInt(options[2], &area)) {
+ return parseErrMsg("area", options[2], "int");
+ }
+ if (!android::base::ParseInt(options[3], &display)) {
+ return parseErrMsg("display", options[3], "int");
+ }
+ if (!android::base::ParseInt(options[4], &keyCode)) {
+ return parseErrMsg("keyCode", options[4], "int");
+ }
+ if (!android::base::ParseInt(options[5], &action)) {
+ return parseErrMsg("action", options[5], "int");
+ }
+ if (!android::base::ParseInt(options[6], &repeatCount)) {
+ return parseErrMsg("repeatCount", options[6], "int");
+ }
+ // Send back to HAL
+ onValueChangeCallback(createHwKeyInputV2Prop(area, display, keyCode, action, repeatCount));
+ return StringPrintf(
+ "keyinputv2 event generated successfully with area:%d, display:%d,"
+ " keyCode:%d, action:%d, repeatCount:%d",
+ area, display, keyCode, action, repeatCount);
+
+ } else if (command == "--motioninput") {
+ int32_t area;
+ int32_t display;
+ int32_t inputType;
+ int32_t action;
+ int32_t buttonState;
+ int32_t pointerCount;
+
+ // --genfakedata --motioninput [area(int32)] [display(int32)] [inputType[int32]]
+ // [action[int32]] [buttonState(int32)] [pointerCount(int32)]
+ // --pointer [pointerId(int32)] [toolType(int32)] [xData(float)] [yData(float)]
+ // [pressure(float)] [size(float)]
+ int optionsSize = (int)options.size();
+ if (optionsSize / 7 < 2) {
+ return "incorrect argument count, need at least 14 arguments for --genfakedata "
+ "--motioninput including at least 1 --pointer\n";
+ }
+
+ if (optionsSize % 7 != 0) {
+ return "incorrect argument count, need 6 arguments for every --pointer\n";
+ }
+ pointerCount = (int)optionsSize / 7 - 1;
+
+ if (!android::base::ParseInt(options[2], &area)) {
+ return parseErrMsg("area", options[2], "int");
+ }
+ if (!android::base::ParseInt(options[3], &display)) {
+ return parseErrMsg("display", options[3], "int");
+ }
+ if (!android::base::ParseInt(options[4], &inputType)) {
+ return parseErrMsg("inputType", options[4], "int");
+ }
+ if (!android::base::ParseInt(options[5], &action)) {
+ return parseErrMsg("action", options[5], "int");
+ }
+ if (!android::base::ParseInt(options[6], &buttonState)) {
+ return parseErrMsg("buttonState", options[6], "int");
+ }
+
+ int32_t pointerId[pointerCount];
+ int32_t toolType[pointerCount];
+ float xData[pointerCount];
+ float yData[pointerCount];
+ float pressure[pointerCount];
+ float size[pointerCount];
+
+ for (int i = 7, pc = 0; i < optionsSize; i += 7, pc += 1) {
+ int offset = i;
+ if (options[offset] != "--pointer") {
+ return "--pointer is needed for the motion input\n";
+ }
+ offset += 1;
+ if (!android::base::ParseInt(options[offset], &pointerId[pc])) {
+ return parseErrMsg("pointerId", options[offset], "int");
+ }
+ offset += 1;
+ if (!android::base::ParseInt(options[offset], &toolType[pc])) {
+ return parseErrMsg("toolType", options[offset], "int");
+ }
+ offset += 1;
+ if (!android::base::ParseFloat(options[offset], &xData[pc])) {
+ return parseErrMsg("xData", options[offset], "float");
+ }
+ offset += 1;
+ if (!android::base::ParseFloat(options[offset], &yData[pc])) {
+ return parseErrMsg("yData", options[offset], "float");
+ }
+ offset += 1;
+ if (!android::base::ParseFloat(options[offset], &pressure[pc])) {
+ return parseErrMsg("pressure", options[offset], "float");
+ }
+ offset += 1;
+ if (!android::base::ParseFloat(options[offset], &size[pc])) {
+ return parseErrMsg("size", options[offset], "float");
+ }
+ }
+
+ // Send back to HAL
+ onValueChangeCallback(createHwMotionInputProp(area, display, inputType, action, buttonState,
+ pointerCount, pointerId, toolType, xData,
+ yData, pressure, size));
+
+ std::string successMessage = StringPrintf(
+ "motion event generated successfully with area:%d, display:%d,"
+ " inputType:%d, action:%d, buttonState:%d, pointerCount:%d\n",
+ area, display, inputType, action, buttonState, pointerCount);
+ for (int i = 0; i < pointerCount; i++) {
+ successMessage += StringPrintf(
+ "Pointer #%d {\n"
+ " id:%d , tooltype:%d \n"
+ " x:%f , y:%f\n"
+ " pressure: %f, data: %f\n"
+ "}\n",
+ i, pointerId[i], toolType[i], xData[i], yData[i], pressure[i], size[i]);
+ }
+ return successMessage;
+ }
+
+ return StringPrintf("Unknown command: \"%s\"\n%s", command.c_str(), genFakeDataHelp().c_str());
+}
+
+VehiclePropValue FakeVehicleHardware::createHwInputKeyProp(VehicleHwKeyInputAction action,
+ int32_t keyCode, int32_t targetDisplay) {
+ VehiclePropValue value = {
+ .prop = toInt(VehicleProperty::HW_KEY_INPUT),
+ .areaId = 0,
+ .timestamp = elapsedRealtimeNano(),
+ .status = VehiclePropertyStatus::AVAILABLE,
+ .value.int32Values = {toInt(action), keyCode, targetDisplay},
+ };
+ return value;
+}
+
+VehiclePropValue FakeVehicleHardware::createHwKeyInputV2Prop(int32_t area, int32_t targetDisplay,
+ int32_t keyCode, int32_t action,
+ int32_t repeatCount) {
+ VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_KEY_INPUT_V2),
+ .areaId = area,
+ .timestamp = elapsedRealtimeNano(),
+ .status = VehiclePropertyStatus::AVAILABLE,
+ .value.int32Values = {targetDisplay, keyCode, action, repeatCount},
+ .value.int64Values = {elapsedRealtimeNano()}};
+ return value;
+}
+
+VehiclePropValue FakeVehicleHardware::createHwMotionInputProp(
+ int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
+ int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[], float yData[],
+ float pressure[], float size[]) {
+ std::vector<int> intValues;
+ intValues.push_back(display);
+ intValues.push_back(inputType);
+ intValues.push_back(action);
+ intValues.push_back(buttonState);
+ intValues.push_back(pointerCount);
+ for (int i = 0; i < pointerCount; i++) {
+ intValues.push_back(pointerId[i]);
+ }
+ for (int i = 0; i < pointerCount; i++) {
+ intValues.push_back(toolType[i]);
+ }
+
+ std::vector<float> floatValues;
+ for (int i = 0; i < pointerCount; i++) {
+ floatValues.push_back(xData[i]);
+ }
+ for (int i = 0; i < pointerCount; i++) {
+ floatValues.push_back(yData[i]);
+ }
+ for (int i = 0; i < pointerCount; i++) {
+ floatValues.push_back(pressure[i]);
+ }
+ for (int i = 0; i < pointerCount; i++) {
+ floatValues.push_back(size[i]);
+ }
+
+ VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_MOTION_INPUT),
+ .areaId = area,
+ .timestamp = elapsedRealtimeNano(),
+ .status = VehiclePropertyStatus::AVAILABLE,
+ .value.int32Values = intValues,
+ .value.floatValues = floatValues,
+ .value.int64Values = {elapsedRealtimeNano()}};
+ return value;
+}
+
+void FakeVehicleHardware::eventFromVehicleBus(const VehiclePropValue& value) {
+ mServerSidePropStore->writeValue(mValuePool->obtain(value));
+}
+
std::string FakeVehicleHardware::dumpHelp() {
return "Usage: \n\n"
"[no args]: dumps (id and value) all supported properties \n"
"--help: shows this help\n"
"--list: lists the ids of all supported properties\n"
- "--get <PROP1> [PROP2] [PROPN]: dumps the value of specific properties \n"
- "--set <PROP> [-i INT_VALUE [INT_VALUE ...]] [-i64 INT64_VALUE [INT64_VALUE ...]] "
- "[-f FLOAT_VALUE [FLOAT_VALUE ...]] [-s STR_VALUE] "
- "[-b BYTES_VALUE] [-a AREA_ID] : sets the value of property PROP. "
+ "--get <PROP1> [PROP2] [PROPN]: dumps the value of specific properties. \n"
+ "--getWithArg <PROP> [ValueArguments]: gets the value for a specific property with "
+ "arguments. \n"
+ "--set <PROP> [ValueArguments]: sets the value of property PROP. \n"
+ "--save-prop <prop> [-a AREA_ID]: saves the current value for PROP, integration test"
+ " that modifies prop value must call this before test and restore-prop after test. \n"
+ "--restore-prop <prop> [-a AREA_ID]: restores a previously saved property value. \n"
+ "--inject-event <PROP> [ValueArguments]: inject a property update event from car\n\n"
+ "ValueArguments are in the format of [-i INT_VALUE [INT_VALUE ...]] "
+ "[-i64 INT64_VALUE [INT64_VALUE ...]] [-f FLOAT_VALUE [FLOAT_VALUE ...]] [-s STR_VALUE] "
+ "[-b BYTES_VALUE] [-a AREA_ID].\n"
"Notice that the string, bytes and area value can be set just once, while the other can"
" have multiple values (so they're used in the respective array), "
- "BYTES_VALUE is in the form of 0xXXXX, e.g. 0xdeadbeef.\n\n"
- "Fake user HAL usage: \n" +
- mFakeUserHal->showDumpHelp();
+ "BYTES_VALUE is in the form of 0xXXXX, e.g. 0xdeadbeef.\n" +
+ genFakeDataHelp() + "Fake user HAL usage: \n" + mFakeUserHal->showDumpHelp();
}
std::string FakeVehicleHardware::dumpAllProperties() {
@@ -719,10 +1297,11 @@
return std::move(values);
}
-Result<VehiclePropValue> FakeVehicleHardware::parseSetPropOptions(
+Result<VehiclePropValue> FakeVehicleHardware::parsePropOptions(
const std::vector<std::string>& options) {
// Options format:
- // --set PROP [-f f1 f2...] [-i i1 i2...] [-i64 i1 i2...] [-s s1 s2...] [-b b1 b2...] [-a a]
+ // --set/get/inject-event PROP [-f f1 f2...] [-i i1 i2...] [-i64 i1 i2...] [-s s1 s2...]
+ // [-b b1 b2...] [-a a] [-t timestamp]
size_t optionIndex = 1;
auto result = safelyParseInt<int32_t>(optionIndex, options[optionIndex]);
if (!result.ok()) {
@@ -736,83 +1315,98 @@
std::unordered_set<std::string> parsedOptions;
while (optionIndex < options.size()) {
- std::string type = options[optionIndex];
+ std::string argType = options[optionIndex];
optionIndex++;
+
size_t currentIndex = optionIndex;
- std::vector<std::string> values = getOptionValues(options, &optionIndex);
- if (parsedOptions.find(type) != parsedOptions.end()) {
- return Error() << StringPrintf("Duplicate \"%s\" options\n", type.c_str());
+ std::vector<std::string> argValues = getOptionValues(options, &optionIndex);
+ if (parsedOptions.find(argType) != parsedOptions.end()) {
+ return Error() << StringPrintf("Duplicate \"%s\" options\n", argType.c_str());
}
- parsedOptions.insert(type);
- if (EqualsIgnoreCase(type, "-i")) {
- if (values.size() == 0) {
+ parsedOptions.insert(argType);
+ size_t argValuesSize = argValues.size();
+ if (EqualsIgnoreCase(argType, "-i")) {
+ if (argValuesSize == 0) {
return Error() << "No values specified when using \"-i\"\n";
}
- prop.value.int32Values.resize(values.size());
- for (size_t i = 0; i < values.size(); i++) {
- auto int32Result = safelyParseInt<int32_t>(currentIndex + i, values[i]);
+ prop.value.int32Values.resize(argValuesSize);
+ for (size_t i = 0; i < argValuesSize; i++) {
+ auto int32Result = safelyParseInt<int32_t>(currentIndex + i, argValues[i]);
if (!int32Result.ok()) {
return Error()
<< StringPrintf("Value: \"%s\" is not a valid int: %s\n",
- values[i].c_str(), getErrorMsg(int32Result).c_str());
+ argValues[i].c_str(), getErrorMsg(int32Result).c_str());
}
prop.value.int32Values[i] = int32Result.value();
}
- } else if (EqualsIgnoreCase(type, "-i64")) {
- if (values.size() == 0) {
+ } else if (EqualsIgnoreCase(argType, "-i64")) {
+ if (argValuesSize == 0) {
return Error() << "No values specified when using \"-i64\"\n";
}
- prop.value.int64Values.resize(values.size());
- for (size_t i = 0; i < values.size(); i++) {
- auto int64Result = safelyParseInt<int64_t>(currentIndex + i, values[i]);
+ prop.value.int64Values.resize(argValuesSize);
+ for (size_t i = 0; i < argValuesSize; i++) {
+ auto int64Result = safelyParseInt<int64_t>(currentIndex + i, argValues[i]);
if (!int64Result.ok()) {
return Error()
<< StringPrintf("Value: \"%s\" is not a valid int64: %s\n",
- values[i].c_str(), getErrorMsg(int64Result).c_str());
+ argValues[i].c_str(), getErrorMsg(int64Result).c_str());
}
prop.value.int64Values[i] = int64Result.value();
}
- } else if (EqualsIgnoreCase(type, "-f")) {
- if (values.size() == 0) {
+ } else if (EqualsIgnoreCase(argType, "-f")) {
+ if (argValuesSize == 0) {
return Error() << "No values specified when using \"-f\"\n";
}
- prop.value.floatValues.resize(values.size());
- for (size_t i = 0; i < values.size(); i++) {
- auto floatResult = safelyParseFloat(currentIndex + i, values[i]);
+ prop.value.floatValues.resize(argValuesSize);
+ for (size_t i = 0; i < argValuesSize; i++) {
+ auto floatResult = safelyParseFloat(currentIndex + i, argValues[i]);
if (!floatResult.ok()) {
return Error()
<< StringPrintf("Value: \"%s\" is not a valid float: %s\n",
- values[i].c_str(), getErrorMsg(floatResult).c_str());
+ argValues[i].c_str(), getErrorMsg(floatResult).c_str());
}
prop.value.floatValues[i] = floatResult.value();
}
- } else if (EqualsIgnoreCase(type, "-s")) {
- if (values.size() != 1) {
+ } else if (EqualsIgnoreCase(argType, "-s")) {
+ if (argValuesSize != 1) {
return Error() << "Expect exact one value when using \"-s\"\n";
}
- prop.value.stringValue = values[0];
- } else if (EqualsIgnoreCase(type, "-b")) {
- if (values.size() != 1) {
+ prop.value.stringValue = argValues[0];
+ } else if (EqualsIgnoreCase(argType, "-b")) {
+ if (argValuesSize != 1) {
return Error() << "Expect exact one value when using \"-b\"\n";
}
- auto bytesResult = parseHexString(values[0]);
+ auto bytesResult = parseHexString(argValues[0]);
if (!bytesResult.ok()) {
return Error() << StringPrintf("value: \"%s\" is not a valid hex string: %s\n",
- values[0].c_str(), getErrorMsg(bytesResult).c_str());
+ argValues[0].c_str(),
+ getErrorMsg(bytesResult).c_str());
}
prop.value.byteValues = std::move(bytesResult.value());
- } else if (EqualsIgnoreCase(type, "-a")) {
- if (values.size() != 1) {
+ } else if (EqualsIgnoreCase(argType, "-a")) {
+ if (argValuesSize != 1) {
return Error() << "Expect exact one value when using \"-a\"\n";
}
- auto int32Result = safelyParseInt<int32_t>(currentIndex, values[0]);
+ auto int32Result = safelyParseInt<int32_t>(currentIndex, argValues[0]);
if (!int32Result.ok()) {
return Error() << StringPrintf("Area ID: \"%s\" is not a valid int: %s\n",
- values[0].c_str(), getErrorMsg(int32Result).c_str());
+ argValues[0].c_str(),
+ getErrorMsg(int32Result).c_str());
}
prop.areaId = int32Result.value();
+ } else if (EqualsIgnoreCase(argType, "-t")) {
+ if (argValuesSize != 1) {
+ return Error() << "Expect exact one value when using \"-t\"\n";
+ }
+ auto int64Result = safelyParseInt<int64_t>(currentIndex, argValues[0]);
+ if (!int64Result.ok()) {
+ return Error() << StringPrintf("Timestamp: \"%s\" is not a valid int64: %s\n",
+ argValues[0].c_str(),
+ getErrorMsg(int64Result).c_str());
+ }
+ prop.timestamp = int64Result.value();
} else {
- return Error() << StringPrintf("Unknown option: %s\n", type.c_str());
+ return Error() << StringPrintf("Unknown option: %s\n", argType.c_str());
}
}
@@ -824,7 +1418,7 @@
return getErrorMsg(result);
}
- auto parseResult = parseSetPropOptions(options);
+ auto parseResult = parsePropOptions(options);
if (!parseResult.ok()) {
return getErrorMsg(parseResult);
}
@@ -847,6 +1441,123 @@
getErrorMsg(setResult).c_str());
}
+std::string FakeVehicleHardware::dumpGetPropertyWithArg(const std::vector<std::string>& options) {
+ if (auto result = checkArgumentsSize(options, 3); !result.ok()) {
+ return getErrorMsg(result);
+ }
+
+ auto parseResult = parsePropOptions(options);
+ if (!parseResult.ok()) {
+ return getErrorMsg(parseResult);
+ }
+ VehiclePropValue prop = std::move(parseResult.value());
+ ALOGD("Dump: Getting property: %s", prop.toString().c_str());
+
+ bool isSpecialValue = false;
+ auto result = maybeGetSpecialValue(prop, &isSpecialValue);
+
+ if (!isSpecialValue) {
+ result = mServerSidePropStore->readValue(prop);
+ }
+
+ if (!result.ok()) {
+ return StringPrintf("failed to read property value: %d, error: %s, code: %d\n", prop.prop,
+ getErrorMsg(result).c_str(), getIntErrorCode(result));
+ }
+ return StringPrintf("Get property result: %s\n", result.value()->toString().c_str());
+}
+
+std::string FakeVehicleHardware::dumpSaveProperty(const std::vector<std::string>& options) {
+ // Format: --save-prop PROP [-a areaID]
+ if (auto result = checkArgumentsSize(options, 2); !result.ok()) {
+ return getErrorMsg(result);
+ }
+
+ auto parseResult = parsePropOptions(options);
+ if (!parseResult.ok()) {
+ return getErrorMsg(parseResult);
+ }
+ // We are only using the prop and areaId option.
+ VehiclePropValue value = std::move(parseResult.value());
+ int32_t propId = value.prop;
+ int32_t areaId = value.areaId;
+
+ auto readResult = mServerSidePropStore->readValue(value);
+ if (!readResult.ok()) {
+ return StringPrintf("Failed to save current property value, error: %s",
+ getErrorMsg(readResult).c_str());
+ }
+
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSavedProps[PropIdAreaId{
+ .propId = propId,
+ .areaId = areaId,
+ }] = std::move(readResult.value());
+
+ return StringPrintf("Property: %" PRId32 ", areaID: %" PRId32 " saved", propId, areaId);
+}
+
+std::string FakeVehicleHardware::dumpRestoreProperty(const std::vector<std::string>& options) {
+ // Format: --restore-prop PROP [-a areaID]
+ if (auto result = checkArgumentsSize(options, 2); !result.ok()) {
+ return getErrorMsg(result);
+ }
+
+ auto parseResult = parsePropOptions(options);
+ if (!parseResult.ok()) {
+ return getErrorMsg(parseResult);
+ }
+ // We are only using the prop and areaId option.
+ VehiclePropValue value = std::move(parseResult.value());
+ int32_t propId = value.prop;
+ int32_t areaId = value.areaId;
+ VehiclePropValuePool::RecyclableType savedValue;
+
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ auto it = mSavedProps.find(PropIdAreaId{
+ .propId = propId,
+ .areaId = areaId,
+ });
+ if (it == mSavedProps.end()) {
+ return StringPrintf("No saved property for property: %" PRId32 ", areaID: %" PRId32,
+ propId, areaId);
+ }
+
+ savedValue = std::move(it->second);
+ // Remove the saved property after restoring it.
+ mSavedProps.erase(it);
+ }
+
+ // Update timestamp.
+ savedValue->timestamp = elapsedRealtimeNano();
+
+ auto writeResult = mServerSidePropStore->writeValue(std::move(savedValue));
+ if (!writeResult.ok()) {
+ return StringPrintf("Failed to restore property value, error: %s",
+ getErrorMsg(writeResult).c_str());
+ }
+
+ return StringPrintf("Property: %" PRId32 ", areaID: %" PRId32 " restored", propId, areaId);
+}
+
+std::string FakeVehicleHardware::dumpInjectEvent(const std::vector<std::string>& options) {
+ if (auto result = checkArgumentsSize(options, 3); !result.ok()) {
+ return getErrorMsg(result);
+ }
+
+ auto parseResult = parsePropOptions(options);
+ if (!parseResult.ok()) {
+ return getErrorMsg(parseResult);
+ }
+ VehiclePropValue prop = std::move(parseResult.value());
+ ALOGD("Dump: Injecting event from vehicle bus: %s", prop.toString().c_str());
+
+ eventFromVehicleBus(prop);
+
+ return StringPrintf("Event for property: %d injected", prop.prop);
+}
+
StatusCode FakeVehicleHardware::checkHealth() {
// Always return OK for checkHealth.
return StatusCode::OK;
@@ -854,13 +1565,19 @@
void FakeVehicleHardware::registerOnPropertyChangeEvent(
std::unique_ptr<const PropertyChangeCallback> callback) {
- std::scoped_lock<std::mutex> lockGuard(mLock);
+ if (mOnPropertyChangeCallback != nullptr) {
+ ALOGE("registerOnPropertyChangeEvent must only be called once");
+ return;
+ }
mOnPropertyChangeCallback = std::move(callback);
}
void FakeVehicleHardware::registerOnPropertySetErrorEvent(
std::unique_ptr<const PropertySetErrorCallback> callback) {
- std::scoped_lock<std::mutex> lockGuard(mLock);
+ if (mOnPropertySetErrorCallback != nullptr) {
+ ALOGE("registerOnPropertySetErrorEvent must only be called once");
+ return;
+ }
mOnPropertySetErrorCallback = std::move(callback);
}
@@ -904,8 +1621,6 @@
}
void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) {
- std::scoped_lock<std::mutex> lockGuard(mLock);
-
if (mOnPropertyChangeCallback == nullptr) {
return;
}
@@ -915,33 +1630,26 @@
(*mOnPropertyChangeCallback)(std::move(updatedValues));
}
-void FakeVehicleHardware::maybeOverrideProperties(const char* overrideDir) {
- if (android::base::GetBoolProperty(OVERRIDE_PROPERTY, false)) {
- overrideProperties(overrideDir);
- }
-}
-
-void FakeVehicleHardware::overrideProperties(const char* overrideDir) {
- ALOGI("loading vendor override properties from %s", overrideDir);
- if (auto dir = opendir(overrideDir); dir != NULL) {
+void FakeVehicleHardware::loadPropConfigsFromDir(
+ const std::string& dirPath,
+ std::unordered_map<int32_t, ConfigDeclaration>* configsByPropId) {
+ ALOGI("loading properties from %s", dirPath.c_str());
+ if (auto dir = opendir(dirPath.c_str()); dir != NULL) {
std::regex regJson(".*[.]json", std::regex::icase);
while (auto f = readdir(dir)) {
if (!std::regex_match(f->d_name, regJson)) {
continue;
}
- std::string file = overrideDir + std::string(f->d_name);
- JsonFakeValueGenerator tmpGenerator(file);
-
- std::vector<VehiclePropValue> propValues = tmpGenerator.getAllEvents();
- for (const VehiclePropValue& prop : propValues) {
- auto propToStore = mValuePool->obtain(prop);
- propToStore->timestamp = elapsedRealtimeNano();
- if (auto result = mServerSidePropStore->writeValue(std::move(propToStore),
- /*updateStatus=*/true);
- !result.ok()) {
- ALOGW("failed to write vendor override properties: %d, error: %s, code: %d",
- prop.prop, getErrorMsg(result).c_str(), getIntErrorCode(result));
- }
+ std::string filePath = dirPath + "/" + std::string(f->d_name);
+ ALOGI("loading properties from %s", filePath.c_str());
+ auto result = mLoader.loadPropConfig(filePath);
+ if (!result.ok()) {
+ ALOGE("failed to load config file: %s, error: %s", filePath.c_str(),
+ result.error().message().c_str());
+ continue;
+ }
+ for (auto& [propId, configDeclaration] : result.value()) {
+ (*configsByPropId)[propId] = std::move(configDeclaration);
}
}
closedir(dir);
@@ -1027,11 +1735,15 @@
std::unordered_map<std::shared_ptr<const GetValuesCallback>, std::vector<GetValueResult>>
callbackToResults;
for (const auto& rwc : mRequests.flush()) {
+ ATRACE_BEGIN("FakeVehicleHardware:handleGetValueRequest");
auto result = mHardware->handleGetValueRequest(rwc.request);
+ ATRACE_END();
callbackToResults[rwc.callback].push_back(std::move(result));
}
for (const auto& [callback, results] : callbackToResults) {
+ ATRACE_BEGIN("FakeVehicleHardware:call get value result callback");
(*callback)(std::move(results));
+ ATRACE_END();
}
}
@@ -1041,11 +1753,15 @@
std::unordered_map<std::shared_ptr<const SetValuesCallback>, std::vector<SetValueResult>>
callbackToResults;
for (const auto& rwc : mRequests.flush()) {
+ ATRACE_BEGIN("FakeVehicleHardware:handleSetValueRequest");
auto result = mHardware->handleSetValueRequest(rwc.request);
+ ATRACE_END();
callbackToResults[rwc.callback].push_back(std::move(result));
}
for (const auto& [callback, results] : callbackToResults) {
+ ATRACE_BEGIN("FakeVehicleHardware:call set value result callback");
(*callback)(std::move(results));
+ ATRACE_END();
}
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
index 90d1516..8d8fcf5 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
@@ -22,13 +22,13 @@
name: "FakeVehicleHardwareTest",
vendor: true,
srcs: ["*.cpp"],
- cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
+ cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
header_libs: [
"IVehicleHardware",
- "VehicleHalDefaultConfig",
"VehicleHalTestUtilHeaders",
],
static_libs: [
+ "VehicleHalJsonConfigLoaderEnableTestProperties",
"VehicleHalUtils",
"FakeVehicleHardware",
"FakeVehicleHalValueGenerators",
@@ -41,7 +41,11 @@
"libjsoncpp",
],
data: [
+ ":VehicleHalDefaultProperties_JSON",
+ ":VehicleHalTestProperties_JSON",
+ ":VehicleHalVendorClusterTestProperties_JSON",
":FakeVehicleHardwareTestOverrideJson",
+ ":FakeVehicleHardwareTestPropJson",
],
defaults: ["VehicleHalDefaults"],
test_suites: ["device-tests"],
@@ -51,3 +55,8 @@
name: "FakeVehicleHardwareTestOverrideJson",
srcs: ["override/*"],
}
+
+filegroup {
+ name: "FakeVehicleHardwareTestPropJson",
+ srcs: ["fakedata/prop.json"],
+}
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 3e8f634..a50b4ad 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -16,7 +16,6 @@
#include <FakeVehicleHardware.h>
-#include <DefaultConfig.h>
#include <FakeObd2Frame.h>
#include <FakeUserHal.h>
#include <PropertyUtils.h>
@@ -53,17 +52,21 @@
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
using ::android::base::expected;
using ::android::base::ScopedLockAssertion;
using ::android::base::StringPrintf;
using ::android::base::unexpected;
+using ::testing::AnyOfArray;
using ::testing::ContainerEq;
using ::testing::ContainsRegex;
using ::testing::Eq;
+using ::testing::HasSubstr;
using ::testing::WhenSortedBy;
using std::chrono::milliseconds;
@@ -78,7 +81,9 @@
public:
FakeVehicleHardwareTestHelper(FakeVehicleHardware* hardware) { mHardware = hardware; }
- void overrideProperties(const char* overrideDir) { mHardware->overrideProperties(overrideDir); }
+ std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations() {
+ return mHardware->loadConfigDeclarations();
+ }
private:
FakeVehicleHardware* mHardware;
@@ -87,6 +92,9 @@
class FakeVehicleHardwareTest : public ::testing::Test {
protected:
void SetUp() override {
+ mHardware = std::make_unique<FakeVehicleHardware>(android::base::GetExecutableDirectory(),
+ /*overrideConfigDir=*/"",
+ /*forceOverride=*/false);
auto callback = std::make_unique<IVehicleHardware::PropertyChangeCallback>(
[this](const std::vector<VehiclePropValue>& values) {
onPropertyChangeEvent(values);
@@ -98,7 +106,17 @@
[this](std::vector<GetValueResult> results) { onGetValues(results); });
}
- FakeVehicleHardware* getHardware() { return &mHardware; }
+ void TearDown() override {
+ // mHardware uses callback which contains reference to 'this', so it has to be destroyed
+ // before 'this'.
+ mHardware.reset();
+ }
+
+ FakeVehicleHardware* getHardware() { return mHardware.get(); }
+
+ void setHardware(std::unique_ptr<FakeVehicleHardware> hardware) {
+ mHardware = std::move(hardware);
+ }
StatusCode setValues(const std::vector<SetValueRequest>& requests) {
{
@@ -251,6 +269,14 @@
return mChangedProperties;
}
+ bool waitForChangedProperties(size_t count, milliseconds timeout) {
+ std::unique_lock<std::mutex> lk(mLock);
+ return mCv.wait_for(lk, timeout, [this, count] {
+ ScopedLockAssertion lockAssertion(mLock);
+ return mChangedProperties.size() >= count;
+ });
+ }
+
bool waitForChangedProperties(int32_t propId, int32_t areaId, size_t count,
milliseconds timeout) {
PropIdAreaId propIdAreaId{
@@ -270,6 +296,15 @@
mChangedProperties.clear();
}
+ size_t getEventCount(int32_t propId, int32_t areaId) {
+ PropIdAreaId propIdAreaId{
+ .propId = propId,
+ .areaId = areaId,
+ };
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mEventCount[propIdAreaId];
+ }
+
static void addSetValueRequest(std::vector<SetValueRequest>& requests,
std::vector<SetValueResult>& expectedResults, int64_t requestId,
const VehiclePropValue& value, StatusCode expectedStatus) {
@@ -332,7 +367,7 @@
} mPropValueCmp;
private:
- FakeVehicleHardware mHardware;
+ std::unique_ptr<FakeVehicleHardware> mHardware;
std::shared_ptr<IVehicleHardware::SetValuesCallback> mSetValuesCallback;
std::shared_ptr<IVehicleHardware::GetValuesCallback> mGetValuesCallback;
std::condition_variable mCv;
@@ -348,7 +383,8 @@
TEST_F(FakeVehicleHardwareTest, testGetAllPropertyConfigs) {
std::vector<VehiclePropConfig> configs = getHardware()->getAllPropertyConfigs();
- ASSERT_EQ(configs.size(), defaultconfig::getDefaultConfigs().size());
+ FakeVehicleHardwareTestHelper helper(getHardware());
+ ASSERT_EQ(configs.size(), helper.loadConfigDeclarations().size());
}
TEST_F(FakeVehicleHardwareTest, testGetDefaultValues) {
@@ -356,7 +392,8 @@
std::vector<GetValueResult> expectedGetValueResults;
int64_t requestId = 1;
- for (auto& config : defaultconfig::getDefaultConfigs()) {
+ FakeVehicleHardwareTestHelper helper(getHardware());
+ for (auto& [propId, config] : helper.loadConfigDeclarations()) {
if (obd2frame::FakeObd2Frame::isDiagnosticProperty(config.config)) {
// Ignore storing default value for diagnostic property. They have special get/set
// logic.
@@ -368,12 +405,16 @@
continue;
}
- if (config.config.prop == ECHO_REVERSE_BYTES) {
+ if (propId == ECHO_REVERSE_BYTES) {
// Ignore ECHO_REVERSE_BYTES, it has special logic.
continue;
}
- int propId = config.config.prop;
+ if (propId == VENDOR_PROPERTY_ID) {
+ // Ignore VENDOR_PROPERTY_ID, it has special logic.
+ continue;
+ }
+
if (isGlobalProp(propId)) {
if (config.initialValue == RawPropValues{}) {
addGetValueRequest(getValueRequests, expectedGetValueResults, requestId++,
@@ -631,10 +672,12 @@
}
TEST_F(FakeVehicleHardwareTest, testVendorOverrideProperties) {
- std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
+ std::string currentDir = android::base::GetExecutableDirectory();
+ std::string overrideDir = currentDir + "/override/";
// Set vendor override directory.
- FakeVehicleHardwareTestHelper helper(getHardware());
- helper.overrideProperties(overrideDir.c_str());
+ std::unique_ptr<FakeVehicleHardware> hardware =
+ std::make_unique<FakeVehicleHardware>(currentDir, overrideDir, /*forceOverride=*/true);
+ setHardware(std::move(hardware));
// This is the same as the prop in 'gear_selection.json'.
int gearProp = toInt(VehicleProperty::GEAR_SELECTION);
@@ -669,10 +712,12 @@
}
TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesMultipleAreas) {
- std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
+ std::string currentDir = android::base::GetExecutableDirectory();
+ std::string overrideDir = currentDir + "/override/";
// Set vendor override directory.
- FakeVehicleHardwareTestHelper helper(getHardware());
- helper.overrideProperties(overrideDir.c_str());
+ std::unique_ptr<FakeVehicleHardware> hardware =
+ std::make_unique<FakeVehicleHardware>(currentDir, overrideDir, /*forceOverride=*/true);
+ setHardware(std::move(hardware));
// This is the same as the prop in 'hvac_temperature_set.json'.
int hvacProp = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
@@ -685,22 +730,16 @@
ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result);
ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size());
ASSERT_EQ(30.0f, result.value().value.floatValues[0]);
-
- // HVAC_RIGHT should not be affected and return the default value.
- result = getValue(VehiclePropValue{
- .prop = hvacProp,
- .areaId = HVAC_RIGHT,
- });
-
- ASSERT_TRUE(result.ok()) << "expect to get the default property ok: " << getStatus(result);
- ASSERT_EQ(static_cast<size_t>(1), result.value().value.floatValues.size());
- ASSERT_EQ(20.0f, result.value().value.floatValues[0]);
}
TEST_F(FakeVehicleHardwareTest, testVendorOverridePropertiesDirDoesNotExist) {
- // Set vendor override directory to a non-existing dir
- FakeVehicleHardwareTestHelper helper(getHardware());
- helper.overrideProperties("123");
+ std::string currentDir = android::base::GetExecutableDirectory();
+ std::string overrideDir = currentDir + "/override/";
+ // Set vendor override directory to a non-existing dir.
+ std::unique_ptr<FakeVehicleHardware> hardware =
+ std::make_unique<FakeVehicleHardware>(currentDir, "1234", /*forceOverride=*/true);
+ setHardware(std::move(hardware));
+
auto result = getValue(VehiclePropValue{
.prop = toInt(VehicleProperty::GEAR_SELECTION),
});
@@ -1108,6 +1147,104 @@
EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
}
+TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
+ int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
+ for (int areaId : seatAreaIds) {
+ StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = areaId,
+ .value.int32Values = {0}});
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+ int powerPropId = HVAC_POWER_PROPERTIES[i];
+ for (int powerDependentAreaId : seatAreaIds) {
+ auto getValueResult = getValue(VehiclePropValue{
+ .prop = powerPropId,
+ .areaId = powerDependentAreaId,
+ });
+
+ if (areaId == powerDependentAreaId) {
+ EXPECT_FALSE(getValueResult.ok());
+ EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
+ } else {
+ EXPECT_TRUE(getValueResult.ok());
+ }
+ }
+ }
+
+ // Resetting HVAC_POWER_ON at areaId back to ON state to ensure that there's no dependence
+ // on this value from any power dependent property values other than those with the same
+ // areaId.
+ setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = areaId,
+ .value.int32Values = {1}});
+ }
+}
+
+TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
+ int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
+ for (int areaId : seatAreaIds) {
+ StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = areaId,
+ .value.int32Values = {0}});
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+ int powerPropId = HVAC_POWER_PROPERTIES[i];
+ for (int powerDependentAreaId : seatAreaIds) {
+ StatusCode status = setValue(VehiclePropValue{.prop = powerPropId,
+ .areaId = powerDependentAreaId,
+ .value.int32Values = {1}});
+
+ if (areaId == powerDependentAreaId) {
+ EXPECT_EQ(status, StatusCode::NOT_AVAILABLE);
+ } else {
+ EXPECT_EQ(status, StatusCode::OK);
+ }
+ }
+ }
+
+ // Resetting HVAC_POWER_ON at areaId back to ON state to ensure that there's no dependence
+ // on this value from any power dependent property values other than those with the same
+ // areaId.
+ setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = areaId,
+ .value.int32Values = {1}});
+ }
+}
+
+TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
+ int seatAreaIds[5] = {SEAT_1_LEFT, SEAT_1_RIGHT, SEAT_2_LEFT, SEAT_2_CENTER, SEAT_2_RIGHT};
+ for (int areaId : seatAreaIds) {
+ StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = areaId,
+ .value.int32Values = {0}});
+
+ ASSERT_EQ(status, StatusCode::OK);
+
+ clearChangedProperties();
+ setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+ .areaId = areaId,
+ .value.int32Values = {1}});
+
+ auto events = getChangedProperties();
+ // If we turn HVAC power on, we expect to receive one property event for every HVAC prop
+ // areas plus one event for HVAC_POWER_ON.
+ std::vector<int32_t> changedPropIds;
+ for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+ changedPropIds.push_back(HVAC_POWER_PROPERTIES[i]);
+ }
+ changedPropIds.push_back(toInt(VehicleProperty::HVAC_POWER_ON));
+
+ for (const auto& event : events) {
+ EXPECT_EQ(event.areaId, areaId);
+ EXPECT_THAT(event.prop, AnyOfArray(changedPropIds));
+ }
+ }
+}
+
TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) {
for (VehicleProperty prop : std::vector<VehicleProperty>({
VehicleProperty::INITIAL_USER_INFO,
@@ -1191,6 +1328,8 @@
ASSERT_EQ(events.size(), static_cast<size_t>(1));
events[0].timestamp = 0;
+ // The returned event will have area ID 0.
+ valueToSet.areaId = 0;
ASSERT_EQ(events[0], valueToSet);
// Try to get switch_user again, should return default value.
@@ -1245,6 +1384,8 @@
auto events = getChangedProperties();
ASSERT_EQ(events.size(), static_cast<size_t>(1));
events[0].timestamp = 0;
+ // The returned event will have area ID 0.
+ valueToSet.areaId = 0;
EXPECT_EQ(events[0], valueToSet);
// Try to get create_user again, should return default value.
@@ -1298,7 +1439,7 @@
ASSERT_EQ(events.size(), static_cast<size_t>(1));
events[0].timestamp = 0;
EXPECT_EQ(events[0], (VehiclePropValue{
- .areaId = 1,
+ .areaId = 0,
.prop = toInt(VehicleProperty::INITIAL_USER_INFO),
.value.int32Values = {3, 1, 11},
}));
@@ -1395,6 +1536,85 @@
ASSERT_THAT(result.buffer, ContainsRegex("Invalid number of arguments"));
}
+TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertyWithArg) {
+ auto getValueResult = getValue(VehiclePropValue{.prop = OBD2_FREEZE_FRAME_INFO});
+ ASSERT_TRUE(getValueResult.ok());
+ auto propValue = getValueResult.value();
+ ASSERT_EQ(propValue.value.int64Values.size(), static_cast<size_t>(3))
+ << "expect 3 obd2 freeze frames stored";
+
+ std::string propIdStr = StringPrintf("%d", OBD2_FREEZE_FRAME);
+ DumpResult result;
+ for (int64_t timestamp : propValue.value.int64Values) {
+ result = getHardware()->dump(
+ {"--getWithArg", propIdStr, "-i64", StringPrintf("%" PRId64, timestamp)});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_NE(result.buffer, "");
+ ASSERT_THAT(result.buffer, ContainsRegex("Get property result:"));
+ }
+
+ // Set the timestamp argument to 0.
+ result = getHardware()->dump({"--getWithArg", propIdStr, "-i64", "0"});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ // There is no freeze obd2 frame at timestamp 0.
+ ASSERT_THAT(result.buffer, ContainsRegex("failed to read property value"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testSaveRestoreProp) {
+ int32_t prop = toInt(VehicleProperty::TIRE_PRESSURE);
+ std::string propIdStr = std::to_string(prop);
+ std::string areaIdStr = std::to_string(WHEEL_FRONT_LEFT);
+
+ DumpResult result = getHardware()->dump({"--save-prop", propIdStr, "-a", areaIdStr});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, ContainsRegex("saved"));
+
+ ASSERT_EQ(setValue(VehiclePropValue{
+ .prop = prop,
+ .areaId = WHEEL_FRONT_LEFT,
+ .value =
+ {
+ .floatValues = {210.0},
+ },
+ }),
+ StatusCode::OK);
+
+ result = getHardware()->dump({"--restore-prop", propIdStr, "-a", areaIdStr});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, ContainsRegex("restored"));
+
+ auto getResult = getValue(VehiclePropValue{.prop = prop, .areaId = WHEEL_FRONT_LEFT});
+
+ ASSERT_TRUE(getResult.ok());
+ // The default value is 200.0.
+ ASSERT_EQ(getResult.value().value.floatValues, std::vector<float>{200.0});
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpInjectEvent) {
+ int32_t prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
+ std::string propIdStr = std::to_string(prop);
+
+ int64_t timestamp = elapsedRealtimeNano();
+ // Inject an event with float value 123.4 and timestamp.
+ DumpResult result = getHardware()->dump(
+ {"--inject-event", propIdStr, "-f", "123.4", "-t", std::to_string(timestamp)});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer,
+ ContainsRegex(StringPrintf("Event for property: %d injected", prop)));
+ ASSERT_TRUE(waitForChangedProperties(prop, 0, /*count=*/1, milliseconds(1000)))
+ << "No changed event received for injected event from vehicle bus";
+ auto events = getChangedProperties();
+ ASSERT_EQ(events.size(), 1u);
+ auto event = events[0];
+ ASSERT_EQ(event.timestamp, timestamp);
+ ASSERT_EQ(event.value.floatValues, std::vector<float>({123.4}));
+}
+
TEST_F(FakeVehicleHardwareTest, testDumpInvalidOptions) {
std::vector<std::string> options;
options.push_back("--invalid");
@@ -1405,26 +1625,16 @@
ASSERT_THAT(result.buffer, ContainsRegex("Invalid option: --invalid"));
}
-TEST_F(FakeVehicleHardwareTest, testDumpFakeUserHalHelp) {
- std::vector<std::string> options;
- options.push_back("--user-hal");
-
- DumpResult result = getHardware()->dump(options);
- ASSERT_FALSE(result.callerShouldDumpState);
- ASSERT_NE(result.buffer, "");
- ASSERT_THAT(result.buffer, ContainsRegex("dumps state used for user management"));
-}
-
TEST_F(FakeVehicleHardwareTest, testDumpFakeUserHal) {
std::vector<std::string> options;
options.push_back("--user-hal");
- // Indent: " ".
- options.push_back(" ");
DumpResult result = getHardware()->dump(options);
ASSERT_FALSE(result.callerShouldDumpState);
ASSERT_NE(result.buffer, "");
- ASSERT_THAT(result.buffer, ContainsRegex(" No InitialUserInfo response\n"));
+ ASSERT_THAT(result.buffer,
+ ContainsRegex("No InitialUserInfo response\nNo SwitchUser response\nNo CreateUser "
+ "response\nNo SetUserIdentificationAssociation response\n"));
}
struct SetPropTestCase {
@@ -1606,6 +1816,386 @@
ASSERT_EQ(3.402823466E+38f, value.value.floatValues[2]);
}
+struct OptionsTestCase {
+ std::string name;
+ std::vector<std::string> options;
+ std::string expectMsg;
+};
+
+class FakeVehicleHardwareOptionsTest : public FakeVehicleHardwareTest,
+ public testing::WithParamInterface<OptionsTestCase> {};
+
+std::vector<OptionsTestCase> GenInvalidOptions() {
+ return {{"unknown_command", {"--unknown"}, "Invalid option: --unknown"},
+ {"help", {"--help"}, "Usage:"},
+ {"genfakedata_no_subcommand",
+ {"--genfakedata"},
+ "No subcommand specified for genfakedata"},
+ {"genfakedata_unknown_subcommand",
+ {"--genfakedata", "--unknown"},
+ "Unknown command: \"--unknown\""},
+ {"genfakedata_start_linear_no_args",
+ {"--genfakedata", "--startlinear"},
+ "incorrect argument count"},
+ {"genfakedata_start_linear_invalid_propId",
+ {"--genfakedata", "--startlinear", "abcd", "0.1", "0.1", "0.1", "0.1", "100000000"},
+ "failed to parse propId as int: \"abcd\""},
+ {"genfakedata_start_linear_invalid_middleValue",
+ {"--genfakedata", "--startlinear", "1", "abcd", "0.1", "0.1", "0.1", "100000000"},
+ "failed to parse middleValue as float: \"abcd\""},
+ {"genfakedata_start_linear_invalid_currentValue",
+ {"--genfakedata", "--startlinear", "1", "0.1", "abcd", "0.1", "0.1", "100000000"},
+ "failed to parse currentValue as float: \"abcd\""},
+ {"genfakedata_start_linear_invalid_dispersion",
+ {"--genfakedata", "--startlinear", "1", "0.1", "0.1", "abcd", "0.1", "100000000"},
+ "failed to parse dispersion as float: \"abcd\""},
+ {"genfakedata_start_linear_invalid_increment",
+ {"--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "abcd", "100000000"},
+ "failed to parse increment as float: \"abcd\""},
+ {"genfakedata_start_linear_invalid_interval",
+ {"--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "0.1", "0.1"},
+ "failed to parse interval as int: \"0.1\""},
+ {"genfakedata_stop_linear_no_args",
+ {"--genfakedata", "--stoplinear"},
+ "incorrect argument count"},
+ {"genfakedata_stop_linear_invalid_propId",
+ {"--genfakedata", "--stoplinear", "abcd"},
+ "failed to parse propId as int: \"abcd\""},
+ {"genfakedata_startjson_no_args",
+ {"--genfakedata", "--startjson"},
+ "incorrect argument count"},
+ {"genfakedata_startjson_invalid_repetition",
+ {"--genfakedata", "--startjson", "--path", "file", "0.1"},
+ "failed to parse repetition as int: \"0.1\""},
+ {"genfakedata_startjson_invalid_json_file",
+ {"--genfakedata", "--startjson", "--path", "file", "1"},
+ "invalid JSON file"},
+ {"genfakedata_stopjson_no_args",
+ {"--genfakedata", "--stopjson"},
+ "incorrect argument count"},
+ {"genfakedata_keypress_no_args",
+ {"--genfakedata", "--keypress"},
+ "incorrect argument count"},
+ {"genfakedata_keypress_invalid_keyCode",
+ {"--genfakedata", "--keypress", "0.1", "1"},
+ "failed to parse keyCode as int: \"0.1\""},
+ {"genfakedata_keypress_invalid_display",
+ {"--genfakedata", "--keypress", "1", "0.1"},
+ "failed to parse display as int: \"0.1\""},
+ {"genfakedata_keyinputv2_incorrect_arguments",
+ {"--genfakedata", "--keyinputv2", "1", "1"},
+ "incorrect argument count, need 7 arguments for --genfakedata --keyinputv2\n"},
+ {"genfakedata_keyinputv2_invalid_area",
+ {"--genfakedata", "--keyinputv2", "0.1", "1", "1", "1", "1"},
+ "failed to parse area as int: \"0.1\""},
+ {"genfakedata_keyinputv2_invalid_display",
+ {"--genfakedata", "--keyinputv2", "1", "0.1", "1", "1", "1"},
+ "failed to parse display as int: \"0.1\""},
+ {"genfakedata_keyinputv2_invalid_keycode",
+ {"--genfakedata", "--keyinputv2", "1", "1", "0.1", "1", "1"},
+ "failed to parse keyCode as int: \"0.1\""},
+ {"genfakedata_keyinputv2_invalid_action",
+ {"--genfakedata", "--keyinputv2", "1", "1", "1", "0.1", "1"},
+ "failed to parse action as int: \"0.1\""},
+ {"genfakedata_keyinputv2_invalid_repeatcount",
+ {"--genfakedata", "--keyinputv2", "1", "1", "1", "1", "0.1"},
+ "failed to parse repeatCount as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_argument_count",
+ {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1"},
+ "incorrect argument count, need at least 14 arguments for --genfakedata "
+ "--motioninput including at least 1 --pointer\n"},
+ {"genfakedata_motioninput_pointer_invalid_argument_count",
+ {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "1", "1", "1",
+ "1", "1", "1", "--pointer"},
+ "incorrect argument count, need 6 arguments for every --pointer\n"},
+ {"genfakedata_motioninput_invalid_area",
+ {"--genfakedata", "--motioninput", "0.1", "1", "1", "1", "1", "--pointer", "1", "1",
+ "1", "1", "1", "1"},
+ "failed to parse area as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_display",
+ {"--genfakedata", "--motioninput", "1", "0.1", "1", "1", "1", "--pointer", "1", "1",
+ "1", "1", "1", "1"},
+ "failed to parse display as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_inputtype",
+ {"--genfakedata", "--motioninput", "1", "1", "0.1", "1", "1", "--pointer", "1", "1",
+ "1", "1", "1", "1"},
+ "failed to parse inputType as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_action",
+ {"--genfakedata", "--motioninput", "1", "1", "1", "0.1", "1", "--pointer", "1", "1",
+ "1", "1", "1", "1"},
+ "failed to parse action as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_buttonstate",
+ {"--genfakedata", "--motioninput", "1", "1", "1", "1", "0.1", "--pointer", "1", "1",
+ "1.2", "1.2", "1.2", "1.2"},
+ "failed to parse buttonState as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_pointerid",
+ {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "0.1", "1",
+ "1.2", "1", "1", "1"},
+ "failed to parse pointerId as int: \"0.1\""},
+ {"genfakedata_motioninput_invalid_tooltype",
+ {"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "1", "0.1",
+ "1.2", "1", "1", "1"},
+ "failed to parse toolType as int: \"0.1\""}};
+}
+
+TEST_P(FakeVehicleHardwareOptionsTest, testInvalidOptions) {
+ auto tc = GetParam();
+
+ DumpResult result = getHardware()->dump(tc.options);
+
+ EXPECT_FALSE(result.callerShouldDumpState);
+ EXPECT_THAT(result.buffer, HasSubstr(tc.expectMsg));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ FakeVehicleHardwareOptionsTests, FakeVehicleHardwareOptionsTest,
+ testing::ValuesIn(GenInvalidOptions()),
+ [](const testing::TestParamInfo<FakeVehicleHardwareOptionsTest::ParamType>& info) {
+ return info.param.name;
+ });
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataLinear) {
+ // Start a fake linear data generator for vehicle speed at 0.1s interval.
+ // range: 0 - 100, current value: 30, step: 20.
+ std::string propIdString = StringPrintf("%d", toInt(VehicleProperty::PERF_VEHICLE_SPEED));
+ std::vector<std::string> options = {"--genfakedata", "--startlinear", propIdString,
+ /*middleValue=*/"50",
+ /*currentValue=*/"30",
+ /*dispersion=*/"50",
+ /*increment=*/"20",
+ /*interval=*/"100000000"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ ASSERT_TRUE(waitForChangedProperties(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 0, /*count=*/5,
+ milliseconds(1000)))
+ << "not enough events generated for linear data generator";
+
+ int32_t value = 30;
+ auto events = getChangedProperties();
+ for (size_t i = 0; i < 5; i++) {
+ ASSERT_EQ(1u, events[i].value.floatValues.size());
+ EXPECT_EQ(static_cast<float>(value), events[i].value.floatValues[0]);
+ value = (value + 20) % 100;
+ }
+
+ // Stop the linear generator.
+ options = {"--genfakedata", "--stoplinear", propIdString};
+
+ result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ clearChangedProperties();
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+
+ // There should be no new events generated.
+ EXPECT_EQ(0u, getEventCount(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 0));
+}
+
+std::string getTestFilePath(const char* filename) {
+ static std::string baseDir = android::base::GetExecutableDirectory();
+ return baseDir + "/fakedata/" + filename;
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJson) {
+ std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+ getTestFilePath("prop.json"), "2"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ ASSERT_TRUE(waitForChangedProperties(/*count=*/8, milliseconds(1000)))
+ << "not enough events generated for JSON data generator";
+
+ auto events = getChangedProperties();
+ ASSERT_EQ(8u, events.size());
+ // First set of events, we test 1st and the last.
+ EXPECT_EQ(1u, events[0].value.int32Values.size());
+ EXPECT_EQ(8, events[0].value.int32Values[0]);
+ EXPECT_EQ(1u, events[3].value.int32Values.size());
+ EXPECT_EQ(10, events[3].value.int32Values[0]);
+ // Second set of the same events.
+ EXPECT_EQ(1u, events[4].value.int32Values.size());
+ EXPECT_EQ(8, events[4].value.int32Values[0]);
+ EXPECT_EQ(1u, events[7].value.int32Values.size());
+ EXPECT_EQ(10, events[7].value.int32Values[0]);
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonByContent) {
+ std::vector<std::string> options = {
+ "--genfakedata", "--startjson", "--content",
+ "[{\"timestamp\":1000000,\"areaId\":0,\"value\":8,\"prop\":289408000}]", "1"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ ASSERT_TRUE(waitForChangedProperties(/*count=*/1, milliseconds(1000)))
+ << "not enough events generated for JSON data generator";
+
+ auto events = getChangedProperties();
+ ASSERT_EQ(1u, events.size());
+ EXPECT_EQ(1u, events[0].value.int32Values.size());
+ EXPECT_EQ(8, events[0].value.int32Values[0]);
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonInvalidContent) {
+ std::vector<std::string> options = {"--genfakedata", "--startjson", "--content", "[{", "2"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("invalid JSON content"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonInvalidFile) {
+ std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+ getTestFilePath("blahblah.json"), "2"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("invalid JSON file"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonStop) {
+ // No iteration number provided, would loop indefinitely.
+ std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+ getTestFilePath("prop.json")};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ std::string id = result.buffer.substr(result.buffer.find("ID: ") + 4);
+
+ result = getHardware()->dump({"--genfakedata", "--stopjson", id});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataJsonStopInvalidFile) {
+ // No iteration number provided, would loop indefinitely.
+ std::vector<std::string> options = {"--genfakedata", "--startjson", "--path",
+ getTestFilePath("prop.json")};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ result = getHardware()->dump({"--genfakedata", "--stopjson", "1234"});
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("No JSON event generator found"));
+
+ // TearDown function should destroy the generator which stops the iteration.
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataKeyPress) {
+ std::vector<std::string> options = {"--genfakedata", "--keypress", "1", "2"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ auto events = getChangedProperties();
+ ASSERT_EQ(2u, events.size());
+ EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[0].prop);
+ EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[1].prop);
+ ASSERT_EQ(3u, events[0].value.int32Values.size());
+ ASSERT_EQ(3u, events[1].value.int32Values.size());
+ EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_DOWN), events[0].value.int32Values[0]);
+ EXPECT_EQ(1, events[0].value.int32Values[1]);
+ EXPECT_EQ(2, events[0].value.int32Values[2]);
+ EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_UP), events[1].value.int32Values[0]);
+ EXPECT_EQ(1, events[1].value.int32Values[1]);
+ EXPECT_EQ(2, events[1].value.int32Values[2]);
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataKeyInputV2) {
+ std::vector<std::string> options = {"--genfakedata", "--keyinputv2", "1", "2", "3", "4", "5"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ auto events = getChangedProperties();
+ ASSERT_EQ(1u, events.size());
+ EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT_V2), events[0].prop);
+ ASSERT_EQ(4u, events[0].value.int32Values.size());
+ EXPECT_EQ(2, events[0].value.int32Values[0]);
+ EXPECT_EQ(3, events[0].value.int32Values[1]);
+ EXPECT_EQ(4, events[0].value.int32Values[2]);
+ EXPECT_EQ(5, events[0].value.int32Values[3]);
+ ASSERT_EQ(1u, events[0].value.int64Values.size());
+}
+
+TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataMotionInput) {
+ std::vector<std::string> options = {"--genfakedata",
+ "--motioninput",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "--pointer",
+ "11",
+ "22",
+ "33.3",
+ "44.4",
+ "55.5",
+ "66.6",
+ "--pointer",
+ "21",
+ "32",
+ "43.3",
+ "54.4",
+ "65.5",
+ "76.6"};
+
+ DumpResult result = getHardware()->dump(options);
+
+ ASSERT_FALSE(result.callerShouldDumpState);
+ ASSERT_THAT(result.buffer, HasSubstr("successfully"));
+
+ auto events = getChangedProperties();
+ ASSERT_EQ(1u, events.size());
+ EXPECT_EQ(toInt(VehicleProperty::HW_MOTION_INPUT), events[0].prop);
+ ASSERT_EQ(9u, events[0].value.int32Values.size());
+ EXPECT_EQ(2, events[0].value.int32Values[0]);
+ EXPECT_EQ(3, events[0].value.int32Values[1]);
+ EXPECT_EQ(4, events[0].value.int32Values[2]);
+ EXPECT_EQ(5, events[0].value.int32Values[3]);
+ EXPECT_EQ(2, events[0].value.int32Values[4]);
+ EXPECT_EQ(11, events[0].value.int32Values[5]);
+ EXPECT_EQ(21, events[0].value.int32Values[6]);
+ EXPECT_EQ(22, events[0].value.int32Values[7]);
+ EXPECT_EQ(32, events[0].value.int32Values[8]);
+ ASSERT_EQ(8u, events[0].value.floatValues.size());
+ EXPECT_FLOAT_EQ(33.3, events[0].value.floatValues[0]);
+ EXPECT_FLOAT_EQ(43.3, events[0].value.floatValues[1]);
+ EXPECT_FLOAT_EQ(44.4, events[0].value.floatValues[2]);
+ EXPECT_FLOAT_EQ(54.4, events[0].value.floatValues[3]);
+ EXPECT_FLOAT_EQ(55.5, events[0].value.floatValues[4]);
+ EXPECT_FLOAT_EQ(65.5, events[0].value.floatValues[5]);
+ EXPECT_FLOAT_EQ(66.6, events[0].value.floatValues[6]);
+ EXPECT_FLOAT_EQ(76.6, events[0].value.floatValues[7]);
+ ASSERT_EQ(1u, events[0].value.int64Values.size());
+}
+
TEST_F(FakeVehicleHardwareTest, testGetEchoReverseBytes) {
ASSERT_EQ(setValue(VehiclePropValue{
.prop = ECHO_REVERSE_BYTES,
@@ -1653,6 +2243,359 @@
}
}
+TEST_F(FakeVehicleHardwareTest, testSetHvacTemperatureValueSuggestion) {
+ float CELSIUS = static_cast<float>(toInt(VehicleUnit::CELSIUS));
+ float FAHRENHEIT = static_cast<float>(toInt(VehicleUnit::FAHRENHEIT));
+
+ VehiclePropValue floatArraySizeFour = {
+ .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {0, CELSIUS, 0, 0},
+ };
+ StatusCode status = setValue(floatArraySizeFour);
+ EXPECT_EQ(status, StatusCode::OK);
+
+ VehiclePropValue floatArraySizeZero = {
+ .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ };
+ status = setValue(floatArraySizeZero);
+ EXPECT_EQ(status, StatusCode::INVALID_ARG);
+
+ VehiclePropValue floatArraySizeFive = {
+ .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {0, CELSIUS, 0, 0, 0},
+ };
+ status = setValue(floatArraySizeFive);
+ EXPECT_EQ(status, StatusCode::INVALID_ARG);
+
+ VehiclePropValue invalidUnit = {
+ .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {0, 0, 0, 0},
+ };
+ status = setValue(floatArraySizeFive);
+ EXPECT_EQ(status, StatusCode::INVALID_ARG);
+ clearChangedProperties();
+
+ // Config array values from HVAC_TEMPERATURE_SET in DefaultProperties.json
+ auto configs = getHardware()->getAllPropertyConfigs();
+ VehiclePropConfig* hvacTemperatureSetConfig = nullptr;
+ for (auto& config : configs) {
+ if (config.prop == toInt(VehicleProperty::HVAC_TEMPERATURE_SET)) {
+ hvacTemperatureSetConfig = &config;
+ break;
+ }
+ }
+ EXPECT_NE(hvacTemperatureSetConfig, nullptr);
+
+ auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfig->configArray;
+ // The HVAC_TEMPERATURE_SET config array values are temperature values that have been multiplied
+ // by 10 and converted to integers. HVAC_TEMPERATURE_VALUE_SUGGESTION specifies the temperature
+ // values to be in the original floating point form so we divide by 10 and convert to float.
+ float minTempInCelsius = hvacTemperatureSetConfigArray[0] / 10.0f;
+ float maxTempInCelsius = hvacTemperatureSetConfigArray[1] / 10.0f;
+ float incrementInCelsius = hvacTemperatureSetConfigArray[2] / 10.0f;
+ float minTempInFahrenheit = hvacTemperatureSetConfigArray[3] / 10.0f;
+ float maxTempInFahrenheit = hvacTemperatureSetConfigArray[4] / 10.0f;
+ float incrementInFahrenheit = hvacTemperatureSetConfigArray[5] / 10.0f;
+
+ auto testCases = {
+ SetSpecialValueTestCase{
+ .name = "min_celsius_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInCelsius, CELSIUS, 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInCelsius, CELSIUS,
+ minTempInCelsius,
+ minTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "min_fahrenheit_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInFahrenheit, FAHRENHEIT,
+ 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInFahrenheit, FAHRENHEIT,
+ minTempInCelsius,
+ minTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "max_celsius_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInCelsius, CELSIUS, 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInCelsius, CELSIUS,
+ maxTempInCelsius,
+ maxTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "max_fahrenheit_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInFahrenheit, FAHRENHEIT,
+ 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInFahrenheit, FAHRENHEIT,
+ maxTempInCelsius,
+ maxTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "below_min_celsius_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInCelsius - 1, CELSIUS, 0,
+ 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInCelsius - 1, CELSIUS,
+ minTempInCelsius,
+ minTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "below_min_fahrenheit_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInFahrenheit - 1,
+ FAHRENHEIT, 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInFahrenheit - 1,
+ FAHRENHEIT, minTempInCelsius,
+ minTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "above_max_celsius_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInCelsius + 1, CELSIUS, 0,
+ 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInCelsius + 1, CELSIUS,
+ maxTempInCelsius,
+ maxTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "above_max_fahrenheit_temperature",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInFahrenheit + 1,
+ FAHRENHEIT, 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {maxTempInFahrenheit + 1,
+ FAHRENHEIT, maxTempInCelsius,
+ maxTempInFahrenheit},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "inbetween_value_celsius",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInCelsius +
+ incrementInCelsius * 2.5f,
+ CELSIUS, 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues =
+ {minTempInCelsius + incrementInCelsius * 2.5f,
+ CELSIUS,
+ minTempInCelsius + incrementInCelsius * 2,
+ minTempInFahrenheit +
+ incrementInFahrenheit * 2},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "inbetween_value_fahrenheit",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues = {minTempInFahrenheit +
+ incrementInFahrenheit *
+ 2.5f,
+ FAHRENHEIT, 0, 0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ HVAC_TEMPERATURE_VALUE_SUGGESTION),
+ .areaId = HVAC_ALL,
+ .value.floatValues =
+ {minTempInFahrenheit +
+ incrementInFahrenheit * 2.5f,
+ FAHRENHEIT,
+ minTempInCelsius + incrementInCelsius * 2,
+ minTempInFahrenheit +
+ incrementInFahrenheit * 2},
+ },
+ },
+ },
+ };
+
+ for (auto& tc : testCases) {
+ StatusCode status = setValue(tc.valuesToSet[0]);
+ EXPECT_EQ(status, StatusCode::OK);
+
+ auto events = getChangedProperties();
+ EXPECT_EQ(events.size(), static_cast<size_t>(1));
+ events[0].timestamp = 0;
+
+ EXPECT_EQ(events[0], (tc.expectedValuesToGet[0]))
+ << "Failed Test: " << tc.name << "\n"
+ << "Received - prop: " << events[0].prop << ", areaId: " << events[0].areaId
+ << ", floatValues: {" << events[0].value.floatValues[0] << ", "
+ << events[0].value.floatValues[1] << ", " << events[0].value.floatValues[2] << ", "
+ << events[0].value.floatValues[3] << "}\n"
+ << "Expected - prop: " << tc.expectedValuesToGet[0].prop
+ << ", areaId: " << tc.expectedValuesToGet[0].areaId << ", floatValues: {"
+ << tc.expectedValuesToGet[0].value.floatValues[0] << ", "
+ << tc.expectedValuesToGet[0].value.floatValues[1] << ", "
+ << tc.expectedValuesToGet[0].value.floatValues[2] << ", "
+ << tc.expectedValuesToGet[0].value.floatValues[3] << "}\n";
+ clearChangedProperties();
+ }
+}
+
} // namespace fake
} // namespace vehicle
} // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
new file mode 100644
index 0000000..7123a00
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
@@ -0,0 +1,26 @@
+[
+ {
+ "timestamp": 1000000,
+ "areaId": 0,
+ "value": 8,
+ "prop": 289408000
+ },
+ {
+ "timestamp": 2000000,
+ "areaId": 0,
+ "value": 4,
+ "prop": 289408000
+ },
+ {
+ "timestamp": 3000000,
+ "areaId": 0,
+ "value": 16,
+ "prop": 289408000
+ },
+ {
+ "timestamp": 4000000,
+ "areaId": 0,
+ "value": 10,
+ "prop": 289408000
+ }
+]
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
index 59666b8..693f1e2 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
@@ -1,9 +1,13 @@
-[
- {
- "timestamp": 1000000,
- "areaId": 0,
- "value": 8,
- // GEAR_SELECTION
- "prop": 289408000
- }
-]
+{
+ "apiVersion": 1,
+ "properties": [
+ {
+ "property": "VehicleProperty::GEAR_SELECTION",
+ "defaultValue": {
+ "int32Values": [
+ 8
+ ]
+ }
+ }
+ ]
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
index 93a97ed..07cfebb 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
@@ -1,10 +1,20 @@
-[
- {
- "timestamp": 1000000,
- // HVAC_LEFT
- "areaId": 49,
- "value": 30,
- // HVAC_TEMPERATURE_SET
- "prop": 358614275
- }
-]
+{
+ "apiVersion": 1,
+ "properties": [
+ {
+ "property": "VehicleProperty::HVAC_TEMPERATURE_SET",
+ "areas": [
+ {
+ "defaultValue": {
+ "floatValues": [
+ 30.0
+ ]
+ },
+ "areaId": 49,
+ "minFloatValue": 16.0,
+ "maxFloatValue": 32.0
+ }
+ ]
+ }
+ ]
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h b/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
index 4ae9c8c..fcbe8fd 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
@@ -64,7 +64,7 @@
std::string showDumpHelp() const;
// Dump its contents.
- std::string dump(std::string indent) const;
+ std::string dump() const;
private:
const std::shared_ptr<VehiclePropValuePool> mValuePool;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp b/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
index 7748fb6..878c2e7 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
@@ -328,6 +328,9 @@
<< "invalid action on lshal response: " << response->toString();
}
+ // Update area ID to 0 since this is a global property (and the area ID was only set to emulate
+ // the request id behavior).
+ response->areaId = 0;
ALOGD("updating property to: %s", response->toString().c_str());
return response;
}
@@ -336,33 +339,31 @@
return fmt::format("{}: dumps state used for user management\n", kUserHalDumpOption);
}
-std::string FakeUserHal::dump(std::string indent) const {
+std::string FakeUserHal::dump() const {
std::scoped_lock<std::mutex> lockGuard(mLock);
std::string info;
if (mInitialUserResponseFromCmd != nullptr) {
- info += fmt::format("{}InitialUserInfo response: {}\n", indent,
+ info += fmt::format("InitialUserInfo response: {}\n",
mInitialUserResponseFromCmd->toString());
} else {
- info += fmt::format("{}No InitialUserInfo response\n", indent);
+ info += "No InitialUserInfo response\n";
}
if (mSwitchUserResponseFromCmd != nullptr) {
- info += fmt::format("{}SwitchUser response: {}\n", indent,
- mSwitchUserResponseFromCmd->toString());
+ info += fmt::format("SwitchUser response: {}\n", mSwitchUserResponseFromCmd->toString());
} else {
- info += fmt::format("{}No SwitchUser response\n", indent);
+ info += "No SwitchUser response\n";
}
if (mCreateUserResponseFromCmd != nullptr) {
- info += fmt::format("{}CreateUser response: {}\n", indent,
- mCreateUserResponseFromCmd->toString());
+ info += fmt::format("CreateUser response: {}\n", mCreateUserResponseFromCmd->toString());
} else {
- info += fmt::format("{}No CreateUser response\n", indent);
+ info += "No CreateUser response\n";
}
if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
- info += fmt::format("{}SetUserIdentificationAssociation response: {}\n", indent,
+ info += fmt::format("SetUserIdentificationAssociation response: {}\n",
mSetUserIdentificationAssociationResponseFromCmd->toString());
} else {
- info += fmt::format("{}No SetUserIdentificationAssociation response\n", indent);
+ info += "No SetUserIdentificationAssociation response\n";
}
return info;
}
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
index 7670c25..2b4059c 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
@@ -47,13 +47,19 @@
],
vendor: true,
defaults: ["VehicleHalDefaults"],
- shared_libs: ["libprotobuf-cpp-full"],
+ shared_libs: [
+ "libprotobuf-cpp-full",
+ "libjsoncpp",
+ ],
static_libs: [
+ "VehicleHalJsonConfigLoaderEnableTestProperties",
"VehicleHalProtoMessageConverter",
"VehicleHalProtos",
"VehicleHalUtils",
"libgtest",
],
- header_libs: ["VehicleHalDefaultConfig"],
+ data: [
+ ":VehicleHalDefaultProperties_JSON",
+ ],
test_suites: ["device-tests"],
}
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
index c742db5..308be46 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
@@ -16,9 +16,11 @@
#include <vector>
-#include <DefaultConfig.h>
+#include <JsonConfigLoader.h>
#include <ProtoMessageConverter.h>
#include <VehicleHalTypes.h>
+
+#include <android-base/file.h>
#include <android-base/format.h>
#include <android/hardware/automotive/vehicle/VehiclePropConfig.pb.h>
#include <android/hardware/automotive/vehicle/VehiclePropValue.pb.h>
@@ -35,23 +37,39 @@
namespace proto = ::android::hardware::automotive::vehicle::proto;
namespace aidl_vehicle = ::aidl::android::hardware::automotive::vehicle;
+constexpr char DEFAULT_PROPERTIES_CONFIG[] = "DefaultProperties.json";
+
+inline std::string getConfigPath(const std::string& name) {
+ return android::base::GetExecutableDirectory() + "/" + name;
+}
+
std::vector<aidl_vehicle::VehiclePropConfig> prepareTestConfigs() {
+ JsonConfigLoader loader;
+ auto result = loader.loadPropConfig(getConfigPath(DEFAULT_PROPERTIES_CONFIG));
+ if (!result.ok()) {
+ return {};
+ }
std::vector<aidl_vehicle::VehiclePropConfig> configs;
- for (auto& property : defaultconfig::getDefaultConfigs()) {
- configs.push_back(property.config);
+ for (auto& [_, configDeclaration] : result.value()) {
+ configs.push_back(configDeclaration.config);
}
return configs;
}
std::vector<aidl_vehicle::VehiclePropValue> prepareTestValues() {
+ JsonConfigLoader loader;
+ auto result = loader.loadPropConfig(getConfigPath(DEFAULT_PROPERTIES_CONFIG));
+ if (!result.ok()) {
+ return {};
+ }
std::vector<aidl_vehicle::VehiclePropValue> values;
int64_t timestamp = 1;
- for (auto& property : defaultconfig::getDefaultConfigs()) {
+ for (auto& [_, configDeclaration] : result.value()) {
values.push_back({
.timestamp = timestamp,
.areaId = 123,
- .prop = property.config.prop,
- .value = property.initialValue,
+ .prop = configDeclaration.config.prop,
+ .value = configDeclaration.initialValue,
.status = aidl_vehicle::VehiclePropertyStatus::ERROR,
});
}
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
index 759db41..d92ccfd 100644
--- a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
@@ -116,11 +116,12 @@
virtual aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() = 0;
// Register a callback that would be called when there is a property change event from vehicle.
+ // Must only be called once during initialization.
virtual void registerOnPropertyChangeEvent(
std::unique_ptr<const PropertyChangeCallback> callback) = 0;
// Register a callback that would be called when there is a property set error event from
- // vehicle.
+ // vehicle. Must only be called once during initialization.
virtual void registerOnPropertySetErrorEvent(
std::unique_ptr<const PropertySetErrorCallback> callback) = 0;
};
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
index b16daa8..749ad6a 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
@@ -18,9 +18,33 @@
package android.hardware.automotive.vehicle.proto;
+import "android/hardware/automotive/vehicle/StatusCode.proto";
import "android/hardware/automotive/vehicle/VehiclePropValue.proto";
message VehiclePropValueRequest {
- int32 request_id = 1;
+ int64 request_id = 1;
VehiclePropValue value = 2;
};
+
+message SetValueResult {
+ int64 request_id = 1;
+ StatusCode status = 2;
+};
+
+message GetValueResult {
+ int64 request_id = 1;
+ StatusCode status = 2;
+ VehiclePropValue value = 3;
+};
+
+message VehiclePropValueRequests {
+ repeated VehiclePropValueRequest requests = 1;
+};
+
+message SetValueResults {
+ repeated SetValueResult results = 1;
+};
+
+message GetValueResults {
+ repeated GetValueResult results = 1;
+};
diff --git a/automotive/vehicle/aidl/impl/utils/README.md b/automotive/vehicle/aidl/impl/utils/README.md
new file mode 100644
index 0000000..87bb7e3
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/utils/README.md
@@ -0,0 +1,62 @@
+# Utility classes for VHAL implementation
+---
+
+This directory stores utility classes for VHAL implementation. Vendor
+implementation could use utility classes from `common` folder in their
+VHAL implementation.
+
+## common
+
+Defines common utility libraries.
+
+### ConcurrentQueue
+
+Provides a thread-safe concurrent queue object. Useful for adding object to
+a queue in one thread (usually binder thread) and handle the objects in a
+separate handler thread.
+
+### ParcelableUtils
+
+Provides functions to convert between a regular parcelable and a
+`LargeParcelabe`.
+
+A `LargeParcelable` is a parcelable that marshals the payload
+into a shared memory file if the payload is too large to pass across binder.
+It is used to pass large data across binder. Before sending the data, VHAL
+impl should convert a regular parcelabe to a `LargeParcelable`. After receving
+data, VHAL impl should convert a `LargeParcelable` back to regular parcelabe.
+
+### PendingRequestPool
+
+Defines A class for managing pending requests and automatically call timeout
+callback if the request timed-out.
+
+### PropertyUtils
+
+Defines some useful constants.
+
+### RecurrentTimer
+
+Defines a thread-safe recurrent timer that can call a function periodically.
+
+### VehicleHalTypes
+
+Provides a header file that includes many commonly used header files. Useful
+when you are using multiple types defined in VHAL interface.
+
+### VehicleObjectPool
+
+Defines a reusable in-memory pool for `VehiclePropValue`.
+
+### VehiclePropertyStore
+
+Defines an in-memory map for storing vehicle properties. Allows easier insert,
+delete and lookup.
+
+### VehicleUtils
+
+Defines many useful utility functions.
+
+## test
+
+Defines utility libraries for test only.
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
index 3f8db93..28cf08e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
@@ -21,7 +21,6 @@
#include <android-base/result.h>
#include <android-base/thread_annotations.h>
-#include <atomic>
#include <list>
#include <mutex>
#include <thread>
@@ -85,7 +84,7 @@
std::unordered_map<const void*, std::list<PendingRequest>> mPendingRequestsByClient
GUARDED_BY(mLock);
std::thread mThread;
- std::atomic<bool> mThreadStop = false;
+ bool mThreadStop = false;
std::condition_variable mCv;
std::mutex mCvLock;
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
index 2743578..7275ba3 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
@@ -28,6 +28,7 @@
namespace propertyutils_impl {
// These names are not part of the API since we only expose ints.
+using ::aidl::android::hardware::automotive::vehicle::EvStoppingMode;
using ::aidl::android::hardware::automotive::vehicle::PortLocationType;
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaDoor;
@@ -96,7 +97,13 @@
constexpr int CHARGE_PORT_FRONT_LEFT = toInt(propertyutils_impl::PortLocationType::FRONT_LEFT);
constexpr int CHARGE_PORT_REAR_LEFT = toInt(propertyutils_impl::PortLocationType::REAR_LEFT);
constexpr int LIGHT_STATE_ON = toInt(propertyutils_impl::VehicleLightState::ON);
+constexpr int LIGHT_STATE_OFF = toInt(propertyutils_impl::VehicleLightState::OFF);
+constexpr int LIGHT_SWITCH_OFF = toInt(propertyutils_impl::VehicleLightSwitch::OFF);
+constexpr int LIGHT_SWITCH_ON = toInt(propertyutils_impl::VehicleLightSwitch::ON);
constexpr int LIGHT_SWITCH_AUTO = toInt(propertyutils_impl::VehicleLightSwitch::AUTOMATIC);
+constexpr int EV_STOPPING_MODE_CREEP = toInt(propertyutils_impl::EvStoppingMode::CREEP);
+constexpr int EV_STOPPING_MODE_ROLL = toInt(propertyutils_impl::EvStoppingMode::ROLL);
+constexpr int EV_STOPPING_MODE_HOLD = toInt(propertyutils_impl::EvStoppingMode::HOLD);
constexpr int WHEEL_FRONT_LEFT = toInt(propertyutils_impl::VehicleAreaWheel::LEFT_FRONT);
constexpr int WHEEL_FRONT_RIGHT = toInt(propertyutils_impl::VehicleAreaWheel::RIGHT_FRONT);
constexpr int WHEEL_REAR_LEFT = toInt(propertyutils_impl::VehicleAreaWheel::LEFT_REAR);
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 8bc3c20..e6d657d 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -17,15 +17,32 @@
#ifndef android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
#define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
+#include <aidl/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.h>
+#include <aidl/android/hardware/automotive/vehicle/BlindSpotWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlCommand.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlState.h>
+#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/EmergencyLaneKeepAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/ErrorState.h>
#include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
+#include <aidl/android/hardware/automotive/vehicle/EvStoppingMode.h>
#include <aidl/android/hardware/automotive/vehicle/EvsServiceState.h>
#include <aidl/android/hardware/automotive/vehicle/EvsServiceType.h>
+#include <aidl/android/hardware/automotive/vehicle/ForwardCollisionWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/FuelType.h>
#include <aidl/android/hardware/automotive/vehicle/GetValueRequest.h>
#include <aidl/android/hardware/automotive/vehicle/GetValueResult.h>
#include <aidl/android/hardware/automotive/vehicle/GetValueResults.h>
+#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/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/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -66,5 +83,7 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleUnit.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.h>
+#include <aidl/android/hardware/automotive/vehicle/WindshieldWipersState.h>
+#include <aidl/android/hardware/automotive/vehicle/WindshieldWipersSwitch.h>
#endif // android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
index 0196edd..ab50499 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
@@ -39,20 +39,27 @@
} // namespace
-PendingRequestPool::PendingRequestPool(int64_t timeoutInNano)
- : mTimeoutInNano(timeoutInNano), mThread([this] {
- // [this] must be alive within this thread because destructor would wait for this thread
- // to exit.
- int64_t sleepTime = std::min(mTimeoutInNano, static_cast<int64_t>(CHECK_TIME_IN_NANO));
- std::unique_lock<std::mutex> lk(mCvLock);
- while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime),
- [this] { return mThreadStop.load(); })) {
- checkTimeout();
- }
- }) {}
+PendingRequestPool::PendingRequestPool(int64_t timeoutInNano) : mTimeoutInNano(timeoutInNano) {
+ mThread = std::thread([this] {
+ // [this] must be alive within this thread because destructor would wait for this thread
+ // to exit.
+ int64_t sleepTime = std::min(mTimeoutInNano, static_cast<int64_t>(CHECK_TIME_IN_NANO));
+ std::unique_lock<std::mutex> lk(mCvLock);
+ while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime),
+ [this] { return mThreadStop; })) {
+ checkTimeout();
+ }
+ });
+}
PendingRequestPool::~PendingRequestPool() {
- mThreadStop = true;
+ {
+ // Even if the shared variable is atomic, it must be modified under the
+ // mutex in order to correctly publish the modification to the waiting
+ // thread.
+ std::unique_lock<std::mutex> lk(mCvLock);
+ mThreadStop = true;
+ }
mCv.notify_all();
if (mThread.joinable()) {
mThread.join();
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index 908564c..c6d3687 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -29,7 +29,9 @@
using ::android::base::ScopedLockAssertion;
-RecurrentTimer::RecurrentTimer() : mThread(&RecurrentTimer::loop, this) {}
+RecurrentTimer::RecurrentTimer() {
+ mThread = std::thread(&RecurrentTimer::loop, this);
+}
RecurrentTimer::~RecurrentTimer() {
{
diff --git a/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h b/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
index d512713..1400288 100644
--- a/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/test/include/TestPropertyUtils.h
@@ -35,7 +35,6 @@
} // namespace testpropertyutils_impl
-#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
// Converts the system property to the vendor property.
// WARNING: This is only for the end-to-end testing, Should NOT include in the user build.
inline constexpr int32_t toVendor(
@@ -55,7 +54,6 @@
toVendor(testpropertyutils_impl::VehicleProperty::CLUSTER_REQUEST_DISPLAY);
constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE =
toVendor(testpropertyutils_impl::VehicleProperty::CLUSTER_NAVIGATION_STATE);
-#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
// These properties are placeholder properties for developers to test new features without
// implementing a real property.
@@ -86,6 +84,13 @@
toInt(testpropertyutils_impl::VehicleArea::GLOBAL) |
toInt(testpropertyutils_impl::VehiclePropertyType::BYTES);
+// This property is used for testing vendor error codes end to end.
+// 0x21402a13
+constexpr int32_t VENDOR_PROPERTY_ID = 0x2a13 |
+ toInt(testpropertyutils_impl::VehiclePropertyGroup::VENDOR) |
+ toInt(testpropertyutils_impl::VehicleArea::GLOBAL) |
+ toInt(testpropertyutils_impl::VehiclePropertyType::INT32);
+
// This property is used for test purpose. End to end tests use this property to test set and get
// method for MIXED type properties.
constexpr int32_t kMixedTypePropertyForTest =
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 5abcaf6..4feea79 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -66,3 +66,25 @@
"libbinder_ndk",
],
}
+
+cc_fuzz {
+ name: "android.hardware.automotive.vehicle@V1-default-service_fuzzer",
+ vendor: true,
+ defaults: [
+ "FakeVehicleHardwareDefaults",
+ "VehicleHalDefaults",
+ "android-automotive-large-parcelable-defaults",
+ "service_fuzzer_defaults",
+ ],
+ static_libs: [
+ "DefaultVehicleHal",
+ "FakeVehicleHardware",
+ "VehicleHalUtils",
+ ],
+ srcs: ["src/fuzzer.cpp"],
+ fuzz_config: {
+ cc: [
+ "[email protected]",
+ ],
+ },
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 9c29816..0439ac6 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -123,10 +123,10 @@
std::shared_ptr<PendingRequestPool> mPendingRequestPool;
};
- // A wrapper for binder operations to enable stubbing for test.
- class IBinder {
+ // A wrapper for binder lifecycle operations to enable stubbing for test.
+ class BinderLifecycleInterface {
public:
- virtual ~IBinder() = default;
+ virtual ~BinderLifecycleInterface() = default;
virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
void* cookie) = 0;
@@ -134,8 +134,8 @@
virtual bool isAlive(const AIBinder* binder) = 0;
};
- // A real implementation for IBinder.
- class AIBinderImpl final : public IBinder {
+ // A real implementation for BinderLifecycleInterface.
+ class BinderLifecycleHandler final : public BinderLifecycleInterface {
public:
binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
void* cookie) override;
@@ -154,7 +154,7 @@
// BinderDiedUnlinkedEvent represents either an onBinderDied or an onBinderUnlinked event.
struct BinderDiedUnlinkedEvent {
// true for onBinderDied, false for onBinderUnlinked.
- bool onBinderDied;
+ bool forOnBinderDied;
const AIBinder* clientId;
};
@@ -186,8 +186,8 @@
GUARDED_BY(mLock);
// SubscriptionClients is thread-safe.
std::shared_ptr<SubscriptionClients> mSubscriptionClients;
- // mBinderImpl is only going to be changed in test.
- std::unique_ptr<IBinder> mBinderImpl;
+ // mBinderLifecycleHandler is only going to be changed in test.
+ std::unique_ptr<BinderLifecycleInterface> mBinderLifecycleHandler;
// Only initialized once.
std::shared_ptr<std::function<void()>> mRecurrentAction;
@@ -263,7 +263,7 @@
void setTimeout(int64_t timeoutInNano);
// Test-only
- void setBinderImpl(std::unique_ptr<IBinder> impl);
+ void setBinderLifecycleHandler(std::unique_ptr<BinderLifecycleInterface> impl);
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
index 7c8f1b4..14799d9 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
@@ -41,15 +41,15 @@
public:
using ClientIdType = const AIBinder*;
- void addClient(const ClientIdType& clientId, float sampleRate);
+ void addClient(const ClientIdType& clientId, float sampleRateHz);
void removeClient(const ClientIdType& clientId);
- float getMaxSampleRate();
+ float getMaxSampleRateHz() const;
private:
- float mMaxSampleRate = 0.;
- std::unordered_map<ClientIdType, float> mSampleRates;
+ float mMaxSampleRateHz = 0.;
+ std::unordered_map<ClientIdType, float> mSampleRateHzByClient;
- void refreshMaxSampleRate();
+ void refreshMaxSampleRateHz();
};
// A thread-safe subscription manager that manages all VHAL subscriptions.
@@ -59,7 +59,7 @@
using CallbackType =
std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
- explicit SubscriptionManager(IVehicleHardware* hardware);
+ explicit SubscriptionManager(IVehicleHardware* vehicleHardware);
~SubscriptionManager();
// Subscribes to properties according to {@code SubscribeOptions}. Note that all option must
@@ -99,13 +99,8 @@
const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
updatedValues);
- // Gets the sample rate for the continuous property. Returns {@code std::nullopt} if the
- // property has not been subscribed before or is not a continuous property.
- std::optional<float> getSampleRate(const ClientIdType& clientId, int32_t propId,
- int32_t areaId);
-
// Checks whether the sample rate is valid.
- static bool checkSampleRate(float sampleRate);
+ static bool checkSampleRateHz(float sampleRateHz);
private:
// Friend class for testing.
@@ -122,17 +117,21 @@
std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea
GUARDED_BY(mLock);
- VhalResult<void> updateSampleRateLocked(const ClientIdType& clientId,
- const PropIdAreaId& propIdAreaId, float sampleRate)
+ VhalResult<void> addContinuousSubscriberLocked(const ClientIdType& clientId,
+ const PropIdAreaId& propIdAreaId,
+ float sampleRateHz) REQUIRES(mLock);
+ VhalResult<void> removeContinuousSubscriberLocked(const ClientIdType& clientId,
+ const PropIdAreaId& propIdAreaId)
REQUIRES(mLock);
- VhalResult<void> removeSampleRateLocked(const ClientIdType& clientId,
- const PropIdAreaId& propIdAreaId) REQUIRES(mLock);
+
+ VhalResult<void> updateContSubConfigs(const PropIdAreaId& PropIdAreaId,
+ const ContSubConfigs& newConfig) REQUIRES(mLock);
// Checks whether the manager is empty. For testing purpose.
bool isEmpty();
// Get the interval in nanoseconds accroding to sample rate.
- static android::base::Result<int64_t> getInterval(float sampleRate);
+ static android::base::Result<int64_t> getIntervalNanos(float sampleRateHz);
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index b191aef..a7ac1b4 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "DefaultVehicleHal"
+#define ATRACE_TAG ATRACE_TAG_HAL
#include <DefaultVehicleHal.h>
@@ -28,6 +29,7 @@
#include <private/android_filesystem_config.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
+#include <utils/Trace.h>
#include <inttypes.h>
#include <set>
@@ -78,14 +80,14 @@
return str;
}
-float getDefaultSampleRate(float sampleRate, float minSampleRate, float maxSampleRate) {
- if (sampleRate < minSampleRate) {
- return minSampleRate;
+float getDefaultSampleRateHz(float sampleRateHz, float minSampleRateHz, float maxSampleRateHz) {
+ if (sampleRateHz < minSampleRateHz) {
+ return minSampleRateHz;
}
- if (sampleRate > maxSampleRate) {
- return maxSampleRate;
+ if (sampleRateHz > maxSampleRateHz) {
+ return maxSampleRateHz;
}
- return sampleRate;
+ return sampleRateHz;
}
} // namespace
@@ -123,8 +125,8 @@
return mClients.size();
}
-DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware)
- : mVehicleHardware(std::move(hardware)),
+DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
+ : mVehicleHardware(std::move(vehicleHardware)),
mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)) {
auto configs = mVehicleHardware->getAllPropertyConfigs();
for (auto& config : configs) {
@@ -144,11 +146,10 @@
}
mSubscriptionClients = std::make_shared<SubscriptionClients>(mPendingRequestPool);
- mSubscriptionClients = std::make_shared<SubscriptionClients>(mPendingRequestPool);
auto subscribeIdByClient = std::make_shared<SubscribeIdByClient>();
- IVehicleHardware* hardwarePtr = mVehicleHardware.get();
- mSubscriptionManager = std::make_shared<SubscriptionManager>(hardwarePtr);
+ IVehicleHardware* vehicleHardwarePtr = mVehicleHardware.get();
+ mSubscriptionManager = std::make_shared<SubscriptionManager>(vehicleHardwarePtr);
std::weak_ptr<SubscriptionManager> subscriptionManagerCopy = mSubscriptionManager;
mVehicleHardware->registerOnPropertyChangeEvent(
@@ -158,13 +159,13 @@
}));
// Register heartbeat event.
- mRecurrentAction =
- std::make_shared<std::function<void()>>([hardwarePtr, subscriptionManagerCopy]() {
- checkHealth(hardwarePtr, subscriptionManagerCopy);
+ mRecurrentAction = std::make_shared<std::function<void()>>(
+ [vehicleHardwarePtr, subscriptionManagerCopy]() {
+ checkHealth(vehicleHardwarePtr, subscriptionManagerCopy);
});
mRecurrentTimer.registerTimerCallback(HEART_BEAT_INTERVAL_IN_NANO, mRecurrentAction);
- mBinderImpl = std::make_unique<AIBinderImpl>();
+ mBinderLifecycleHandler = std::make_unique<BinderLifecycleHandler>();
mOnBinderDiedUnlinkedHandlerThread = std::thread([this] { onBinderDiedUnlinkedHandler(); });
mDeathRecipient = ScopedAIBinder_DeathRecipient(
AIBinder_DeathRecipient_new(&DefaultVehicleHal::onBinderDied));
@@ -220,7 +221,7 @@
bool DefaultVehicleHal::monitorBinderLifeCycleLocked(const AIBinder* clientId) {
OnBinderDiedContext* contextPtr = nullptr;
if (mOnBinderDiedContexts.find(clientId) != mOnBinderDiedContexts.end()) {
- return mBinderImpl->isAlive(clientId);
+ return mBinderLifecycleHandler->isAlive(clientId);
} else {
std::unique_ptr<OnBinderDiedContext> context = std::make_unique<OnBinderDiedContext>(
OnBinderDiedContext{.vhal = this, .clientId = clientId});
@@ -232,7 +233,7 @@
}
// If this function fails, onBinderUnlinked would be called to remove the added context.
- binder_status_t status = mBinderImpl->linkToDeath(
+ binder_status_t status = mBinderLifecycleHandler->linkToDeath(
const_cast<AIBinder*>(clientId), mDeathRecipient.get(), static_cast<void*>(contextPtr));
if (status == STATUS_OK) {
return true;
@@ -246,7 +247,8 @@
OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
// To be handled in mOnBinderDiedUnlinkedHandlerThread. We cannot handle the event in the same
// thread because we might be holding the mLock the handler requires.
- context->vhal->mBinderEvents.push(BinderDiedUnlinkedEvent{true, context->clientId});
+ context->vhal->mBinderEvents.push(
+ BinderDiedUnlinkedEvent{/*forOnBinderDied=*/true, context->clientId});
}
void DefaultVehicleHal::onBinderDiedWithContext(const AIBinder* clientId) {
@@ -262,7 +264,8 @@
OnBinderDiedContext* context = reinterpret_cast<OnBinderDiedContext*>(cookie);
// To be handled in mOnBinderDiedUnlinkedHandlerThread. We cannot handle the event in the same
// thread because we might be holding the mLock the handler requires.
- context->vhal->mBinderEvents.push(BinderDiedUnlinkedEvent{false, context->clientId});
+ context->vhal->mBinderEvents.push(
+ BinderDiedUnlinkedEvent{/*forOnBinderDied=*/false, context->clientId});
}
void DefaultVehicleHal::onBinderUnlinkedWithContext(const AIBinder* clientId) {
@@ -275,7 +278,7 @@
void DefaultVehicleHal::onBinderDiedUnlinkedHandler() {
while (mBinderEvents.waitForItems()) {
for (BinderDiedUnlinkedEvent& event : mBinderEvents.flush()) {
- if (event.onBinderDied) {
+ if (event.forOnBinderDied) {
onBinderDiedWithContext(event.clientId);
} else {
onBinderUnlinkedWithContext(event.clientId);
@@ -349,6 +352,10 @@
ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback,
const GetValueRequests& requests) {
+ ATRACE_CALL();
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
expected<LargeParcelableBase::BorrowedOwnedObject<GetValueRequests>, ScopedAStatus>
deserializedResults = fromStableLargeParcelable(requests);
if (!deserializedResults.ok()) {
@@ -432,6 +439,10 @@
ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback,
const SetValueRequests& requests) {
+ ATRACE_CALL();
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
expected<LargeParcelableBase::BorrowedOwnedObject<SetValueRequests>, ScopedAStatus>
deserializedResults = fromStableLargeParcelable(requests);
if (!deserializedResults.ok()) {
@@ -589,18 +600,20 @@
}
if (config.changeMode == VehiclePropertyChangeMode::CONTINUOUS) {
- float sampleRate = option.sampleRate;
- float minSampleRate = config.minSampleRate;
- float maxSampleRate = config.maxSampleRate;
- if (sampleRate < minSampleRate || sampleRate > maxSampleRate) {
- float defaultRate = getDefaultSampleRate(sampleRate, minSampleRate, maxSampleRate);
- ALOGW("sample rate: %f out of range, must be within %f and %f, set to %f",
- sampleRate, minSampleRate, maxSampleRate, defaultRate);
- sampleRate = defaultRate;
+ float sampleRateHz = option.sampleRate;
+ float minSampleRateHz = config.minSampleRate;
+ float maxSampleRateHz = config.maxSampleRate;
+ float defaultRateHz =
+ getDefaultSampleRateHz(sampleRateHz, minSampleRateHz, maxSampleRateHz);
+ if (sampleRateHz != defaultRateHz) {
+ ALOGW("sample rate: %f HZ out of range, must be within %f HZ and %f HZ , set to %f "
+ "HZ",
+ sampleRateHz, minSampleRateHz, maxSampleRateHz, defaultRateHz);
+ sampleRateHz = defaultRateHz;
}
- if (!SubscriptionManager::checkSampleRate(sampleRate)) {
+ if (!SubscriptionManager::checkSampleRateHz(sampleRateHz)) {
return StatusError(StatusCode::INVALID_ARG)
- << "invalid sample rate: " << sampleRate;
+ << "invalid sample rate: " << sampleRateHz << " HZ";
}
}
@@ -625,11 +638,13 @@
const std::vector<SubscribeOptions>& options,
[[maybe_unused]] int32_t maxSharedMemoryFileCount) {
// TODO(b/205189110): Use shared memory file count.
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
if (auto result = checkSubscribeOptions(options); !result.ok()) {
ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
return toScopedAStatus(result);
}
-
std::vector<SubscribeOptions> onChangeSubscriptions;
std::vector<SubscribeOptions> continuousSubscriptions;
for (const auto& option : options) {
@@ -650,7 +665,7 @@
}
if (config.changeMode == VehiclePropertyChangeMode::CONTINUOUS) {
- optionCopy.sampleRate = getDefaultSampleRate(
+ optionCopy.sampleRate = getDefaultSampleRateHz(
optionCopy.sampleRate, config.minSampleRate, config.maxSampleRate);
continuousSubscriptions.push_back(std::move(optionCopy));
} else {
@@ -685,6 +700,9 @@
ScopedAStatus DefaultVehicleHal::unsubscribe(const CallbackType& callback,
const std::vector<int32_t>& propIds) {
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
return toScopedAStatus(mSubscriptionManager->unsubscribe(callback->asBinder().get(), propIds));
}
@@ -729,9 +747,9 @@
return {};
}
-void DefaultVehicleHal::checkHealth(IVehicleHardware* hardware,
+void DefaultVehicleHal::checkHealth(IVehicleHardware* vehicleHardware,
std::weak_ptr<SubscriptionManager> subscriptionManager) {
- StatusCode status = hardware->checkHealth();
+ StatusCode status = vehicleHardware->checkHealth();
if (status != StatusCode::OK) {
ALOGE("VHAL check health returns non-okay status");
return;
@@ -746,18 +764,18 @@
return;
}
-binder_status_t DefaultVehicleHal::AIBinderImpl::linkToDeath(AIBinder* binder,
- AIBinder_DeathRecipient* recipient,
- void* cookie) {
+binder_status_t DefaultVehicleHal::BinderLifecycleHandler::linkToDeath(
+ AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) {
return AIBinder_linkToDeath(binder, recipient, cookie);
}
-bool DefaultVehicleHal::AIBinderImpl::isAlive(const AIBinder* binder) {
+bool DefaultVehicleHal::BinderLifecycleHandler::isAlive(const AIBinder* binder) {
return AIBinder_isAlive(binder);
}
-void DefaultVehicleHal::setBinderImpl(std::unique_ptr<IBinder> impl) {
- mBinderImpl = std::move(impl);
+void DefaultVehicleHal::setBinderLifecycleHandler(
+ std::unique_ptr<BinderLifecycleInterface> handler) {
+ mBinderLifecycleHandler = std::move(handler);
}
bool DefaultVehicleHal::checkDumpPermission() {
@@ -775,10 +793,13 @@
for (uint32_t i = 0; i < numArgs; i++) {
options.push_back(args[i]);
}
+ if (options.size() == 1 && options[0] == "-a") {
+ // Ignore "-a" option. Bugreport will call with this option.
+ options.clear();
+ }
DumpResult result = mVehicleHardware->dump(options);
dprintf(fd, "%s", (result.buffer + "\n").c_str());
if (!result.callerShouldDumpState) {
- dprintf(fd, "Skip dumping Vehicle HAL State.\n");
return STATUS_OK;
}
dprintf(fd, "Vehicle HAL State: \n");
diff --git a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
index 2694401..bba730f 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
@@ -42,7 +42,8 @@
using ::android::base::StringPrintf;
using ::ndk::ScopedAStatus;
-SubscriptionManager::SubscriptionManager(IVehicleHardware* hardware) : mVehicleHardware(hardware) {}
+SubscriptionManager::SubscriptionManager(IVehicleHardware* vehicleHardware)
+ : mVehicleHardware(vehicleHardware) {}
SubscriptionManager::~SubscriptionManager() {
std::scoped_lock<std::mutex> lockGuard(mLock);
@@ -51,94 +52,82 @@
mSubscribedPropsByClient.clear();
}
-bool SubscriptionManager::checkSampleRate(float sampleRate) {
- return getInterval(sampleRate).ok();
+bool SubscriptionManager::checkSampleRateHz(float sampleRateHz) {
+ return getIntervalNanos(sampleRateHz).ok();
}
-Result<int64_t> SubscriptionManager::getInterval(float sampleRate) {
- int64_t interval = 0;
- if (sampleRate <= 0) {
+Result<int64_t> SubscriptionManager::getIntervalNanos(float sampleRateHz) {
+ int64_t intervalNanos = 0;
+ if (sampleRateHz <= 0) {
return Error() << "invalid sample rate, must be a positive number";
}
- if (sampleRate <= (ONE_SECOND_IN_NANO / static_cast<float>(INT64_MAX))) {
- return Error() << "invalid sample rate: " << sampleRate << ", too small";
+ if (sampleRateHz <= (ONE_SECOND_IN_NANO / static_cast<float>(INT64_MAX))) {
+ return Error() << "invalid sample rate: " << sampleRateHz << ", too small";
}
- interval = static_cast<int64_t>(ONE_SECOND_IN_NANO / sampleRate);
- return interval;
+ intervalNanos = static_cast<int64_t>(ONE_SECOND_IN_NANO / sampleRateHz);
+ return intervalNanos;
}
-void ContSubConfigs::refreshMaxSampleRate() {
- float maxSampleRate = 0.;
+void ContSubConfigs::refreshMaxSampleRateHz() {
+ float maxSampleRateHz = 0.;
// This is not called frequently so a brute-focre is okay. More efficient way exists but this
// is simpler.
- for (const auto& [_, sampleRate] : mSampleRates) {
- if (sampleRate > maxSampleRate) {
- maxSampleRate = sampleRate;
+ for (const auto& [_, sampleRateHz] : mSampleRateHzByClient) {
+ if (sampleRateHz > maxSampleRateHz) {
+ maxSampleRateHz = sampleRateHz;
}
}
- mMaxSampleRate = maxSampleRate;
+ mMaxSampleRateHz = maxSampleRateHz;
}
-void ContSubConfigs::addClient(const ClientIdType& clientId, float sampleRate) {
- mSampleRates[clientId] = sampleRate;
- refreshMaxSampleRate();
+void ContSubConfigs::addClient(const ClientIdType& clientId, float sampleRateHz) {
+ mSampleRateHzByClient[clientId] = sampleRateHz;
+ refreshMaxSampleRateHz();
}
void ContSubConfigs::removeClient(const ClientIdType& clientId) {
- mSampleRates.erase(clientId);
- refreshMaxSampleRate();
+ mSampleRateHzByClient.erase(clientId);
+ refreshMaxSampleRateHz();
}
-float ContSubConfigs::getMaxSampleRate() {
- return mMaxSampleRate;
+float ContSubConfigs::getMaxSampleRateHz() const {
+ return mMaxSampleRateHz;
}
-VhalResult<void> SubscriptionManager::updateSampleRateLocked(const ClientIdType& clientId,
- const PropIdAreaId& propIdAreaId,
- float sampleRate) {
+VhalResult<void> SubscriptionManager::addContinuousSubscriberLocked(
+ const ClientIdType& clientId, const PropIdAreaId& propIdAreaId, float sampleRateHz) {
// Make a copy so that we don't modify 'mContSubConfigsByPropIdArea' on failure cases.
- ContSubConfigs infoCopy = mContSubConfigsByPropIdArea[propIdAreaId];
- infoCopy.addClient(clientId, sampleRate);
- if (infoCopy.getMaxSampleRate() ==
- mContSubConfigsByPropIdArea[propIdAreaId].getMaxSampleRate()) {
- mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
+ ContSubConfigs newConfig = mContSubConfigsByPropIdArea[propIdAreaId];
+ newConfig.addClient(clientId, sampleRateHz);
+ return updateContSubConfigs(propIdAreaId, newConfig);
+}
+
+VhalResult<void> SubscriptionManager::removeContinuousSubscriberLocked(
+ const ClientIdType& clientId, const PropIdAreaId& propIdAreaId) {
+ // Make a copy so that we don't modify 'mContSubConfigsByPropIdArea' on failure cases.
+ ContSubConfigs newConfig = mContSubConfigsByPropIdArea[propIdAreaId];
+ newConfig.removeClient(clientId);
+ return updateContSubConfigs(propIdAreaId, newConfig);
+}
+
+VhalResult<void> SubscriptionManager::updateContSubConfigs(const PropIdAreaId& propIdAreaId,
+ const ContSubConfigs& newConfig) {
+ if (newConfig.getMaxSampleRateHz() ==
+ mContSubConfigsByPropIdArea[propIdAreaId].getMaxSampleRateHz()) {
+ mContSubConfigsByPropIdArea[propIdAreaId] = newConfig;
return {};
}
- float newRate = infoCopy.getMaxSampleRate();
+ float newRateHz = newConfig.getMaxSampleRateHz();
int32_t propId = propIdAreaId.propId;
int32_t areaId = propIdAreaId.areaId;
- if (auto status = mVehicleHardware->updateSampleRate(propId, areaId, newRate);
+ if (auto status = mVehicleHardware->updateSampleRate(propId, areaId, newRateHz);
status != StatusCode::OK) {
return StatusError(status) << StringPrintf("failed to update sample rate for prop: %" PRId32
", area"
- ": %" PRId32 ", sample rate: %f",
- propId, areaId, newRate);
+ ": %" PRId32 ", sample rate: %f HZ",
+ propId, areaId, newRateHz);
}
- mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
- return {};
-}
-
-VhalResult<void> SubscriptionManager::removeSampleRateLocked(const ClientIdType& clientId,
- const PropIdAreaId& propIdAreaId) {
- // Make a copy so that we don't modify 'mContSubConfigsByPropIdArea' on failure cases.
- ContSubConfigs infoCopy = mContSubConfigsByPropIdArea[propIdAreaId];
- infoCopy.removeClient(clientId);
- if (infoCopy.getMaxSampleRate() ==
- mContSubConfigsByPropIdArea[propIdAreaId].getMaxSampleRate()) {
- mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
- return {};
- }
- float newRate = infoCopy.getMaxSampleRate();
- int32_t propId = propIdAreaId.propId;
- int32_t areaId = propIdAreaId.areaId;
- if (auto status = mVehicleHardware->updateSampleRate(propId, areaId, newRate);
- status != StatusCode::OK) {
- return StatusError(status) << StringPrintf("failed to update sample rate for prop: %" PRId32
- ", area"
- ": %" PRId32 ", sample rate: %f",
- propId, areaId, newRate);
- }
- mContSubConfigsByPropIdArea[propIdAreaId] = infoCopy;
+ mContSubConfigsByPropIdArea[propIdAreaId] = newConfig;
return {};
}
@@ -147,14 +136,12 @@
bool isContinuousProperty) {
std::scoped_lock<std::mutex> lockGuard(mLock);
- std::vector<int64_t> intervals;
for (const auto& option : options) {
- float sampleRate = option.sampleRate;
+ float sampleRateHz = option.sampleRate;
if (isContinuousProperty) {
- auto intervalResult = getInterval(sampleRate);
- if (!intervalResult.ok()) {
- return StatusError(StatusCode::INVALID_ARG) << intervalResult.error().message();
+ if (auto result = getIntervalNanos(sampleRateHz); !result.ok()) {
+ return StatusError(StatusCode::INVALID_ARG) << result.error().message();
}
}
@@ -176,7 +163,8 @@
.areaId = areaId,
};
if (isContinuousProperty) {
- if (auto result = updateSampleRateLocked(clientId, propIdAreaId, option.sampleRate);
+ if (auto result = addContinuousSubscriberLocked(clientId, propIdAreaId,
+ option.sampleRate);
!result.ok()) {
return result;
}
@@ -214,7 +202,7 @@
while (it != propIdAreaIds.end()) {
int32_t propId = it->propId;
if (std::find(propIds.begin(), propIds.end(), propId) != propIds.end()) {
- if (auto result = removeSampleRateLocked(clientId, *it); !result.ok()) {
+ if (auto result = removeContinuousSubscriberLocked(clientId, *it); !result.ok()) {
return result;
}
@@ -244,7 +232,7 @@
auto& subscriptions = mSubscribedPropsByClient[clientId];
for (auto const& propIdAreaId : subscriptions) {
- if (auto result = removeSampleRateLocked(clientId, propIdAreaId); !result.ok()) {
+ if (auto result = removeContinuousSubscriberLocked(clientId, propIdAreaId); !result.ok()) {
return result;
}
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
index c8b5c65..f8a4e7d 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
@@ -27,6 +27,13 @@
using ::android::hardware::automotive::vehicle::fake::FakeVehicleHardware;
int main(int /* argc */, char* /* argv */[]) {
+ ALOGI("Starting thread pool...");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(4)) {
+ ALOGE("%s", "failed to set thread pool max thread count");
+ return 1;
+ }
+ ABinderProcess_startThreadPool();
+
std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
std::shared_ptr<DefaultVehicleHal> vhal =
::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
@@ -39,12 +46,6 @@
return 1;
}
- if (!ABinderProcess_setThreadPoolMaxThreadCount(4)) {
- ALOGE("%s", "failed to set thread pool max thread count");
- return 1;
- }
- ABinderProcess_startThreadPool();
-
ALOGI("Vehicle Service Ready");
ABinderProcess_joinThreadPool();
diff --git a/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp b/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
new file mode 100644
index 0000000..ac1e3b1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <DefaultVehicleHal.h>
+#include <FakeVehicleHardware.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using ::android::fuzzService;
+using ::android::hardware::automotive::vehicle::DefaultVehicleHal;
+using ::android::hardware::automotive::vehicle::fake::FakeVehicleHardware;
+using ::ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
+ std::shared_ptr<DefaultVehicleHal> vhal =
+ ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+
+ fuzzService(vhal->asBinder().get(), FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index f48b906..05e569a 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -324,9 +324,9 @@
mCallbackClient = IVehicleCallback::fromBinder(mBinder);
// Set the linkToDeath to a fake implementation that always returns OK.
- auto binderImpl = std::make_unique<TestBinderImpl>();
- mBinderImpl = binderImpl.get();
- mVhal->setBinderImpl(std::move(binderImpl));
+ auto handler = std::make_unique<TestBinderLifecycleHandler>();
+ mBinderLifecycleHandler = handler.get();
+ mVhal->setBinderLifecycleHandler(std::move(handler));
}
void TearDown() override {
@@ -370,7 +370,7 @@
bool hasNoSubscriptions() { return mVhal->mSubscriptionManager->isEmpty(); }
- void setBinderAlive(bool isAlive) { mBinderImpl->setAlive(isAlive); };
+ void setBinderAlive(bool isAlive) { mBinderLifecycleHandler->setAlive(isAlive); };
static Result<void> getValuesTestCases(size_t size, GetValueRequests& requests,
std::vector<GetValueResult>& expectedResults,
@@ -444,7 +444,7 @@
}
private:
- class TestBinderImpl final : public DefaultVehicleHal::IBinder {
+ class TestBinderLifecycleHandler final : public DefaultVehicleHal::BinderLifecycleInterface {
public:
binder_status_t linkToDeath(AIBinder*, AIBinder_DeathRecipient*, void*) override {
if (mIsAlive) {
@@ -468,7 +468,7 @@
std::shared_ptr<MockVehicleCallback> mCallback;
std::shared_ptr<IVehicleCallback> mCallbackClient;
SpAIBinder mBinder;
- TestBinderImpl* mBinderImpl;
+ TestBinderLifecycleHandler* mBinderLifecycleHandler;
};
TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
@@ -671,8 +671,8 @@
}
TEST_F(DefaultVehicleHalTest, testGetValuesFinishBeforeTimeout) {
- // timeout: 0.1s
- int64_t timeout = 100000000;
+ // timeout: 1s
+ int64_t timeout = 1000000000;
setTimeout(timeout);
GetValueRequests requests;
@@ -681,17 +681,15 @@
ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
- // The response would be returned after 0.05s.
- getHardware()->setSleepTime(timeout / 2);
+ // The response would be returned after 0.01s.
+ getHardware()->setSleepTime(timeout / 100);
getHardware()->addGetValueResponses(expectedResults);
auto status = getClient()->getValues(getCallbackClient(), requests);
ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
- // Wait for the response.
- std::this_thread::sleep_for(std::chrono::nanoseconds(timeout));
-
+ ASSERT_TRUE(getCallback()->waitForGetValueResults(1, timeout)) << "no results in callback";
auto maybeGetValueResults = getCallback()->nextGetValueResults();
ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
@@ -699,8 +697,8 @@
}
TEST_F(DefaultVehicleHalTest, testGetValuesFinishAfterTimeout) {
- // timeout: 0.1s
- int64_t timeout = 100000000;
+ // timeout: 0.01s
+ int64_t timeout = 10000000;
setTimeout(timeout);
GetValueRequests requests;
@@ -709,17 +707,14 @@
ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
- // The response would be returned after 0.2s.
- getHardware()->setSleepTime(timeout * 2);
+ // The response would be returned after 0.1s.
+ getHardware()->setSleepTime(timeout * 10);
getHardware()->addGetValueResponses(expectedResults);
auto status = getClient()->getValues(getCallbackClient(), requests);
ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
- // Wait for the response.
- std::this_thread::sleep_for(std::chrono::nanoseconds(timeout * 5));
-
for (size_t i = 0; i < expectedResults.size(); i++) {
expectedResults[i] = {
.requestId = expectedResults[i].requestId,
@@ -728,6 +723,8 @@
};
}
+ ASSERT_TRUE(getCallback()->waitForGetValueResults(1, timeout * 100))
+ << "no results in callback";
auto maybeGetValueResults = getCallback()->nextGetValueResults();
ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
ASSERT_THAT(maybeGetValueResults.value().payloads, UnorderedElementsAreArray(expectedResults))
@@ -960,8 +957,8 @@
}
TEST_F(DefaultVehicleHalTest, testSetValuesFinishBeforeTimeout) {
- // timeout: 0.1s
- int64_t timeout = 100000000;
+ // timeout: 1s
+ int64_t timeout = 1000000000;
setTimeout(timeout);
SetValueRequests requests;
@@ -970,17 +967,15 @@
ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
- // The response would be returned after 0.05s.
- getHardware()->setSleepTime(timeout / 2);
+ // The response would be returned after 0.01s.
+ getHardware()->setSleepTime(timeout / 100);
getHardware()->addSetValueResponses(expectedResults);
auto status = getClient()->setValues(getCallbackClient(), requests);
ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
- // Wait for the response.
- std::this_thread::sleep_for(std::chrono::nanoseconds(timeout));
-
+ ASSERT_TRUE(getCallback()->waitForSetValueResults(1, timeout)) << "no set value results";
auto maybeSetValueResults = getCallback()->nextSetValueResults();
ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
EXPECT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
@@ -988,8 +983,8 @@
}
TEST_F(DefaultVehicleHalTest, testSetValuesFinishAfterTimeout) {
- // timeout: 0.1s
- int64_t timeout = 100000000;
+ // timeout: 0.01s
+ int64_t timeout = 10000000;
setTimeout(timeout);
SetValueRequests requests;
@@ -998,17 +993,14 @@
ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
- // The response would be returned after 0.2s.
- getHardware()->setSleepTime(timeout * 2);
+ // The response would be returned after 0.1s.
+ getHardware()->setSleepTime(timeout * 10);
getHardware()->addSetValueResponses(expectedResults);
auto status = getClient()->setValues(getCallbackClient(), requests);
ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
- // Wait for the response.
- std::this_thread::sleep_for(std::chrono::nanoseconds(timeout * 5));
-
for (size_t i = 0; i < expectedResults.size(); i++) {
expectedResults[i] = {
.requestId = expectedResults[i].requestId,
@@ -1016,6 +1008,7 @@
};
}
+ ASSERT_TRUE(getCallback()->waitForSetValueResults(1, timeout * 100)) << "no set value results";
auto maybeSetValueResults = getCallback()->nextSetValueResults();
ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
ASSERT_THAT(maybeSetValueResults.value().payloads, UnorderedElementsAreArray(expectedResults))
@@ -1456,7 +1449,7 @@
std::vector<SubscribeOptions> options = {
{
.propId = GLOBAL_CONTINUOUS_PROP,
- .sampleRate = 20.0,
+ .sampleRate = 100.0,
},
};
@@ -1469,16 +1462,20 @@
ASSERT_TRUE(status.isOk()) << "unsubscribe failed: " << status.getMessage();
+ // Wait for the last events to come.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
// Clear existing events.
while (getCallback()->nextOnPropertyEventResults().has_value()) {
// Do nothing.
}
- // Wait for a while, make sure no new events are generated.
+ // Wait for a while, make sure no new events are generated. If still subscribed, this should
+ // generate around 10 events.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
- ASSERT_FALSE(getCallback()->nextOnPropertyEventResults().has_value())
- << "No property event should be generated after unsubscription";
+ ASSERT_EQ(getCallback()->countOnPropertyEventResults(), 0u)
+ << "Property event generation must stop after unsubscription";
}
class SubscribeInvalidOptionsTest
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
index 0e46357..f51ce5c 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
@@ -16,6 +16,9 @@
#include "MockVehicleCallback.h"
+#include <android-base/thread_annotations.h>
+#include <chrono>
+
namespace android {
namespace hardware {
namespace automotive {
@@ -27,6 +30,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::android::base::ScopedLockAssertion;
using ::ndk::ScopedAStatus;
using ::ndk::ScopedFileDescriptor;
@@ -46,21 +50,35 @@
} // namespace
ScopedAStatus MockVehicleCallback::onGetValues(const GetValueResults& results) {
- std::scoped_lock<std::mutex> lockGuard(mLock);
- return storeResults(results, &mGetValueResults);
+ ScopedAStatus result;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ result = storeResults(results, &mGetValueResults);
+ }
+ mCond.notify_all();
+ return result;
}
ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
- std::scoped_lock<std::mutex> lockGuard(mLock);
- return storeResults(results, &mSetValueResults);
+ ScopedAStatus result;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ result = storeResults(results, &mSetValueResults);
+ }
+ mCond.notify_all();
+ return result;
}
ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues& results,
int32_t sharedMemoryFileCount) {
- std::scoped_lock<std::mutex> lockGuard(mLock);
-
- mSharedMemoryFileCount = sharedMemoryFileCount;
- return storeResults(results, &mOnPropertyEventResults);
+ ScopedAStatus result;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ mSharedMemoryFileCount = sharedMemoryFileCount;
+ result = storeResults(results, &mOnPropertyEventResults);
+ }
+ mCond.notify_all();
+ return result;
}
ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors&) {
@@ -87,6 +105,22 @@
return mOnPropertyEventResults.size();
}
+bool MockVehicleCallback::waitForSetValueResults(size_t size, size_t timeoutInNano) {
+ std::unique_lock lk(mLock);
+ return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+ ScopedLockAssertion lockAssertion(mLock);
+ return mSetValueResults.size() >= size;
+ });
+}
+
+bool MockVehicleCallback::waitForGetValueResults(size_t size, size_t timeoutInNano) {
+ std::unique_lock lk(mLock);
+ return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+ ScopedLockAssertion lockAssertion(mLock);
+ return mGetValueResults.size() >= size;
+ });
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
index 0faaa1f..f17b273 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
@@ -22,6 +22,7 @@
#include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h>
#include <android-base/thread_annotations.h>
+#include <condition_variable>
#include <list>
#include <mutex>
#include <optional>
@@ -63,9 +64,12 @@
std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropValues>
nextOnPropertyEventResults();
size_t countOnPropertyEventResults();
+ bool waitForSetValueResults(size_t size, size_t timeoutInNano);
+ bool waitForGetValueResults(size_t size, size_t timeoutInNano);
private:
std::mutex mLock;
+ std::condition_variable mCond;
std::list<aidl::android::hardware::automotive::vehicle::GetValueResults> mGetValueResults
GUARDED_BY(mLock);
std::list<aidl::android::hardware::automotive::vehicle::SetValueResults> mSetValueResults
diff --git a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
index 3f59363..cb8c8d1 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
@@ -231,7 +231,7 @@
std::vector<SubscribeOptions> options = {{
.propId = 0,
.areaIds = {0},
- .sampleRate = 10.0,
+ .sampleRate = 100.0,
}};
auto result = getManager()->subscribe(getCallbackClient(), options, true);
@@ -240,11 +240,13 @@
result = getManager()->unsubscribe(getCallbackClient()->asBinder().get());
ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+ // Wait for the last events to come.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
clearEvents();
- std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
- // Theoretically trigger 10 times, but check for at least 9 times to be stable.
ASSERT_TRUE(getEvents().empty());
}
@@ -269,6 +271,9 @@
std::vector<int32_t>({0}));
ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+ // Wait for the last events to come.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
clearEvents();
std::this_thread::sleep_for(std::chrono::seconds(1));
@@ -301,6 +306,9 @@
result = getManager()->unsubscribe(getCallbackClient()->asBinder().get());
ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+ // Wait for the last events to come.
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
clearEvents();
std::this_thread::sleep_for(std::chrono::seconds(1));
@@ -477,16 +485,16 @@
ASSERT_THAT(clients[getCallbackClient()], ElementsAre(&updatedValues[1]));
}
-TEST_F(SubscriptionManagerTest, testCheckSampleRateValid) {
- ASSERT_TRUE(SubscriptionManager::checkSampleRate(1.0));
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzValid) {
+ ASSERT_TRUE(SubscriptionManager::checkSampleRateHz(1.0));
}
-TEST_F(SubscriptionManagerTest, testCheckSampleRateInvalidTooSmall) {
- ASSERT_FALSE(SubscriptionManager::checkSampleRate(FLT_MIN));
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzInvalidTooSmall) {
+ ASSERT_FALSE(SubscriptionManager::checkSampleRateHz(FLT_MIN));
}
-TEST_F(SubscriptionManagerTest, testCheckSampleRateInvalidZero) {
- ASSERT_FALSE(SubscriptionManager::checkSampleRate(0));
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzInvalidZero) {
+ ASSERT_FALSE(SubscriptionManager::checkSampleRateHz(0));
}
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
index 4d587ee..9834cdb 100644
--- a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
+++ b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.automotive.vehicle</name>
- <version>1</version>
+ <version>2</version>
<fqname>IVehicle/default</fqname>
</hal>
</manifest>
diff --git a/automotive/vehicle/aidl_property/Android.bp b/automotive/vehicle/aidl_property/Android.bp
new file mode 100644
index 0000000..58ce50d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/Android.bp
@@ -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 {
+ // 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.automotive.vehicle.property",
+ vendor_available: true,
+ srcs: [
+ // This HAL was originally part of android.hardware.automotive.vehicle
+ "android/hardware/automotive/vehicle/*.aidl",
+ ],
+ frozen: false,
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ min_sdk_version: "31",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.car.framework",
+ ],
+ },
+ },
+ versions_with_info: [
+ {
+ version: "1",
+ imports: [],
+ },
+ ],
+
+}
diff --git a/automotive/vehicle/aidl_property/OWNERS b/automotive/vehicle/aidl_property/OWNERS
new file mode 100644
index 0000000..73e45ca
--- /dev/null
+++ b/automotive/vehicle/aidl_property/OWNERS
@@ -0,0 +1 @@
[email protected]
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/.hash b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/.hash
new file mode 100644
index 0000000..02d7352
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/.hash
@@ -0,0 +1,2 @@
+8610b651e162c614a97542d6f4ed039c969823e5
+d80c4423311162bf7e4fdda8c7be2bad2371cc00
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/CustomInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvChargeState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/EvsServiceType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/EvsServiceType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/PortLocationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/TrailerState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/TrailerState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/TrailerState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UserInfo.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UserInfo.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/UsersInfo.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleArea.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleArea.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleArea.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleDisplay.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleGear.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleGear.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleGear.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleProperty.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleProperty.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleProperty.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleUnit.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleUnit.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleUnit.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/1/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..b316df7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum AutomaticEmergencyBrakingState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATED = 2,
+ USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
new file mode 100644
index 0000000..535b0b1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/BlindSpotWarningState.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 BlindSpotWarningState {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlCommand.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
new file mode 100644
index 0000000..d6a104d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlCommand.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 CruiseControlCommand {
+ ACTIVATE = 1,
+ SUSPEND = 2,
+ INCREASE_TARGET_SPEED = 3,
+ DECREASE_TARGET_SPEED = 4,
+ INCREASE_TARGET_TIME_GAP = 5,
+ DECREASE_TARGET_TIME_GAP = 6,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlState.aidl
new file mode 100644
index 0000000..ddaffa3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlState.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 CruiseControlState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATED = 2,
+ USER_OVERRIDE = 3,
+ SUSPENDED = 4,
+ FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlType.aidl
new file mode 100644
index 0000000..aab9dfe
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CruiseControlType.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum CruiseControlType {
+ OTHER = 0,
+ STANDARD = 1,
+ ADAPTIVE = 2,
+ PREDICTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CustomInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
new file mode 100644
index 0000000..078acde1
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.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 EmergencyLaneKeepAssistState {
+ OTHER = 0,
+ ENABLED = 1,
+ WARNING_LEFT = 2,
+ WARNING_RIGHT = 3,
+ ACTIVATED_STEER_LEFT = 4,
+ ACTIVATED_STEER_RIGHT = 5,
+ USER_OVERRIDE = 6,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ErrorState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ErrorState.aidl
new file mode 100644
index 0000000..dd950ce
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ErrorState.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 ErrorState {
+ OTHER_ERROR_STATE = (-1) /* -1 */,
+ NOT_AVAILABLE_DISABLED = (-2) /* -2 */,
+ NOT_AVAILABLE_SPEED_LOW = (-3) /* -3 */,
+ NOT_AVAILABLE_SPEED_HIGH = (-4) /* -4 */,
+ NOT_AVAILABLE_POOR_VISIBILITY = (-5) /* -5 */,
+ NOT_AVAILABLE_SAFETY = (-6) /* -6 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvChargeState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..3be8d12
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvStoppingMode {
+ OTHER = 0,
+ CREEP = 1,
+ ROLL = 2,
+ HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/EvsServiceState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
new file mode 100644
index 0000000..285732c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvsServiceType.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum EvsServiceType {
+ REARVIEW = 0,
+ SURROUNDVIEW = 1,
+ FRONTVIEW = 2,
+ LEFTVIEW = 3,
+ RIGHTVIEW = 4,
+ DRIVERVIEW = 5,
+ FRONTPASSENGERSVIEW = 6,
+ REARPASSENGERSVIEW = 7,
+ USER_DEFINED = 1000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
new file mode 100644
index 0000000..371885d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ForwardCollisionWarningState.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 ForwardCollisionWarningState {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..9c565ee
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum GsrComplianceRequirementType {
+ GSR_COMPLIANCE_NOT_REQUIRED = 0,
+ GSR_COMPLIANCE_REQUIRED_V1 = 1,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
new file mode 100644
index 0000000..bb390f2
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.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 HandsOnDetectionDriverState {
+ OTHER = 0,
+ HANDS_ON = 1,
+ HANDS_OFF = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
new file mode 100644
index 0000000..4ea4d1d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/HandsOnDetectionWarning.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 HandsOnDetectionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
new file mode 100644
index 0000000..9e72605
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneCenteringAssistCommand {
+ ACTIVATE = 1,
+ DEACTIVATE = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
new file mode 100644
index 0000000..c5afe2b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneCenteringAssistState.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 LaneCenteringAssistState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATION_REQUESTED = 2,
+ ACTIVATED = 3,
+ USER_OVERRIDE = 4,
+ FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
new file mode 100644
index 0000000..cdddb6f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneDepartureWarningState.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneDepartureWarningState {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING_LEFT = 2,
+ WARNING_RIGHT = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
new file mode 100644
index 0000000..9c92ff6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LaneKeepAssistState.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LaneKeepAssistState {
+ OTHER = 0,
+ ENABLED = 1,
+ ACTIVATED_STEER_LEFT = 2,
+ ACTIVATED_STEER_RIGHT = 3,
+ USER_OVERRIDE = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LocationCharacterization.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LocationCharacterization.aidl
new file mode 100644
index 0000000..27abe41
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LocationCharacterization.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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 LocationCharacterization {
+ PRIOR_LOCATIONS = 0x1,
+ GYROSCOPE_FUSION = 0x2,
+ ACCELEROMETER_FUSION = 0x4,
+ COMPASS_FUSION = 0x8,
+ WHEEL_SPEED_FUSION = 0x10,
+ STEERING_ANGLE_FUSION = 0x20,
+ CAR_SPEED_FUSION = 0x40,
+ DEAD_RECKONED = 0x80,
+ RAW_GNSS_ONLY = 0x100,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
new file mode 100644
index 0000000..7d12224
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2CommonIgnitionMonitors {
+ COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+ COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+ FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+ FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+ MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+ MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
new file mode 100644
index 0000000..90240bf
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2CompressionIgnitionMonitors {
+ COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+ COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+ FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+ FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+ MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+ MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+ EGR_OR_VVT_AVAILABLE = (0x1 << 6) /* 64 */,
+ EGR_OR_VVT_INCOMPLETE = (0x1 << 7) /* 128 */,
+ PM_FILTER_AVAILABLE = (0x1 << 8) /* 256 */,
+ PM_FILTER_INCOMPLETE = (0x1 << 9) /* 512 */,
+ EXHAUST_GAS_SENSOR_AVAILABLE = (0x1 << 10) /* 1024 */,
+ EXHAUST_GAS_SENSOR_INCOMPLETE = (0x1 << 11) /* 2048 */,
+ BOOST_PRESSURE_AVAILABLE = (0x1 << 12) /* 4096 */,
+ BOOST_PRESSURE_INCOMPLETE = (0x1 << 13) /* 8192 */,
+ NOx_SCR_AVAILABLE = (0x1 << 14) /* 16384 */,
+ NOx_SCR_INCOMPLETE = (0x1 << 15) /* 32768 */,
+ NMHC_CATALYST_AVAILABLE = (0x1 << 16) /* 65536 */,
+ NMHC_CATALYST_INCOMPLETE = (0x1 << 17) /* 131072 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
new file mode 100644
index 0000000..51e321b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum Obd2SparkIgnitionMonitors {
+ COMPONENTS_AVAILABLE = (0x1 << 0) /* 1 */,
+ COMPONENTS_INCOMPLETE = (0x1 << 1) /* 2 */,
+ FUEL_SYSTEM_AVAILABLE = (0x1 << 2) /* 4 */,
+ FUEL_SYSTEM_INCOMPLETE = (0x1 << 3) /* 8 */,
+ MISFIRE_AVAILABLE = (0x1 << 4) /* 16 */,
+ MISFIRE_INCOMPLETE = (0x1 << 5) /* 32 */,
+ EGR_AVAILABLE = (0x1 << 6) /* 64 */,
+ EGR_INCOMPLETE = (0x1 << 7) /* 128 */,
+ OXYGEN_SENSOR_HEATER_AVAILABLE = (0x1 << 8) /* 256 */,
+ OXYGEN_SENSOR_HEATER_INCOMPLETE = (0x1 << 9) /* 512 */,
+ OXYGEN_SENSOR_AVAILABLE = (0x1 << 10) /* 1024 */,
+ OXYGEN_SENSOR_INCOMPLETE = (0x1 << 11) /* 2048 */,
+ AC_REFRIGERANT_AVAILABLE = (0x1 << 12) /* 4096 */,
+ AC_REFRIGERANT_INCOMPLETE = (0x1 << 13) /* 8192 */,
+ SECONDARY_AIR_SYSTEM_AVAILABLE = (0x1 << 14) /* 16384 */,
+ SECONDARY_AIR_SYSTEM_INCOMPLETE = (0x1 << 15) /* 32768 */,
+ EVAPORATIVE_SYSTEM_AVAILABLE = (0x1 << 16) /* 65536 */,
+ EVAPORATIVE_SYSTEM_INCOMPLETE = (0x1 << 17) /* 131072 */,
+ HEATED_CATALYST_AVAILABLE = (0x1 << 18) /* 262144 */,
+ HEATED_CATALYST_INCOMPLETE = (0x1 << 19) /* 524288 */,
+ CATALYST_AVAILABLE = (0x1 << 20) /* 1048576 */,
+ CATALYST_INCOMPLETE = (0x1 << 21) /* 2097152 */,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PortLocationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RotaryInputType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/TrailerState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/TrailerState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/TrailerState.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserInfo.aidl
new file mode 100644
index 0000000..feb5a73
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UserInfo.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.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable UserInfo {
+ int userId = 0;
+ int flags;
+ const int USER_FLAG_SYSTEM = 0x01;
+ const int USER_FLAG_GUEST = 0x02;
+ const int USER_FLAG_EPHEMERAL = 0x04;
+ const int USER_FLAG_ADMIN = 0x08;
+ const int USER_FLAG_DISABLED = 0x10;
+ const int USER_FLAG_PROFILE = 0x20;
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
new file mode 100644
index 0000000..9720aca
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerBootupReason {
+ USER_POWER_ON = 0,
+ SYSTEM_USER_DETECTION = 1,
+ SYSTEM_REMOTE_ACCESS = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
new file mode 100644
index 0000000..cc12490
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerStateConfigFlag {
+ ENABLE_DEEP_SLEEP_FLAG = 0x1,
+ CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2,
+ ENABLE_HIBERNATION_FLAG = 0x4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
new file mode 100644
index 0000000..e4f7e54
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReport.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleApPowerStateReport {
+ WAIT_FOR_VHAL = 0x1,
+ DEEP_SLEEP_ENTRY = 0x2,
+ DEEP_SLEEP_EXIT = 0x3,
+ SHUTDOWN_POSTPONE = 0x4,
+ SHUTDOWN_START = 0x5,
+ ON = 0x6,
+ SHUTDOWN_PREPARE = 0x7,
+ SHUTDOWN_CANCELLED = 0x8,
+ HIBERNATION_ENTRY = 0x9,
+ HIBERNATION_EXIT = 0xA,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
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
new file mode 100644
index 0000000..db867f4
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleArea {
+ GLOBAL = 0x01000000,
+ WINDOW = 0x03000000,
+ MIRROR = 0x04000000,
+ SEAT = 0x05000000,
+ DOOR = 0x06000000,
+ WHEEL = 0x07000000,
+ MASK = 0x0f000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
new file mode 100644
index 0000000..04976d6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaDoor.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaDoor {
+ ROW_1_LEFT = 0x00000001,
+ ROW_1_RIGHT = 0x00000004,
+ ROW_2_LEFT = 0x00000010,
+ ROW_2_RIGHT = 0x00000040,
+ ROW_3_LEFT = 0x00000100,
+ ROW_3_RIGHT = 0x00000400,
+ HOOD = 0x10000000,
+ REAR = 0x20000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
new file mode 100644
index 0000000..2d1c048
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaMirror.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaMirror {
+ DRIVER_LEFT = 0x00000001,
+ DRIVER_RIGHT = 0x00000002,
+ DRIVER_CENTER = 0x00000004,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
new file mode 100644
index 0000000..44c9d54
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaSeat {
+ ROW_1_LEFT = 0x0001,
+ ROW_1_CENTER = 0x0002,
+ ROW_1_RIGHT = 0x0004,
+ ROW_2_LEFT = 0x0010,
+ ROW_2_CENTER = 0x0020,
+ ROW_2_RIGHT = 0x0040,
+ ROW_3_LEFT = 0x0100,
+ ROW_3_CENTER = 0x0200,
+ ROW_3_RIGHT = 0x0400,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
new file mode 100644
index 0000000..d1b314e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaWheel {
+ UNKNOWN = 0x0,
+ LEFT_FRONT = 0x1,
+ RIGHT_FRONT = 0x2,
+ LEFT_REAR = 0x4,
+ RIGHT_REAR = 0x8,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
new file mode 100644
index 0000000..2afcca3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAreaWindow.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAreaWindow {
+ FRONT_WINDSHIELD = 0x00000001,
+ REAR_WINDSHIELD = 0x00000002,
+ ROW_1_LEFT = 0x00000010,
+ ROW_1_RIGHT = 0x00000040,
+ ROW_2_LEFT = 0x00000100,
+ ROW_2_RIGHT = 0x00000400,
+ ROW_3_LEFT = 0x00001000,
+ ROW_3_RIGHT = 0x00004000,
+ ROOF_TOP_1 = 0x00010000,
+ ROOF_TOP_2 = 0x00020000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
new file mode 100644
index 0000000..be335ec
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleDisplay.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleDisplay {
+ MAIN = 0,
+ INSTRUMENT_CLUSTER = 1,
+ HUD = 2,
+ INPUT = 3,
+ AUXILIARY = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleGear.aidl
new file mode 100644
index 0000000..b8a299c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleGear.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleGear {
+ GEAR_UNKNOWN = 0x0000,
+ GEAR_NEUTRAL = 0x0001,
+ GEAR_REVERSE = 0x0002,
+ GEAR_PARK = 0x0004,
+ GEAR_DRIVE = 0x0008,
+ GEAR_1 = 0x0010,
+ GEAR_2 = 0x0020,
+ GEAR_3 = 0x0040,
+ GEAR_4 = 0x0080,
+ GEAR_5 = 0x0100,
+ GEAR_6 = 0x0200,
+ GEAR_7 = 0x0400,
+ GEAR_8 = 0x0800,
+ GEAR_9 = 0x1000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
new file mode 100644
index 0000000..4f9870a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHvacFanDirection {
+ UNKNOWN = 0x0,
+ FACE = 0x1,
+ FLOOR = 0x2,
+ FACE_AND_FLOOR = 0x3,
+ DEFROST = 0x4,
+ DEFROST_AND_FLOOR = 0x06,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
new file mode 100644
index 0000000..29c5ed6
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionButtonStateFlag {
+ BUTTON_PRIMARY = 0x0001,
+ BUTTON_SECONDARY = 0x0002,
+ BUTTON_TERTIARY = 0x0004,
+ BUTTON_BACK = 0x0008,
+ BUTTON_FORWARD = 0x0010,
+ BUTTON_STYLUS_PRIMARY = 0x0020,
+ BUTTON_STYLUS_SECONDARY = 0x0040,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
new file mode 100644
index 0000000..db4b41e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionInputAction {
+ ACTION_DOWN = 0,
+ ACTION_UP = 1,
+ ACTION_MOVE = 2,
+ ACTION_CANCEL = 3,
+ ACTION_OUTSIDE = 4,
+ ACTION_POINTER_DOWN = 5,
+ ACTION_POINTER_UP = 6,
+ ACTION_HOVER_MOVE = 7,
+ ACTION_SCROLL = 8,
+ ACTION_HOVER_ENTER = 9,
+ ACTION_HOVER_EXIT = 10,
+ ACTION_BUTTON_PRESS = 11,
+ ACTION_BUTTON_RELEASE = 12,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
new file mode 100644
index 0000000..88c7873
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionInputSource {
+ SOURCE_UNKNOWN = 0,
+ SOURCE_KEYBOARD = 1,
+ SOURCE_DPAD = 2,
+ SOURCE_GAMEPAD = 3,
+ SOURCE_TOUCHSCREEN = 4,
+ SOURCE_MOUSE = 5,
+ SOURCE_STYLUS = 6,
+ SOURCE_BLUETOOTH_STYLUS = 7,
+ SOURCE_TRACKBALL = 8,
+ SOURCE_MOUSE_RELATIVE = 9,
+ SOURCE_TOUCHPAD = 10,
+ SOURCE_TOUCH_NAVIGATION = 11,
+ SOURCE_ROTARY_ENCODER = 12,
+ SOURCE_JOYSTICK = 13,
+ SOURCE_HDMI = 14,
+ SOURCE_SENSOR = 15,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
new file mode 100644
index 0000000..2b3bc7f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleHwMotionToolType {
+ TOOL_TYPE_UNKNOWN = 0,
+ TOOL_TYPE_FINGER = 1,
+ TOOL_TYPE_STYLUS = 2,
+ TOOL_TYPE_MOUSE = 3,
+ TOOL_TYPE_ERASER = 4,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
new file mode 100644
index 0000000..f572a12
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleIgnitionState {
+ UNDEFINED = 0,
+ LOCK = 1,
+ OFF,
+ ACC,
+ ON,
+ START,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleLightState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
new file mode 100644
index 0000000..f244884
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleLightSwitch.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleLightSwitch {
+ OFF = 0,
+ ON = 1,
+ DAYTIME_RUNNING = 2,
+ AUTOMATIC = 0x100,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
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
new file mode 100644
index 0000000..ba75e7b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -0,0 +1,273 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleProperty {
+ INVALID = 0x00000000,
+ INFO_VIN = (((0x0100 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261504 */,
+ INFO_MAKE = (((0x0101 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261505 */,
+ INFO_MODEL = (((0x0102 + 0x10000000) + 0x01000000) + 0x00100000) /* 286261506 */,
+ INFO_MODEL_YEAR = (((0x0103 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407235 */,
+ INFO_FUEL_CAPACITY = (((0x0104 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504388 */,
+ INFO_FUEL_TYPE = (((0x0105 + 0x10000000) + 0x01000000) + 0x00410000) /* 289472773 */,
+ INFO_EV_BATTERY_CAPACITY = (((0x0106 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504390 */,
+ INFO_EV_CONNECTOR_TYPE = (((0x0107 + 0x10000000) + 0x01000000) + 0x00410000) /* 289472775 */,
+ INFO_FUEL_DOOR_LOCATION = (((0x0108 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407240 */,
+ INFO_EV_PORT_LOCATION = (((0x0109 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407241 */,
+ INFO_DRIVER_SEAT = (((0x010A + 0x10000000) + 0x05000000) + 0x00400000) /* 356516106 */,
+ INFO_EXTERIOR_DIMENSIONS = (((0x010B + 0x10000000) + 0x01000000) + 0x00410000) /* 289472779 */,
+ INFO_MULTI_EV_PORT_LOCATIONS = (((0x010C + 0x10000000) + 0x01000000) + 0x00410000) /* 289472780 */,
+ PERF_ODOMETER = (((0x0204 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504644 */,
+ PERF_VEHICLE_SPEED = (((0x0207 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504647 */,
+ PERF_VEHICLE_SPEED_DISPLAY = (((0x0208 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504648 */,
+ PERF_STEERING_ANGLE = (((0x0209 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504649 */,
+ PERF_REAR_STEERING_ANGLE = (((0x0210 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504656 */,
+ ENGINE_COOLANT_TEMP = (((0x0301 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504897 */,
+ ENGINE_OIL_LEVEL = (((0x0303 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407747 */,
+ ENGINE_OIL_TEMP = (((0x0304 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504900 */,
+ ENGINE_RPM = (((0x0305 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504901 */,
+ WHEEL_TICK = (((0x0306 + 0x10000000) + 0x01000000) + 0x00510000) /* 290521862 */,
+ FUEL_LEVEL = (((0x0307 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504903 */,
+ FUEL_DOOR_OPEN = (((0x0308 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310600 */,
+ EV_BATTERY_LEVEL = (((0x0309 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504905 */,
+ EV_CURRENT_BATTERY_CAPACITY = (((0x030D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504909 */,
+ EV_CHARGE_PORT_OPEN = (((0x030A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310602 */,
+ 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 */,
+ 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 */,
+ GEAR_SELECTION = (((0x0400 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408000 */,
+ CURRENT_GEAR = (((0x0401 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408001 */,
+ PARKING_BRAKE_ON = (((0x0402 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310850 */,
+ PARKING_BRAKE_AUTO_APPLY = (((0x0403 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310851 */,
+ EV_BRAKE_REGENERATION_LEVEL = (((0x040C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408012 */,
+ FUEL_LEVEL_LOW = (((0x0405 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310853 */,
+ NIGHT_MODE = (((0x0407 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310855 */,
+ TURN_SIGNAL_STATE = (((0x0408 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408008 */,
+ IGNITION_STATE = (((0x0409 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408009 */,
+ 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 */,
+ HVAC_FAN_SPEED = (((0x0500 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517120 */,
+ HVAC_FAN_DIRECTION = (((0x0501 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517121 */,
+ HVAC_TEMPERATURE_CURRENT = (((0x0502 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614274 */,
+ HVAC_TEMPERATURE_SET = (((0x0503 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614275 */,
+ HVAC_DEFROSTER = (((0x0504 + 0x10000000) + 0x03000000) + 0x00200000) /* 320865540 */,
+ HVAC_AC_ON = (((0x0505 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419973 */,
+ HVAC_MAX_AC_ON = (((0x0506 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419974 */,
+ HVAC_MAX_DEFROST_ON = (((0x0507 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419975 */,
+ HVAC_RECIRC_ON = (((0x0508 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419976 */,
+ HVAC_DUAL_ON = (((0x0509 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419977 */,
+ HVAC_AUTO_ON = (((0x050A + 0x10000000) + 0x05000000) + 0x00200000) /* 354419978 */,
+ HVAC_SEAT_TEMPERATURE = (((0x050B + 0x10000000) + 0x05000000) + 0x00400000) /* 356517131 */,
+ HVAC_SIDE_MIRROR_HEAT = (((0x050C + 0x10000000) + 0x04000000) + 0x00400000) /* 339739916 */,
+ HVAC_STEERING_WHEEL_HEAT = (((0x050D + 0x10000000) + 0x01000000) + 0x00400000) /* 289408269 */,
+ HVAC_TEMPERATURE_DISPLAY_UNITS = (((0x050E + 0x10000000) + 0x01000000) + 0x00400000) /* 289408270 */,
+ HVAC_ACTUAL_FAN_SPEED_RPM = (((0x050F + 0x10000000) + 0x05000000) + 0x00400000) /* 356517135 */,
+ HVAC_POWER_ON = (((0x0510 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419984 */,
+ HVAC_FAN_DIRECTION_AVAILABLE = (((0x0511 + 0x10000000) + 0x05000000) + 0x00410000) /* 356582673 */,
+ HVAC_AUTO_RECIRC_ON = (((0x0512 + 0x10000000) + 0x05000000) + 0x00200000) /* 354419986 */,
+ HVAC_SEAT_VENTILATION = (((0x0513 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517139 */,
+ HVAC_ELECTRIC_DEFROSTER_ON = (((0x0514 + 0x10000000) + 0x03000000) + 0x00200000) /* 320865556 */,
+ HVAC_TEMPERATURE_VALUE_SUGGESTION = (((0x0515 + 0x10000000) + 0x01000000) + 0x00610000) /* 291570965 */,
+ DISTANCE_DISPLAY_UNITS = (((0x0600 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408512 */,
+ FUEL_VOLUME_DISPLAY_UNITS = (((0x0601 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408513 */,
+ TIRE_PRESSURE_DISPLAY_UNITS = (((0x0602 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408514 */,
+ EV_BATTERY_DISPLAY_UNITS = (((0x0603 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408515 */,
+ FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = (((0x0604 + 0x10000000) + 0x01000000) + 0x00200000) /* 287311364 */,
+ VEHICLE_SPEED_DISPLAY_UNITS = (((0x0605 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408517 */,
+ EXTERNAL_CAR_TIME = (((0x0608 + 0x10000000) + 0x01000000) + 0x00500000) /* 290457096 */,
+ ANDROID_EPOCH_TIME = (((0x0606 + 0x10000000) + 0x01000000) + 0x00500000) /* 290457094 */,
+ STORAGE_ENCRYPTION_BINDING_SEED = (((0x0607 + 0x10000000) + 0x01000000) + 0x00700000) /* 292554247 */,
+ ENV_OUTSIDE_TEMPERATURE = (((0x0703 + 0x10000000) + 0x01000000) + 0x00600000) /* 291505923 */,
+ AP_POWER_STATE_REQ = (((0x0A00 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475072 */,
+ AP_POWER_STATE_REPORT = (((0x0A01 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475073 */,
+ AP_POWER_BOOTUP_REASON = (((0x0A02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409538 */,
+ DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
+ PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
+ 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 */,
+ HW_ROTARY_INPUT = (((0x0A20 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475104 */,
+ HW_CUSTOM_INPUT = (((0X0A30 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475120 */,
+ DOOR_POS = (((0x0B00 + 0x10000000) + 0x06000000) + 0x00400000) /* 373295872 */,
+ DOOR_MOVE = (((0x0B01 + 0x10000000) + 0x06000000) + 0x00400000) /* 373295873 */,
+ DOOR_LOCK = (((0x0B02 + 0x10000000) + 0x06000000) + 0x00200000) /* 371198722 */,
+ DOOR_CHILD_LOCK_ENABLED = (((0x0B03 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.DOOR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 371198723 */,
+ MIRROR_Z_POS = (((0x0B40 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741504 */,
+ MIRROR_Z_MOVE = (((0x0B41 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741505 */,
+ MIRROR_Y_POS = (((0x0B42 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741506 */,
+ MIRROR_Y_MOVE = (((0x0B43 + 0x10000000) + 0x04000000) + 0x00400000) /* 339741507 */,
+ MIRROR_LOCK = (((0x0B44 + 0x10000000) + 0x01000000) + 0x00200000) /* 287312708 */,
+ MIRROR_FOLD = (((0x0B45 + 0x10000000) + 0x01000000) + 0x00200000) /* 287312709 */,
+ MIRROR_AUTO_FOLD_ENABLED = (((0x0B46 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 337644358 */,
+ MIRROR_AUTO_TILT_ENABLED = (((0x0B47 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 337644359 */,
+ SEAT_MEMORY_SELECT = (((0x0B80 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518784 */,
+ SEAT_MEMORY_SET = (((0x0B81 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518785 */,
+ SEAT_BELT_BUCKLED = (((0x0B82 + 0x10000000) + 0x05000000) + 0x00200000) /* 354421634 */,
+ SEAT_BELT_HEIGHT_POS = (((0x0B83 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518787 */,
+ SEAT_BELT_HEIGHT_MOVE = (((0x0B84 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518788 */,
+ SEAT_FORE_AFT_POS = (((0x0B85 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518789 */,
+ SEAT_FORE_AFT_MOVE = (((0x0B86 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518790 */,
+ SEAT_BACKREST_ANGLE_1_POS = (((0x0B87 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518791 */,
+ SEAT_BACKREST_ANGLE_1_MOVE = (((0x0B88 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518792 */,
+ SEAT_BACKREST_ANGLE_2_POS = (((0x0B89 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518793 */,
+ SEAT_BACKREST_ANGLE_2_MOVE = (((0x0B8A + 0x10000000) + 0x05000000) + 0x00400000) /* 356518794 */,
+ SEAT_HEIGHT_POS = (((0x0B8B + 0x10000000) + 0x05000000) + 0x00400000) /* 356518795 */,
+ SEAT_HEIGHT_MOVE = (((0x0B8C + 0x10000000) + 0x05000000) + 0x00400000) /* 356518796 */,
+ SEAT_DEPTH_POS = (((0x0B8D + 0x10000000) + 0x05000000) + 0x00400000) /* 356518797 */,
+ SEAT_DEPTH_MOVE = (((0x0B8E + 0x10000000) + 0x05000000) + 0x00400000) /* 356518798 */,
+ SEAT_TILT_POS = (((0x0B8F + 0x10000000) + 0x05000000) + 0x00400000) /* 356518799 */,
+ SEAT_TILT_MOVE = (((0x0B90 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518800 */,
+ SEAT_LUMBAR_FORE_AFT_POS = (((0x0B91 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518801 */,
+ SEAT_LUMBAR_FORE_AFT_MOVE = (((0x0B92 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518802 */,
+ SEAT_LUMBAR_SIDE_SUPPORT_POS = (((0x0B93 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518803 */,
+ SEAT_LUMBAR_SIDE_SUPPORT_MOVE = (((0x0B94 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518804 */,
+ SEAT_HEADREST_HEIGHT_POS = (((0x0B95 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409941 */,
+ SEAT_HEADREST_HEIGHT_POS_V2 = (((0x0BA4 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518820 */,
+ SEAT_HEADREST_HEIGHT_MOVE = (((0x0B96 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518806 */,
+ SEAT_HEADREST_ANGLE_POS = (((0x0B97 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518807 */,
+ SEAT_HEADREST_ANGLE_MOVE = (((0x0B98 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518808 */,
+ SEAT_HEADREST_FORE_AFT_POS = (((0x0B99 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518809 */,
+ SEAT_HEADREST_FORE_AFT_MOVE = (((0x0B9A + 0x10000000) + 0x05000000) + 0x00400000) /* 356518810 */,
+ SEAT_FOOTWELL_LIGHTS_STATE = (((0x0B9B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518811 */,
+ 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_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_OCCUPANCY = (((0x0BB0 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518832 */,
+ WINDOW_POS = (((0x0BC0 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964416 */,
+ WINDOW_MOVE = (((0x0BC1 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964417 */,
+ WINDOW_LOCK = (((0x0BC4 + 0x10000000) + 0x03000000) + 0x00200000) /* 320867268 */,
+ WINDSHIELD_WIPERS_PERIOD = (((0x0BC5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964421 */,
+ WINDSHIELD_WIPERS_STATE = (((0x0BC6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964422 */,
+ WINDSHIELD_WIPERS_SWITCH = (((0x0BC7 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WINDOW) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 322964423 */,
+ STEERING_WHEEL_DEPTH_POS = (((0x0BE0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410016 */,
+ STEERING_WHEEL_DEPTH_MOVE = (((0x0BE1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410017 */,
+ STEERING_WHEEL_HEIGHT_POS = (((0x0BE2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410018 */,
+ STEERING_WHEEL_HEIGHT_MOVE = (((0x0BE3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410019 */,
+ STEERING_WHEEL_THEFT_LOCK_ENABLED = (((0x0BE4 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312868 */,
+ STEERING_WHEEL_LOCKED = (((0x0BE5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312869 */,
+ STEERING_WHEEL_EASY_ACCESS_ENABLED = (((0x0BE6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312870 */,
+ GLOVE_BOX_DOOR_POS = (((0x0BF0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518896 */,
+ GLOVE_BOX_LOCKED = (((0x0BF1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421745 */,
+ VEHICLE_MAP_SERVICE = (((0x0C00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299895808 */,
+ LOCATION_CHARACTERIZATION = (((0x0C10 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410064 */,
+ OBD2_LIVE_FRAME = (((0x0D00 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896064 */,
+ OBD2_FREEZE_FRAME = (((0x0D01 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896065 */,
+ OBD2_FREEZE_FRAME_INFO = (((0x0D02 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896066 */,
+ OBD2_FREEZE_FRAME_CLEAR = (((0x0D03 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896067 */,
+ HEADLIGHTS_STATE = (((0x0E00 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410560 */,
+ HIGH_BEAM_LIGHTS_STATE = (((0x0E01 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410561 */,
+ FOG_LIGHTS_STATE = (((0x0E02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410562 */,
+ HAZARD_LIGHTS_STATE = (((0x0E03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410563 */,
+ HEADLIGHTS_SWITCH = (((0x0E10 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410576 */,
+ HIGH_BEAM_LIGHTS_SWITCH = (((0x0E11 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410577 */,
+ FOG_LIGHTS_SWITCH = (((0x0E12 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410578 */,
+ HAZARD_LIGHTS_SWITCH = (((0x0E13 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410579 */,
+ CABIN_LIGHTS_STATE = (((0x0F01 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410817 */,
+ CABIN_LIGHTS_SWITCH = (((0x0F02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410818 */,
+ READING_LIGHTS_STATE = (((0x0F03 + 0x10000000) + 0x05000000) + 0x00400000) /* 356519683 */,
+ READING_LIGHTS_SWITCH = (((0x0F04 + 0x10000000) + 0x05000000) + 0x00400000) /* 356519684 */,
+ STEERING_WHEEL_LIGHTS_STATE = (((0x0F0C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410828 */,
+ STEERING_WHEEL_LIGHTS_SWITCH = (((0x0F0D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410829 */,
+ SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = (((0x0F05 + 0x10000000) + 0x01000000) + 0x00200000) /* 287313669 */,
+ DISABLED_OPTIONAL_FEATURES = (((0x0F06 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265094 */,
+ INITIAL_USER_INFO = (((0x0F07 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896583 */,
+ SWITCH_USER = (((0x0F08 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896584 */,
+ CREATE_USER = (((0x0F09 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896585 */,
+ REMOVE_USER = (((0x0F0A + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896586 */,
+ USER_IDENTIFICATION_ASSOCIATION = (((0x0F0B + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896587 */,
+ EVS_SERVICE_REQUEST = (((0x0F10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476368 */,
+ POWER_POLICY_REQ = (((0x0F21 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265121 */,
+ POWER_POLICY_GROUP_REQ = (((0x0F22 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265122 */,
+ CURRENT_POWER_POLICY = (((0x0F23 + 0x10000000) + 0x01000000) + 0x00100000) /* 286265123 */,
+ WATCHDOG_ALIVE = (((0xF31 + 0x10000000) + 0x01000000) + 0x00500000) /* 290459441 */,
+ WATCHDOG_TERMINATED_PROCESS = (((0x0F32 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896626 */,
+ VHAL_HEARTBEAT = (((0x0F33 + 0x10000000) + 0x01000000) + 0x00500000) /* 290459443 */,
+ CLUSTER_SWITCH_UI = (((0x0F34 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410868 */,
+ CLUSTER_DISPLAY_STATE = (((0x0F35 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476405 */,
+ CLUSTER_REPORT_STATE = (((0x0F36 + 0x10000000) + 0x01000000) + 0x00e00000) /* 299896630 */,
+ CLUSTER_REQUEST_DISPLAY = (((0x0F37 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410871 */,
+ CLUSTER_NAVIGATION_STATE = (((0x0F38 + 0x10000000) + 0x01000000) + 0x00700000) /* 292556600 */,
+ ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = (((0x0F39 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410873 */,
+ ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = (((0x0F3A + 0x10000000) + 0x01000000) + 0x00400000) /* 289410874 */,
+ FRONT_FOG_LIGHTS_STATE = (((0x0F3B + 0x10000000) + 0x01000000) + 0x00400000) /* 289410875 */,
+ FRONT_FOG_LIGHTS_SWITCH = (((0x0F3C + 0x10000000) + 0x01000000) + 0x00400000) /* 289410876 */,
+ REAR_FOG_LIGHTS_STATE = (((0x0F3D + 0x10000000) + 0x01000000) + 0x00400000) /* 289410877 */,
+ REAR_FOG_LIGHTS_SWITCH = (((0x0F3E + 0x10000000) + 0x01000000) + 0x00400000) /* 289410878 */,
+ EV_CHARGE_CURRENT_DRAW_LIMIT = (((0x0F3F + 0x10000000) + 0x01000000) + 0x00600000) /* 291508031 */,
+ EV_CHARGE_PERCENT_LIMIT = (((0x0F40 + 0x10000000) + 0x01000000) + 0x00600000) /* 291508032 */,
+ EV_CHARGE_STATE = (((0x0F41 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410881 */,
+ EV_CHARGE_SWITCH = (((0x0F42 + 0x10000000) + 0x01000000) + 0x00200000) /* 287313730 */,
+ EV_CHARGE_TIME_REMAINING = (((0x0F43 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410883 */,
+ EV_REGENERATIVE_BRAKING_STATE = (((0x0F44 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410884 */,
+ TRAILER_PRESENT = (((0x0F45 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410885 */,
+ VEHICLE_CURB_WEIGHT = (((0x0F46 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410886 */,
+ GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = (((0x0F47 + 0x10000000) + 0x01000000) + 0x00400000) /* 289410887 */,
+ SUPPORTED_PROPERTY_IDS = (((0x0F48 + 0x10000000) + 0x01000000) + 0x00410000) /* 289476424 */,
+ 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 */,
+ 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 */,
+ FORWARD_COLLISION_WARNING_STATE = (((0x1003 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411075 */,
+ BLIND_SPOT_WARNING_ENABLED = (((0x1004 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313924 */,
+ BLIND_SPOT_WARNING_STATE = (((0x1005 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.MIRROR) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 339742725 */,
+ LANE_DEPARTURE_WARNING_ENABLED = (((0x1006 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313926 */,
+ LANE_DEPARTURE_WARNING_STATE = (((0x1007 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411079 */,
+ LANE_KEEP_ASSIST_ENABLED = (((0x1008 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313928 */,
+ LANE_KEEP_ASSIST_STATE = (((0x1009 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411081 */,
+ LANE_CENTERING_ASSIST_ENABLED = (((0x100A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313930 */,
+ LANE_CENTERING_ASSIST_COMMAND = (((0x100B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411083 */,
+ LANE_CENTERING_ASSIST_STATE = (((0x100C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411084 */,
+ EMERGENCY_LANE_KEEP_ASSIST_ENABLED = (((0x100D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313933 */,
+ EMERGENCY_LANE_KEEP_ASSIST_STATE = (((0x100E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411086 */,
+ CRUISE_CONTROL_ENABLED = (((0x100F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313935 */,
+ CRUISE_CONTROL_TYPE = (((0x1010 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411088 */,
+ CRUISE_CONTROL_STATE = (((0x1011 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411089 */,
+ CRUISE_CONTROL_COMMAND = (((0x1012 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411090 */,
+ CRUISE_CONTROL_TARGET_SPEED = (((0x1013 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291508243 */,
+ ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP = (((0x1014 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411092 */,
+ ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE = (((0x1015 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411093 */,
+ 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 */,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
new file mode 100644
index 0000000..714d514
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyGroup.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyGroup {
+ SYSTEM = 0x10000000,
+ VENDOR = 0x20000000,
+ MASK = 0xf0000000,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
new file mode 100644
index 0000000..7525cbb
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehiclePropertyType.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehiclePropertyType {
+ STRING = 0x00100000,
+ BOOLEAN = 0x00200000,
+ INT32 = 0x00400000,
+ INT32_VEC = 0x00410000,
+ INT64 = 0x00500000,
+ INT64_VEC = 0x00510000,
+ FLOAT = 0x00600000,
+ FLOAT_VEC = 0x00610000,
+ BYTES = 0x00700000,
+ MIXED = 0x00e00000,
+ MASK = 0x00ff0000,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
new file mode 100644
index 0000000..0431b45
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleTurnSignal.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleTurnSignal {
+ NONE = 0x00,
+ RIGHT = 0x01,
+ LEFT = 0x02,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
new file mode 100644
index 0000000..9aca98b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleUnit.aidl
@@ -0,0 +1,71 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleUnit {
+ SHOULD_NOT_USE = 0x000,
+ METER_PER_SEC = 0x01,
+ RPM = 0x02,
+ HERTZ = 0x03,
+ PERCENTILE = 0x10,
+ MILLIMETER = 0x20,
+ METER = 0x21,
+ KILOMETER = 0x23,
+ MILE = 0x24,
+ CELSIUS = 0x30,
+ FAHRENHEIT = 0x31,
+ KELVIN = 0x32,
+ MILLILITER = 0x40,
+ LITER = 0x41,
+ GALLON = 0x42,
+ US_GALLON = 0x42,
+ IMPERIAL_GALLON = 0x43,
+ NANO_SECS = 0x50,
+ MILLI_SECS = 0x51,
+ SECS = 0x53,
+ YEAR = 0x59,
+ WATT_HOUR = 0x60,
+ MILLIAMPERE = 0x61,
+ MILLIVOLT = 0x62,
+ MILLIWATTS = 0x63,
+ AMPERE_HOURS = 0x64,
+ KILOWATT_HOUR = 0x65,
+ AMPERE = 0x66,
+ KILOPASCAL = 0x70,
+ PSI = 0x71,
+ BAR = 0x72,
+ DEGREES = 0x80,
+ MILES_PER_HOUR = 0x90,
+ KILOMETERS_PER_HOUR = 0x91,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
new file mode 100644
index 0000000..3aa326c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleVendorPermission {
+ PERMISSION_DEFAULT = 0x00000000,
+ PERMISSION_SET_VENDOR_CATEGORY_WINDOW = 0X00000001,
+ PERMISSION_GET_VENDOR_CATEGORY_WINDOW = 0x00000002,
+ PERMISSION_SET_VENDOR_CATEGORY_DOOR = 0x00000003,
+ PERMISSION_GET_VENDOR_CATEGORY_DOOR = 0x00000004,
+ PERMISSION_SET_VENDOR_CATEGORY_SEAT = 0x00000005,
+ PERMISSION_GET_VENDOR_CATEGORY_SEAT = 0x00000006,
+ PERMISSION_SET_VENDOR_CATEGORY_MIRROR = 0x00000007,
+ PERMISSION_GET_VENDOR_CATEGORY_MIRROR = 0x00000008,
+ PERMISSION_SET_VENDOR_CATEGORY_INFO = 0x00000009,
+ PERMISSION_GET_VENDOR_CATEGORY_INFO = 0x0000000A,
+ PERMISSION_SET_VENDOR_CATEGORY_ENGINE = 0x0000000B,
+ PERMISSION_GET_VENDOR_CATEGORY_ENGINE = 0x0000000C,
+ PERMISSION_SET_VENDOR_CATEGORY_HVAC = 0x0000000D,
+ PERMISSION_GET_VENDOR_CATEGORY_HVAC = 0x0000000E,
+ PERMISSION_SET_VENDOR_CATEGORY_LIGHT = 0x0000000F,
+ PERMISSION_GET_VENDOR_CATEGORY_LIGHT = 0x00000010,
+ PERMISSION_SET_VENDOR_CATEGORY_1 = 0x00010000,
+ PERMISSION_GET_VENDOR_CATEGORY_1 = 0x00011000,
+ PERMISSION_SET_VENDOR_CATEGORY_2 = 0x00020000,
+ PERMISSION_GET_VENDOR_CATEGORY_2 = 0x00021000,
+ PERMISSION_SET_VENDOR_CATEGORY_3 = 0x00030000,
+ PERMISSION_GET_VENDOR_CATEGORY_3 = 0x00031000,
+ PERMISSION_SET_VENDOR_CATEGORY_4 = 0x00040000,
+ PERMISSION_GET_VENDOR_CATEGORY_4 = 0x00041000,
+ PERMISSION_SET_VENDOR_CATEGORY_5 = 0x00050000,
+ PERMISSION_GET_VENDOR_CATEGORY_5 = 0x00051000,
+ PERMISSION_SET_VENDOR_CATEGORY_6 = 0x00060000,
+ PERMISSION_GET_VENDOR_CATEGORY_6 = 0x00061000,
+ PERMISSION_SET_VENDOR_CATEGORY_7 = 0x00070000,
+ PERMISSION_GET_VENDOR_CATEGORY_7 = 0x00071000,
+ PERMISSION_SET_VENDOR_CATEGORY_8 = 0x00080000,
+ PERMISSION_GET_VENDOR_CATEGORY_8 = 0x00081000,
+ PERMISSION_SET_VENDOR_CATEGORY_9 = 0x00090000,
+ PERMISSION_GET_VENDOR_CATEGORY_9 = 0x00091000,
+ PERMISSION_SET_VENDOR_CATEGORY_10 = 0x000A0000,
+ PERMISSION_GET_VENDOR_CATEGORY_10 = 0x000A1000,
+ PERMISSION_NOT_ACCESSIBLE = 0xF0000000,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageType.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
new file mode 100644
index 0000000..d0c1e8d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersState.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum WindshieldWipersState {
+ OTHER = 0,
+ OFF = 1,
+ ON = 2,
+ SERVICE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
new file mode 100644
index 0000000..6c170fe
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/WindshieldWipersSwitch.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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum WindshieldWipersSwitch {
+ OTHER = 0,
+ OFF = 1,
+ MIST = 2,
+ INTERMITTENT_LEVEL_1 = 3,
+ INTERMITTENT_LEVEL_2 = 4,
+ INTERMITTENT_LEVEL_3 = 5,
+ INTERMITTENT_LEVEL_4 = 6,
+ INTERMITTENT_LEVEL_5 = 7,
+ CONTINUOUS_LEVEL_1 = 8,
+ CONTINUOUS_LEVEL_2 = 9,
+ CONTINUOUS_LEVEL_3 = 10,
+ CONTINUOUS_LEVEL_4 = 11,
+ CONTINUOUS_LEVEL_5 = 12,
+ AUTO = 13,
+ SERVICE = 14,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
new file mode 100644
index 0000000..540c663
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.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.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Automatic Emergency Braking (AEB).
+ */
+@VintfStability
+@Backing(type="int")
+enum AutomaticEmergencyBrakingState {
+
+ /**
+ * This state is used as an alternative to any AutomaticEmergencyBrakingState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#AUTOMATIC_EMERGENCY_BRAKING_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if AutomaticEmergencyBrakingState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * AEB is enabled and monitoring safety, but brakes are not activated.
+ */
+ ENABLED = 1,
+ /**
+ * AEB is enabled and currently has the brakes applied for the vehicle.
+ */
+ ACTIVATED = 2,
+ /**
+ * Many AEB implementations allow the driver to override AEB. This means that the car has
+ * determined it should brake, but a user decides to take over and do something else. This is
+ * often done for safety reasons and to ensure that the driver can always take control of the
+ * vehicle. This state should be set when the user is actively overriding the AEB system.
+ */
+ USER_OVERRIDE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
new file mode 100644
index 0000000..3f567c0
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.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 Blind Spot Warning State (BSW).
+ */
+@VintfStability
+@Backing(type="int")
+enum BlindSpotWarningState {
+
+ /**
+ * This state is used as an alternative to any BlindSpotWarningState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#BLIND_SPOT_WARNING_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if BlindSpotWarningState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * BSW is enabled and monitoring safety, but no vehicle or object detected in the vehicle's
+ * blind spot.
+ */
+ NO_WARNING = 1,
+ /**
+ * BSW is enabled, detects a vehicle or object in the vehicle's blind spot, and is actively
+ * warning the user.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CreateUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
new file mode 100644
index 0000000..18e1405
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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 Cruise Control (CC) commands.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum CruiseControlCommand {
+ /**
+ * Activate cruise control, which means CC takes control of maintaining the vehicle's target
+ * speed without the driver having to keep their foot on the accelerator. The target speed for
+ * CC is generally set to the vehicle's speed at the time of activation.
+ */
+ ACTIVATE = 1,
+ /**
+ * Suspend cruise control, but still keep it enabled. Once CC is activated again, the
+ * target speed should resume to the previous setting.
+ */
+ SUSPEND = 2,
+ /**
+ * Increase the target speed when CC is activated. The increment value should be decided by the
+ * OEM. The updated value can be read from CRUISE_CONTROL_TARGET_SPEED.
+ */
+ INCREASE_TARGET_SPEED = 3,
+ /**
+ * Decrease the target speed when CC is activated. The decrement value should be decided by the
+ * OEM. The updated value can be read from CRUISE_CONTROL_TARGET_SPEED.
+ */
+ DECREASE_TARGET_SPEED = 4,
+ /**
+ * Increase the target time gap or distance from the vehicle ahead when adaptive/predictive CC
+ * is activated. The increment value should be decided by the OEM. The updated value can be read
+ * from ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP. Setting this command on a standard CC vehicle
+ * should return StatusCode.NOT_AVAILABLE.
+ */
+ INCREASE_TARGET_TIME_GAP = 5,
+ /**
+ * Decrease the target time gap or distance from the vehicle ahead when adaptive/predictive CC
+ * is activated. The decrement value should be decided by the 0EM. The updated value can be read
+ * from ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP. Setting this command on a standard CC vehicle
+ * should return StatusCode.NOT_AVAILABLE.
+ */
+ DECREASE_TARGET_TIME_GAP = 6,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
new file mode 100644
index 0000000..0e55e00
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
@@ -0,0 +1,67 @@
+/*
+ * 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 Cruise Control (CC).
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum CruiseControlState {
+ /**
+ * This state is used as an alternative for any CruiseControlState value that is not defined in
+ * the platform. Ideally, implementations of VehicleProperty#CRUISE_CONTROL_STATE should not use
+ * this state. The framework can use this field to remain backwards compatible if
+ * CruiseControlState is extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * CC is enabled but the ADAS system is not actively controlling the vehicle's speed.
+ */
+ ENABLED = 1,
+ /**
+ * CC is enabled and activated, so the ADAS system is actively controlling the vehicle's speed.
+ */
+ ACTIVATED = 2,
+ /**
+ * Most CC implementations allow the driver to override CC. This means that the car has
+ * determined it should maintain a certain speed and/or maintain a certain distance from a
+ * leading vehicle, but the driver decides to take over and do something else. This is often
+ * done for safety reasons and to ensure that the driver can always take control of the vehicle.
+ * This state should be set when the user is actively overriding the CC system.
+ */
+ USER_OVERRIDE = 3,
+ /**
+ * Suspended state indicates CC is enabled and was activated, but now is suspended. This could
+ * be caused by the user tapping the brakes while CC is ACTIVATED or the user using the
+ * VehicleProperty#CRUISE_CONTROL_COMMAND to suspend CC. Once CC is suspended, the CC system
+ * gives control of the vehicle back to the driver, but saves the target speed and/or target
+ * time gap settings in case CC is resumed. This state can also be used when adaptive/predictive
+ * CC slows to a stop and needs a user signal to start again.
+ */
+ SUSPENDED = 4,
+ /**
+ * When CC is in the ACTIVATED state but may potentially need to deactivate because of external
+ * conditions (e.g. roads curvature is too extreme, the driver does not have their hands on the
+ * steering wheel for a long period of time, or the driver is not paying attention), then the
+ * ADAS system will notify the driver of a potential need to deactivate and give control back to
+ * the driver.
+ */
+ FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl
new file mode 100644
index 0000000..2367b82
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.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.automotive.vehicle;
+
+/**
+ * Used to enumerate the current type of Cruise Control (CC).
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum CruiseControlType {
+ /**
+ * This state is used as an alternative for any CruiseControlType value that is not defined in
+ * the platform. Ideally, implementations of VehicleProperty#CRUISE_CONTROL_TYPE should not use
+ * this state. The framework can use this field to remain backwards compatible if
+ * CruiseControlType is extended to include additional types.
+ */
+ OTHER = 0,
+ /**
+ * Standard cruise control is when a system in the vehicle automatically maintains a set speed
+ * without the driver having to keep their foot on the accelerator. This version of cruise
+ * control does not include automatic acceleration and deceleration to maintain a set time gap
+ * from a vehicle ahead.
+ */
+ STANDARD = 1,
+ /**
+ * Adaptive cruise control is when a system in the vehicle automatically accelerates and
+ * decelerates to maintain a set speed and/or a set time gap from a vehicle ahead.
+ */
+ ADAPTIVE = 2,
+ /**
+ * Predictive cruise control is a version of adaptive cruise control that also considers road
+ * topography, road curvature, speed limit and traffic signs, etc. to actively adjust braking,
+ * acceleration, gear shifting, etc. for the vehicle. This feature is often used to optimize
+ * fuel consumption.
+ */
+ PREDICTIVE = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CustomInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/CustomInputType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CustomInputType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
new file mode 100644
index 0000000..302b9af
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.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.automotive.vehicle;
+
+/**
+ * Used by emergency lane keep assist to enumerate state.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum EmergencyLaneKeepAssistState {
+ /**
+ * This state is used as an alternative for any EmergencyLaneKeepAssistState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#EMERGENCY_LANE_KEEP_ASSIST_STATE should not use this state. The framework can
+ * use this field to remain backwards compatible if EmergencyLaneKeepAssistState is extended to
+ * include additional states.
+ */
+ OTHER = 0,
+ /**
+ * ELKA is enabled and monitoring safety, but no safety event is detected and steering assist is
+ * not activated.
+ */
+ ENABLED = 1,
+ /**
+ * ELKA is enabled and a safety event is detected. Vehicle is sending out a warning to the
+ * driver indicating that there is a dangerous maneuver on the left side of the vehicle.
+ */
+ WARNING_LEFT = 2,
+ /**
+ * ELKA is enabled and a safety event is detected. Vehicle is sending out a warning to the
+ * driver indicating that there is a dangerous maneuver on the right side of the vehicle.
+ */
+ WARNING_RIGHT = 3,
+ /**
+ * ELKA is enabled and currently has steering assist applied to the vehicle. Steering assist
+ * nudges the vehicle towards the left, which generally means the steering wheel turns counter
+ * clockwise. This is usually in response to the driver making an unsafe right lane change.
+ */
+ ACTIVATED_STEER_LEFT = 4,
+ /**
+ * ELKA is enabled and currently has steering assist applied to the vehicle. Steering assist
+ * nudges the vehicle towards the right, which generally means the steering wheel turns
+ * clockwise. This is usually in response to the driver making an unsafe left lane change.
+ */
+ ACTIVATED_STEER_RIGHT = 5,
+ /**
+ * Many safety feature implementations allow the driver to override said feature. This means
+ * that the car has determined it should take some action, but a user decides to take over and
+ * do something else. This is often done for safety reasons and to ensure that the driver can
+ * always take control of the vehicle. This state should be set when the user is currently
+ * overriding ELKA.
+ */
+ USER_OVERRIDE = 6,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
new file mode 100644
index 0000000..ba44672
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
@@ -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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the possible error states. For version 2 of this interface, ErrorState is used
+ * by ADAS STATE properties, but its use may be expanded in future releases.
+ */
+@VintfStability
+@Backing(type="int")
+enum ErrorState {
+
+ /**
+ * This state is used as an alternative to any ErrorState value that is not defined in the
+ * platform. Ideally, implementations of vehicle properties should not use this state. The
+ * framework can use this field to remain backwards compatible if this enum is extended to
+ * include additional states.
+ */
+ OTHER_ERROR_STATE = -1,
+ /**
+ * Vehicle property is not available because the feature is disabled.
+ */
+ NOT_AVAILABLE_DISABLED = -2,
+ /**
+ * Vehicle property is not available because the vehicle speed is too low to use this feature.
+ */
+ NOT_AVAILABLE_SPEED_LOW = -3,
+ /**
+ * Vehicle property is not available because the vehicle speed is too high to use this feature.
+ */
+ NOT_AVAILABLE_SPEED_HIGH = -4,
+ /**
+ * Vehicle property is not available because sensor or camera visibility is insufficient to use
+ * this feature. For example, this can be caused by bird poop blocking the camera, poor weather
+ * conditions such as snow or fog, or by any object obstructing the required sensors.
+ */
+ NOT_AVAILABLE_POOR_VISIBILITY = -5,
+ /**
+ * Vehicle property is not available because there is a safety risk that makes this feature
+ * unavailable to use presently. For example, this can be caused by someone blocking the trunk
+ * door while it is closing, or by the system being in a faulty state.
+ */
+ NOT_AVAILABLE_SAFETY = -6,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvChargeState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvConnectorType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl
new file mode 100644
index 0000000..8c5ac46
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by EV_STOPPING_MODE to enumerate the current state of the stopping mode.
+ *
+ * This enum may be extended to include more states in the future.
+ */
+@VintfStability
+@Backing(type="int")
+enum EvStoppingMode {
+ /**
+ * Other EV stopping mode. Ideally, this should never be used.
+ */
+ OTHER = 0,
+ /**
+ * Vehicle slowly moves forward when the brake pedal is released.
+ */
+ CREEP = 1,
+ /**
+ * Vehicle rolls freely when the brake pedal is released (similar to neutral gear).
+ */
+ ROLL = 2,
+ /**
+ * Vehicle stops and holds its position when the brake pedal is released.
+ */
+ HOLD = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceRequestIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/EvsServiceState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceState.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceType.aidl
new file mode 100644
index 0000000..20582dc
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvsServiceType.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by EVS_SERVICE_REQUEST to enumerate the service's type.
+ */
+@VintfStability
+@Backing(type="int")
+enum EvsServiceType {
+ REARVIEW = 0,
+ SURROUNDVIEW = 1,
+ FRONTVIEW = 2,
+ LEFTVIEW = 3,
+ RIGHTVIEW = 4,
+ DRIVERVIEW = 5,
+ FRONTPASSENGERSVIEW = 6,
+ REARPASSENGERSVIEW = 7,
+ USER_DEFINED = 1000,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
new file mode 100644
index 0000000..b20cf25
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.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.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Forward Collision Warning State (FCW).
+ */
+@VintfStability
+@Backing(type="int")
+enum ForwardCollisionWarningState {
+
+ /**
+ * This state is used as an alternative to any ForwardCollisionWarningState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#FORWARD_COLLISION_WARNING_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if ForwardCollisionWarningState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * FCW is enabled and monitoring safety, but no potential collision is detected.
+ */
+ NO_WARNING = 1,
+ /**
+ * FCW is enabled, detects a potential collision, and is actively warning the user.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/FuelType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/FuelType.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..fb3ca9f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used by GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT to indicate what
+ * kind of general safety regulation compliance requirement is enforced.
+ */
+@VintfStability
+@Backing(type="int")
+enum GsrComplianceRequirementType {
+ /**
+ * GSR compliance is not required.
+ */
+ GSR_COMPLIANCE_NOT_REQUIRED = 0,
+
+ /**
+ * GSR compliance is required and the requirement solution version is 1.
+ */
+ GSR_COMPLIANCE_REQUIRED_V1 = 1,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
new file mode 100644
index 0000000..4a36999
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current driver state of Hands On Detection (HOD).
+ */
+@VintfStability
+@Backing(type="int")
+enum HandsOnDetectionDriverState {
+ /**
+ * This state is used as an alternative for any HandsOnDetectionDriverState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#HANDS_ON_DETECTION_DRIVER_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if HandsOnDetectionDriverState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * The system detects that the driver has their hands on the steering wheel.
+ */
+ HANDS_ON = 1,
+ /**
+ * The system detects that the driver has their hands off the steering wheel.
+ */
+ HANDS_OFF = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
new file mode 100644
index 0000000..c1a58ce
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.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 Hands On Detection (HOD).
+ */
+@VintfStability
+@Backing(type="int")
+enum HandsOnDetectionWarning {
+ /**
+ * This state is used as an alternative for any HandsOnDetectionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#HANDS_ON_DETECTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if HandsOnDetectionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * HOD is enabled and the driver's current safety does not warrant sending a warning. This
+ * state is independent of whether the driver actually has their hands on or off the wheel.
+ */
+ NO_WARNING = 1,
+ /**
+ * HOD is enabled and the driver's hands have been off the wheel for too long a duration,
+ * and the vehicle is sending a warning to the driver as a consequence of this.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoRequestType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/InitialUserInfoResponseAction.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
new file mode 100644
index 0000000..d8b0e65
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.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 by Lane Centering Assist (LCA) to enumerate commands.
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneCenteringAssistCommand {
+ /**
+ * When VehicleProperty#LANE_CENTERING_ASSIST_STATE = LaneCenteringAssistState#ENABLED, this
+ * command sends a request to activate steering control that keeps the vehicle centered in its
+ * lane. While waiting for the LCA System to take control of the vehicle,
+ * VehicleProperty#LANE_CENTERING_ASSIST_STATE must be in the
+ * LaneCenteringAssistState#ACTIVATION_REQUESTED state. Once the vehicle takes control of
+ * steering, then VehicleProperty#LANE_CENTERING_ASSIST_STATE must be in the
+ * LaneCenteringAssistState#ACTIVATED state. Otherwise, an error can be communicated through an
+ * ErrorState value.
+ */
+ ACTIVATE = 1,
+ /**
+ * When VehicleProperty#LANE_CENTERING_ASSIST_STATE is set to
+ * LaneCenteringAssistState#ACTIVATION_REQUESTED or LaneCenteringAssistState#ACTIVATED, this
+ * command deactivates steering control and the driver should take full control of the vehicle.
+ * If this command succeeds, VehicleProperty#LANE_CENTERING_ASSIST_STATE must be updated to
+ * LaneCenteringAssistState#ENABLED.
+ */
+ DEACTIVATE = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
new file mode 100644
index 0000000..340a669d
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.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.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Lane Centering Assist (LCA).
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneCenteringAssistState {
+
+ /**
+ * This state is used as an alternative for any LaneCenteringAssistState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#LANE_CENTERING_ASSIST_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if LaneCenteringAssistState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * LCA is enabled but the ADAS system has not received an activation signal from the driver.
+ * Therefore, LCA is not steering the car and waits for the driver to send a
+ * LaneCenteringAssistCommand#ACTIVATE command.
+ */
+ ENABLED = 1,
+ /**
+ * LCA is enabled and the driver has sent an activation command to the LCA system, but the
+ * system has not started actively steering the vehicle. This may happen when LCA needs time to
+ * detect valid lane lines. The activation command can be sent through the
+ * VehicleProperty#LANE_CENTERING_ASSIST_COMMAND vehicle property or through a system external
+ * to Android. Once LCA is actively steering the vehicle, the state must be updated to
+ * ACTIVATED. If the feature is not able to activate, then the cause can be communicated through
+ * the ErrorState values and then return to the ENABLED state.
+ */
+ ACTIVATION_REQUESTED = 2,
+ /**
+ * LCA is enabled and actively steering the car to keep it centered in its lane.
+ */
+ ACTIVATED = 3,
+ /**
+ * Many LCA implementations allow the driver to override LCA. This means that the car has
+ * determined it should go a certain direction to keep the car centered in the lane, but a user
+ * decides to take over and do something else. This is often done for safety reasons and to
+ * ensure that the driver can always take control of the vehicle. This state should be set when
+ * the user is actively overriding the LCA system.
+ */
+ USER_OVERRIDE = 4,
+ /**
+ * When LCA is in the ACTIVATED state but it will potentially need to deactivate because of
+ * external conditions (e.g. roads curvature is too extreme, the driver does not have their
+ * hands on the steering wheel for a long period of time, or the driver is not paying
+ * attention), then the ADAS system will notify the driver of a potential need to deactivate and
+ * give control back to the driver.
+ */
+ FORCED_DEACTIVATION_WARNING = 5,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
new file mode 100644
index 0000000..c12c5765
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Lane Departure Warning (LDW).
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneDepartureWarningState {
+
+ /**
+ * This state is used as an alternative for any LaneDepartureWarningState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#LANE_DEPARTURE_WARNING_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if LaneDepartureWarningState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * LDW is enabled and monitoring, but the vehicle is centered in the lane.
+ */
+ NO_WARNING = 1,
+ /**
+ * LDW is enabled, detects the vehicle is approaching or crossing lane lines on the left side
+ * of the vehicle, and is currently warning the user.
+ */
+ WARNING_LEFT = 2,
+ /**
+ * LDW is enabled, detects the vehicle is approaching or crossing lane lines on the right side
+ * of the vehicle, and is currently warning the user.
+ */
+ WARNING_RIGHT = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
new file mode 100644
index 0000000..c1c15a0
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
@@ -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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Lane Keep Assist (LKA).
+ */
+@VintfStability
+@Backing(type="int")
+enum LaneKeepAssistState {
+
+ /**
+ * This state is used as an alternative for any LaneKeepAssistState value that is not defined in
+ * the platform. Ideally, implementations of VehicleProperty#LANE_KEEP_ASSIST_STATE should not
+ * use this state. The framework can use this field to remain backwards compatible if
+ * LaneKeepAssistState is extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * LKA is enabled and monitoring, but steering assist is not activated.
+ */
+ ENABLED = 1,
+ /**
+ * LKA is enabled and currently has steering assist applied for the vehicle. Steering assist is
+ * steering toward the left direction, which generally means the steering wheel turns counter
+ * clockwise. This is usually in response to the vehicle drifting to the right. Once steering
+ * assist is completed, LKA must return to the ENABLED state.
+ */
+ ACTIVATED_STEER_LEFT = 2,
+ /**
+ * LKA is enabled and currently has steering assist applied for the vehicle. Steering assist is
+ * steering toward the right direction, which generally means the steering wheel turns
+ * clockwise. This is usually in response to the vehicle drifting to the left. Once steering
+ * assist is completed, LKA must return to the ENABLED state.
+ */
+ ACTIVATED_STEER_RIGHT = 3,
+ /**
+ * Many LKA implementations allow the driver to override LKA. This means that the car has
+ * determined it should take some action, but a user decides to take over and do something else.
+ * This is often done for safety reasons and to ensure that the driver can always take control
+ * of the vehicle. This state should be set when the user is actively overriding the LKA system.
+ */
+ USER_OVERRIDE = 4,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LocationCharacterization.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LocationCharacterization.aidl
new file mode 100644
index 0000000..e06df40
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LocationCharacterization.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 by LOCATION_CHARACTERIZATION to enumerate the supported bit flags.
+ *
+ * These flags are used to indicate to what transformations are performed on the
+ * GNSS data before the location data is sent, so that location processing
+ * algorithms can take into account prior fusion.
+ *
+ * This enum can be extended in future releases to include additional bit flags.
+ */
+@VintfStability
+@Backing(type="int")
+enum LocationCharacterization {
+ /**
+ * Prior location samples have been used to refine the raw GNSS data (e.g. a
+ * Kalman Filter).
+ */
+ PRIOR_LOCATIONS = 0x1,
+ /**
+ * Gyroscope data has been used to refine the raw GNSS data.
+ */
+ GYROSCOPE_FUSION = 0x2,
+ /**
+ * Accelerometer data has been used to refine the raw GNSS data.
+ */
+ ACCELEROMETER_FUSION = 0x4,
+ /**
+ * Compass data has been used to refine the raw GNSS data.
+ */
+ COMPASS_FUSION = 0x8,
+ /**
+ * Wheel speed has been used to refine the raw GNSS data.
+ */
+ WHEEL_SPEED_FUSION = 0x10,
+ /**
+ * Steering angle has been used to refine the raw GNSS data.
+ */
+ STEERING_ANGLE_FUSION = 0x20,
+ /**
+ * Car speed has been used to refine the raw GNSS data.
+ */
+ CAR_SPEED_FUSION = 0x40,
+ /**
+ * Some effort is made to dead-reckon location. In particular, this means that
+ * relative changes in location have meaning when no GNSS satellite is
+ * available.
+ */
+ DEAD_RECKONED = 0x80,
+ /**
+ * Location is based on GNSS satellite signals without sufficient fusion of
+ * other sensors for complete dead reckoning. This flag should be set when
+ * relative changes to location cannot be relied on when no GNSS satellite is
+ * available.
+ */
+ RAW_GNSS_ONLY = 0x100,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2CompressionIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2FuelType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2FuelType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/PortLocationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/PortLocationType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/PortLocationType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ProcessTerminationReason.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RotaryInputType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/RotaryInputType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/RotaryInputType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserMessageType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/SwitchUserStatus.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl
new file mode 100644
index 0000000..ef65374
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of VehicleProperty#TRAILER_PRESENT.
+ */
+@VintfStability
+@Backing(type="int")
+enum TrailerState {
+ /**
+ * This state is used as an alternative for any TrailerState value that is not defined in the
+ * platform. Ideally, implementations of VehicleProperty#TRAILER_PRESENT should not use this
+ * state. The framework can use this field to remain backwards compatible if TrailerState is
+ * extended to include additional states.
+ */
+ UNKNOWN = 0,
+ /**
+ * A trailer is not attached to the vehicle.
+ */
+ NOT_PRESENT = 1,
+ /**
+ * A trailer is attached to the vehicle.
+ */
+ PRESENT = 2,
+ /**
+ * The state of the trailer is not available due to an error.
+ */
+ ERROR = 3,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationSetValue.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationAssociationValue.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UserInfo.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UsersInfo.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/UsersInfo.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
new file mode 100644
index 0000000..e325b38
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Vehicle AP power bootup reason.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleApPowerBootupReason {
+ /**
+ * Power on due to user's pressing of power key or rotating of ignition
+ * switch.
+ */
+ USER_POWER_ON = 0,
+ /**
+ * Automatic power on triggered by door unlock or any other kind of automatic
+ * user detection.
+ */
+ SYSTEM_USER_DETECTION = 1,
+ /**
+ * Automatic power on to execute a remote task. This is triggered by
+ * receiving a wakeup message from TCU wakeup client.
+ */
+ SYSTEM_REMOTE_ACCESS = 2,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateConfigFlag.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReport.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateReqIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleApPowerStateShutdownParam.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
new file mode 100644
index 0000000..6f7f783
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * List of different supported area types for vehicle properties.
+ * Used to construct property IDs in the VehicleProperty enum.
+ *
+ * Some properties may be associated with particular areas in the vehicle. For example,
+ * VehicleProperty#DOOR_LOCK property must be associated with a particular door, thus this property
+ * must be of the VehicleArea#DOOR area type.
+ *
+ * Other properties may not be associated with a particular area in the vehicle. These kinds of
+ * properties must be of the VehicleArea#GLOBAL area type.
+ *
+ * Note: This is not the same as areaId used in VehicleAreaConfig. E.g. for a global property, the
+ * property ID is of the VehicleArea#GLOBAL area type, however, the area ID must be 0.
+ */
+@VintfStability
+@Backing(type="int")
+// A better name would be VehicleAreaType
+enum VehicleArea {
+ /**
+ * A global property is a property that applies to the entire vehicle and is not associated with
+ * a specific area. For example, FUEL_LEVEL, HVAC_STEERING_WHEEL_HEAT are global properties.
+ */
+ GLOBAL = 0x01000000,
+ /** WINDOW maps to enum VehicleAreaWindow */
+ WINDOW = 0x03000000,
+ /** MIRROR maps to enum VehicleAreaMirror */
+ MIRROR = 0x04000000,
+ /** SEAT maps to enum VehicleAreaSeat */
+ SEAT = 0x05000000,
+ /** DOOR maps to enum VehicleAreaDoor */
+ DOOR = 0x06000000,
+ /** WHEEL maps to enum VehicleAreaWheel */
+ WHEEL = 0x07000000,
+
+ MASK = 0x0f000000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaDoor.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaMirror.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaSeat.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWheel.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAreaWindow.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleDisplay.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleDisplay.aidl
new file mode 100644
index 0000000..6642eee
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleDisplay.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+@VintfStability
+@Backing(type="int")
+enum VehicleDisplay {
+ /**
+ * The primary Android display (for example, center console)
+ */
+ MAIN = 0,
+ /**
+ * Instrument cluster display. This may exist only for driver
+ */
+ INSTRUMENT_CLUSTER = 1,
+
+ /**
+ * Head Up Display. This may exist only for driver
+ */
+ HUD = 2,
+ /**
+ * Dedicated display for showing IME for {@code MAIN}
+ */
+ INPUT = 3,
+ /**
+ * Auxiliary display which can provide additional screen for {@code MAIN} display
+ */
+ AUXILIARY = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleGear.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
new file mode 100644
index 0000000..f5b77de
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Bit flags for fan direction
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHvacFanDirection {
+ UNKNOWN = 0x0,
+ FACE = 0x1,
+ FLOOR = 0x2,
+ /**
+ * FACE_AND_FLOOR = FACE | FLOOR
+ */
+ FACE_AND_FLOOR = 0x3,
+ /**
+ * DEFROST may also be described as the windshield fan direction.
+ */
+ DEFROST = 0x4,
+ /**
+ * DEFROST_AND_FLOOR = DEFROST | FLOOR
+ */
+ DEFROST_AND_FLOOR = 0x06,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwKeyInputAction.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
new file mode 100644
index 0000000..5313a55
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionButtonStateFlag.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.MotionEvent#getButtonState()} for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionButtonStateFlag {
+ /**
+ * Button state primary
+ */
+ BUTTON_PRIMARY = 0x0001,
+ /**
+ * Button state secondary
+ */
+ BUTTON_SECONDARY = 0x0002,
+ /**
+ * Button state tertiary
+ */
+ BUTTON_TERTIARY = 0x0004,
+ /**
+ * Button state back
+ */
+ BUTTON_BACK = 0x0008,
+ /**
+ * Button state forward
+ */
+ BUTTON_FORWARD = 0x0010,
+ /**
+ * Button state stylus primary
+ */
+ BUTTON_STYLUS_PRIMARY = 0x0020,
+ /**
+ * Button state stylus secondary
+ */
+ BUTTON_STYLUS_SECONDARY = 0x0040,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
new file mode 100644
index 0000000..d80119a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputAction.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.MotionEvent#ACTION_*} fields for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionInputAction {
+ /**
+ * Motion down
+ */
+ ACTION_DOWN = 0,
+ /**
+ * Motion up
+ */
+ ACTION_UP = 1,
+ /**
+ * Motion move
+ */
+ ACTION_MOVE = 2,
+ /**
+ * Motion cancel
+ */
+ ACTION_CANCEL = 3,
+ /**
+ * Motion outside
+ */
+ ACTION_OUTSIDE = 4,
+ /**
+ * Motion pointer down
+ */
+ ACTION_POINTER_DOWN = 5,
+ /**
+ * Motion pointer up
+ */
+ ACTION_POINTER_UP = 6,
+ /**
+ * Motion hover move
+ */
+ ACTION_HOVER_MOVE = 7,
+ /**
+ * Motion scroll
+ */
+ ACTION_SCROLL = 8,
+ /**
+ * Motion hover enter
+ */
+ ACTION_HOVER_ENTER = 9,
+ /**
+ * Motion hover exit
+ */
+ ACTION_HOVER_EXIT = 10,
+ /**
+ * Motion button press
+ */
+ ACTION_BUTTON_PRESS = 11,
+ /**
+ * Motion button release
+ */
+ ACTION_BUTTON_RELEASE = 12,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
new file mode 100644
index 0000000..fb79983
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionInputSource.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.InputDevice#SOURCE_*} for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionInputSource {
+ /**
+ * Unknown source
+ */
+ SOURCE_UNKNOWN = 0,
+ /**
+ * Source keyboard
+ */
+ SOURCE_KEYBOARD = 1,
+ /**
+ * Source dpad
+ */
+ SOURCE_DPAD = 2,
+ /**
+ * Source game pad
+ */
+ SOURCE_GAMEPAD = 3,
+ /**
+ * Source touch screen
+ */
+ SOURCE_TOUCHSCREEN = 4,
+ /**
+ * Source mouse
+ */
+ SOURCE_MOUSE = 5,
+ /**
+ * Source stylus
+ */
+ SOURCE_STYLUS = 6,
+ /**
+ * Source bluetooth stylus
+ */
+ SOURCE_BLUETOOTH_STYLUS = 7,
+ /**
+ * Source trackball
+ */
+ SOURCE_TRACKBALL = 8,
+ /**
+ * Source mouse relative
+ */
+ SOURCE_MOUSE_RELATIVE = 9,
+ /**
+ * Source touchpad
+ */
+ SOURCE_TOUCHPAD = 10,
+ /**
+ * Source touch navigation
+ */
+ SOURCE_TOUCH_NAVIGATION = 11,
+ /**
+ * Source rotary encoder
+ */
+ SOURCE_ROTARY_ENCODER = 12,
+ /**
+ * Source joystick
+ */
+ SOURCE_JOYSTICK = 13,
+ /**
+ * Source hdmi
+ */
+ SOURCE_HDMI = 14,
+ /**
+ * Source sensor
+ */
+ SOURCE_SENSOR = 15,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionToolType.aidl
new file mode 100644
index 0000000..08c9aed
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHwMotionToolType.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * See {@code android.view.MotionEvent#TOOL_TYPE_*} for more details.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleHwMotionToolType {
+ /**
+ * Unknown type such as for a trackballl or other non-pointing device
+ */
+ TOOL_TYPE_UNKNOWN = 0,
+ /**
+ * Finger type
+ */
+ TOOL_TYPE_FINGER = 1,
+ /**
+ * Stylus type
+ */
+ TOOL_TYPE_STYLUS = 2,
+ /**
+ * Mouse type
+ */
+ TOOL_TYPE_MOUSE = 3,
+ /**
+ * Eraser type
+ */
+ TOOL_TYPE_ERASER = 4,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
new file mode 100644
index 0000000..3c722ba
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current level of VehicleProperty#ENGINE_OIL_LEVEL.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleOilLevel {
+ /**
+ * The oil level of the engine is critically low, so the vehicle may be unsafe to drive.
+ */
+ CRITICALLY_LOW = 0,
+ /**
+ * The oil level of the engine is low and needs to be replaced.
+ */
+ LOW = 1,
+ /**
+ * The oil level of the engine is normal for the vehicle.
+ */
+ NORMAL = 2,
+ /**
+ * The oil level of the engine is high, so the vehicle may be unsafe to drive.
+ */
+ HIGH = 3,
+ /**
+ * This value represents an error when retrieving the oil level of the engine.
+ */
+ ERROR = 4,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
new file mode 100644
index 0000000..8267568
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -0,0 +1,4525 @@
+/*
+ * 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.VehicleArea;
+import android.hardware.automotive.vehicle.VehiclePropertyGroup;
+import android.hardware.automotive.vehicle.VehiclePropertyType;
+/**
+ * Declares all vehicle properties. VehicleProperty has a bitwise structure.
+ * Each property must have:
+ * - a unique id from range 0x0100 - 0xffff
+ * - associated data type using VehiclePropertyType
+ * - property group (VehiclePropertyGroup)
+ * - vehicle area (VehicleArea)
+ *
+ * Vendors are allowed to extend this enum with their own properties. In this
+ * case they must use VehiclePropertyGroup:VENDOR flag when the property is
+ * declared.
+ *
+ * When a property's status field is not set to AVAILABLE:
+ * - IVehicle#set may return StatusCode::NOT_AVAILABLE.
+ * - IVehicle#get is not guaranteed to work.
+ *
+ * Properties set to values out of range must be ignored and no action taken
+ * in response to such ill formed requests.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleProperty {
+ /**
+ * Undefined property.
+ *
+ * This property must never be used/supported.
+ */
+ INVALID = 0x00000000,
+ /**
+ * VIN of vehicle
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Manufacturer of vehicle
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Model of vehicle
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Model year of vehicle.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:YEAR
+ */
+ INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Fuel capacity of the vehicle in milliliters
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MILLILITER
+ */
+ INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * List of fuels the vehicle may use.
+ *
+ * FuelType::FUEL_TYPE_ELECTRIC must only be included if the vehicle is plug in rechargeable.
+ * For example:
+ * An FHEV (Fully Hybrid Electric Vehicle) must not include FuelType::FUEL_TYPE_ELECTRIC in
+ * INFO_FUEL_TYPE's INT32_VEC value. So INFO_FUEL_TYPE can be populated as such:
+ * int32Values = { FuelType::FUEL_TYPE_UNLEADED }
+ * On the other hand, a PHEV (Partially Hybrid Electric Vehicle) is plug in rechargeable, and
+ * hence should include FuelType::FUEL_TYPE_ELECTRIC in INFO_FUEL_TYPE's INT32_VEC value. So
+ * INFO_FUEL_TYPE can be populated as such:
+ * int32Values = { FuelType::FUEL_TYPE_UNLEADED, FuelType::FUEL_TYPE_ELECTRIC }
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @data_enum FuelType
+ */
+ INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Nominal battery capacity for EV or hybrid vehicle
+ *
+ * Returns the nominal battery capacity, if EV or hybrid. This is the battery capacity when the
+ * vehicle is new. This value might be different from EV_CURRENT_BATTERY_CAPACITY because
+ * EV_CURRENT_BATTERY_CAPACITY returns the real-time battery capacity taking into account
+ * factors such as battery aging and temperature dependency.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:WH
+ */
+ INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * List of connectors this EV may use
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @data_enum EvConnectorType
+ * @access VehiclePropertyAccess.READ
+ */
+ INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Fuel door location
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @data_enum PortLocationType
+ * @access VehiclePropertyAccess.READ
+ */
+ INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * EV port location
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @data_enum PortLocationType
+ */
+ INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Driver's seat location
+ * VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @data_enum VehicleAreaSeat
+ * @access VehiclePropertyAccess.READ
+ */
+ INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Exterior dimensions of vehicle.
+ *
+ * int32Values[0] = height
+ * int32Values[1] = length
+ * int32Values[2] = width
+ * int32Values[3] = width including mirrors
+ * int32Values[4] = wheel base
+ * int32Values[5] = track width front
+ * int32Values[6] = track width rear
+ * int32Values[7] = curb to curb turning radius
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MILLIMETER
+ */
+ INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Multiple EV port locations
+ *
+ * Implement this property if the vehicle has multiple EV ports.
+ * Port locations are defined in PortLocationType.
+ * For example, a car has one port in front left and one port in rear left:
+ * int32Values[0] = PortLocationType::FRONT_LEFT
+ * int32Values[0] = PortLocationType::REAR_LEFT
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @data_enum PortLocationType
+ */
+ INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Current odometer value of the vehicle
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:KILOMETER
+ */
+ PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Speed of the vehicle
+ *
+ * The value must be positive when the vehicle is moving forward and negative when
+ * the vehicle is moving backward. This value is independent of gear value
+ * (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL,
+ * PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving
+ * backward, and zero when not moving.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:METER_PER_SEC
+ */
+ PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Speed of the vehicle for displays
+ *
+ * Some cars display a slightly slower speed than the actual speed. This is
+ * usually displayed on the speedometer.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:METER_PER_SEC
+ */
+ PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Front bicycle model steering angle for vehicle
+ *
+ * Angle is in degrees. Left is negative.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:DEGREES
+ */
+ PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Rear bicycle model steering angle for vehicle
+ *
+ * Angle is in degrees. Left is negative.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:DEGREES
+ */
+ PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Temperature of engine coolant
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:CELSIUS
+ */
+ ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Engine oil level
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleOilLevel
+ */
+ ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Temperature of engine oil
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:CELSIUS
+ */
+ ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Engine rpm
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:RPM
+ */
+ ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Reports wheel ticks
+ *
+ * The first element in the vector is a reset count. A reset indicates
+ * previous tick counts are not comparable with this and future ones. Some
+ * sort of discontinuity in tick counting has occurred.
+ *
+ * The next four elements represent ticks for individual wheels in the
+ * following order: front left, front right, rear right, rear left. All
+ * tick counts are cumulative. Tick counts increment when the vehicle
+ * moves forward, and decrement when vehicles moves in reverse. The ticks
+ * should be reset to 0 when the vehicle is started by the user.
+ *
+ * int64Values[0] = reset count
+ * int64Values[1] = front left ticks
+ * int64Values[2] = front right ticks
+ * int64Values[3] = rear right ticks
+ * int64Values[4] = rear left ticks
+ *
+ * configArray is used to indicate the micrometers-per-wheel-tick value and
+ * which wheels are supported. configArray is set as follows:
+ *
+ * configArray[0], bits [0:3] = supported wheels. Uses enum Wheel. For example, if all wheels
+ * are supported, then configArray[0] = VehicleAreaWheel::LEFT_FRONT
+ * | VehicleAreaWheel::RIGHT_FRONT | VehicleAreaWheel::LEFT_REAR
+ * | VehicleAreaWheel::RIGHT_REAR
+ * configArray[1] = micrometers per front left wheel tick
+ * configArray[2] = micrometers per front right wheel tick
+ * configArray[3] = micrometers per rear right wheel tick
+ * configArray[4] = micrometers per rear left wheel tick
+ *
+ * NOTE: If a wheel is not supported, its value shall always be set to 0.
+ *
+ * VehiclePropValue.timestamp must be correctly filled in.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ */
+ WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
+ + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
+ /**
+ * Fuel remaining in the vehicle, in milliliters
+ *
+ * Value may not exceed INFO_FUEL_CAPACITY
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MILLILITER
+ */
+ FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Fuel door open
+ *
+ * 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
+ */
+ FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Battery level for EV or hybrid vehicle
+ *
+ * Returns the current battery level, if EV or hybrid. This value will not exceed
+ * EV_CURRENT_BATTERY_CAPACITY. To calculate the battery percentage, use:
+ * (EV_BATTERY_LEVEL/EV_CURRENT_BATTERY_CAPACITY)*100.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:WH
+ */
+ EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Current battery capacity for EV or hybrid vehicle
+ *
+ * Returns the actual value of battery capacity, if EV or hybrid. This property captures the
+ * real-time battery capacity taking into account factors such as battery aging and temperature
+ * dependency. Therefore, this value might be different from INFO_EV_BATTERY_CAPACITY because
+ * INFO_EV_BATTERY_CAPACITY returns the nominal battery capacity from when the vehicle was new.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:WH
+ */
+ EV_CURRENT_BATTERY_CAPACITY =
+ 0x030D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+ /**
+ * EV charge port open
+ *
+ * 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
+ */
+ EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * EV charge port connected
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * EV instantaneous charge rate in milliwatts
+ *
+ * Positive value indicates battery is being charged.
+ * Negative value indicates battery being discharged.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MW
+ */
+ EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Range remaining
+ *
+ * Meters remaining of fuel and charge. Range remaining shall account for
+ * all energy sources in a vehicle. For example, a hybrid car's range will
+ * be the sum of the ranges based on fuel and battery.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE because a navigation app could
+ * update the range if it has a more accurate estimate based on the upcoming route. However,
+ * this property can be implemented as VehiclePropertyAccess.READ only at the OEM's discretion.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @unit VehicleUnit:METER
+ */
+ RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Tire pressure
+ *
+ * Each tires is identified by its areaConfig.areaId config and their
+ * minFloatValue/maxFloatValue are used to store OEM recommended pressure
+ * range.
+ * The Min value in the areaConfig data represents the lower bound of
+ * the recommended tire pressure.
+ * The Max value in the areaConfig data represents the upper bound of
+ * the recommended tire pressure.
+ * For example:
+ * The following areaConfig indicates the recommended tire pressure
+ * of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
+ * .areaConfigs = {
+ * VehicleAreaConfig {
+ * .areaId = VehicleAreaWheel::LEFT_FRONT,
+ * .minFloatValue = 200.0,
+ * .maxFloatValue = 240.0,
+ * }
+ * },
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:KILOPASCAL
+ */
+ TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
+ /**
+ * Critically low tire pressure
+ *
+ * This property indicates the critically low pressure threshold for each tire.
+ * It indicates when it is time for tires to be replaced or fixed. The value
+ * must be less than or equal to minFloatValue in TIRE_PRESSURE.
+ * Minimum and maximum property values (that is, minFloatValue, maxFloatValue)
+ * are not applicable to this property.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:KILOPASCAL
+ */
+ CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
+ /**
+ * Represents feature for engine idle automatic stop.
+ *
+ * If true, the vehicle may automatically shut off the engine when it is not needed and then
+ * automatically restart it when needed.
+ *
+ * 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
+ */
+ ENGINE_IDLE_AUTO_STOP_ENABLED =
+ 0x0320 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Currently selected gear
+ *
+ * This is the gear selected by the user.
+ *
+ * Values in the config data must represent the list of supported gears for this vehicle. For
+ * example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE,
+ * GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission the list must be
+ * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
+ *
+ * In the case of an automatic transmission vehicle that allows the driver to select specific
+ * gears on demand (i.e. "manual mode"), GEAR_SELECTION's value must be set to the specific gear
+ * selected by the driver instead of simply GEAR_DRIVE.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleGear
+ */
+ GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Current gear. In non-manual case, selected gear may not
+ * match the current gear. For example, if the selected gear is GEAR_DRIVE,
+ * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
+ * the actual gear the transmission is currently running in.
+ *
+ * Values in the config data must represent the list of supported gears
+ * for this vehicle. For example, config data for an automatic transmission
+ * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
+ * and for manual transmission the list must be
+ * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
+ * same as that of the supported gears reported in GEAR_SELECTION.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleGear
+ */
+ CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Parking brake state.
+ *
+ * This property is true indicates that the car's parking brake is currently engaged. False
+ * implies that the car's parking brake is currently disengaged.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Auto-apply parking brake.
+ *
+ * This property is true indicates that the car's automatic parking brake feature is currently
+ * enabled. False indicates that the car's automatic parking brake feature is currently
+ * disabled.
+ *
+ * This property is often confused with PARKING_BRAKE_ON. The difference is that
+ * PARKING_BRAKE_ON describes whether the actual parking brake is currently on/off, whereas
+ * PARKING_BRAKE_AUTO_APPLY describes whether the feature of automatic parking brake is enabled/
+ * disabled, and does not describe the current state of the actual parking brake.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Regenerative braking level of a electronic vehicle
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+ * minInt32Value and maxInt32Value must be supported. The minInt32Value must be 0.
+ *
+ * The maxInt32Value in default area's VehicleAreaConfig indicates the maximum amount of energy
+ * regenerated from braking. The minInt32Value in default area's VehicleAreaConfig indicates no
+ * regenerative braking.
+ *
+ * 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
+ */
+ EV_BRAKE_REGENERATION_LEVEL =
+ 0x040C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Warning for fuel low level.
+ *
+ * This property corresponds to the low fuel warning on the dashboard.
+ * Once FUEL_LEVEL_LOW is set, it should not be cleared until more fuel is
+ * added to the vehicle. This property may take into account all fuel
+ * sources for a vehicle - for example:
+ *
+ * For a gas powered vehicle, this property is based soley on gas level.
+ * For a battery powered vehicle, this property is based solely on battery level.
+ * For a hybrid vehicle, this property may be based on the combination of gas and battery
+ * levels, at the OEM's discretion.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Night mode
+ *
+ * True indicates that the night mode sensor has detected that the car cabin environment has
+ * low light. The platform could use this, for example, to enable appropriate UI for
+ * better viewing in dark or low light environments.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * State of the vehicles turn signals
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleTurnSignal
+ */
+ TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Represents ignition state
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleIgnitionState
+ */
+ IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * ABS is active
+ *
+ * Set to true when ABS is active. Reset to false when ABS is off. This
+ * property may be intermittently set (pulsing) based on the real-time
+ * state of the ABS system.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Traction Control is active
+ *
+ * Set to true when traction control (TC) is active. Reset to false when
+ * TC is off. This property may be intermittently set (pulsing) based on
+ * the real-time state of the TC system.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Represents property for the current stopping mode of the vehicle.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+ * all enum values of EvStoppingMode are supported.
+ *
+ * The EvStoppingMode enum may be extended to include more states in the future.
+ *
+ * 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
+ * @data_enum EvStoppingMode
+ */
+ EV_STOPPING_MODE =
+ 0x040D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * HVAC Properties
+ *
+ * Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
+ * to AreaIDs:
+ * - Every “area” for a specific VehicleArea type that is affected by the
+ * property, must be included in an area ID for that property.
+ *
+ * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+ * back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+ * temperature control units -- driver side and passenger side.
+ * - A valid mapping set of AreaIDs for HVAC_TEMPERATURE_SET would be a
+ * two element array:
+ * - ROW_1_LEFT | ROW_2_LEFT
+ * - ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT
+ * - An alternative mapping for the same hardware configuration would be:
+ * - ROW_1_LEFT | ROW_2_CENTER | ROW_2_LEFT
+ * - ROW_1_RIGHT | ROW_2_RIGHT
+ * The temperature controllers are assigned to the seats which they
+ * "most influence", but every seat must be included exactly once. The
+ * assignment of the center rear seat to the left or right AreaID may seem
+ * arbitrary, but the inclusion of every seat in exactly one AreaID ensures
+ * that the seats in the car are all expressed and that a "reasonable" way
+ * to affect each seat is available.
+ *
+ * Example 2: A car has three seat rows with two seats in the front row (ROW_1_LEFT,
+ * ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER,
+ * ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). There
+ * are three temperature control units -- driver side, passenger side, and rear.
+ * - A reasonable way to map HVAC_TEMPERATURE_SET to AreaIDs is a three
+ * element array:
+ * - ROW_1_LEFT
+ * - ROW_1_RIGHT
+ * - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+ *
+ * Example 3: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+ * back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). Suppose the car
+ * supports HVAC_AUTO_ON for just the two front seats.
+ * - A valid mapping set of AreaIDs for HVAC_AUTO_ON would be:
+ * - ROW_1_LEFT | ROW_1_RIGHT
+ * - If HVAC_AUTO_ON had two separate control units for the driver side
+ * and passenger side, an alternative mapping would be:
+ * - ROW_1_LEFT
+ * - ROW_1_RIGHT
+ *
+ *
+ * Fan speed setting
+ *
+ * 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
+ */
+ HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Fan direction setting
+ *
+ * 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
+ * @data_enum VehicleHvacFanDirection
+ */
+ HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * HVAC current temperature.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:CELSIUS
+ */
+ HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
+ /**
+ * HVAC, target temperature set.
+ *
+ * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
+ * Android might use it in the HVAC app UI.
+ * The configArray is set as follows:
+ * configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
+ * configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
+ * configArray[2] = [the increment in Celsius] * 10.
+ * configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
+ * configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
+ * configArray[5] = [the increment in Fahrenheit] * 10.
+ * For example, if the vehicle supports temperature values as:
+ * [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
+ * [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
+ * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
+ *
+ * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
+ * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
+ * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
+ *
+ * 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
+ * @unit VehicleUnit:CELSIUS
+ */
+ HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
+ /**
+ * Fan-based defrost for designated window.
+ *
+ * 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
+ */
+ HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+ /**
+ * On/off AC for designated areaId
+ *
+ * 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
+ * @config_flags Supported areaIds
+ */
+ HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * On/off max AC
+ *
+ * When MAX AC is on, the ECU may adjust the vent position, fan speed,
+ * temperature, etc as necessary to cool the vehicle as quickly as possible.
+ * Any parameters modified as a side effect of turning on/off the MAX AC
+ * parameter shall generate onPropertyEvent() callbacks to the VHAL.
+ *
+ * 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
+ */
+ HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * On/off max defrost
+ *
+ * When MAX DEFROST is on, the ECU may adjust the vent position, fan speed,
+ * temperature, etc as necessary to defrost the windows as quickly as
+ * possible. Any parameters modified as a side effect of turning on/off
+ * the MAX DEFROST parameter shall generate onPropertyEvent() callbacks to
+ * the VHAL.
+ * The AreaIDs for HVAC_MAX_DEFROST_ON indicate MAX DEFROST can be controlled
+ * in the area.
+ * For example:
+ * areaConfig.areaId = {ROW_1_LEFT | ROW_1_RIGHT} indicates HVAC_MAX_DEFROST_ON
+ * only can be controlled for the front rows.
+ *
+ * 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
+ */
+ HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * Recirculation on/off
+ *
+ * Controls the supply of exterior air to the cabin. Recirc “on” means the
+ * majority of the airflow into the cabin is originating in the cabin.
+ * Recirc “off” means the majority of the airflow into the cabin is coming
+ * from outside the car.
+ *
+ * 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
+ */
+ HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * Enable temperature coupling between areas.
+ *
+ * The AreaIDs for HVAC_DUAL_ON property shall contain a combination of
+ * HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If
+ * HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if
+ * HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON
+ * property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also
+ * be coupled together separately then HVAC_DUAL_ON must be mapped to
+ * [a_i | a_j, a_k | a_l].
+ *
+ * Example: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three
+ * back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two
+ * temperature control units -- driver side and passenger side -- which can
+ * be optionally synchronized. This may be expressed in the AreaIDs this way:
+ * - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+ * - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]
+ *
+ * When the property is enabled, the ECU must synchronize the temperature
+ * for the affected areas. Any parameters modified as a side effect
+ * of turning on/off the DUAL_ON parameter shall generate
+ * onPropertyEvent() callbacks to the VHAL. In addition, if setting
+ * a temperature (i.e. driver's temperature) changes another temperature
+ * (i.e. front passenger's temperature), then the appropriate
+ * onPropertyEvent() callbacks must be generated. If a user changes a
+ * temperature that breaks the coupling (e.g. setting the passenger
+ * temperature independently) then the VHAL must send the appropriate
+ * onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false,
+ * HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).
+ *
+ * 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
+ */
+ HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * On/off automatic climate control.
+ *
+ * If true, automatic climate control is on. If false, automatic climate control is off.
+ *
+ * If the vehicle does not support directly turning off automatic climate control, then OEMs
+ * should add logic in their VHAL implementation so that setting HVAC_AUTO_ON to false would
+ * change the necessary HVAC settings to indirectly turn off HVAC_AUTO_ON. Ideally, this should
+ * not be disruptive to the user, so OEMs should change back to the previous state any settings
+ * that were modified once automatic climate control is off. That way the only outcome should be
+ * that HVAC_AUTO_ON is off. If restoring the HVAC settings to its previous settings is not
+ * possible, then the OEM should choose the least disruptive change and implement that.
+ *
+ * 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
+ */
+ HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * Seat heating/cooling
+ *
+ * Negative values indicate cooling.
+ * 0 indicates off.
+ * Positive values indicate heating.
+ *
+ * Some vehicles may have multiple levels of heating and cooling. The
+ * min/max range defines the allowable range and number of steps in each
+ * direction.
+ *
+ * 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
+ */
+ HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Side Mirror Heat
+ *
+ * Increasing values denote higher heating levels for side mirrors.
+ * The Max value in the config data represents the highest heating level.
+ * The Min value in the config data MUST be zero and indicates no heating.
+ *
+ * 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
+ */
+ HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+ /**
+ * Steering Wheel Heating/Cooling
+ *
+ * Sets the amount of heating/cooling for the steering wheel
+ * config data Min and Max MUST be set appropriately.
+ * Positive value indicates heating.
+ * Negative value indicates cooling.
+ * 0 indicates temperature control is off.
+ *
+ * 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
+ */
+ HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Temperature units for display
+ *
+ * Indicates whether the vehicle is displaying temperature to the user as
+ * Celsius or Fahrenheit.
+ * VehiclePropConfig.configArray is used to indicate the supported temperature display units.
+ * For example: configArray[0] = CELSIUS
+ * configArray[1] = FAHRENHEIT
+ *
+ * This parameter MAY be used for displaying any HVAC temperature in the system.
+ * Values must be one of VehicleUnit::CELSIUS or VehicleUnit::FAHRENHEIT
+ * Note that internally, all temperatures are represented in floating point Celsius.
+ *
+ * If updating HVAC_TEMPERATURE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
+ * properties, then their values must be updated and communicated to the AAOS framework as well.
+ *
+ * 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
+ * @data_enum VehicleUnit
+ */
+ HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Actual fan speed
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Represents global power state for HVAC. Setting this property to false
+ * MAY mark some properties that control individual HVAC features/subsystems
+ * to UNAVAILABLE state. Setting this property to true MAY mark some
+ * properties that control individual HVAC features/subsystems to AVAILABLE
+ * state (unless any/all of them are UNAVAILABLE on their own individual
+ * merits).
+ *
+ * [Definition] HvacPower_DependentProperties: Properties that need HVAC to be
+ * powered on in order to enable their functionality. For example, in some cars,
+ * in order to turn on the AC, HVAC must be powered on first.
+ *
+ * HvacPower_DependentProperties list must be set in the
+ * VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain
+ * properties that are associated with VehicleArea:SEAT. Properties that are not
+ * associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never
+ * depend on HVAC_POWER_ON property and must never be part of
+ * HvacPower_DependentProperties list.
+ *
+ * AreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that
+ * HvacPower_DependentProperties are mapped to.
+ *
+ * Example 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back
+ * seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC,
+ * Temperature etc.) throughout the car are dependent on a single HVAC power
+ * controller then HVAC_POWER_ON must be mapped to
+ * [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].
+ *
+ * Example 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and
+ * three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third
+ * rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature
+ * controllers in the front row which can operate entirely independently of
+ * temperature controllers in the back of the vehicle, then HVAC_POWER_ON
+ * must be mapped to a two element array:
+ * - ROW_1_LEFT | ROW_1_RIGHT
+ * - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT
+ *
+ * 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
+ */
+ HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * Fan Positions Available
+ *
+ * This is a bit mask of fan positions available for the zone. Each
+ * available fan direction is denoted by a separate entry in the vector. A
+ * fan direction may have multiple bits from vehicle_hvac_fan_direction set.
+ * For instance, a typical car may have the following fan positions:
+ * - FAN_DIRECTION_FACE (0x1)
+ * - FAN_DIRECTION_FLOOR (0x2)
+ * - FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR (0x3)
+ * - FAN_DIRECTION_DEFROST (0x4)
+ * - FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST (0x6)
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleHvacFanDirection
+ */
+ HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
+ /**
+ * Automatic recirculation on/off
+ *
+ * When automatic recirculation is ON, the HVAC system may automatically
+ * switch to recirculation mode if the vehicle detects poor incoming air
+ * quality.
+ *
+ * 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
+ */
+ HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * Seat ventilation
+ *
+ * 0 indicates off.
+ * Positive values indicates ventilation level.
+ *
+ * Used by HVAC apps and Assistant to enable, change, or read state of seat
+ * ventilation. This is different than seating cooling. It can be on at the
+ * same time as cooling, or not.
+ *
+ * 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
+ */
+ HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Electric defrosters' status
+ *
+ * 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
+ */
+ HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+ /**
+ * Suggested values for setting HVAC temperature.
+ *
+ * Implement the property to help applications understand the closest supported temperature
+ * value in Celsius or Fahrenheit.
+ *
+ * floatValues[0] = the requested value that an application wants to set a temperature to.
+ * floatValues[1] = the unit for floatValues[0]. It should be one of
+ * {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}.
+ * floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included
+ * in the request.
+ * floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included
+ * in the request.
+ *
+ * An application calls set(VehiclePropValue propValue) with the requested value and unit for
+ * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
+ * onPropertyEvent() callbacks.
+ *
+ * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
+ * Fahrenheit.
+ * First, an application will set this property with the value
+ * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0].
+ * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL
+ * must generate a callback with property value
+ * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the
+ * callback, it will inform the user and set HVAC temperature to the suggested value.
+ *
+ * Another example, an application receives 21 Celsius as the current temperature value by
+ * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on
+ * the car's UI in Fahrenheit.
+ * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If
+ * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a
+ * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0].
+ * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
+ + 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
+ /**
+ * Distance units for display
+ *
+ * Indicates which units the car is using to display distances to the user. Eg. Mile, Meter
+ * Kilometer.
+ *
+ * Distance units are defined in VehicleUnit.
+ * VehiclePropConfig.configArray is used to indicate the supported distance display units.
+ * For example: configArray[0] = METER
+ * configArray[1] = KILOMETER
+ * configArray[2] = MILE
+ *
+ * If updating DISTANCE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties,
+ * then their values must be updated and communicated to the AAOS framework as well.
+ *
+ * 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
+ * @data_enum VehicleUnit
+ */
+ DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Fuel volume units for display
+ *
+ * Indicates which units the car is using to display fuel volume to the user. Eg. Liter or
+ * Gallon.
+ *
+ * VehiclePropConfig.configArray is used to indicate the supported fuel volume display units.
+ * Volume units are defined in VehicleUnit.
+ * For example: configArray[0] = LITER
+ * configArray[1] = GALLON
+ *
+ * If updating FUEL_VOLUME_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties,
+ * then their values must be updated and communicated to the AAOS framework as well.
+ *
+ * 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
+ * @data_enum VehicleUnit
+ */
+ FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Tire pressure units for display
+ *
+ * Indicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or
+ * Kilopascal.
+ *
+ * VehiclePropConfig.configArray is used to indicate the supported pressure display units.
+ * Pressure units are defined in VehicleUnit.
+ * For example: configArray[0] = KILOPASCAL
+ * configArray[1] = PSI
+ * configArray[2] = BAR
+ *
+ * If updating TIRE_PRESSURE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
+ * properties, then their values must be updated and communicated to the AAOS framework as well.
+ *
+ * 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
+ * @data_enum VehicleUnit
+ */
+ TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * EV battery units for display
+ *
+ * Indicates which units the car is using to display EV battery information to the user. Eg.
+ * watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).
+ *
+ * VehiclePropConfig.configArray is used to indicate the supported electrical energy units.
+ * Electrical energy units are defined in VehicleUnit.
+ * For example: configArray[0] = WATT_HOUR
+ * configArray[1] = AMPERE_HOURS
+ * configArray[2] = KILOWATT_HOUR
+ *
+ * If updating EV_BATTERY_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties,
+ * then their values must be updated and communicated to the AAOS framework as well.
+ *
+ * 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
+ * @data_enum VehicleUnit
+ */
+ EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Fuel consumption units for display
+ *
+ * Indicates type of units the car is using to display fuel consumption information to user
+ * True indicates units are distance over volume such as MPG.
+ * False indicates units are volume over distance such as L/100KM.
+ *
+ * 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
+ */
+ FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Speed units for display
+ *
+ * Indicates type of units the car is using to display speed to user. Eg. m/s, km/h, or mph.
+ *
+ * VehiclePropConfig.configArray is used to indicate the supported speed display units.
+ * Pressure units are defined in VehicleUnit.
+ * For example: configArray[0] = METER_PER_SEC
+ * configArray[1] = MILES_PER_HOUR
+ * configArray[2] = KILOMETERS_PER_HOUR
+ *
+ * If updating VEHICLE_SPEED_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
+ * properties, then their values must be updated and communicated to the AAOS framework as well.
+ *
+ * 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
+ */
+ VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Current date and time suggestion for the Car, encoded as Epoch time
+ * (in milliseconds). This value denotes the number of milliseconds seconds
+ * that have elapsed since 1/1/1970 UTC.
+ *
+ * This property signals a change in CarTime to Android. If the property is supported, VHAL
+ * must report the most accurate current CarTime when this property is read, and publish a
+ * change to this property when the CarTime value has changed. An on-change event for this
+ * property must be published when CarTime changes for any reason other than the natural elapse
+ * of time (time delta smaller than 500ms should not trigger an on change event). Android will
+ * read and subscribe to this property to fetch time from VHAL. This can be useful to
+ * synchronize Android's time with other vehicle systems (dash clock etc).
+ * int64Values[0] = provided Epoch time (in milliseconds)
+ *
+ * Whenever a new Value for the property is received, AAOS will create
+ * and send an "ExternalTimeSuggestion" to the "TimeDetectorService".
+ * If other sources do not have a higher priority, Android will use this
+ * to set the system time. For information on how to adjust time source
+ * priorities and how time suggestions are handled (including how Android
+ * handles gitter, drift, and minimum resolution) see Time Detector Service
+ * documentation.
+ *
+ * Note that the property may take >0 ms to get propagated through the stack
+ * and, having a timestamped property helps reduce any time drift. So,
+ * for all reads to the property, the timestamp can be used to negate this
+ * drift:
+ * drift = elapsedTime - PropValue.timestamp
+ * effectiveTime = PropValue.value.int64Values[0] + drift
+ *
+ * It is strongly recommended that this property must not be used to retrieve
+ * time from ECUs using protocols (GNSS, NTP, Telephony etc). Since these
+ * protocols are already supported by Android, it is recommended to use
+ * Android’s own systems for them instead of wiring those through the VHAL
+ * using this property.
+ *
+ * WARNING: The value available through this property should not be dependent
+ * on value written by Android to ANDROID_EPOCH_TIME property in any way.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MILLI_SECS
+ */
+ EXTERNAL_CAR_TIME = 0x0608 + 0x10000000 // VehiclePropertyGroup:SYSTEM
+ + 0x01000000 // VehicleArea:GLOBAL
+ + 0x00500000, // VehiclePropertyType:INT64
+ /**
+ * Current date and time, encoded as Epoch time (in milliseconds).
+ * This value denotes the number of milliseconds seconds that have
+ * elapsed since 1/1/1970 UTC.
+ *
+ * CarServices will write to this value to give VHAL the Android system's
+ * time, if the VHAL supports this property. This can be useful to
+ * synchronize other vehicle systems (dash clock etc) with Android's time.
+ *
+ * AAOS writes to this property once during boot, and
+ * will thereafter write only when some time-source changes are propagated.
+ * AAOS will fill in VehiclePropValue.timestamp correctly.
+ * Note that AAOS will not send updates for natural elapse of time.
+ * int64Values[0] = provided Unix time (in milliseconds)
+ *
+ * Note that the property may take >0 ms to get propagated through the stack
+ * and, having a timestamped property helps reduce any time drift. So,
+ * for all writes to the property, the timestamp can be used to negate this
+ * drift:
+ * drift = elapsedTime - PropValue.timestamp
+ * effectiveTime = PropValue.value.int64Values[0] + drift
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ * @unit VehicleUnit:MILLI_SECS
+ */
+ ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
+ + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+ /**
+ * External encryption binding seed.
+ *
+ * This value is mixed with the local key storage encryption key.
+ * This property holds 16 bytes, and is expected to be persisted on an ECU separate from
+ * the IVI. The property is initially set by AAOS, who generates it using a CSRNG.
+ * AAOS will then read the property on subsequent boots. The binding seed is expected to be
+ * reliably persisted. Any loss of the seed results in a factory reset of the IVI.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
+ + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
+ /**
+ * Outside temperature
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:CELSIUS
+ */
+ ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+ /**
+ * Property to control power state of application processor
+ *
+ * It is assumed that AP's power state is controlled by a separate power
+ * controller.
+ *
+ * For configuration information, VehiclePropConfig.configArray must have bit flag combining
+ * values in VehicleApPowerStateConfigFlag.
+ *
+ * int32Values[0] : VehicleApPowerStateReq enum value
+ * int32Values[1] : additional parameter relevant for each state,
+ * 0 if not used.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Property to report power state of application processor
+ *
+ * It is assumed that AP's power state is controller by separate power
+ * controller.
+ *
+ * int32Values[0] : VehicleApPowerStateReport enum value
+ * int32Values[1] : Time in ms to wake up, if necessary. Otherwise 0.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Property to report bootup reason for the current power on. This is a
+ * static property that will not change for the whole duration until power
+ * off. For example, even if user presses power on button after automatic
+ * power on with door unlock, bootup reason must stay with
+ * VehicleApPowerBootupReason#USER_UNLOCK.
+ *
+ * int32Values[0] must be VehicleApPowerBootupReason.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Property to represent brightness of the display.
+ *
+ * Some cars have single control for the brightness of all displays and this
+ * property is to share change in that control. In cars which have displays
+ * whose brightness is controlled separately, they must use
+ * PER_DISPLAY_BRIGHTNESS.
+ *
+ * Only one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be
+ * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
+ * AAOS.
+ *
+ * If this is writable, android side can set this value when user changes
+ * display brightness from Settings. If this is read only, user may still
+ * change display brightness from Settings, but that must not be reflected
+ * to other displays.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Property to represent brightness of the displays which are controlled separately.
+ *
+ * Some cars have one or more displays whose brightness is controlled
+ * separately and this property is to inform the brightness of each
+ * passenger display. In cars where all displays' brightness is controlled
+ * together, they must use DISPLAY_BRIGHTNESS.
+ *
+ * Only one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be
+ * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
+ * AAOS.
+ *
+ * The display port uniquely identifies a physical connector on the device
+ * for display output, ranging from 0 to 255.
+ *
+ * int32Values[0] : display port
+ * int32Values[1] : brightness
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ PER_DISPLAY_BRIGHTNESS = 0x0A04 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Property to feed H/W input events to android
+ *
+ * int32Values[0] : action defined by VehicleHwKeyInputAction
+ * int32Values[1] : key code, must use standard android key code
+ * int32Values[2] : target display defined in VehicleDisplay. Events not
+ * tied to specific display must be sent to
+ * VehicleDisplay#MAIN.
+ * int32Values[3] : [optional] Number of ticks. The value must be equal or
+ * greater than 1. When omitted, Android will default to 1.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @config_flags
+ */
+ HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Property to feed H/W input events to android
+ *
+ * int32array[0]: target display defined by VehicleDisplay like VehicleDisplay::MAIN,
+ * VehicleDisplay::INSTRUMENT_CLUSTER, VehicleDisplay::AUX
+ * int32array[1]: key code, must use standard android key code like KEYCODE_HOME, KEYCODE_BACK
+ * int32array[2]: action defined in VehicleHwKeyInputAction like
+ * VehicleHwKeyInputAction::ACTION_UP, VehicleHwKeyInputAction::ACTION_UP
+ * int32array[3]: repeat count of the event. For key down events, this is the repeat count
+ * with the first down starting at 0 and counting up from there. For key up
+ * events, this is always equal to 0
+ *
+ * int64array[0]: down time, elapsed nanoseconds since boot. Denotes the time of the most
+ * recent key down event. For the down event, it will be the event time of the
+ * down event itself
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @config_flags
+ */
+ HW_KEY_INPUT_V2 =
+ 0x0A11 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
+ /**
+ * Property to feed H/W input events to android
+ *
+ * int32array[0]: target display defined by VehicleDisplay like VehicleDisplay::MAIN,
+ * VehicleDisplay::INSTRUMENT_CLUSTER, VehicleDisplay::AUX
+ * int32array[1]: input type defined in VehicleHwMotionInputSource like
+ * VehicleHwMotionInputSource::SOURCE_KEYBOARD,
+ * VehicleHwMotionInputSource::SOURCE_DPAD
+ * int32array[2]: action code defined in VehicleHwMotionInputAction like
+ * VehicleHwMotionInputAction::ACTION_UP, VehicleHwMotionInputAction::ACTION_DOWN
+ * int32array[3]: button state flag defined in VehicleHwMotionButtonStateFlag like
+ * VehicleHwMotionButtonStateFlag::BUTTON_PRIMARY,
+ * VehicleHwMotionButtonStateFlag::BUTTON_SECONDARY
+ * int32array[4]: pointer events count, N. N must be a positive integer
+ * int32array[5:5+N-1]: pointer id, length N
+ * int32array[5+N:5+2*N-1] : tool type, length N. As defined in VehicleHwMotionToolType like
+ * VehicleHwMotionToolType::TOOL_TYPE_FINGER,
+ * VehicleHwMotionToolType::TOOL_TYPE_STYLUS
+ *
+ * floatArray[0:N-1] : x data, length N
+ * floatArray[N:2*N-1] : y data, length N
+ * floatArray[2*N:3*N-1] : pressure data, length N
+ * floatArray[3*N:4*N-1] : size data, length N
+ *
+ * int64array[0]: down time, elapsed nanoseconds since boot. Denotes the time when the user
+ * originally pressed down to start a stream of position events. For the down
+ * event, it will be the event time of the down event itself
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @config_flags
+ */
+ HW_MOTION_INPUT =
+ 0x0A12 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
+ /**
+ * Property to feed H/W rotary events to android
+ *
+ * int32Values[0] : RotaryInputType identifying which rotary knob rotated
+ * int32Values[1] : number of detents (clicks), positive for clockwise,
+ * negative for counterclockwise
+ * int32Values[2] : target display defined in VehicleDisplay. Events not
+ * tied to specific display must be sent to
+ * VehicleDisplay#MAIN.
+ * int32values[3 .. 3 + abs(number of detents) - 2]:
+ * nanosecond deltas between pairs of consecutive detents,
+ * if the number of detents is > 1 or < -1
+ *
+ * VehiclePropValue.timestamp: when the rotation occurred. If the number of
+ * detents is > 1 or < -1, this is when the
+ * first detent of rotation occurred.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @data_enum RotaryInputType
+ * @access VehiclePropertyAccess.READ
+ */
+ HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Defines a custom OEM partner input event.
+ *
+ * This input event must be used by OEM partners who wish to propagate events not supported
+ * by Android. It is composed by an array of int32 values only.
+ *
+ * The Android properties are:
+ *
+ * int32Values[0] : Input code identifying the function representing this event. Valid event
+ * types are defined by CustomInputType.CUSTOM_EVENT_F1 up to
+ * CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be
+ * defined by OEM partners.
+ * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific
+ * display must be sent to VehicleDisplay#MAIN.
+ * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means
+ * how many times this event repeated.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @data_enum CustomInputType
+ * @access VehiclePropertyAccess.READ
+ */
+ HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /***************************************************************************
+ * Most Car Cabin properties have both a POSition and MOVE parameter. These
+ * are used to control the various movements for seats, doors, and windows
+ * in a vehicle.
+ *
+ * A POS parameter allows the user to set the absolution position. For
+ * instance, for a door, 0 indicates fully closed and max value indicates
+ * fully open. Thus, a value halfway between min and max must indicate
+ * the door is halfway open.
+ *
+ * A MOVE parameter moves the device in a particular direction. The sign
+ * indicates direction, and the magnitude indicates speed (if multiple
+ * speeds are available). For a door, a move of -1 will close the door, and
+ * a move of +1 will open it. Once a door reaches the limit of open/close,
+ * the door should automatically stop moving. The user must NOT need to
+ * send a MOVE(0) command to stop the door at the end of its range.
+ **************************************************************************/
+
+ /**
+ * Door position
+ *
+ * This is an integer in case a door may be set to a particular position.
+ * Max value indicates fully open, min value (0) indicates fully closed.
+ *
+ * Some vehicles (minivans) can open the door electronically. Hence, the
+ * ability to write this 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
+ */
+ DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
+ /**
+ * Door move
+ *
+ * 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
+ */
+ DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
+ /**
+ * Door lock
+ *
+ * 'true' indicates door is locked
+ *
+ * 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
+ */
+ DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
+ /**
+ * Door child lock feature enabled
+ *
+ * Returns true if the door child lock feature is enabled and false if it is disabled.
+ *
+ * If enabled, the door is unable to be opened from the inside.
+ *
+ * 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
+ */
+ DOOR_CHILD_LOCK_ENABLED =
+ 0x0B03 + VehiclePropertyGroup.SYSTEM + VehicleArea.DOOR + VehiclePropertyType.BOOLEAN,
+ /**
+ * Mirror Z Position
+ *
+ * Positive value indicates tilt upwards, negative value is downwards
+ *
+ * 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
+ */
+ MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+ /**
+ * Mirror Z Move
+ *
+ * Positive value indicates tilt upwards, negative value is downwards
+ *
+ * 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
+ */
+ MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+ /**
+ * Mirror Y Position
+ *
+ * Positive value indicate tilt right, negative value is left
+ *
+ * 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
+ */
+ MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+ /**
+ * Mirror Y Move
+ *
+ * Positive value indicate tilt right, negative value is left
+ *
+ * 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
+ */
+ MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
+ /**
+ * Mirror Lock
+ *
+ * True indicates mirror positions are locked and not changeable
+ *
+ * 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
+ */
+ MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Mirror Fold
+ *
+ * True indicates mirrors are folded
+ *
+ * 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
+ */
+ MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+
+ /**
+ * Represents property for Mirror Auto Fold feature.
+ *
+ * This property is true when the feature for automatically folding the vehicle's side mirrors
+ * (for example, when the mirrors fold inward automatically when one exits and locks the
+ * vehicle) is enabled.
+ *
+ * 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
+ */
+
+ MIRROR_AUTO_FOLD_ENABLED =
+ 0x0B46 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Represents property for Mirror Auto Tilt feature.
+ *
+ * This property is true when the feature for automatically tilting the vehicle's side mirrors
+ * (for example, when the mirrors tilt downward automatically when one reverses the vehicle) is
+ * enabled.
+ *
+ * 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
+ */
+
+ MIRROR_AUTO_TILT_ENABLED =
+ 0x0B47 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Seat memory select
+ *
+ * This parameter selects the memory preset to use to select the seat
+ * position. The minValue is always 0, and the maxValue determines the
+ * number of seat preset memory slots available (i.e. numSeatPresets - 1).
+ *
+ * For instance, if the driver's seat has 3 memory presets, the maxValue
+ * will be 2. When the user wants to select a preset, the desired preset
+ * number (0, 1, or 2) is set.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat memory set
+ *
+ * This setting allows the user to save the current seat position settings
+ * into the selected preset slot. The maxValue for each seat position
+ * must match the maxValue for SEAT_MEMORY_SELECT.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seatbelt buckled
+ *
+ * True indicates belt is buckled.
+ *
+ * Write access indicates automatic seat buckling capabilities. There are
+ * no known cars at this time, but you never know...
+ *
+ * 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
+ */
+ SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
+ /**
+ * Seatbelt height position
+ *
+ * Adjusts the shoulder belt anchor point.
+ * Max value indicates highest position
+ * Min value indicates lowest position
+ *
+ * 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
+ */
+ SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seatbelt height move
+ *
+ * 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
+ */
+ SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat fore/aft position
+ *
+ * Sets the seat position forward (closer to steering wheel) and backwards.
+ * Max value indicates closest to wheel, min value indicates most rearward
+ * position.
+ *
+ * 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
+ */
+ SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat fore/aft move
+ *
+ * Moves the seat position forward and aft.
+ *
+ * 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
+ */
+ SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat backrest angle 1 position
+ *
+ * Backrest angle 1 is the actuator closest to the bottom of the seat.
+ * Max value indicates angling forward towards the steering wheel.
+ * Min value indicates full recline.
+ *
+ * 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
+ */
+ SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat backrest angle 1 move
+ *
+ * Moves the backrest forward or recline.
+ *
+ * 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
+ */
+ SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat backrest angle 2 position
+ *
+ * Backrest angle 2 is the next actuator up from the bottom of the seat.
+ * Max value indicates angling forward towards the steering wheel.
+ * Min value indicates full recline.
+ *
+ * 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
+ */
+ SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat backrest angle 2 move
+ *
+ * Moves the backrest forward or recline.
+ *
+ * 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
+ */
+ SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat height position
+ *
+ * Sets the seat height.
+ * Max value indicates highest position.
+ * Min value indicates lowest position.
+ *
+ * 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
+ */
+ SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat height move
+ *
+ * Moves the seat height.
+ *
+ * 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
+ */
+ SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat depth position
+ *
+ * Sets the seat depth, distance from back rest to front edge of seat.
+ * Max value indicates longest depth position.
+ * Min value indicates shortest position.
+ *
+ * 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
+ */
+ SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat depth move
+ *
+ * Adjusts the seat depth.
+ *
+ * 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
+ */
+ SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat tilt position
+ *
+ * Sets the seat tilt.
+ * Max value indicates front edge of seat higher than back edge.
+ * Min value indicates front edge of seat lower than back edge.
+ *
+ * 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
+ */
+ SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Seat tilt move
+ *
+ * Tilts the seat.
+ *
+ * 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
+ */
+ SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Lumber fore/aft position
+ *
+ * Pushes the lumbar support forward and backwards
+ * Max value indicates most forward position.
+ * Min value indicates most rearward position.
+ *
+ * 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
+ */
+ SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Lumbar fore/aft move
+ *
+ * Adjusts the lumbar support.
+ *
+ * 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
+ */
+ SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Lumbar side support position
+ *
+ * Sets the amount of lateral lumbar support.
+ * Max value indicates widest lumbar setting (i.e. least support)
+ * Min value indicates thinnest lumbar setting.
+ *
+ * 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
+ */
+ SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Lumbar side support move
+ *
+ * Adjusts the amount of lateral lumbar support.
+ *
+ * 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
+ */
+ SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * (Deprecated) Headrest height position
+ *
+ * This property is deprecated because it is defined as type VehicleArea:GLOBAL, which means all
+ * seats use the same value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by
+ * being defined as type VehicleArea:SEAT.
+ *
+ * Sets the headrest height.
+ * Max value indicates tallest setting.
+ * Min value indicates shortest setting.
+ *
+ * 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
+ */
+ SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Headrest height position
+ *
+ * Sets the headrest height for supported seats. VehiclePropConfig.areaConfigs specifies which
+ * seats are supported.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+ * minInt32Value and maxInt32Value must be supported. The maxInt32Value indicates the tallest
+ * setting and the minInt32Value indicates the shortest setting.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ SEAT_HEADREST_HEIGHT_POS_V2 =
+ 0x0BA4 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+
+ /**
+ * Headrest height move
+ *
+ * Moves the headrest up and down.
+ *
+ * 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
+ */
+ SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Headrest angle position
+ *
+ * Sets the angle of the headrest.
+ * Max value indicates most upright angle.
+ * Min value indicates shallowest headrest angle.
+ *
+ * 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
+ */
+ SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Headrest angle move
+ *
+ * Adjusts the angle of the headrest
+ *
+ * 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
+ */
+ SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Headrest fore/aft position
+ *
+ * Adjusts the headrest forwards and backwards.
+ * Max value indicates position closest to front of car.
+ * Min value indicates position closest to rear of car.
+ *
+ * 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
+ */
+ SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Headrest fore/aft move
+ *
+ * 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
+ */
+ SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Represents property for the seat footwell lights state.
+ *
+ * SEAT_FOOTWELL_LIGHTS_STATE reflects the current state of the lights at any point in time.
+ * This is different from the function of SEAT_FOOTWELL_LIGHTS_SWITCH which represents the
+ * position of the switch controlling the lights. Therefore, SEAT_FOOTWELL_LIGHTS_STATE may not
+ * match the value of SEAT_FOOTWELL_LIGHTS_SWITCH (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC
+ * and SEAT_FOOTWELL_LIGHTS_STATE=ON).
+ *
+ * This property should only be implemented if SEAT_FOOTWELL_LIGHTS_STATE's value may be
+ * different from that of CABIN_LIGHTS_STATE.
+ *
+ * For each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless
+ * all enum values of VehicleLightState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ SEAT_FOOTWELL_LIGHTS_STATE =
+ 0x0B9B + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for the seat footwell lights switch.
+ *
+ * SEAT_FOOTWELL_LIGHTS_SWITCH represents the position of the switch controlling the lights.
+ * This is different from the function of SEAT_FOOTWELL_LIGHTS_STATE which reflects the current
+ * state of the lights at any point in time. Therefore, SEAT_FOOTWELL_LIGHTS_SWITCH may not
+ * match the value of SEAT_FOOTWELL_LIGHTS_STATE (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC and
+ * SEAT_FOOTWELL_LIGHTS_STATE=ON).
+ *
+ * This property should only be implemented if SEAT_FOOTWELL_LIGHTS_SWITCH's value may be
+ * different from that of CABIN_LIGHTS_SWITCH.
+ *
+ * For each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless
+ * all enum values of VehicleLightSwitch are supported.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ SEAT_FOOTWELL_LIGHTS_SWITCH =
+ 0x0B9C + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for Seat easy access feature.
+ *
+ * If true, the seat will automatically adjust to make it easier for the occupant to enter and
+ * exit the vehicle. Each area ID must map to the seat that the user is trying to enter/exit
+ * with the help of the easy access feature.
+ *
+ * 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
+ */
+ SEAT_EASY_ACCESS_ENABLED =
+ 0x0B9D + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+ /**
+ * Represents feature to enable/disable a seat's ability to deploy airbag(s) when triggered
+ * (e.g. by a crash).
+ *
+ * If true, it means the seat's airbags are enabled, and if triggered (e.g. by a crash), they
+ * will deploy. If false, it means the seat's airbags are disabled, and they will not deploy
+ * under any circumstance. This property does not indicate if the airbags are deployed or not.
+ *
+ * This property can be set to VehiclePropertyAccess.READ read only for the sake of regulation
+ * or safety concerns.
+ *
+ * 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
+ */
+ SEAT_AIRBAG_ENABLED =
+ 0x0B9E + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+ /**
+ * Represents property for seat’s hipside (bottom cushion’s side) support position.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value are supported.
+ *
+ * maxInt32Value indicates the widest cushion side support setting (i.e. least support).
+ * minInt32Value indicates the thinnest cushion side support setting (i.e most support).
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ SEAT_CUSHION_SIDE_SUPPORT_POS =
+ 0x0B9F + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for movement direction and speed of seat cushion side support.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value must be supported.
+ *
+ * maxInt32Value in default area's VehicleAreaConfig represents the maximum movement speed of
+ * the seat cushion side support in the growing wider direction (i.e. less support).
+ * minInt32Value in default area's VehicleAreaConfig represents the maximum movement speed of
+ * the seat cushion side support in the growing thinner direction (i.e. more support).
+ *
+ * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+ * the seat cushion side support reaches the positional limit, the value resets to 0.
+ *
+ * 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
+ */
+ SEAT_CUSHION_SIDE_SUPPORT_MOVE =
+ 0x0BA0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for seat’s lumbar support vertical position.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value are supported.
+ *
+ * maxInt32Value indicates the highest position.
+ * minInt32Value indicates the lowest position.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ SEAT_LUMBAR_VERTICAL_POS =
+ 0x0BA1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property for vertical movement direction and speed of seat lumbar support.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers
+ * between minInt32Value and maxInt32Value must be supported.
+ *
+ * maxInt32Value in default area's VehicleAreaConfig indicates the lumbar support is moving at
+ * the fastest upward speed.
+ * minInt32Value in default area's VehicleAreaConfig indicates the lumbar support is moving at
+ * the fastest downward speed.
+ *
+ * Larger absolute values, either positive or negative, indicate a faster movement speed. Once
+ * the seat cushion side support reaches the positional limit, the value resets to 0.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ SEAT_LUMBAR_VERTICAL_MOVE =
+ 0x0BA2 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Represents property that indicates the current walk-in position of the seat.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+ * The minInt32Value must be 0.
+ * All integers between minInt32Value and maxInt32Value must be supported.
+ *
+ * minInt32Value indicates the normal seat position.
+ * maxInt32Value indicates the seat is in the full walk-in position.
+ *
+ * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+ * normal and walk-in positions.
+ *
+ * The area ID must match the seat that actually moves when the walk-in feature activates, not
+ * the intended seat the passengers will sit in.
+ *
+ * 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
+ */
+ SEAT_WALK_IN_POS =
+ 0x0BA3 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
+ * Seat Occupancy
+ *
+ * Indicates whether a particular seat is occupied or not, to the best of the car's ability
+ * to determine. Valid values are from the VehicleSeatOccupancyState enum.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleSeatOccupancyState
+ */
+ SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Window Position
+ *
+ * Min = window up / closed
+ * Max = window down / open
+ *
+ * For a window that may open out of plane (i.e. vent mode of sunroof) this
+ * parameter will work with negative values as follows:
+ * Max = sunroof completely open
+ * 0 = sunroof closed.
+ * Min = sunroof vent completely open
+ *
+ * Note that in this mode, 0 indicates the window is closed.
+ *
+ * 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
+ */
+ WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+ /**
+ * Window Move
+ *
+ * Max = Open the window as fast as possible
+ * Min = Close the window as fast as possible
+ * Magnitude denotes relative speed. I.e. +2 is faster than +1 in closing
+ * the window.
+ *
+ * For a window that may open out of plane (i.e. vent mode of sunroof) this
+ * parameter will work as follows:
+ *
+ * If sunroof is open:
+ * Max = open the sunroof further, automatically stop when fully open.
+ * Min = close the sunroof, automatically stop when sunroof is closed.
+ *
+ * If vent is open:
+ * Max = close the vent, automatically stop when vent is closed.
+ * Min = open the vent further, automatically stop when vent is fully open.
+ *
+ * If sunroof is in the closed position:
+ * Max = open the sunroof, automatically stop when sunroof is fully open.
+ * Min = open the vent, automatically stop when vent is fully open.
+ *
+ * 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
+ */
+ WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+ /**
+ * Window Lock
+ *
+ * True indicates windows are locked and can't be moved.
+ *
+ * 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
+ */
+ WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
+ /**
+ * Windshield wipers period (milliseconds).
+ *
+ * Returns the instantaneous time period for 1 full cycle of the windshield wipers in
+ * milliseconds. A full cycle is defined as a wiper moving from and returning to its rest
+ * position.
+ *
+ * When an intermittent wiper setting is selected, this property value must be set to 0 during
+ * the "pause" period of the intermittent wiping.
+ *
+ * The maxInt32Value for each area ID must specify the longest wiper period. The minInt32Value
+ * must be set to 0 for each area ID.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MILLI_SECS
+ */
+ WINDSHIELD_WIPERS_PERIOD =
+ 0x0BC5 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
+
+ /**
+ * Windshield wipers state.
+ *
+ * Returns the current state of the windshield wipers. The value of WINDSHIELD_WIPERS_STATE may
+ * not match the value of WINDSHIELD_WIPERS_SWITCH. (e.g. WINDSHIELD_WIPERS_STATE = ON and
+ * WINDSHIELD_WIPERS_SWITCH = WindshieldWipersSwitch#AUTO).
+ *
+ * If WINDSHIELD_WIPERS_STATE = ON and WINDSHIELD_WIPERS_PERIOD is implemented, then
+ * WINDSHIELD_WIPERS_PERIOD must reflect the time period of 1 full cycle of the wipers.
+ *
+ * For each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states in WindshieldWipersState are supported (including OTHER, which is not
+ * recommended).
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum WindshieldWipersState
+ */
+ WINDSHIELD_WIPERS_STATE =
+ 0x0BC6 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
+
+ /**
+ * Windshield wipers switch.
+ *
+ * Represents the position of the switch controlling the windshield wipers. The value of
+ * WINDSHIELD_WIPERS_SWITCH may not match the value of WINDSHIELD_WIPERS_STATE (e.g.
+ * WINDSHIELD_WIPERS_SWITCH = AUTO and WINDSHIELD_WIPERS_STATE = WindshieldWipersState#ON).
+ *
+ * For each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states in WindshieldWipersSwitch are supported (including OTHER, which is not
+ * recommended).
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * If this property is implemented as VehiclePropertyAccess.READ_WRITE and the OTHER state is
+ * listed in the VehicleAreaConfig#supportedEnumValues array, then OTHER is not a supported
+ * value for writing. It is only a supported value for reading.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @data_enum WindshieldWipersSwitch
+ */
+ WINDSHIELD_WIPERS_SWITCH =
+ 0x0BC7 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
+
+ /**
+ * Steering wheel depth position
+ *
+ * All steering wheel properties' unique ids start from 0x0BE0.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+ * minInt32Value and maxInt32Value must be supported.
+ *
+ * The maxInt32Value in default area's VehicleAreaConfig indicates the steering wheel position
+ * closest to the driver. The minInt32Value in default area's VehicleAreaConfig indicates the
+ * steering wheel position furthest to the driver.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ STEERING_WHEEL_DEPTH_POS =
+ 0x0BE0 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Steering wheel depth movement
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+ * minInt32Value and maxInt32Value must be supported.
+ *
+ * The maxInt32Value in default area's VehicleAreaConfig indicates the steering wheel moving
+ * towards the driver. The minInt32Value in default area's VehicleAreaConfig indicates the
+ * steering wheel moving away from the driver. Larger integers, either positive or negative,
+ * indicate a faster movement speed. Once the steering wheel reaches the positional limit, the
+ * value resets to 0.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ STEERING_WHEEL_DEPTH_MOVE =
+ 0x0BE1 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Steering wheel height position
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+ * minInt32Value and maxInt32Value must be supported.
+ *
+ * The maxInt32Value in default area's VehicleAreaConfig indicates the steering wheel being in
+ * the highest position. The minInt32Value in default area's VehicleAreaConfig indicates the
+ * steering wheel being in the lowest position.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ STEERING_WHEEL_HEIGHT_POS =
+ 0x0BE2 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Steering wheel height movement
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
+ * minInt32Value and maxInt32Value must be supported.
+ *
+ * The maxInt32Value in default area's VehicleAreaConfig indicates the steering wheel moving
+ * upwards. The minInt32Value in default area's VehicleAreaConfig indicates the steering wheel
+ * moving downwards. Larger integers, either positive or negative, indicate a faster movement
+ * speed. Once the steering wheel reaches the positional limit, the value resets to 0.
+ *
+ * This value is not in any particular unit but in a specified range of steps.
+ *
+ * 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
+ */
+ STEERING_WHEEL_HEIGHT_MOVE =
+ 0x0BE3 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Steering wheel theft lock feature enabled
+ *
+ * If true, the steering wheel will lock automatically to prevent theft in certain
+ * situations.
+ *
+ * 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
+ */
+ STEERING_WHEEL_THEFT_LOCK_ENABLED =
+ 0x0BE4 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Steering wheel locked
+ *
+ * If true, the steering wheel's position is locked and not changeable.
+ *
+ * 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
+ */
+ STEERING_WHEEL_LOCKED =
+ 0x0BE5 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Steering wheel easy access feature enabled
+ *
+ * If true, the driver’s steering wheel will automatically adjust to make it easier for the
+ * driver to enter and exit the vehicle.
+ *
+ * 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
+ */
+ STEERING_WHEEL_EASY_ACCESS_ENABLED =
+ 0x0BE6 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
+ * Property that represents the current position of the glove box door.
+ *
+ * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined.
+ * The minInt32Value must be 0.
+ * All integers between minInt32Value and maxInt32Value must be supported.
+ *
+ * minInt32Value indicates that the glove box door is closed.
+ * maxInt32Value indicates that the glove box door is in the fully open position.
+ *
+ * Values in between minInt32Value and maxInt32Value indicate a transition state between the
+ * closed and fully open positions.
+ *
+ * The area ID must match the seat by which the glove box is intended to be used (e.g. if the
+ * front right dashboard has a glove box embedded in it, then the area ID should be
+ * SEAT_1_RIGHT).
+ *
+ * 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
+ */
+ GLOVE_BOX_DOOR_POS =
+ 0x0BF0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+
+ /**
+ * Lock or unlock the glove box.
+ *
+ * If true, the glove box is locked. If false, the glove box is unlocked.
+ *
+ * The area ID must match the seat by which the glove box is intended to be used (e.g. if the
+ * front right dashboard has a glove box embedded in it, then the area ID should be
+ * VehicleAreaSeat#ROW_1_RIGHT).
+ *
+ * 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
+ */
+ GLOVE_BOX_LOCKED =
+ 0x0BF1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Vehicle Maps Service (VMS) message
+ *
+ * This property uses MIXED data to communicate vms messages.
+ *
+ * Its contents are to be interpreted as follows:
+ * the indices defined in VmsMessageIntegerValuesIndex are to be used to
+ * read from int32Values;
+ * bytes is a serialized VMS message as defined in the vms protocol
+ * which is opaque to the framework;
+ *
+ * IVehicle#get must always return StatusCode::NOT_AVAILABLE.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Characterization of inputs used for computing location.
+ *
+ * This property must indicate what (if any) data and sensor inputs are considered by the system
+ * when computing the vehicle's location that is shared with Android through the GNSS HAL.
+ *
+ * The value must return a collection of bit flags. The bit flags are defined in
+ * LocationCharacterization. The value must also include exactly one of DEAD_RECKONED or
+ * RAW_GNSS_ONLY among its collection of bit flags.
+ *
+ * When this property is not supported, it is assumed that no additional sensor inputs are fused
+ * into the GNSS updates provided through the GNSS HAL. That is unless otherwise specified
+ * through the GNSS HAL interfaces.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ LOCATION_CHARACTERIZATION =
+ 0x0C10 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * OBD2 Live Sensor Data
+ *
+ * Reports a snapshot of the current (live) values of the OBD2 sensors available.
+ *
+ * The configArray is set as follows:
+ * configArray[0] = number of vendor-specific integer-valued sensors
+ * configArray[1] = number of vendor-specific float-valued sensors
+ *
+ * The values of this property are to be interpreted as in the following example.
+ * Considering a configArray = {2,3}
+ * int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2
+ * elements (that is, 33 elements);
+ * floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3
+ * elements (that is, 73 elements);
+ *
+ * It is possible for each frame to contain a different subset of sensor values, both system
+ * provided sensors, and vendor-specific ones. In order to support that, the bytes element
+ * of the property value is used as a bitmask,.
+ *
+ * bytes must have a sufficient number of bytes to represent the total number of possible
+ * sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as
+ * a contiguous bitmask such that each bit indicates the presence or absence of a sensor
+ * from the frame, starting with as many bits as the size of int32Values, immediately
+ * followed by as many bits as the size of floatValues.
+ *
+ * For example, should bytes[0] = 0x4C (0b01001100) it would mean that:
+ * int32Values[0 and 1] are not valid sensor values
+ * int32Values[2 and 3] are valid sensor values
+ * int32Values[4 and 5] are not valid sensor values
+ * int32Values[6] is a valid sensor value
+ * int32Values[7] is not a valid sensor value
+ * Should bytes[5] = 0x61 (0b01100001) it would mean that:
+ * int32Values[32] is a valid sensor value
+ * floatValues[0 thru 3] are not valid sensor values
+ * floatValues[4 and 5] are valid sensor values
+ * floatValues[6] is not a valid sensor value
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * OBD2 Freeze Frame Sensor Data
+ *
+ * Reports a snapshot of the value of the OBD2 sensors available at the time that a fault
+ * occurred and was detected.
+ *
+ * A configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.
+ *
+ * The values of this property are to be interpreted in a similar fashion as those for
+ * OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty
+ * diagnostic troubleshooting code (DTC).
+ *
+ * A IVehicle#get request of this property must provide a value for int64Values[0].
+ * This will be interpreted as the timestamp of the freeze frame to retrieve. A list of
+ * timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.
+ *
+ * Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
+ * must be returned by the implementation. Because vehicles may have limited storage for
+ * freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if
+ * the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * OBD2 Freeze Frame Information
+ *
+ * This property describes the current freeze frames stored in vehicle
+ * memory and available for retrieval via OBD2_FREEZE_FRAME.
+ *
+ * The values are to be interpreted as follows:
+ * each element of int64Values must be the timestamp at which a a fault code
+ * has been detected and the corresponding freeze frame stored, and each
+ * such element can be used as the key to OBD2_FREEZE_FRAME to retrieve
+ * the corresponding freeze frame.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * OBD2 Freeze Frame Clear
+ *
+ * This property allows deletion of any of the freeze frames stored in
+ * vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.
+ *
+ * The configArray is set as follows:
+ * configArray[0] = 1 if the implementation is able to clear individual freeze frames
+ * by timestamp, 0 otherwise
+ *
+ * IVehicle#set of this property is to be interpreted as follows:
+ * if int64Values contains no elements, then all frames stored must be cleared;
+ * if int64Values contains one or more elements, then frames at the timestamps
+ * stored in int64Values must be cleared, and the others not cleared. Should the
+ * vehicle not support selective clearing of freeze frames, this latter mode must
+ * return NOT_AVAILABLE.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Headlights State
+ *
+ * Return the current state of headlights.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * High beam lights state
+ *
+ * Return the current state of high beam lights.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Fog light state
+ *
+ * Return the current state of fog lights.
+ *
+ * If the car has both front and rear fog lights:
+ * If front and rear fog lights can only be controlled together: FOG_LIGHTS_STATE must be
+ * implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must not be implemented.
+ *
+ * If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_STATE
+ * must not be implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must be
+ * implemented.
+ *
+ * If the car has only front fog lights:
+ * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented and not both.
+ * REAR_FOG_LIGHTS_STATE must not be implemented.
+ *
+ * If the car has only rear fog lights:
+ * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented and not both.
+ * FRONT_FOG_LIGHTS_STATE must not be implemented.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Hazard light status
+ *
+ * Return the current status of hazard lights.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Headlight switch
+ *
+ * The setting that the user wants.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * High beam light switch
+ *
+ * The setting that the user wants.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Fog light switch
+ *
+ * The setting that the user wants.
+ *
+ * If the car has both front and rear fog lights:
+ * If front and rear fog lights can only be controlled together: FOG_LIGHTS_SWITCH must be
+ * implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must not be implemented.
+ *
+ * If the front and rear fog lights can only be controlled independently: FOG_LIGHTS_SWITCH
+ * must not be implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must be
+ * implemented.
+ *
+ * If the car has only front fog lights:
+ * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented and not both.
+ * REAR_FOG_LIGHTS_SWITCH must not be implemented.
+ *
+ * If the car has only rear fog lights:
+ * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented and not both.
+ * FRONT_FOG_LIGHTS_SWITCH must not be implemented.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Hazard light switch
+ *
+ * The setting that the user wants.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Cabin lights
+ *
+ * Return current status of cabin lights.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Cabin lights switch
+ *
+ * The position of the physical switch which controls the cabin lights.
+ * This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door
+ * is open or because of a voice command.
+ * For example, while the switch is in the "off" or "automatic" position.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Reading lights
+ *
+ * Return current status of reading lights.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Reading lights switch
+ *
+ * The position of the physical switch which controls the reading lights.
+ * This might be different than the READING_LIGHTS_STATE if the lights are on because a door
+ * is open or because of a voice command.
+ * For example, while the switch is in the "off" or "automatic" position.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
+ /**
+ * Steering wheel lights state
+ *
+ * Represents the current state of the steering wheel lights. This is different from
+ * STEERING_WHEEL_LIGHTS_SWITCH which represents the position of the switch controlling
+ * the lights. Therefore, STEERING_WHEEL_LIGHTS_STATE may not match the value of
+ * STEERING_WHEEL_LIGHTS_SWITCH (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and
+ * STEERING_WHEEL_LIGHTS_STATE=ON).
+ *
+ * This property should only be implemented if STEERING_WHEEL_LIGHTS_STATE's value may be
+ * different from that of CABIN_LIGHTS_STATE.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+ * all enum values of VehicleLightState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ STEERING_WHEEL_LIGHTS_STATE =
+ 0x0F0C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Steering wheel lights switch
+ *
+ * Represents the position of the switch controlling the steering wheel lights. This is
+ * different from STEERING_WHEEL_LIGHTS_STATE which represents the current state of the steering
+ * wheel lights. Therefore, STEERING_WHEEL_LIGHTS_SWITCH may not match the value of
+ * STEERING_WHEEL_LIGHTS_STATE (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and
+ * STEERING_WHEEL_LIGHTS_STATE=ON).
+ *
+ * This property should only be implemented if STEERING_WHEEL_LIGHTS_SWITCH's value may be
+ * different from that of CABIN_LIGHTS_SWITCH.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+ * all enum values of VehicleLightSwitch are supported.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ STEERING_WHEEL_LIGHTS_SWITCH =
+ 0x0F0D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Support customize permissions for vendor properties
+ *
+ * Implement this property if vehicle hal support customize vendor permissions feature.
+ * VehiclePropConfig.configArray is used to indicate vendor properties and permissions
+ * which selected for this vendor property. The permission must be one of enum in
+ * VehicleVendorPermission.
+ * The configArray is set as follows:
+ * configArray[n] = propId : property ID for the vendor property
+ * configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission
+ * for reading value of the property.
+ * configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission
+ * for writing value of the property.
+ *
+ * For example:
+ * configArray = {
+ * vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE,
+ * vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE,
+ * }
+ * If vendor properties are not in this array, they will have the default vendor permission.
+ * If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In
+ * the example, Android can not write value for vendor_prop_2.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+ /**
+ * Allow disabling optional featurs from vhal.
+ *
+ * This property reports optional features that should be disabled.
+ * All allowed optional features for the system is declared in Car service overlay,
+ * config_allowed_optional_car_features.
+ * This property allows disabling features defined in the overlay. Without this property,
+ * all the features declared in the overlay will be enabled.
+ *
+ * Value read should include all features disabled with ',' separation.
+ * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Defines the initial Android user to be used during initialization.
+ *
+ * This property is called by the Android system when it initializes and it lets the HAL
+ * define which Android user should be started.
+ *
+ * This request is made by setting a VehiclePropValue (defined by InitialUserInfoRequest),
+ * and the HAL must respond with a property change event (defined by InitialUserInfoResponse).
+ * If the HAL doesn't respond after some time (defined by the Android system), the Android
+ * system will proceed as if HAL returned a response of action
+ * InitialUserInfoResponseAction:DEFAULT.
+ *
+ * For example, on first boot, the request could be:
+ *
+ * int32[0]: 42 // request id (arbitrary number set by Android system)
+ * int32[1]: 1 // InitialUserInfoRequestType::FIRST_BOOT
+ * int32[2]: 0 // id of current user (usersInfo.currentUser.userId)
+ * int32[3]: 1 // flag of current user (usersInfo.currentUser.flags = SYSTEM)
+ * int32[4]: 1 // number of existing users (usersInfo.numberUsers);
+ * int32[5]: 0 // user #0 (usersInfo.existingUsers[0].userId)
+ * int32[6]: 1 // flags of user #0 (usersInfo.existingUsers[0].flags)
+ *
+ * And if the HAL want to respond with the creation of an admin user called "Owner", the
+ * response would be:
+ *
+ * int32[0]: 42 // must match the request id from the request
+ * int32[1]: 2 // action = InitialUserInfoResponseAction::CREATE
+ * int32[2]: -10000 // userToSwitchOrCreate.userId (not used as user will be created)
+ * int32[3]: 8 // userToSwitchOrCreate.flags = ADMIN
+ * string: "||Owner" // userLocales + separator + userNameToCreate
+ *
+ * Notice the string value represents multiple values, separated by ||. The first value is the
+ * (optional) system locales for the user to be created (in this case, it's empty, meaning it
+ * will use Android's default value), while the second value is the (also optional) name of the
+ * to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE).
+ * For example, to create the same "Owner" user with "en-US" and "pt-BR" locales, the string
+ * value of the response would be "en-US,pt-BR||Owner". As such, neither the locale nor the
+ * name can have || on it, although a single | is fine.
+ *
+ * NOTE: if the HAL doesn't support user management, then it should not define this property,
+ * which in turn would disable the other user-related properties (for example, the Android
+ * system would never issue them and user-related requests from the HAL layer would be ignored
+ * by the Android System). But if it supports user management, then it must support all core
+ * user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER).
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Defines a request to switch the foreground Android user.
+ *
+ * This property is used primarily by the Android System to inform the HAL that the
+ * current foreground Android user is switching, but it could also be used by the HAL to request
+ * the Android system to switch users - the
+ *
+ * When the request is made by Android, it sets a VehiclePropValue and the HAL must responde
+ * with a property change event; when the HAL is making the request, it must also do it through
+ * a property change event (the main difference is that the request id will be positive in the
+ * former case, and negative in the latter; the SwitchUserMessageType will also be different).
+ *
+ * The format of both request is defined by SwitchUserRequest and the format of the response
+ * (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should
+ * proceed depends on the message type (which is defined by the SwitchUserMessageType
+ * parameter), as defined below.
+ *
+ * 1.LEGACY_ANDROID_SWITCH
+ * -----------------------
+ *
+ * Called by the Android System to indicate the Android user is about to change, when the change
+ * request was made in a way that is not integrated with the HAL (for example, through
+ * adb shell am switch-user).
+ *
+ * The HAL can switch its internal user once it receives this request, but it doesn't need to
+ * reply back to the Android System. If its internal user cannot be changed for some reason,
+ * then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover
+ * (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to
+ * the previous user), but ideally it should never fail (as switching back could result in a
+ * confusing experience for the end user).
+ *
+ * For example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none
+ * of them have any special flag), the request would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 1 // SwitchUserMessageType::LEGACY_ANDROID_SWITCH
+ * int32[2]: 11 // target user id
+ * int32[3]: 0 // target user flags (none)
+ * int32[4]: 10 // current user
+ * int32[5]: 0 // current user flags (none)
+ * int32[6]: 3 // number of users
+ * int32[7]: 0 // user #0 (Android user id 0)
+ * int32[8]: 0 // flags of user #0 (none)
+ * int32[9]: 10 // user #1 (Android user id 10)
+ * int32[10]: 0 // flags of user #1 (none)
+ * int32[11]: 11 // user #2 (Android user id 11)
+ * int32[12]: 0 // flags of user #2 (none)
+ *
+ * 2.ANDROID_SWITCH
+ * ----------------
+ * Called by the Android System to indicate the Android user is about to change, but Android
+ * will wait for the HAL's response (up to some time) before proceeding.
+ *
+ * The HAL must switch its internal user once it receives this request, then respond back to
+ * Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal
+ * user was switched or not (through the SwitchUserStatus enum).
+ *
+ * For example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where
+ * none of them have any special flag), the request would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 2 // SwitchUserMessageType::ANDROID_SWITCH
+ * int32[2]: 11 // target user id
+ * int32[3]: 0 // target user flags (none)
+ * int32[4]: 10 // current user
+ * int32[5]: 0 // current user flags (none)
+ * int32[6]: 3 // number of users
+ * int32[7]: 0 // 1st user (user 0)
+ * int32[8]: 1 // 1st user flags (SYSTEM)
+ * int32[9]: 10 // 2nd user (user 10)
+ * int32[10]: 0 // 2nd user flags (none)
+ * int32[11]: 11 // 3rd user (user 11)
+ * int32[12]: 0 // 3rd user flags (none)
+ *
+ * If the request succeeded, the HAL must update the property with:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 3 // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
+ * int32[2]: 1 // status = SwitchUserStatus::SUCCESS
+ *
+ * But if it failed, the response would be something like:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 3 // messageType = SwitchUserMessageType::VEHICLE_RESPONSE
+ * int32[2]: 2 // status = SwitchUserStatus::FAILURE
+ * string: "108-D'OH!" // OEM-specific error message
+ *
+ * 3.VEHICLE_RESPONSE
+ * ------------------
+ * Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or
+ * abort - see the ANDROID_SWITCH section above for more info.
+ *
+ * 4.VEHICLE_REQUEST
+ * ------------------
+ * Called by the HAL to request that the current foreground Android user is switched.
+ *
+ * This is useful in situations where Android started as one user, but the vehicle identified
+ * the driver as another user. For example, user A unlocked the car using the key fob of user B;
+ * the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem
+ * identified the user as A.
+ *
+ * The HAL makes this request by a property change event (passing a negative request id), and
+ * the Android system will response by issue an ANDROID_POST_SWITCH call which the same
+ * request id.
+ *
+ * For example, if the current foreground Android user is 10 and the HAL asked it to switch to
+ * 11, the request would be:
+ *
+ * int32[0]: -108 // request id
+ * int32[1]: 4 // messageType = SwitchUserMessageType::VEHICLE_REQUEST
+ * int32[2]: 11 // Android user id
+ *
+ * If the request succeeded and Android has 3 users (0, 10, 11), the response would be:
+ *
+ * int32[0]: -108 // request id
+ * int32[1]: 5 // messageType = SwitchUserMessageType::ANDROID_POST_SWITCH
+ * int32[2]: 11 // target user id
+ * int32[3]: 0 // target user id flags (none)
+ * int32[4]: 11 // current user
+ * int32[5]: 0 // current user flags (none)
+ * int32[6]: 3 // number of users
+ * int32[7]: 0 // 1st user (user 0)
+ * int32[8]: 0 // 1st user flags (none)
+ * int32[9]: 10 // 2nd user (user 10)
+ * int32[10]: 4 // 2nd user flags (none)
+ * int32[11]: 11 // 3rd user (user 11)
+ * int32[12]: 3 // 3rd user flags (none)
+ *
+ * Notice that both the current and target user ids are the same - if the request failed, then
+ * they would be different (i.e, target user would be 11, but current user would still be 10).
+ *
+ * 5.ANDROID_POST_SWITCH
+ * ---------------------
+ * Called by the Android System after a request to switch a user was made.
+ *
+ * This property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH,
+ * ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or
+ * failed:
+ *
+ * 1. When it succeeded, it's called when the Android user is in the unlocked state and the
+ * value of the current and target users ids in the response are the same. This would be
+ * equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app.
+ * 2. When it failed it's called right away and the value of the current and target users ids
+ * in the response are different (as the current user didn't change to the target).
+ * 3. If a new switch request is made before the HAL responded to the previous one or before
+ * the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example,
+ * the driver could accidentally switch to the wrong user which has lock credentials, then
+ * switch to the right one before entering the credentials.
+ *
+ * The HAL can update its internal state once it receives this request, but it doesn't need to
+ * reply back to the Android System.
+ *
+ * Request: the first N values as defined by INITIAL_USER_INFO (where the request-specific
+ * value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the
+ * target user id (i.e., the Android user id that was requested to be switched to) and its flags
+ * (as defined by UserFlags).
+ *
+ * Response: none.
+ *
+ * Example: see VEHICLE_REQUEST section above.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Called by the Android System after an Android user was created.
+ *
+ * The HAL can use this property to create its equivalent user.
+ *
+ * This is an async request: Android makes the request by setting a VehiclePropValue, and HAL
+ * must respond with a property change indicating whether the request succeeded or failed. If
+ * it failed, the Android system will remove the user.
+ *
+ * The format of the request is defined by CreateUserRequest and the format of the response by
+ * CreateUserResponse.
+ *
+ * For example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was
+ * created, the request would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 11 // Android id of the created user
+ * int32[2]: 6 // Android flags (ephemeral guest) of the created user
+ * int32[3]: 10 // current user
+ * int32[4]: 0 // current user flags (none)
+ * int32[5]: 3 // number of users
+ * int32[6]: 0 // 1st user (user 0)
+ * int32[7]: 0 // 1st user flags (none)
+ * int32[8]: 10 // 2nd user (user 10)
+ * int32[9]: 0 // 2nd user flags (none)
+ * int32[19]: 11 // 3rd user (user 11)
+ * int32[11]: 6 // 3rd user flags (ephemeral guest)
+ * string: "ElGuesto" // name of the new user
+ *
+ * Then if the request succeeded, the HAL would return:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 1 // CreateUserStatus::SUCCESS
+ *
+ * But if it failed:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 2 // CreateUserStatus::FAILURE
+ * string: "D'OH!" // The meaning is a blackbox - it's passed to the caller (like Settings UI),
+ * // which in turn can take the proper action.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Called by the Android System after an Android user was removed.
+ *
+ * The HAL can use this property to remove its equivalent user.
+ *
+ * This is write-only call - the Android System is not expecting a reply from the HAL. Hence,
+ * this request should not fail - if the equivalent HAL user cannot be removed, then HAL should
+ * mark it as inactive or recover in some other way.
+ *
+ * The request is made by setting the VehiclePropValue with the contents defined by
+ * RemoveUserRequest.
+ *
+ * For example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request
+ * would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 11 // (Android user id of the removed user)
+ * int32[2]: 0 // (Android user flags of the removed user)
+ * int32[3]: 10 // current user
+ * int32[4]: 0 // current user flags (none)
+ * int32[5]: 2 // number of users
+ * int32[6]: 0 // 1st user (user 0)
+ * int32[7]: 0 // 1st user flags (none)
+ * int32[8]: 10 // 2nd user (user 10)
+ * int32[9]: 0 // 2nd user flags (none)
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.WRITE
+ */
+ REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Property used to associate (or query the association) the current user with vehicle-specific
+ * identification mechanisms (such as key FOB).
+ *
+ * This is an optional user management property - the OEM could still support user management
+ * without defining it. In fact, this property could be used without supporting the core
+ * user-related functions described on INITIAL_USER_INFO.
+ *
+ * To query the association, the Android system gets the property, passing a VehiclePropValue
+ * containing the types of associations are being queried, as defined by
+ * UserIdentificationGetRequest. The HAL must return right away, returning a VehiclePropValue
+ * with a UserIdentificationResponse. Notice that user identification should have already
+ * happened while system is booting up and the VHAL implementation should only return the
+ * already identified association (like the key FOB used to unlock the car), instead of starting
+ * a new association from the get call.
+ *
+ * To associate types, the Android system sets the property, passing a VehiclePropValue
+ * containing the types and values of associations being set, as defined by the
+ * UserIdentificationSetRequest. The HAL will then use a property change event (whose
+ * VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of
+ * the types after the request.
+ *
+ * For example, to query if the current user (10) is associated with the FOB that unlocked the
+ * car and a custom mechanism provided by the OEM, the request would be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 10 (Android user id)
+ * int32[2]: 0 (Android user flags)
+ * int32[3]: 2 (number of types queried)
+ * int32[4]: 1 (1st type queried, UserIdentificationAssociationType::KEY_FOB)
+ * int32[5]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)
+ *
+ * If the user is associated with the FOB but not with the custom mechanism, the response would
+ * be:
+ *
+ * int32[0]: 42 // request id
+ * int32[1]: 2 (number of associations in the response)
+ * int32[2]: 1 (1st type: UserIdentificationAssociationType::KEY_FOB)
+ * int32[3]: 2 (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+ * int32[4]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[5]: 4 (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)
+ *
+ * Then to associate the user with the custom mechanism, a set request would be made:
+ *
+ * int32[0]: 43 // request id
+ * int32[1]: 10 (Android user id)
+ * int32[2]: 0 (Android user flags)
+ * int32[3]: 1 (number of associations being set)
+ * int32[4]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[5]: 1 (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)
+ *
+ * If the request succeeded, the response would be simply:
+ *
+ * int32[0]: 43 // request id
+ * int32[1]: 1 (number of associations in the response)
+ * int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[3]: 1 (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)
+ *
+ * Notice that the set request adds associations, but doesn't remove the existing ones. In the
+ * example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to
+ * associate the user with just CUSTOM_1 but not FOB, then the request should have been:
+ *
+ * int32[0]: 43 // request id
+ * int32[1]: 10 (Android user id)
+ * int32[2]: 2 (number of types set)
+ * int32[3]: 1 (1st type: UserIdentificationAssociationType::KEY_FOB)
+ * int32[4]: 2 (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER)
+ * int32[5]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1)
+ * int32[6]: 1 (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Enable/request an EVS service.
+ *
+ * The property provides a generalized way to trigger EVS services. VHAL
+ * should use this property to request Android to start or stop EVS service.
+ *
+ * int32Values[0] = a type of the EVS service. The value must be one of enums in
+ * EvsServiceType.
+ * int32Values[1] = the state of the EVS service. The value must be one of enums in
+ * EvsServiceState.
+ *
+ * For example, to enable rear view EVS service, android side can set the property value as
+ * [EvsServiceType::REAR_VIEW, EvsServiceState::ON].
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Defines a request to apply power policy.
+ *
+ * VHAL sets this property to change car power policy. Car power policy service subscribes to
+ * this property and actually changes the power policy.
+ * The request is made by setting the VehiclePropValue with the ID of a power policy which is
+ * defined at /vendor/etc/automotive/power_policy.xml.
+ * If the given ID is not defined, car power policy service ignores the request
+ * and the current power policy is maintained.
+ *
+ * string: "sample_policy_id" // power policy ID
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Defines a request to set the power polic group used to decide a default power policy per
+ * power status transition.
+ *
+ * VHAL sets this property with the ID of a power policy group in order to set the default power
+ * policy applied at power status transition. Power policy groups are defined at
+ * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service
+ * ignores the request.
+ * Car power policy service subscribes to this property and sets the power policy group.
+ * The actual application of power policy takes place when the system power status changes and
+ * there is a valid mapped power policy for the new power status.
+ *
+ * string: "sample_policy_group_id" // power policy group ID
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Notifies the current power policy to VHAL layer.
+ *
+ * Car power policy service sets this property when the current power policy is changed.
+ *
+ * string: "sample_policy_id" // power policy ID
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
+ + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
+ /**
+ * Defines an event that car watchdog updates to tell it's alive.
+ *
+ * Car watchdog sets this property to system uptime in milliseconds at every 3 second.
+ * During the boot, the update may take longer time.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
+ + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+ /**
+ * Defines a process terminated by car watchdog and the reason of termination.
+ *
+ * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated.
+ * string: "/system/bin/log" // Process execution command.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Defines an event that VHAL signals to car watchdog as a heartbeat.
+ *
+ * If VHAL supports this property, VHAL should write system uptime to this property at every 3
+ * second. Car watchdog subscribes to this property and checks if the property is updated at
+ * every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be
+ * signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers
+ * VHAL unhealthy and terminates it.
+ * If this property is not supported by VHAL, car watchdog doesn't check VHAL health status.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
+ + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
+ /**
+ * Starts the ClusterUI in cluster display.
+ *
+ * int32: the type of ClusterUI to show
+ * 0 indicates ClusterHome, that is a home screen of cluster display, and provides
+ * the default UI and a kind of launcher functionality for cluster display.
+ * the other values are followed by OEM's definition.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Changes the state of the cluster display.
+ *
+ * Bounds: the area to render the cluster Activity.
+ * Inset: the area which Activity should avoid from placing any important
+ * information.
+ *
+ * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
+ * int32[1]: Bounds - left: positive number - left position in pixels
+ -1 - don't care (should set all Bounds fields)
+ * int32[2]: Bounds - top: same format with 'left'
+ * int32[3]: Bounds - right: same format with 'left'
+ * int32[4]: Bounds - bottom: same format with 'left'
+ * int32[5]: Inset - left: positive number - actual left inset value in pixels
+ -1 - don't care (should set "don't care" all Inset fields)
+ * int32[6]: Inset - top: same format with 'left'
+ * int32[7]: Inset - right: same format with 'left'
+ * int32[8]: Inset - bottom: same format with 'left'
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+ /**
+ * Reports the current display state and ClusterUI state.
+ *
+ * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.
+ *
+ * In addition, ClusterHome should send this message when it starts for the first time.
+ * When ClusterOS receives this message and if the internal expectation is different with the
+ * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to
+ * match the state.
+ *
+ * int32[0]: on/off: 0 - off, 1 - on
+ * int32[1]: Bounds - left
+ * int32[2]: Bounds - top
+ * int32[3]: Bounds - right
+ * int32[4]: Bounds - bottom
+ * int32[5]: Inset - left
+ * int32[6]: Inset - top
+ * int32[7]: Inset - right
+ * int32[8]: Inset - bottom
+ * int32[9]: the type of ClusterUI in the fullscreen or main screen.
+ * 0 indicates ClusterHome.
+ * the other values are followed by OEM's definition.
+ * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown.
+ * -1 indicates the area isn't used any more.
+ * bytes: the array to represent the availability of ClusterUI.
+ * 0 indicates non-available and 1 indicates available.
+ * For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
+ * and it only supports CALL UI only when the cellular network is available. Then, if the
+ * nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
+ + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
+ /**
+ * Requests to change the cluster display state to show some ClusterUI.
+ *
+ * When the current display state is off and ClusterHome sends this message to ClusterOS to
+ * request to turn the display on to show some specific ClusterUI.
+ * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
+ *
+ * int32: the type of ClusterUI to show
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Informs the current navigation state.
+ *
+ * bytes: the serialized message of NavigationStateProto.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ */
+ CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
+ + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
+ /**
+ * Electronic Toll Collection card type.
+ *
+ * This property indicates the type of ETC card in this vehicle.
+ * If the head unit is aware of an ETC card attached to the vehicle, this property should
+ * return the type of card attached; otherwise, this property should be UNAVAILABLE.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum ElectronicTollCollectionCardType
+ */
+ ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Electronic Toll Collection card status.
+ *
+ * This property indicates the status of ETC card in this vehicle.
+ * If the head unit is aware of an ETC card attached to the vehicle,
+ * ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise,
+ * this property should be UNAVAILABLE.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum ElectronicTollCollectionCardStatus
+ */
+ ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * Front fog lights state
+ *
+ * Return the current state of the front fog lights.
+ * Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented. Please refer to
+ * the documentation on FOG_LIGHTS_STATE for more information.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ FRONT_FOG_LIGHTS_STATE = 0x0F3B + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Front fog lights switch
+ *
+ * The setting that the user wants.
+ * Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented. Please refer to
+ * the documentation on FOG_LIGHTS_SWITCH for more information.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ FRONT_FOG_LIGHTS_SWITCH = 0x0F3C + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Rear fog lights state
+ *
+ * Return the current state of the rear fog lights.
+ * Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented. Please refer to
+ * the documentation on FOG_LIGHTS_STATE for more information.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleLightState
+ */
+ REAR_FOG_LIGHTS_STATE = 0x0F3D + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Rear fog lights switch
+ *
+ * The setting that the user wants.
+ * Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented. Please refer to
+ * the documentation on FOG_LIGHTS_SWITCH for more information.
+ *
+ * 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
+ * @data_enum VehicleLightSwitch
+ */
+ REAR_FOG_LIGHTS_SWITCH = 0x0F3E + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Indicates the maximum current draw threshold for charging set by the user
+ *
+ * configArray[0] is used to specify the max current draw allowed by
+ * the vehicle in Amperes.
+ *
+ * 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
+ * @unit VehicleUnit:AMPERE
+ */
+ EV_CHARGE_CURRENT_DRAW_LIMIT = 0x0F3F + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+
+ /**
+ * Indicates the maximum charge percent threshold set by the user
+ *
+ * Returns a float value from 0 to 100.
+ *
+ * configArray is used to specify the valid values.
+ * For example, if the vehicle supports the following charge percent limit values:
+ * [20, 40, 60, 80, 100]
+ * then the configArray should be {20, 40, 60, 80, 100}
+ * If the configArray is empty then all values from 0 to 100 must be valid.
+ *
+ * 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
+ */
+ EV_CHARGE_PERCENT_LIMIT = 0x0F40 + 0x10000000 + 0x01000000
+ + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
+
+ /**
+ * Charging state of the car
+ *
+ * Returns the current charging state of the car.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum EvChargeState
+ */
+ EV_CHARGE_STATE = 0x0F41 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Start or stop charging the EV battery
+ *
+ * The setting that the user wants. Setting this property to true starts the battery charging
+ * and setting to false stops charging.
+ *
+ * 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
+ */
+ EV_CHARGE_SWITCH = 0x0F42 + 0x10000000 + 0x01000000
+ + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
+
+ /**
+ * Estimated charge time remaining in seconds
+ *
+ * Returns 0 if the vehicle is not charging.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:SECS
+ */
+ EV_CHARGE_TIME_REMAINING = 0x0F43 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Regenerative braking or one-pedal drive state of the car
+ *
+ * Returns the current state associated with the regenerative braking
+ * setting in the car
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum EvRegenerativeBrakingState
+ */
+ EV_REGENERATIVE_BRAKING_STATE = 0x0F44 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Indicates if there is a trailer present or not.
+ *
+ * Returns the trailer state of the car.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum TrailerState
+ */
+ TRAILER_PRESENT = 0x0F45 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * Vehicle’s curb weight
+ *
+ * Returns the vehicle's curb weight in kilograms. Curb weight is
+ * the total weight of the vehicle with standard equipment and all
+ * necessary operating consumables such as motor oil,transmission oil,
+ * brake fluid, coolant, air conditioning refrigerant, and weight of
+ * fuel at nominal tank capacity, while not loaded with either passengers
+ * or cargo.
+ *
+ * configArray[0] is used to specify the vehicle’s gross weight in kilograms.
+ * The vehicle’s gross weight is the maximum operating weight of the vehicle
+ * as specified by the manufacturer including the vehicle's chassis, body, engine,
+ * engine fluids, fuel, accessories, driver, passengers and cargo but excluding
+ * that of any trailers.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:KILOGRAM
+ */
+
+ VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * EU's General security regulation compliance requirement.
+ *
+ * Returns whether general security regulation compliance is required, if
+ * so, what type of requirement.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ * @data_enum GsrComplianceRequirementType
+ */
+ GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 0x0F47 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
+ /**
+ * (Deprecated) List of all supported property IDs.
+ *
+ * A list of all supported property IDs (including this property). This property is required for
+ * HIDL VHAL to work with large amount of vehicle prop configs where the getAllPropConfigs
+ * payload exceeds the binder limitation. This issue is fixed in AIDL version using
+ * LargeParcelable in getAllPropConfigs, so this property is deprecated.
+ *
+ * In HIDL VHAL implementation, if the amount of data returned in getAllPropConfigs exceeds the
+ * binder limitation, vendor must support this property and return all the supported property
+ * IDs. Car service will divide this list into smaller sub lists and use getPropConfigs([ids])
+ * to query the sub lists. The results will be merged together in Car Service.
+ *
+ * The config array for this property must contain one int element which is the number of
+ * configs per getPropConfigs request by Car Service. This number must be small enough so that
+ * each getPropConfigs payload will not exceed binder limitation, however, a smaller number will
+ * cause more requests, which increase overhead to fetch all the configs.
+ *
+ * @change_mode VehiclePropertyChangeMode.STATIC
+ * @access VehiclePropertyAccess.READ
+ */
+ SUPPORTED_PROPERTY_IDS = 0x0F48 + 0x10000000 + 0x01000000
+ + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+
+ /**
+ * Request the head unit to be shutdown.
+ *
+ * <p>This usually involves telling a separate system outside the head unit (e.g. a power
+ * controller) to prepare shutting down the head unit.
+ *
+ * <p>This does not mean the head unit will shutdown immediately.
+ *
+ * <p>This means that another system will start sending a shutdown signal to the head unit,
+ * which will cause VHAL to send SHUTDOWN_PREPARE message to Android. Android will then start
+ * the shut down process by handling the message.
+ *
+ * <p>This property is only for issuing a request and only supports writing. Every time this
+ * property value is set, the request to shutdown will be issued no matter what the current
+ * property value is. The current property value is meaningless.
+ *
+ * <p>Since this property is write-only, subscribing is not allowed and no property change
+ * event will be generated.
+ *
+ * <p>The value to set indicates the shutdown option, it must be one of
+ * {@code VehicleApPowerStateShutdownParam}, e.g.,
+ * VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY. This shutdown option might not be honored
+ * if the system doesn't support such option. In such case, an error will not be returned.
+ *
+ * <p>For configuration information, VehiclePropConfig.configArray must have bit flag combining
+ * values in {@code VehicleApPowerStateConfigFlag} to indicate which shutdown options are
+ * supported.
+ *
+ * <p>Returns error if failed to send the shutdown request to the other system.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ * @data_enum VehicleApPowerStateShutdownParam
+ */
+ SHUTDOWN_REQUEST =
+ 0x0F49 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Whether the vehicle is currently in use.
+ *
+ * <p>In-use means a human user is present and is intended to use the vehicle. This doesn't
+ * necessarily means the human user is in the vehicle. For example, if the human user unlocks
+ * the vehicle remotely, the vehicle is considered in use.
+ *
+ * <p>If this property is supported:
+ *
+ * <p>Each time user powers on the vehicle or the system detects the user is present,
+ * VEHICLE_IN_USE must be set to true. Each time user powers off the vehicle or the system
+ * detects the user is not present, VEHICLE_IN_USE must be set to false.
+ *
+ * <p>This property is different than AP_POWER_BOOTUP_REASON in the sense that
+ * AP_POWER_BOOTUP_REASON is only set once during the system bootup. However, this property
+ * might change multiple times during a system bootup cycle.
+ *
+ * <p>For example, a device is currently not in use. The system bootup to execute a remote task.
+ * VEHICLE_IN_USE is false. While the remote task is executing, the user enters the vehicle and
+ * powers on the vehicle. VEHICLE_IN_USE is set to true. After a driving session, user powers
+ * off the vehicle, VEHICLE_IN_USE is set to false.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ */
+ VEHICLE_IN_USE =
+ 0x0F4A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /***********************************************************************************************
+ * Start of ADAS Properties
+ *
+ * Android is not a safety critical system and is provided as is without any timing guarantees,
+ * representations or warranties. OEMs implementing these properties, and clients using these
+ * properties should ensure they complete any necessary safety reviews, in accordance with
+ * industry standards, to ensure the use of these APIs do not negatively impact driver safety.
+ * Use of any Google APIs will be at the OEM's sole risk.
+ *
+ * Allocate IDs in range of 0x1000 (inclusive) to 0x1100 (exclusive) for ADAS properties
+ **********************************************************************************************/
+
+ /**
+ * Enable or disable Automatic Emergency Braking (AEB).
+ *
+ * Set true to enable AEB and false to disable AEB. When AEB is enabled, the ADAS system in the
+ * vehicle should be turned on and monitoring to avoid potential collisions.
+ *
+ * In general, AUTOMATIC_EMERGENCY_BRAKING_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
+ * low, that information must be conveyed through the ErrorState values in the
+ * AUTOMATIC_EMERGENCY_BRAKING_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
+ */
+ AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
+ 0x1000 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Automatic Emergency Braking (AEB) state.
+ *
+ * Returns the current state of AEB. This property must always return a valid state defined in
+ * AutomaticEmergencyBrakingState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * If AEB includes forward collision warnings before activating the brakes, those warnings must
+ * be surfaced through the Forward Collision Warning (FCW) properties.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both AutomaticEmergencyBrakingState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum AutomaticEmergencyBrakingState
+ * @data_enum ErrorState
+ */
+ AUTOMATIC_EMERGENCY_BRAKING_STATE =
+ 0x1001 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Forward Collision Warning (FCW).
+ *
+ * Set true to enable FCW and false to disable FCW. When FCW is enabled, the ADAS system in the
+ * vehicle should be turned on and monitoring for potential collisions.
+ *
+ * In general, FORWARD_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
+ * low, that information must be conveyed through the ErrorState values in the
+ * FORWARD_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
+ */
+ FORWARD_COLLISION_WARNING_ENABLED =
+ 0x1002 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Forward Collision Warning (FCW) state.
+ *
+ * Returns the current state of FCW. This property must always return a valid state defined in
+ * ForwardCollisionWarningState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both ForwardCollisionWarningState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum ForwardCollisionWarningState
+ * @data_enum ErrorState
+ */
+ FORWARD_COLLISION_WARNING_STATE =
+ 0x1003 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable and disable Blind Spot Warning (BSW).
+ *
+ * Set true to enable BSW and false to disable BSW. When BSW is enabled, the ADAS system in the
+ * vehicle should be turned on and monitoring for objects in the vehicle’s blind spots.
+ *
+ * In general, BLIND_SPOT_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 low, that
+ * information must be conveyed through the ErrorState values in the BLIND_SPOT_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
+ */
+ BLIND_SPOT_WARNING_ENABLED =
+ 0x1004 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Blind Spot Warning (BSW) state.
+ *
+ * Returns the current state of BSW. This property must always return a valid state defined in
+ * BlindSpotWarningState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * For each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both BlindSpotWarningState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum BlindSpotWarningState
+ * @data_enum ErrorState
+ */
+ BLIND_SPOT_WARNING_STATE =
+ 0x1005 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Lane Departure Warning (LDW).
+ *
+ * Set true to enable LDW and false to disable LDW. When LDW is enabled, the ADAS system in the
+ * vehicle should be turned on and monitoring if the vehicle is approaching or crossing lane
+ * lines, in which case a warning will be given.
+ *
+ * In general, LANE_DEPARTURE_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 low or too
+ * high, that information must be conveyed through the ErrorState values in the
+ * LANE_DEPARTURE_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
+ */
+ LANE_DEPARTURE_WARNING_ENABLED =
+ 0x1006 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Lane Departure Warning (LDW) state.
+ *
+ * Returns the current state of LDW. This property must always return a valid state defined in
+ * LaneDepartureWarningState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LaneDepartureWarningState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LaneDepartureWarningState
+ * @data_enum ErrorState
+ */
+ LANE_DEPARTURE_WARNING_STATE =
+ 0x1007 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Lane Keep Assist (LKA).
+ *
+ * Set true to enable LKA and false to disable LKA. When LKA is enabled, the ADAS system in the
+ * vehicle should be turned on and monitoring if the driver unintentionally drifts toward or
+ * over the lane marking. If an unintentional lane departure is detected, the system applies
+ * steering control to return the vehicle into the current lane.
+ *
+ * This is different from Lane Centering Assist (LCA) which, when activated, applies continuous
+ * steering control to keep the vehicle centered in the current lane.
+ *
+ * In general, LANE_KEEP_ASSIST_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 low or too
+ * high, that information must be conveyed through the ErrorState values in the
+ * LANE_KEEP_ASSIST_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
+ */
+ LANE_KEEP_ASSIST_ENABLED =
+ 0x1008 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Lane Keep Assist (LKA) state.
+ *
+ * Returns the current state of LKA. This property must always return a valid state defined in
+ * LaneKeepAssistState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * If LKA includes lane departure warnings before applying steering corrections, those warnings
+ * must be surfaced through the Lane Departure Warning (LDW) properties.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LaneKeepAssistState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LaneKeepAssistState
+ * @data_enum ErrorState
+ */
+ LANE_KEEP_ASSIST_STATE =
+ 0x1009 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Lane Centering Assist (LCA).
+ *
+ * Set true to enable LCA and false to disable LCA. When LCA is enabled, the ADAS system in the
+ * vehicle should be turned on and waiting for an activation signal from the driver. Once the
+ * feature is activated, the ADAS system should be steering the vehicle to keep it centered in
+ * its current lane.
+ *
+ * This is different from Lane Keep Assist (LKA) which monitors if the driver unintentionally
+ * drifts toward or over the lane marking. If an unintentional lane departure is detected, the
+ * system applies steering control to return the vehicle into the current lane.
+ *
+ * In general, LANE_CENTERING_ASSIST_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 low or too
+ * high, that information must be conveyed through the ErrorState values in the
+ * LANE_CENTERING_ASSIST_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
+ */
+ LANE_CENTERING_ASSIST_ENABLED =
+ 0x100A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Lane Centering Assist (LCA) commands.
+ *
+ * Commands to activate and suspend LCA. They are only valid when LANE_CENTERING_ASSIST_ENABLED
+ * = true. Otherwise, these commands must return StatusCode#NOT_AVAILABLE or
+ * StatusCode#NOT_AVAILABLE_DISABLED.
+ *
+ * When the command ACTIVATE from LaneCenteringAssistCommmand is sent,
+ * LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ACTIVATION_REQUESTED.
+ * When the ACTIVATE command succeeds, LANE_CENTERING_ASSIST_STATE must be set to
+ * LaneCenteringAssistState#ACTIVATED. When the command DEACTIVATE from
+ * LaneCenteringAssistCommmand succeeds, LANE_CENTERING_ASSIST_STATE must be set to
+ * LaneCenteringAssistState#ENABLED.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
+ * all enum values of LaneCenteringAssistCommand are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ * @data_enum LaneCenteringAssistCommmand
+ */
+ LANE_CENTERING_ASSIST_COMMAND =
+ 0x100B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Lane Centering Assist (LCA) state.
+ *
+ * Returns the current state of LCA. This property must always return a valid state defined in
+ * LaneCenteringAssistState or ErrorState. It must not surface errors through StatusCode
+ * and must use the supported error states instead.
+ *
+ * If LCA includes lane departure warnings, those warnings must be surfaced through the Lane
+ * Departure Warning (LDW) properties.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LaneCenteringAssistState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LaneCenteringAssistState
+ * @data_enum ErrorState
+ */
+ LANE_CENTERING_ASSIST_STATE =
+ 0x100C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /*
+ * Enable or disable Emergency Lane Keep Assist (ELKA).
+ *
+ * Set true to enable ELKA and false to disable ELKA. When ELKA is enabled, the ADAS system in
+ * the vehicle should be on and monitoring for unsafe lane changes by the driver. When an unsafe
+ * maneuver is detected, ELKA alerts the driver and applies steering corrections to keep the
+ * vehicle in its original lane.
+ *
+ * In general, EMERGENCY_LANE_KEEP_ASSIST_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
+ * low, that information must be conveyed through the ErrorState values in the
+ * EMERGENCY_LANE_KEEP_ASSIST_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
+ */
+ EMERGENCY_LANE_KEEP_ASSIST_ENABLED =
+ 0x100D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Emergency Lane Keep Assist (ELKA) state.
+ *
+ * Returns the current state of ELKA. Generally, this property should return a valid state
+ * defined in the EmergencyLaneKeepAssistState or ErrorState. For example, if the feature is not
+ * available due to some temporary state, that information should be conveyed through
+ * ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of EmergencyLaneKeepAssistState (including OTHER, which is not recommended)
+ * and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum EmergencyLaneKeepAssistState
+ * @data_enum ErrorState
+ */
+ EMERGENCY_LANE_KEEP_ASSIST_STATE =
+ 0x100E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable cruise control (CC).
+ *
+ * Set true to enable CC and false to disable CC. This property is shared by all forms of
+ * CruiseControlType(s).
+ *
+ * When CC is enabled, the ADAS system in the vehicle should be turned on and responding to
+ * commands.
+ *
+ * In general, CRUISE_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 low, that
+ * information must be conveyed through the ErrorState values in the CRUISE_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
+ */
+ CRUISE_CONTROL_ENABLED =
+ 0x100F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Current type of Cruise Control (CC).
+ *
+ * When CRUISE_CONTROL_ENABLED is true, this property returns the type of CC that is currently
+ * enabled (for example, standard CC, adaptive CC, predictive CC, etc.). Generally, this
+ * property should return a valid state defined in the CruiseControlType or ErrorState. For
+ * example, if the feature is not available due to some temporary state, that information should
+ * be conveyed through ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of CruiseControlType (including OTHER, which is not recommended) and
+ * ErrorState are supported.
+ *
+ * Trying to write CruiseControlType#OTHER or an ErrorState to this property will throw an
+ * IllegalArgumentException.
+ *
+ * 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
+ * @data_enum CruiseControlType
+ * @data_enum ErrorState
+ */
+ CRUISE_CONTROL_TYPE =
+ 0x1010 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Current state of Cruise Control (CC).
+ *
+ * This property returns the current state of CC. Generally, this property should return a valid
+ * state defined in the CruiseControlState or ErrorState. For example, if the feature is not
+ * available due to some temporary state, that information should be conveyed through
+ * ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of CruiseControlState (including OTHER, which is not recommended) and
+ * ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum CruiseControlState
+ * @data_enum ErrorState
+ */
+ CRUISE_CONTROL_STATE =
+ 0x1011 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Write Cruise Control (CC) commands.
+ *
+ * See CruiseControlCommand for the details about each supported command.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of CruiseControlState are supported. Any unsupported commands sent through
+ * this property must return StatusCode#INVALID_ARG.
+ *
+ * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+ * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.WRITE
+ * @data_enum CruiseControlCommand
+ */
+ CRUISE_CONTROL_COMMAND =
+ 0x1012 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Current target speed for Cruise Control (CC).
+ *
+ * OEMs should set the minInt32Value and maxInt32Value values for this property to define the
+ * min and max target speed values. These values must be non-negative.
+ *
+ * The maxFloatValue represents the upper bound of the target speed.
+ * The minFloatValue represents the lower bound of the target speed.
+ *
+ * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+ * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:METER_PER_SEC
+ */
+ CRUISE_CONTROL_TARGET_SPEED =
+ 0x1013 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+
+ /**
+ * Current target time gap for Adaptive Cruise Control (ACC) or Predictive Cruise Control in
+ * milliseconds.
+ *
+ * This property should specify the target time gap to a leading vehicle. This gap is defined as
+ * the time to travel the distance between the leading vehicle's rear-most point to the ACC
+ * vehicle's front-most point. The actual time gap from a leading vehicle can be above or below
+ * this value.
+ *
+ * The possible values to set for the target time gap should be specified in configArray in
+ * ascending order. All values must be positive. If the property is writable, all values must be
+ * writable.
+ *
+ * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+ * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+ *
+ * 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
+ * @unit VehicleUnit:MILLI_SECS
+ */
+ ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP =
+ 0x1014 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Measured distance from leading vehicle when using Adaptive Cruise Control (ACC) or
+ * Predictive Cruise Control.
+ *
+ * Returns the measured distance in millimeters between the rear-most point of the leading
+ * vehicle and the front-most point of the ACC vehicle.
+ *
+ * The minInt32Value should be 0.
+ * The maxInt32Value should be populated with the maximum range the distance sensor can support.
+ * This value should be non-negative.
+ *
+ * When no lead vehicle is detected (that is, when there is no leading vehicle or the leading
+ * vehicle is too far away for the sensor to detect), this property should return
+ * StatusCode.NOT_AVAILABLE.
+ *
+ * When this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is
+ * false), this property must return StatusCode#NOT_AVAILABLE_DISABLED.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:MILLIMETER
+ */
+ ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE =
+ 0x1015 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Hands On Detection (HOD).
+ *
+ * Set true to enable HOD and false to disable HOD. When HOD is enabled, a system inside the
+ * vehicle should be monitoring the presence of the driver's hands on the steering wheel and
+ * send a warning if it detects that the driver's hands are no longer on the steering wheel.
+ *
+ * In general, HANDS_ON_DETECTION_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 HANDS_ON_DETECTION_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
+ */
+ HANDS_ON_DETECTION_ENABLED =
+ 0x1016 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Hands On Detection (HOD) driver state.
+ *
+ * Returns whether the driver's hands are on the steering wheel. Generally, this property should
+ * return a valid state defined in the HandsOnDetectionDriverState 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 wants to send a warning to the user because the driver's hands have been off
+ * the steering wheel for too long, the warning should be surfaced through
+ * HANDS_ON_DETECTION_WARNING.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both HandsOnDetectionDriverState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum HandsOnDetectionDriverState
+ * @data_enum ErrorState
+ */
+ HANDS_ON_DETECTION_DRIVER_STATE =
+ 0x1017 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Hands On Detection (HOD) warning.
+ *
+ * Returns whether a warning is being sent to the driver for having their hands off the wheel
+ * for too long a duration.
+ *
+ * Generally, this property should return a valid state defined in HandsOnDetectionWarning 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 HandsOnDetectionWarning (including OTHER, which is not recommended)
+ * and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum HandsOnDetectionWarning
+ * @data_enum ErrorState
+ */
+ HANDS_ON_DETECTION_WARNING =
+ 0x1018 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /***************************************************************************
+ * End of ADAS Properties
+ **************************************************************************/
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyGroup.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyType.aidl
new file mode 100644
index 0000000..7a68b4a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehiclePropertyType.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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Enumerates supported data type for VehicleProperty.
+ *
+ * Used to create property ID in VehicleProperty enum.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehiclePropertyType {
+ STRING = 0x00100000,
+ /**
+ * Boolean values should be specified through the int32Values in RawPropValues.
+ * int32Value = {0} represents false and int32Value = {1} represents true.
+ */
+ BOOLEAN = 0x00200000,
+ INT32 = 0x00400000,
+ INT32_VEC = 0x00410000,
+ INT64 = 0x00500000,
+ INT64_VEC = 0x00510000,
+ FLOAT = 0x00600000,
+ FLOAT_VEC = 0x00610000,
+ BYTES = 0x00700000,
+
+ /**
+ * Any combination of scalar or vector types. The exact format must be
+ * provided in the description of the property.
+ *
+ * For vendor MIXED type properties, configArray needs to be formatted in this
+ * structure.
+ * configArray[0], 1 indicates the property has a String value
+ * configArray[1], 1 indicates the property has a Boolean value .
+ * configArray[2], 1 indicates the property has an Integer value.
+ * configArray[3], the number indicates the size of Integer[] in the property.
+ * configArray[4], 1 indicates the property has a Long value.
+ * configArray[5], the number indicates the size of Long[] in the property.
+ * configArray[6], 1 indicates the property has a Float value.
+ * configArray[7], the number indicates the size of Float[] in the property.
+ * configArray[8], the number indicates the size of byte[] in the property.
+ * For example:
+ * {@code configArray = {1, 1, 1, 3, 0, 0, 0, 0, 0}} indicates the property has
+ * a String value, a Boolean value, an Integer value and an array with 3 integers.
+ */
+ MIXED = 0x00e00000,
+
+ MASK = 0x00ff0000,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleTurnSignal.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleUnit.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleUnit.aidl
new file mode 100644
index 0000000..d4f9086
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleUnit.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Units used for int or float type with no attached enum types.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleUnit {
+ SHOULD_NOT_USE = 0x000,
+ METER_PER_SEC = 0x01,
+ RPM = 0x02,
+ HERTZ = 0x03,
+ PERCENTILE = 0x10,
+ MILLIMETER = 0x20,
+ METER = 0x21,
+ KILOMETER = 0x23,
+ MILE = 0x24,
+ CELSIUS = 0x30,
+ FAHRENHEIT = 0x31,
+ KELVIN = 0x32,
+ MILLILITER = 0x40,
+ LITER = 0x41,
+ /**
+ * deprecated. Use US_GALLON instead.
+ */
+ GALLON = 0x42,
+ US_GALLON = 0x42,
+ IMPERIAL_GALLON = 0x43,
+ NANO_SECS = 0x50,
+ MILLI_SECS = 0x51,
+ SECS = 0x53,
+ YEAR = 0x59,
+ WATT_HOUR = 0x60,
+ MILLIAMPERE = 0x61,
+ MILLIVOLT = 0x62,
+ MILLIWATTS = 0x63,
+ AMPERE_HOURS = 0x64,
+ KILOWATT_HOUR = 0x65,
+ AMPERE = 0x66,
+ KILOPASCAL = 0x70,
+ PSI = 0x71,
+ BAR = 0x72,
+ DEGREES = 0x80,
+ MILES_PER_HOUR = 0x90,
+ KILOMETERS_PER_HOUR = 0x91,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleVendorPermission.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsAvailabilityStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsBaseMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageType.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageType.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageType.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsMessageWithLayerIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsOfferingMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsPublisherInformationIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsStartSessionMessageIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
similarity index 100%
rename from automotive/vehicle/aidl/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
rename to automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VmsSubscriptionsStateIntegerValuesIndex.aidl
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
new file mode 100644
index 0000000..820fcc8
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.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.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of VehicleProperty#WINDSHIELD_WIPERS_STATE.
+ */
+@VintfStability
+@Backing(type="int")
+enum WindshieldWipersState {
+
+ /**
+ * This state is used as an alternative for any WindshieldWipersState value that is not defined
+ * in the platform. Ideally, implementations of VehicleProperty#WINDSHIELD_WIPERS_STATE should
+ * not use this state. The framework can use this field to remain backwards compatible if
+ * WindshieldWipersState is extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * This state indicates the windshield wipers are currently off. If
+ * VehicleProperty#WINDSHIELD_WIPERS_SWITCH is implemented, then it may be set to any of the
+ * following modes: OFF or AUTO.
+ */
+ OFF = 1,
+ /**
+ * This state indicates the windshield wipers are currently on. If
+ * VehicleProperty#WINDSHIELD_WIPERS_SWITCH is implemented, then it may be set to any of the
+ * following modes: MIST, INTERMITTENT_LEVEL_*, CONTINUOUS_LEVEL_*, or AUTO.
+ */
+ ON = 2,
+ /**
+ * Windshield wipers are in the service mode.
+ */
+ SERVICE = 3,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
new file mode 100644
index 0000000..911d7eb
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.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.automotive.vehicle;
+
+/**
+ * Used to enumerate the current position of VehicleProperty#WINDSHIELD_WIPERS_SWITCH.
+ */
+@VintfStability
+@Backing(type="int")
+enum WindshieldWipersSwitch {
+
+ /**
+ * This value is used as an alternative for any WindshieldWipersSwitch value that is not defined
+ * in the platform. Ideally, implementations of VehicleProperty#WINDSHIELD_WIPERS_SWITCH should
+ * not use this value. The framework can use this field to remain backwards compatible if
+ * WindshieldWipersSwitch is extended to include additional values.
+ */
+ OTHER = 0,
+ /**
+ * The windshield wipers switch is set to the off position.
+ */
+ OFF = 1,
+ /**
+ * MIST mode performs a single wipe, and then returns to the OFF position.
+ */
+ MIST = 2,
+ /**
+ * INTERMITTENT_LEVEL_* modes performs intermittent wiping. As the level increases, the
+ * intermittent time period decreases.
+ */
+ INTERMITTENT_LEVEL_1 = 3,
+ INTERMITTENT_LEVEL_2 = 4,
+ INTERMITTENT_LEVEL_3 = 5,
+ INTERMITTENT_LEVEL_4 = 6,
+ INTERMITTENT_LEVEL_5 = 7,
+ /**
+ * CONTINUOUS_LEVEL_* modes performs continuous wiping. As the level increases the speed of the
+ * wiping increases as well.
+ */
+ CONTINUOUS_LEVEL_1 = 8,
+ CONTINUOUS_LEVEL_2 = 9,
+ CONTINUOUS_LEVEL_3 = 10,
+ CONTINUOUS_LEVEL_4 = 11,
+ CONTINUOUS_LEVEL_5 = 12,
+ /**
+ * AUTO allows the vehicle to decide the required wiping level based on the exterior weather
+ * conditions.
+ */
+ AUTO = 13,
+ /**
+ * Windshield wipers are set to the service mode.
+ */
+ SERVICE = 14,
+}
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
new file mode 100644
index 0000000..c36cbb0
--- /dev/null
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -0,0 +1,245 @@
+#!/usr/bin/python
+
+# 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.
+#
+"""A script to generate Java files and CPP header files based on annotations in VehicleProperty.aidl
+
+ Need ANDROID_BUILD_TOP environmental variable to be set. This script will update
+ ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/cpp and
+ ChangeModeForVehicleProperty.java and AccessForVehicleProperty.java under generated_lib/java.
+
+ Usage:
+ $ python generate_annotation_enums.py
+"""
+import os
+import re
+import sys
+
+PROP_AIDL_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/" +
+ "automotive/vehicle/VehicleProperty.aidl")
+CHANGE_MODE_CPP_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/" +
+ "ChangeModeForVehicleProperty.h")
+ACCESS_CPP_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/" +
+ "AccessForVehicleProperty.h")
+CHANGE_MODE_JAVA_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/" +
+ "ChangeModeForVehicleProperty.java")
+ACCESS_JAVA_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/" +
+ "AccessForVehicleProperty.java")
+
+TAB = " "
+RE_ENUM_START = re.compile("\s*enum VehicleProperty \{")
+RE_ENUM_END = re.compile("\s*\}\;")
+RE_COMMENT_BEGIN = re.compile("\s*\/\*\*?")
+RE_COMMENT_END = re.compile("\s*\*\/")
+RE_CHANGE_MODE = re.compile("\s*\* @change_mode (\S+)\s*")
+RE_ACCESS = re.compile("\s*\* @access (\S+)\s*")
+RE_VALUE = re.compile("\s*(\w+)\s*=(.*)")
+
+LICENSE = """/*
+ * 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.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+"""
+
+CHANGE_MODE_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
+"""
+
+CHANGE_MODE_CPP_FOOTER = """
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // aidl
+
+#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+"""
+
+ACCESS_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
+"""
+
+ACCESS_CPP_FOOTER = """
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // aidl
+
+#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+"""
+
+CHANGE_MODE_JAVA_HEADER = """package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class ChangeModeForVehicleProperty {
+
+ public static final Map<Integer, Integer> values = Map.ofEntries(
+"""
+
+CHANGE_MODE_JAVA_FOOTER = """
+ );
+
+}
+"""
+
+ACCESS_JAVA_HEADER = """package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class AccessForVehicleProperty {
+
+ public static final Map<Integer, Integer> values = Map.ofEntries(
+"""
+
+ACCESS_JAVA_FOOTER = """
+ );
+
+}
+"""
+
+
+class Converter:
+
+ def __init__(self, name, annotation_re):
+ self.name = name
+ self.annotation_re = annotation_re
+
+ def convert(self, input, output, header, footer, cpp):
+ processing = False
+ in_comment = False
+ content = LICENSE + header
+ annotation = None
+ id = 0
+ with open(input, 'r') as f:
+ for line in f.readlines():
+ if RE_ENUM_START.match(line):
+ processing = True
+ annotation = None
+ elif RE_ENUM_END.match(line):
+ processing = False
+ if not processing:
+ continue
+ if RE_COMMENT_BEGIN.match(line):
+ in_comment = True
+ if RE_COMMENT_END.match(line):
+ in_comment = False
+ if in_comment:
+ match = self.annotation_re.match(line)
+ if match:
+ annotation = match.group(1)
+ else:
+ match = RE_VALUE.match(line)
+ if match:
+ prop_name = match.group(1)
+ if prop_name == "INVALID":
+ continue
+ if not annotation:
+ print("No @" + self.name + " annotation for property: " + prop_name)
+ sys.exit(1)
+ if id != 0:
+ content += "\n"
+ if cpp:
+ annotation = annotation.replace(".", "::")
+ content += (TAB + TAB + "{VehicleProperty::" + prop_name + ", " +
+ annotation + "},")
+ else:
+ content += (TAB + TAB + "Map.entry(VehicleProperty." + prop_name + ", " +
+ annotation + "),")
+ id += 1
+
+ # Remove the additional "," at the end for the Java file.
+ if not cpp:
+ content = content[:-1]
+
+ content += footer
+
+ with open(output, 'w') as f:
+ f.write(content)
+
+
+def main():
+ android_top = os.environ['ANDROID_BUILD_TOP']
+ if not android_top:
+ print("ANDROID_BUILD_TOP is not in envorinmental variable, please run source and lunch " +
+ "at the android root")
+
+ aidl_file = os.path.join(android_top, PROP_AIDL_FILE_PATH)
+ change_mode_cpp_output = os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH);
+ access_cpp_output = os.path.join(android_top, ACCESS_CPP_FILE_PATH);
+ change_mode_java_output = os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH);
+ access_java_output = os.path.join(android_top, ACCESS_JAVA_FILE_PATH);
+
+ c = Converter("change_mode", RE_CHANGE_MODE);
+ c.convert(aidl_file, change_mode_cpp_output, CHANGE_MODE_CPP_HEADER, CHANGE_MODE_CPP_FOOTER, True)
+ c.convert(aidl_file, change_mode_java_output, CHANGE_MODE_JAVA_HEADER, CHANGE_MODE_JAVA_FOOTER, False)
+ c = Converter("access", RE_ACCESS)
+ c.convert(aidl_file, access_cpp_output, ACCESS_CPP_HEADER, ACCESS_CPP_FOOTER, True)
+ c.convert(aidl_file, access_java_output, ACCESS_JAVA_HEADER, ACCESS_JAVA_FOOTER, False)
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/automotive/vehicle/vhal_static_cpp_lib.mk b/automotive/vehicle/vhal_static_cpp_lib.mk
new file mode 100644
index 0000000..995589c
--- /dev/null
+++ b/automotive/vehicle/vhal_static_cpp_lib.mk
@@ -0,0 +1,20 @@
+# 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 make file contains the latest version of static cpp libraries for VHAL
+# interface and VHAL properties.
+
+LOCAL_STATIC_LIBRARIES += \
+ android.hardware.automotive.vehicle-V2-ndk \
+ android.hardware.automotive.vehicle.property-V2-ndk
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index b78e0ff..736787b 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -44,6 +44,8 @@
test_suites: [
"general-tests",
"vts",
+ "automotive-tests",
+ "automotive-general-tests",
],
require_root: true,
}
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index c431d85..8bcad1e 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -44,10 +44,13 @@
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
using ::android::getAidlHalInstanceNames;
using ::android::base::ScopedLockAssertion;
using ::android::base::StringPrintf;
+using ::android::frameworks::automotive::vhal::ErrorCode;
using ::android::frameworks::automotive::vhal::HalPropError;
using ::android::frameworks::automotive::vhal::IHalPropConfig;
using ::android::frameworks::automotive::vhal::IHalPropValue;
@@ -113,6 +116,9 @@
class VtsHalAutomotiveVehicleTargetTest : public testing::TestWithParam<ServiceDescriptor> {
public:
+ void verifyProperty(VehicleProperty propId, VehiclePropertyAccess access,
+ VehiclePropertyChangeMode changeMode, VehiclePropertyGroup group,
+ VehicleArea area, VehiclePropertyType propertyType);
virtual void SetUp() override {
auto descriptor = GetParam();
if (descriptor.isAidlService) {
@@ -287,7 +293,31 @@
auto setValueResult = mVhalClient->setValueSync(*getValueResult.value());
ASSERT_FALSE(setValueResult.ok()) << "Expect set a read-only value to fail";
- ASSERT_EQ(setValueResult.error().code(), StatusCode::ACCESS_DENIED);
+ ASSERT_EQ(setValueResult.error().code(), ErrorCode::ACCESS_DENIED_FROM_VHAL);
+}
+
+// Test get(), set() and getAllPropConfigs() on VehicleProperty::INVALID.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, getSetPropertyIdInvalid) {
+ ALOGD("VtsHalAutomotiveVehicleTargetTest::getSetPropertyIdInvalid");
+
+ int32_t propId = toInt(VehicleProperty::INVALID);
+ auto getValueResult = mVhalClient->getValueSync(*mVhalClient->createHalPropValue(propId));
+ ASSERT_FALSE(getValueResult.ok()) << "Expect get on VehicleProperty::INVALID to fail";
+ ASSERT_EQ(getValueResult.error().code(), ErrorCode::INVALID_ARG);
+
+ auto propToSet = mVhalClient->createHalPropValue(propId);
+ propToSet->setInt32Values({0});
+ auto setValueResult = mVhalClient->setValueSync(*propToSet);
+ ASSERT_FALSE(setValueResult.ok()) << "Expect set on VehicleProperty::INVALID to fail";
+ ASSERT_EQ(setValueResult.error().code(), ErrorCode::INVALID_ARG);
+
+ auto result = mVhalClient->getAllPropConfigs();
+ ASSERT_TRUE(result.ok());
+ for (const auto& cfgPtr : result.value()) {
+ const IHalPropConfig& cfg = *cfgPtr;
+ ASSERT_FALSE(cfg.getPropId() == propId) << "Expect VehicleProperty::INVALID to not be "
+ "included in propConfigs";
+ }
}
// Test subscribe() and unsubscribe().
@@ -419,6 +449,422 @@
}
}
+// Helper function to compare actual vs expected property config
+void VtsHalAutomotiveVehicleTargetTest::verifyProperty(VehicleProperty propId,
+ VehiclePropertyAccess access,
+ VehiclePropertyChangeMode changeMode,
+ VehiclePropertyGroup group, VehicleArea area,
+ VehiclePropertyType propertyType) {
+ int expectedPropId = toInt(propId);
+ int expectedAccess = toInt(access);
+ int expectedChangeMode = toInt(changeMode);
+ int expectedGroup = toInt(group);
+ int expectedArea = toInt(area);
+ int expectedPropertyType = toInt(propertyType);
+
+ auto result = mVhalClient->getAllPropConfigs();
+ ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
+ << result.error().message();
+
+ // Check if property is implemented by getting all configs and looking to see if the expected
+ // property id is in that list.
+ bool isExpectedPropIdImplemented = false;
+ for (const auto& cfgPtr : result.value()) {
+ const IHalPropConfig& cfg = *cfgPtr;
+ if (expectedPropId == cfg.getPropId()) {
+ isExpectedPropIdImplemented = true;
+ break;
+ }
+ }
+
+ if (!isExpectedPropIdImplemented) {
+ GTEST_SKIP() << StringPrintf("Property %" PRId32 " has not been implemented",
+ expectedPropId);
+ }
+
+ result = mVhalClient->getPropConfigs({expectedPropId});
+ ASSERT_TRUE(result.ok()) << "Failed to get required property config, error: "
+ << result.error().message();
+
+ ASSERT_EQ(result.value().size(), 1u)
+ << StringPrintf("Expect to get exactly 1 config, got %zu", result.value().size());
+
+ const auto& config = result.value().at(0);
+ int actualPropId = config->getPropId();
+ int actualAccess = config->getAccess();
+ int actualChangeMode = config->getChangeMode();
+ int actualGroup = actualPropId & toInt(VehiclePropertyGroup::MASK);
+ int actualArea = actualPropId & toInt(VehicleArea::MASK);
+ int actualPropertyType = actualPropId & toInt(VehiclePropertyType::MASK);
+
+ ASSERT_EQ(actualPropId, expectedPropId)
+ << StringPrintf("Expect to get property ID: %i, got %i", expectedPropId, actualPropId);
+
+ if (expectedAccess == toInt(VehiclePropertyAccess::READ_WRITE)) {
+ ASSERT_TRUE(actualAccess == expectedAccess ||
+ actualAccess == toInt(VehiclePropertyAccess::READ))
+ << StringPrintf("Expect to get VehiclePropertyAccess: %i or %i, got %i",
+ expectedAccess, toInt(VehiclePropertyAccess::READ), actualAccess);
+ } else {
+ ASSERT_EQ(actualAccess, expectedAccess) << StringPrintf(
+ "Expect to get VehiclePropertyAccess: %i, got %i", expectedAccess, actualAccess);
+ }
+
+ ASSERT_EQ(actualChangeMode, expectedChangeMode)
+ << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
+ expectedChangeMode, actualChangeMode);
+ ASSERT_EQ(actualGroup, expectedGroup) << StringPrintf(
+ "Expect to get VehiclePropertyGroup: %i, got %i", expectedGroup, actualGroup);
+ ASSERT_EQ(actualArea, expectedArea)
+ << StringPrintf("Expect to get VehicleArea: %i, got %i", expectedArea, actualArea);
+ ASSERT_EQ(actualPropertyType, expectedPropertyType)
+ << StringPrintf("Expect to get VehiclePropertyType: %i, got %i", expectedPropertyType,
+ actualPropertyType);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLocationCharacterizationConfig) {
+ verifyProperty(VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistEnabledConfig) {
+ verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEmergencyLaneKeepAssistStateConfig) {
+ verifyProperty(VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlEnabledConfig) {
+ verifyProperty(VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlTypeConfig) {
+ verifyProperty(VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlStateConfig) {
+ verifyProperty(VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlCommandConfig) {
+ verifyProperty(VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyAccess::WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyCruiseControlTargetSpeedConfig) {
+ verifyProperty(VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAdaptiveCruiseControlTargetTimeGapConfig) {
+ verifyProperty(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest,
+ verifyAdaptiveCruiseControlLeadVehicleMeasuredDistanceConfig) {
+ verifyProperty(VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::CONTINUOUS,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionEnabledConfig) {
+ verifyProperty(VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionDriverStateConfig) {
+ verifyProperty(VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyHandsOnDetectionWarningConfig) {
+ verifyProperty(VehicleProperty::HANDS_ON_DETECTION_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,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvStoppingModeConfig) {
+ verifyProperty(VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvCurrentBatteryCapacityConfig) {
+ verifyProperty(VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEngineIdleAutoStopEnabledConfig) {
+ verifyProperty(VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDoorChildLockEnabledConfig) {
+ verifyProperty(VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::DOOR, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyWindshieldWipersPeriodConfig) {
+ verifyProperty(VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::WINDOW, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyWindshieldWipersStateConfig) {
+ verifyProperty(VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::WINDOW, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyWindshieldWipersSwitchConfig) {
+ verifyProperty(VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::WINDOW, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelDepthPosConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelDepthMoveConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelHeightPosConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelHeightMoveConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelTheftLockEnabledConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLockedConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelEasyAccessEnabledConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLightsStateConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySteeringWheelLightsSwitchConfig) {
+ verifyProperty(VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyGloveBoxDoorPosConfig) {
+ verifyProperty(VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyGloveBoxLockedConfig) {
+ verifyProperty(VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyMirrorAutoFoldEnabledConfig) {
+ verifyProperty(VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::MIRROR, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyMirrorAutoTiltEnabledConfig) {
+ verifyProperty(VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::MIRROR, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatHeadrestHeightPosV2Config) {
+ verifyProperty(VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatWalkInPosConfig) {
+ verifyProperty(VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatFootwellLightsStateConfig) {
+ verifyProperty(VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatFootwellLightsSwitchConfig) {
+ verifyProperty(VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatEasyAccessEnabledConfig) {
+ verifyProperty(VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatAirbagEnabledConfig) {
+ verifyProperty(VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatCushionSideSupportPosConfig) {
+ verifyProperty(VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatCushionSideSupportMoveConfig) {
+ verifyProperty(VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatLumbarVerticalPosConfig) {
+ verifyProperty(VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatLumbarVerticalMoveConfig) {
+ verifyProperty(VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAutomaticEmergencyBrakingEnabledConfig) {
+ verifyProperty(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAutomaticEmergencyBrakingStateConfig) {
+ verifyProperty(VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyForwardCollisionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyForwardCollisionWarningStateConfig) {
+ verifyProperty(VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBlindSpotWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBlindSpotWarningStateConfig) {
+ verifyProperty(VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::MIRROR, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneDepartureWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneDepartureWarningStateConfig) {
+ verifyProperty(VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneKeepAssistEnabledConfig) {
+ verifyProperty(VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneKeepAssistStateConfig) {
+ verifyProperty(VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistEnabledConfig) {
+ verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistCommandConfig) {
+ verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess::WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLaneCenteringAssistStateConfig) {
+ verifyProperty(VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
std::vector<ServiceDescriptor> getDescriptors() {
std::vector<ServiceDescriptor> descriptors;
for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) {
diff --git a/biometrics/OWNERS b/biometrics/OWNERS
new file mode 100644
index 0000000..e162d2d
--- /dev/null
+++ b/biometrics/OWNERS
@@ -0,0 +1,4 @@
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index 0f795f8..88edf04 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: {
@@ -32,7 +32,5 @@
version: "2",
imports: [],
},
-
],
-
}
diff --git a/biometrics/common/aidl/OWNERS b/biometrics/common/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/common/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
[email protected]
[email protected]
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/AuthenticateReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/AuthenticateReason.aidl
new file mode 100644
index 0000000..f639ead
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/AuthenticateReason.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.common;
+/* @hide */
+@VintfStability
+union AuthenticateReason {
+ android.hardware.biometrics.common.AuthenticateReason.Vendor vendorAuthenticateReason;
+ android.hardware.biometrics.common.AuthenticateReason.Face faceAuthenticateReason;
+ android.hardware.biometrics.common.AuthenticateReason.Fingerprint fingerprintAuthenticateReason;
+ @VintfStability
+ parcelable Vendor {
+ ParcelableHolder extension;
+ }
+ @Backing(type="int") @VintfStability
+ enum Fingerprint {
+ UNKNOWN,
+ }
+ @Backing(type="int") @VintfStability
+ enum Face {
+ UNKNOWN,
+ STARTED_WAKING_UP,
+ PRIMARY_BOUNCER_SHOWN,
+ ASSISTANT_VISIBLE,
+ ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
+ NOTIFICATION_PANEL_CLICKED,
+ OCCLUDING_APP_REQUESTED,
+ PICK_UP_GESTURE_TRIGGERED,
+ QS_EXPANDED,
+ SWIPE_UP_ON_BOUNCER,
+ UDFPS_POINTER_DOWN,
+ }
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
index d4433c5..1eb8541 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
parcelable CommonProps {
int sensorId;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
index ad11dda..471ed2b 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
parcelable ComponentInfo {
String componentId;
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/DisplayState.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/DisplayState.aidl
new file mode 100644
index 0000000..176e8d6
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/DisplayState.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.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DisplayState {
+ UNKNOWN,
+ LOCKSCREEN,
+ NO_UI,
+ SCREENSAVER,
+ AOD,
+}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
index 2bc6a6d..670114f 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
interface ICancellationSignal {
oneway void cancel();
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
index 9d1cb8f..378017e 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
@@ -32,10 +32,17 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@VintfStability
parcelable OperationContext {
int id = 0;
android.hardware.biometrics.common.OperationReason reason = android.hardware.biometrics.common.OperationReason.UNKNOWN;
+ /**
+ * @deprecated use displayState instead.
+ */
boolean isAod = false;
boolean isCrypto = false;
+ android.hardware.biometrics.common.WakeReason wakeReason = android.hardware.biometrics.common.WakeReason.UNKNOWN;
+ android.hardware.biometrics.common.DisplayState displayState = android.hardware.biometrics.common.DisplayState.UNKNOWN;
+ @nullable android.hardware.biometrics.common.AuthenticateReason authenticateReason;
}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
index 3da3a6a..188054a 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
@@ -32,9 +32,10 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@Backing(type="byte") @VintfStability
enum OperationReason {
- UNKNOWN = 0,
- BIOMETRIC_PROMPT = 1,
- KEYGUARD = 2,
+ UNKNOWN,
+ BIOMETRIC_PROMPT,
+ KEYGUARD,
}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
index 6675d09..c931781 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
@@ -32,9 +32,10 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.common;
+/* @hide */
@Backing(type="byte") @VintfStability
enum SensorStrength {
- CONVENIENCE = 0,
- WEAK = 1,
- STRONG = 2,
+ CONVENIENCE,
+ WEAK,
+ STRONG,
}
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/WakeReason.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/WakeReason.aidl
new file mode 100644
index 0000000..6a08776
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/WakeReason.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.biometrics.common;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum WakeReason {
+ UNKNOWN,
+ POWER_BUTTON,
+ GESTURE,
+ WAKE_KEY,
+ WAKE_MOTION,
+ LID,
+ DISPLAY_GROUP_ADDED,
+ TAP,
+ LIFT,
+ BIOMETRIC,
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/AuthenticateReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/AuthenticateReason.aidl
new file mode 100644
index 0000000..fcf5294
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/AuthenticateReason.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.
+ */
+
+package android.hardware.biometrics.common;
+
+/**
+ * Reason for an authenticate operation.
+ *
+ * @hide
+ */
+@VintfStability
+union AuthenticateReason {
+ /** Vendor reason for invoking an authenticate operation. */
+ @VintfStability
+ parcelable Vendor {
+ ParcelableHolder extension;
+ }
+
+ /** Reason for invoking fingerprint authentication. */
+ @VintfStability
+ @Backing(type="int")
+ enum Fingerprint {
+ UNKNOWN,
+ }
+
+ /** Reason for invoking face authentication. */
+ @VintfStability
+ @Backing(type="int")
+ enum Face {
+ UNKNOWN,
+ STARTED_WAKING_UP,
+ PRIMARY_BOUNCER_SHOWN,
+ ASSISTANT_VISIBLE,
+ ALTERNATE_BIOMETRIC_BOUNCER_SHOWN,
+ NOTIFICATION_PANEL_CLICKED,
+ OCCLUDING_APP_REQUESTED,
+ PICK_UP_GESTURE_TRIGGERED,
+ QS_EXPANDED,
+ SWIPE_UP_ON_BOUNCER,
+ UDFPS_POINTER_DOWN,
+ }
+
+ AuthenticateReason.Vendor vendorAuthenticateReason;
+ AuthenticateReason.Face faceAuthenticateReason;
+ AuthenticateReason.Fingerprint fingerprintAuthenticateReason;
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
index 2f5af5d..cdedf4f 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
@@ -18,7 +18,9 @@
import android.hardware.biometrics.common.ComponentInfo;
import android.hardware.biometrics.common.SensorStrength;
-
+/**
+ * @hide
+ */
@VintfStability
parcelable CommonProps {
/**
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
index b268eef..1da9cf6 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
parcelable ComponentInfo {
/**
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/DisplayState.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/DisplayState.aidl
new file mode 100644
index 0000000..d01eac8
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/DisplayState.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.
+ */
+
+package android.hardware.biometrics.common;
+
+/**
+ * Display state during an operation.
+ *
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DisplayState {
+ /** The display state is unknown. */
+ UNKNOWN,
+
+ /** The display is on and showing the lockscreen (or an occluding app). */
+ LOCKSCREEN,
+
+ /** The display is off or dozing. */
+ NO_UI,
+
+ /** The display is showing a screensaver (dreaming). */
+ SCREENSAVER,
+
+ /** The display is dreaming with always on display. */
+ AOD,
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
index 1010256..b9b1f39 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -15,9 +15,10 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
oneway interface ICancellationSignal {
void cancel();
}
-
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
index 72fe660..f4191d7 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
@@ -16,10 +16,14 @@
package android.hardware.biometrics.common;
+import android.hardware.biometrics.common.AuthenticateReason;
+import android.hardware.biometrics.common.DisplayState;
import android.hardware.biometrics.common.OperationReason;
+import android.hardware.biometrics.common.WakeReason;
/**
* Additional context associated with an operation.
+ * @hide
*/
@VintfStability
parcelable OperationContext {
@@ -41,9 +45,30 @@
*/
OperationReason reason = OperationReason.UNKNOWN;
- /* Flag indicating that the display is in AOD mode. */
+ /** @deprecated use displayState instead. */
boolean isAod = false;
/** Flag indicating that crypto was requested. */
boolean isCrypto = false;
+
+ /**
+ * An associated wake reason for this operation or WakeReason.UNKNOWN if this
+ * operation was not associated with a device wake up event.
+ *
+ * This should be interpreted as a hint to enable optimizations or tracing. The
+ * framework may choose to use WakeReason.UNKNOWN at any time based on the device's
+ * policy.
+ */
+ WakeReason wakeReason = WakeReason.UNKNOWN;
+
+ /** The current display state. */
+ DisplayState displayState = DisplayState.UNKNOWN;
+
+ /**
+ * An associated reason for an authenticate operation.
+ *
+ * This should be interpreted as a hint to enable optimizations or tracing. The
+ * framework may choose to omit the reason at any time based on the device's policy.
+ */
+ @nullable AuthenticateReason authenticateReason;
}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
index abc25ed..1775c43 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
@@ -16,6 +16,10 @@
package android.hardware.biometrics.common;
+/**
+ * The reason for invoking an operation.
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum OperationReason {
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
index 790691c..b5c0999 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.common;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum SensorStrength {
@@ -40,4 +42,4 @@
* HardwareAuthToken(s).
*/
STRONG,
-}
\ No newline at end of file
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/WakeReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/WakeReason.aidl
new file mode 100644
index 0000000..2f36b00
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/WakeReason.aidl
@@ -0,0 +1,81 @@
+/*
+ * 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.biometrics.common;
+
+/**
+ * The wake event associated with an operation, if applicable.
+ *
+ * The events largely shadow constants defined in PowerManager but they may deviate over time.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum WakeReason {
+ /**
+ * A normal operation without an explicit reason.
+ */
+ UNKNOWN,
+
+ /**
+ * Waking up due to power button press.
+ */
+ POWER_BUTTON,
+
+ /**
+ * Waking up due to a user performed gesture. This includes user
+ * interactions with UI on the screen such as the notification shade. This does not include
+ * WakeReason.TAP or WakeReason.LIFT.
+ */
+ GESTURE,
+
+ /**
+ * Waking up because a wake key other than power was pressed.
+ */
+ WAKE_KEY,
+
+ /**
+ * Waking up because a wake motion was performed.
+ */
+ WAKE_MOTION,
+
+ /**
+ * Waking due to the lid being opened.
+ */
+ LID,
+
+ /**
+ * Waking due to display group being added.
+ */
+ DISPLAY_GROUP_ADDED,
+
+ /**
+ * Waking up due to the user single or double tapping on the screen. This
+ * wake reason is used when the user is not tapping on a specific UI element; rather, the device
+ * wakes up due to a generic tap on the screen.
+ */
+ TAP,
+
+ /**
+ * Waking up due to a user performed lift gesture.
+ */
+ LIFT,
+
+ /**
+ * Waking up due to a user interacting with a biometric.
+ */
+ BIOMETRIC,
+}
diff --git a/biometrics/common/thread/Android.bp b/biometrics/common/thread/Android.bp
new file mode 100644
index 0000000..a497d01
--- /dev/null
+++ b/biometrics/common/thread/Android.bp
@@ -0,0 +1,26 @@
+cc_library {
+ // 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
+ name: "android.hardware.biometrics.common.thread",
+ export_include_dirs: ["include"],
+ vendor: true,
+ srcs: [
+ "WorkerThread.cpp",
+ ],
+}
+
+cc_test_host {
+ name: "android.hardware.biometrics.common.WorkerThreadTest",
+ local_include_dirs: ["include"],
+ srcs: [
+ "tests/WorkerThreadTest.cpp",
+ "WorkerThread.cpp",
+ ],
+ shared_libs: [
+ "libcutils",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/biometrics/common/thread/WorkerThread.cpp b/biometrics/common/thread/WorkerThread.cpp
new file mode 100644
index 0000000..61d1a13
--- /dev/null
+++ b/biometrics/common/thread/WorkerThread.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#include "thread/WorkerThread.h"
+
+namespace aidl::android::hardware::biometrics {
+
+// It's important that mThread is initialized after everything else because it runs a member
+// function that may use any member of this class.
+WorkerThread::WorkerThread(size_t maxQueueSize)
+ : mMaxSize(maxQueueSize),
+ mIsDestructing(false),
+ mQueue(),
+ mQueueMutex(),
+ mQueueCond(),
+ mThread(&WorkerThread::threadFunc, this) {}
+
+WorkerThread::~WorkerThread() {
+ // This is a signal for threadFunc to terminate as soon as possible, and a hint for schedule
+ // that it doesn't need to do any work.
+ {
+ std::unique_lock<std::mutex> lock(mQueueMutex);
+ mIsDestructing = true;
+ }
+ mQueueCond.notify_all();
+ mThread.join();
+}
+
+bool WorkerThread::schedule(std::unique_ptr<Callable> task) {
+ if (mIsDestructing) {
+ return false;
+ }
+
+ std::unique_lock<std::mutex> lock(mQueueMutex);
+ if (mQueue.size() >= mMaxSize) {
+ return false;
+ }
+ mQueue.push_back(std::move(task));
+ lock.unlock();
+ mQueueCond.notify_one();
+ return true;
+}
+
+void WorkerThread::threadFunc() {
+ while (!mIsDestructing) {
+ std::unique_lock<std::mutex> lock(mQueueMutex);
+ mQueueCond.wait(lock, [this] { return !mQueue.empty() || mIsDestructing; });
+ if (mIsDestructing) {
+ return;
+ }
+ std::unique_ptr<Callable> task = std::move(mQueue.front());
+ mQueue.pop_front();
+ lock.unlock();
+ (*task)();
+ }
+}
+
+} // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/thread/include/thread/Callable.h b/biometrics/common/thread/include/thread/Callable.h
new file mode 100644
index 0000000..6eeff76
--- /dev/null
+++ b/biometrics/common/thread/include/thread/Callable.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+namespace aidl::android::hardware::biometrics {
+
+// Interface for representing parameterless functions. Unlike std::function<void()>, this can also
+// represent move-only lambdas.
+class Callable {
+ public:
+ virtual void operator()() = 0;
+ virtual ~Callable() = default;
+
+ // Creates a heap-allocated Callable instance from any function object.
+ template <typename T>
+ static std::unique_ptr<Callable> from(T func);
+
+ private:
+ template <typename T>
+ class AnyFuncWrapper;
+};
+
+// Private helper class for wrapping any function object into a Callable.
+template <typename T>
+class Callable::AnyFuncWrapper : public Callable {
+ public:
+ explicit AnyFuncWrapper(T func) : mFunc(std::move(func)) {}
+
+ void operator()() override { mFunc(); }
+
+ private:
+ T mFunc;
+};
+
+template <typename T>
+std::unique_ptr<Callable> Callable::from(T func) {
+ return std::make_unique<AnyFuncWrapper<T>>(std::move(func));
+}
+
+} // namespace aidl::android::hardware::biometrics
\ No newline at end of file
diff --git a/biometrics/common/thread/include/thread/WorkerThread.h b/biometrics/common/thread/include/thread/WorkerThread.h
new file mode 100644
index 0000000..5f89a7f
--- /dev/null
+++ b/biometrics/common/thread/include/thread/WorkerThread.h
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <optional>
+#include <queue>
+#include <thread>
+
+#include "Callable.h"
+
+namespace aidl::android::hardware::biometrics {
+
+// A class that encapsulates a worker thread and a task queue, and provides a convenient interface
+// for a Session to schedule its tasks for asynchronous execution.
+class WorkerThread final {
+ public:
+ // Internally creates a queue that cannot exceed maxQueueSize elements and a new thread that
+ // polls the queue for tasks until this instance is destructed.
+ explicit WorkerThread(size_t maxQueueSize);
+
+ // Unblocks the internal queue and calls join on the internal thread allowing it to gracefully
+ // exit.
+ ~WorkerThread();
+
+ // Disallow copying this class.
+ WorkerThread(const WorkerThread&) = delete;
+ WorkerThread& operator=(const WorkerThread&) = delete;
+
+ // Also disable moving this class to simplify implementation.
+ WorkerThread(WorkerThread&&) = delete;
+ WorkerThread& operator=(WorkerThread&&) = delete;
+
+ // If the internal queue is not full, pushes a task at the end of the queue and returns true.
+ // Otherwise, returns false. If the queue is busy, blocks until it becomes available.
+ // This method expects heap-allocated tasks because it's the simplest way to represent function
+ // objects of any type. Stack-allocated std::function could be used instead, but it cannot
+ // represent functions with move-only captures because std::function is inherently copyable.
+ // Not being able to pass move-only lambdas is a major limitation for the HAL implementation,
+ // so heap-allocated tasks that share a common interface (Callable) were chosen instead.
+ bool schedule(std::unique_ptr<Callable> task);
+
+ private:
+ // The function that runs on the internal thread. Sequentially runs the available tasks from
+ // the queue. If the queue is empty, waits until a new task is added. If the worker is being
+ // destructed, finishes its current task and gracefully exits.
+ void threadFunc();
+
+ // The maximum size that the queue is allowed to expand to.
+ size_t mMaxSize;
+
+ // Whether the destructor was called. If true, tells threadFunc to exit as soon as possible, and
+ // tells schedule to avoid doing any work.
+ std::atomic<bool> mIsDestructing;
+
+ // Queue that's guarded by mQueueMutex and mQueueCond.
+ std::deque<std::unique_ptr<Callable>> mQueue;
+ std::mutex mQueueMutex;
+ std::condition_variable mQueueCond;
+
+ // The internal thread that works on the tasks from the queue.
+ std::thread mThread;
+};
+
+} // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/thread/tests/WorkerThreadTest.cpp b/biometrics/common/thread/tests/WorkerThreadTest.cpp
new file mode 100644
index 0000000..5bb9e7e
--- /dev/null
+++ b/biometrics/common/thread/tests/WorkerThreadTest.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+#include <algorithm>
+#include <chrono>
+#include <future>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include "thread/WorkerThread.h"
+
+namespace {
+
+using namespace aidl::android::hardware::biometrics;
+using namespace std::chrono_literals;
+
+TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) {
+ WorkerThread worker(1 /*maxQueueSize*/);
+ for (int i = 0; i < 100; ++i) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+
+ ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
+ // Notify that the task has started.
+ promise.set_value();
+ })));
+
+ future.wait();
+ }
+}
+
+TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) {
+ WorkerThread worker(2 /*maxQueueSize*/);
+
+ std::promise<void> promise;
+ auto future = promise.get_future();
+
+ // Schedule a long-running task.
+ ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
+ // Notify that the task has started.
+ promise.set_value();
+ // Block for a "very long" time.
+ std::this_thread::sleep_for(1s);
+ })));
+
+ // Make sure the long-running task began executing.
+ future.wait();
+
+ // The first task is already being worked on, which means the queue must be empty.
+ // Fill the worker's queue to the maximum.
+ ASSERT_TRUE(worker.schedule(Callable::from([] {})));
+ ASSERT_TRUE(worker.schedule(Callable::from([] {})));
+
+ EXPECT_FALSE(worker.schedule(Callable::from([] {})));
+}
+
+TEST(WorkerThreadTest, TasksExecuteInOrder) {
+ constexpr int NUM_TASKS = 10000;
+ WorkerThread worker(NUM_TASKS + 1);
+
+ std::mutex mut;
+ std::condition_variable cv;
+ bool finished = false;
+ std::vector<int> results;
+
+ for (int i = 0; i < NUM_TASKS; ++i) {
+ worker.schedule(Callable::from([&mut, &results, i] {
+ // Delay tasks differently to provoke races.
+ std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100));
+ auto lock = std::lock_guard(mut);
+ results.push_back(i);
+ }));
+ }
+
+ // Schedule a special task to signal when all of the tasks are finished.
+ worker.schedule(Callable::from([&mut, &cv, &finished] {
+ auto lock = std::lock_guard(mut);
+ finished = true;
+ cv.notify_one();
+ }));
+
+ auto lock = std::unique_lock(mut);
+ cv.wait(lock, [&finished] { return finished; });
+ ASSERT_EQ(results.size(), NUM_TASKS);
+ EXPECT_TRUE(std::is_sorted(results.begin(), results.end()));
+}
+
+TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) {
+ std::promise<void> promise1;
+ std::promise<void> promise2;
+ auto future1 = promise1.get_future();
+ auto future2 = promise2.get_future();
+ std::atomic<bool> value;
+
+ // Local scope for the worker to test its destructor when it goes out of scope.
+ {
+ WorkerThread worker(2 /*maxQueueSize*/);
+
+ ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise1)]() mutable {
+ promise.set_value();
+ std::this_thread::sleep_for(200ms);
+ })));
+
+ // The first task should start executing.
+ future1.wait();
+
+ // The second task should schedule successfully.
+ ASSERT_TRUE(
+ worker.schedule(Callable::from([promise = std::move(promise2), &value]() mutable {
+ // The worker should destruct before it gets a chance to execute this.
+ value = true;
+ promise.set_value();
+ })));
+ }
+
+ // The second task should never execute.
+ future2.wait();
+ // The future is expected to be ready but contain an exception.
+ // Cannot use ASSERT_THROW because exceptions are disabled in this codebase.
+ // ASSERT_THROW(future2.get(), std::future_error);
+ EXPECT_FALSE(value);
+}
+
+} // namespace
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
new file mode 100644
index 0000000..b990812
--- /dev/null
+++ b/biometrics/common/util/Android.bp
@@ -0,0 +1,18 @@
+cc_library {
+ // 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
+ name: "android.hardware.biometrics.common.util",
+ export_include_dirs: ["include"],
+ vendor: true,
+ srcs: [
+ "CancellationSignal.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ ],
+}
diff --git a/biometrics/common/util/CancellationSignal.cpp b/biometrics/common/util/CancellationSignal.cpp
new file mode 100644
index 0000000..7888838
--- /dev/null
+++ b/biometrics/common/util/CancellationSignal.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "util/CancellationSignal.h"
+
+#include <android-base/logging.h>
+#include <chrono>
+
+namespace aidl::android::hardware::biometrics {
+
+CancellationSignal::CancellationSignal(std::promise<void>&& cancellationPromise)
+ : mCancellationPromise(std::move(cancellationPromise)) {}
+
+ndk::ScopedAStatus CancellationSignal::cancel() {
+ mCancellationPromise.set_value();
+ return ndk::ScopedAStatus::ok();
+}
+
+bool shouldCancel(const std::future<void>& f) {
+ CHECK(f.valid());
+ return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
+}
+
+} // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/util/include/util/CancellationSignal.h b/biometrics/common/util/include/util/CancellationSignal.h
new file mode 100644
index 0000000..be77e29
--- /dev/null
+++ b/biometrics/common/util/include/util/CancellationSignal.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
+#include <functional>
+#include <future>
+
+namespace aidl::android::hardware::biometrics {
+
+class CancellationSignal : public common::BnCancellationSignal {
+ public:
+ explicit CancellationSignal(std::promise<void>&& cancellationPromise);
+
+ ndk::ScopedAStatus cancel() override;
+
+ private:
+ std::promise<void> mCancellationPromise;
+};
+
+// Returns whether the given cancellation future is ready, i.e. whether the operation corresponding
+// to this future should be cancelled.
+bool shouldCancel(const std::future<void>& cancellationFuture);
+
+} // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/common/util/include/util/Util.h b/biometrics/common/util/include/util/Util.h
new file mode 100644
index 0000000..da19dc6
--- /dev/null
+++ b/biometrics/common/util/include/util/Util.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android-base/logging.h>
+
+#include <chrono>
+#include <regex>
+#include <thread>
+#include <vector>
+
+namespace aidl::android::hardware::biometrics {
+
+#define SLEEP_MS(x) \
+ if (x > 0) std::this_thread::sleep_for(std::chrono::milliseconds(x))
+#define BEGIN_OP(x) \
+ do { \
+ LOG(INFO) << __func__; \
+ SLEEP_MS(x); \
+ } while (0)
+#define IS_TRUE(x) ((x == "1") || (x == "true"))
+
+// This is for non-test situations, such as casual cuttlefish users, that don't
+// set an explicit value.
+// Some operations (i.e. enroll, authenticate) will be executed in tight loops
+// by parts of the UI or fail if there is no latency. For example, the
+// Face settings page constantly runs auth and the enrollment UI uses a
+// cancel/restart cycle that requires some latency while the activities change.
+#define DEFAULT_LATENCY 400
+
+class Util {
+ public:
+ static int64_t getSystemNanoTime() {
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return now.tv_sec * 1000000000LL + now.tv_nsec;
+ }
+
+ static bool hasElapsed(int64_t start, int64_t durationMillis) {
+ auto now = getSystemNanoTime();
+ if (now < start) return true;
+ if (durationMillis <= 0) return true;
+ return ((now - start) / 1000000LL) > durationMillis;
+ }
+
+ static std::vector<std::string> split(const std::string& str, const std::string& sep) {
+ std::regex regex(sep);
+ std::vector<std::string> parts(
+ std::sregex_token_iterator(str.begin(), str.end(), regex, -1),
+ std::sregex_token_iterator());
+ return parts;
+ }
+};
+
+} // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/face/1.0/vts/functional/OWNERS b/biometrics/face/1.0/vts/functional/OWNERS
deleted file mode 100644
index 7651b69..0000000
--- a/biometrics/face/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 432605
[email protected]
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 78f113d..7b11335 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,9 +14,9 @@
"android/hardware/biometrics/face/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V2",
+ "android.hardware.biometrics.common-V3",
"android.hardware.common-V2",
- "android.hardware.keymaster-V3",
+ "android.hardware.keymaster-V4",
],
stability: "vintf",
backend: {
diff --git a/biometrics/face/aidl/OWNERS b/biometrics/face/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/face/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
[email protected]
[email protected]
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 7f66eca..876a91f 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -16,12 +16,45 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.face-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
+ "android.hardware.biometrics.face-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common.thread",
+ "android.hardware.biometrics.common.util",
],
srcs: [
"main.cpp",
"Face.cpp",
+ "FakeFaceEngine.cpp",
"Session.cpp",
],
+ static_libs: ["libandroid.hardware.biometrics.face.VirtualProps"],
+}
+
+sysprop_library {
+ name: "android.hardware.biometrics.face.VirtualProps",
+ srcs: ["face.sysprop"],
+ property_owner: "Vendor",
+ vendor: true,
+}
+
+cc_test {
+ name: "android.hardware.biometrics.face.FakeFaceEngineTest",
+ srcs: [
+ "tests/FakeFaceEngineTest.cpp",
+ "FakeFaceEngine.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "libandroid.hardware.biometrics.face.VirtualProps",
+ "android.hardware.biometrics.face-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
+ "android.hardware.biometrics.common.util",
+ ],
+ vendor: true,
+ test_suites: ["general-tests"],
+ require_root: true,
}
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index aca3e13..652a7e1 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -17,12 +17,14 @@
#include "Face.h"
#include "Session.h"
+#include "FakeFaceEngine.h"
+
namespace aidl::android::hardware::biometrics::face {
const int kSensorId = 4;
-const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG;
+const common::SensorStrength kSensorStrength = FakeFaceEngine::GetSensorStrength();
const int kMaxEnrollmentsPerUser = 5;
-const FaceSensorType kSensorType = FaceSensorType::RGB;
+const FaceSensorType kSensorType = FakeFaceEngine::GetSensorType();
const bool kHalControlsPreview = true;
const std::string kHwComponentId = "faceSensor";
const std::string kHardwareVersion = "vendor/model/revision";
@@ -69,7 +71,7 @@
ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* return_val) {
- *return_val = SharedRefBase::make<Session>(cb);
+ *return_val = SharedRefBase::make<Session>(std::make_unique<FakeFaceEngine>(), cb);
return ndk::ScopedAStatus::ok();
}
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.cpp b/biometrics/face/aidl/default/FakeFaceEngine.cpp
new file mode 100644
index 0000000..0f088f4
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeFaceEngine.cpp
@@ -0,0 +1,318 @@
+#include "FakeFaceEngine.h"
+
+#include <android-base/logging.h>
+
+#include <face.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::face::virt;
+
+namespace aidl::android::hardware::biometrics::face {
+
+FaceSensorType FakeFaceEngine::GetSensorType() {
+ std::string type = FaceHalProperties::type().value_or("");
+ if (type == "IR") {
+ return FaceSensorType::IR;
+ } else {
+ FaceHalProperties::type("RGB");
+ return FaceSensorType::RGB;
+ }
+}
+
+common::SensorStrength FakeFaceEngine::GetSensorStrength() {
+ std::string strength = FaceHalProperties::strength().value_or("");
+ if (strength == "convenience") {
+ return common::SensorStrength::CONVENIENCE;
+ } else if (strength == "weak") {
+ return common::SensorStrength::WEAK;
+ } else {
+ FaceHalProperties::strength("strong");
+ return common::SensorStrength::STRONG;
+ }
+}
+
+void FakeFaceEngine::generateChallengeImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ std::uniform_int_distribution<int64_t> dist;
+ auto challenge = dist(mRandom);
+ FaceHalProperties::challenge(challenge);
+ cb->onChallengeGenerated(challenge);
+}
+
+void FakeFaceEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
+ BEGIN_OP(0);
+ FaceHalProperties::challenge({});
+ cb->onChallengeRevoked(challenge);
+}
+void FakeFaceEngine::getEnrollmentConfigImpl(ISessionCallback* /*cb*/,
+ std::vector<EnrollmentStageConfig>* /*return_val*/) {}
+void FakeFaceEngine::enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ EnrollmentType /*enrollmentType*/,
+ 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()) {
+ LOG(ERROR) << "Fail: hat";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ if (FaceHalProperties::operation_enroll_fails().value_or(false)) {
+ LOG(ERROR) << "Fail: operation_enroll_fails";
+ 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];
+
+ SLEEP_MS(std::stoi(delay));
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+
+ if (!IS_TRUE(succeeds)) { // end and failed
+ LOG(ERROR) << "Fail: requested by caller: " << parts[i];
+ 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);
+ }
+ }
+
+ 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*/,
+ const std::future<void>& cancel) {
+ BEGIN_OP(FaceHalProperties::operation_authenticate_latency().value_or(0));
+
+ // Signal to the framework that we have begun authenticating.
+ AuthenticationFrame frame;
+ frame.data.acquiredInfo = AcquiredInfo::START;
+ frame.data.vendorCode = 0;
+ cb->onAuthenticationFrame(frame);
+
+ // Also signal that we have opened the camera.
+ frame = {};
+ frame.data.acquiredInfo = AcquiredInfo::FIRST_FRAME_RECEIVED;
+ frame.data.vendorCode = 0;
+ cb->onAuthenticationFrame(frame);
+
+ auto now = Util::getSystemNanoTime();
+ int64_t duration = FaceHalProperties::operation_authenticate_duration().value_or(0);
+ if (duration > 0) {
+ do {
+ SLEEP_MS(5);
+ } while (!Util::hasElapsed(now, duration));
+ }
+
+ if (FaceHalProperties::operation_authenticate_fails().value_or(false)) {
+ LOG(ERROR) << "Fail: operation_authenticate_fails";
+ cb->onError(Error::VENDOR, 0 /* vendorError */);
+ return;
+ }
+
+ if (FaceHalProperties::lockout().value_or(false)) {
+ LOG(ERROR) << "Fail: lockout";
+ cb->onLockoutPermanent();
+ cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
+ return;
+ }
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+
+ auto id = FaceHalProperties::enrollment_hit().value_or(0);
+ auto enrolls = FaceHalProperties::enrollments();
+ auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+ if (id < 0 || !isEnrolled) {
+ LOG(ERROR) << (isEnrolled ? "invalid enrollment hit" : "Fail: not enrolled");
+ cb->onAuthenticationFailed();
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ cb->onAuthenticationSucceeded(id, {} /* hat */);
+}
+
+void FakeFaceEngine::detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel) {
+ BEGIN_OP(FaceHalProperties::operation_detect_interaction_latency().value_or(0));
+
+ if (FaceHalProperties::operation_detect_interaction_fails().value_or(false)) {
+ LOG(ERROR) << "Fail: operation_detect_interaction_fails";
+ cb->onError(Error::VENDOR, 0 /* vendorError */);
+ return;
+ }
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+
+ auto id = FaceHalProperties::enrollment_hit().value_or(0);
+ auto enrolls = FaceHalProperties::enrollments();
+ auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+ if (id <= 0 || !isEnrolled) {
+ LOG(ERROR) << "Fail: not enrolled";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ cb->onInteractionDetected();
+}
+
+void FakeFaceEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ std::vector<int32_t> enrollments;
+ for (const auto& enrollmentId : FaceHalProperties::enrollments()) {
+ if (enrollmentId) {
+ enrollments.push_back(*enrollmentId);
+ }
+ }
+ cb->onEnrollmentsEnumerated(enrollments);
+}
+
+void FakeFaceEngine::removeEnrollmentsImpl(ISessionCallback* cb,
+ const std::vector<int32_t>& enrollmentIds) {
+ BEGIN_OP(0);
+
+ std::vector<std::optional<int32_t>> newEnrollments;
+ for (const auto& enrollment : FaceHalProperties::enrollments()) {
+ auto id = enrollment.value_or(0);
+ if (std::find(enrollmentIds.begin(), enrollmentIds.end(), id) == enrollmentIds.end()) {
+ newEnrollments.emplace_back(id);
+ }
+ }
+ FaceHalProperties::enrollments(newEnrollments);
+ cb->onEnrollmentsRemoved(enrollmentIds);
+}
+
+void FakeFaceEngine::getFeaturesImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+
+ if (FaceHalProperties::enrollments().empty()) {
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+ return;
+ }
+
+ std::vector<Feature> featuresToReturn = {};
+ for (const auto& feature : FaceHalProperties::features()) {
+ if (feature) {
+ featuresToReturn.push_back((Feature)(*feature));
+ }
+ }
+ cb->onFeaturesRetrieved(featuresToReturn);
+}
+
+void FakeFaceEngine::setFeatureImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ Feature feature, bool enabled) {
+ BEGIN_OP(0);
+
+ if (FaceHalProperties::enrollments().empty()) {
+ LOG(ERROR) << "Unable to set feature, enrollments are empty";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+ return;
+ }
+
+ if (hat.mac.empty()) {
+ LOG(ERROR) << "Unable to set feature, invalid hat";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+ return;
+ }
+
+ auto features = FaceHalProperties::features();
+
+ auto itr = std::find_if(features.begin(), features.end(), [feature](const auto& theFeature) {
+ return *theFeature == (int)feature;
+ });
+
+ if (!enabled && (itr != features.end())) {
+ features.erase(itr);
+ } else if (enabled && (itr == features.end())) {
+ features.push_back((int)feature);
+ }
+
+ FaceHalProperties::features(features);
+ cb->onFeatureSet(feature);
+}
+
+void FakeFaceEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ // If this is a weak HAL return 0 per the spec.
+ if (GetSensorStrength() != common::SensorStrength::STRONG) {
+ cb->onAuthenticatorIdRetrieved(0);
+ } else {
+ cb->onAuthenticatorIdRetrieved(FaceHalProperties::authenticator_id().value_or(0));
+ }
+}
+
+void FakeFaceEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ int64_t authenticatorId = FaceHalProperties::authenticator_id().value_or(0);
+ int64_t newId = authenticatorId + 1;
+ FaceHalProperties::authenticator_id(newId);
+ cb->onAuthenticatorIdInvalidated(newId);
+}
+
+void FakeFaceEngine::resetLockoutImpl(ISessionCallback* cb,
+ const keymaster::HardwareAuthToken& /*hat*/) {
+ BEGIN_OP(0);
+ FaceHalProperties::lockout(false);
+ cb->onLockoutCleared();
+}
+
+} // namespace aidl::android::hardware::biometrics::face
\ No newline at end of file
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.h b/biometrics/face/aidl/default/FakeFaceEngine.h
new file mode 100644
index 0000000..edb54ce
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeFaceEngine.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/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 <vector>
+
+namespace aidl::android::hardware::biometrics::face {
+
+namespace face = aidl::android::hardware::biometrics::face;
+namespace common = aidl::android::hardware::biometrics::common;
+namespace keymaster = aidl::android::hardware::keymaster;
+
+using aidl::android::hardware::common::NativeHandle;
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFaceEngine {
+ public:
+ FakeFaceEngine() : mRandom(std::mt19937::default_seed) {}
+
+ static face::FaceSensorType GetSensorType();
+ static common::SensorStrength GetSensorStrength();
+ void generateChallengeImpl(ISessionCallback* cb);
+ void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge);
+ void getEnrollmentConfigImpl(ISessionCallback* cb,
+ std::vector<EnrollmentStageConfig>* return_val);
+ void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ EnrollmentType enrollmentType, const std::vector<Feature>& features,
+ const std::future<void>& cancel);
+ void authenticateImpl(ISessionCallback* cb, int64_t operationId,
+ const std::future<void>& cancel);
+ void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
+ void enumerateEnrollmentsImpl(ISessionCallback* cb);
+ void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector<int32_t>& enrollmentIds);
+ void getFeaturesImpl(ISessionCallback* cb);
+ void setFeatureImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ Feature feature, bool enabled);
+ void getAuthenticatorIdImpl(ISessionCallback* cb);
+ void invalidateAuthenticatorIdImpl(ISessionCallback* cb);
+ void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/);
+
+ std::mt19937 mRandom;
+};
+
+} // namespace aidl::android::hardware::biometrics::face
\ No newline at end of file
diff --git a/biometrics/face/aidl/default/README.md b/biometrics/face/aidl/default/README.md
new file mode 100644
index 0000000..1655973
--- /dev/null
+++ b/biometrics/face/aidl/default/README.md
@@ -0,0 +1,77 @@
+# Virtual Face HAL
+
+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.
+
+## Device Selection
+
+You can either run the FakeFaceEngine on a [real device](#actual-device) or a [virtual device/cuttlefish](#getting-started-on-a-virtual-device-cuttlefish). This document should
+help you to get started on either one.
+
+After setting up a device, go ahead and try out [enrolling](#enrolling) & [authenticating](#authenticating)
+
+### Getting started on a Virtual Device (cuttlefish)
+
+
+Note, I'm running this via a cloudtop virtual device.
+
+1. Setup cuttlefish on cloudtop, See [this](https://g3doc.corp.google.com/company/teams/android/teampages/acloud/getting_started.md?cl=head) for more details.
+2. acloud create --local-image
+3. Enter in the shell command to disable hidl
+
+```shell
+$ adb root
+$ adb shell settings put secure com.android.server.biometrics.AuthService.hidlDisabled 1
+$ adb reboot
+```
+4. You should now be able to do fake enrollments and authentications (as seen down below)
+
+### Actual Device
+
+1. Modify your real devices make file (I.E. vendor/google/products/{YOUR_DEVICE}.mk)
+2. Ensure that there is no other face HAL that is being included by the device
+3. Add the following
+```
+PRODUCT_COPY_FILES += \
+ frameworks/native/data/etc/android.hardware.biometrics.face.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/permissions/android.hardware.biometrics.face.xml
+
+PRODUCT_PACKAGES += \
+ android.hardware.biometrics.face-service.example \
+
+```
+4. Now build and flash m -j120 && flash
+5. Run the following commands
+
+```shell
+# This is a temporary workaround
+$ adb root
+$ adb shell setprop persist.vendor.face.virtual.type RGB
+$ adb shell setprop persist.vendor.face.virtual.strength strong
+$ adb shell locksettings set-pin 0000
+$ adb reboot
+```
+
+## Enrolling
+
+```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
+$ adb shell am start -n com.android.settings/.biometrics.face.FaceEnrollIntroduction
+# If you would like to get rid of the enrollment, run the follwoing command
+$ adb shell setprop persist.vendor.face.virtual.enrollments \"\"
+```
+
+## Authenticating
+
+```shell
+# If enrollment hasn't been setup
+$ adb shell setprop persist.vendor.face.virtual.enrollments 1
+$ adb shell cmd face sync
+# After enrollment has been setup
+$ adb shell setprop vendor.face.virtual.operation_authenticate_duration 800
+$ adb shell setprop vendor.face.virtual.enrollment_hit 1
+# Power button press to simulate auth
+$ adb shell input keyevent 26
+```
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index 984a1a9..1188459 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -14,139 +14,135 @@
* limitations under the License.
*/
-#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
#include <android-base/logging.h>
#include "Session.h"
namespace aidl::android::hardware::biometrics::face {
-class CancellationSignal : public common::BnCancellationSignal {
- private:
- std::shared_ptr<ISessionCallback> cb_;
+constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;
- public:
- explicit CancellationSignal(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
-
- ndk::ScopedAStatus cancel() override {
- cb_->onError(Error::CANCELED, 0 /* vendorCode */);
- return ndk::ScopedAStatus::ok();
- }
-};
-
-Session::Session(std::shared_ptr<ISessionCallback> cb)
- : cb_(std::move(cb)), mRandom(std::mt19937::default_seed) {}
+Session::Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb)
+ : mEngine(std::move(engine)), mCb(std::move(cb)), mRandom(std::mt19937::default_seed) {
+ mThread = std::make_unique<WorkerThread>(MAX_WORKER_QUEUE_SIZE);
+}
ndk::ScopedAStatus Session::generateChallenge() {
LOG(INFO) << "generateChallenge";
- if (cb_) {
- std::uniform_int_distribution<int64_t> dist;
- auto challenge = dist(mRandom);
- cb_->onChallengeGenerated(challenge);
- }
+ mThread->schedule(Callable::from([this] { mEngine->generateChallengeImpl(mCb.get()); }));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) {
LOG(INFO) << "revokeChallenge";
- if (cb_) {
- cb_->onChallengeRevoked(challenge);
- }
+ mThread->schedule(Callable::from(
+ [this, challenge] { mEngine->revokeChallengeImpl(mCb.get(), challenge); }));
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::getEnrollmentConfig(EnrollmentType /*enrollmentType*/,
- std::vector<EnrollmentStageConfig>* return_val) {
- *return_val = {};
+ndk::ScopedAStatus Session::getEnrollmentConfig(
+ EnrollmentType /*enrollmentType*/, std::vector<EnrollmentStageConfig>* cancellationSignal) {
+ *cancellationSignal = {};
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::enroll(
- const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/,
- const std::vector<Feature>& /*features*/,
- const std::optional<NativeHandle>& /*previewSurface*/,
- std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) {
+ const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType,
+ const std::vector<Feature>& features, const std::optional<NativeHandle>& /*previewSurface*/,
+ std::shared_ptr<biometrics::common::ICancellationSignal>* cancellationSignal) {
LOG(INFO) << "enroll";
- if (cb_) {
- cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
- }
+ std::promise<void> cancellationPromise;
+ auto cancFuture = cancellationPromise.get_future();
+
+ mThread->schedule(Callable::from(
+ [this, hat, enrollmentType, features, cancFuture = std::move(cancFuture)] {
+ mEngine->enrollImpl(mCb.get(), hat, enrollmentType, features, cancFuture);
+ }));
+
+ *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::authenticate(int64_t /*keystoreOperationId*/,
- std::shared_ptr<common::ICancellationSignal>* return_val) {
+ndk::ScopedAStatus Session::authenticate(
+ int64_t keystoreOperationId,
+ std::shared_ptr<common::ICancellationSignal>* cancellationSignal) {
LOG(INFO) << "authenticate";
- if (cb_) {
- cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
- }
- *return_val = SharedRefBase::make<CancellationSignal>(cb_);
+ std::promise<void> cancellationPromise;
+ auto cancFuture = cancellationPromise.get_future();
+
+ mThread->schedule(
+ Callable::from([this, keystoreOperationId, cancFuture = std::move(cancFuture)] {
+ mEngine->authenticateImpl(mCb.get(), keystoreOperationId, cancFuture);
+ }));
+
+ *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::detectInteraction(
- std::shared_ptr<common::ICancellationSignal>* /*return_val*/) {
+ std::shared_ptr<common::ICancellationSignal>* cancellationSignal) {
LOG(INFO) << "detectInteraction";
+ std::promise<void> cancellationPromise;
+ auto cancFuture = cancellationPromise.get_future();
+
+ mThread->schedule(Callable::from([this, cancFuture = std::move(cancFuture)] {
+ mEngine->detectInteractionImpl(mCb.get(), cancFuture);
+ }));
+
+ *cancellationSignal = SharedRefBase::make<CancellationSignal>(std::move(cancellationPromise));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::enumerateEnrollments() {
LOG(INFO) << "enumerateEnrollments";
- if (cb_) {
- cb_->onEnrollmentsEnumerated(std::vector<int32_t>());
- }
+ mThread->schedule(Callable::from([this] { mEngine->enumerateEnrollmentsImpl(mCb.get()); }));
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& /*enrollmentIds*/) {
+ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
LOG(INFO) << "removeEnrollments";
- if (cb_) {
- cb_->onEnrollmentsRemoved(std::vector<int32_t>());
- }
+ mThread->schedule(Callable::from(
+ [this, enrollmentIds] { mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds); }));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::getFeatures() {
LOG(INFO) << "getFeatures";
- if (cb_) {
- // Must error out with UNABLE_TO_PROCESS when no faces are enrolled.
- cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
- }
+ mThread->schedule(Callable::from([this] { mEngine->getFeaturesImpl(mCb.get()); }));
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& /*hat*/,
- Feature /*feature*/, bool /*enabled*/) {
+ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& hat, Feature feature,
+ bool enabled) {
LOG(INFO) << "setFeature";
+ mThread->schedule(Callable::from([this, hat, feature, enabled] {
+ mEngine->setFeatureImpl(mCb.get(), hat, feature, enabled);
+ }));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::getAuthenticatorId() {
LOG(INFO) << "getAuthenticatorId";
- if (cb_) {
- cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */);
- }
+ mThread->schedule(Callable::from([this] { mEngine->getAuthenticatorIdImpl(mCb.get()); }));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::invalidateAuthenticatorId() {
LOG(INFO) << "invalidateAuthenticatorId";
- if (cb_) {
- cb_->onAuthenticatorIdInvalidated(0);
- }
+ mThread->schedule(
+ Callable::from([this] { mEngine->invalidateAuthenticatorIdImpl(mCb.get()); }));
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& /*hat*/) {
+ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat) {
LOG(INFO) << "resetLockout";
- if (cb_) {
- cb_->onLockoutCleared();
- }
+ mThread->schedule(Callable::from([this, hat] { mEngine->resetLockoutImpl(mCb.get(), hat); }));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::close() {
- if (cb_) {
- cb_->onSessionClosed();
+ if (mCb) {
+ mCb->onSessionClosed();
}
return ndk::ScopedAStatus::ok();
}
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 9db17d2..7ca6a1f 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -21,6 +21,10 @@
#include <aidl/android/hardware/biometrics/face/BnSession.h>
#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
+#include "FakeFaceEngine.h"
+#include "thread/WorkerThread.h"
+#include "util/CancellationSignal.h"
+
namespace aidl::android::hardware::biometrics::face {
namespace common = aidl::android::hardware::biometrics::common;
@@ -30,7 +34,7 @@
class Session : public BnSession {
public:
- explicit Session(std::shared_ptr<ISessionCallback> cb);
+ explicit Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb);
ndk::ScopedAStatus generateChallenge() override;
@@ -85,8 +89,11 @@
ndk::ScopedAStatus onContextChanged(const common::OperationContext& context) override;
private:
- std::shared_ptr<ISessionCallback> cb_;
+ std::unique_ptr<FakeFaceEngine> mEngine;
+ std::shared_ptr<ISessionCallback> mCb;
std::mt19937 mRandom;
+ std::unique_ptr<WorkerThread> mThread;
+ std::shared_ptr<CancellationSignal> mCancellationSignal;
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt b/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
new file mode 100644
index 0000000..9548920
--- /dev/null
+++ b/biometrics/face/aidl/default/api/android.hardware.biometrics.face.VirtualProps-current.txt
@@ -0,0 +1,98 @@
+props {
+ owner: Vendor
+ module: "android.face.virt.FaceHalProperties"
+ prop {
+ api_name: "authenticator_id"
+ type: Long
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.authenticator_id"
+ }
+ prop {
+ api_name: "challenge"
+ type: Long
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.challenge"
+ }
+ prop {
+ api_name: "enrollment_hit"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.enrollment_hit"
+ }
+ prop {
+ api_name: "enrollments"
+ type: IntegerList
+ access: ReadWrite
+ prop_name: "persist.vendor.face.virtual.enrollments"
+ }
+ prop {
+ api_name: "features"
+ type: IntegerList
+ access: ReadWrite
+ prop_name: "persist.vendor.face.virtual.features"
+ }
+ prop {
+ api_name: "lockout"
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.lockout"
+ }
+ prop {
+ api_name: "next_enrollment"
+ type: String
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.next_enrollment"
+ }
+ prop {
+ api_name: "operation_authenticate_duration"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_authenticate_duration"
+ }
+ prop {
+ api_name: "operation_authenticate_fails"
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_authenticate_fails"
+ }
+ prop {
+ api_name: "operation_authenticate_latency"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_authenticate_latency"
+ }
+ prop {
+ api_name: "operation_detect_interaction_fails"
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_detect_interaction_fails"
+ }
+ prop {
+ api_name: "operation_detect_interaction_latency"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_detect_interaction_latency"
+ }
+ prop {
+ api_name: "operation_enroll_fails"
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_enroll_fails"
+ }
+ prop {
+ api_name: "operation_start_enroll_latency"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.face.virtual.operation_start_enroll_latency"
+ }
+ prop {
+ api_name: "strength"
+ type: String
+ access: ReadWrite
+ prop_name: "persist.vendor.face.virtual.strength"
+ enum_values: "convenience|weak|strong"
+ }
+ prop {
+ api_name: "type"
+ type: String
+ access: ReadWrite
+ prop_name: "persist.vendor.face.virtual.type"
+ enum_values: "IR|RGB"
+ }
+}
diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml
index e6ef842..8f2fbb8 100644
--- a/biometrics/face/aidl/default/face-default.xml
+++ b/biometrics/face/aidl/default/face-default.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.biometrics.face</name>
- <version>2</version>
+ <version>3</version>
<fqname>IFace/default</fqname>
</hal>
</manifest>
diff --git a/biometrics/face/aidl/default/face.sysprop b/biometrics/face/aidl/default/face.sysprop
new file mode 100644
index 0000000..6b0f37f
--- /dev/null
+++ b/biometrics/face/aidl/default/face.sysprop
@@ -0,0 +1,159 @@
+# face.sysprop
+# module becomes static class (Java) / namespace (C++) for serving API
+module: "android.face.virt.FaceHalProperties"
+owner: Vendor
+
+# type of face sensor
+prop {
+ prop_name: "persist.vendor.face.virtual.type"
+ type: String
+ scope: Public
+ access: ReadWrite
+ enum_values: "IR|RGB"
+ api_name: "type"
+}
+
+# the strength of the sensor
+prop {
+ prop_name: "persist.vendor.face.virtual.strength"
+ type: String
+ scope: Public
+ access: ReadWrite
+ enum_values: "convenience|weak|strong"
+ api_name: "strength"
+}
+
+# ids of current enrollments
+prop {
+ prop_name: "persist.vendor.face.virtual.enrollments"
+ type: IntegerList
+ scope: Public
+ access: ReadWrite
+ api_name: "enrollments"
+}
+
+# List of features
+prop {
+ prop_name: "persist.vendor.face.virtual.features"
+ type: IntegerList
+ scope: Public
+ access: ReadWrite
+ api_name: "features"
+}
+
+# authenticate and detectInteraction will succeed with this
+# enrollment id, when present, otherwise they will error
+prop {
+ prop_name: "vendor.face.virtual.enrollment_hit"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "enrollment_hit"
+}
+
+# The initial latency for enrollment
+prop {
+ prop_name: "vendor.face.virtual.operation_start_enroll_latency"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_start_enroll_latency"
+}
+
+# the next enrollment in the format:
+# "<id>,<bucket_id>:<delay>:<succeeds>,<bucket_id>..."
+# for example: "0:1,0:100:1,1:200:1" indicating that bucket 0 took
+# 50 milliseconds, bucket 1 took 100 milliseconds, bucket 2 took 200 milliseconds.
+# Note that it is up to the configuration to determine how many buckets are required
+# to complete an enrollment
+prop {
+ prop_name: "vendor.face.virtual.next_enrollment"
+ type: String
+ scope: Public
+ access: ReadWrite
+ api_name: "next_enrollment"
+}
+
+# value for getAuthenticatorId or 0
+prop {
+ prop_name: "vendor.face.virtual.authenticator_id"
+ type: Long
+ scope: Public
+ access: ReadWrite
+ api_name: "authenticator_id"
+}
+
+# value for generateChallenge
+prop {
+ prop_name: "vendor.face.virtual.challenge"
+ type: Long
+ scope: Public
+ access: ReadWrite
+ api_name: "challenge"
+}
+
+# if locked out
+prop {
+ prop_name: "vendor.face.virtual.lockout"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "lockout"
+}
+
+# force all authenticate operations to fail
+prop {
+ prop_name: "vendor.face.virtual.operation_authenticate_fails"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_authenticate_fails"
+}
+
+# force all detectInteraction operations to fail
+prop {
+ prop_name: "vendor.face.virtual.operation_detect_interaction_fails"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_detect_interaction_fails"
+}
+
+# force all enroll operations to fail
+prop {
+ prop_name: "vendor.face.virtual.operation_enroll_fails"
+ type: Boolean
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_enroll_fails"
+}
+
+# add a latency to authentication operations
+# Note that this latency is the initial authentication latency that occurs before
+# the HAL will send AcquiredInfo::START and AcquiredInfo::FIRST_FRAME_RECEIVED
+prop {
+ prop_name: "vendor.face.virtual.operation_authenticate_latency"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_authenticate_latency"
+}
+
+# add a latency to detectInteraction operations
+prop {
+ prop_name: "vendor.face.virtual.operation_detect_interaction_latency"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_detect_interaction_latency"
+}
+
+# millisecond duration for authenticate operations
+# (waits for changes to enrollment_hit)
+prop {
+ prop_name: "vendor.face.virtual.operation_authenticate_duration"
+ type: Integer
+ scope: Public
+ access: ReadWrite
+ api_name: "operation_authenticate_duration"
+}
diff --git a/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
new file mode 100644
index 0000000..c8ad6b7
--- /dev/null
+++ b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <face.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
+#include <android-base/logging.h>
+
+#include "FakeFaceEngine.h"
+
+using namespace ::android::face::virt;
+using namespace ::aidl::android::hardware::biometrics::face;
+using namespace ::aidl::android::hardware::keymaster;
+
+namespace aidl::android::hardware::biometrics::face {
+
+class TestSessionCallback : public BnSessionCallback {
+ public:
+ ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+ mLastChallenge = challenge;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+ mLastChallengeRevoked = challenge;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onError(Error error, int32_t) override {
+ mError = error;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
+ if (remaining == 0) mLastEnrolled = enrollmentId;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t enrollmentId,
+ const HardwareAuthToken&) override {
+ mLastAuthenticated = enrollmentId;
+ mAuthenticateFailed = false;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFailed() override {
+ mLastAuthenticated = 0;
+ mAuthenticateFailed = true;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onInteractionDetected() override {
+ mInteractionDetectedCount++;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ ::ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame& frame) override {
+ mEnrollmentFrames.push_back(frame.data.vendorCode);
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+ const std::vector<int32_t>& enrollmentIds) override {
+ mLastEnrollmentsEnumerated = enrollmentIds;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentsRemoved(const std::vector<int32_t>& enrollmentIds) override {
+ mLastEnrollmentRemoved = enrollmentIds;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t authenticatorId) override {
+ mLastAuthenticatorId = authenticatorId;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t authenticatorId) override {
+ mLastAuthenticatorId = authenticatorId;
+ mAuthenticatorIdInvalidated = true;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame& /*authFrame*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onLockoutPermanent() override {
+ mLockoutPermanent = true;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onLockoutCleared() override {
+ mLockoutPermanent = false;
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+ ::ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>& features) override {
+ mFeatures = features;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ::ndk::ScopedAStatus onFeatureSet(Feature feature) override {
+ mLastFeatureSet = feature;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ Error mError = Error::UNKNOWN;
+ int64_t mLastChallenge = -1;
+ int64_t mLastChallengeRevoked = -1;
+ int32_t mLastEnrolled = -1;
+ int32_t mLastAuthenticated = -1;
+ int64_t mLastAuthenticatorId = -1;
+ std::vector<int32_t> mLastEnrollmentsEnumerated;
+ std::vector<int32_t> mLastEnrollmentRemoved;
+ std::vector<Feature> mFeatures;
+ Feature mLastFeatureSet;
+ std::vector<int32_t> mEnrollmentFrames;
+ bool mAuthenticateFailed = false;
+ bool mAuthenticatorIdInvalidated = false;
+ bool mLockoutPermanent = false;
+ int mInteractionDetectedCount = 0;
+};
+
+class FakeFaceEngineTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ LOG(ERROR) << "JRM SETUP";
+ mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+ FaceHalProperties::enrollments({});
+ FaceHalProperties::challenge({});
+ FaceHalProperties::features({});
+ FaceHalProperties::authenticator_id({});
+ FaceHalProperties::strength("");
+ }
+
+ FakeFaceEngine mEngine;
+ std::shared_ptr<TestSessionCallback> mCallback;
+ std::promise<void> mCancel;
+};
+
+TEST_F(FakeFaceEngineTest, one_eq_one) {
+ ASSERT_EQ(1, 1);
+}
+
+TEST_F(FakeFaceEngineTest, GenerateChallenge) {
+ mEngine.generateChallengeImpl(mCallback.get());
+ ASSERT_EQ(FaceHalProperties::challenge().value(), mCallback->mLastChallenge);
+}
+
+TEST_F(FakeFaceEngineTest, RevokeChallenge) {
+ auto challenge = FaceHalProperties::challenge().value_or(10);
+ mEngine.revokeChallengeImpl(mCallback.get(), challenge);
+ ASSERT_FALSE(FaceHalProperties::challenge().has_value());
+ ASSERT_EQ(challenge, mCallback->mLastChallengeRevoked);
+}
+
+TEST_F(FakeFaceEngineTest, ResetLockout) {
+ FaceHalProperties::lockout(true);
+ mEngine.resetLockoutImpl(mCallback.get(), {});
+ ASSERT_FALSE(mCallback->mLockoutPermanent);
+ ASSERT_FALSE(FaceHalProperties::lockout().value_or(true));
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticatorId) {
+ FaceHalProperties::authenticator_id(50);
+ mEngine.getAuthenticatorIdImpl(mCallback.get());
+ ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
+ ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFaceEngineTest, GetAuthenticatorIdWeakReturnsZero) {
+ FaceHalProperties::strength("weak");
+ FaceHalProperties::authenticator_id(500);
+ mEngine.getAuthenticatorIdImpl(mCallback.get());
+ ASSERT_EQ(0, mCallback->mLastAuthenticatorId);
+ ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticatorIdInvalidate) {
+ FaceHalProperties::authenticator_id(500);
+ mEngine.invalidateAuthenticatorIdImpl(mCallback.get());
+ ASSERT_NE(500, FaceHalProperties::authenticator_id().value());
+ ASSERT_TRUE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFaceEngineTest, Enroll) {
+ FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:true");
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
+ mCancel.get_future());
+ ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+ ASSERT_EQ(1, FaceHalProperties::enrollments().size());
+ ASSERT_EQ(1, FaceHalProperties::enrollments()[0].value());
+ ASSERT_EQ(1, mCallback->mLastEnrolled);
+}
+
+TEST_F(FakeFaceEngineTest, EnrollFails) {
+ FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
+ mCancel.get_future());
+ ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+ ASSERT_EQ(0, FaceHalProperties::enrollments().size());
+}
+
+TEST_F(FakeFaceEngineTest, EnrollCancel) {
+ FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mCancel.set_value();
+ mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
+ mCancel.get_future());
+ ASSERT_EQ(Error::CANCELED, mCallback->mError);
+ ASSERT_EQ(-1, mCallback->mLastEnrolled);
+ ASSERT_EQ(0, FaceHalProperties::enrollments().size());
+ ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+}
+
+TEST_F(FakeFaceEngineTest, Authenticate) {
+ FaceHalProperties::enrollments({100});
+ FaceHalProperties::enrollment_hit(100);
+ mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, mCancel.get_future());
+
+ ASSERT_EQ(100, mCallback->mLastAuthenticated);
+ ASSERT_FALSE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticateCancel) {
+ FaceHalProperties::enrollments({100});
+ FaceHalProperties::enrollment_hit(100);
+ mCancel.set_value();
+ mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, mCancel.get_future());
+ ASSERT_EQ(Error::CANCELED, mCallback->mError);
+}
+
+TEST_F(FakeFaceEngineTest, AuthenticateFailedForUnEnrolled) {
+ FaceHalProperties::enrollments({3});
+ FaceHalProperties::enrollment_hit(100);
+ mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, mCancel.get_future());
+ ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
+ ASSERT_TRUE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFaceEngineTest, DetectInteraction) {
+ FaceHalProperties::enrollments({100});
+ FaceHalProperties::enrollment_hit(100);
+ ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFaceEngineTest, DetectInteractionCancel) {
+ FaceHalProperties::enrollments({100});
+ FaceHalProperties::enrollment_hit(100);
+ mCancel.set_value();
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(Error::CANCELED, mCallback->mError);
+}
+
+TEST_F(FakeFaceEngineTest, GetFeatureEmpty) {
+ mEngine.getFeaturesImpl(mCallback.get());
+ ASSERT_TRUE(mCallback->mFeatures.empty());
+}
+
+TEST_F(FakeFaceEngineTest, SetFeature) {
+ FaceHalProperties::enrollments({1});
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+ auto features = mCallback->mFeatures;
+ ASSERT_TRUE(features.empty());
+ ASSERT_EQ(Feature::REQUIRE_ATTENTION, mCallback->mLastFeatureSet);
+
+ mEngine.getFeaturesImpl(mCallback.get());
+ features = mCallback->mFeatures;
+ ASSERT_FALSE(features.empty());
+ ASSERT_NE(features.end(),
+ std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+}
+
+TEST_F(FakeFaceEngineTest, ToggleFeature) {
+ FaceHalProperties::enrollments({1});
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+ mEngine.getFeaturesImpl(mCallback.get());
+ auto features = mCallback->mFeatures;
+ ASSERT_FALSE(features.empty());
+ ASSERT_NE(features.end(),
+ std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, false);
+ mEngine.getFeaturesImpl(mCallback.get());
+ features = mCallback->mFeatures;
+ ASSERT_TRUE(features.empty());
+}
+
+TEST_F(FakeFaceEngineTest, TurningOffNonExistentFeatureDoesNothing) {
+ FaceHalProperties::enrollments({1});
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, false);
+ mEngine.getFeaturesImpl(mCallback.get());
+ auto features = mCallback->mFeatures;
+ ASSERT_TRUE(features.empty());
+}
+
+TEST_F(FakeFaceEngineTest, SetMultipleFeatures) {
+ FaceHalProperties::enrollments({1});
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_DIVERSE_POSES, true);
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::DEBUG, true);
+ mEngine.getFeaturesImpl(mCallback.get());
+ auto features = mCallback->mFeatures;
+ ASSERT_EQ(3, features.size());
+ ASSERT_NE(features.end(),
+ std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+ ASSERT_NE(features.end(),
+ std::find(features.begin(), features.end(), Feature::REQUIRE_DIVERSE_POSES));
+ ASSERT_NE(features.end(), std::find(features.begin(), features.end(), Feature::DEBUG));
+}
+
+TEST_F(FakeFaceEngineTest, SetMultipleFeaturesAndTurnOffSome) {
+ FaceHalProperties::enrollments({1});
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_ATTENTION, true);
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::REQUIRE_DIVERSE_POSES, true);
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::DEBUG, true);
+ mEngine.setFeatureImpl(mCallback.get(), hat, Feature::DEBUG, false);
+ mEngine.getFeaturesImpl(mCallback.get());
+ auto features = mCallback->mFeatures;
+ ASSERT_EQ(2, features.size());
+ ASSERT_NE(features.end(),
+ std::find(features.begin(), features.end(), Feature::REQUIRE_ATTENTION));
+ ASSERT_NE(features.end(),
+ std::find(features.begin(), features.end(), Feature::REQUIRE_DIVERSE_POSES));
+ ASSERT_EQ(features.end(), std::find(features.begin(), features.end(), Feature::DEBUG));
+}
+
+TEST_F(FakeFaceEngineTest, Enumerate) {
+ FaceHalProperties::enrollments({120, 3});
+ mEngine.enumerateEnrollmentsImpl(mCallback.get());
+ auto enrolls = mCallback->mLastEnrollmentsEnumerated;
+ ASSERT_FALSE(enrolls.empty());
+ ASSERT_NE(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 120));
+ ASSERT_NE(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 3));
+}
+
+TEST_F(FakeFaceEngineTest, RemoveEnrollments) {
+ FaceHalProperties::enrollments({120, 3, 100});
+ mEngine.removeEnrollmentsImpl(mCallback.get(), {120, 100});
+ mEngine.enumerateEnrollmentsImpl(mCallback.get());
+ auto enrolls = mCallback->mLastEnrollmentsEnumerated;
+ ASSERT_FALSE(enrolls.empty());
+ ASSERT_EQ(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 120));
+ ASSERT_NE(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 3));
+ ASSERT_EQ(enrolls.end(), std::find(enrolls.begin(), enrolls.end(), 100));
+}
+
+TEST_F(FakeFaceEngineTest, ResetLockoutWithAuth) {
+ FaceHalProperties::lockout(true);
+ FaceHalProperties::enrollments({33});
+ FaceHalProperties::enrollment_hit(33);
+ auto cancelFuture = mCancel.get_future();
+ mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, cancelFuture);
+
+ ASSERT_TRUE(mCallback->mLockoutPermanent);
+
+ mEngine.resetLockoutImpl(mCallback.get(), {} /* hat */);
+ ASSERT_FALSE(mCallback->mLockoutPermanent);
+ FaceHalProperties::enrollment_hit(33);
+ mEngine.authenticateImpl(mCallback.get(), 0 /* operationId*/, cancelFuture);
+ ASSERT_EQ(33, mCallback->mLastAuthenticated);
+ ASSERT_FALSE(mCallback->mAuthenticateFailed);
+}
+
+} // namespace aidl::android::hardware::biometrics::face
\ No newline at end of file
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
index 4171ac3..f62c4e4 100644
--- a/biometrics/face/aidl/vts/Android.bp
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -15,10 +15,10 @@
],
srcs: ["VtsHalBiometricsFaceTargetTest.cpp"],
static_libs: [
- "android.hardware.biometrics.common-V2-ndk",
- "android.hardware.biometrics.face-V2-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.face-V3-ndk",
"android.hardware.common-V2-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/biometrics/fingerprint/2.1/vts/functional/OWNERS b/biometrics/fingerprint/2.1/vts/functional/OWNERS
deleted file mode 100644
index 0014ce9..0000000
--- a/biometrics/fingerprint/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 114777
[email protected]
diff --git a/biometrics/fingerprint/2.2/vts/functional/OWNERS b/biometrics/fingerprint/2.2/vts/functional/OWNERS
deleted file mode 100644
index 0014ce9..0000000
--- a/biometrics/fingerprint/2.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 114777
[email protected]
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index 620e270..f749822 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,8 +14,8 @@
"android/hardware/biometrics/fingerprint/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V2",
- "android.hardware.keymaster-V3",
+ "android.hardware.biometrics.common-V3",
+ "android.hardware.keymaster-V4",
],
stability: "vintf",
backend: {
@@ -41,7 +41,5 @@
"android.hardware.keymaster-V3",
],
},
-
],
-
}
diff --git a/biometrics/fingerprint/aidl/OWNERS b/biometrics/fingerprint/aidl/OWNERS
deleted file mode 100644
index 36d7261..0000000
--- a/biometrics/fingerprint/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
[email protected]
[email protected]
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index c51aa03..7075f71 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -32,19 +32,22 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@Backing(type="byte") @VintfStability
enum AcquiredInfo {
- UNKNOWN = 0,
- GOOD = 1,
- PARTIAL = 2,
- INSUFFICIENT = 3,
- SENSOR_DIRTY = 4,
- TOO_SLOW = 5,
- TOO_FAST = 6,
- VENDOR = 7,
- START = 8,
- TOO_DARK = 9,
- TOO_BRIGHT = 10,
- IMMOBILE = 11,
- RETRYING_CAPTURE = 12,
+ UNKNOWN,
+ GOOD,
+ PARTIAL,
+ INSUFFICIENT,
+ SENSOR_DIRTY,
+ TOO_SLOW,
+ TOO_FAST,
+ VENDOR,
+ START,
+ TOO_DARK,
+ TOO_BRIGHT,
+ IMMOBILE,
+ RETRYING_CAPTURE,
+ LIFT_TOO_SOON,
+ POWER_PRESS,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index af7bc3c..9eeaac5 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -32,15 +32,17 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@Backing(type="byte") @VintfStability
enum Error {
- UNKNOWN = 0,
- HW_UNAVAILABLE = 1,
- UNABLE_TO_PROCESS = 2,
- TIMEOUT = 3,
- NO_SPACE = 4,
- CANCELED = 5,
- UNABLE_TO_REMOVE = 6,
- VENDOR = 7,
- BAD_CALIBRATION = 8,
+ UNKNOWN,
+ HW_UNAVAILABLE,
+ UNABLE_TO_PROCESS,
+ TIMEOUT,
+ NO_SPACE,
+ CANCELED,
+ UNABLE_TO_REMOVE,
+ VENDOR,
+ BAD_CALIBRATION,
+ POWER_PRESS,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index 9c208c4..381aaf7 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -32,12 +32,13 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@Backing(type="byte") @VintfStability
enum FingerprintSensorType {
- UNKNOWN = 0,
- REAR = 1,
- UNDER_DISPLAY_ULTRASONIC = 2,
- UNDER_DISPLAY_OPTICAL = 3,
- POWER_BUTTON = 4,
- HOME_BUTTON = 5,
+ UNKNOWN,
+ REAR,
+ UNDER_DISPLAY_ULTRASONIC,
+ UNDER_DISPLAY_OPTICAL,
+ POWER_BUTTON,
+ HOME_BUTTON,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 5d3df6f..0b6f300 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
interface IFingerprint {
android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 30f299d..4fdcefc 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
interface ISession {
void generateChallenge();
@@ -45,7 +46,13 @@
void invalidateAuthenticatorId();
void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
void close();
+ /**
+ * @deprecated use onPointerDownWithContext instead.
+ */
void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
+ /**
+ * @deprecated use onPointerUpWithContext instead.
+ */
void onPointerUp(in int pointerId);
void onUiReady();
android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
@@ -54,4 +61,6 @@
void onPointerDownWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
+ void onPointerCancelWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+ void setIgnoreDisplayTouches(in boolean shouldIgnore);
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index 3c40ad6..be18ffe 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
interface ISessionCallback {
void onChallengeGenerated(in long challenge);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
index 43db6cf..d9bf085 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -32,14 +32,15 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
-@VintfStability
+/* @hide */
+@JavaDerive(equals=true) @VintfStability
parcelable PointerContext {
- int pointerId = -1;
- float x = 0.000000f;
- float y = 0.000000f;
- float minor = 0.000000f;
- float major = 0.000000f;
- float orientation = 0.000000f;
+ int pointerId = (-1) /* -1 */;
+ float x = 0f;
+ float y = 0f;
+ float minor = 0f;
+ float major = 0f;
+ float orientation = 0f;
boolean isAod = false;
long time = 0;
long gestureStart = 0;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index 295fde9..965576e 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -32,11 +32,16 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
parcelable SensorLocation {
+ /**
+ * @deprecated use the display field instead. This field was never used.
+ */
int displayId;
int sensorLocationX;
int sensorLocationY;
int sensorRadius;
String display = "";
+ android.hardware.biometrics.fingerprint.SensorShape sensorShape = android.hardware.biometrics.fingerprint.SensorShape.CIRCLE;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
index 782d289..a97d819 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.fingerprint;
+/* @hide */
@VintfStability
parcelable SensorProps {
android.hardware.biometrics.common.CommonProps commonProps;
@@ -41,4 +42,5 @@
boolean supportsDetectInteraction;
boolean halHandlesDisplayTouches;
boolean halControlsIllumination;
+ @nullable android.hardware.biometrics.fingerprint.TouchDetectionParameters touchDetectionParameters;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorShape.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorShape.aidl
new file mode 100644
index 0000000..f673b1c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorShape.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.biometrics.fingerprint;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum SensorShape {
+ SQUARE,
+ CIRCLE,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
new file mode 100644
index 0000000..2e3ec4f
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/TouchDetectionParameters.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.biometrics.fingerprint;
+/* @hide */
+@VintfStability
+parcelable TouchDetectionParameters {
+ float targetSize = 1.0f;
+ float minOverlap = 0.0f;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 8ec8574..41b7c5e 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum AcquiredInfo {
@@ -96,4 +98,15 @@
* However, RETRYING_CAPTURE must not be sent after ACQUIRED_GOOD is sent.
*/
RETRYING_CAPTURE,
+
+ /**
+ * Fingerprint was lifted before the capture completed.
+ */
+ LIFT_TOO_SOON,
+
+ /**
+ * Indicates a power press event has occurred. This is typically sent by fingerprint
+ * sensors that have the sensor co-located with the power button.
+ */
+ POWER_PRESS,
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
index e69859a..39a5676 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum Error {
@@ -68,4 +70,10 @@
* There's a problem with the sensor's calibration.
*/
BAD_CALIBRATION,
+
+ /**
+ * Indicates a power press event has occurred. This is typically sent by fingerprint
+ * sensors that have the sensor co-located with the power button.
+ */
+ POWER_PRESS,
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index dbe7137..7caa154 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.fingerprint;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum FingerprintSensorType {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 75f90a1..f4febad 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -19,7 +19,9 @@
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
import android.hardware.biometrics.fingerprint.SensorProps;
-
+/**
+ * @hide
+ */
@VintfStability
interface IFingerprint {
/**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index db01145..83e7bbc 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -45,6 +45,7 @@
* ISession only supports execution of one non-interrupting operation at a time, regardless of
* whether it's cancellable. The framework must wait for a callback indicating the end of the
* current non-interrupting operation before a new non-interrupting operation can be started.
+ * @hide
*/
@VintfStability
interface ISession {
@@ -419,6 +420,8 @@
* @param y The distance in pixels from the top edge of the display.
* @param minor See android.view.MotionEvent#getTouchMinor
* @param major See android.view.MotionEvent#getTouchMajor
+ *
+ * @deprecated use onPointerDownWithContext instead.
*/
void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
@@ -433,6 +436,8 @@
* ISession#enroll, ISession#detectInteraction.
*
* @param pointerId See android.view.MotionEvent#getPointerId
+ *
+ * @deprecated use onPointerUpWithContext instead.
*/
void onPointerUp(in int pointerId);
@@ -468,15 +473,77 @@
/** See ISession#detectInteraction() */
ICancellationSignal detectInteractionWithContext(in OperationContext context);
- /** See ISession#onPointerDown(int, int, int, float, float) */
+ /**
+ * onPointerDownWithContext:
+ *
+ * This operation only applies to sensors that are configured as
+ * FingerprintSensorType::UNDER_DISPLAY_*. If invoked erroneously by the framework for sensors
+ * of other types, the HAL must treat this as a no-op and return immediately.
+ *
+ * Notifies the HAL that a finger entered the sensor area. This operation can be invoked
+ * regardless of the current state of the HAL.
+ *
+ * Note that for sensors which require illumination, for example
+ * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, this is a good time to start illuminating.
+ *
+ * @param context See PointerContext
+ */
void onPointerDownWithContext(in PointerContext context);
- /** See ISession#onPointerUp(int) */
+ /**
+ * onPointerUpWithContext:
+ *
+ * This operation only applies to sensors that are configured as
+ * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must
+ * treat this as a no-op and return immediately.
+ *
+ * Notifies the HAL that a finger left the sensor area. This operation can be invoked regardless
+ * of the current state of the HAL.
+ *
+ * @param context See PointerContext
+ */
void onPointerUpWithContext(in PointerContext context);
/**
+ * onContextChanged:
+ *
* This may be called while an authenticate, detect interaction, or enrollment operation is
* running when the context changes.
*/
void onContextChanged(in OperationContext context);
+
+ /**
+ * onPointerCancelWithContext:
+ *
+ * This operation only applies to sensors that are configured as
+ * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must
+ * treat this as a no-op and return immediately.
+ *
+ * Notifies the HAL that if there were fingers within the sensor area, they are no longer being
+ * tracked. The fingers may or may not still be on the sensor. This operation can be invoked
+ * regardless of the current state of the HAL.
+ *
+ * @param context See PointerContext
+ */
+ void onPointerCancelWithContext(in PointerContext context);
+
+ /**
+ * setIgnoreDisplayTouches:
+ *
+ * This operation only applies to sensors that have SensorProps#halHandlesDisplayTouches
+ * set to true. For all other sensors this is a no-op.
+ *
+ * Instructs the HAL whether to ignore display touches. This can be useful to avoid unintended
+ * fingerprint captures during certain UI interactions. For example, when entering a lockscreen
+ * PIN, some of the touches might overlap with the fingerprint sensor. Those touches should be
+ * ignored to avoid unintended authentication attempts.
+ *
+ * This flag must default to false when the HAL starts.
+ *
+ * The framework is responsible for both setting the flag to true and resetting it to false
+ * whenever it's appropriate.
+ *
+ * @param shouldIgnore whether the display touches should be ignored.
+ */
+ void setIgnoreDisplayTouches(in boolean shouldIgnore);
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index f699966..24b169e 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -19,7 +19,9 @@
import android.hardware.biometrics.fingerprint.AcquiredInfo;
import android.hardware.biometrics.fingerprint.Error;
import android.hardware.keymaster.HardwareAuthToken;
-
+/**
+ * @hide
+ */
@VintfStability
interface ISessionCallback {
/**
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
index e025d34..582e6cf 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -18,7 +18,9 @@
/**
* Additional context associated with a pointer event.
+ * @hide
*/
+@JavaDerive(equals=true)
@VintfStability
parcelable PointerContext {
/**
@@ -64,7 +66,7 @@
boolean isAod = false;
/**
- * The time of the user interaction that produced this event, in milliseconds.
+ * The time when this event was created, in milliseconds.
*
* This is obtained from MotionEvent#getEventTime, which uses SystemClock.uptimeMillis() as
* the clock.
@@ -74,10 +76,10 @@
long time = 0;
/**
- * The time of the first user interaction in this gesture, in milliseconds.
+ * This event is part of some gesture. This is the time when MotionEvent#ACTION_DOWN was
+ * created for that gesture, in milliseconds.
*
- * If this event is MotionEvent#ACTION_DOWN, it means it's the first event in this gesture,
- * and `gestureStart` will be equal to `time`.
+ * If this event is MotionEvent#ACTION_DOWN, then this value is equal to `time`.
*
* This is obtained from MotionEvent#getDownTime, which uses SystemClock.uptimeMillis() as
* the clock.
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index d12605c..fd8c7fc 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -16,10 +16,15 @@
package android.hardware.biometrics.fingerprint;
+import android.hardware.biometrics.fingerprint.SensorShape;
+
+/**
+ * @hide
+ */
@VintfStability
parcelable SensorLocation {
/**
- * Deprecated use the display field instead. This field was never used.
+ * @deprecated use the display field instead. This field was never used.
*/
int displayId;
@@ -57,4 +62,10 @@
* for each display from which the sensor is accessible from.
*/
String display = "";
+
+ /**
+ * The shape of the sensor if applicable. Most useful for the sensor of type
+ * SensorType::UNDER_DISPLAY_*.
+ */
+ SensorShape sensorShape = SensorShape.CIRCLE;
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
index fb516da..853aae4 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -19,7 +19,11 @@
import android.hardware.biometrics.common.CommonProps;
import android.hardware.biometrics.fingerprint.FingerprintSensorType;
import android.hardware.biometrics.fingerprint.SensorLocation;
+import android.hardware.biometrics.fingerprint.TouchDetectionParameters;
+/**
+ * @hide
+ */
@VintfStability
parcelable SensorProps {
/**
@@ -70,4 +74,9 @@
* This value must be ignored for sensors that aren't optical UDFPS.
*/
boolean halControlsIllumination;
+
+ /**
+ * Parameters used for fingerprint touch detection.
+ */
+ @nullable TouchDetectionParameters touchDetectionParameters;
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorShape.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorShape.aidl
new file mode 100644
index 0000000..1279332
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorShape.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.biometrics.fingerprint;
+/**
+ * This is most useful for sensors configured as FingerprintSensorType::UNDER_DISPLAY_OPTICAL,
+ * as it's used to compute the on-screen sensor boundaries for the touch detection algorithm.
+ *
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum SensorShape {
+ SQUARE,
+ CIRCLE,
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
new file mode 100644
index 0000000..bf117a3
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/TouchDetectionParameters.aidl
@@ -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.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable TouchDetectionParameters {
+ /**
+ * The percentage of the sensor that is considered the target. Value is required to be within
+ * [0.0, 1.0]. The target area expands outwards from center matching the sensorShape. Some
+ * portion of the touch must be within the target to be considered a valid touch.
+ */
+ float targetSize = 1.0f;
+
+ /**
+ * The minimum percentage overlap needed on the sensor to be considered a valid touch. Value is
+ * required to be within [0.0, 1.0].
+ */
+ float minOverlap = 0.0f;
+}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index 430bf3c..fe224c9 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -11,33 +11,108 @@
name: "android.hardware.biometrics.fingerprint-service.example",
vendor: true,
relative_install_path: "hw",
- init_rc: ["fingerprint-default.rc"],
- vintf_fragments: ["fingerprint-default.xml"],
+ init_rc: ["fingerprint-example.rc"],
+ vintf_fragments: ["fingerprint-example.xml"],
local_include_dirs: ["include"],
srcs: [
- "CancellationSignal.cpp",
+ "FakeLockoutTracker.cpp",
+ "FakeFingerprintEngine.cpp",
+ "FakeFingerprintEngineRear.cpp",
+ "FakeFingerprintEngineUdfps.cpp",
+ "FakeFingerprintEngineSide.cpp",
"Fingerprint.cpp",
"Session.cpp",
- "WorkerThread.cpp",
"main.cpp",
],
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.fingerprint-V2-ndk",
- "android.hardware.biometrics.common-V2-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common.thread",
+ "android.hardware.biometrics.common.util",
],
+ static_libs: ["libandroid.hardware.biometrics.fingerprint.VirtualProps"],
}
-cc_test_host {
- name: "android.hardware.biometrics.fingerprint.WorkerThreadTest",
+cc_test {
+ name: "android.hardware.biometrics.fingerprint.FakeFingerprintEngineTest",
local_include_dirs: ["include"],
srcs: [
- "tests/WorkerThreadTest.cpp",
- "WorkerThread.cpp",
+ "tests/FakeFingerprintEngineTest.cpp",
+ "FakeFingerprintEngine.cpp",
+ "FakeLockoutTracker.cpp",
],
shared_libs: [
- "libcutils",
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.biometrics.common.thread",
],
+ static_libs: [
+ "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-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.fingerprint.FakeFingerprintEngineUdfpsTest",
+ local_include_dirs: ["include"],
+ srcs: [
+ "tests/FakeFingerprintEngineUdfpsTest.cpp",
+ "FakeFingerprintEngineUdfps.cpp",
+ "FakeFingerprintEngine.cpp",
+ "FakeLockoutTracker.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.biometrics.common.thread",
+ ],
+ static_libs: [
+ "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-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.fingerprint.FakeLockoutTrackerTest",
+ local_include_dirs: ["include"],
+ srcs: [
+ "tests/FakeLockoutTrackerTest.cpp",
+ "FakeLockoutTracker.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.biometrics.common.thread",
+ ],
+ static_libs: [
+ "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
+ "android.hardware.biometrics.common.util",
+ ],
+ vendor: true,
+ test_suites: ["general-tests"],
+ require_root: true,
+}
+
+sysprop_library {
+ name: "android.hardware.biometrics.fingerprint.VirtualProps",
+ srcs: ["fingerprint.sysprop"],
+ property_owner: "Vendor",
+ vendor: true,
}
diff --git a/biometrics/fingerprint/aidl/default/CancellationSignal.cpp b/biometrics/fingerprint/aidl/default/CancellationSignal.cpp
deleted file mode 100644
index 6598316..0000000
--- a/biometrics/fingerprint/aidl/default/CancellationSignal.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-#include "CancellationSignal.h"
-
-#include <android-base/logging.h>
-#include <chrono>
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-CancellationSignal::CancellationSignal(std::promise<void>&& cancellationPromise)
- : mCancellationPromise(std::move(cancellationPromise)) {}
-
-ndk::ScopedAStatus CancellationSignal::cancel() {
- mCancellationPromise.set_value();
- return ndk::ScopedAStatus::ok();
-}
-
-bool shouldCancel(const std::future<void>& f) {
- CHECK(f.valid());
- return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
-}
-
-} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
new file mode 100644
index 0000000..90ec8f2
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngine.h"
+#include <regex>
+#include "Fingerprint.h"
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using ::android::base::ParseInt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+void FakeFingerprintEngine::generateChallengeImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ std::uniform_int_distribution<int64_t> dist;
+ auto challenge = dist(mRandom);
+ FingerprintHalProperties::challenge(challenge);
+ cb->onChallengeGenerated(challenge);
+}
+
+void FakeFingerprintEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
+ BEGIN_OP(0);
+ FingerprintHalProperties::challenge({});
+ cb->onChallengeRevoked(challenge);
+}
+
+void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
+ const keymaster::HardwareAuthToken& hat,
+ const std::future<void>& cancel) {
+ BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));
+
+ // Do proper HAT verification in the real implementation.
+ if (hat.mac.empty()) {
+ LOG(ERROR) << "Fail: hat";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ // Force error-out
+ auto err = FingerprintHalProperties::operation_enroll_error().value_or(0);
+ if (err != 0) {
+ LOG(ERROR) << "Fail: operation_enroll_error";
+ auto ec = convertError(err);
+ cb->onError(ec.first, ec.second);
+ return;
+ }
+
+ // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
+ auto nextEnroll = FingerprintHalProperties::next_enrollment().value_or("");
+ auto parts = Util::split(nextEnroll, ":");
+ if (parts.size() != 3) {
+ LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
+ cb->onError(Error::VENDOR, 0 /* vendorError */);
+ return;
+ }
+ auto enrollmentId = std::stoi(parts[0]);
+ auto progress = 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();
+
+ 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;
+ }
+ auto ac = convertAcquiredInfo(acquired[j]);
+ cb->onAcquired(ac.first, ac.second);
+ }
+
+ if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
+ LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
+ FingerprintHalProperties::next_enrollment({});
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
+ } else { // progress and update props if last time
+ LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
+ if (left == 0) {
+ auto enrollments = FingerprintHalProperties::enrollments();
+ enrollments.emplace_back(enrollmentId);
+ FingerprintHalProperties::enrollments(enrollments);
+ FingerprintHalProperties::next_enrollment({});
+ // change authenticatorId after new enrollment
+ auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+ auto newId = id + 1;
+ FingerprintHalProperties::authenticator_id(newId);
+ LOG(INFO) << "Enrolled: " << enrollmentId;
+ }
+ cb->onEnrollmentProgress(enrollmentId, left);
+ }
+ }
+}
+
+void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* operationId */,
+ const std::future<void>& cancel) {
+ BEGIN_OP(getLatency(FingerprintHalProperties::operation_authenticate_latency()));
+
+ int64_t now = Util::getSystemNanoTime();
+ int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(10);
+ auto acquired = FingerprintHalProperties::operation_authenticate_acquired().value_or("1");
+ auto acquiredInfos = parseIntSequence(acquired);
+ int N = acquiredInfos.size();
+
+ if (N == 0) {
+ LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ // got lockout?
+ FakeLockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
+ if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) {
+ LOG(ERROR) << "Fail: lockout permanent";
+ cb->onLockoutPermanent();
+ return;
+ } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) {
+ int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
+ LOG(ERROR) << "Fail: lockout timed " << timeLeft;
+ cb->onLockoutTimed(timeLeft);
+ }
+
+ int i = 0;
+ do {
+ if (FingerprintHalProperties::operation_authenticate_fails().value_or(false)) {
+ LOG(ERROR) << "Fail: operation_authenticate_fails";
+ mLockoutTracker.addFailedAttempt();
+ cb->onAuthenticationFailed();
+ return;
+ }
+
+ auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
+ if (err != 0) {
+ LOG(ERROR) << "Fail: operation_authenticate_error";
+ auto ec = convertError(err);
+ cb->onError(ec.first, ec.second);
+ return;
+ }
+
+ if (FingerprintHalProperties::lockout().value_or(false)) {
+ LOG(ERROR) << "Fail: lockout";
+ cb->onLockoutPermanent();
+ cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
+ return;
+ }
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+
+ if (i < N) {
+ auto ac = convertAcquiredInfo(acquiredInfos[i]);
+ cb->onAcquired(ac.first, ac.second);
+ i++;
+ }
+
+ SLEEP_MS(duration / N);
+ } while (!Util::hasElapsed(now, duration));
+
+ auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
+ auto enrolls = FingerprintHalProperties::enrollments();
+ auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+ if (id > 0 && isEnrolled) {
+ cb->onAuthenticationSucceeded(id, {} /* hat */);
+ mLockoutTracker.reset();
+ return;
+ } else {
+ LOG(ERROR) << "Fail: fingerprint not enrolled";
+ cb->onAuthenticationFailed();
+ mLockoutTracker.addFailedAttempt();
+ }
+}
+
+void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
+ const std::future<void>& cancel) {
+ BEGIN_OP(getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+
+ int64_t duration =
+ FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
+
+ auto detectInteractionSupported =
+ FingerprintHalProperties::detect_interaction().value_or(false);
+ if (!detectInteractionSupported) {
+ LOG(ERROR) << "Detect interaction is not supported";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
+ auto acquiredInfos = parseIntSequence(acquired);
+ int N = acquiredInfos.size();
+ int64_t now = Util::getSystemNanoTime();
+
+ if (N == 0) {
+ LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ int i = 0;
+ do {
+ auto err = FingerprintHalProperties::operation_detect_interaction_error().value_or(0);
+ if (err != 0) {
+ LOG(ERROR) << "Fail: operation_detect_interaction_error";
+ auto ec = convertError(err);
+ cb->onError(ec.first, ec.second);
+ return;
+ }
+
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+
+ if (i < N) {
+ auto ac = convertAcquiredInfo(acquiredInfos[i]);
+ cb->onAcquired(ac.first, ac.second);
+ i++;
+ }
+ SLEEP_MS(duration / N);
+ } while (!Util::hasElapsed(now, duration));
+
+ auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
+ auto enrolls = FingerprintHalProperties::enrollments();
+ auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
+ if (id <= 0 || !isEnrolled) {
+ LOG(ERROR) << "Fail: not enrolled";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+
+ cb->onInteractionDetected();
+}
+
+void FakeFingerprintEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+
+ std::vector<int32_t> ids;
+ // There are some enrollment sync issue with framework, which results in
+ // a single template removal during the very firt sync command after reboot.
+ // This is a workaround for now. TODO(b/243129174)
+ ids.push_back(-1);
+
+ for (auto& enrollment : FingerprintHalProperties::enrollments()) {
+ auto id = enrollment.value_or(0);
+ if (id > 0) {
+ ids.push_back(id);
+ }
+ }
+
+ cb->onEnrollmentsEnumerated(ids);
+}
+
+void FakeFingerprintEngine::removeEnrollmentsImpl(ISessionCallback* cb,
+ const std::vector<int32_t>& enrollmentIds) {
+ BEGIN_OP(0);
+
+ std::vector<std::optional<int32_t>> newEnrollments;
+ std::vector<int32_t> removed;
+ for (auto& enrollment : FingerprintHalProperties::enrollments()) {
+ auto id = enrollment.value_or(0);
+ if (std::find(enrollmentIds.begin(), enrollmentIds.end(), id) != enrollmentIds.end()) {
+ removed.push_back(id);
+ } else if (id > 0) {
+ newEnrollments.emplace_back(id);
+ }
+ }
+ FingerprintHalProperties::enrollments(newEnrollments);
+
+ cb->onEnrollmentsRemoved(enrollmentIds);
+}
+
+void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ int64_t authenticatorId;
+ if (FingerprintHalProperties::enrollments().size() == 0) {
+ authenticatorId = 0;
+ } else {
+ authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
+ if (authenticatorId == 0) authenticatorId = 1;
+ }
+ cb->onAuthenticatorIdRetrieved(authenticatorId);
+}
+
+void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
+ BEGIN_OP(0);
+ int64_t newId;
+ if (FingerprintHalProperties::enrollments().size() == 0) {
+ newId = 0;
+ } else {
+ auto id = FingerprintHalProperties::authenticator_id().value_or(0);
+ newId = id + 1;
+ }
+ FingerprintHalProperties::authenticator_id(newId);
+ cb->onAuthenticatorIdInvalidated(newId);
+}
+
+void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
+ const keymaster::HardwareAuthToken& hat) {
+ BEGIN_OP(0);
+ if (hat.mac.empty()) {
+ LOG(ERROR) << "Fail: hat in resetLockout()";
+ cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
+ return;
+ }
+ FingerprintHalProperties::lockout(false);
+ cb->onLockoutCleared();
+ mLockoutTracker.reset();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*/, int32_t /*x*/,
+ int32_t /*y*/, float /*minor*/,
+ float /*major*/) {
+ BEGIN_OP(0);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngine::onPointerUpImpl(int32_t /*pointerId*/) {
+ BEGIN_OP(0);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngine::onUiReadyImpl() {
+ BEGIN_OP(0);
+ return ndk::ScopedAStatus::ok();
+}
+
+bool FakeFingerprintEngine::getSensorLocationConfig(SensorLocation& out) {
+ auto loc = FingerprintHalProperties::sensor_location().value_or("");
+ auto isValidStr = false;
+ auto dim = Util::split(loc, ":");
+
+ if (dim.size() < 3 or dim.size() > 4) {
+ if (!loc.empty()) LOG(WARNING) << "Invalid sensor location input (x:y:radius):" + loc;
+ return false;
+ } else {
+ int32_t x, y, r;
+ std::string d = "";
+ if (dim.size() >= 3) {
+ isValidStr = ParseInt(dim[0], &x) && ParseInt(dim[1], &y) && ParseInt(dim[2], &r);
+ }
+ if (dim.size() >= 4) {
+ d = dim[3];
+ }
+ if (isValidStr) out = {0, x, y, r, d};
+
+ return isValidStr;
+ }
+}
+SensorLocation FakeFingerprintEngine::getSensorLocation() {
+ SensorLocation location;
+
+ if (getSensorLocationConfig(location)) {
+ return location;
+ } else {
+ return defaultSensorLocation();
+ }
+}
+
+SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
+ return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
+ 0 /* sensorRadius */, "" /* display */};
+}
+
+std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
+ const std::string& sep) {
+ std::vector<std::string> seqs = Util::split(str, sep);
+ std::vector<int32_t> res;
+
+ for (const auto& seq : seqs) {
+ int32_t val;
+ if (ParseInt(seq, &val)) {
+ res.push_back(val);
+ } else {
+ LOG(WARNING) << "Invalid int sequence:" + str;
+ res.clear();
+ break;
+ }
+ }
+
+ return res;
+}
+
+bool FakeFingerprintEngine::parseEnrollmentCaptureSingle(const std::string& str,
+ std::vector<std::vector<int32_t>>& res) {
+ std::vector<int32_t> defaultAcquiredInfo = {(int32_t)AcquiredInfo::GOOD};
+ bool aborted = true;
+
+ do {
+ std::smatch sms;
+ // Parses strings like "1000-[5,1]" or "500"
+ std::regex ex("((\\d+)(-\\[([\\d|,]+)\\])?)");
+ if (!regex_match(str.cbegin(), str.cend(), sms, ex)) break;
+ int32_t duration;
+ if (!ParseInt(sms.str(2), &duration)) break;
+ res.push_back({duration});
+ if (!sms.str(4).empty()) {
+ auto acqv = parseIntSequence(sms.str(4));
+ if (acqv.empty()) break;
+ res.push_back(acqv);
+ } else
+ res.push_back(defaultAcquiredInfo);
+ aborted = false;
+ } while (0);
+
+ return !aborted;
+}
+
+std::vector<std::vector<int32_t>> FakeFingerprintEngine::parseEnrollmentCapture(
+ const std::string& str) {
+ std::vector<std::vector<int32_t>> res;
+
+ std::string s(str);
+ s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
+ bool aborted = false;
+ std::smatch sms;
+ // Parses strings like "1000-[5,1],500,800-[6,5,1]"
+ // ---------- --- -----------
+ // into parts: A B C
+ while (regex_search(s, sms, std::regex("^(,)?(\\d+(-\\[[\\d|,]+\\])?)"))) {
+ if (!parseEnrollmentCaptureSingle(sms.str(2), res)) {
+ aborted = true;
+ break;
+ }
+ s = sms.suffix();
+ }
+ if (aborted || s.length() != 0) {
+ res.clear();
+ LOG(ERROR) << "Failed to parse enrollment captures:" + str;
+ }
+
+ return res;
+}
+
+std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
+ std::pair<AcquiredInfo, int32_t> res;
+ if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
+ res.first = AcquiredInfo::VENDOR;
+ res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
+ } else {
+ res.first = (AcquiredInfo)code;
+ res.second = 0;
+ }
+ return res;
+}
+
+std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
+ std::pair<Error, int32_t> res;
+ if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
+ res.first = Error::VENDOR;
+ res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
+ } else {
+ res.first = (Error)code;
+ res.second = 0;
+ }
+ return res;
+}
+
+int32_t FakeFingerprintEngine::getLatency(
+ const std::vector<std::optional<std::int32_t>>& latencyIn) {
+ int32_t res = DEFAULT_LATENCY;
+
+ std::vector<int32_t> latency;
+ for (auto x : latencyIn)
+ if (x.has_value()) latency.push_back(*x);
+
+ switch (latency.size()) {
+ case 0:
+ break;
+ case 1:
+ res = latency[0];
+ break;
+ case 2:
+ res = getRandomInRange(latency[0], latency[1]);
+ break;
+ default:
+ LOG(ERROR) << "ERROR: unexpected input of size " << latency.size();
+ break;
+ }
+
+ return res;
+}
+
+int32_t FakeFingerprintEngine::getRandomInRange(int32_t bound1, int32_t bound2) {
+ std::uniform_int_distribution<int32_t> dist(std::min(bound1, bound2), std::max(bound1, bound2));
+ return dist(mRandom);
+}
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineRear.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineRear.cpp
new file mode 100644
index 0000000..eea80d5
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineRear.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngineRear.h"
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {}
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
new file mode 100644
index 0000000..9f736e7
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineSide.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngineSide.h"
+
+#include <android-base/logging.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+SensorLocation FakeFingerprintEngineSide::defaultSensorLocation() {
+ SensorLocation location;
+
+ return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
+ defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
+ "" /* display */};
+}
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
new file mode 100644
index 0000000..3cdfc70
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngineUdfps.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeFingerprintEngineUdfps.h"
+
+#include <android-base/logging.h>
+
+#include <fingerprint.sysprop.h>
+
+#include "util/CancellationSignal.h"
+#include "util/Util.h"
+
+#undef LOG_TAG
+#define LOG_TAG "FingerprintVirtualHalUdfps"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+FakeFingerprintEngineUdfps::FakeFingerprintEngineUdfps()
+ : FakeFingerprintEngine(), mWorkMode(WorkMode::kIdle), mPointerDownTime(0), mUiReadyTime(0) {}
+
+SensorLocation FakeFingerprintEngineUdfps::defaultSensorLocation() {
+ return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
+ defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
+ "" /* display */};
+}
+
+ndk::ScopedAStatus FakeFingerprintEngineUdfps::onPointerDownImpl(int32_t /*pointerId*/,
+ int32_t /*x*/, int32_t /*y*/,
+ float /*minor*/, float /*major*/) {
+ BEGIN_OP(0);
+ // verify whetehr touch coordinates/area matching sensor location ?
+ mPointerDownTime = Util::getSystemNanoTime();
+ if (FingerprintHalProperties::control_illumination().value_or(false)) {
+ fingerDownAction();
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngineUdfps::onPointerUpImpl(int32_t /*pointerId*/) {
+ BEGIN_OP(0);
+ mUiReadyTime = 0;
+ mPointerDownTime = 0;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FakeFingerprintEngineUdfps::onUiReadyImpl() {
+ BEGIN_OP(0);
+
+ if (Util::hasElapsed(mPointerDownTime, uiReadyTimeoutInMs * 100)) {
+ LOG(ERROR) << "onUiReady() arrives too late after onPointerDown()";
+ } else {
+ fingerDownAction();
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+void FakeFingerprintEngineUdfps::fingerDownAction() {
+ switch (mWorkMode) {
+ case WorkMode::kAuthenticate:
+ onAuthenticateFingerDown();
+ break;
+ case WorkMode::kEnroll:
+ onEnrollFingerDown();
+ break;
+ case WorkMode::kDetectInteract:
+ onDetectInteractFingerDown();
+ break;
+ default:
+ LOG(WARNING) << "unexpected call: onUiReady()";
+ break;
+ }
+
+ mUiReadyTime = 0;
+ mPointerDownTime = 0;
+}
+
+void FakeFingerprintEngineUdfps::onAuthenticateFingerDown() {
+ FakeFingerprintEngine::authenticateImpl(mCb, mOperationId, mCancelVec[0]);
+}
+
+void FakeFingerprintEngineUdfps::onEnrollFingerDown() {
+ // Any use case to emulate display touch for each capture during enrollment?
+ FakeFingerprintEngine::enrollImpl(mCb, mHat, mCancelVec[0]);
+}
+
+void FakeFingerprintEngineUdfps::onDetectInteractFingerDown() {
+ FakeFingerprintEngine::detectInteractionImpl(mCb, mCancelVec[0]);
+}
+
+void FakeFingerprintEngineUdfps::enrollImpl(ISessionCallback* cb,
+ const keymaster::HardwareAuthToken& hat,
+ const std::future<void>& cancel) {
+ updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
+}
+
+void FakeFingerprintEngineUdfps::authenticateImpl(ISessionCallback* cb, int64_t operationId,
+ const std::future<void>& cancel) {
+ updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
+ keymaster::HardwareAuthToken());
+}
+
+void FakeFingerprintEngineUdfps::detectInteractionImpl(ISessionCallback* cb,
+ const std::future<void>& cancel) {
+ updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
+ keymaster::HardwareAuthToken());
+}
+
+void FakeFingerprintEngineUdfps::updateContext(WorkMode mode, ISessionCallback* cb,
+ std::future<void>& cancel, int64_t operationId,
+ const keymaster::HardwareAuthToken& hat) {
+ mPointerDownTime = 0;
+ mUiReadyTime = 0;
+ mCancelVec.clear();
+
+ mCancelVec.push_back(std::move(cancel));
+ mWorkMode = mode;
+ mCb = cb;
+ mOperationId = operationId;
+ mHat = hat;
+}
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
new file mode 100644
index 0000000..5996406
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FakeLockoutTracker.h"
+#include <fingerprint.sysprop.h>
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+void FakeLockoutTracker::reset() {
+ mFailedCount = 0;
+ mLockoutTimedStart = 0;
+ mCurrentMode = LockoutMode::kNone;
+}
+
+void FakeLockoutTracker::addFailedAttempt() {
+ bool enabled = FingerprintHalProperties::lockout_enable().value_or(false);
+ if (enabled) {
+ mFailedCount++;
+ int32_t lockoutTimedThreshold =
+ FingerprintHalProperties::lockout_timed_threshold().value_or(5);
+ int32_t lockoutPermanetThreshold =
+ FingerprintHalProperties::lockout_permanent_threshold().value_or(20);
+ if (mFailedCount >= lockoutPermanetThreshold) {
+ mCurrentMode = LockoutMode::kPermanent;
+ FingerprintHalProperties::lockout(true);
+ } else if (mFailedCount >= lockoutTimedThreshold) {
+ if (mCurrentMode == LockoutMode::kNone) {
+ mCurrentMode = LockoutMode::kTimed;
+ mLockoutTimedStart = Util::getSystemNanoTime();
+ }
+ }
+ } else {
+ reset();
+ }
+}
+
+FakeLockoutTracker::LockoutMode FakeLockoutTracker::getMode() {
+ if (mCurrentMode == LockoutMode::kTimed) {
+ int32_t lockoutTimedDuration =
+ FingerprintHalProperties::lockout_timed_duration().value_or(10 * 100);
+ if (Util::hasElapsed(mLockoutTimedStart, lockoutTimedDuration)) {
+ mCurrentMode = LockoutMode::kNone;
+ mLockoutTimedStart = 0;
+ }
+ }
+
+ return mCurrentMode;
+}
+
+int64_t FakeLockoutTracker::getLockoutTimeLeft() {
+ int64_t res = 0;
+
+ if (mLockoutTimedStart > 0) {
+ auto now = Util::getSystemNanoTime();
+ auto left = now - mLockoutTimedStart;
+ res = (left > 0) ? (left / 1000000LL) : 0;
+ }
+
+ return res;
+}
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 1f14de6..7808a13 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -15,16 +15,22 @@
*/
#include "Fingerprint.h"
-
#include "Session.h"
+#include <fingerprint.sysprop.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+using namespace ::android::fingerprint::virt;
+
namespace aidl::android::hardware::biometrics::fingerprint {
namespace {
constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;
-constexpr int SENSOR_ID = 1;
+constexpr int SENSOR_ID = 5;
constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG;
constexpr int MAX_ENROLLMENTS_PER_USER = 5;
-constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR;
constexpr bool SUPPORTS_NAVIGATION_GESTURES = true;
constexpr char HW_COMPONENT_ID[] = "fingerprintSensor";
constexpr char HW_VERSION[] = "vendor/model/revision";
@@ -35,27 +41,57 @@
} // namespace
-Fingerprint::Fingerprint()
- : mEngine(std::make_unique<FakeFingerprintEngine>()), mWorker(MAX_WORKER_QUEUE_SIZE) {}
+Fingerprint::Fingerprint() : mWorker(MAX_WORKER_QUEUE_SIZE) {
+ std::string sensorTypeProp = FingerprintHalProperties::type().value_or("");
+ if (sensorTypeProp == "" || sensorTypeProp == "default" || sensorTypeProp == "rear") {
+ mSensorType = FingerprintSensorType::REAR;
+ mEngine = std::make_unique<FakeFingerprintEngineRear>();
+ } else if (sensorTypeProp == "udfps") {
+ mSensorType = FingerprintSensorType::UNDER_DISPLAY_OPTICAL;
+ mEngine = std::make_unique<FakeFingerprintEngineUdfps>();
+ } else if (sensorTypeProp == "side") {
+ mSensorType = FingerprintSensorType::POWER_BUTTON;
+ mEngine = std::make_unique<FakeFingerprintEngineSide>();
+ } else {
+ mSensorType = FingerprintSensorType::UNKNOWN;
+ mEngine = std::make_unique<FakeFingerprintEngineRear>();
+ UNIMPLEMENTED(FATAL) << "unrecognized or unimplemented fingerprint behavior: "
+ << sensorTypeProp;
+ }
+ LOG(INFO) << "sensorTypeProp:" << sensorTypeProp;
+}
ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
std::vector<common::ComponentInfo> componentInfo = {
{HW_COMPONENT_ID, HW_VERSION, FW_VERSION, SERIAL_NUMBER, "" /* softwareVersion */},
{SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */,
"" /* serialNumber */, SW_VERSION}};
+ auto sensorId = FingerprintHalProperties::sensor_id().value_or(SENSOR_ID);
+ auto sensorStrength =
+ FingerprintHalProperties::sensor_strength().value_or((int)SENSOR_STRENGTH);
+ auto maxEnrollments =
+ FingerprintHalProperties::max_enrollments().value_or(MAX_ENROLLMENTS_PER_USER);
+ auto navigationGuesture = FingerprintHalProperties::navigation_guesture().value_or(false);
+ auto detectInteraction = FingerprintHalProperties::detect_interaction().value_or(false);
+ auto displayTouch = FingerprintHalProperties::display_touch().value_or(true);
+ auto controlIllumination = FingerprintHalProperties::control_illumination().value_or(false);
- common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER,
- componentInfo};
+ common::CommonProps commonProps = {sensorId, (common::SensorStrength)sensorStrength,
+ maxEnrollments, componentInfo};
- SensorLocation sensorLocation = {0 /* displayId (not used) */, 0 /* sensorLocationX */,
- 0 /* sensorLocationY */, 0 /* sensorRadius */,
- "" /* display */};
+ SensorLocation sensorLocation = mEngine->getSensorLocation();
+
+ LOG(INFO) << "sensor type:" << ::android::internal::ToString(mSensorType)
+ << " location:" << sensorLocation.toString();
*out = {{commonProps,
- SENSOR_TYPE,
+ mSensorType,
{sensorLocation},
- SUPPORTS_NAVIGATION_GESTURES,
- false /* supportsDetectInteraction */}};
+ navigationGuesture,
+ detectInteraction,
+ displayTouch,
+ controlIllumination,
+ std::nullopt}};
return ndk::ScopedAStatus::ok();
}
@@ -66,7 +102,101 @@
mSession = SharedRefBase::make<Session>(sensorId, userId, cb, mEngine.get(), &mWorker);
*out = mSession;
+
+ LOG(INFO) << "createSession: sensorId:" << sensorId << " userId:" << userId;
return ndk::ScopedAStatus::ok();
}
+binder_status_t Fingerprint::dump(int fd, const char** /*args*/, uint32_t numArgs) {
+ if (fd < 0) {
+ LOG(ERROR) << "Fingerprint::dump fd invalid: " << fd;
+ return STATUS_BAD_VALUE;
+ } else {
+ LOG(INFO) << "Fingerprint::dump fd:" << fd << "numArgs:" << numArgs;
+ }
+
+ dprintf(fd, "----- FingerprintVirtualHal::dump -----\n");
+ std::vector<SensorProps> sps(1);
+ getSensorProps(&sps);
+ for (auto& sp : sps) {
+ ::android::base::WriteStringToFd(sp.toString(), fd);
+ }
+ ::android::base::WriteStringToFd(mEngine->toString(), fd);
+
+ fsync(fd);
+ return STATUS_OK;
+}
+
+binder_status_t Fingerprint::handleShellCommand(int in, int out, int err, const char** args,
+ uint32_t numArgs) {
+ LOG(INFO) << "Fingerprint::handleShellCommand in:" << in << " out:" << out << " err:" << err
+ << " numArgs:" << numArgs;
+
+ if (numArgs == 0) {
+ LOG(INFO) << "Fingerprint::handleShellCommand: available commands";
+ onHelp(out);
+ return STATUS_OK;
+ }
+
+ for (auto&& str : std::vector<std::string_view>(args, args + numArgs)) {
+ std::string option = str.data();
+ if (option.find("clearconfig") != std::string::npos ||
+ option.find("resetconfig") != std::string::npos) {
+ resetConfigToDefault();
+ }
+ if (option.find("help") != std::string::npos) {
+ onHelp(out);
+ }
+ }
+
+ return STATUS_OK;
+}
+
+void Fingerprint::onHelp(int fd) {
+ dprintf(fd, "Virtual HAL commands:\n");
+ dprintf(fd, " help: print this help\n");
+ dprintf(fd, " resetconfig: reset all configuration to default\n");
+ dprintf(fd, "\n");
+ fsync(fd);
+}
+
+void Fingerprint::resetConfigToDefault() {
+ LOG(INFO) << "reset virtual HAL configuration to default";
+#define RESET_CONFIG_O(__NAME__) \
+ if (FingerprintHalProperties::__NAME__()) FingerprintHalProperties::__NAME__(std::nullopt)
+#define RESET_CONFIG_V(__NAME__) \
+ if (!FingerprintHalProperties::__NAME__().empty()) \
+ FingerprintHalProperties::__NAME__({std::nullopt})
+
+ RESET_CONFIG_O(type);
+ RESET_CONFIG_V(enrollments);
+ RESET_CONFIG_O(enrollment_hit);
+ RESET_CONFIG_O(authenticator_id);
+ RESET_CONFIG_O(challenge);
+ RESET_CONFIG_O(lockout);
+ RESET_CONFIG_O(operation_authenticate_fails);
+ RESET_CONFIG_O(operation_detect_interaction_error);
+ RESET_CONFIG_O(operation_enroll_error);
+ RESET_CONFIG_V(operation_authenticate_latency);
+ RESET_CONFIG_V(operation_detect_interaction_latency);
+ RESET_CONFIG_V(operation_enroll_latency);
+ RESET_CONFIG_O(operation_authenticate_duration);
+ RESET_CONFIG_O(operation_authenticate_error);
+ RESET_CONFIG_O(sensor_location);
+ RESET_CONFIG_O(operation_authenticate_acquired);
+ RESET_CONFIG_O(operation_detect_interaction_duration);
+ RESET_CONFIG_O(operation_detect_interaction_acquired);
+ RESET_CONFIG_O(sensor_id);
+ RESET_CONFIG_O(sensor_strength);
+ RESET_CONFIG_O(max_enrollments);
+ RESET_CONFIG_O(navigation_guesture);
+ RESET_CONFIG_O(detect_interaction);
+ RESET_CONFIG_O(display_touch);
+ RESET_CONFIG_O(control_illumination);
+ RESET_CONFIG_O(lockout_enable);
+ RESET_CONFIG_O(lockout_timed_threshold);
+ RESET_CONFIG_O(lockout_timed_duration);
+ RESET_CONFIG_O(lockout_permanent_threshold);
+}
+
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/README.md b/biometrics/fingerprint/aidl/default/README.md
new file mode 100644
index 0000000..49b6c9d
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/README.md
@@ -0,0 +1,165 @@
+# Virtual Fingerprint HAL
+
+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.
+
+## Supported Devices
+
+This HAL can be used on emulators, like cuttlefish, or on real devices. Add the
+following to your device's `.mk` file to include it:
+
+```
+PRODUCT_PACKAGES_DEBUG += android.hardware.biometrics.fingerprint-service.example
+```
+
+The virtual HAL will be ignored if a real HAL is also installed on the target
+device. Set the `biometric_virtual_enabled` settings and reboot the device to
+switch to the virtual HAL. Unset it and reboot again to switch back.
+
+## Getting Started
+
+First, set the type of sensor the device should use, enable the virtual
+extensions in the framework, and reboot.
+
+```shell
+$ adb root
+$ adb shell settings put secure biometric_virtual_enabled 1
+$ adb shell setprop persist.vendor.fingerprint.virtual.type rear
+$ adb reboot
+```
+
+### Enrollments
+
+Next, setup enrollments on the device. This can either be done through the UI,
+or via adb directly.
+
+#### Direct Enrollment
+
+To set enrollment directly without the UI:
+
+```shell
+$ adb root
+$ adb shell locksettings set-pin 0000
+$ adb shell setprop persist.vendor.fingerprint.virtual.enrollments 1
+$ adb shell cmd fingerprint sync
+```
+
+#### UI Enrollment
+
+1. Set pin
+ ```shell
+ $ adb shell locksettings set-pin 0000
+ ```
+2. Tee up the results of the enrollment before starting the process:
+
+ ```shell
+ $ adb shell setprop vendor.fingerprint.virtual.next_enrollment 1:100,100,100:true
+ ```
+
+3. Navigate to `Settings -> Security -> Fingerprint Unlock` and follow the
+ prompts.
+4. Verify the enrollments in the UI:
+
+ ```shell
+ $ adb shell getprop persist.vendor.fingerprint.virtual.enrollments
+ ```
+
+## Authenticate
+
+To authenticate successfully set the enrolled id that should succeed. Unset it
+or change the value to make authenticate operations fail:
+
+````shell
+$ adb shell setprop vendor.fingerprint.virtual.enrollment_hit 1
+````
+
+## Acquired Info Insertion
+
+Fingerprint image acquisition states at HAL are reported to framework via onAcquired() callback. The valid acquired state info for AIDL HAL include
+
+{UNKNOWN(0), GOOD(1), PARTIAL(2), INSUFFICIENT(3), SENSOR_DIRTY(4), TOO_SLOW(5), TOO_FAST(6), VENDOR(7), START(8), TOO_DARK(9), TOO_BRIGHT(10), IMMOBILE(11), RETRYING_CAPTURE(12)}
+
+Refer to [AcquiredInfo.aidl](../android/hardware/biometrics/fingerprint/AcquiredInfo.aidl) for details
+
+
+The states can be specified in sequence for the HAL operations involving fingerprint image captures, namely authenticate, enrollment and detectInteraction
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_acquired 6,9,1
+$ adb shell setprop vendor.fingerprint.virtual.operation_detect_interaction_acquired 6,1
+$ adb shell setprop vendor.fingerprint.virtual.next_enrollment 2:1000-[5,1],500:true
+
+#next_enrollment format example:
+.---------------------- enrollment id (2)
+| .------------------ the image capture 1 duration (1000ms)
+| | .-------------- acquired info first (TOO_SLOW)
+| | | .------------ acquired info second (GOOD)
+| | | | .-------- the image capture 2 duration (500ms)
+| | | | | .---- enrollment end status (success)
+| | | | | |
+| | | | | |
+| | | | | |
+2:1000-[5,1],500:true
+```
+For vendor specific acquired info, acquiredInfo = 1000 + vendorAcquiredInfo
+
+## Error Insertion
+The valid error codes for AIDL HAL include
+
+{UNKNOWN(0), HW_UNAVAILABLE(1), UNABLE_TO_PROCESS(2), TIMEOUT(3), NO_SPACE(4), CANCELED(5), UNABLE_TO_REMOVE(6), VENDOR(7), BAD_CALIBRATION(8)}
+
+Refer to [Error.aidl](../android/hardware/biometrics/fingerprint/Error.aidl) for details
+
+
+There are many HAL operations which can result in errors, refer to [here](fingerprint.sysprop) file for details.
+
+```shell
+$ adb shell setprop vendor.fingerprint.virtual.operation_authenticate_error 8
+```
+For vendor specific error, errorCode = 1000 + vendorErrorCode
+
+## Latency Insertion
+Three HAL operations (authenticate, enrollment and detect interaction) latency can be optionally specified in multiple ways
+1. default latency is fixed at 400 ms if not specified via sysprop
+2. specify authenticate operation latency to 900 ms
+ ```shell adb shell setprop vendor.fingerprint.virtual.operation_authenticate_latency 900```
+3. specify authenticate operation latency between 600 to 1200 ms in unifrom distribution
+ ```shelladb shell setprop vendor.fingerprint.virtual.operation_authenticate_latency 600,1200```
+
+## Lockout
+To force the device into lockout state
+```shell
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout true
+```
+To test permanent lockout based on the failed authentication attempts (e.g. 7)
+```shell
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_permanent_threshold 7
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_enable true
+```
+To test timed lockout based on the failed authentication attempts (e.g. 8 seconds on 5 attempts)
+```shell
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_timed_duration 8000
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_timed_threshold 5
+$ adb shell setprop persist.vendor.fingerprint.virtual.lockout_enable true
+```
+
+## Reset all configurations to default
+The following command will reset virtual configurations (related system properties) to default value.
+```shell
+$ adb shell cmd android.hardware.biometrics.fingerprint.IFingerprint/virtual resetconfig
+$ adb reboot
+```
+
+## View HAL State
+
+To view all the properties of the HAL (see `fingerprint.sysprop` file for the API):
+
+```shell
+$ adb shell getprop | grep vendor.fingerprint.virtual
+```
+To dump virtual HAL internal data
+```shell
+adb shell dumpsys android.hardware.biometrics.fingerprint.IFingerprint/virtual
+```
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index 452ed12..38d6a13 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -18,7 +18,10 @@
#include <android-base/logging.h>
-#include "CancellationSignal.h"
+#include "util/CancellationSignal.h"
+
+#undef LOG_TAG
+#define LOG_TAG "FingerprintVirtualHalSession"
namespace aidl::android::hardware::biometrics::fingerprint {
@@ -101,7 +104,7 @@
if (shouldCancel(cancFuture)) {
mCb->onError(Error::CANCELED, 0 /* vendorCode */);
} else {
- mEngine->enrollImpl(mCb.get(), hat);
+ mEngine->enrollImpl(mCb.get(), hat, cancFuture);
}
enterIdling();
}));
@@ -123,7 +126,7 @@
if (shouldCancel(cancFuture)) {
mCb->onError(Error::CANCELED, 0 /* vendorCode */);
} else {
- mEngine->authenticateImpl(mCb.get(), operationId);
+ mEngine->authenticateImpl(mCb.get(), operationId, cancFuture);
}
enterIdling();
}));
@@ -144,7 +147,7 @@
if (shouldCancel(cancFuture)) {
mCb->onError(Error::CANCELED, 0 /* vendorCode */);
} else {
- mEngine->detectInteractionImpl(mCb.get());
+ mEngine->detectInteractionImpl(mCb.get(), cancFuture);
}
enterIdling();
}));
@@ -167,7 +170,7 @@
}
ndk::ScopedAStatus Session::removeEnrollments(const std::vector<int32_t>& enrollmentIds) {
- LOG(INFO) << "removeEnrollments";
+ LOG(INFO) << "removeEnrollments, size:" << enrollmentIds.size();
scheduleStateOrCrash(SessionState::REMOVING_ENROLLMENTS);
mWorker->schedule(Callable::from([this, enrollmentIds] {
@@ -228,19 +231,31 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/,
- float /*minor*/, float /*major*/) {
+ndk::ScopedAStatus Session::onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor,
+ float major) {
LOG(INFO) << "onPointerDown";
+ mWorker->schedule(Callable::from([this, pointerId, x, y, minor, major] {
+ mEngine->onPointerDownImpl(pointerId, x, y, minor, major);
+ enterIdling();
+ }));
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) {
+ndk::ScopedAStatus Session::onPointerUp(int32_t pointerId) {
LOG(INFO) << "onPointerUp";
+ mWorker->schedule(Callable::from([this, pointerId] {
+ mEngine->onPointerUpImpl(pointerId);
+ enterIdling();
+ }));
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Session::onUiReady() {
LOG(INFO) << "onUiReady";
+ mWorker->schedule(Callable::from([this] {
+ mEngine->onUiReadyImpl();
+ enterIdling();
+ }));
return ndk::ScopedAStatus::ok();
}
@@ -274,4 +289,12 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Session::onPointerCancelWithContext(const PointerContext& /*context*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Session::setIgnoreDisplayTouches(bool /*shouldIgnore*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/WorkerThread.cpp b/biometrics/fingerprint/aidl/default/WorkerThread.cpp
deleted file mode 100644
index d1a63d0..0000000
--- a/biometrics/fingerprint/aidl/default/WorkerThread.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-#include "WorkerThread.h"
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-// It's important that mThread is initialized after everything else because it runs a member
-// function that may use any member of this class.
-WorkerThread::WorkerThread(size_t maxQueueSize)
- : mMaxSize(maxQueueSize),
- mIsDestructing(false),
- mQueue(),
- mQueueMutex(),
- mQueueCond(),
- mThread(&WorkerThread::threadFunc, this) {}
-
-WorkerThread::~WorkerThread() {
- // This is a signal for threadFunc to terminate as soon as possible, and a hint for schedule
- // that it doesn't need to do any work.
- mIsDestructing = true;
- mQueueCond.notify_all();
- mThread.join();
-}
-
-bool WorkerThread::schedule(std::unique_ptr<Callable> task) {
- if (mIsDestructing) {
- return false;
- }
-
- std::unique_lock<std::mutex> lock(mQueueMutex);
- if (mQueue.size() >= mMaxSize) {
- return false;
- }
- mQueue.push_back(std::move(task));
- lock.unlock();
- mQueueCond.notify_one();
- return true;
-}
-
-void WorkerThread::threadFunc() {
- while (!mIsDestructing) {
- std::unique_lock<std::mutex> lock(mQueueMutex);
- mQueueCond.wait(lock, [this] { return !mQueue.empty() || mIsDestructing; });
- if (mIsDestructing) {
- return;
- }
- std::unique_ptr<Callable> task = std::move(mQueue.front());
- mQueue.pop_front();
- lock.unlock();
- (*task)();
- }
-}
-
-} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.rc b/biometrics/fingerprint/aidl/default/fingerprint-default.rc
deleted file mode 100644
index eb62c56..0000000
--- a/biometrics/fingerprint/aidl/default/fingerprint-default.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.example
- class hal
- user nobody
- group nobody
-
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.xml b/biometrics/fingerprint/aidl/default/fingerprint-default.xml
deleted file mode 100644
index d322eb6..0000000
--- a/biometrics/fingerprint/aidl/default/fingerprint-default.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.biometrics.fingerprint</name>
- <version>2</version>
- <fqname>IFingerprint/default</fqname>
- </hal>
-</manifest>
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.rc b/biometrics/fingerprint/aidl/default/fingerprint-example.rc
new file mode 100644
index 0000000..ee4713c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.rc
@@ -0,0 +1,7 @@
+service vendor.fingerprint-example /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.example
+ class hal
+ user nobody
+ group nobody
+ interface aidl android.hardware.biometrics.fingerprint.IFingerprint/virtual
+ oneshot
+ disabled
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
new file mode 100644
index 0000000..e977b98
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.biometrics.fingerprint</name>
+ <version>3</version>
+ <fqname>IFingerprint/virtual</fqname>
+ </hal>
+</manifest>
diff --git a/biometrics/fingerprint/aidl/default/fingerprint.sysprop b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
new file mode 100644
index 0000000..6a6c297
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
@@ -0,0 +1,300 @@
+# fingerprint.sysprop
+# module becomes static class (Java) / namespace (C++) for serving API
+module: "android.fingerprint.virt.FingerprintHalProperties"
+owner: Vendor
+
+# type of fingerprint sensor
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.type"
+ type: String
+ scope: Internal
+ access: ReadWrite
+ enum_values: "default|rear|udfps|side"
+ api_name: "type"
+}
+
+# ids of call current enrollments
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.enrollments"
+ type: IntegerList
+ scope: Internal
+ access: ReadWrite
+ api_name: "enrollments"
+}
+
+# authenticate and detectInteraction will succeed with this
+# enrollment id, when present, otherwise they will error
+prop {
+ prop_name: "vendor.fingerprint.virtual.enrollment_hit"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "enrollment_hit"
+}
+
+# the next enrollment in the format of:
+# "<id>:<delay>,<delay>,...:<result>"
+# <delay> = <duration-[acquiredInfos]>
+# [acquiredInfos] = [acquiredInfo1, acquiredInfo2, ...]
+# (refer to README.md file for acquiredInfo values)
+# e.g. "2:100,20:true", "2:100-[5,1],20:true"
+# this property is reset after enroll completes
+prop {
+ prop_name: "vendor.fingerprint.virtual.next_enrollment"
+ type: String
+ scope: Internal
+ access: ReadWrite
+ api_name: "next_enrollment"
+}
+
+# value for getAuthenticatorId or 0
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
+ type: Long
+ scope: Internal
+ access: ReadWrite
+ api_name: "authenticator_id"
+}
+
+# value for generateChallenge
+prop {
+ prop_name: "vendor.fingerprint.virtual.challenge"
+ type: Long
+ scope: Internal
+ access: ReadWrite
+ api_name: "challenge"
+}
+
+# force all authenticate operations to fail
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_fails"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_authenticate_fails"
+}
+
+# force all detectInteraction operations to error out
+# error consists of errorCode and vendorErrorCode
+# valid errorCodes are listed in README.md file
+# vendorErrorCode = (error>1000) ? error-1000 : 0
+# e.g. error(1002) --> errorCode(7) and vendorErrorCode(2)
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_detect_interaction_error"
+}
+
+# force all enroll operations to result in error
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_enroll_error"
+}
+
+# add a latency to authentication operations
+# default to 400ms
+# [x] = x ms
+# [x,y] = randomly between x and y ms
+# others = invalid
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
+ type: IntegerList
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_authenticate_latency"
+}
+
+# add a latency to detectInteraction operations
+# refer to `operation_authenticate_latency` above for usage
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
+ type: IntegerList
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_detect_interaction_latency"
+}
+
+# add a latency to enroll operations
+# refer to `operation_authenticate_latency` above for usage
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
+ type: IntegerList
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_enroll_latency"
+}
+
+# millisecond duration for authenticate operations
+# (waits for changes to enrollment_hit)
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_authenticate_duration"
+}
+
+# insert error for authenticate operations
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_authenticate_error"
+}
+
+# sensor location
+# <x>:<y>:<radius> in pixel
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
+ type: String
+ scope: Internal
+ access: ReadWrite
+ api_name: "sensor_location"
+}
+
+# acquired info during authentication in format of sequence
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+ type: String
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_authenticate_acquired"
+}
+
+# millisecond duration for detect interaction operations
+# (waits for changes to enrollment_hit)
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_detect_interaction_duration"
+}
+
+# acquired info during detect interaction operation in format of sequence
+# e.g. 5,6,1 (TOO_SLOW, TOO_FAST, GOOD)
+# onAcquired() callback will be invoked in sequence
+# vendorAcquiredCode = (acquired>1000) ? acquired-1000 : 0
+prop {
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+ type: String
+ scope: Internal
+ access: ReadWrite
+ api_name: "operation_detect_interaction_acquired"
+}
+
+# sensor id (default: 5)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "sensor_id"
+}
+
+# sensor strength (default: 2)
+# [0=CONVENECE, 1=WEAK, 2=STRONG]
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "sensor_strength"
+}
+
+# max enrollments per user (default: 5)
+#
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "max_enrollments"
+}
+
+# whether support navigation guestures (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "navigation_guesture"
+}
+
+# whether support detect interaction (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "detect_interaction"
+}
+
+# whether support display touch by hal (default: true)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "display_touch"
+}
+
+# whether support illumination control by hal (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "control_illumination"
+}
+
+# force to be locked out (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.lockout"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout"
+}
+
+# whether support lockout based on the failed auth attempts (default: false)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.lockout_enable"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_enable"
+}
+
+# temporarily lockout threshold in number of consecutive failed auth attempts (default: 5)
+prop {
+ prop_name: "persist.vendor.fingerprint.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.fingerprint.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 (default: 20)
+prop {
+ prop_name: "persist.vendor.fingerprint.virtual.lockout_permanent_threshold"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_permanent_threshold"
+}
diff --git a/biometrics/fingerprint/aidl/default/include/Callable.h b/biometrics/fingerprint/aidl/default/include/Callable.h
deleted file mode 100644
index c629511..0000000
--- a/biometrics/fingerprint/aidl/default/include/Callable.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-// Interface for representing parameterless functions. Unlike std::function<void()>, this can also
-// represent move-only lambdas.
-class Callable {
- public:
- virtual void operator()() = 0;
- virtual ~Callable() = default;
-
- // Creates a heap-allocated Callable instance from any function object.
- template <typename T>
- static std::unique_ptr<Callable> from(T func);
-
- private:
- template <typename T>
- class AnyFuncWrapper;
-};
-
-// Private helper class for wrapping any function object into a Callable.
-template <typename T>
-class Callable::AnyFuncWrapper : public Callable {
- public:
- explicit AnyFuncWrapper(T func) : mFunc(std::move(func)) {}
-
- void operator()() override { mFunc(); }
-
- private:
- T mFunc;
-};
-
-template <typename T>
-std::unique_ptr<Callable> Callable::from(T func) {
- return std::make_unique<AnyFuncWrapper<T>>(std::move(func));
-}
-
-} // namespace aidl::android::hardware::biometrics::fingerprint
\ No newline at end of file
diff --git a/biometrics/fingerprint/aidl/default/include/CancellationSignal.h b/biometrics/fingerprint/aidl/default/include/CancellationSignal.h
deleted file mode 100644
index 99f2fba..0000000
--- a/biometrics/fingerprint/aidl/default/include/CancellationSignal.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <aidl/android/hardware/biometrics/common/BnCancellationSignal.h>
-#include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
-#include <functional>
-#include <future>
-
-#include "WorkerThread.h"
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-class CancellationSignal : public common::BnCancellationSignal {
- public:
- explicit CancellationSignal(std::promise<void>&& cancellationPromise);
-
- ndk::ScopedAStatus cancel() override;
-
- private:
- std::promise<void> mCancellationPromise;
-};
-
-// Returns whether the given cancellation future is ready, i.e. whether the operation corresponding
-// to this future should be cancelled.
-bool shouldCancel(const std::future<void>& cancellationFuture);
-
-} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index b927770..1279cd9 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -16,73 +16,83 @@
#pragma once
-#include <android-base/logging.h>
+#define LOG_TAG "FingerprintVirtualHal"
+
+#include <aidl/android/hardware/biometrics/common/SensorStrength.h>
+#include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
+#include <android/binder_to_string.h>
+#include <string>
+
#include <random>
+#include <aidl/android/hardware/biometrics/fingerprint/SensorLocation.h>
+#include <future>
+#include <vector>
+
+#include "FakeLockoutTracker.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
namespace aidl::android::hardware::biometrics::fingerprint {
+// A fake engine that is backed by system properties instead of hardware.
class FakeFingerprintEngine {
public:
FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {}
+ virtual ~FakeFingerprintEngine() {}
- void generateChallengeImpl(ISessionCallback* cb) {
- LOG(INFO) << "generateChallengeImpl";
- std::uniform_int_distribution<int64_t> dist;
- auto challenge = dist(mRandom);
- cb->onChallengeGenerated(challenge);
- }
+ void generateChallengeImpl(ISessionCallback* cb);
+ void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge);
+ virtual void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ const std::future<void>& cancel);
+ virtual void authenticateImpl(ISessionCallback* cb, int64_t operationId,
+ const std::future<void>& cancel);
+ virtual void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
+ void enumerateEnrollmentsImpl(ISessionCallback* cb);
+ void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector<int32_t>& enrollmentIds);
+ void getAuthenticatorIdImpl(ISessionCallback* cb);
+ void invalidateAuthenticatorIdImpl(ISessionCallback* cb);
+ void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/);
+ bool getSensorLocationConfig(SensorLocation& out);
- void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
- LOG(INFO) << "revokeChallengeImpl";
- cb->onChallengeRevoked(challenge);
- }
+ virtual ndk::ScopedAStatus onPointerDownImpl(int32_t pointerId, int32_t x, int32_t y,
+ float minor, float major);
- void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat) {
- LOG(INFO) << "enrollImpl";
- // Do proper HAT verification in the real implementation.
- if (hat.mac.empty()) {
- cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
- return;
- }
- cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */);
- }
+ virtual ndk::ScopedAStatus onPointerUpImpl(int32_t pointerId);
- void authenticateImpl(ISessionCallback* cb, int64_t /* operationId */) {
- LOG(INFO) << "authenticateImpl";
- cb->onAuthenticationSucceeded(0 /* enrollmentId */, {} /* hat */);
- }
+ virtual ndk::ScopedAStatus onUiReadyImpl();
- void detectInteractionImpl(ISessionCallback* cb) {
- LOG(INFO) << "detectInteractionImpl";
- cb->onInteractionDetected();
- }
+ virtual SensorLocation getSensorLocation();
- void enumerateEnrollmentsImpl(ISessionCallback* cb) {
- LOG(INFO) << "enumerateEnrollmentsImpl";
- cb->onEnrollmentsEnumerated({} /* enrollmentIds */);
- }
+ virtual SensorLocation defaultSensorLocation();
- void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector<int32_t>& enrollmentIds) {
- LOG(INFO) << "removeEnrollmentsImpl";
- cb->onEnrollmentsRemoved(enrollmentIds);
- }
+ std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");
- void getAuthenticatorIdImpl(ISessionCallback* cb) {
- LOG(INFO) << "getAuthenticatorIdImpl";
- cb->onAuthenticatorIdRetrieved(0 /* authenticatorId */);
- }
+ std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
- void invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
- LOG(INFO) << "invalidateAuthenticatorIdImpl";
- cb->onAuthenticatorIdInvalidated(0 /* newAuthenticatorId */);
- }
-
- void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) {
- LOG(INFO) << "resetLockoutImpl";
- cb->onLockoutCleared();
- }
+ int32_t getLatency(const std::vector<std::optional<std::int32_t>>& latencyVec);
std::mt19937 mRandom;
+
+ virtual std::string toString() const {
+ std::ostringstream os;
+ os << "----- FakeFingerprintEngine:: -----" << std::endl;
+ os << "acquiredVendorInfoBase:" << FINGERPRINT_ACQUIRED_VENDOR_BASE;
+ os << ", errorVendorBase:" << FINGERPRINT_ERROR_VENDOR_BASE << std::endl;
+ os << mLockoutTracker.toString();
+ return os.str();
+ }
+
+ private:
+ static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
+ static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
+ std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
+ std::pair<Error, int32_t> convertError(int32_t code);
+ bool parseEnrollmentCaptureSingle(const std::string& str,
+ std::vector<std::vector<int32_t>>& res);
+ int32_t getRandomInRange(int32_t bound1, int32_t bound2);
+
+ FakeLockoutTracker mLockoutTracker;
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineRear.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineRear.h
new file mode 100644
index 0000000..14d5399
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineRear.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "FakeFingerprintEngine.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFingerprintEngineRear : public FakeFingerprintEngine {
+ public:
+ FakeFingerprintEngineRear() : FakeFingerprintEngine() {}
+ ~FakeFingerprintEngineRear() {}
+};
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
new file mode 100644
index 0000000..c2fc005
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineSide.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "FakeFingerprintEngine.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFingerprintEngineSide : public FakeFingerprintEngine {
+ public:
+ static constexpr int32_t defaultSensorLocationX = 0;
+ static constexpr int32_t defaultSensorLocationY = 600;
+ static constexpr int32_t defaultSensorRadius = 150;
+
+ FakeFingerprintEngineSide() : FakeFingerprintEngine() {}
+ ~FakeFingerprintEngineSide() {}
+
+ virtual SensorLocation defaultSensorLocation() override;
+};
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
new file mode 100644
index 0000000..c5e93e7
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngineUdfps.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#pragma once
+#include "FakeFingerprintEngine.h"
+
+using namespace ::aidl::android::hardware::biometrics::common;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+// A fake engine that is backed by system properties instead of hardware.
+class FakeFingerprintEngineUdfps : public FakeFingerprintEngine {
+ public:
+ static constexpr int32_t defaultSensorLocationX = 400;
+ static constexpr int32_t defaultSensorLocationY = 1600;
+ static constexpr int32_t defaultSensorRadius = 150;
+
+ static constexpr int32_t uiReadyTimeoutInMs = 5000;
+
+ FakeFingerprintEngineUdfps();
+ ~FakeFingerprintEngineUdfps() {}
+
+ ndk::ScopedAStatus onPointerDownImpl(int32_t pointerId, int32_t x, int32_t y, float minor,
+ float major) override;
+
+ ndk::ScopedAStatus onPointerUpImpl(int32_t pointerId) override;
+
+ ndk::ScopedAStatus onUiReadyImpl() override;
+
+ SensorLocation defaultSensorLocation() override;
+
+ void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
+ const std::future<void>& cancel);
+ void authenticateImpl(ISessionCallback* cb, int64_t operationId,
+ const std::future<void>& cancel);
+ void detectInteractionImpl(ISessionCallback* cb, const std::future<void>& cancel);
+
+ enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };
+
+ WorkMode getWorkMode() { return mWorkMode; }
+
+ std::string toString() const {
+ std::ostringstream os;
+ os << FakeFingerprintEngine::toString();
+ os << "----- FakeFingerprintEngineUdfps -----" << std::endl;
+ os << "mWorkMode:" << (int)mWorkMode;
+ os << ", mUiReadyTime:" << mUiReadyTime;
+ os << ", mPointerDownTime:" << mPointerDownTime << std::endl;
+ return os.str();
+ }
+
+ private:
+ void onAuthenticateFingerDown();
+ void onEnrollFingerDown();
+ void onDetectInteractFingerDown();
+ void fingerDownAction();
+ void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
+ int64_t operationId, const keymaster::HardwareAuthToken& hat);
+
+ WorkMode mWorkMode;
+ ISessionCallback* mCb;
+ keymaster::HardwareAuthToken mHat;
+ std::vector<std::future<void>> mCancelVec;
+ int64_t mOperationId;
+ int64_t mPointerDownTime;
+ int64_t mUiReadyTime;
+};
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
new file mode 100644
index 0000000..a1b6128
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_to_string.h>
+#include <stdint.h>
+#include <string>
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class FakeLockoutTracker {
+ public:
+ FakeLockoutTracker() : mFailedCount(0) {}
+ ~FakeLockoutTracker() {}
+
+ enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
+
+ void reset();
+ LockoutMode getMode();
+ void addFailedAttempt();
+ int64_t getLockoutTimeLeft();
+ inline std::string toString() const {
+ std::ostringstream os;
+ os << "----- FakeLockoutTracker:: -----" << std::endl;
+ os << "FakeLockoutTracker::mFailedCount:" << mFailedCount;
+ os << ", FakeLockoutTracker::mCurrentMode:" << (int)mCurrentMode;
+ os << std::endl;
+ return os.str();
+ }
+
+ private:
+ int32_t mFailedCount;
+ int64_t mLockoutTimedStart;
+ LockoutMode mCurrentMode;
+};
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
index 7bd3d6d..fc4fb8d 100644
--- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
@@ -19,8 +19,12 @@
#include <aidl/android/hardware/biometrics/fingerprint/BnFingerprint.h>
#include "FakeFingerprintEngine.h"
+#include "FakeFingerprintEngineRear.h"
+#include "FakeFingerprintEngineSide.h"
+#include "FakeFingerprintEngineUdfps.h"
+
#include "Session.h"
-#include "WorkerThread.h"
+#include "thread/WorkerThread.h"
namespace aidl::android::hardware::biometrics::fingerprint {
@@ -33,11 +37,17 @@
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* out) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs);
+ binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc);
private:
+ void resetConfigToDefault();
+ void onHelp(int);
+
std::unique_ptr<FakeFingerprintEngine> mEngine;
WorkerThread mWorker;
std::shared_ptr<Session> mSession;
+ FingerprintSensorType mSensorType;
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h
index acd5def..b596d9e 100644
--- a/biometrics/fingerprint/aidl/default/include/Session.h
+++ b/biometrics/fingerprint/aidl/default/include/Session.h
@@ -20,7 +20,7 @@
#include <aidl/android/hardware/biometrics/fingerprint/ISessionCallback.h>
#include "FakeFingerprintEngine.h"
-#include "WorkerThread.h"
+#include "thread/WorkerThread.h"
namespace aidl::android::hardware::biometrics::fingerprint {
@@ -97,6 +97,10 @@
ndk::ScopedAStatus onContextChanged(const common::OperationContext& context) override;
+ ndk::ScopedAStatus onPointerCancelWithContext(const PointerContext& context) override;
+
+ ndk::ScopedAStatus setIgnoreDisplayTouches(bool shouldIgnore) override;
+
bool isClosed();
private:
diff --git a/biometrics/fingerprint/aidl/default/include/WorkerThread.h b/biometrics/fingerprint/aidl/default/include/WorkerThread.h
deleted file mode 100644
index 6fff4f2..0000000
--- a/biometrics/fingerprint/aidl/default/include/WorkerThread.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include <mutex>
-#include <optional>
-#include <queue>
-#include <thread>
-
-#include "Callable.h"
-
-namespace aidl::android::hardware::biometrics::fingerprint {
-
-// A class that encapsulates a worker thread and a task queue, and provides a convenient interface
-// for a Session to schedule its tasks for asynchronous execution.
-class WorkerThread final {
- public:
- // Internally creates a queue that cannot exceed maxQueueSize elements and a new thread that
- // polls the queue for tasks until this instance is destructed.
- explicit WorkerThread(size_t maxQueueSize);
-
- // Unblocks the internal queue and calls join on the internal thread allowing it to gracefully
- // exit.
- ~WorkerThread();
-
- // Disallow copying this class.
- WorkerThread(const WorkerThread&) = delete;
- WorkerThread& operator=(const WorkerThread&) = delete;
-
- // Also disable moving this class to simplify implementation.
- WorkerThread(WorkerThread&&) = delete;
- WorkerThread& operator=(WorkerThread&&) = delete;
-
- // If the internal queue is not full, pushes a task at the end of the queue and returns true.
- // Otherwise, returns false. If the queue is busy, blocks until it becomes available.
- // This method expects heap-allocated tasks because it's the simplest way to represent function
- // objects of any type. Stack-allocated std::function could be used instead, but it cannot
- // represent functions with move-only captures because std::function is inherently copyable.
- // Not being able to pass move-only lambdas is a major limitation for the HAL implementation,
- // so heap-allocated tasks that share a common interface (Callable) were chosen instead.
- bool schedule(std::unique_ptr<Callable> task);
-
- private:
- // The function that runs on the internal thread. Sequentially runs the available tasks from
- // the queue. If the queue is empty, waits until a new task is added. If the worker is being
- // destructed, finishes its current task and gracefully exits.
- void threadFunc();
-
- // The maximum size that the queue is allowed to expand to.
- size_t mMaxSize;
-
- // Whether the destructor was called. If true, tells threadFunc to exit as soon as possible, and
- // tells schedule to avoid doing any work.
- std::atomic<bool> mIsDestructing;
-
- // Queue that's guarded by mQueueMutex and mQueueCond.
- std::deque<std::unique_ptr<Callable>> mQueue;
- std::mutex mQueueMutex;
- std::condition_variable mQueueCond;
-
- // The internal thread that works on the tasks from the queue.
- std::thread mThread;
-};
-
-} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp
index c985201..7df015b 100644
--- a/biometrics/fingerprint/aidl/default/main.cpp
+++ b/biometrics/fingerprint/aidl/default/main.cpp
@@ -27,9 +27,11 @@
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Fingerprint> hal = ndk::SharedRefBase::make<Fingerprint>();
- const std::string instance = std::string(Fingerprint::descriptor) + "/default";
- binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str());
+ const std::string instance = std::string(Fingerprint::descriptor) + "/virtual";
+ binder_status_t status =
+ AServiceManager_registerLazyService(hal->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
+ AServiceManager_forceLazyServicesPersist(true);
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
new file mode 100644
index 0000000..a200b39
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineTest.cpp
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
+
+#include "FakeFingerprintEngine.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+using namespace ::aidl::android::hardware::keymaster;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class TestSessionCallback : public BnSessionCallback {
+ public:
+ ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
+ mLastChallenge = challenge;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
+ mLastChallengeRevoked = challenge;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t vendorCode) override {
+ mError = error;
+ mErrorVendorCode = vendorCode;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
+ if (remaining == 0) mLastEnrolled = enrollmentId;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t enrollmentId,
+ const keymaster::HardwareAuthToken&) override {
+ mLastAuthenticated = enrollmentId;
+ mAuthenticateFailed = false;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFailed() override {
+ mLastAuthenticated = 0;
+ mAuthenticateFailed = true;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onInteractionDetected() override {
+ mInteractionDetectedCount++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ndk::ScopedAStatus onAcquired(AcquiredInfo info, int32_t vendorCode) override {
+ mLastAcquiredInfo = (int32_t)info;
+ mLastAcquiredVendorCode = vendorCode;
+ mLastAcquiredCount++;
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+ const std::vector<int32_t>& enrollmentIds) override {
+ mLastEnrollmentEnumerated = enrollmentIds;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentsRemoved(const std::vector<int32_t>& enrollmentIds) override {
+ mLastEnrollmentRemoved = enrollmentIds;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t authenticatorId) override {
+ mLastAuthenticatorId = authenticatorId;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t authenticatorId) override {
+ mLastAuthenticatorId = authenticatorId;
+ mAuthenticatorIdInvalidated = true;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutPermanent() override {
+ mLockoutPermanent = true;
+ return ndk::ScopedAStatus::ok();
+ };
+ ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+ Error mError = Error::UNKNOWN;
+ int32_t mErrorVendorCode = 0;
+ int64_t mLastChallenge = -1;
+ int64_t mLastChallengeRevoked = -1;
+ int32_t mLastEnrolled = -1;
+ int32_t mLastAuthenticated = -1;
+ int64_t mLastAuthenticatorId = -1;
+ std::vector<int32_t> mLastEnrollmentEnumerated;
+ std::vector<int32_t> mLastEnrollmentRemoved;
+ bool mAuthenticateFailed = false;
+ bool mAuthenticatorIdInvalidated = false;
+ bool mLockoutPermanent = false;
+ int mInteractionDetectedCount = 0;
+ int32_t mLastAcquiredInfo = -1;
+ int32_t mLastAcquiredVendorCode = -1;
+ int32_t mLastAcquiredCount = 0;
+};
+
+class FakeFingerprintEngineTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ FingerprintHalProperties::operation_enroll_latency({0});
+ FingerprintHalProperties::operation_authenticate_latency({0});
+ FingerprintHalProperties::operation_detect_interaction_latency({0});
+ mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+ }
+
+ void TearDown() override {
+ FingerprintHalProperties::operation_authenticate_error(0);
+ FingerprintHalProperties::operation_detect_interaction_error(0);
+ FingerprintHalProperties::operation_authenticate_acquired("");
+ FingerprintHalProperties::operation_enroll_latency({});
+ FingerprintHalProperties::operation_authenticate_latency({});
+ FingerprintHalProperties::operation_detect_interaction_latency({});
+ }
+
+ FakeFingerprintEngine mEngine;
+ std::shared_ptr<TestSessionCallback> mCallback;
+ std::promise<void> mCancel;
+};
+
+TEST_F(FakeFingerprintEngineTest, GenerateChallenge) {
+ mEngine.generateChallengeImpl(mCallback.get());
+ ASSERT_EQ(FingerprintHalProperties::challenge().value(), mCallback->mLastChallenge);
+}
+
+TEST_F(FakeFingerprintEngineTest, RevokeChallenge) {
+ auto challenge = FingerprintHalProperties::challenge().value_or(10);
+ mEngine.revokeChallengeImpl(mCallback.get(), challenge);
+ ASSERT_FALSE(FingerprintHalProperties::challenge().has_value());
+ ASSERT_EQ(challenge, mCallback->mLastChallengeRevoked);
+}
+
+TEST_F(FakeFingerprintEngineTest, ResetLockout) {
+ FingerprintHalProperties::lockout(true);
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.resetLockoutImpl(mCallback.get(), hat);
+ ASSERT_FALSE(FingerprintHalProperties::lockout().value_or(true));
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticatorId) {
+ FingerprintHalProperties::enrollments({1});
+ FingerprintHalProperties::authenticator_id(50);
+ mEngine.getAuthenticatorIdImpl(mCallback.get());
+ ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
+ ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticatorIdInvalidate) {
+ FingerprintHalProperties::authenticator_id(500);
+ mEngine.invalidateAuthenticatorIdImpl(mCallback.get());
+ ASSERT_NE(500, FingerprintHalProperties::authenticator_id().value());
+ ASSERT_TRUE(mCallback->mAuthenticatorIdInvalidated);
+}
+
+TEST_F(FakeFingerprintEngineTest, Enroll) {
+ FingerprintHalProperties::enrollments({});
+ FingerprintHalProperties::next_enrollment("4:0,0:true");
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+ ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
+ ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
+ ASSERT_EQ(4, mCallback->mLastEnrolled);
+ ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+}
+
+TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
+ FingerprintHalProperties::enrollments({});
+ auto next = "4:0,0:true";
+ FingerprintHalProperties::next_enrollment(next);
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mCancel.set_value();
+ mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ ASSERT_EQ(Error::CANCELED, mCallback->mError);
+ ASSERT_EQ(-1, mCallback->mLastEnrolled);
+ ASSERT_EQ(0, FingerprintHalProperties::enrollments().size());
+ ASSERT_EQ(next, FingerprintHalProperties::next_enrollment().value_or(""));
+}
+
+TEST_F(FakeFingerprintEngineTest, EnrollFail) {
+ FingerprintHalProperties::enrollments({});
+ auto next = "2:0,0:false";
+ FingerprintHalProperties::next_enrollment(next);
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
+ ASSERT_EQ(-1, mCallback->mLastEnrolled);
+ ASSERT_EQ(0, FingerprintHalProperties::enrollments().size());
+ ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+}
+
+TEST_F(FakeFingerprintEngineTest, EnrollAcquired) {
+ FingerprintHalProperties::enrollments({});
+ FingerprintHalProperties::next_enrollment("4:0,5-[12,1013]:true");
+ keymaster::HardwareAuthToken hat{.mac = {2, 4}};
+ int32_t prevCnt = mCallback->mLastAcquiredCount;
+ mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
+ ASSERT_FALSE(FingerprintHalProperties::next_enrollment().has_value());
+ ASSERT_EQ(1, FingerprintHalProperties::enrollments().size());
+ ASSERT_EQ(4, FingerprintHalProperties::enrollments()[0].value());
+ ASSERT_EQ(4, mCallback->mLastEnrolled);
+ ASSERT_EQ(prevCnt + 3, mCallback->mLastAcquiredCount);
+ ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
+TEST_F(FakeFingerprintEngineTest, Authenticate) {
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_FALSE(mCallback->mAuthenticateFailed);
+ ASSERT_EQ(2, mCallback->mLastAuthenticated);
+ ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
+ FingerprintHalProperties::enrollments({2});
+ FingerprintHalProperties::enrollment_hit(2);
+ mCancel.set_value();
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_EQ(Error::CANCELED, mCallback->mError);
+ ASSERT_EQ(-1, mCallback->mLastAuthenticated);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateNotSet) {
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit({});
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_TRUE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(3);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_TRUE(mCallback->mAuthenticateFailed);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
+ FingerprintHalProperties::enrollments({22, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::lockout(true);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_TRUE(mCallback->mLockoutPermanent);
+ ASSERT_NE(mCallback->mError, Error::UNKNOWN);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
+ FingerprintHalProperties::operation_authenticate_error(8);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_EQ(mCallback->mError, (Error)8);
+ ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
+ FingerprintHalProperties::operation_authenticate_error(1009);
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_EQ(mCallback->mError, (Error)7);
+ ASSERT_EQ(mCallback->mErrorVendorCode, 9);
+}
+
+TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
+ FingerprintHalProperties::lockout(false);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_authenticate_acquired("4,1009");
+ int32_t prevCount = mCallback->mLastAcquiredCount;
+ mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
+ ASSERT_FALSE(mCallback->mAuthenticateFailed);
+ ASSERT_EQ(2, mCallback->mLastAuthenticated);
+ ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+ ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(9, mCallback->mLastAcquiredVendorCode);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_detect_interaction_acquired("");
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+ ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ mCancel.set_value();
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(Error::CANCELED, mCallback->mError);
+ ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectNotSet) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit({});
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectNotEnrolled) {
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(25);
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::operation_detect_interaction_error(8);
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
+ ASSERT_EQ(mCallback->mError, (Error)8);
+ ASSERT_EQ(mCallback->mErrorVendorCode, 0);
+}
+
+TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_detect_interaction_acquired("4,1013");
+ int32_t prevCount = mCallback->mLastAcquiredCount;
+ mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
+ ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
+ ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
+ ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
+ ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
+}
+
+TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
+ FingerprintHalProperties::enrollments({2, 4, 8});
+ mEngine.enumerateEnrollmentsImpl(mCallback.get());
+ ASSERT_EQ(
+ 4,
+ mCallback->mLastEnrollmentEnumerated.size()); // Due to workaround. TODO (b/243129174)
+ for (auto id : FingerprintHalProperties::enrollments()) {
+ ASSERT_TRUE(std::find(mCallback->mLastEnrollmentEnumerated.begin(),
+ mCallback->mLastEnrollmentEnumerated.end(),
+ id) != mCallback->mLastEnrollmentEnumerated.end());
+ }
+}
+
+TEST_F(FakeFingerprintEngineTest, RemoveEnrolled) {
+ FingerprintHalProperties::enrollments({2, 4, 8, 1});
+ mEngine.removeEnrollmentsImpl(mCallback.get(), {2, 8});
+ auto enrolls = FingerprintHalProperties::enrollments();
+ ASSERT_EQ(2, mCallback->mLastEnrollmentRemoved.size());
+ for (auto id : {2, 8}) {
+ ASSERT_TRUE(std::find(mCallback->mLastEnrollmentRemoved.begin(),
+ mCallback->mLastEnrollmentRemoved.end(),
+ id) != mCallback->mLastEnrollmentRemoved.end());
+ }
+ ASSERT_EQ(2, enrolls.size());
+ for (auto id : {1, 4}) {
+ ASSERT_TRUE(std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end());
+ }
+}
+
+TEST_F(FakeFingerprintEngineTest, parseIntSequence) {
+ std::vector<int32_t> seqV;
+ seqV = mEngine.parseIntSequence("");
+ ASSERT_EQ(0, seqV.size());
+ seqV = mEngine.parseIntSequence("2");
+ ASSERT_EQ(1, seqV.size());
+ ASSERT_EQ(2, seqV[0]);
+ seqV = mEngine.parseIntSequence("2,3,4");
+ std::vector<int32_t> expV{2, 3, 4};
+ ASSERT_EQ(expV, seqV);
+ seqV = mEngine.parseIntSequence("2,3,a");
+ ASSERT_EQ(0, seqV.size());
+ seqV = mEngine.parseIntSequence("2, 3, 4");
+ ASSERT_EQ(expV, seqV);
+ seqV = mEngine.parseIntSequence("123,456");
+ ASSERT_EQ(2, seqV.size());
+ std::vector<int32_t> expV1{123, 456};
+ ASSERT_EQ(expV1, seqV);
+ seqV = mEngine.parseIntSequence("12f3,456");
+ ASSERT_EQ(0, seqV.size());
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureOk) {
+ std::vector<std::vector<int32_t>> ecV;
+ ecV = mEngine.parseEnrollmentCapture("100,200,300");
+ ASSERT_EQ(6, ecV.size());
+ std::vector<std::vector<int32_t>> expE{{100}, {200}, {300}};
+ std::vector<int32_t> defC{1};
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(defC, ecV[i + 1]);
+ }
+ ecV = mEngine.parseEnrollmentCapture("100");
+ ASSERT_EQ(2, ecV.size());
+ ASSERT_EQ(expE[0], ecV[0]);
+ ASSERT_EQ(defC, ecV[1]);
+
+ ecV = mEngine.parseEnrollmentCapture("100-[5,6,7]");
+ std::vector<int32_t> expC{5, 6, 7};
+ ASSERT_EQ(2, ecV.size());
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(expC, ecV[i + 1]);
+ }
+ ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200, 300-[9,10]");
+ std::vector<std::vector<int32_t>> expC1{{5, 6, 7}, {1}, {9, 10}};
+ ASSERT_EQ(6, ecV.size());
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(expC1[i / 2], ecV[i + 1]);
+ }
+ ecV = mEngine.parseEnrollmentCapture("100-[5,6,7], 200-[2,1], 300-[9]");
+ std::vector<std::vector<int32_t>> expC2{{5, 6, 7}, {2, 1}, {9}};
+ ASSERT_EQ(ecV.size(), 6);
+ for (int i = 0; i < ecV.size(); i += 2) {
+ ASSERT_EQ(expE[i / 2], ecV[i]);
+ ASSERT_EQ(expC2[i / 2], ecV[i + 1]);
+ }
+}
+
+TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureFail) {
+ std::vector<std::string> badStr{"10c", "100-5", "100-[5,6,7", "100-5,6,7]",
+ "100,2x0,300", "200-[f]", "a,b"};
+ std::vector<std::vector<int32_t>> ecV;
+ for (const auto& s : badStr) {
+ ecV = mEngine.parseEnrollmentCapture(s);
+ ASSERT_EQ(ecV.size(), 0);
+ }
+}
+
+TEST_F(FakeFingerprintEngineTest, randomLatency) {
+ FingerprintHalProperties::operation_detect_interaction_latency({});
+ ASSERT_EQ(DEFAULT_LATENCY,
+ mEngine.getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+ FingerprintHalProperties::operation_detect_interaction_latency({10});
+ ASSERT_EQ(10,
+ mEngine.getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
+ FingerprintHalProperties::operation_detect_interaction_latency({1, 1000});
+ std::set<int32_t> latencySet;
+ for (int i = 0; i < 100; i++) {
+ latencySet.insert(mEngine.getLatency(
+ FingerprintHalProperties::operation_detect_interaction_latency()));
+ }
+ ASSERT_TRUE(latencySet.size() > 95);
+ FingerprintHalProperties::operation_detect_interaction_latency({});
+}
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
new file mode 100644
index 0000000..f551899
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeFingerprintEngineUdfpsTest.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeFingerprintEngine.h"
+#include "FakeFingerprintEngineUdfps.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+using namespace ::aidl::android::hardware::keymaster;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+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(fingerprint::Error /*error*/, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+ int32_t /*remaining*/) override {
+ mEnrollmentProgress++;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
+ const keymaster::HardwareAuthToken&) override {
+ mAuthenticationSuccess++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFailed() override {
+ mAuthenticationFailure++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onInteractionDetected() override {
+ mDetectInteraction++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onEnrollmentsEnumerated(
+ const std::vector<int32_t>& /*enrollmentIds*/) 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 onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); };
+ ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
+ ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+
+ int32_t getAuthenticationCount() { return mAuthenticationSuccess + mAuthenticationFailure; }
+ int32_t getDetectInteractionCount() { return mDetectInteraction; }
+
+ int32_t mAuthenticationSuccess = 0;
+ int32_t mAuthenticationFailure = 0;
+ int32_t mEnrollmentProgress = 0;
+ int32_t mDetectInteraction = 0;
+};
+
+class FakeFingerprintEngineUdfpsTest : public ::testing::Test {
+ protected:
+ void SetUp() override {}
+
+ void TearDown() override {
+ // reset to default
+ FingerprintHalProperties::sensor_location("");
+ }
+
+ FakeFingerprintEngineUdfps mEngine;
+};
+
+bool isDefaultLocation(SensorLocation& sc) {
+ return (sc.sensorLocationX == FakeFingerprintEngineUdfps::defaultSensorLocationX &&
+ sc.sensorLocationY == FakeFingerprintEngineUdfps::defaultSensorLocationY &&
+ sc.sensorRadius == FakeFingerprintEngineUdfps::defaultSensorRadius && sc.display == "");
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationOk) {
+ auto loc = "100:200:30";
+ FingerprintHalProperties::sensor_location(loc);
+ SensorLocation sc = mEngine.getSensorLocation();
+ ASSERT_TRUE(sc.sensorLocationX == 100);
+ ASSERT_TRUE(sc.sensorLocationY == 200);
+ ASSERT_TRUE(sc.sensorRadius == 30);
+
+ loc = "100:200:30:screen1";
+ FingerprintHalProperties::sensor_location(loc);
+ sc = mEngine.getSensorLocation();
+ ASSERT_TRUE(sc.sensorLocationX == 100);
+ ASSERT_TRUE(sc.sensorLocationY == 200);
+ ASSERT_TRUE(sc.sensorRadius == 30);
+ ASSERT_TRUE(sc.display == "screen1");
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, getSensorLocationBad) {
+ const std::vector<std::string> badStr{"", "100", "10:20", "10,20,5", "a:b:c"};
+ SensorLocation sc;
+ for (const auto& s : badStr) {
+ FingerprintHalProperties::sensor_location(s);
+ sc = mEngine.getSensorLocation();
+ ASSERT_TRUE(isDefaultLocation(sc));
+ }
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, initialization) {
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kIdle);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, authenticate) {
+ std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+ std::promise<void> cancel;
+ mEngine.authenticateImpl(cb.get(), 1, cancel.get_future());
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kAuthenticate);
+ mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+ ASSERT_EQ(cb->getAuthenticationCount(), 0);
+ mEngine.onUiReadyImpl();
+ ASSERT_EQ(cb->getAuthenticationCount(), 1);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, enroll) {
+ std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+ std::promise<void> cancel;
+ keymaster::HardwareAuthToken hat{.mac = {5, 6}};
+ FingerprintHalProperties::next_enrollment("5:0,0:true");
+ mEngine.enrollImpl(cb.get(), hat, cancel.get_future());
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kEnroll);
+ mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+ ASSERT_EQ(cb->mEnrollmentProgress, 0);
+ mEngine.onUiReadyImpl();
+ ASSERT_TRUE(cb->mEnrollmentProgress > 0);
+}
+
+TEST_F(FakeFingerprintEngineUdfpsTest, detectInteraction) {
+ FingerprintHalProperties::detect_interaction(true);
+ FingerprintHalProperties::enrollments({1, 2});
+ FingerprintHalProperties::enrollment_hit(2);
+ FingerprintHalProperties::operation_detect_interaction_acquired("");
+ std::shared_ptr<TestSessionCallback> cb = ndk::SharedRefBase::make<TestSessionCallback>();
+ std::promise<void> cancel;
+ mEngine.detectInteractionImpl(cb.get(), cancel.get_future());
+ ASSERT_TRUE(mEngine.getWorkMode() == FakeFingerprintEngineUdfps::WorkMode::kDetectInteract);
+ mEngine.onPointerDownImpl(1, 2, 3, 4.0, 5.0);
+ ASSERT_EQ(cb->getDetectInteractionCount(), 0);
+ mEngine.onUiReadyImpl();
+ ASSERT_EQ(cb->getDetectInteractionCount(), 1);
+}
+// More
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
new file mode 100644
index 0000000..1b071ee
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeLockoutTracker.h"
+#include "util/Util.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+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 {
+ FingerprintHalProperties::lockout_timed_threshold(LOCKOUT_TIMED_THRESHOLD);
+ FingerprintHalProperties::lockout_timed_duration(LOCKOUT_TIMED_DURATION);
+ FingerprintHalProperties::lockout_permanent_threshold(LOCKOUT_PERMANENT_THRESHOLD);
+ }
+
+ void TearDown() override {
+ // reset to default
+ FingerprintHalProperties::lockout_timed_threshold(5);
+ FingerprintHalProperties::lockout_timed_duration(20);
+ FingerprintHalProperties::lockout_permanent_threshold(10000);
+ FingerprintHalProperties::lockout_enable(false);
+ FingerprintHalProperties::lockout(false);
+ }
+
+ FakeLockoutTracker mLockoutTracker;
+};
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
+ FingerprintHalProperties::lockout_enable(false);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD + 1; i++) mLockoutTracker.addFailedAttempt();
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ mLockoutTracker.reset();
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
+ FingerprintHalProperties::lockout_enable(true);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++) mLockoutTracker.addFailedAttempt();
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+ // time left
+ int N = 5;
+ int64_t prevTimeLeft = INT_MIN;
+ 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;
+ }
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ mLockoutTracker.reset();
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
+ FingerprintHalProperties::lockout_enable(true);
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - 1; i++) mLockoutTracker.addFailedAttempt();
+ ASSERT_NE(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ mLockoutTracker.addFailedAttempt();
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ ASSERT_TRUE(FingerprintHalProperties::lockout());
+ mLockoutTracker.reset();
+}
+
+} // namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
deleted file mode 100644
index 902fb40..0000000
--- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.
- */
-
-#include <algorithm>
-#include <chrono>
-#include <future>
-#include <thread>
-
-#include <gtest/gtest.h>
-
-#include "WorkerThread.h"
-
-namespace {
-
-using aidl::android::hardware::biometrics::fingerprint::Callable;
-using aidl::android::hardware::biometrics::fingerprint::WorkerThread;
-using namespace std::chrono_literals;
-
-TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) {
- WorkerThread worker(1 /*maxQueueSize*/);
- for (int i = 0; i < 100; ++i) {
- std::promise<void> promise;
- auto future = promise.get_future();
-
- ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
- // Notify that the task has started.
- promise.set_value();
- })));
-
- future.wait();
- }
-}
-
-TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) {
- WorkerThread worker(2 /*maxQueueSize*/);
-
- std::promise<void> promise;
- auto future = promise.get_future();
-
- // Schedule a long-running task.
- ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable {
- // Notify that the task has started.
- promise.set_value();
- // Block for a "very long" time.
- std::this_thread::sleep_for(1s);
- })));
-
- // Make sure the long-running task began executing.
- future.wait();
-
- // The first task is already being worked on, which means the queue must be empty.
- // Fill the worker's queue to the maximum.
- ASSERT_TRUE(worker.schedule(Callable::from([] {})));
- ASSERT_TRUE(worker.schedule(Callable::from([] {})));
-
- EXPECT_FALSE(worker.schedule(Callable::from([] {})));
-}
-
-TEST(WorkerThreadTest, TasksExecuteInOrder) {
- constexpr int NUM_TASKS = 10000;
- WorkerThread worker(NUM_TASKS + 1);
-
- std::mutex mut;
- std::condition_variable cv;
- bool finished = false;
- std::vector<int> results;
-
- for (int i = 0; i < NUM_TASKS; ++i) {
- worker.schedule(Callable::from([&mut, &results, i] {
- // Delay tasks differently to provoke races.
- std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100));
- auto lock = std::lock_guard(mut);
- results.push_back(i);
- }));
- }
-
- // Schedule a special task to signal when all of the tasks are finished.
- worker.schedule(Callable::from([&mut, &cv, &finished] {
- auto lock = std::lock_guard(mut);
- finished = true;
- cv.notify_one();
- }));
-
- auto lock = std::unique_lock(mut);
- cv.wait(lock, [&finished] { return finished; });
- ASSERT_EQ(results.size(), NUM_TASKS);
- EXPECT_TRUE(std::is_sorted(results.begin(), results.end()));
-}
-
-TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) {
- std::promise<void> promise1;
- std::promise<void> promise2;
- auto future1 = promise1.get_future();
- auto future2 = promise2.get_future();
- std::atomic<bool> value;
-
- // Local scope for the worker to test its destructor when it goes out of scope.
- {
- WorkerThread worker(2 /*maxQueueSize*/);
-
- ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise1)]() mutable {
- promise.set_value();
- std::this_thread::sleep_for(200ms);
- })));
-
- // The first task should start executing.
- future1.wait();
-
- // The second task should schedule successfully.
- ASSERT_TRUE(
- worker.schedule(Callable::from([promise = std::move(promise2), &value]() mutable {
- // The worker should destruct before it gets a chance to execute this.
- value = true;
- promise.set_value();
- })));
- }
-
- // The second task should never execute.
- future2.wait();
- // The future is expected to be ready but contain an exception.
- // Cannot use ASSERT_THROW because exceptions are disabled in this codebase.
- // ASSERT_THROW(future2.get(), std::future_error);
- EXPECT_FALSE(value);
-}
-
-} // namespace
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index 30d5624..1652905 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -15,9 +15,9 @@
],
srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"],
static_libs: [
- "android.hardware.biometrics.common-V1-ndk",
- "android.hardware.biometrics.fingerprint-V1-ndk",
- "android.hardware.keymaster-V3-ndk",
+ "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.keymaster-V4-ndk",
],
shared_libs: [
"libbinder_ndk",
diff --git a/broadcastradio/2.0/default/TunerSession.cpp b/broadcastradio/2.0/default/TunerSession.cpp
index 2ba4d02..cc2f1a5 100644
--- a/broadcastradio/2.0/default/TunerSession.cpp
+++ b/broadcastradio/2.0/default/TunerSession.cpp
@@ -241,13 +241,13 @@
};
std::copy_if(list.begin(), list.end(), std::back_inserter(filteredList), filterCb);
- auto task = [this, list]() {
+ auto task = [this, filteredList]() {
lock_guard<mutex> lk(mMut);
ProgramListChunk chunk = {};
chunk.purge = true;
chunk.complete = true;
- chunk.modified = hidl_vec<ProgramInfo>(list.begin(), list.end());
+ chunk.modified = hidl_vec<ProgramInfo>(filteredList.begin(), filteredList.end());
mCallback->onProgramListUpdated(chunk);
};
diff --git a/broadcastradio/2.0/default/VirtualRadio.cpp b/broadcastradio/2.0/default/VirtualRadio.cpp
index c59fd8f..e6b1017 100644
--- a/broadcastradio/2.0/default/VirtualRadio.cpp
+++ b/broadcastradio/2.0/default/VirtualRadio.cpp
@@ -46,9 +46,9 @@
VirtualRadio gDabRadio(
"DAB radio mock",
{
- {make_selector_dab(12345, 225648), "BBC Radio 1", "Khalid", "Talk"}, // 12B
- {make_selector_dab(22345, 222064), "Classic FM", "Jean Sibelius", "Andante Festivo"}, // 11D
- {make_selector_dab(32345, 222064), "Absolute Radio", "Coldplay", "Clocks"}, // 11D
+ {make_selector_dab(0xA00001u, 0x0001u), "BBC Radio 1", "Khalid", "Talk"},
+ {make_selector_dab(0xB00001u, 0x1001u), "Classic FM", "Jean Sibelius", "Andante Festivo"},
+ {make_selector_dab(0xB00002u, 0x1001u), "Absolute Radio", "Coldplay", "Clocks"},
});
// clang-format on
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 615fde0..5e8a5cf 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -108,6 +108,7 @@
bool openSession();
bool getAmFmRegionConfig(bool full, AmFmRegionConfig* config);
std::optional<utils::ProgramInfoSet> getProgramList();
+ std::optional<utils::ProgramInfoSet> getProgramList(const ProgramFilter& filter);
sp<IBroadcastRadio> mModule;
Properties mProperties;
@@ -239,9 +240,15 @@
}
std::optional<utils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList() {
+ ProgramFilter emptyFilter = {};
+ return getProgramList(emptyFilter);
+}
+
+std::optional<utils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList(
+ const ProgramFilter& filter) {
EXPECT_TIMEOUT_CALL(*mCallback, onProgramListReady).Times(AnyNumber());
- auto startResult = mSession->startProgramListUpdates({});
+ auto startResult = mSession->startProgramListUpdates(filter);
if (startResult == Result::NOT_SUPPORTED) {
printSkipped("Program list not supported");
return std::nullopt;
@@ -810,20 +817,98 @@
}
/**
- * Test getting program list.
+ * Test getting program list using empty program filter.
*
* Verifies that:
* - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
* - the complete list is fetched within timeout::programListScan;
* - stopProgramListUpdates does not crash.
*/
-TEST_P(BroadcastRadioHalTest, GetProgramList) {
+TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
ASSERT_TRUE(openSession());
getProgramList();
}
/**
+ * Test getting program list using AMFM frequency program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within timeout::programListScan;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with AMFM_FREQUENCY value of the first AMFM
+ * program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromAmFmFilter) {
+ ASSERT_TRUE(openSession());
+
+ auto completeList = getProgramList();
+ if (!completeList) return;
+
+ ProgramFilter amfmFilter = {};
+ int expectedResultSize = 0;
+ uint64_t expectedFreq = 0;
+ for (auto&& program : *completeList) {
+ auto amfmIds = utils::getAllIds(program.selector, IdentifierType::AMFM_FREQUENCY);
+ EXPECT_LE(amfmIds.size(), 1u);
+ if (amfmIds.size() == 0) continue;
+
+ if (expectedResultSize == 0) {
+ expectedFreq = amfmIds[0];
+ amfmFilter.identifiers = {
+ make_identifier(IdentifierType::AMFM_FREQUENCY, expectedFreq)};
+ expectedResultSize = 1;
+ } else if (amfmIds[0] == expectedFreq) {
+ expectedResultSize++;
+ }
+ }
+
+ if (expectedResultSize == 0) return;
+ auto amfmList = getProgramList(amfmFilter);
+ ASSERT_EQ(expectedResultSize, amfmList->size()) << "amfm filter result size is wrong";
+}
+
+/**
+ * Test getting program list using DAB ensemble program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within timeout::programListScan;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with DAB_ENSEMBLE value of the first DAB
+ * program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromDabFilter) {
+ ASSERT_TRUE(openSession());
+
+ auto completeList = getProgramList();
+ if (!completeList) return;
+
+ ProgramFilter dabFilter = {};
+ int expectedResultSize = 0;
+ uint64_t expectedEnsemble = 0;
+ for (auto&& program : *completeList) {
+ auto dabEnsembles = utils::getAllIds(program.selector, IdentifierType::DAB_ENSEMBLE);
+ EXPECT_LE(dabEnsembles.size(), 1u);
+ if (dabEnsembles.size() == 0) continue;
+
+ if (expectedResultSize == 0) {
+ expectedEnsemble = dabEnsembles[0];
+ dabFilter.identifiers = {
+ make_identifier(IdentifierType::DAB_ENSEMBLE, expectedEnsemble)};
+ expectedResultSize = 1;
+ } else if (dabEnsembles[0] == expectedEnsemble) {
+ expectedResultSize++;
+ }
+ }
+
+ if (expectedResultSize == 0) return;
+ auto dabList = getProgramList(dabFilter);
+ ASSERT_EQ(expectedResultSize, dabList->size()) << "dab filter result size is wrong";
+}
+
+/**
* Test HD_STATION_NAME correctness.
*
* Verifies that if a program on the list contains HD_STATION_NAME identifier:
diff --git a/broadcastradio/aidl/Android.bp b/broadcastradio/aidl/Android.bp
new file mode 100644
index 0000000..2d8078b
--- /dev/null
+++ b/broadcastradio/aidl/Android.bp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // 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.broadcastradio",
+ vendor_available: true,
+ srcs: ["android/hardware/broadcastradio/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ min_sdk_version: "Tiramisu",
+ },
+ },
+}
diff --git a/broadcastradio/aidl/OWNERS b/broadcastradio/aidl/OWNERS
new file mode 100644
index 0000000..302fdd7
--- /dev/null
+++ b/broadcastradio/aidl/OWNERS
@@ -0,0 +1,4 @@
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmBandRange.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmBandRange.aidl
new file mode 100644
index 0000000..ca511aa
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmBandRange.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AmFmBandRange {
+ int lowerBound;
+ int upperBound;
+ int spacing;
+ int seekSpacing;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmRegionConfig.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmRegionConfig.aidl
new file mode 100644
index 0000000..fe8489c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AmFmRegionConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AmFmRegionConfig {
+ android.hardware.broadcastradio.AmFmBandRange[] ranges;
+ int fmDeemphasis;
+ int fmRds;
+ const int DEEMPHASIS_D50 = (1 << 0);
+ const int DEEMPHASIS_D75 = (1 << 1);
+ const int RDS = (1 << 0);
+ const int RBDS = (1 << 1);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Announcement.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Announcement.aidl
new file mode 100644
index 0000000..bbdd86f
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Announcement.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Announcement {
+ android.hardware.broadcastradio.ProgramSelector selector;
+ android.hardware.broadcastradio.AnnouncementType type = android.hardware.broadcastradio.AnnouncementType.INVALID;
+ android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AnnouncementType.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AnnouncementType.aidl
new file mode 100644
index 0000000..1d187fe
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AnnouncementType.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="byte") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AnnouncementType {
+ INVALID = 0,
+ EMERGENCY = 1,
+ WARNING,
+ TRAFFIC,
+ WEATHER,
+ NEWS,
+ EVENT,
+ SPORT,
+ MISC,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ConfigFlag.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ConfigFlag.aidl
new file mode 100644
index 0000000..98af437
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ConfigFlag.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum ConfigFlag {
+ FORCE_MONO = 1,
+ FORCE_ANALOG,
+ FORCE_DIGITAL,
+ RDS_AF,
+ RDS_REG,
+ DAB_DAB_LINKING,
+ DAB_FM_LINKING,
+ DAB_DAB_SOFT_LINKING,
+ DAB_FM_SOFT_LINKING,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/DabTableEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/DabTableEntry.aidl
new file mode 100644
index 0000000..162f4abd
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/DabTableEntry.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable DabTableEntry {
+ String label;
+ int frequencyKhz;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IAnnouncementListener.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IAnnouncementListener.aidl
new file mode 100644
index 0000000..346af58
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IAnnouncementListener.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface IAnnouncementListener {
+ oneway void onListUpdated(in android.hardware.broadcastradio.Announcement[] announcements);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IBroadcastRadio.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IBroadcastRadio.aidl
new file mode 100644
index 0000000..39eb04c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IBroadcastRadio.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface IBroadcastRadio {
+ android.hardware.broadcastradio.Properties getProperties();
+ android.hardware.broadcastradio.AmFmRegionConfig getAmFmRegionConfig(in boolean full);
+ android.hardware.broadcastradio.DabTableEntry[] getDabRegionConfig();
+ void setTunerCallback(in android.hardware.broadcastradio.ITunerCallback callback);
+ void unsetTunerCallback();
+ void tune(in android.hardware.broadcastradio.ProgramSelector program);
+ void seek(in boolean directionUp, in boolean skipSubChannel);
+ void step(in boolean directionUp);
+ void cancel();
+ void startProgramListUpdates(in android.hardware.broadcastradio.ProgramFilter filter);
+ void stopProgramListUpdates();
+ boolean isConfigFlagSet(in android.hardware.broadcastradio.ConfigFlag flag);
+ void setConfigFlag(in android.hardware.broadcastradio.ConfigFlag flag, in boolean value);
+ android.hardware.broadcastradio.VendorKeyValue[] setParameters(in android.hardware.broadcastradio.VendorKeyValue[] parameters);
+ android.hardware.broadcastradio.VendorKeyValue[] getParameters(in String[] keys);
+ byte[] getImage(in int id);
+ android.hardware.broadcastradio.ICloseHandle registerAnnouncementListener(in android.hardware.broadcastradio.IAnnouncementListener listener, in android.hardware.broadcastradio.AnnouncementType[] enabled);
+ const int INVALID_IMAGE = 0;
+ const int ANTENNA_STATE_CHANGE_TIMEOUT_MS = 100;
+ const int LIST_COMPLETE_TIMEOUT_MS = 300000;
+ const int TUNER_TIMEOUT_MS = 30000;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ICloseHandle.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ICloseHandle.aidl
new file mode 100644
index 0000000..75e7f2a
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ICloseHandle.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@VintfStability
+interface ICloseHandle {
+ void close();
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ITunerCallback.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ITunerCallback.aidl
new file mode 100644
index 0000000..f5badad
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ITunerCallback.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.broadcastradio;
+@VintfStability
+interface ITunerCallback {
+ oneway void onTuneFailed(in android.hardware.broadcastradio.Result result, in android.hardware.broadcastradio.ProgramSelector selector);
+ oneway void onCurrentProgramInfoChanged(in android.hardware.broadcastradio.ProgramInfo info);
+ oneway void onProgramListUpdated(in android.hardware.broadcastradio.ProgramListChunk chunk);
+ oneway void onAntennaStateChange(in boolean connected);
+ oneway void onConfigFlagUpdated(in android.hardware.broadcastradio.ConfigFlag flag, in boolean value);
+ oneway void onParametersUpdated(in android.hardware.broadcastradio.VendorKeyValue[] parameters);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IdentifierType.aidl
new file mode 100644
index 0000000..4df272c
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/IdentifierType.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum IdentifierType {
+ VENDOR_START = 1000,
+ VENDOR_END = 1999,
+ INVALID = 0,
+ AMFM_FREQUENCY_KHZ,
+ RDS_PI,
+ HD_STATION_ID_EXT,
+ HD_STATION_NAME,
+ DAB_SID_EXT,
+ DAB_ENSEMBLE,
+ DAB_SCID,
+ DAB_FREQUENCY_KHZ,
+ DRMO_SERVICE_ID,
+ DRMO_FREQUENCY_KHZ,
+ SXM_SERVICE_ID = (DRMO_FREQUENCY_KHZ + 2),
+ SXM_CHANNEL,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Metadata.aidl
new file mode 100644
index 0000000..e02b6b1
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Metadata.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+union Metadata {
+ String rdsPs;
+ int rdsPty;
+ int rbdsPty;
+ String rdsRt;
+ String songTitle;
+ String songArtist;
+ String songAlbum;
+ int stationIcon;
+ int albumArt;
+ String programName;
+ String dabEnsembleName;
+ String dabEnsembleNameShort;
+ String dabServiceName;
+ String dabServiceNameShort;
+ String dabComponentName;
+ String dabComponentNameShort;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramFilter.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramFilter.aidl
new file mode 100644
index 0000000..9edeb8d
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramFilter.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramFilter {
+ android.hardware.broadcastradio.IdentifierType[] identifierTypes;
+ android.hardware.broadcastradio.ProgramIdentifier[] identifiers;
+ boolean includeCategories;
+ boolean excludeModifications;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramIdentifier.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramIdentifier.aidl
new file mode 100644
index 0000000..6676350
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramIdentifier.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramIdentifier {
+ android.hardware.broadcastradio.IdentifierType type = android.hardware.broadcastradio.IdentifierType.INVALID;
+ long value;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
new file mode 100644
index 0000000..b14023a
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramInfo {
+ android.hardware.broadcastradio.ProgramSelector selector;
+ android.hardware.broadcastradio.ProgramIdentifier logicallyTunedTo;
+ android.hardware.broadcastradio.ProgramIdentifier physicallyTunedTo;
+ @nullable android.hardware.broadcastradio.ProgramIdentifier[] relatedContent;
+ int infoFlags;
+ int signalQuality;
+ android.hardware.broadcastradio.Metadata[] metadata;
+ android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+ const int FLAG_LIVE = (1 << 0);
+ const int FLAG_MUTED = (1 << 1);
+ const int FLAG_TRAFFIC_PROGRAM = (1 << 2);
+ const int FLAG_TRAFFIC_ANNOUNCEMENT = (1 << 3);
+ const int FLAG_TUNABLE = (1 << 4);
+ const int FLAG_STEREO = (1 << 5);
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramListChunk.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramListChunk.aidl
new file mode 100644
index 0000000..5d53b99
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramListChunk.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramListChunk {
+ boolean purge;
+ boolean complete;
+ android.hardware.broadcastradio.ProgramInfo[] modified;
+ @nullable android.hardware.broadcastradio.ProgramIdentifier[] removed;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramSelector.aidl
new file mode 100644
index 0000000..9af1dc8
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ProgramSelector {
+ android.hardware.broadcastradio.ProgramIdentifier primaryId;
+ android.hardware.broadcastradio.ProgramIdentifier[] secondaryIds;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Properties.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Properties.aidl
new file mode 100644
index 0000000..643b819
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Properties.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Properties {
+ String maker;
+ String product;
+ String version;
+ String serial;
+ android.hardware.broadcastradio.IdentifierType[] supportedIdentifierTypes;
+ android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
new file mode 100644
index 0000000..8af74c74
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Result.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum Result {
+ OK,
+ INTERNAL_ERROR,
+ INVALID_ARGUMENTS,
+ INVALID_STATE,
+ NOT_SUPPORTED,
+ TIMEOUT,
+ CANCELED,
+ UNKNOWN_ERROR,
+}
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/VendorKeyValue.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/VendorKeyValue.aidl
new file mode 100644
index 0000000..3c6b194
--- /dev/null
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/VendorKeyValue.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VendorKeyValue {
+ String key;
+ String value;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AmFmBandRange.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmBandRange.aidl
new file mode 100644
index 0000000..562631f
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmBandRange.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Defines the AM/FM band range for configuring different regions.
+ *
+ * <p>Channel grid is defined as: each possible channel is set at
+ * lowerBound + channelNumber * spacing, up to upperBound.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable AmFmBandRange {
+ /**
+ * The frequency (in kHz) of the first channel within the range.
+ *
+ * Lower bound must be a tunable frequency.
+ */
+ int lowerBound;
+
+ /**
+ * The frequency (in kHz) of the last channel within the range.
+ */
+ int upperBound;
+
+ /**
+ * Channel grid resolution (in kHz), telling how far the channels are apart.
+ */
+ int spacing;
+
+ /**
+ * Channel spacing (in kHz) used to speed up seeking to the next station
+ * via the {@link IBroadcastRadio#seek} operation.
+ *
+ * It must be a multiple of channel grid resolution.
+ *
+ * Tuner may first quickly check every n-th channel and if it detects echo
+ * from a station, it fine-tunes to find the exact frequency.
+ *
+ * It's ignored for capabilities check (with full=true when calling
+ * getAmFmRegionConfig).
+ */
+ int seekSpacing;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
new file mode 100644
index 0000000..f4c6fd3
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AmFmRegionConfig.aidl
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AmFmBandRange;
+
+/**
+ * Regional configuration for AM/FM.
+ *
+ * <p>For hardware capabilities check (with full=true when calling
+ * {@link IBroadcastRadio#getAmFmRegionConfig}), HAL implementation fills
+ * entire supported range of frequencies and features.
+ *
+ * When checking current configuration, at most one bit in each bitset
+ * can be set.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable AmFmRegionConfig {
+ /**
+ * Noth D50 and D75 are FM de-emphasis filter supported or configured.
+ *
+ * Both might be set for hardware capabilities check (with full={@code true}
+ * when calling getAmFmRegionConfig), but exactly one for specific region
+ * settings.
+ */
+ const int DEEMPHASIS_D50 = 1 << 0;
+
+ const int DEEMPHASIS_D75 = 1 << 1;
+
+ /**
+ * Both RDS and RBDS are supported or configured RDS variants.
+ *
+ * Both might be set for hardware capabilities check (with full={@code true}
+ * when calling getAmFmRegionConfig), but only one (or none) for specific
+ * region settings.
+ *
+ * RDS is Standard variant, used everywhere except North America.
+ */
+ const int RDS = 1 << 0;
+
+ /**
+ * Variant used in North America (see RDS).
+ */
+ const int RBDS = 1 << 1;
+
+ /**
+ * All supported or configured AM/FM bands.
+ *
+ * AM/FM bands are identified by frequency value
+ * (see {@link IdentifierType#AMFM_FREQUENCY_KHZ}).
+ *
+ * With typical configuration, it's expected to have two frequency ranges
+ * for capabilities check (AM and FM) and four ranges for specific region
+ * configuration (AM LW, AM MW, AM SW, FM).
+ */
+ AmFmBandRange[] ranges;
+
+ /**
+ * De-emphasis filter supported/configured.
+ *
+ * It can be a combination of de-emphasis values ({@link #DEEMPHASIS_D50} and
+ * {@link #DEEMPHASIS_D75}).
+ */
+ int fmDeemphasis;
+
+ /**
+ * RDS/RBDS variant supported/configured.
+ *
+ * It can be a combination of RDS values ({@link #RDS} and {@link #RBDS}).
+ */
+ int fmRds;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Announcement.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Announcement.aidl
new file mode 100644
index 0000000..a972d4d
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Announcement.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AnnouncementType;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Station broadcasting active announcement.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Announcement {
+ /**
+ * Program selector to tune to the announcement.
+ */
+ ProgramSelector selector;
+
+ /**
+ * Announcement type.
+ */
+ AnnouncementType type = AnnouncementType.INVALID;
+
+ /**
+ * Vendor-specific information.
+ *
+ * It may be used for extra features, not supported by the platform,
+ * for example: com.me.hdradio.urgency=100; com.me.hdradio.certainity=50.
+ */
+ VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AnnouncementType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AnnouncementType.aidl
new file mode 100644
index 0000000..8df8025
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AnnouncementType.aidl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Type of an announcement.
+ *
+ * <p>It maps to different announcement types for each radio technology.
+ */
+@VintfStability
+@Backing(type="byte")
+@JavaDerive(equals=true, toString=true)
+enum AnnouncementType {
+ /**
+ * Undefined announcement type
+ */
+ INVALID = 0,
+
+ /**
+ * DAB alarm, RDS emergency program type (PTY 31).
+ */
+ EMERGENCY = 1,
+
+ /**
+ * DAB warning.
+ */
+ WARNING,
+
+ /**
+ * DAB road traffic, RDS TA, HD Radio transportation.
+ */
+ TRAFFIC,
+
+ /**
+ * Weather.
+ */
+ WEATHER,
+
+ /**
+ * News.
+ */
+ NEWS,
+
+ /**
+ * DAB event, special event.
+ */
+ EVENT,
+
+ /**
+ * DAB sport report, RDS sports.
+ */
+ SPORT,
+
+ /**
+ * All others.
+ */
+ MISC,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ConfigFlag.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ConfigFlag.aidl
new file mode 100644
index 0000000..11da39c
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ConfigFlag.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Configuration flags to be used with isConfigFlagSet and setConfigFlag methods
+ * of IBroadcastRadio.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum ConfigFlag {
+ /**
+ * Forces mono audio stream reception.
+ *
+ * Analog broadcasts can recover poor reception conditions by jointing
+ * stereo channels into one. Mainly for, but not limited to AM/FM.
+ */
+ FORCE_MONO = 1,
+
+ /**
+ * Forces the analog playback for the supporting radio technology.
+ *
+ * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+ * this option. This is purely user choice, ie. does not reflect digital-
+ * analog handover state managed from the HAL implementation side.
+ *
+ * Some radio technologies may not support this, ie. DAB.
+ */
+ FORCE_ANALOG,
+
+ /**
+ * Forces the digital playback for the supporting radio technology.
+ *
+ * User may disable digital-analog handover that happens with poor
+ * reception conditions. With digital forced, the radio will remain silent
+ * instead of switching to analog channel if it's available. This is purely
+ * user choice, it does not reflect the actual state of handover.
+ */
+ FORCE_DIGITAL,
+
+ /**
+ * RDS Alternative Frequencies.
+ *
+ * If set and the currently tuned RDS station broadcasts on multiple
+ * channels, radio tuner automatically switches to the best available
+ * alternative.
+ */
+ RDS_AF,
+
+ /**
+ * RDS region-specific program lock-down.
+ *
+ * Allows user to lock to the current region as they move into the
+ * other region.
+ */
+ RDS_REG,
+
+ /**
+ * Enables DAB-DAB hard- and implicit-linking (the same content).
+ */
+ DAB_DAB_LINKING,
+
+ /**
+ * Enables DAB-FM hard- and implicit-linking (the same content).
+ */
+ DAB_FM_LINKING,
+
+ /**
+ * Enables DAB-DAB soft-linking (related content).
+ */
+ DAB_DAB_SOFT_LINKING,
+
+ /**
+ * Enables DAB-FM soft-linking (related content).
+ */
+ DAB_FM_SOFT_LINKING,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/DabTableEntry.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/DabTableEntry.aidl
new file mode 100644
index 0000000..13c20b0
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/DabTableEntry.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * An entry in regional configuration for DAB.
+ *
+ * <p>This defines a frequency table row for ensembles.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable DabTableEntry {
+ /**
+ * Channel name, i.e. 5A, 7B.
+ *
+ * It must match the following regular expression:
+ * /^[A-Z0-9][A-Z0-9 ]{0,5}[A-Z0-9]$/ (2-7 uppercase alphanumeric characters
+ * without spaces allowed at the beginning nor end).
+ */
+ String label;
+
+ /**
+ * Frequency, in kHz.
+ */
+ int frequencyKhz;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IAnnouncementListener.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IAnnouncementListener.aidl
new file mode 100644
index 0000000..f6021c1
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IAnnouncementListener.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.Announcement;
+
+/**
+ * Callback interface for announcement listener.
+ *
+ * For typical configuration, the listener is a broadcast radio service.
+ */
+@VintfStability
+interface IAnnouncementListener {
+ /**
+ * Called whenever announcement list has changed.
+ *
+ * @param announcements The complete list of currently active announcements.
+ */
+ oneway void onListUpdated(in Announcement[] announcements);
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IBroadcastRadio.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IBroadcastRadio.aidl
new file mode 100644
index 0000000..0f88fc0
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IBroadcastRadio.aidl
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AmFmRegionConfig;
+import android.hardware.broadcastradio.AnnouncementType;
+import android.hardware.broadcastradio.ConfigFlag;
+import android.hardware.broadcastradio.DabTableEntry;
+import android.hardware.broadcastradio.IAnnouncementListener;
+import android.hardware.broadcastradio.ICloseHandle;
+import android.hardware.broadcastradio.ITunerCallback;
+import android.hardware.broadcastradio.ProgramFilter;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.Properties;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Represents a hardware broadcast radio module. A single module may contain
+ * multiple hardware tuners (i.e. with an additional background tuner), but the
+ * layers above the HAL see them as a single logical unit.
+ */
+@VintfStability
+interface IBroadcastRadio {
+ /**
+ * Invalid identifier for {@link IBroadcastRadio#getImage}.
+ */
+ const int INVALID_IMAGE = 0;
+
+ /**
+ * If the antenna is disconnected from the beginning, the
+ * {@link ITunerCallback#onAntennaStateChange} callback must be
+ * called within this time.
+ */
+ const int ANTENNA_STATE_CHANGE_TIMEOUT_MS = 100;
+
+ /**
+ * All chunks of a signal program list update must be transmitted
+ * within this time.
+ */
+ const int LIST_COMPLETE_TIMEOUT_MS = 300000;
+
+ /**
+ * All tune, seek and step operations must be completed within
+ * this time.
+ */
+ const int TUNER_TIMEOUT_MS = 30000;
+
+ /**
+ * Returns module properties: a description of a module and its
+ * capabilities. This method must not fail.
+ *
+ * @return Module description.
+ */
+ Properties getProperties();
+
+ /**
+ * Fetches current or possible AM/FM region configuration.
+ *
+ * If the tuner doesn't support AM/FM, a service-specific error
+ * {@link Result#NOT_SUPPORTED} will be returned.
+ *
+ * @param full If {@code true}, returns full hardware capabilities.
+ * If {@code false}, returns current regional configuration.
+ * @return config Hardware capabilities (full={@code true}) or current configuration
+ * (full={@code false}).
+ */
+ AmFmRegionConfig getAmFmRegionConfig(in boolean full);
+
+ /**
+ * Fetches current DAB region configuration.
+ *
+ * If tuner doesn't support DAB, a service-specific error
+ * {@link Result#NOT_SUPPORTED} wiil be returned.
+ *
+ * @return config Current configuration.
+ */
+ DabTableEntry[] getDabRegionConfig();
+
+ /**
+ * Sets callback interface.
+ *
+ * It is expected that there will only ever be a single callback set.
+ * If called when a callback is already set, the existing one should be
+ * replaced with the new callback.
+ *
+ * If the callback to be set is null, a service-specific error
+ * {@link Result#INVALID_ARGUMENTS} will be returned; if the callback
+ * is not set successfully, a service-specific error
+ * {@link Result#NOT_SUPPORTED} should be returned.
+ *
+ * @param callback The callback interface used for BroadcastRadio HAL.
+ */
+ void setTunerCallback(in ITunerCallback callback);
+
+ /**
+ * Unsets callback interface.
+ *
+ * The existing callback is set to null.
+ */
+ void unsetTunerCallback();
+
+ /**
+ * Tunes to a specified program.
+ *
+ * Automatically cancels pending tune(), seek() or step().
+ * The method should first check whether tune can be processed by the status
+ * of tuner and inputs, schedule tune task, and then return status
+ * immediately. If a non-null callback is not set, a service-specific
+ * error {@link Result#INVALID_STATE} will be returned; if the program
+ * selector doesn't contain any supported identifier, a service-specific error
+ * {@link Result#NOT_SUPPORTED} will be returned; if the program selector
+ * contains identifiers in invalid format (i.e. out of range), a
+ * service-specific error {@link Result#INVALID_ARGUMENTS} will be returned;
+ * otherwise, OK will be returned as status. Tune task should be processed
+ * asynchronously after the method returns status. If the method returns OK,
+ * {@link ITunerCallback#tuneFailed} or
+ * {@link ITunerCallback#currentProgramInfoChanged} callback must be called
+ * after the tune task completes.
+ *
+ * @param program Program to tune to.
+ */
+ void tune(in ProgramSelector program);
+
+ /**
+ * Seeks the next valid program on the "air".
+ *
+ * Advance to the next detected program and stay there.
+ *
+ * Automatically cancels pending tune(), seek() or step().
+ * The method should first check whether seek can be processed by the status
+ * of tuner and inputs, schedule seek task, and then return status
+ * immediately. If a non-null callback is not set, a service-specific
+ * error {@link Result#INVALID_STATE} will be returned; otherwise, OK will
+ * be returned as status. Seek task should be processed asynchronously
+ * after the method returns status. If the method returns OK,
+ * {@link ITunerCallback#tuneFailed} or
+ * {@link ITunerCallback#currentProgramInfoChanged} callback must be called
+ * after the seek task completes.
+ *
+ * The skipSubChannel parameter is used to skip digital radio subchannels:
+ * - HD Radio SPS;
+ * - DAB secondary service.
+ *
+ * As an implementation detail, the HAL has the option to perform an actual
+ * seek or select the next program from the list retrieved in the
+ * background.
+ *
+ * @param directionUp {@code true} to change towards higher numeric values
+ * (frequency, channel number), {@code false} towards
+ * lower.
+ * @param skipSubChannel Don't tune to subchannels.
+ */
+ void seek(in boolean directionUp, in boolean skipSubChannel);
+
+ /**
+ * Steps to the adjacent channel, which may not be occupied by any program.
+ *
+ * Automatically cancels pending tune(), seek() or step().
+ * The method should first check whether step can be processed by the status
+ * of tuner and inputs, schedule step task, and then return status
+ * immediately. If a non-null callback is not set, service-specific
+ * error {@link Result#INVALID_STATE} will be returned; if tuning to an
+ * unoccupied channel is not supported (i.e. for satellite radio), a
+ * service-specific error {@link Result#NOT_SUPPORTED} will be returned;
+ * otherwise, OK should be returned as status. Step task should be
+ * processed asynchronously after the method returns status. If the
+ * method returns OK, {@link ITunerCallback#tuneFailed} or
+ * {@link currentProgramInfoChanged} callback must be called after the
+ * step task completes.
+ *
+ * @param directionUp {@code true} to change towards higher numeric values
+ * (frequency, channel number), {@code false} towards lower.
+ */
+ void step(in boolean directionUp);
+
+ /**
+ * Cancels pending tune(), seek() or step().
+ *
+ * If there is no such operation running, the call can be ignored.
+ * If cancel is called after the HAL completes an operation (tune, seek, and step)
+ * and before the callback completions, the cancel can be ignored and the callback
+ * should complete.
+ */
+ void cancel();
+
+ /**
+ * Applies a filter to the program list and starts sending program list
+ * update over {@link ITunerCallback#onProgramListUpdated} callback.
+ *
+ * There may be only one updates stream active at the moment. Calling this
+ * method again must result in cancelling the pending update request.
+ *
+ * This call clears the program list on the client side, the HAL must send
+ * the whole list again.
+ *
+ * If the program list scanning hardware (i.e. background tuner) is
+ * unavailable at the moment, the call must succeed and start updates
+ * when it becomes available.
+ *
+ * If the program list scanning is not supported by the hardware, a
+ * service-specific error {@link Result#NOT_SUPPORTED} will be returned.
+ *
+ * @param filter Filter to apply on the fetched program list.
+ */
+ void startProgramListUpdates(in ProgramFilter filter);
+
+ /**
+ * Stops sending program list updates.
+ *
+ * If stopProgramListUpdates is called after the HAL completes a program list update
+ * and before the onCurrentProgramInfoChanged callback completions,
+ * stopProgramListUpdates can be ignored and the callback should complete.
+ */
+ void stopProgramListUpdates();
+
+ /**
+ * Fetches the current setting of a given config flag.
+ *
+ * The success/failure result must be consistent with setConfigFlag.
+ *
+ * If the flag is not applicable, a service-specific error
+ * {@link Result#INVALID_STATE} will be returned. If the flag is not
+ * supported at all, a service-specific error {@link Result#NOT_SUPPORTED}
+ * will be returned.
+ *
+ * @return the current value of the flag, if succeed.
+ */
+ boolean isConfigFlagSet(in ConfigFlag flag);
+
+ /**
+ * Sets the config flag.
+ *
+ * The success/failure result must be consistent with isConfigFlagSet.
+ *
+ * If the flag is not applicable, a service-specific error
+ * {@link Result#INVALID_STATE} will be returned. If the flag is not
+ * supported at all, a service-specific error {@link Result#NOT_SUPPORTED}
+ * will be returned.
+ *
+ * @param flag Flag to set.
+ * @param value The new value of a given flag.
+ */
+ void setConfigFlag(in ConfigFlag flag, in boolean value);
+
+ /**
+ * Generic method for setting vendor-specific parameter values.
+ * The framework does not interpret the parameters, they are passed
+ * in an opaque manner between a vendor application and HAL.
+ *
+ * Framework does not make any assumptions on the keys or values, other than
+ * ones stated in VendorKeyValue documentation (a requirement of key
+ * prefixes).
+ *
+ * For each pair in the result array, the key must be one of the keys
+ * contained in the input (possibly with wildcards expanded), and the value
+ * must be a vendor-specific result status (i.e. the string "OK" or an error
+ * code). The implementation may choose to return an empty array, or only
+ * return a status for a subset of the provided inputs, at its discretion.
+ *
+ * Application and HAL must not use keys with unknown prefix. In particular,
+ * it must not place a key-value pair in results array for unknown key from
+ * parameters array - instead, an unknown key should simply be ignored.
+ * In other words, results array may contain a subset of parameter keys
+ * (however, the framework doesn't enforce a strict subset - the only
+ * formal requirement is vendor domain prefix for keys).
+ *
+ * @param parameters Vendor-specific key-value pairs.
+ * @return Operation completion status for parameters being set.
+ */
+ VendorKeyValue[] setParameters(in VendorKeyValue[] parameters);
+
+ /**
+ * Generic method for retrieving vendor-specific parameter values.
+ * The framework does not interpret the parameters, they are passed
+ * in an opaque manner between a vendor application and HAL.
+ *
+ * Framework does not cache set/get requests, so it's allowed for
+ * getParameter to return a different value than previous setParameter call.
+ *
+ * The syntax and semantics of keys are up to the vendor (as long as prefix
+ * rules are obeyed). For instance, vendors may include some form of
+ * wildcard support. In such case, result array may be of different size
+ * than requested keys array. However, wildcards are not recognized by
+ * framework and they are passed as-is to the HAL implementation.
+ *
+ * Unknown keys must be ignored and not placed into results array.
+ *
+ * @param keys Parameter keys to fetch.
+ * @return Vendor-specific key-value pairs.
+ */
+ VendorKeyValue[] getParameters(in String[] keys);
+
+ /**
+ * Fetches image from radio module cache.
+ *
+ * This is out-of-band transport mechanism for images carried with metadata.
+ * The metadata array only passes the identifier, so the client may cache
+ * images or even not fetch them.
+ *
+ * The identifier may be any arbitrary number (i.e. sha256 prefix) selected
+ * by the vendor. It must be stable so the application may cache it.
+ *
+ * The data must be a valid PNG, JPEG, GIF or BMP file, and must be less
+ * than 1MB, due to hard limit on binder transaction buffer.
+ *
+ * Image data with an invalid format must be handled gracefully in the same
+ * way as a missing image.
+ *
+ * The image identifier may become invalid after some time from passing it
+ * with metadata struct (due to resource cleanup at the HAL implementation).
+ * However, it must remain valid for a currently tuned program at least
+ * until onCurrentProgramInfoChanged is called.
+ *
+ * @param id Identifier of an image (value of {@link IBroadcastRadio#INVALID_IMAGE}
+ * is reserved and must be treated as invalid image).
+ * @return A binary blob with image data
+ * or a zero-length array if identifier doesn't exist.
+ */
+ byte[] getImage(in int id);
+
+ /**
+ * Registers announcement listener.
+ *
+ * If there is at least one observer registered, HAL implementation must
+ * notify about announcements.
+ *
+ * If the observer dies, the HAL implementation must unregister observer
+ * automatically.
+ *
+ * If the tuner doesn't support announcements, a service-specific error
+ * {@link Result#NOT_SUPPORTED} will be returned.
+ *
+ * @param listener The listener interface.
+ * @param enabled The list of announcement types to watch for.
+ * @return a handle to unregister observer.
+ */
+ ICloseHandle registerAnnouncementListener(
+ in IAnnouncementListener listener, in AnnouncementType[] enabled);
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ICloseHandle.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ICloseHandle.aidl
new file mode 100644
index 0000000..4a3240b
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ICloseHandle.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Represents a generic close handle to remove a callback that doesn't need
+ * active interface.
+ */
+@VintfStability
+interface ICloseHandle {
+ /**
+ * Closes the handle.
+ *
+ * The call must not fail and must only be issued once.
+ *
+ * After the close call is executed, no other calls to this interface
+ * are allowed. If the call is issued second time, a service-specific
+ * error {@link Result#INVALID_STATE} will be returned.
+ */
+ void close();
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
new file mode 100644
index 0000000..8de12c8
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ITunerCallback.aidl
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.ConfigFlag;
+import android.hardware.broadcastradio.ProgramInfo;
+import android.hardware.broadcastradio.ProgramListChunk;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.Result;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+@VintfStability
+oneway interface ITunerCallback {
+ /**
+ * Method called by the HAL when a tuning operation fails asynchronously
+ * following {@link IBroadcastRadio#tune}, {@link IBroadcastRadio#seek}
+ * or {@link IBroadcastRadio#step}.
+ *
+ * This callback is only called when the tune(), seek() or step() command
+ * succeeds without returning any error at first.
+ *
+ * @param result {@link Result#TIMEOUT} in case that tune(), seek() or
+ * step() is not completed within
+ * @link IBroadcastRadio#TUNER_TIMEOUT_MS}
+ * or {@link Result#CANCELED} if the command was canceled.
+ * @param selector A ProgramSelector structure passed from tune() call;
+ * empty for step() and seek().
+ */
+ void onTuneFailed(in Result result, in ProgramSelector selector);
+
+ /**
+ * Method called by the HAL when current program information (including
+ * metadata) is updated. It must be called when {@link IBroadcastRadio#tune}
+ * {@link IBroadcastRadio#seek} or {@link IBroadcastRadio#step} command
+ * succeeds.
+ *
+ * This is also called when the radio tuned to the static (not a valid
+ * station), see {@link ProgramInfo#FLAG_TUNABLE} flag.
+ *
+ * @param info Current program information.
+ */
+ void onCurrentProgramInfoChanged(in ProgramInfo info);
+
+ /**
+ * A delta update of the program list, called whenever there's a change in
+ * the list.
+ *
+ * If there are frequent changes, HAL implementation must throttle the rate
+ * of the updates.
+ *
+ * There is a hard limit on binder transaction buffer, and the list must
+ * not exceed it. For large lists, HAL implementation must split them to
+ * multiple chunks, no larger than 500kiB each, and call this program list
+ * update callback method separately.
+ *
+ * @param chunk A chunk of the program list update.
+ */
+ void onProgramListUpdated(in ProgramListChunk chunk);
+
+ /**
+ * Method called by the HAL when the antenna gets connected or disconnected.
+ *
+ * For broadcast radio service, client must assume the antenna is connected.
+ * If it's not, then antennaStateChange must be called within
+ * {@link IBroadcastRadio#ANTENNA_STATE_CHANGE_TIMEOUT_MS} to indicate that.
+ *
+ * @param connected {@code true} if the antenna is now connected, {@code false}
+ * otherwise.
+ */
+ void onAntennaStateChange(in boolean connected);
+
+ /**
+ * Generic callback for passing updates to config flags.
+ *
+ * It's up to the HAL implementation if and how to implement this callback,
+ * as long as it obeys the prefix rule. However, setConfigFlag must not
+ * trigger this callback, while an internal event can change config flag
+ * asynchronously at the HAL layer.
+ *
+ * @param flag Flag that has changed.
+ * @param value The new value of the given flag.
+ */
+ void onConfigFlagUpdated(in ConfigFlag flag, in boolean value);
+
+ /**
+ * Generic callback for passing updates to vendor-specific parameter values.
+ * The framework does not interpret the parameters, they are passed
+ * in an opaque manner between a vendor application and HAL.
+ *
+ * It's up to the HAL implementation if and how to implement this callback,
+ * as long as it obeys the prefix rule. In particular, only selected keys
+ * may be notified this way. However, setParameters must not trigger
+ * this callback, while an internal event can change parameters
+ * asynchronously at the HAL layer.
+ *
+ * @param parameters Vendor-specific key-value pairs,
+ * opaque to Android framework.
+ */
+ void onParametersUpdated(in VendorKeyValue[] parameters);
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
new file mode 100644
index 0000000..646c502
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Type of program identifier component.
+ *
+ * Each identifier type corresponds to exactly one radio technology,
+ * i.e. DAB_ENSEMBLE is specifically for DAB.
+ *
+ * VENDOR identifier types must be opaque to the framework.
+ *
+ * The value format for each (but VENDOR_*) identifier is strictly defined
+ * to maintain interoperability between devices made by different vendors.
+ *
+ * All other values are reserved for future use.
+ * Values not matching any enumerated constant must be ignored.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum IdentifierType {
+ /**
+ * Primary/secondary identifier for vendor-specific radio technology.
+ * The value format is determined by a vendor.
+ *
+ * The vendor identifiers have limited serialization capabilities - see
+ * ProgramSelector description.
+ */
+ VENDOR_START = 1000,
+
+ /**
+ * See VENDOR_START
+ */
+ VENDOR_END = 1999,
+
+ /**
+ * Undefined identifier type.
+ */
+ INVALID = 0,
+
+ /**
+ * Primary identifier for analogue (without RDS) AM/FM stations:
+ * frequency in kHz.
+ *
+ * This identifier also contains band information:
+ * - <500kHz: AM LW;
+ * - 500kHz - 1705kHz: AM MW;
+ * - 1.71MHz - 30MHz: AM SW;
+ * - >60MHz: FM.
+ */
+ AMFM_FREQUENCY_KHZ,
+
+ /**
+ * 16bit primary identifier for FM RDS station.
+ */
+ RDS_PI,
+
+ /**
+ * 64bit compound primary identifier for HD Radio.
+ *
+ * Consists of (from the LSB):
+ * - 32bit: Station ID number;
+ * - 4bit: HD Radio subchannel;
+ * - 18bit: AMFM_FREQUENCY_KHZ.
+ *
+ * While station ID number should be unique globally, it sometimes get
+ * abused by broadcasters (i.e. not being set at all). To ensure local
+ * uniqueness, AMFM_FREQUENCY_KHZ was added here. Global uniqueness is
+ * a best-effort - see HD_STATION_NAME.
+ *
+ * HD Radio subchannel is a value in range 0-7.
+ * This index is 0-based (where 0 is MPS and 1..7 are SPS),
+ * as opposed to HD Radio standard (where it's 1-based).
+ *
+ * The remaining bits should be set to zeros when writing on the chip side
+ * and ignored when read.
+ */
+
+ HD_STATION_ID_EXT,
+
+ /**
+ * 64bit additional identifier for HD Radio.
+ *
+ * Due to Station ID abuse, some HD_STATION_ID_EXT identifiers may be not
+ * globally unique. To provide a best-effort solution, a short version of
+ * station name may be carried as additional identifier and may be used
+ * by the tuner hardware to double-check tuning.
+ *
+ * The name is limited to the first 8 A-Z0-9 characters (lowercase letters
+ * must be converted to uppercase). Encoded in little-endian ASCII:
+ * the first character of the name is the LSB.
+ *
+ * For example: "Abc" is encoded as 0x434241.
+ */
+ HD_STATION_NAME,
+
+ /**
+ * 44bit compound primary identifier for Digital Audio Broadcasting and
+ * Digital Multimeida Broadcasting.
+ *
+ * Consists of (from the LSB):
+ * - 32bit: SId;
+ * - 8bit: ECC code;
+ * - 4bit: SCIdS.
+ *
+ * SCIdS (Service Component Identifier within the Service) value
+ * of 0 represents the main service, while 1 and above represents
+ * secondary services.
+ *
+ * The remaining bits should be set to zeros when writing on the chip side
+ * and ignored when read.
+ */
+ DAB_SID_EXT,
+
+ /**
+ * 16bit
+ */
+ DAB_ENSEMBLE,
+
+ /**
+ * 12bit
+ */
+ DAB_SCID,
+
+ /**
+ * kHz (see AMFM_FREQUENCY_KHZ)
+ */
+ DAB_FREQUENCY_KHZ,
+
+ /**
+ * 24bit primary identifier for Digital Radio Mondiale.
+ */
+ DRMO_SERVICE_ID,
+
+ /**
+ * kHz (see AMFM_FREQUENCY_KHZ)
+ */
+ DRMO_FREQUENCY_KHZ,
+
+ /**
+ * 32bit primary identifier for SiriusXM Satellite Radio.
+ */
+ SXM_SERVICE_ID = DRMO_FREQUENCY_KHZ + 2,
+
+ /**
+ * 0-999 range
+ */
+ SXM_CHANNEL,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
new file mode 100644
index 0000000..3298cac
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Metadata.aidl
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * An element of metadata array.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+union Metadata {
+ /**
+ * RDS PS (string)
+ */
+ String rdsPs;
+
+ /**
+ * RDS PTY (uint8_t)
+ */
+ int rdsPty;
+
+ /**
+ * RBDS PTY (uint8_t)
+ */
+ int rbdsPty;
+
+ /**
+ * RDS RT (string)
+ */
+ String rdsRt;
+
+ /**
+ * Song title (string)
+ */
+ String songTitle;
+
+ /**
+ * Artist name (string)
+ */
+ String songArtist;
+
+ /**
+ * Album name (string)
+ */
+ String songAlbum;
+
+ /**
+ * Station icon (uint32_t, see {@link IBroadcastRadio#getImage})
+ */
+ int stationIcon;
+
+ /**
+ * Album art (uint32_t, see {@link IBroadcastRadio#getImage})
+ */
+ int albumArt;
+
+ /**
+ * Station name.
+ *
+ * This is a generic field to cover any radio technology.
+ *
+ * If the PROGRAM_NAME has the same content as DAB_*_NAME or RDS_PS,
+ * it may not be present, to preserve space - framework must repopulate
+ * it on the client side.
+ */
+ String programName;
+
+ /**
+ * DAB ensemble name (string)
+ */
+ String dabEnsembleName;
+
+ /**
+ * DAB ensemble name abbreviated (string).
+ *
+ * The string must be up to 8 characters long.
+ *
+ * If the short variant is present, the long (DAB_ENSEMBLE_NAME) one must be
+ * present as well.
+ */
+ String dabEnsembleNameShort;
+
+ /**
+ * DAB service name (string)
+ */
+ String dabServiceName;
+
+ /**
+ * DAB service name abbreviated (see DAB_ENSEMBLE_NAME_SHORT) (string)
+ */
+ String dabServiceNameShort;
+
+ /**
+ * DAB component name (string)
+ */
+ String dabComponentName;
+
+ /**
+ * DAB component name abbreviated (see DAB_ENSEMBLE_NAME_SHORT) (string)
+ */
+ String dabComponentNameShort;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramFilter.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramFilter.aidl
new file mode 100644
index 0000000..3dd10eb
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramFilter.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.IdentifierType;
+import android.hardware.broadcastradio.ProgramIdentifier;
+
+/**
+ * Large-grain filter to the program list.
+ *
+ * This is meant to reduce binder transaction bandwidth, not for fine-grained
+ * filtering user might expect.
+ *
+ * The filter is designed as conjunctive normal form: the entry that passes the
+ * filter must satisfy all the clauses (members of this struct). Vector clauses
+ * are disjunctions of literals. In other words, there is AND between each
+ * high-level group and OR inside it.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramFilter {
+ /**
+ * List of identifier types that are filtered by the filter.
+ *
+ * If the program list entry contains at least one identifier of the type
+ * listed, it satisfies this condition.
+ *
+ * Empty list means no filtering on identifier type.
+ */
+ IdentifierType[] identifierTypes;
+
+ /**
+ * List of identifiers that are filtered by the filter.
+ *
+ * If the program list entry contains at least one listed identifier,
+ * it satisfies this condition.
+ *
+ * Empty list means no filtering on identifier.
+ */
+ ProgramIdentifier[] identifiers;
+
+ /**
+ * Includes non-tunable entries that define tree structure on the
+ * program list (i.e. DAB ensembles).
+ */
+ boolean includeCategories;
+
+ /**
+ * Disables updates on entry modifications.
+ *
+ * If {@code true}, 'modified' vector of {@link ProgramListChunk} must contain
+ * list additions only. Once the program is added to the list, it's not
+ * updated anymore.
+ */
+ boolean excludeModifications;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
new file mode 100644
index 0000000..2057d97
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramIdentifier.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.IdentifierType;
+
+/**
+ * A single program identifier component, i.e. frequency or channel ID.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramIdentifier {
+ /**
+ * Maps to IdentifierType enum.
+ */
+ IdentifierType type = IdentifierType.INVALID;
+
+ /**
+ * The uint64_t value field holds the value in format described in comments
+ * for IdentifierType enum.
+ */
+ long value;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
new file mode 100644
index 0000000..7632c81
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.Metadata;
+import android.hardware.broadcastradio.ProgramIdentifier;
+import android.hardware.broadcastradio.ProgramSelector;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Program (channel, station) information.
+ *
+ * Carries both user-visible information (like station name) and technical
+ * details (tuning selector).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramInfo {
+ /**
+ * Set when the program is currently playing live stream.
+ * This may result in a slightly altered reception parameters,
+ * usually targeted at reduced latency.
+ */
+ const int FLAG_LIVE = 1 << 0;
+
+ /**
+ * Radio stream is not playing, ie. due to bad reception conditions or
+ * buffering. In this state volume knob MAY be disabled to prevent user
+ * increasing volume too much.
+ */
+ const int FLAG_MUTED = 1 << 1;
+
+ /**
+ * Station broadcasts traffic information regularly,
+ * but not necessarily right now.
+ */
+ const int FLAG_TRAFFIC_PROGRAM = 1 << 2;
+
+ /**
+ * Station is broadcasting traffic information at the very moment.
+ */
+ const int FLAG_TRAFFIC_ANNOUNCEMENT = 1 << 3;
+
+ /**
+ * Station can be tuned to (not playing static).
+ *
+ * It's the same condition that would stop a seek operation
+ * (i.e. {@link IBroadcastRadio#seek}).
+ *
+ * By definition, this flag must be set for all items on the program list.
+ */
+ const int FLAG_TUNABLE = 1 << 4;
+
+ /**
+ * Audio stream is MONO if this bit is not set.
+ */
+ const int FLAG_STEREO = 1 << 5;
+
+ /**
+ * An identifier used to point at the program (primarily to tune to it).
+ *
+ * This field is required - its type field must not be set to
+ * {@link IdentifierType#INVALID}.
+ */
+ ProgramSelector selector;
+
+ /**
+ * Identifier currently used for program selection.
+ *
+ * It allows to determine which technology is currently used for reception.
+ *
+ * Some program selectors contain tuning information for different radio
+ * technologies (i.e. FM RDS and DAB). For example, user may tune using
+ * a ProgramSelector with RDS_PI primary identifier, but the tuner hardware
+ * may choose to use DAB technology to make actual tuning. This identifier
+ * must reflect that.
+ *
+ * This field is required for currently tuned program only.
+ * For all other items on the program list, its type field must be
+ * initialized to {@link IdentifierType#INVALID}.
+ *
+ * Only primary identifiers for a given radio technology are valid:
+ * - AMFM_FREQUENCY_KHZ for analog AM/FM;
+ * - RDS_PI for FM RDS;
+ * - HD_STATION_ID_EXT;
+ * - DAB_SID_EXT;
+ * - DRMO_SERVICE_ID;
+ * - SXM_SERVICE_ID;
+ * - VENDOR_*;
+ * - more might come in next minor versions of this HAL.
+ */
+ ProgramIdentifier logicallyTunedTo;
+
+ /**
+ * Identifier currently used by hardware to physically tune to a channel.
+ *
+ * Some radio technologies broadcast the same program on multiple channels,
+ * i.e. with RDS AF the same program may be broadcasted on multiple
+ * alternative frequencies; the same DAB program may be broadcast on
+ * multiple ensembles. This identifier points to the channel to which the
+ * radio hardware is physically tuned to.
+ *
+ * This field is required for currently tuned program only.
+ * For all other items on the program list, its type field must be
+ * initialized to {@link IdentifierType#INVALID}.
+ *
+ * Only physical identifiers are valid:
+ * - AMFM_FREQUENCY_KHZ;
+ * - DAB_FREQUENCY_KHZ;
+ * - DRMO_FREQUENCY_KHZ;
+ * - SXM_CHANNEL;
+ * - VENDOR_*;
+ * - more might come in next minor versions of this HAL.
+ */
+ ProgramIdentifier physicallyTunedTo;
+
+ /**
+ * Primary identifiers of related contents.
+ *
+ * Some radio technologies provide pointers to other programs that carry
+ * related content (i.e. DAB soft-links). This field is a list of pointers
+ * to other programs on the program list.
+ *
+ * This is not a list of programs that carry the same content (i.e.
+ * DAB hard-links, RDS AF). Switching to programs from this list usually
+ * require user action.
+ *
+ * Please note, that these identifiers do not have to exist on the program
+ * list - i.e. DAB tuner may provide information on FM RDS alternatives
+ * despite not supporting FM RDS. If the system has multiple tuners, another
+ * one may have it on its list.
+ *
+ * This field is optional.
+ */
+ @nullable ProgramIdentifier[] relatedContent;
+
+ /**
+ * Program flags.
+ *
+ * It can be a combination of {@link #FLAG_LIVE}, {@link #FLAG_MUTED},
+ * {@link #FLAG_TRAFFIC_PROGRAM}, {@link #FLAG_TRAFFIC_ANNOUNCEMENT},
+ * {@link #FLAG_TUNABLE}, and {@link #FLAG_STEREO}.
+ */
+ int infoFlags;
+
+ /**
+ * Signal quality measured in 0% to 100% range to be shown in the UI.
+ */
+ int signalQuality;
+
+ /**
+ * Program metadata (station name, PTY, song title).
+ */
+ Metadata[] metadata;
+
+ /**
+ * Vendor-specific information.
+ *
+ * It may be used for extra features, not supported by the platform,
+ * for example: paid-service=true; bitrate=320kbps.
+ */
+ VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramListChunk.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramListChunk.aidl
new file mode 100644
index 0000000..a62d461
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramListChunk.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.ProgramIdentifier;
+import android.hardware.broadcastradio.ProgramInfo;
+
+/**
+ * An update packet of the program list.
+ *
+ * The order of entries in the arrays is unspecified.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramListChunk {
+ /**
+ * Treats all previously added entries as removed.
+ *
+ * This is meant to save binder transaction bandwidth on 'removed' array
+ * and provide a clear empty state.
+ *
+ * If set, 'removed' array must be null.
+ *
+ * The client may wait with taking action on this until it received the
+ * chunk with complete flag set (to avoid part of stations temporarily
+ * disappearing from the list).
+ */
+ boolean purge;
+
+ /**
+ * If false, it means there are still programs not transmitted,
+ * due for transmission in following updates.
+ *
+ * Used by UIs that wait for complete list instead of displaying
+ * programs while scanning.
+ *
+ * After the whole channel range was scanned and all discovered programs
+ * were transmitted, the last chunk must have set this flag to {@code true}.
+ * This must happen within {@link IBroadcastRadio#LIST_COMPLETE_TIMEOUT_MS}
+ * from the startProgramListUpdates call. If it doesn't, client may assume
+ * the tuner came into a bad state and display error message.
+ */
+ boolean complete;
+
+ /**
+ * Added or modified program list entries.
+ *
+ * Two entries with the same primaryId (ProgramSelector member)
+ * are considered the same.
+ */
+ ProgramInfo[] modified;
+
+ /**
+ * Removed program list entries.
+ *
+ * Contains primaryId (ProgramSelector member) of a program to remove.
+ */
+ @nullable ProgramIdentifier[] removed;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
new file mode 100644
index 0000000..71b824b
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramSelector.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.ProgramIdentifier;
+
+/**
+ * A set of identifiers necessary to tune to a given station.
+ *
+ * This can hold a combination of various identifiers, like:
+ * - AM/FM frequency,
+ * - HD Radio subchannel,
+ * - DAB service ID.
+ *
+ * The type of radio technology is determined by the primary identifier - if the
+ * primary identifier is for DAB, the program is DAB. However, a program of a
+ * specific radio technology may have additional secondary identifiers for other
+ * technologies, i.e. a satellite program may have FM fallback frequency,
+ * if a station broadcasts both via satellite and FM.
+ *
+ * The identifiers from VENDOR_START..VENDOR_END range have limited
+ * serialization capabilities: they are serialized locally, but ignored by the
+ * cloud services. If a program has primary id from vendor range, it's not
+ * synchronized with other devices at all.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable ProgramSelector {
+ /**
+ * Primary program identifier.
+ *
+ * This identifier uniquely identifies a station and can be used for
+ * equality check.
+ *
+ * It can hold only a subset of identifier types, one per each
+ * radio technology:
+ * - analogue AM/FM: AMFM_FREQUENCY_KHZ;
+ * - FM RDS: RDS_PI;
+ * - HD Radio: HD_STATION_ID_EXT;
+ * - DAB/DMB: DAB_SID_EXT;
+ * - Digital Radio Mondiale: DRMO_SERVICE_ID;
+ * - SiriusXM: SXM_SERVICE_ID;
+ * - vendor-specific: VENDOR_START..VENDOR_END.
+ */
+ ProgramIdentifier primaryId;
+
+ /**
+ * Secondary program identifiers.
+ *
+ * These identifiers are supplementary and can speed up tuning process,
+ * but the primary ID should be sufficient (i.e. RDS PI is enough to select
+ * a station from the list after a full band scan).
+ *
+ * Two selectors with different secondary IDs, but the same primary ID are
+ * considered equal. In particular, secondary IDs array may get updated for
+ * an entry on the program list (ie. when a better frequency for a given
+ * station is found).
+ *
+ * If DAB_SID_EXT is used as primaryId, using DAB_ENSEMBLE or DAB_FREQUENCY_KHZ
+ * as secondray identifiers can uniquely identify the DAB station.
+ */
+ ProgramIdentifier[] secondaryIds;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Properties.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Properties.aidl
new file mode 100644
index 0000000..36cbaff
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Properties.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.IdentifierType;
+import android.hardware.broadcastradio.VendorKeyValue;
+
+/**
+ * Properties of a given broadcast radio module.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Properties {
+ /**
+ * A company name who made the radio module. Must be a valid, registered
+ * name of the company itself.
+ *
+ * It must be opaque to the Android framework.
+ */
+ String maker;
+
+ /**
+ * A product name. Must be unique within the company.
+ *
+ * It must be opaque to the Android framework.
+ */
+ String product;
+
+ /**
+ * Version of the hardware module.
+ *
+ * It must be opaque to the Android framework.
+ */
+ String version;
+
+ /**
+ * Hardware serial number (for subscription services).
+ *
+ * It must be opaque to the Android framework.
+ */
+ String serial;
+
+ /**
+ * A list of supported {@link IdentifierType} values.
+ *
+ * If an identifier is supported by radio module, it means it can use it for
+ * tuning to ProgramSelector with either primary or secondary Identifier of
+ * a given type.
+ *
+ * Support for VENDOR identifier type does not guarantee compatibility, as
+ * other module properties (implementor, product, version) must be checked.
+ */
+ IdentifierType[] supportedIdentifierTypes;
+
+ /**
+ * Vendor-specific information.
+ *
+ * It may be used for extra features, not supported by the platform,
+ * for example: com.me.preset-slots=6; com.me.ultra-hd-capable={@code false}.
+ */
+ VendorKeyValue[] vendorInfo;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
new file mode 100644
index 0000000..9f7263a
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Result.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Result for methods of BroadcastRadio AIDL HAL interfaces.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum Result {
+ /**
+ * Methods run without error.
+ */
+ OK = 0,
+
+ /**
+ * Internal error in HAL.
+ */
+ INTERNAL_ERROR,
+
+ /**
+ * Error used when the input argument for the method is invalid.
+ */
+ INVALID_ARGUMENTS,
+
+ /**
+ * Error used when the service is of invalid state (i.e. callback
+ * is not registered for IBroadcastRadio).
+ */
+ INVALID_STATE,
+
+ /**
+ * Error used when an operation is not supported.
+ */
+ NOT_SUPPORTED,
+
+ /**
+ * Error used when a tune, seek, step or operation is not completed
+ * within {@link IBroadcastRadio#LIST_COMPLETE_TIMEOUT_MS}.
+ */
+ TIMEOUT,
+
+ /**
+ * Error used when a tune, seek, step or operation is canceled before
+ * being processed.
+ */
+ CANCELED,
+
+ /**
+ * Error that does not follow into the error categories above.
+ */
+ UNKNOWN_ERROR,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/VendorKeyValue.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/VendorKeyValue.aidl
new file mode 100644
index 0000000..c923e92
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/VendorKeyValue.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * A key-value pair for vendor-specific information to be passed as-is through
+ * Android framework to the front-end application.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable VendorKeyValue {
+ /**
+ * Key must start with unique vendor Java-style namespace,
+ * eg. 'com.somecompany.parameter1'.
+ */
+ String key;
+
+ /**
+ * Value must be passed through the framework without any changes.
+ * Format of this string can vary across vendors.
+ */
+ String value;
+}
diff --git a/broadcastradio/aidl/default/Android.bp b/broadcastradio/aidl/default/Android.bp
new file mode 100644
index 0000000..720aa8a
--- /dev/null
+++ b/broadcastradio/aidl/default/Android.bp
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "android.hardware.broadcastradio-service.default",
+ relative_install_path: "hw",
+ init_rc: ["broadcastradio-default.rc"],
+ vintf_fragments: ["broadcastradio-default.xml"],
+ vendor: true,
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ srcs: [
+ "BroadcastRadio.cpp",
+ "main.cpp",
+ "VirtualProgram.cpp",
+ "VirtualRadio.cpp",
+ ],
+ static_libs: [
+ "android.hardware.broadcastradio@common-utils-aidl-lib",
+ "android.hardware.broadcastradio@common-utils-lib",
+ ],
+ shared_libs: [
+ "android.hardware.broadcastradio-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "liblog",
+ "libcutils",
+ ],
+}
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
new file mode 100644
index 0000000..c0c475a
--- /dev/null
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -0,0 +1,802 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BroadcastRadio.h"
+#include <broadcastradio-utils-aidl/Utils.h>
+#include "resources.h"
+
+#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
+#include <aidl/android/hardware/broadcastradio/Result.h>
+
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+
+#include <private/android_filesystem_config.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+using ::aidl::android::hardware::broadcastradio::utils::resultToInt;
+using ::aidl::android::hardware::broadcastradio::utils::tunesTo;
+using ::android::base::EqualsIgnoreCase;
+using ::ndk::ScopedAStatus;
+using ::std::literals::chrono_literals::operator""ms;
+using ::std::literals::chrono_literals::operator""s;
+using ::std::lock_guard;
+using ::std::mutex;
+using ::std::string;
+using ::std::vector;
+
+namespace {
+
+inline constexpr std::chrono::milliseconds kSeekDelayTimeMs = 200ms;
+inline constexpr std::chrono::milliseconds kStepDelayTimeMs = 100ms;
+inline constexpr std::chrono::milliseconds kTuneDelayTimeMs = 150ms;
+inline constexpr std::chrono::seconds kListDelayTimeS = 1s;
+
+// clang-format off
+const AmFmRegionConfig kDefaultAmFmConfig = {
+ {
+ {87500, 108000, 100, 100}, // FM
+ {153, 282, 3, 9}, // AM LW
+ {531, 1620, 9, 9}, // AM MW
+ {1600, 30000, 1, 5}, // AM SW
+ },
+ AmFmRegionConfig::DEEMPHASIS_D50,
+ AmFmRegionConfig::RDS};
+// clang-format on
+
+Properties initProperties(const VirtualRadio& virtualRadio) {
+ Properties prop = {};
+
+ 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.vendorInfo = vector<VendorKeyValue>({
+ {"com.android.sample", "sample"},
+ });
+
+ return prop;
+}
+
+// Makes ProgramInfo that does not point to any particular program
+ProgramInfo makeSampleProgramInfo(const ProgramSelector& selector) {
+ ProgramInfo info = {};
+ info.selector = selector;
+ info.logicallyTunedTo =
+ utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ utils::getId(selector, IdentifierType::AMFM_FREQUENCY_KHZ));
+ info.physicallyTunedTo = info.logicallyTunedTo;
+ return info;
+}
+
+static bool checkDumpCallerHasWritePermissions(int fd) {
+ uid_t uid = AIBinder_getCallingUid();
+ if (uid == AID_ROOT || uid == AID_SHELL || uid == AID_SYSTEM) {
+ return true;
+ }
+ dprintf(fd, "BroadcastRadio HAL dump must be root, shell or system\n");
+ return false;
+}
+
+} // namespace
+
+BroadcastRadio::BroadcastRadio(const VirtualRadio& virtualRadio)
+ : mVirtualRadio(virtualRadio),
+ mAmFmConfig(kDefaultAmFmConfig),
+ mProperties(initProperties(virtualRadio)) {
+ const auto& ranges = kDefaultAmFmConfig.ranges;
+ if (ranges.size() > 0) {
+ ProgramSelector sel = utils::makeSelectorAmfm(ranges[0].lowerBound);
+ VirtualProgram virtualProgram = {};
+ if (mVirtualRadio.getProgram(sel, &virtualProgram)) {
+ mCurrentProgram = virtualProgram.selector;
+ } else {
+ mCurrentProgram = sel;
+ }
+ }
+}
+
+BroadcastRadio::~BroadcastRadio() {
+ mThread.reset();
+}
+
+ScopedAStatus BroadcastRadio::getAmFmRegionConfig(bool full, AmFmRegionConfig* returnConfigs) {
+ if (full) {
+ *returnConfigs = {};
+ returnConfigs->ranges = vector<AmFmBandRange>({
+ {65000, 108000, 10, 0}, // FM
+ {150, 30000, 1, 0}, // AM
+ });
+ returnConfigs->fmDeemphasis =
+ AmFmRegionConfig::DEEMPHASIS_D50 | AmFmRegionConfig::DEEMPHASIS_D75;
+ returnConfigs->fmRds = AmFmRegionConfig::RDS | AmFmRegionConfig::RBDS;
+ return ScopedAStatus::ok();
+ }
+ lock_guard<mutex> lk(mMutex);
+ *returnConfigs = mAmFmConfig;
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getDabRegionConfig(vector<DabTableEntry>* returnConfigs) {
+ *returnConfigs = {
+ {"5A", 174928}, {"7D", 194064}, {"8A", 195936}, {"8B", 197648}, {"9A", 202928},
+ {"9B", 204640}, {"9C", 206352}, {"10B", 211648}, {"10C", 213360}, {"10D", 215072},
+ {"11A", 216928}, {"11B", 218640}, {"11C", 220352}, {"11D", 222064}, {"12A", 223936},
+ {"12B", 225648}, {"12C", 227360}, {"12D", 229072},
+ };
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getImage(int32_t id, vector<uint8_t>* returnImage) {
+ LOG(DEBUG) << __func__ << ": fetching image " << std::hex << id;
+
+ if (id == resources::kDemoPngId) {
+ *returnImage = vector<uint8_t>(resources::kDemoPng, std::end(resources::kDemoPng));
+ return ScopedAStatus::ok();
+ }
+
+ LOG(WARNING) << __func__ << ": image of id " << std::hex << id << " doesn't exist";
+ *returnImage = {};
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getProperties(Properties* returnProperties) {
+ lock_guard<mutex> lk(mMutex);
+ *returnProperties = mProperties;
+ return ScopedAStatus::ok();
+}
+
+ProgramInfo BroadcastRadio::tuneInternalLocked(const ProgramSelector& sel) {
+ LOG(DEBUG) << __func__ << ": tune (internal) to " << sel.toString();
+
+ VirtualProgram virtualProgram = {};
+ ProgramInfo programInfo;
+ if (mVirtualRadio.getProgram(sel, &virtualProgram)) {
+ mCurrentProgram = virtualProgram.selector;
+ programInfo = virtualProgram;
+ } else {
+ mCurrentProgram = sel;
+ programInfo = makeSampleProgramInfo(sel);
+ }
+ mIsTuneCompleted = true;
+
+ return programInfo;
+}
+
+ScopedAStatus BroadcastRadio::setTunerCallback(const std::shared_ptr<ITunerCallback>& callback) {
+ LOG(DEBUG) << __func__ << ": setTunerCallback";
+
+ if (callback == nullptr) {
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::INVALID_ARGUMENTS), "cannot set tuner callback to null");
+ }
+
+ lock_guard<mutex> lk(mMutex);
+ mCallback = callback;
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::unsetTunerCallback() {
+ LOG(DEBUG) << __func__ << ": unsetTunerCallback";
+
+ lock_guard<mutex> lk(mMutex);
+ mCallback = nullptr;
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::tune(const ProgramSelector& program) {
+ LOG(DEBUG) << __func__ << ": tune to " << program.toString() << "...";
+
+ lock_guard<mutex> lk(mMutex);
+ if (mCallback == nullptr) {
+ LOG(ERROR) << __func__ << ": callback is not registered.";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::INVALID_STATE), "callback is not registered");
+ }
+
+ if (!utils::isSupported(mProperties, program)) {
+ LOG(WARNING) << __func__ << ": selector not supported: " << program.toString();
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::NOT_SUPPORTED), "selector is not supported");
+ }
+
+ if (!utils::isValid(program)) {
+ LOG(ERROR) << __func__ << ": selector is not valid: " << program.toString();
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::INVALID_ARGUMENTS), "selector is not valid");
+ }
+
+ cancelLocked();
+
+ mIsTuneCompleted = false;
+ std::shared_ptr<ITunerCallback> callback = mCallback;
+ auto task = [this, program, callback]() {
+ ProgramInfo programInfo = {};
+ {
+ lock_guard<mutex> lk(mMutex);
+ programInfo = tuneInternalLocked(program);
+ }
+ callback->onCurrentProgramInfoChanged(programInfo);
+ };
+ auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
+ mThread->schedule(task, cancelTask, kTuneDelayTimeMs);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {
+ LOG(DEBUG) << __func__ << ": seek " << (directionUp ? "up" : "down") << " with skipSubChannel? "
+ << (skipSubChannel ? "yes" : "no") << "...";
+
+ lock_guard<mutex> lk(mMutex);
+ if (mCallback == nullptr) {
+ LOG(ERROR) << __func__ << ": callback is not registered.";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::INVALID_STATE), "callback is not registered");
+ }
+
+ cancelLocked();
+
+ const auto& list = mVirtualRadio.getProgramList();
+ std::shared_ptr<ITunerCallback> callback = mCallback;
+ auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
+ if (list.empty()) {
+ mIsTuneCompleted = false;
+ auto task = [callback]() {
+ LOG(DEBUG) << "seek: program list is empty, seek couldn't stop";
+
+ callback->onTuneFailed(Result::TIMEOUT, {});
+ };
+ mThread->schedule(task, cancelTask, kSeekDelayTimeMs);
+
+ return ScopedAStatus::ok();
+ }
+
+ // The list is not sorted here since it has already stored in VirtualRadio.
+ // If the list is not sorted in advance, it should be sorted here.
+ const auto& current = mCurrentProgram;
+ auto found = std::lower_bound(list.begin(), list.end(), VirtualProgram({current}));
+ if (directionUp) {
+ if (found < list.end() - 1) {
+ if (tunesTo(current, found->selector)) found++;
+ } else {
+ found = list.begin();
+ }
+ } else {
+ if (found > list.begin() && found != list.end()) {
+ found--;
+ } else {
+ found = list.end() - 1;
+ }
+ }
+ const ProgramSelector tuneTo = found->selector;
+
+ mIsTuneCompleted = false;
+ auto task = [this, tuneTo, callback]() {
+ ProgramInfo programInfo = {};
+ {
+ lock_guard<mutex> lk(mMutex);
+ programInfo = tuneInternalLocked(tuneTo);
+ }
+ callback->onCurrentProgramInfoChanged(programInfo);
+ };
+ mThread->schedule(task, cancelTask, kSeekDelayTimeMs);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::step(bool directionUp) {
+ LOG(DEBUG) << __func__ << ": step " << (directionUp ? "up" : "down") << "...";
+
+ lock_guard<mutex> lk(mMutex);
+ if (mCallback == nullptr) {
+ LOG(ERROR) << __func__ << ": callback is not registered.";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::INVALID_STATE), "callback is not registered");
+ }
+
+ cancelLocked();
+
+ if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+ LOG(WARNING) << __func__ << ": can't step in anything else than AM/FM";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::NOT_SUPPORTED), "cannot step in anything else than AM/FM");
+ }
+
+ int64_t stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
+ std::optional<AmFmBandRange> range = getAmFmRangeLocked();
+ if (!range) {
+ LOG(ERROR) << __func__ << ": can't find current band or tune operation is in process";
+ ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::INTERNAL_ERROR),
+ "can't find current band or tune operation is in process");
+ }
+
+ if (directionUp) {
+ stepTo += range->spacing;
+ } else {
+ stepTo -= range->spacing;
+ }
+ if (stepTo > range->upperBound) {
+ stepTo = range->lowerBound;
+ }
+ if (stepTo < range->lowerBound) {
+ stepTo = range->upperBound;
+ }
+
+ mIsTuneCompleted = false;
+ std::shared_ptr<ITunerCallback> callback = mCallback;
+ auto task = [this, stepTo, callback]() {
+ ProgramInfo programInfo;
+ {
+ lock_guard<mutex> lk(mMutex);
+ programInfo = tuneInternalLocked(utils::makeSelectorAmfm(stepTo));
+ }
+ callback->onCurrentProgramInfoChanged(programInfo);
+ };
+ auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
+ mThread->schedule(task, cancelTask, kStepDelayTimeMs);
+
+ return ScopedAStatus::ok();
+}
+
+void BroadcastRadio::cancelLocked() {
+ LOG(DEBUG) << __func__ << ": cancelling current operations...";
+
+ mThread->cancelAll();
+ if (mCurrentProgram.primaryId.type != IdentifierType::INVALID) {
+ mIsTuneCompleted = true;
+ }
+}
+
+ScopedAStatus BroadcastRadio::cancel() {
+ LOG(DEBUG) << __func__ << ": cancel pending tune, seek and step...";
+
+ lock_guard<mutex> lk(mMutex);
+ cancelLocked();
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::startProgramListUpdates(const ProgramFilter& filter) {
+ LOG(DEBUG) << __func__ << ": requested program list updates, filter = " << filter.toString()
+ << "...";
+
+ auto filterCb = [&filter](const VirtualProgram& program) {
+ return utils::satisfies(filter, program.selector);
+ };
+
+ lock_guard<mutex> lk(mMutex);
+
+ const auto& list = mVirtualRadio.getProgramList();
+ vector<VirtualProgram> filteredList;
+ std::copy_if(list.begin(), list.end(), std::back_inserter(filteredList), filterCb);
+
+ auto task = [this, filteredList]() {
+ std::shared_ptr<ITunerCallback> callback;
+ {
+ lock_guard<mutex> lk(mMutex);
+ if (mCallback == nullptr) {
+ LOG(WARNING) << "Callback is null when updating program List";
+ return;
+ }
+ callback = mCallback;
+ }
+
+ ProgramListChunk chunk = {};
+ chunk.purge = true;
+ chunk.complete = true;
+ chunk.modified = vector<ProgramInfo>(filteredList.begin(), filteredList.end());
+
+ callback->onProgramListUpdated(chunk);
+ };
+ mThread->schedule(task, kListDelayTimeS);
+
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::stopProgramListUpdates() {
+ LOG(DEBUG) << __func__ << ": requested program list updates to stop...";
+ // TODO(b/243681584) Implement stop program list updates method
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::isConfigFlagSet(ConfigFlag flag, [[maybe_unused]] bool* returnIsSet) {
+ LOG(DEBUG) << __func__ << ": flag = " << toString(flag);
+
+ LOG(INFO) << __func__ << ": getting ConfigFlag is not supported";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::NOT_SUPPORTED), "getting ConfigFlag is not supported");
+}
+
+ScopedAStatus BroadcastRadio::setConfigFlag(ConfigFlag flag, bool value) {
+ LOG(DEBUG) << __func__ << ": flag = " << toString(flag) << ", value = " << value;
+
+ LOG(INFO) << __func__ << ": setting ConfigFlag is not supported";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::NOT_SUPPORTED), "setting ConfigFlag is not supported");
+}
+
+ScopedAStatus BroadcastRadio::setParameters(
+ [[maybe_unused]] const vector<VendorKeyValue>& parameters,
+ vector<VendorKeyValue>* returnParameters) {
+ // TODO(b/243682330) Support vendor parameter functionality
+ *returnParameters = {};
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus BroadcastRadio::getParameters([[maybe_unused]] const vector<string>& keys,
+ vector<VendorKeyValue>* returnParameters) {
+ // TODO(b/243682330) Support vendor parameter functionality
+ *returnParameters = {};
+ return ScopedAStatus::ok();
+}
+
+std::optional<AmFmBandRange> BroadcastRadio::getAmFmRangeLocked() const {
+ if (!mIsTuneCompleted) {
+ LOG(WARNING) << __func__ << ": tune operation is in process";
+ return {};
+ }
+ if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+ LOG(WARNING) << __func__ << ": current program does not has AMFM_FREQUENCY_KHZ identifier";
+ return {};
+ }
+
+ int64_t freq = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
+ for (const auto& range : mAmFmConfig.ranges) {
+ if (range.lowerBound <= freq && range.upperBound >= freq) {
+ return range;
+ }
+ }
+
+ return {};
+}
+
+ScopedAStatus BroadcastRadio::registerAnnouncementListener(
+ [[maybe_unused]] const std::shared_ptr<IAnnouncementListener>& listener,
+ const vector<AnnouncementType>& enabled, std::shared_ptr<ICloseHandle>* returnCloseHandle) {
+ LOG(DEBUG) << __func__ << ": registering announcement listener for "
+ << utils::vectorToString(enabled);
+
+ // TODO(b/243683842) Support announcement listener
+ *returnCloseHandle = nullptr;
+ LOG(INFO) << __func__ << ": registering announcementListener is not supported";
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ resultToInt(Result::NOT_SUPPORTED),
+ "registering announcementListener is not supported");
+}
+
+binder_status_t BroadcastRadio::dump(int fd, const char** args, uint32_t numArgs) {
+ if (numArgs == 0) {
+ return dumpsys(fd);
+ }
+
+ string option = string(args[0]);
+ if (EqualsIgnoreCase(option, "--help")) {
+ return cmdHelp(fd);
+ } else if (EqualsIgnoreCase(option, "--tune")) {
+ return cmdTune(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--seek")) {
+ return cmdSeek(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--step")) {
+ return cmdStep(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--cancel")) {
+ return cmdCancel(fd, numArgs);
+ } else if (EqualsIgnoreCase(option, "--startProgramListUpdates")) {
+ return cmdStartProgramListUpdates(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--stopProgramListUpdates")) {
+ return cmdStopProgramListUpdates(fd, numArgs);
+ }
+ dprintf(fd, "Invalid option: %s\n", option.c_str());
+ return STATUS_BAD_VALUE;
+}
+
+binder_status_t BroadcastRadio::dumpsys(int fd) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ lock_guard<mutex> lk(mMutex);
+ dprintf(fd, "AmFmRegionConfig: %s\n", mAmFmConfig.toString().c_str());
+ dprintf(fd, "Properties: %s \n", mProperties.toString().c_str());
+ if (mIsTuneCompleted) {
+ dprintf(fd, "Tune completed\n");
+ } else {
+ dprintf(fd, "Tune not completed\n");
+ }
+ if (mCallback == nullptr) {
+ dprintf(fd, "No ITunerCallback registered\n");
+ } else {
+ dprintf(fd, "ITunerCallback registered\n");
+ }
+ dprintf(fd, "CurrentProgram: %s \n", mCurrentProgram.toString().c_str());
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdHelp(int fd) const {
+ dprintf(fd, "Usage: \n\n");
+ dprintf(fd, "[no args]: dumps focus listener / gain callback registered status\n");
+ dprintf(fd, "--help: shows this help\n");
+ dprintf(fd,
+ "--tune amfm <FREQUENCY>: tunes amfm radio to frequency (in Hz) specified: "
+ "frequency (int) \n"
+ "--tune dab <SID> <ENSEMBLE>: tunes dab radio to sid and ensemble specified: "
+ "sidExt (int), ensemble (int) \n");
+ dprintf(fd,
+ "--seek [up|down] <SKIP_SUB_CHANNEL>: seek with direction (up or down) and "
+ "option whether skipping sub channel: "
+ "skipSubChannel (string, should be either \"true\" or \"false\")\n");
+ dprintf(fd, "--step [up|down]: step in direction (up or down) specified\n");
+ dprintf(fd, "--cancel: cancel current pending tune, step, and seek\n");
+ dprintf(fd,
+ "--startProgramListUpdates <IDENTIFIER_TYPES> <IDENTIFIERS> <INCLUDE_CATEGORIES> "
+ "<EXCLUDE_MODIFICATIONS>: start update program list with the filter specified: "
+ "identifier types (string, in format <TYPE>,<TYPE>,...,<TYPE> or \"null\" (if empty), "
+ "where TYPE is int), "
+ "program identifiers (string, in format "
+ "<TYPE>:<VALUE>,<TYPE>:<VALUE>,...,<TYPE>:<VALUE> or \"null\" (if empty), "
+ "where TYPE is int and VALUE is long), "
+ "includeCategories (string, should be either \"true\" or \"false\"), "
+ "excludeModifications (string, should be either \"true\" or \"false\")\n");
+ dprintf(fd, "--stopProgramListUpdates: stop current pending program list updates\n");
+ dprintf(fd,
+ "Note on <TYPE> for --startProgramList command: it is int for identifier type. "
+ "Please see broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl "
+ "for its definition.\n");
+ dprintf(fd,
+ "Note on <VALUE> for --startProgramList command: it is long type for identifier value. "
+ "Please see broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl "
+ "for its value.\n");
+
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdTune(int fd, const char** args, uint32_t numArgs) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 3 && numArgs != 4) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --tune amfm <FREQUENCY> "
+ "or --tune dab <SID> <ENSEMBLE>\n");
+ return STATUS_BAD_VALUE;
+ }
+ bool isDab = false;
+ if (EqualsIgnoreCase(string(args[1]), "dab")) {
+ isDab = true;
+ } else if (!EqualsIgnoreCase(string(args[1]), "amfm")) {
+ dprintf(fd, "Unknown radio type provided with tune: %s\n", args[1]);
+ return STATUS_BAD_VALUE;
+ }
+ ProgramSelector sel = {};
+ if (isDab) {
+ if (numArgs != 5 && numArgs != 3) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide "
+ "--tune dab <SID> <ENSEMBLE> <FREQUENCY> or "
+ "--tune dab <SID>\n");
+ return STATUS_BAD_VALUE;
+ }
+ int sid;
+ if (!utils::parseArgInt(string(args[2]), &sid)) {
+ dprintf(fd, "Non-integer sid provided with tune: %s\n", args[2]);
+ return STATUS_BAD_VALUE;
+ }
+ if (numArgs == 3) {
+ sel = utils::makeSelectorDab(sid);
+ } else {
+ int ensemble;
+ if (!utils::parseArgInt(string(args[3]), &ensemble)) {
+ dprintf(fd, "Non-integer ensemble provided with tune: %s\n", args[3]);
+ return STATUS_BAD_VALUE;
+ }
+ int freq;
+ if (!utils::parseArgInt(string(args[4]), &freq)) {
+ dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[4]);
+ return STATUS_BAD_VALUE;
+ }
+ sel = utils::makeSelectorDab(sid, ensemble, freq);
+ }
+ } else {
+ if (numArgs != 3) {
+ dprintf(fd, "Invalid number of arguments: please provide --tune amfm <FREQUENCY>\n");
+ return STATUS_BAD_VALUE;
+ }
+ int freq;
+ if (!utils::parseArgInt(string(args[2]), &freq)) {
+ dprintf(fd, "Non-integer frequency provided with tune: %s\n", args[2]);
+ return STATUS_BAD_VALUE;
+ }
+ sel = utils::makeSelectorAmfm(freq);
+ }
+
+ auto tuneResult = tune(sel);
+ if (!tuneResult.isOk()) {
+ dprintf(fd, "Unable to tune %s radio to %s\n", args[1], sel.toString().c_str());
+ return STATUS_BAD_VALUE;
+ }
+ dprintf(fd, "Tune %s radio to %s \n", args[1], sel.toString().c_str());
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdSeek(int fd, const char** args, uint32_t numArgs) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 3) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --seek <DIRECTION> "
+ "<SKIP_SUB_CHANNEL>\n");
+ return STATUS_BAD_VALUE;
+ }
+ string seekDirectionIn = string(args[1]);
+ bool seekDirectionUp;
+ if (!utils::parseArgDirection(seekDirectionIn, &seekDirectionUp)) {
+ dprintf(fd, "Invalid direction (\"up\" or \"down\") provided with seek: %s\n",
+ seekDirectionIn.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ string skipSubChannelIn = string(args[2]);
+ bool skipSubChannel;
+ if (!utils::parseArgBool(skipSubChannelIn, &skipSubChannel)) {
+ dprintf(fd, "Invalid skipSubChannel (\"true\" or \"false\") provided with seek: %s\n",
+ skipSubChannelIn.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ auto seekResult = seek(seekDirectionUp, skipSubChannel);
+ if (!seekResult.isOk()) {
+ dprintf(fd, "Unable to seek in %s direction\n", seekDirectionIn.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ dprintf(fd, "Seek in %s direction\n", seekDirectionIn.c_str());
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdStep(int fd, const char** args, uint32_t numArgs) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 2) {
+ dprintf(fd, "Invalid number of arguments: please provide --step <DIRECTION>\n");
+ return STATUS_BAD_VALUE;
+ }
+ string stepDirectionIn = string(args[1]);
+ bool stepDirectionUp;
+ if (!utils::parseArgDirection(stepDirectionIn, &stepDirectionUp)) {
+ dprintf(fd, "Invalid direction (\"up\" or \"down\") provided with step: %s\n",
+ stepDirectionIn.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ auto stepResult = step(stepDirectionUp);
+ if (!stepResult.isOk()) {
+ dprintf(fd, "Unable to step in %s direction\n", stepDirectionIn.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ dprintf(fd, "Step in %s direction\n", stepDirectionIn.c_str());
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdCancel(int fd, uint32_t numArgs) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 1) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --cancel "
+ "only and no more arguments\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ auto cancelResult = cancel();
+ if (!cancelResult.isOk()) {
+ dprintf(fd, "Unable to cancel pending tune, seek, and step\n");
+ return STATUS_BAD_VALUE;
+ }
+ dprintf(fd, "Canceled pending tune, seek, and step\n");
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdStartProgramListUpdates(int fd, const char** args,
+ uint32_t numArgs) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 5) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --startProgramListUpdates "
+ "<IDENTIFIER_TYPES> <IDENTIFIERS> <INCLUDE_CATEGORIES> "
+ "<EXCLUDE_MODIFICATIONS>\n");
+ return STATUS_BAD_VALUE;
+ }
+ string filterTypesStr = string(args[1]);
+ std::vector<IdentifierType> filterTypeList;
+ if (!EqualsIgnoreCase(filterTypesStr, "null") &&
+ !utils::parseArgIdentifierTypeArray(filterTypesStr, &filterTypeList)) {
+ dprintf(fd,
+ "Invalid identifier types provided with startProgramListUpdates: %s, "
+ "should be: <TYPE>,<TYPE>,...,<TYPE>\n",
+ filterTypesStr.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ string filtersStr = string(args[2]);
+ std::vector<ProgramIdentifier> filterList;
+ if (!EqualsIgnoreCase(filtersStr, "null") &&
+ !utils::parseProgramIdentifierList(filtersStr, &filterList)) {
+ dprintf(fd,
+ "Invalid program identifiers provided with startProgramListUpdates: %s, "
+ "should be: <TYPE>:<VALUE>,<TYPE>:<VALUE>,...,<TYPE>:<VALUE>\n",
+ filtersStr.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ string includeCategoriesStr = string(args[3]);
+ bool includeCategories;
+ if (!utils::parseArgBool(includeCategoriesStr, &includeCategories)) {
+ dprintf(fd,
+ "Invalid includeCategories (\"true\" or \"false\") "
+ "provided with startProgramListUpdates : %s\n",
+ includeCategoriesStr.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ string excludeModificationsStr = string(args[4]);
+ bool excludeModifications;
+ if (!utils::parseArgBool(excludeModificationsStr, &excludeModifications)) {
+ dprintf(fd,
+ "Invalid excludeModifications(\"true\" or \"false\") "
+ "provided with startProgramListUpdates : %s\n",
+ excludeModificationsStr.c_str());
+ return STATUS_BAD_VALUE;
+ }
+ ProgramFilter filter = {filterTypeList, filterList, includeCategories, excludeModifications};
+
+ auto updateResult = startProgramListUpdates(filter);
+ if (!updateResult.isOk()) {
+ dprintf(fd, "Unable to start program list update for filter %s \n",
+ filter.toString().c_str());
+ return STATUS_BAD_VALUE;
+ }
+ dprintf(fd, "Start program list update for filter %s\n", filter.toString().c_str());
+ return STATUS_OK;
+}
+
+binder_status_t BroadcastRadio::cmdStopProgramListUpdates(int fd, uint32_t numArgs) {
+ if (!checkDumpCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 1) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --stopProgramListUpdates "
+ "only and no more arguments\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ auto stopResult = stopProgramListUpdates();
+ if (!stopResult.isOk()) {
+ dprintf(fd, "Unable to stop pending program list update\n");
+ return STATUS_BAD_VALUE;
+ }
+ dprintf(fd, "Stop pending program list update\n");
+ return STATUS_OK;
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/BroadcastRadio.h b/broadcastradio/aidl/default/BroadcastRadio.h
new file mode 100644
index 0000000..1c85ddc
--- /dev/null
+++ b/broadcastradio/aidl/default/BroadcastRadio.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "VirtualRadio.h"
+
+#include <aidl/android/hardware/broadcastradio/AmFmBandRange.h>
+#include <aidl/android/hardware/broadcastradio/AmFmRegionConfig.h>
+#include <aidl/android/hardware/broadcastradio/AnnouncementType.h>
+#include <aidl/android/hardware/broadcastradio/BnBroadcastRadio.h>
+#include <aidl/android/hardware/broadcastradio/DabTableEntry.h>
+#include <aidl/android/hardware/broadcastradio/IAnnouncementListener.h>
+#include <aidl/android/hardware/broadcastradio/ICloseHandle.h>
+#include <aidl/android/hardware/broadcastradio/ITunerCallback.h>
+#include <aidl/android/hardware/broadcastradio/Properties.h>
+#include <broadcastradio-utils/WorkerThread.h>
+
+#include <android-base/thread_annotations.h>
+
+#include <optional>
+
+namespace aidl::android::hardware::broadcastradio {
+
+class BroadcastRadio final : public BnBroadcastRadio {
+ public:
+ explicit BroadcastRadio(const VirtualRadio& virtualRadio);
+ ~BroadcastRadio();
+ ndk::ScopedAStatus getAmFmRegionConfig(bool full, AmFmRegionConfig* returnConfigs) override;
+ ndk::ScopedAStatus getDabRegionConfig(std::vector<DabTableEntry>* returnConfigs) override;
+ ndk::ScopedAStatus getImage(int32_t id, std::vector<uint8_t>* returnImage) override;
+ ndk::ScopedAStatus getProperties(Properties* returnProperties) override;
+
+ ndk::ScopedAStatus setTunerCallback(const std::shared_ptr<ITunerCallback>& callback) override;
+ ndk::ScopedAStatus unsetTunerCallback() override;
+ ndk::ScopedAStatus tune(const ProgramSelector& program) override;
+ ndk::ScopedAStatus seek(bool directionUp, bool skipSubChannel) override;
+ ndk::ScopedAStatus step(bool directionUp) override;
+ ndk::ScopedAStatus cancel() override;
+ ndk::ScopedAStatus startProgramListUpdates(const ProgramFilter& filter) override;
+ ndk::ScopedAStatus stopProgramListUpdates() override;
+ ndk::ScopedAStatus isConfigFlagSet(ConfigFlag flag, bool* returnIsSet) override;
+ ndk::ScopedAStatus setConfigFlag(ConfigFlag flag, bool in_value) override;
+ ndk::ScopedAStatus setParameters(const std::vector<VendorKeyValue>& parameters,
+ std::vector<VendorKeyValue>* returnParameters) override;
+ ndk::ScopedAStatus getParameters(const std::vector<std::string>& keys,
+ std::vector<VendorKeyValue>* returnParameters) override;
+ ndk::ScopedAStatus registerAnnouncementListener(
+ const std::shared_ptr<IAnnouncementListener>& listener,
+ const std::vector<AnnouncementType>& enabled,
+ std::shared_ptr<ICloseHandle>* returnCloseHandle) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ private:
+ const VirtualRadio& mVirtualRadio;
+ std::mutex mMutex;
+ AmFmRegionConfig mAmFmConfig GUARDED_BY(mMutex);
+ std::unique_ptr<::android::WorkerThread> mThread GUARDED_BY(mMutex) =
+ std::unique_ptr<::android::WorkerThread>(new ::android::WorkerThread());
+ bool mIsTuneCompleted GUARDED_BY(mMutex) = true;
+ Properties mProperties GUARDED_BY(mMutex);
+ ProgramSelector mCurrentProgram GUARDED_BY(mMutex) = {};
+ std::shared_ptr<ITunerCallback> mCallback GUARDED_BY(mMutex);
+
+ std::optional<AmFmBandRange> getAmFmRangeLocked() const;
+ void cancelLocked();
+ ProgramInfo tuneInternalLocked(const ProgramSelector& sel);
+
+ binder_status_t cmdHelp(int fd) const;
+ binder_status_t cmdTune(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdSeek(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdStep(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdCancel(int fd, uint32_t numArgs);
+ binder_status_t cmdStartProgramListUpdates(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdStopProgramListUpdates(int fd, uint32_t numArgs);
+
+ binder_status_t dumpsys(int fd);
+};
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualProgram.cpp b/broadcastradio/aidl/default/VirtualProgram.cpp
new file mode 100644
index 0000000..4fe6567
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualProgram.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VirtualProgram.h"
+
+#include <broadcastradio-utils-aidl/Utils.h>
+#include "resources.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+using ::std::vector;
+
+VirtualProgram::operator ProgramInfo() const {
+ ProgramInfo info = {};
+
+ info.selector = selector;
+
+ IdentifierType programType = selector.primaryId.type;
+ bool isDigital = (programType != IdentifierType::AMFM_FREQUENCY_KHZ &&
+ programType != IdentifierType::RDS_PI);
+
+ auto selectId = [&info](const IdentifierType& type) {
+ return utils::makeIdentifier(type, utils::getId(info.selector, type));
+ };
+
+ switch (programType) {
+ case IdentifierType::AMFM_FREQUENCY_KHZ:
+ info.logicallyTunedTo = info.physicallyTunedTo =
+ selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+ break;
+ case IdentifierType::RDS_PI:
+ info.logicallyTunedTo = selectId(IdentifierType::RDS_PI);
+ info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+ break;
+ case IdentifierType::HD_STATION_ID_EXT:
+ info.logicallyTunedTo = selectId(IdentifierType::HD_STATION_ID_EXT);
+ info.physicallyTunedTo = selectId(IdentifierType::AMFM_FREQUENCY_KHZ);
+ break;
+ case IdentifierType::DAB_SID_EXT:
+ info.logicallyTunedTo = selectId(IdentifierType::DAB_SID_EXT);
+ info.physicallyTunedTo = selectId(IdentifierType::DAB_FREQUENCY_KHZ);
+ break;
+ case IdentifierType::DRMO_SERVICE_ID:
+ info.logicallyTunedTo = selectId(IdentifierType::DRMO_SERVICE_ID);
+ info.physicallyTunedTo = selectId(IdentifierType::DRMO_FREQUENCY_KHZ);
+ break;
+ case IdentifierType::SXM_SERVICE_ID:
+ info.logicallyTunedTo = selectId(IdentifierType::SXM_SERVICE_ID);
+ info.physicallyTunedTo = selectId(IdentifierType::SXM_CHANNEL);
+ break;
+ default:
+ LOG(FATAL) << "unsupported program type: " << toString(programType);
+ return {};
+ }
+
+ info.infoFlags |= (ProgramInfo::FLAG_TUNABLE | ProgramInfo::FLAG_STEREO);
+ info.signalQuality = isDigital ? kSignalQualityDigital : kSignalQualityNonDigital;
+
+ info.metadata = vector<Metadata>({
+ Metadata::make<Metadata::rdsPs>(programName),
+ Metadata::make<Metadata::songTitle>(songTitle),
+ Metadata::make<Metadata::songArtist>(songArtist),
+ Metadata::make<Metadata::stationIcon>(resources::kDemoPngId),
+ Metadata::make<Metadata::albumArt>(resources::kDemoPngId),
+ });
+
+ info.vendorInfo = vector<VendorKeyValue>({
+ {"com.android.sample", "sample"},
+ {"com.android.sample.VirtualProgram", "VirtualProgram"},
+ });
+
+ return info;
+}
+
+bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
+ auto& l = lhs.selector;
+ auto& r = rhs.selector;
+
+ // Two programs with the same primaryId are considered the same.
+ if (l.primaryId.type != r.primaryId.type) return l.primaryId.type < r.primaryId.type;
+
+ return l.primaryId.value < r.primaryId.value;
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualProgram.h b/broadcastradio/aidl/default/VirtualProgram.h
new file mode 100644
index 0000000..0c20721
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualProgram.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+constexpr int kSignalQualityDigital = 100;
+constexpr int kSignalQualityNonDigital = 80;
+/**
+ * A radio program mock.
+ *
+ * This represents broadcast waves flying over the air,
+ * not an entry for a captured station in the radio tuner memory.
+ */
+struct VirtualProgram {
+ ProgramSelector selector;
+
+ std::string programName = "";
+ std::string songArtist = "";
+ std::string songTitle = "";
+
+ operator ProgramInfo() const;
+
+ /**
+ * Defines order in which virtual programs appear on the "air" with
+ * ITunerSession::scan().
+ *
+ * It's for default implementation purposes, may not be complete or correct.
+ */
+ friend bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs);
+};
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualRadio.cpp b/broadcastradio/aidl/default/VirtualRadio.cpp
new file mode 100644
index 0000000..126bcff
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualRadio.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VirtualRadio.h"
+#include <broadcastradio-utils-aidl/Utils.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorAmfm;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
+using ::std::string;
+using ::std::vector;
+
+VirtualRadio::VirtualRadio(const string& name, const vector<VirtualProgram>& initialList)
+ : mName(name), mPrograms(initialList) {
+ sort(mPrograms.begin(), mPrograms.end());
+}
+
+string VirtualRadio::getName() const {
+ return mName;
+}
+
+const vector<VirtualProgram>& VirtualRadio::getProgramList() const {
+ return mPrograms;
+}
+
+bool VirtualRadio::getProgram(const ProgramSelector& selector, VirtualProgram* programOut) const {
+ for (const auto& program : mPrograms) {
+ if (utils::tunesTo(selector, program.selector)) {
+ *programOut = program;
+ return true;
+ }
+ }
+ return false;
+}
+
+// get singleton of AMFM Virtual Radio
+const VirtualRadio& VirtualRadio::getAmFmRadio() {
+ // clang-format off
+ static VirtualRadio amFmRadioMock(
+ "AM/FM radio mock",
+ {
+ {makeSelectorAmfm(/* frequency= */ 94900), "Wild 94.9", "Drake ft. Rihanna",
+ "Too Good"},
+ {makeSelectorAmfm(/* frequency= */ 96500), "KOIT", "Celine Dion", "All By Myself"},
+ {makeSelectorAmfm(/* frequency= */ 97300), "[email protected]", "Drops of Jupiter", "Train"},
+ {makeSelectorAmfm(/* frequency= */ 99700), "99.7 Now!", "The Chainsmokers", "Closer"},
+ {makeSelectorAmfm(/* frequency= */ 101300), "101-3 KISS-FM", "Justin Timberlake",
+ "Rock Your Body"},
+ {makeSelectorAmfm(/* frequency= */ 103700), "iHeart80s @ 103.7", "Michael Jackson",
+ "Billie Jean"},
+ {makeSelectorAmfm(/* frequency= */ 106100), "106 KMEL", "Drake", "Marvins Room"},
+ {makeSelectorAmfm(/* frequency= */ 700), "700 AM", "Artist700", "Title700"},
+ {makeSelectorAmfm(/* frequency= */ 1700), "1700 AM", "Artist1700", "Title1700"},
+ });
+ // clang-format on
+ return amFmRadioMock;
+}
+
+// get singleton of DAB Virtual Radio
+const VirtualRadio& VirtualRadio::getDabRadio() {
+ // clang-format off
+ static VirtualRadio dabRadioMock(
+ "DAB radio mock",
+ {
+ {makeSelectorDab(/* sidExt= */ 0xA000000001u, /* ensemble= */ 0x0001u,
+ /* freq= */ 225648), "BBC Radio 1", "Khalid", "Talk"},
+ {makeSelectorDab(/* sidExt= */ 0xB000000001u, /* ensemble= */ 0x1001u,
+ /* freq= */ 222064), "Classic FM", "Jean Sibelius", "Andante Festivo"},
+ {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+ /* freq= */ 227360), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+ /* freq= */ 222064), "Absolute Radio", "Coldplay", "Clocks"},
+ });
+ // clang-format on
+ return dabRadioMock;
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualRadio.h b/broadcastradio/aidl/default/VirtualRadio.h
new file mode 100644
index 0000000..ae039c4
--- /dev/null
+++ b/broadcastradio/aidl/default/VirtualRadio.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "VirtualProgram.h"
+
+#include <vector>
+
+namespace aidl::android::hardware::broadcastradio {
+
+/**
+ * A radio frequency space mock.
+ *
+ * This represents all broadcast waves in the air for a given radio technology,
+ * not a captured station list in the radio tuner memory.
+ *
+ * It's meant to abstract out radio content from default tuner implementation.
+ */
+class VirtualRadio final {
+ public:
+ VirtualRadio(const std::string& name, const std::vector<VirtualProgram>& initialList);
+ std::string getName() const;
+ const std::vector<VirtualProgram>& getProgramList() const;
+ bool getProgram(const ProgramSelector& selector, VirtualProgram* program) const;
+
+ static const VirtualRadio& getAmFmRadio();
+ static const VirtualRadio& getDabRadio();
+
+ private:
+ const std::string mName;
+ std::vector<VirtualProgram> mPrograms;
+};
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/broadcastradio-default.rc b/broadcastradio/aidl/default/broadcastradio-default.rc
new file mode 100644
index 0000000..49389e6
--- /dev/null
+++ b/broadcastradio/aidl/default/broadcastradio-default.rc
@@ -0,0 +1,6 @@
+service vendor.broadcastradio-default /vendor/bin/hw/android.hardware.broadcastradio-service.default
+ interface aidl android.hardware.broadcastradio.IBroadcastRadio/amfm
+ interface aidl android.hardware.broadcastradio.IBroadcastRadio/dab
+ class hal
+ user audioserver
+ group audio
diff --git a/broadcastradio/aidl/default/broadcastradio-default.xml b/broadcastradio/aidl/default/broadcastradio-default.xml
new file mode 100644
index 0000000..1555822
--- /dev/null
+++ b/broadcastradio/aidl/default/broadcastradio-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.broadcastradio</name>
+ <fqname>IBroadcastRadio/amfm</fqname>
+ <fqname>IBroadcastRadio/dab</fqname>
+ </hal>
+</manifest>
diff --git a/broadcastradio/aidl/default/main.cpp b/broadcastradio/aidl/default/main.cpp
new file mode 100644
index 0000000..6bf20d5
--- /dev/null
+++ b/broadcastradio/aidl/default/main.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BroadcastRadio.h"
+#include "VirtualRadio.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::aidl::android::hardware::broadcastradio::BroadcastRadio;
+using ::aidl::android::hardware::broadcastradio::VirtualRadio;
+
+int main() {
+ android::base::SetDefaultTag("BcRadioAidlDef");
+ ABinderProcess_setThreadPoolMaxThreadCount(4);
+ ABinderProcess_startThreadPool();
+
+ const VirtualRadio& amFmRadioMock = VirtualRadio::getAmFmRadio();
+ std::shared_ptr<BroadcastRadio> broadcastRadio =
+ ::ndk::SharedRefBase::make<BroadcastRadio>(amFmRadioMock);
+ const std::string instanceAmFm = std::string() + BroadcastRadio::descriptor + "/amfm";
+ binder_status_t statusAmFm =
+ AServiceManager_addService(broadcastRadio->asBinder().get(), instanceAmFm.c_str());
+ CHECK_EQ(statusAmFm, STATUS_OK)
+ << "Failed to register Broadcast Radio AM/FM HAL implementation";
+
+ const VirtualRadio& dabRadioMock = VirtualRadio::getDabRadio();
+ std::shared_ptr<BroadcastRadio> dabRadio =
+ ::ndk::SharedRefBase::make<BroadcastRadio>(dabRadioMock);
+ const std::string instanceDab = std::string() + BroadcastRadio::descriptor + "/dab";
+ binder_status_t statusDab =
+ AServiceManager_addService(dabRadio->asBinder().get(), instanceDab.c_str());
+ CHECK_EQ(statusDab, STATUS_OK) << "Failed to register Broadcast Radio DAB HAL implementation";
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/broadcastradio/aidl/default/resources.h b/broadcastradio/aidl/default/resources.h
new file mode 100644
index 0000000..beffc76
--- /dev/null
+++ b/broadcastradio/aidl/default/resources.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+
+namespace aidl::android::hardware::broadcastradio::resources {
+
+constexpr int32_t kDemoPngId = 123456;
+constexpr uint8_t kDemoPng[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44,
+ 0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25,
+ 0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x5d, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0xd9,
+ 0xc1, 0x09, 0x00, 0x30, 0x08, 0x04, 0xc1, 0x33, 0xfd, 0xf7, 0x6c, 0x6a, 0xc8, 0x23, 0x04,
+ 0xc9, 0x6c, 0x01, 0xc2, 0x20, 0xbe, 0x4c, 0x86, 0x57, 0x49, 0xba, 0xfb, 0xd6, 0xf4, 0xba,
+ 0x3e, 0x7f, 0x4d, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8f, 0x00, 0xbd, 0xce, 0x7f,
+ 0xc0, 0x11, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xb8, 0x0d, 0x32, 0xd4, 0x0c, 0x77, 0xbd,
+ 0xfb, 0xc1, 0xce, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82};
+
+} // namespace aidl::android::hardware::broadcastradio::resources
diff --git a/broadcastradio/aidl/vts/Android.bp b/broadcastradio/aidl/vts/Android.bp
new file mode 100644
index 0000000..b60387e
--- /dev/null
+++ b/broadcastradio/aidl/vts/Android.bp
@@ -0,0 +1,47 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBroadcastradioAidlTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ tidy_timeout_srcs: ["src/*.cpp"],
+ srcs: ["src/*.cpp"],
+ shared_libs: [
+ "libbinder_ndk",
+ "libbase",
+ "libxml2",
+ ],
+ static_libs: [
+ "android.hardware.broadcastradio-V1-ndk",
+ "android.hardware.broadcastradio@common-utils-aidl-lib",
+ "android.hardware.broadcastradio@vts-utils-lib",
+ "libgmock",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/broadcastradio/aidl/vts/OWNERS b/broadcastradio/aidl/vts/OWNERS
new file mode 100644
index 0000000..302fdd7
--- /dev/null
+++ b/broadcastradio/aidl/vts/OWNERS
@@ -0,0 +1,4 @@
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
new file mode 100644
index 0000000..356673f
--- /dev/null
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -0,0 +1,1141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define EGMOCK_VERBOSE 1
+
+#include <aidl/android/hardware/broadcastradio/BnAnnouncementListener.h>
+#include <aidl/android/hardware/broadcastradio/BnTunerCallback.h>
+#include <aidl/android/hardware/broadcastradio/ConfigFlag.h>
+#include <aidl/android/hardware/broadcastradio/IBroadcastRadio.h>
+#include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+#include <aidl/android/hardware/broadcastradio/VendorKeyValue.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <broadcastradio-utils-aidl/Utils.h>
+#include <broadcastradio-vts-utils/mock-timeout.h>
+#include <cutils/bitops.h>
+#include <gmock/gmock.h>
+
+#include <chrono>
+#include <optional>
+#include <regex>
+
+namespace aidl::android::hardware::broadcastradio::vts {
+
+namespace {
+
+using ::aidl::android::hardware::broadcastradio::utils::makeIdentifier;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorAmfm;
+using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
+using ::aidl::android::hardware::broadcastradio::utils::resultToInt;
+using ::ndk::ScopedAStatus;
+using ::ndk::SharedRefBase;
+using ::std::string;
+using ::std::vector;
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::ByMove;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::SaveArg;
+
+namespace bcutils = ::aidl::android::hardware::broadcastradio::utils;
+
+inline constexpr std::chrono::seconds kTuneTimeoutSec =
+ std::chrono::seconds(IBroadcastRadio::TUNER_TIMEOUT_MS * 1000);
+inline constexpr std::chrono::seconds kProgramListScanTimeoutSec =
+ std::chrono::seconds(IBroadcastRadio::LIST_COMPLETE_TIMEOUT_MS * 1000);
+
+const ConfigFlag kConfigFlagValues[] = {
+ ConfigFlag::FORCE_MONO,
+ ConfigFlag::FORCE_ANALOG,
+ ConfigFlag::FORCE_DIGITAL,
+ ConfigFlag::RDS_AF,
+ ConfigFlag::RDS_REG,
+ ConfigFlag::DAB_DAB_LINKING,
+ ConfigFlag::DAB_FM_LINKING,
+ ConfigFlag::DAB_DAB_SOFT_LINKING,
+ ConfigFlag::DAB_FM_SOFT_LINKING,
+};
+
+void printSkipped(const string& msg) {
+ const auto testInfo = testing::UnitTest::GetInstance()->current_test_info();
+ LOG(INFO) << "[ SKIPPED ] " << testInfo->test_case_name() << "." << testInfo->name()
+ << " with message: " << msg;
+}
+
+bool isValidAmFmFreq(int64_t freq) {
+ ProgramIdentifier id = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq);
+ return bcutils::isValid(id);
+}
+
+void validateRange(const AmFmBandRange& range) {
+ EXPECT_TRUE(isValidAmFmFreq(range.lowerBound));
+ EXPECT_TRUE(isValidAmFmFreq(range.upperBound));
+ EXPECT_LT(range.lowerBound, range.upperBound);
+ EXPECT_GT(range.spacing, 0u);
+ EXPECT_EQ((range.upperBound - range.lowerBound) % range.spacing, 0u);
+}
+
+bool supportsFM(const AmFmRegionConfig& config) {
+ for (const auto& range : config.ranges) {
+ if (bcutils::getBand(range.lowerBound) == bcutils::FrequencyBand::FM) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+class TunerCallbackMock : public BnTunerCallback {
+ public:
+ TunerCallbackMock();
+ ScopedAStatus onTuneFailed(Result result, const ProgramSelector& selector) override;
+ MOCK_TIMEOUT_METHOD1(onCurrentProgramInfoChangedMock, ScopedAStatus(const ProgramInfo&));
+ ScopedAStatus onCurrentProgramInfoChanged(const ProgramInfo& info) override;
+ ScopedAStatus onProgramListUpdated(const ProgramListChunk& chunk) override;
+ MOCK_METHOD1(onAntennaStateChange, ScopedAStatus(bool connected));
+ MOCK_METHOD1(onParametersUpdated, ScopedAStatus(const vector<VendorKeyValue>& parameters));
+ MOCK_METHOD2(onConfigFlagUpdated, ScopedAStatus(ConfigFlag in_flag, bool in_value));
+ MOCK_TIMEOUT_METHOD0(onProgramListReady, void());
+
+ std::mutex mLock;
+ bcutils::ProgramInfoSet mProgramList GUARDED_BY(mLock);
+};
+
+struct AnnouncementListenerMock : public BnAnnouncementListener {
+ MOCK_METHOD1(onListUpdated, ScopedAStatus(const vector<Announcement>&));
+};
+
+class BroadcastRadioHalTest : public testing::TestWithParam<string> {
+ protected:
+ void SetUp() override;
+ void TearDown() override;
+
+ bool getAmFmRegionConfig(bool full, AmFmRegionConfig* config);
+ std::optional<bcutils::ProgramInfoSet> getProgramList();
+ std::optional<bcutils::ProgramInfoSet> getProgramList(const ProgramFilter& filter);
+
+ std::shared_ptr<IBroadcastRadio> mModule;
+ Properties mProperties;
+ std::shared_ptr<TunerCallbackMock> mCallback = SharedRefBase::make<TunerCallbackMock>();
+};
+
+MATCHER_P(InfoHasId, id, string(negation ? "does not contain" : "contains") + " " + id.toString()) {
+ vector<int> ids = bcutils::getAllIds(arg.selector, id.type);
+ return ids.end() != find(ids.begin(), ids.end(), id.value);
+}
+
+TunerCallbackMock::TunerCallbackMock() {
+ EXPECT_TIMEOUT_CALL(*this, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+
+ // we expect the antenna is connected through the whole test
+ EXPECT_CALL(*this, onAntennaStateChange(false)).Times(0);
+}
+
+ScopedAStatus TunerCallbackMock::onTuneFailed(Result result, const ProgramSelector& selector) {
+ LOG(DEBUG) << "Tune failed for selector" << selector.toString();
+ EXPECT_TRUE(result == Result::CANCELED);
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus TunerCallbackMock::onCurrentProgramInfoChanged(const ProgramInfo& info) {
+ for (const auto& id : info.selector) {
+ EXPECT_NE(id.type, IdentifierType::INVALID);
+ }
+
+ IdentifierType logically = info.logicallyTunedTo.type;
+ // This field is required for currently tuned program and should be INVALID
+ // for entries from the program list.
+ EXPECT_TRUE(logically == IdentifierType::AMFM_FREQUENCY_KHZ ||
+ logically == IdentifierType::RDS_PI ||
+ logically == IdentifierType::HD_STATION_ID_EXT ||
+ logically == IdentifierType::DAB_SID_EXT ||
+ logically == IdentifierType::DRMO_SERVICE_ID ||
+ logically == IdentifierType::SXM_SERVICE_ID ||
+ (logically >= IdentifierType::VENDOR_START &&
+ logically <= IdentifierType::VENDOR_END) ||
+ logically > IdentifierType::SXM_CHANNEL);
+
+ IdentifierType physically = info.physicallyTunedTo.type;
+ // ditto (see "logically" above)
+ EXPECT_TRUE(physically == IdentifierType::AMFM_FREQUENCY_KHZ ||
+ physically == IdentifierType::DAB_FREQUENCY_KHZ ||
+ physically == IdentifierType::DRMO_FREQUENCY_KHZ ||
+ physically == IdentifierType::SXM_CHANNEL ||
+ (physically >= IdentifierType::VENDOR_START &&
+ physically <= IdentifierType::VENDOR_END) ||
+ physically > IdentifierType::SXM_CHANNEL);
+
+ if (logically == IdentifierType::AMFM_FREQUENCY_KHZ) {
+ std::optional<string> ps = bcutils::getMetadataString(info, Metadata::rdsPs);
+ if (ps.has_value()) {
+ EXPECT_NE(::android::base::Trim(*ps), "")
+ << "Don't use empty RDS_PS as an indicator of missing RSD PS data.";
+ }
+ }
+
+ return onCurrentProgramInfoChangedMock(info);
+}
+
+ScopedAStatus TunerCallbackMock::onProgramListUpdated(const ProgramListChunk& chunk) {
+ std::lock_guard<std::mutex> lk(mLock);
+
+ updateProgramList(chunk, &mProgramList);
+
+ if (chunk.complete) {
+ onProgramListReady();
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+void BroadcastRadioHalTest::SetUp() {
+ EXPECT_EQ(mModule.get(), nullptr) << "Module is already open";
+
+ // lookup AIDL service (radio module)
+ AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+ ASSERT_NE(binder, nullptr);
+ mModule = IBroadcastRadio::fromBinder(ndk::SpAIBinder(binder));
+ ASSERT_NE(mModule, nullptr) << "Couldn't find broadcast radio HAL implementation";
+
+ // get module properties
+ auto propResult = mModule->getProperties(&mProperties);
+
+ ASSERT_TRUE(propResult.isOk());
+ EXPECT_FALSE(mProperties.maker.empty());
+ EXPECT_FALSE(mProperties.product.empty());
+ EXPECT_GT(mProperties.supportedIdentifierTypes.size(), 0u);
+
+ // set callback
+ EXPECT_TRUE(mModule->setTunerCallback(mCallback).isOk());
+}
+
+void BroadcastRadioHalTest::TearDown() {
+ if (mModule) {
+ ASSERT_TRUE(mModule->unsetTunerCallback().isOk());
+ }
+}
+
+bool BroadcastRadioHalTest::getAmFmRegionConfig(bool full, AmFmRegionConfig* config) {
+ auto halResult = mModule->getAmFmRegionConfig(full, config);
+
+ if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ return false;
+ }
+
+ EXPECT_TRUE(halResult.isOk());
+ return halResult.isOk();
+}
+
+std::optional<bcutils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList() {
+ ProgramFilter emptyFilter = {};
+ return getProgramList(emptyFilter);
+}
+
+std::optional<bcutils::ProgramInfoSet> BroadcastRadioHalTest::getProgramList(
+ const ProgramFilter& filter) {
+ EXPECT_TIMEOUT_CALL(*mCallback, onProgramListReady).Times(AnyNumber());
+
+ auto startResult = mModule->startProgramListUpdates(filter);
+
+ if (startResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ printSkipped("Program list not supported");
+ return std::nullopt;
+ }
+ EXPECT_TRUE(startResult.isOk());
+ if (!startResult.isOk()) {
+ return std::nullopt;
+ }
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onProgramListReady, kProgramListScanTimeoutSec);
+
+ auto stopResult = mModule->stopProgramListUpdates();
+
+ EXPECT_TRUE(stopResult.isOk());
+
+ return mCallback->mProgramList;
+}
+
+/**
+ * Test setting tuner callback to null.
+ *
+ * Verifies that:
+ * - Setting to a null tuner callback results with INVALID_ARGUMENTS.
+ */
+TEST_P(BroadcastRadioHalTest, TunerCallbackFailsWithNull) {
+ LOG(DEBUG) << "TunerCallbackFailsWithNull Test";
+
+ auto halResult = mModule->setTunerCallback(nullptr);
+
+ EXPECT_EQ(halResult.getServiceSpecificError(), resultToInt(Result::INVALID_ARGUMENTS));
+}
+
+/**
+ * Test fetching AM/FM regional configuration.
+ *
+ * Verifies that:
+ * - AM/FM regional configuration is either set at startup or not supported at all by the hardware;
+ * - FM Deemphasis and RDS are correctly configured for FM-capable radio;
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfig) {
+ LOG(DEBUG) << "GetAmFmRegionConfig Test";
+
+ AmFmRegionConfig config;
+
+ bool supported = getAmFmRegionConfig(/* full= */ false, &config);
+
+ if (!supported) {
+ printSkipped("AM/FM not supported");
+ return;
+ }
+
+ EXPECT_LE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
+ EXPECT_LE(popcountll(static_cast<unsigned long long>(config.fmRds)), 1);
+
+ if (supportsFM(config)) {
+ EXPECT_EQ(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
+ }
+}
+
+/**
+ * Test fetching ranges of AM/FM regional configuration.
+ *
+ * Verifies that:
+ * - AM/FM regional configuration is either set at startup or not supported at all by the hardware;
+ * - there is at least one AM/FM band configured;
+ * - all channel grids (frequency ranges and spacings) are valid;
+ * - seek spacing is a multiple of the manual spacing value.
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigRanges) {
+ LOG(DEBUG) << "GetAmFmRegionConfigRanges Test";
+
+ AmFmRegionConfig config;
+
+ bool supported = getAmFmRegionConfig(/* full= */ false, &config);
+
+ if (!supported) {
+ printSkipped("AM/FM not supported");
+ return;
+ }
+
+ EXPECT_GT(config.ranges.size(), 0u);
+ for (const auto& range : config.ranges) {
+ validateRange(range);
+ EXPECT_EQ(range.seekSpacing % range.spacing, 0u);
+ EXPECT_GE(range.seekSpacing, range.spacing);
+ }
+}
+
+/**
+ * Test fetching FM regional capabilities.
+ *
+ * Verifies that:
+ * - AM/FM regional capabilities are either available or not supported at all by the hardware;
+ * - there is at least one de-emphasis filter mode supported for FM-capable radio;
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigCapabilitiesForFM) {
+ LOG(DEBUG) << "GetAmFmRegionConfigCapabilitiesForFM Test";
+
+ AmFmRegionConfig config;
+
+ bool supported = getAmFmRegionConfig(/* full= */ true, &config);
+
+ if (supported && supportsFM(config)) {
+ EXPECT_GE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
+ } else {
+ printSkipped("FM not supported");
+ }
+}
+
+/**
+ * Test fetching the ranges of AM/FM regional capabilities.
+ *
+ * Verifies that:
+ * - AM/FM regional capabilities are either available or not supported at all by the hardware;
+ * - there is at least one AM/FM range supported;
+ * - all channel grids (frequency ranges and spacings) are valid;
+ * - seek spacing is not set.
+ */
+TEST_P(BroadcastRadioHalTest, GetAmFmRegionConfigCapabilitiesRanges) {
+ LOG(DEBUG) << "GetAmFmRegionConfigCapabilitiesRanges Test";
+
+ AmFmRegionConfig config;
+
+ bool supported = getAmFmRegionConfig(/* full= */ true, &config);
+
+ if (!supported) {
+ printSkipped("AM/FM not supported");
+ return;
+ }
+
+ EXPECT_GT(config.ranges.size(), 0u);
+
+ for (const auto& range : config.ranges) {
+ validateRange(range);
+ EXPECT_EQ(range.seekSpacing, 0u);
+ }
+}
+
+/**
+ * Test fetching DAB regional configuration.
+ *
+ * Verifies that:
+ * - DAB regional configuration is either set at startup or not supported at all by the hardware;
+ * - all channel labels match correct format;
+ * - all channel frequencies are in correct range.
+ */
+TEST_P(BroadcastRadioHalTest, GetDabRegionConfig) {
+ LOG(DEBUG) << "GetDabRegionConfig Test";
+ vector<DabTableEntry> config;
+
+ auto halResult = mModule->getDabRegionConfig(&config);
+
+ if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ printSkipped("DAB not supported");
+ return;
+ }
+ ASSERT_TRUE(halResult.isOk());
+
+ std::regex re("^[A-Z0-9][A-Z0-9 ]{0,5}[A-Z0-9]$");
+
+ for (const auto& entry : config) {
+ EXPECT_TRUE(std::regex_match(string(entry.label), re));
+
+ ProgramIdentifier id =
+ bcutils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, entry.frequencyKhz);
+ EXPECT_TRUE(bcutils::isValid(id));
+ }
+}
+
+/**
+ * Test tuning without tuner callback set.
+ *
+ * Verifies that:
+ * - No tuner callback set results in INVALID_STATE, regardless of whether the selector is
+ * supported.
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithoutTunerCallback) {
+ LOG(DEBUG) << "TuneFailsWithoutTunerCallback Test";
+
+ mModule->unsetTunerCallback();
+ int64_t freq = 90900; // 90.9 FM
+ ProgramSelector sel = makeSelectorAmfm(freq);
+
+ auto result = mModule->tune(sel);
+
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+}
+
+/**
+ * Test tuning with selectors that can be not supported.
+ *
+ * Verifies that:
+ * - if the selector is not supported, an invalid value results with NOT_SUPPORTED, regardless of
+ * whether it is valid;
+ * - if it is supported, the test is ignored;
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithNotSupported) {
+ LOG(DEBUG) << "TuneFailsWithInvalid Test";
+
+ vector<ProgramIdentifier> supportTestId = {
+ makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0), // invalid
+ makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 94900), // valid
+ makeIdentifier(IdentifierType::RDS_PI, 0x10000), // invalid
+ makeIdentifier(IdentifierType::RDS_PI, 0x1001), // valid
+ makeIdentifier(IdentifierType::HD_STATION_ID_EXT, 0x100000000), // invalid
+ makeIdentifier(IdentifierType::HD_STATION_ID_EXT, 0x10000001), // valid
+ makeIdentifier(IdentifierType::DAB_SID_EXT, 0), // invalid
+ makeIdentifier(IdentifierType::DAB_SID_EXT, 0xA00001), // valid
+ makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000000), // invalid
+ makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x10000001), // valid
+ makeIdentifier(IdentifierType::SXM_SERVICE_ID, 0x100000000), // invalid
+ makeIdentifier(IdentifierType::SXM_SERVICE_ID, 0x10000001), // valid
+ };
+
+ auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
+ for (const auto& id : supportTestId) {
+ ProgramSelector sel{id, {}};
+
+ auto result = mModule->tune(sel);
+
+ if (!bcutils::isSupported(mProperties, sel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), notSupportedError);
+ }
+ }
+}
+
+/**
+ * Test tuning with invalid selectors.
+ *
+ * Verifies that:
+ * - if the selector is not supported, it's ignored;
+ * - if it is supported, an invalid value results with INVALID_ARGUMENTS;
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithInvalid) {
+ LOG(DEBUG) << "TuneFailsWithInvalid Test";
+
+ vector<ProgramIdentifier> invalidId = {
+ makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 0),
+ makeIdentifier(IdentifierType::RDS_PI, 0x10000),
+ makeIdentifier(IdentifierType::HD_STATION_ID_EXT, 0x100000000),
+ makeIdentifier(IdentifierType::DAB_SID_EXT, 0),
+ makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000000),
+ makeIdentifier(IdentifierType::SXM_SERVICE_ID, 0x100000000),
+ };
+
+ auto invalidArgumentsError = resultToInt(Result::INVALID_ARGUMENTS);
+ for (const auto& id : invalidId) {
+ ProgramSelector sel{id, {}};
+
+ auto result = mModule->tune(sel);
+
+ if (bcutils::isSupported(mProperties, sel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), invalidArgumentsError);
+ }
+ }
+}
+
+/**
+ * Test tuning with empty program selector.
+ *
+ * Verifies that:
+ * - tune fails with NOT_SUPPORTED when program selector is not initialized.
+ */
+TEST_P(BroadcastRadioHalTest, TuneFailsWithEmpty) {
+ LOG(DEBUG) << "TuneFailsWithEmpty Test";
+
+ // Program type is 1-based, so 0 will always be invalid.
+ ProgramSelector sel = {};
+
+ auto result = mModule->tune(sel);
+
+ ASSERT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+}
+
+/**
+ * Test tuning with FM selector.
+ *
+ * Verifies that:
+ * - if AM/FM 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 exactly to what was requested.
+ */
+TEST_P(BroadcastRadioHalTest, FmTune) {
+ LOG(DEBUG) << "FmTune Test";
+
+ int64_t freq = 90900; // 90.9 FM
+ ProgramSelector sel = makeSelectorAmfm(freq);
+ // try tuning
+ ProgramInfo infoCb = {};
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock,
+ InfoHasId(makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq)))
+ .Times(AnyNumber())
+ .WillOnce(DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(ndk::ScopedAStatus::ok()))))
+ .WillRepeatedly(testing::InvokeWithoutArgs([] { return ndk::ScopedAStatus::ok(); }));
+
+ auto result = mModule->tune(sel);
+
+ // expect a failure if it's not supported
+ if (!bcutils::isSupported(mProperties, sel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+ return;
+ }
+
+ // expect a callback if it succeeds
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+
+ LOG(DEBUG) << "Current program info: " << infoCb.toString();
+
+ // it should tune exactly to what was requested
+ vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
+ EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
+ << "FM freq " << freq << " kHz is not sent back by callback.";
+}
+
+/**
+ * Test tuning with DAB selector.
+ *
+ * Verifies that:
+ * - if DAB 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 exactly to what was requested.
+ */
+TEST_P(BroadcastRadioHalTest, DabTune) {
+ LOG(DEBUG) << "DabTune Test";
+ vector<DabTableEntry> config;
+
+ auto halResult = mModule->getDabRegionConfig(&config);
+
+ if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ printSkipped("DAB not supported");
+ return;
+ }
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_NE(config.size(), 0U);
+
+ auto programList = getProgramList();
+
+ if (!programList) {
+ printSkipped("Empty DAB station list, tune cannot be performed");
+ return;
+ }
+
+ ProgramSelector sel = {};
+ uint64_t freq = 0;
+ bool dabStationPresent = false;
+ for (auto&& programInfo : *programList) {
+ if (!utils::hasId(programInfo.selector, IdentifierType::DAB_FREQUENCY_KHZ)) {
+ continue;
+ }
+ for (auto&& config_entry : config) {
+ if (config_entry.frequencyKhz ==
+ utils::getId(programInfo.selector, IdentifierType::DAB_FREQUENCY_KHZ, 0)) {
+ freq = config_entry.frequencyKhz;
+ break;
+ }
+ }
+ // Do not trigger a tune request if the programList entry does not contain
+ // a valid DAB frequency.
+ if (freq == 0) {
+ continue;
+ }
+ int64_t dabSidExt = utils::getId(programInfo.selector, IdentifierType::DAB_SID_EXT, 0);
+ int64_t dabEns = utils::getId(programInfo.selector, IdentifierType::DAB_ENSEMBLE, 0);
+ sel = makeSelectorDab(dabSidExt, (int32_t)dabEns, freq);
+ dabStationPresent = true;
+ break;
+ }
+
+ if (!dabStationPresent) {
+ printSkipped("No DAB stations in the list, tune cannot be performed");
+ return;
+ }
+
+ // try tuning
+ ProgramInfo infoCb = {};
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock,
+ InfoHasId(makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, freq)))
+ .Times(AnyNumber())
+ .WillOnce(
+ DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(ndk::ScopedAStatus::ok()))));
+
+ auto result = mModule->tune(sel);
+
+ // expect a failure if it's not supported
+ if (!bcutils::isSupported(mProperties, sel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+ return;
+ }
+
+ // expect a callback if it succeeds
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+ LOG(DEBUG) << "Current program info: " << infoCb.toString();
+
+ // it should tune exactly to what was requested
+ vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY_KHZ);
+ EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
+ << "DAB freq " << freq << " kHz is not sent back by callback.";
+}
+
+/**
+ * Test seeking to next/prev station via IBroadcastRadio::seek().
+ *
+ * Verifies that:
+ * - the method succeeds;
+ * - the program info is changed within kTuneTimeoutSec;
+ * - works both directions and with or without skipping sub-channel.
+ */
+TEST_P(BroadcastRadioHalTest, Seek) {
+ LOG(DEBUG) << "Seek Test";
+
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+
+ auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
+
+ if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ printSkipped("Seek not supported");
+ return;
+ }
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+
+ result = mModule->seek(/* in_directionUp= */ false, /* in_skipSubChannel= */ false);
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+}
+
+/**
+ * Test seeking without tuner callback set.
+ *
+ * Verifies that:
+ * - No tuner callback set results in INVALID_STATE.
+ */
+TEST_P(BroadcastRadioHalTest, SeekFailsWithoutTunerCallback) {
+ LOG(DEBUG) << "SeekFailsWithoutTunerCallback Test";
+
+ mModule->unsetTunerCallback();
+
+ auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
+
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+
+ result = mModule->seek(/* in_directionUp= */ false, /* in_skipSubChannel= */ false);
+
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+}
+
+/**
+ * Test step operation.
+ *
+ * Verifies that:
+ * - the method succeeds or returns NOT_SUPPORTED;
+ * - the program info is changed within kTuneTimeoutSec if the method succeeded;
+ * - works both directions.
+ */
+TEST_P(BroadcastRadioHalTest, Step) {
+ LOG(DEBUG) << "Step Test";
+
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+
+ auto result = mModule->step(/* in_directionUp= */ true);
+
+ if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ printSkipped("Step not supported");
+ return;
+ }
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChangedMock, _).Times(AnyNumber());
+
+ result = mModule->step(/* in_directionUp= */ false);
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChangedMock, kTuneTimeoutSec);
+}
+
+/**
+ * Test step operation without tuner callback set.
+ *
+ * Verifies that:
+ * - No tuner callback set results in INVALID_STATE.
+ */
+TEST_P(BroadcastRadioHalTest, StepFailsWithoutTunerCallback) {
+ LOG(DEBUG) << "StepFailsWithoutTunerCallback Test";
+
+ mModule->unsetTunerCallback();
+
+ auto result = mModule->step(/* in_directionUp= */ true);
+
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+
+ result = mModule->step(/* in_directionUp= */ false);
+
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::INVALID_STATE));
+}
+
+/**
+ * Test tune cancellation.
+ *
+ * Verifies that:
+ * - the method does not crash after being invoked multiple times.
+ *
+ * Since cancel() might be called after the HAL completes an operation (tune, seek, and step)
+ * and before the callback completions, the operation might not be actually canceled and the
+ * effect of cancel() is not deterministic to be tested here.
+ */
+TEST_P(BroadcastRadioHalTest, Cancel) {
+ LOG(DEBUG) << "Cancel Test";
+
+ auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
+ for (int i = 0; i < 10; i++) {
+ auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
+
+ if (result.getServiceSpecificError() == notSupportedError) {
+ printSkipped("Cancel is skipped because of seek not supported");
+ return;
+ }
+ EXPECT_TRUE(result.isOk());
+
+ auto cancelResult = mModule->cancel();
+
+ ASSERT_TRUE(cancelResult.isOk());
+ }
+}
+
+/**
+ * Test IBroadcastRadio::get|setParameters() methods called with no parameters.
+ *
+ * Verifies that:
+ * - callback is called for empty parameters set.
+ */
+TEST_P(BroadcastRadioHalTest, NoParameters) {
+ LOG(DEBUG) << "NoParameters Test";
+
+ vector<VendorKeyValue> parametersResults = {};
+
+ auto halResult = mModule->setParameters({}, ¶metersResults);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_EQ(parametersResults.size(), 0u);
+
+ parametersResults.clear();
+
+ halResult = mModule->getParameters({}, ¶metersResults);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_EQ(parametersResults.size(), 0u);
+}
+
+/**
+ * Test IBroadcastRadio::get|setParameters() methods called with unknown parameters.
+ *
+ * Verifies that:
+ * - unknown parameters are ignored;
+ * - callback is called also for empty results set.
+ */
+TEST_P(BroadcastRadioHalTest, UnknownParameters) {
+ LOG(DEBUG) << "UnknownParameters Test";
+
+ vector<VendorKeyValue> parametersResults = {};
+
+ auto halResult =
+ mModule->setParameters({{"com.android.unknown", "sample"}}, ¶metersResults);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_EQ(parametersResults.size(), 0u);
+
+ parametersResults.clear();
+
+ halResult = mModule->getParameters({"com.android.unknown*", "sample"}, ¶metersResults);
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_EQ(parametersResults.size(), 0u);
+}
+
+/**
+ * Test geting image of invalid ID.
+ *
+ * Verifies that:
+ * - getImage call handles argument 0 gracefully.
+ */
+TEST_P(BroadcastRadioHalTest, GetNoImage) {
+ LOG(DEBUG) << "GetNoImage Test";
+ vector<uint8_t> rawImage;
+
+ auto result = mModule->getImage(IBroadcastRadio::INVALID_IMAGE, &rawImage);
+
+ ASSERT_TRUE(result.isOk());
+ ASSERT_EQ(rawImage.size(), 0u);
+}
+
+/**
+ * Test getting config flags.
+ *
+ * Verifies that:
+ * - isConfigFlagSet either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
+ * - call success or failure is consistent with setConfigFlag.
+ */
+TEST_P(BroadcastRadioHalTest, FetchConfigFlags) {
+ LOG(DEBUG) << "FetchConfigFlags Test";
+
+ for (const auto& flag : kConfigFlagValues) {
+ bool gotValue = false;
+
+ auto halResult = mModule->isConfigFlagSet(flag, &gotValue);
+
+ if (halResult.getServiceSpecificError() != resultToInt(Result::NOT_SUPPORTED) &&
+ halResult.getServiceSpecificError() != resultToInt(Result::INVALID_STATE)) {
+ ASSERT_TRUE(halResult.isOk());
+ }
+
+ // set must fail or succeed the same way as get
+ auto setResult = mModule->setConfigFlag(flag, /* value= */ false);
+
+ EXPECT_TRUE((halResult.isOk() && setResult.isOk()) ||
+ (halResult.getServiceSpecificError()) == setResult.getServiceSpecificError());
+
+ setResult = mModule->setConfigFlag(flag, /* value= */ true);
+
+ EXPECT_TRUE((halResult.isOk() && setResult.isOk()) ||
+ (halResult.getServiceSpecificError()) == setResult.getServiceSpecificError());
+ }
+}
+
+/**
+ * Test setting config flags.
+ *
+ * Verifies that:
+ * - setConfigFlag either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
+ * - isConfigFlagSet reflects the state requested immediately after the set call.
+ */
+TEST_P(BroadcastRadioHalTest, SetConfigFlags) {
+ LOG(DEBUG) << "SetConfigFlags Test";
+
+ auto get = [&](ConfigFlag flag) -> bool {
+ bool* gotValue = nullptr;
+
+ auto halResult = mModule->isConfigFlagSet(flag, gotValue);
+
+ EXPECT_FALSE(gotValue == nullptr);
+ EXPECT_TRUE(halResult.isOk());
+ return *gotValue;
+ };
+
+ auto notSupportedError = resultToInt(Result::NOT_SUPPORTED);
+ auto invalidStateError = resultToInt(Result::INVALID_STATE);
+ for (const auto& flag : kConfigFlagValues) {
+ auto result = mModule->setConfigFlag(flag, /* value= */ false);
+
+ if (result.getServiceSpecificError() == notSupportedError ||
+ result.getServiceSpecificError() == invalidStateError) {
+ // setting to true must result in the same error as false
+ auto secondResult = mModule->setConfigFlag(flag, /* value= */ true);
+
+ EXPECT_TRUE((result.isOk() && secondResult.isOk()) ||
+ result.getServiceSpecificError() == secondResult.getServiceSpecificError());
+ continue;
+ } else {
+ ASSERT_TRUE(result.isOk());
+ }
+
+ // verify false is set
+ bool value = get(flag);
+ EXPECT_FALSE(value);
+
+ // try setting true this time
+ result = mModule->setConfigFlag(flag, /* value= */ true);
+
+ ASSERT_TRUE(result.isOk());
+ value = get(flag);
+ EXPECT_TRUE(value);
+
+ // false again
+ result = mModule->setConfigFlag(flag, /* value= */ false);
+
+ ASSERT_TRUE(result.isOk());
+ value = get(flag);
+ EXPECT_FALSE(value);
+ }
+}
+
+/**
+ * Test getting program list using empty program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within kProgramListScanTimeoutSec;
+ * - stopProgramListUpdates does not crash.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
+ LOG(DEBUG) << "GetProgramListFromEmptyFilter Test";
+
+ getProgramList();
+}
+
+/**
+ * Test getting program list using AMFM frequency program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within kProgramListScanTimeoutSec;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with AMFM_FREQUENCY_KHZ value of the first
+ * AMFM program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromAmFmFilter) {
+ LOG(DEBUG) << "GetProgramListFromAmFmFilter Test";
+
+ std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
+ if (!completeList) {
+ printSkipped("No program list available");
+ return;
+ }
+
+ ProgramFilter amfmFilter = {};
+ int expectedResultSize = 0;
+ uint64_t expectedFreq = 0;
+ for (const auto& program : *completeList) {
+ vector<int> amfmIds =
+ bcutils::getAllIds(program.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
+ EXPECT_LE(amfmIds.size(), 1u);
+ if (amfmIds.size() == 0) {
+ continue;
+ }
+
+ if (expectedResultSize == 0) {
+ expectedFreq = amfmIds[0];
+ amfmFilter.identifiers = {
+ makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, expectedFreq)};
+ expectedResultSize = 1;
+ } else if (amfmIds[0] == expectedFreq) {
+ expectedResultSize++;
+ }
+ }
+
+ if (expectedResultSize == 0) {
+ printSkipped("No Am/FM programs available");
+ return;
+ }
+ std::optional<bcutils::ProgramInfoSet> amfmList = getProgramList(amfmFilter);
+ ASSERT_EQ(amfmList->size(), expectedResultSize) << "amfm filter result size is wrong";
+}
+
+/**
+ * Test getting program list using DAB ensemble program filter.
+ *
+ * Verifies that:
+ * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
+ * - the complete list is fetched within kProgramListScanTimeoutSec;
+ * - stopProgramListUpdates does not crash;
+ * - result for startProgramListUpdates using a filter with DAB_ENSEMBLE value of the first DAB
+ * program matches the expected result.
+ */
+TEST_P(BroadcastRadioHalTest, GetProgramListFromDabFilter) {
+ LOG(DEBUG) << "GetProgramListFromDabFilter Test";
+
+ std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
+ if (!completeList) {
+ printSkipped("No program list available");
+ return;
+ }
+
+ ProgramFilter dabFilter = {};
+ int expectedResultSize = 0;
+ uint64_t expectedEnsemble = 0;
+ for (const auto& program : *completeList) {
+ auto dabEnsembles = bcutils::getAllIds(program.selector, IdentifierType::DAB_ENSEMBLE);
+ EXPECT_LE(dabEnsembles.size(), 1u);
+ if (dabEnsembles.size() == 0) {
+ continue;
+ }
+
+ if (expectedResultSize == 0) {
+ expectedEnsemble = dabEnsembles[0];
+ dabFilter.identifiers = {
+ makeIdentifier(IdentifierType::DAB_ENSEMBLE, expectedEnsemble)};
+ expectedResultSize = 1;
+ } else if (dabEnsembles[0] == expectedEnsemble) {
+ expectedResultSize++;
+ }
+ }
+
+ if (expectedResultSize == 0) {
+ printSkipped("No DAB programs available");
+ return;
+ }
+ std::optional<bcutils::ProgramInfoSet> dabList = getProgramList(dabFilter);
+ ASSERT_EQ(dabList->size(), expectedResultSize) << "dab filter result size is wrong";
+}
+
+/**
+ * Test HD_STATION_NAME correctness.
+ *
+ * Verifies that if a program on the list contains HD_STATION_NAME identifier:
+ * - the program provides station name in its metadata;
+ * - the identifier matches the name;
+ * - there is only one identifier of that type.
+ */
+TEST_P(BroadcastRadioHalTest, HdRadioStationNameId) {
+ LOG(DEBUG) << "HdRadioStationNameId Test";
+
+ std::optional<bcutils::ProgramInfoSet> list = getProgramList();
+ if (!list) {
+ printSkipped("No program list");
+ return;
+ }
+
+ for (const auto& program : *list) {
+ vector<int> nameIds = bcutils::getAllIds(program.selector, IdentifierType::HD_STATION_NAME);
+ EXPECT_LE(nameIds.size(), 1u);
+ if (nameIds.size() == 0) {
+ continue;
+ }
+
+ std::optional<string> name = bcutils::getMetadataString(program, Metadata::programName);
+ if (!name) {
+ name = bcutils::getMetadataString(program, Metadata::rdsPs);
+ }
+ ASSERT_TRUE(name.has_value());
+
+ ProgramIdentifier expectedId = bcutils::makeHdRadioStationName(*name);
+ EXPECT_EQ(nameIds[0], expectedId.value);
+ }
+}
+
+/**
+ * Test announcement listener registration.
+ *
+ * Verifies that:
+ * - registerAnnouncementListener either succeeds or returns NOT_SUPPORTED;
+ * - if it succeeds, it returns a valid close handle (which is a nullptr otherwise);
+ * - closing handle does not crash.
+ */
+TEST_P(BroadcastRadioHalTest, AnnouncementListenerRegistration) {
+ LOG(DEBUG) << "AnnouncementListenerRegistration Test";
+ std::shared_ptr<AnnouncementListenerMock> listener =
+ SharedRefBase::make<AnnouncementListenerMock>();
+ std::shared_ptr<ICloseHandle> closeHandle = nullptr;
+
+ auto halResult = mModule->registerAnnouncementListener(listener, {AnnouncementType::EMERGENCY},
+ &closeHandle);
+
+ if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
+ ASSERT_EQ(closeHandle.get(), nullptr);
+ printSkipped("Announcements not supported");
+ return;
+ }
+
+ ASSERT_TRUE(halResult.isOk());
+ ASSERT_NE(closeHandle.get(), nullptr);
+
+ closeHandle->close();
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BroadcastRadioHalTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, BroadcastRadioHalTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IBroadcastRadio::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+} // namespace aidl::android::hardware::broadcastradio::vts
+
+int main(int argc, char** argv) {
+ android::base::SetDefaultTag("BcRadio.vts");
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(4);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/broadcastradio/common/utils/WorkerThread.cpp b/broadcastradio/common/utils/WorkerThread.cpp
index 31f4d3f..43fd04a 100644
--- a/broadcastradio/common/utils/WorkerThread.cpp
+++ b/broadcastradio/common/utils/WorkerThread.cpp
@@ -18,20 +18,23 @@
namespace android {
-using std::chrono::milliseconds;
-using std::chrono::steady_clock;
using std::function;
using std::lock_guard;
using std::mutex;
-using std::priority_queue;
-using std::this_thread::sleep_for;
using std::unique_lock;
+using std::chrono::milliseconds;
+using std::chrono::steady_clock;
+using std::this_thread::sleep_for;
bool operator<(const WorkerThread::Task& lhs, const WorkerThread::Task& rhs) {
return lhs.when > rhs.when;
}
-WorkerThread::WorkerThread() : mIsTerminating(false), mThread(&WorkerThread::threadLoop, this) {}
+WorkerThread::WorkerThread() : mIsTerminating(false) {
+ // putting mThread in constructor instead of initializer list
+ // to ensure all class members are init before mThread starts
+ mThread = std::thread(&WorkerThread::threadLoop, this);
+}
WorkerThread::~WorkerThread() {
{
@@ -43,16 +46,26 @@
}
void WorkerThread::schedule(function<void()> task, milliseconds delay) {
+ auto cancelTask = []() {};
+ schedule(std::move(task), cancelTask, delay);
+}
+
+void WorkerThread::schedule(function<void()> task, function<void()> cancelTask,
+ milliseconds delay) {
auto when = steady_clock::now() + delay;
lock_guard<mutex> lk(mMut);
- mTasks.push(Task({when, task}));
+ mTasks.push(Task({when, std::move(task), std::move(cancelTask)}));
mCond.notify_one();
}
void WorkerThread::cancelAll() {
lock_guard<mutex> lk(mMut);
- priority_queue<Task>().swap(mTasks); // empty queue
+ while (!mTasks.empty()) {
+ auto task = mTasks.top();
+ task.onCanceled();
+ mTasks.pop();
+ }
}
void WorkerThread::threadLoop() {
diff --git a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
index 62bede6..457b57e 100644
--- a/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
+++ b/broadcastradio/common/utils/include/broadcastradio-utils/WorkerThread.h
@@ -28,12 +28,15 @@
virtual ~WorkerThread();
void schedule(std::function<void()> task, std::chrono::milliseconds delay);
+ void schedule(std::function<void()> task, std::function<void()> cancelTask,
+ std::chrono::milliseconds delay);
void cancelAll();
private:
struct Task {
std::chrono::time_point<std::chrono::steady_clock> when;
std::function<void()> what;
+ std::function<void()> onCanceled;
};
friend bool operator<(const Task& lhs, const Task& rhs);
diff --git a/broadcastradio/common/utilsaidl/Android.bp b/broadcastradio/common/utilsaidl/Android.bp
new file mode 100644
index 0000000..fa6de19
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/Android.bp
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+ name: "android.hardware.broadcastradio@common-utils-aidl-lib",
+ vendor_available: true,
+ relative_install_path: "hw",
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wno-error=implicit-fallthrough",
+ ],
+ cppflags: [
+ "-std=c++1z",
+ ],
+ srcs: [
+ "Utils.cpp",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "android.hardware.broadcastradio-V1-ndk",
+ "libbase",
+ ],
+ static_libs: [
+ "libmath",
+ ],
+}
diff --git a/broadcastradio/common/utilsaidl/Utils.cpp b/broadcastradio/common/utilsaidl/Utils.cpp
new file mode 100644
index 0000000..0551bad
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/Utils.cpp
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BcRadioAidlDef.utils"
+
+#include "broadcastradio-utils-aidl/Utils.h"
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+#include <math/HashCombine.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace utils {
+
+namespace {
+
+using ::android::base::EqualsIgnoreCase;
+using ::std::string;
+using ::std::vector;
+
+const int64_t kValueForNotFoundIdentifier = 0;
+
+bool bothHaveId(const ProgramSelector& a, const ProgramSelector& b, const IdentifierType& type) {
+ return hasId(a, type) && hasId(b, type);
+}
+
+bool haveEqualIds(const ProgramSelector& a, const ProgramSelector& b, const IdentifierType& type) {
+ if (!bothHaveId(a, b, type)) {
+ return false;
+ }
+ /* We should check all Ids of a given type (ie. other AF),
+ * but it doesn't matter for default implementation.
+ */
+ return getId(a, type) == getId(b, type);
+}
+
+int getHdSubchannel(const ProgramSelector& sel) {
+ int64_t hdSidExt = getId(sel, IdentifierType::HD_STATION_ID_EXT, /* defaultValue */ 0);
+ hdSidExt >>= 32; // Station ID number
+ return hdSidExt & 0xF; // HD Radio subchannel
+}
+
+bool maybeGetId(const ProgramSelector& sel, const IdentifierType& type, int64_t* val) {
+ // iterate through primaryId and secondaryIds
+ for (auto it = begin(sel); it != end(sel); it++) {
+ if (it->type == type) {
+ if (val != nullptr) {
+ *val = it->value;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace
+
+IdentifierIterator::IdentifierIterator(const ProgramSelector& sel) : IdentifierIterator(sel, 0) {}
+
+IdentifierIterator::IdentifierIterator(const ProgramSelector& sel, size_t pos)
+ : mSel(sel), mPos(pos) {}
+
+const IdentifierIterator IdentifierIterator::operator++(int) {
+ IdentifierIterator i = *this;
+ mPos++;
+ return i;
+}
+
+IdentifierIterator& IdentifierIterator::operator++() {
+ ++mPos;
+ return *this;
+}
+
+IdentifierIterator::refType IdentifierIterator::operator*() const {
+ if (mPos == 0) {
+ return getSelector().primaryId;
+ }
+
+ // mPos is 1-based for secondary identifiers
+ DCHECK(mPos <= getSelector().secondaryIds.size());
+ return getSelector().secondaryIds[mPos - 1];
+}
+
+bool IdentifierIterator::operator==(const IdentifierIterator& rhs) const {
+ // Check, if both iterators points at the same selector.
+ if (reinterpret_cast<intptr_t>(&getSelector()) !=
+ reinterpret_cast<intptr_t>(&rhs.getSelector())) {
+ return false;
+ }
+
+ return mPos == rhs.mPos;
+}
+
+int32_t resultToInt(Result result) {
+ return static_cast<int32_t>(result);
+}
+
+FrequencyBand getBand(int64_t freq) {
+ // keep in sync with
+ // frameworks/base/services/core/java/com/android/server/broadcastradio/aidl/Utils.java
+ if (freq < 30) return FrequencyBand::UNKNOWN;
+ if (freq < 500) return FrequencyBand::AM_LW;
+ if (freq < 1705) return FrequencyBand::AM_MW;
+ if (freq < 30000) return FrequencyBand::AM_SW;
+ if (freq < 60000) return FrequencyBand::UNKNOWN;
+ if (freq < 110000) return FrequencyBand::FM;
+ return FrequencyBand::UNKNOWN;
+}
+
+bool tunesTo(const ProgramSelector& a, const ProgramSelector& b) {
+ IdentifierType type = b.primaryId.type;
+
+ switch (type) {
+ case IdentifierType::HD_STATION_ID_EXT:
+ case IdentifierType::RDS_PI:
+ case IdentifierType::AMFM_FREQUENCY_KHZ:
+ if (haveEqualIds(a, b, IdentifierType::HD_STATION_ID_EXT)) return true;
+ if (haveEqualIds(a, b, IdentifierType::RDS_PI)) return true;
+ return getHdSubchannel(b) == 0 &&
+ haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY_KHZ);
+ case IdentifierType::DAB_SID_EXT:
+ if (!haveEqualIds(a, b, IdentifierType::DAB_SID_EXT)) {
+ return false;
+ }
+ if (hasId(a, IdentifierType::DAB_ENSEMBLE) &&
+ !haveEqualIds(a, b, IdentifierType::DAB_ENSEMBLE)) {
+ return false;
+ }
+ if (hasId(a, IdentifierType::DAB_FREQUENCY_KHZ) &&
+ !haveEqualIds(a, b, IdentifierType::DAB_FREQUENCY_KHZ)) {
+ return false;
+ }
+ return true;
+ case IdentifierType::DRMO_SERVICE_ID:
+ return haveEqualIds(a, b, IdentifierType::DRMO_SERVICE_ID);
+ case IdentifierType::SXM_SERVICE_ID:
+ return haveEqualIds(a, b, IdentifierType::SXM_SERVICE_ID);
+ default: // includes all vendor types
+ LOG(WARNING) << "unsupported program type: " << toString(type);
+ return false;
+ }
+}
+
+bool hasId(const ProgramSelector& sel, const IdentifierType& type) {
+ return maybeGetId(sel, type, /* val */ nullptr);
+}
+
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type) {
+ int64_t val;
+
+ if (maybeGetId(sel, type, &val)) {
+ return val;
+ }
+
+ LOG(WARNING) << "identifier not found: " << toString(type);
+ return kValueForNotFoundIdentifier;
+}
+
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue) {
+ if (!hasId(sel, type)) {
+ return defaultValue;
+ }
+ return getId(sel, type);
+}
+
+vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type) {
+ vector<int> ret;
+
+ // iterate through primaryId and secondaryIds
+ for (auto it = begin(sel); it != end(sel); it++) {
+ if (it->type == type) {
+ ret.push_back(it->value);
+ }
+ }
+
+ return ret;
+}
+
+bool isSupported(const Properties& prop, const ProgramSelector& sel) {
+ for (auto it = prop.supportedIdentifierTypes.begin(); it != prop.supportedIdentifierTypes.end();
+ it++) {
+ if (hasId(sel, *it)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool isValid(const ProgramIdentifier& id) {
+ int64_t val = id.value;
+ bool valid = true;
+
+ auto expect = [&valid](bool condition, const string& message) {
+ if (!condition) {
+ valid = false;
+ LOG(ERROR) << "identifier not valid, expected " << message;
+ }
+ };
+
+ switch (id.type) {
+ case IdentifierType::INVALID:
+ expect(false, "IdentifierType::INVALID");
+ break;
+ case IdentifierType::DAB_FREQUENCY_KHZ:
+ expect(val > 100000u, "f > 100MHz");
+ [[fallthrough]];
+ case IdentifierType::AMFM_FREQUENCY_KHZ:
+ case IdentifierType::DRMO_FREQUENCY_KHZ:
+ expect(val > 100u, "f > 100kHz");
+ expect(val < 10000000u, "f < 10GHz");
+ break;
+ case IdentifierType::RDS_PI:
+ expect(val != 0u, "RDS PI != 0");
+ expect(val <= 0xFFFFu, "16bit id");
+ break;
+ case IdentifierType::HD_STATION_ID_EXT: {
+ int64_t stationId = val & 0xFFFFFFFF; // 32bit
+ val >>= 32;
+ int64_t subchannel = val & 0xF; // 4bit
+ val >>= 4;
+ int64_t freq = val & 0x3FFFF; // 18bit
+ expect(stationId != 0u, "HD station id != 0");
+ expect(subchannel < 8u, "HD subch < 8");
+ expect(freq > 100u, "f > 100kHz");
+ expect(freq < 10000000u, "f < 10GHz");
+ break;
+ }
+ case IdentifierType::HD_STATION_NAME: {
+ while (val > 0) {
+ char ch = static_cast<char>(val & 0xFF);
+ val >>= 8;
+ expect((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z'),
+ "HD_STATION_NAME does not match [A-Z0-9]+");
+ }
+ break;
+ }
+ case IdentifierType::DAB_SID_EXT: {
+ int64_t sid = val & 0xFFFFFFFF; // 32bit
+ val >>= 32;
+ int64_t ecc = val & 0xFF; // 8bit
+ expect(sid != 0u, "DAB SId != 0");
+ expect(ecc >= 0xA0u && ecc <= 0xF6u, "Invalid ECC, see ETSI TS 101 756 V2.1.1");
+ break;
+ }
+ case IdentifierType::DAB_ENSEMBLE:
+ expect(val != 0u, "DAB ensemble != 0");
+ expect(val <= 0xFFFFu, "16bit id");
+ break;
+ case IdentifierType::DAB_SCID:
+ expect(val > 0xFu, "12bit SCId (not 4bit SCIdS)");
+ expect(val <= 0xFFFu, "12bit id");
+ break;
+ case IdentifierType::DRMO_SERVICE_ID:
+ expect(val != 0u, "DRM SId != 0");
+ expect(val <= 0xFFFFFFu, "24bit id");
+ break;
+ case IdentifierType::SXM_SERVICE_ID:
+ expect(val != 0u, "SXM SId != 0");
+ expect(val <= 0xFFFFFFFFu, "32bit id");
+ break;
+ case IdentifierType::SXM_CHANNEL:
+ expect(val < 1000u, "SXM channel < 1000");
+ break;
+ case IdentifierType::VENDOR_START:
+ case IdentifierType::VENDOR_END:
+ // skip
+ break;
+ }
+
+ return valid;
+}
+
+bool isValid(const ProgramSelector& sel) {
+ if (sel.primaryId.type != IdentifierType::AMFM_FREQUENCY_KHZ &&
+ sel.primaryId.type != IdentifierType::RDS_PI &&
+ sel.primaryId.type != IdentifierType::HD_STATION_ID_EXT &&
+ sel.primaryId.type != IdentifierType::DAB_SID_EXT &&
+ sel.primaryId.type != IdentifierType::DRMO_SERVICE_ID &&
+ sel.primaryId.type != IdentifierType::SXM_SERVICE_ID &&
+ (sel.primaryId.type < IdentifierType::VENDOR_START ||
+ sel.primaryId.type > IdentifierType::VENDOR_END)) {
+ return false;
+ }
+ return isValid(sel.primaryId);
+}
+
+ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value) {
+ return {type, value};
+}
+
+ProgramSelector makeSelectorAmfm(int32_t frequency) {
+ ProgramSelector sel = {};
+ sel.primaryId = makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, frequency);
+ return sel;
+}
+
+ProgramSelector makeSelectorDab(int64_t sidExt) {
+ ProgramSelector sel = {};
+ sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
+ return sel;
+}
+
+ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq) {
+ ProgramSelector sel = {};
+ sel.primaryId = makeIdentifier(IdentifierType::DAB_SID_EXT, sidExt);
+ vector<ProgramIdentifier> secondaryIds = {
+ makeIdentifier(IdentifierType::DAB_ENSEMBLE, ensemble),
+ makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, freq)};
+ sel.secondaryIds = std::move(secondaryIds);
+ return sel;
+}
+
+bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel) {
+ if (filter.identifierTypes.size() > 0) {
+ auto typeEquals = [](const ProgramIdentifier& id, IdentifierType type) {
+ return id.type == type;
+ };
+ auto it = std::find_first_of(begin(sel), end(sel), filter.identifierTypes.begin(),
+ filter.identifierTypes.end(), typeEquals);
+ if (it == end(sel)) {
+ return false;
+ }
+ }
+
+ if (filter.identifiers.size() > 0) {
+ auto it = std::find_first_of(begin(sel), end(sel), filter.identifiers.begin(),
+ filter.identifiers.end());
+ if (it == end(sel)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+size_t ProgramInfoHasher::operator()(const ProgramInfo& info) const {
+ const ProgramIdentifier& id = info.selector.primaryId;
+
+ // This is not the best hash implementation, but good enough for default HAL
+ // implementation and tests.
+ size_t h = 0;
+ ::android::hashCombineSingle(h, id.type);
+ ::android::hashCombineSingle(h, id.value);
+ return h;
+}
+
+bool ProgramInfoKeyEqual::operator()(const ProgramInfo& info1, const ProgramInfo& info2) const {
+ const ProgramIdentifier& id1 = info1.selector.primaryId;
+ const ProgramIdentifier& id2 = info2.selector.primaryId;
+ return id1.type == id2.type && id1.value == id2.value;
+}
+
+void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list) {
+ if (chunk.purge) {
+ list->clear();
+ }
+
+ list->insert(chunk.modified.begin(), chunk.modified.end());
+
+ if (!chunk.removed.has_value()) {
+ return;
+ }
+
+ for (auto& id : chunk.removed.value()) {
+ if (id.has_value()) {
+ ProgramInfo info = {};
+ info.selector.primaryId = id.value();
+ list->erase(info);
+ }
+ }
+}
+
+std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag) {
+ auto isRdsPs = [tag](const Metadata& item) { return item.getTag() == tag; };
+
+ auto it = std::find_if(info.metadata.begin(), info.metadata.end(), isRdsPs);
+ if (it == info.metadata.end()) {
+ return std::nullopt;
+ }
+
+ std::string metadataString;
+ switch (it->getTag()) {
+ case Metadata::rdsPs:
+ metadataString = it->get<Metadata::rdsPs>();
+ break;
+ case Metadata::rdsPty:
+ metadataString = std::to_string(it->get<Metadata::rdsPty>());
+ break;
+ case Metadata::rbdsPty:
+ metadataString = std::to_string(it->get<Metadata::rbdsPty>());
+ break;
+ case Metadata::rdsRt:
+ metadataString = it->get<Metadata::rdsRt>();
+ break;
+ case Metadata::songTitle:
+ metadataString = it->get<Metadata::songTitle>();
+ break;
+ case Metadata::songArtist:
+ metadataString = it->get<Metadata::songArtist>();
+ break;
+ case Metadata::songAlbum:
+ metadataString = it->get<Metadata::songAlbum>();
+ break;
+ case Metadata::stationIcon:
+ metadataString = std::to_string(it->get<Metadata::stationIcon>());
+ break;
+ case Metadata::albumArt:
+ metadataString = std::to_string(it->get<Metadata::albumArt>());
+ break;
+ case Metadata::programName:
+ metadataString = it->get<Metadata::programName>();
+ break;
+ case Metadata::dabEnsembleName:
+ metadataString = it->get<Metadata::dabEnsembleName>();
+ break;
+ case Metadata::dabEnsembleNameShort:
+ metadataString = it->get<Metadata::dabEnsembleNameShort>();
+ break;
+ case Metadata::dabServiceName:
+ metadataString = it->get<Metadata::dabServiceName>();
+ break;
+ case Metadata::dabServiceNameShort:
+ metadataString = it->get<Metadata::dabServiceNameShort>();
+ break;
+ case Metadata::dabComponentName:
+ metadataString = it->get<Metadata::dabComponentName>();
+ break;
+ case Metadata::dabComponentNameShort:
+ metadataString = it->get<Metadata::dabComponentNameShort>();
+ break;
+ default:
+ LOG(ERROR) << "Metadata " << it->toString() << " is not converted.";
+ return std::nullopt;
+ }
+ return metadataString;
+}
+
+ProgramIdentifier makeHdRadioStationName(const string& name) {
+ constexpr size_t maxlen = 8;
+
+ string shortName;
+ shortName.reserve(maxlen);
+
+ const auto& loc = std::locale::classic();
+ for (const char& ch : name) {
+ if (!std::isalnum(ch, loc)) {
+ continue;
+ }
+ shortName.push_back(std::toupper(ch, loc));
+ if (shortName.length() >= maxlen) {
+ break;
+ }
+ }
+
+ // Short name is converted to HD_STATION_NAME by encoding each char into its ASCII value in
+ // in little-endian order. For example, "Abc" is converted to 0x434241.
+ int64_t val = 0;
+ for (auto rit = shortName.rbegin(); rit != shortName.rend(); ++rit) {
+ val <<= 8;
+ val |= static_cast<char>(*rit);
+ }
+
+ return makeIdentifier(IdentifierType::HD_STATION_NAME, val);
+}
+
+IdentifierType getType(int typeAsInt) {
+ return static_cast<IdentifierType>(typeAsInt);
+}
+
+bool parseArgInt(const string& s, int* out) {
+ return ::android::base::ParseInt(s, out);
+}
+
+bool parseArgLong(const std::string& s, long* out) {
+ return ::android::base::ParseInt(s, out);
+}
+
+bool parseArgBool(const string& s, bool* out) {
+ if (EqualsIgnoreCase(s, "true")) {
+ *out = true;
+ } else if (EqualsIgnoreCase(s, "false")) {
+ *out = false;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool parseArgDirection(const string& s, bool* out) {
+ if (EqualsIgnoreCase(s, "up")) {
+ *out = true;
+ } else if (EqualsIgnoreCase(s, "down")) {
+ *out = false;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool parseArgIdentifierTypeArray(const string& s, vector<IdentifierType>* out) {
+ for (const string& val : ::android::base::Split(s, ",")) {
+ int outInt;
+ if (!parseArgInt(val, &outInt)) {
+ return false;
+ }
+ out->push_back(getType(outInt));
+ }
+ return true;
+}
+
+bool parseProgramIdentifierList(const std::string& s, vector<ProgramIdentifier>* out) {
+ for (const string& idStr : ::android::base::Split(s, ",")) {
+ const vector<string> idStrPair = ::android::base::Split(idStr, ":");
+ if (idStrPair.size() != 2) {
+ return false;
+ }
+ int idType;
+ if (!parseArgInt(idStrPair[0], &idType)) {
+ return false;
+ }
+ long idVal;
+ if (!parseArgLong(idStrPair[1], &idVal)) {
+ return false;
+ }
+ ProgramIdentifier id = {getType(idType), idVal};
+ out->push_back(id);
+ }
+ return true;
+}
+
+} // namespace utils
+
+utils::IdentifierIterator begin(const ProgramSelector& sel) {
+ return utils::IdentifierIterator(sel);
+}
+
+utils::IdentifierIterator end(const ProgramSelector& sel) {
+ return utils::IdentifierIterator(sel) + 1 /* primary id */ + sel.secondaryIds.size();
+}
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
new file mode 100644
index 0000000..ad075f2
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
+#include <aidl/android/hardware/broadcastradio/Metadata.h>
+#include <aidl/android/hardware/broadcastradio/ProgramFilter.h>
+#include <aidl/android/hardware/broadcastradio/ProgramIdentifier.h>
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+#include <aidl/android/hardware/broadcastradio/ProgramListChunk.h>
+#include <aidl/android/hardware/broadcastradio/ProgramSelector.h>
+#include <aidl/android/hardware/broadcastradio/Properties.h>
+#include <aidl/android/hardware/broadcastradio/Result.h>
+
+#include <numeric>
+#include <optional>
+#include <thread>
+#include <unordered_set>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace utils {
+
+enum class FrequencyBand {
+ UNKNOWN,
+ FM,
+ AM_LW,
+ AM_MW,
+ AM_SW,
+};
+
+class IdentifierIterator final
+ : public std::iterator<std::random_access_iterator_tag, ProgramIdentifier, ssize_t,
+ const ProgramIdentifier*, const ProgramIdentifier&> {
+ using ptrType = typename std::iterator_traits<IdentifierIterator>::pointer;
+ using refType = typename std::iterator_traits<IdentifierIterator>::reference;
+ using diffType = typename std::iterator_traits<IdentifierIterator>::difference_type;
+
+ public:
+ explicit IdentifierIterator(const ProgramSelector& sel);
+
+ const IdentifierIterator operator++(int);
+ IdentifierIterator& operator++();
+ refType operator*() const;
+ inline ptrType operator->() const { return &operator*(); }
+ IdentifierIterator operator+(diffType v) const { return IdentifierIterator(mSel, mPos + v); }
+ bool operator==(const IdentifierIterator& rhs) const;
+ inline bool operator!=(const IdentifierIterator& rhs) const { return !operator==(rhs); };
+
+ private:
+ explicit IdentifierIterator(const ProgramSelector& sel, size_t pos);
+
+ std::reference_wrapper<const ProgramSelector> mSel;
+
+ const ProgramSelector& getSelector() const { return mSel.get(); }
+
+ /** 0 is the primary identifier, 1-n are secondary identifiers. */
+ size_t mPos = 0;
+};
+
+/**
+ * Convert Result to int
+ */
+int32_t resultToInt(Result result);
+
+/**
+ * Guesses band from the frequency value.
+ *
+ * The band bounds are not exact to cover multiple regions.
+ * The function is biased towards success, i.e. it never returns
+ * FrequencyBand::UNKNOWN for correct frequency, but a result for
+ * incorrect one is undefined (it doesn't have to return UNKNOWN).
+ */
+FrequencyBand getBand(int64_t frequency);
+
+/**
+ * Checks, if {@code pointer} tunes to {@channel}.
+ *
+ * For example, having a channel {AMFM_FREQUENCY_KHZ = 103.3}:
+ * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 0} can tune to this channel;
+ * - selector {AMFM_FREQUENCY_KHZ = 103.3, HD_SUBCHANNEL = 1} can't.
+ *
+ * @param pointer selector we're trying to match against channel.
+ * @param channel existing channel.
+ */
+bool tunesTo(const ProgramSelector& pointer, const ProgramSelector& channel);
+
+/**
+ * Checks whether a given program selector has the given ID (either primary or secondary).
+ */
+bool hasId(const ProgramSelector& sel, const IdentifierType& type);
+
+/**
+ * Returns ID (either primary or secondary) for a given program selector.
+ *
+ * If the selector does not contain given type, returns kValueForNotFoundIdentifier
+ * and emits a warning.
+ */
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type);
+
+/**
+ * Returns ID (either primary or secondary) for a given program selector.
+ *
+ * If the selector does not contain given type, returns default value.
+ */
+int64_t getId(const ProgramSelector& sel, const IdentifierType& type, int64_t defaultValue);
+
+/**
+ * Returns all IDs of a given type.
+ */
+std::vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type);
+
+/**
+ * Checks, if a given selector is supported by the radio module.
+ *
+ * @param prop Module description.
+ * @param sel The selector to check.
+ * @return True, if the selector is supported, false otherwise.
+ */
+bool isSupported(const Properties& prop, const ProgramSelector& sel);
+
+bool isValid(const ProgramIdentifier& id);
+bool isValid(const ProgramSelector& sel);
+
+ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value);
+ProgramSelector makeSelectorAmfm(int32_t frequency);
+ProgramSelector makeSelectorDab(int64_t sidExt);
+ProgramSelector makeSelectorDab(int64_t sidExt, int32_t ensemble, int64_t freq);
+
+bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
+
+struct ProgramInfoHasher {
+ size_t operator()(const ProgramInfo& info) const;
+};
+
+struct ProgramInfoKeyEqual {
+ bool operator()(const ProgramInfo& info1, const ProgramInfo& info2) const;
+};
+
+typedef std::unordered_set<ProgramInfo, ProgramInfoHasher, ProgramInfoKeyEqual> ProgramInfoSet;
+
+void updateProgramList(const ProgramListChunk& chunk, ProgramInfoSet* list);
+
+std::optional<std::string> getMetadataString(const ProgramInfo& info, const Metadata::Tag& tag);
+
+ProgramIdentifier makeHdRadioStationName(const std::string& name);
+
+template <typename aidl_type>
+inline std::string vectorToString(const std::vector<aidl_type>& in_values) {
+ return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
+ [](const std::string& ls, const aidl_type& rs) {
+ return ls + (ls.empty() ? "" : ",") + toString(rs);
+ });
+}
+
+IdentifierType getType(int typeAsInt);
+
+bool parseArgInt(const std::string& s, int* out);
+
+bool parseArgLong(const std::string& s, long* out);
+
+bool parseArgBool(const std::string& s, bool* out);
+
+bool parseArgDirection(const std::string& s, bool* out);
+
+bool parseArgIdentifierTypeArray(const std::string& s, std::vector<IdentifierType>* out);
+
+bool parseProgramIdentifierList(const std::string& s, std::vector<ProgramIdentifier>* out);
+
+} // namespace utils
+
+utils::IdentifierIterator begin(const ProgramSelector& sel);
+utils::IdentifierIterator end(const ProgramSelector& sel);
+
+} // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/common/1.0/default/Android.bp b/camera/common/1.0/default/Android.bp
deleted file mode 100644
index 4a5ca83..0000000
--- a/camera/common/1.0/default/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_interfaces_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_library_static {
- name: "[email protected]",
- vendor_available: true,
- defaults: ["hidl_defaults"],
- srcs: [
- "CameraModule.cpp",
- "CameraMetadata.cpp",
- "CameraParameters.cpp",
- "VendorTagDescriptor.cpp",
- "HandleImporter.cpp",
- "Exif.cpp",
- ],
- cflags: [
- "-Werror",
- "-Wextra",
- "-Wall",
- ],
- shared_libs: [
- "liblog",
- "libgralloctypes",
- "libhardware",
- "libcamera_metadata",
- "[email protected]",
- "[email protected]",
- "[email protected]",
- "libexif",
- ],
- include_dirs: ["system/media/private/camera/include"],
- export_include_dirs: ["include"],
-}
diff --git a/camera/common/1.0/default/CameraMetadata.cpp b/camera/common/1.0/default/CameraMetadata.cpp
deleted file mode 100644
index eb1bd1c..0000000
--- a/camera/common/1.0/default/CameraMetadata.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open 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_NDEBUG 0
-
-#define LOG_TAG "CamComm1.0-MD"
-#include <log/log.h>
-#include <utils/Errors.h>
-
-#include "CameraMetadata.h"
-#include "VendorTagDescriptor.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-#define ALIGN_TO(val, alignment) \
- (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1))
-
-CameraMetadata::CameraMetadata() :
- mBuffer(NULL), mLocked(false) {
-}
-
-CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
- mLocked(false)
-{
- mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
-}
-
-CameraMetadata::CameraMetadata(const CameraMetadata &other) :
- mLocked(false) {
- mBuffer = clone_camera_metadata(other.mBuffer);
-}
-
-CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
- mBuffer(NULL), mLocked(false) {
- acquire(buffer);
-}
-
-CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
- return operator=(other.mBuffer);
-}
-
-CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
- if (mLocked) {
- ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
- return *this;
- }
-
- if (CC_LIKELY(buffer != mBuffer)) {
- camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
- clear();
- mBuffer = newBuffer;
- }
- return *this;
-}
-
-CameraMetadata::~CameraMetadata() {
- mLocked = false;
- clear();
-}
-
-const camera_metadata_t* CameraMetadata::getAndLock() const {
- mLocked = true;
- return mBuffer;
-}
-
-status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
- if (!mLocked) {
- ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if (buffer != mBuffer) {
- ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
- __FUNCTION__);
- return BAD_VALUE;
- }
- mLocked = false;
- return OK;
-}
-
-camera_metadata_t* CameraMetadata::release() {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return NULL;
- }
- camera_metadata_t *released = mBuffer;
- mBuffer = NULL;
- return released;
-}
-
-void CameraMetadata::clear() {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return;
- }
- if (mBuffer) {
- free_camera_metadata(mBuffer);
- mBuffer = NULL;
- }
-}
-
-void CameraMetadata::acquire(camera_metadata_t *buffer) {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return;
- }
- clear();
- mBuffer = buffer;
-
- ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
- "%s: Failed to validate metadata structure %p",
- __FUNCTION__, buffer);
-}
-
-void CameraMetadata::acquire(CameraMetadata &other) {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return;
- }
- acquire(other.release());
-}
-
-status_t CameraMetadata::append(const CameraMetadata &other) {
- return append(other.mBuffer);
-}
-
-status_t CameraMetadata::append(const camera_metadata_t* other) {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- size_t extraEntries = get_camera_metadata_entry_count(other);
- size_t extraData = get_camera_metadata_data_count(other);
- resizeIfNeeded(extraEntries, extraData);
-
- return append_camera_metadata(mBuffer, other);
-}
-
-size_t CameraMetadata::entryCount() const {
- return (mBuffer == NULL) ? 0 :
- get_camera_metadata_entry_count(mBuffer);
-}
-
-bool CameraMetadata::isEmpty() const {
- return entryCount() == 0;
-}
-
-status_t CameraMetadata::sort() {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- return sort_camera_metadata(mBuffer);
-}
-
-status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
- int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
- if ( CC_UNLIKELY(tagType == -1)) {
- ALOGE("Update metadata entry: Unknown tag %d", tag);
- return INVALID_OPERATION;
- }
- if ( CC_UNLIKELY(tagType != expectedType) ) {
- ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
- "got type %s data instead ",
- get_local_camera_metadata_tag_name(tag, mBuffer), tag,
- camera_metadata_type_names[tagType], camera_metadata_type_names[expectedType]);
- return INVALID_OPERATION;
- }
- return OK;
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const int32_t *data, size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_INT32)) != OK) {
- return res;
- }
- return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const uint8_t *data, size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
- return res;
- }
- return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const float *data, size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
- return res;
- }
- return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const int64_t *data, size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_INT64)) != OK) {
- return res;
- }
- return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const double *data, size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
- return res;
- }
- return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const camera_metadata_rational_t *data, size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
- return res;
- }
- return updateImpl(tag, (const void*)data, data_count);
-}
-
-status_t CameraMetadata::update(uint32_t tag,
- const String8 &string) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
- return res;
- }
- // string.size() doesn't count the null termination character.
- return updateImpl(tag, (const void*)string.string(), string.size() + 1);
-}
-
-status_t CameraMetadata::update(const camera_metadata_ro_entry &entry) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- if ( (res = checkType(entry.tag, entry.type)) != OK) {
- return res;
- }
- return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
-}
-
-status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
- size_t data_count) {
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- int type = get_local_camera_metadata_tag_type(tag, mBuffer);
- if (type == -1) {
- ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
- return BAD_VALUE;
- }
- // Safety check - ensure that data isn't pointing to this metadata, since
- // that would get invalidated if a resize is needed
- size_t bufferSize = get_camera_metadata_size(mBuffer);
- uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
- uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
- if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
- ALOGE("%s: Update attempted with data from the same metadata buffer!",
- __FUNCTION__);
- return INVALID_OPERATION;
- }
-
- size_t data_size = calculate_camera_metadata_entry_data_size(type,
- data_count);
-
- res = resizeIfNeeded(1, data_size);
-
- if (res == OK) {
- camera_metadata_entry_t entry;
- res = find_camera_metadata_entry(mBuffer, tag, &entry);
- if (res == NAME_NOT_FOUND) {
- res = add_camera_metadata_entry(mBuffer,
- tag, data, data_count);
- } else if (res == OK) {
- res = update_camera_metadata_entry(mBuffer,
- entry.index, data, data_count, NULL);
- }
- }
-
- if (res != OK) {
- ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__,
- get_local_camera_metadata_section_name(tag, mBuffer),
- get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
- }
-
- IF_ALOGV() {
- ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
- OK,
-
- "%s: Failed to validate metadata structure after update %p",
- __FUNCTION__, mBuffer);
- }
-
- return res;
-}
-
-bool CameraMetadata::exists(uint32_t tag) const {
- camera_metadata_ro_entry entry;
- return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
-}
-
-camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
- status_t res;
- camera_metadata_entry entry;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- entry.count = 0;
- return entry;
- }
- res = find_camera_metadata_entry(mBuffer, tag, &entry);
- if (CC_UNLIKELY( res != OK )) {
- entry.count = 0;
- entry.data.u8 = NULL;
- }
- return entry;
-}
-
-camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
- status_t res;
- camera_metadata_ro_entry entry;
- res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
- if (CC_UNLIKELY( res != OK )) {
- entry.count = 0;
- entry.data.u8 = NULL;
- }
- return entry;
-}
-
-status_t CameraMetadata::erase(uint32_t tag) {
- camera_metadata_entry_t entry;
- status_t res;
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return INVALID_OPERATION;
- }
- res = find_camera_metadata_entry(mBuffer, tag, &entry);
- if (res == NAME_NOT_FOUND) {
- return OK;
- } else if (res != OK) {
- ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", __FUNCTION__,
- get_local_camera_metadata_section_name(tag, mBuffer),
- get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
- return res;
- }
- res = delete_camera_metadata_entry(mBuffer, entry.index);
- if (res != OK) {
- ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", __FUNCTION__,
- get_local_camera_metadata_section_name(tag, mBuffer),
- get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
- }
- return res;
-}
-
-void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
- dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
-}
-
-status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
- if (mBuffer == NULL) {
- mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
- if (mBuffer == NULL) {
- ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
- return NO_MEMORY;
- }
- } else {
- size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
- size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
- size_t newEntryCount = currentEntryCount +
- extraEntries;
- newEntryCount = (newEntryCount > currentEntryCap) ?
- newEntryCount * 2 : currentEntryCap;
-
- size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
- size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
- size_t newDataCount = currentDataCount +
- extraData;
- newDataCount = (newDataCount > currentDataCap) ?
- newDataCount * 2 : currentDataCap;
-
- if (newEntryCount > currentEntryCap ||
- newDataCount > currentDataCap) {
- camera_metadata_t *oldBuffer = mBuffer;
- mBuffer = allocate_camera_metadata(newEntryCount,
- newDataCount);
- if (mBuffer == NULL) {
- ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
- return NO_MEMORY;
- }
- append_camera_metadata(mBuffer, oldBuffer);
- free_camera_metadata(oldBuffer);
- }
- }
- return OK;
-}
-
-void CameraMetadata::swap(CameraMetadata& other) {
- if (mLocked) {
- ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
- return;
- } else if (other.mLocked) {
- ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
- return;
- }
-
- camera_metadata* thisBuf = mBuffer;
- camera_metadata* otherBuf = other.mBuffer;
-
- other.mBuffer = thisBuf;
- mBuffer = otherBuf;
-}
-
-status_t CameraMetadata::getTagFromName(const char *name,
- const VendorTagDescriptor* vTags, uint32_t *tag) {
-
- if (name == nullptr || tag == nullptr) return BAD_VALUE;
-
- size_t nameLength = strlen(name);
-
- const SortedVector<String8> *vendorSections;
- size_t vendorSectionCount = 0;
-
- if (vTags != NULL) {
- vendorSections = vTags->getAllSectionNames();
- vendorSectionCount = vendorSections->size();
- }
-
- // First, find the section by the longest string match
- const char *section = NULL;
- size_t sectionIndex = 0;
- size_t sectionLength = 0;
- size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
- for (size_t i = 0; i < totalSectionCount; ++i) {
-
- const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] :
- (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
-
- ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
-
- if (strstr(name, str) == name) { // name begins with the section name
- size_t strLength = strlen(str);
-
- ALOGV("%s: Name begins with section name", __FUNCTION__);
-
- // section name is the longest we've found so far
- if (section == NULL || sectionLength < strLength) {
- section = str;
- sectionIndex = i;
- sectionLength = strLength;
-
- ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
- }
- }
- }
-
- if (section == NULL) {
- return NAME_NOT_FOUND;
- } else {
- ALOGV("%s: Found matched section '%s' (%zu)",
- __FUNCTION__, section, sectionIndex);
- }
-
- // Get the tag name component of the name
- const char *nameTagName = name + sectionLength + 1; // x.y.z -> z
- if (sectionLength + 1 >= nameLength) {
- return BAD_VALUE;
- }
-
- // Match rest of name against the tag names in that section only
- uint32_t candidateTag = 0;
- if (sectionIndex < ANDROID_SECTION_COUNT) {
- // Match built-in tags (typically android.*)
- uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
- tagBegin = camera_metadata_section_bounds[sectionIndex][0];
- tagEnd = camera_metadata_section_bounds[sectionIndex][1];
-
- for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
- const char *tagName = get_camera_metadata_tag_name(candidateTag);
-
- if (strcmp(nameTagName, tagName) == 0) {
- ALOGV("%s: Found matched tag '%s' (%d)",
- __FUNCTION__, tagName, candidateTag);
- break;
- }
- }
-
- if (candidateTag == tagEnd) {
- return NAME_NOT_FOUND;
- }
- } else if (vTags != NULL) {
- // Match vendor tags (typically com.*)
- const String8 sectionName(section);
- const String8 tagName(nameTagName);
-
- status_t res = OK;
- if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
- return NAME_NOT_FOUND;
- }
- }
-
- *tag = candidateTag;
- return OK;
-}
-
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
deleted file mode 100644
index 16fb85c..0000000
--- a/camera/common/1.0/default/CameraModule.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open 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 "CamComm1.0-CamModule"
-#define ATRACE_TAG ATRACE_TAG_CAMERA
-//#define LOG_NDEBUG 0
-
-#include <utils/Trace.h>
-
-#include "CameraModule.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-void CameraModule::deriveCameraCharacteristicsKeys(
- uint32_t deviceVersion, CameraMetadata &chars) {
- ATRACE_CALL();
-
- Vector<int32_t> derivedCharKeys;
- Vector<int32_t> derivedRequestKeys;
- Vector<int32_t> derivedResultKeys;
- // Keys added in HAL3.3
- if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
- Vector<uint8_t> controlModes;
- uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
- chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/1);
- data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
- chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/1);
- controlModes.push(ANDROID_CONTROL_MODE_AUTO);
- camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
- if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) {
- controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE);
- }
-
- // Only advertise CONTROL_OFF mode if 3A manual controls are supported.
- bool isManualAeSupported = false;
- bool isManualAfSupported = false;
- bool isManualAwbSupported = false;
- entry = chars.find(ANDROID_CONTROL_AE_AVAILABLE_MODES);
- if (entry.count > 0) {
- for (size_t i = 0; i < entry.count; i++) {
- if (entry.data.u8[i] == ANDROID_CONTROL_AE_MODE_OFF) {
- isManualAeSupported = true;
- break;
- }
- }
- }
- entry = chars.find(ANDROID_CONTROL_AF_AVAILABLE_MODES);
- if (entry.count > 0) {
- for (size_t i = 0; i < entry.count; i++) {
- if (entry.data.u8[i] == ANDROID_CONTROL_AF_MODE_OFF) {
- isManualAfSupported = true;
- break;
- }
- }
- }
- entry = chars.find(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
- if (entry.count > 0) {
- for (size_t i = 0; i < entry.count; i++) {
- if (entry.data.u8[i] == ANDROID_CONTROL_AWB_MODE_OFF) {
- isManualAwbSupported = true;
- break;
- }
- }
- }
- if (isManualAeSupported && isManualAfSupported && isManualAwbSupported) {
- controlModes.push(ANDROID_CONTROL_MODE_OFF);
- }
-
- chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
-
- entry = chars.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
- // HAL3.2 devices passing existing CTS test should all support all LSC modes and LSC map
- bool lensShadingModeSupported = false;
- if (entry.count > 0) {
- for (size_t i = 0; i < entry.count; i++) {
- if (entry.data.i32[i] == ANDROID_SHADING_MODE) {
- lensShadingModeSupported = true;
- break;
- }
- }
- }
- Vector<uint8_t> lscModes;
- Vector<uint8_t> lscMapModes;
- lscModes.push(ANDROID_SHADING_MODE_FAST);
- lscModes.push(ANDROID_SHADING_MODE_HIGH_QUALITY);
- lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
- if (lensShadingModeSupported) {
- lscModes.push(ANDROID_SHADING_MODE_OFF);
- lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
- }
- chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
- chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
-
- derivedCharKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
- derivedCharKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
- derivedCharKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
- derivedCharKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
- derivedCharKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
-
- // Need update android.control.availableHighSpeedVideoConfigurations since HAL3.3
- // adds batch size to this array.
- entry = chars.find(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
- if (entry.count > 0) {
- Vector<int32_t> highSpeedConfig;
- for (size_t i = 0; i < entry.count; i += 4) {
- highSpeedConfig.add(entry.data.i32[i]); // width
- highSpeedConfig.add(entry.data.i32[i + 1]); // height
- highSpeedConfig.add(entry.data.i32[i + 2]); // fps_min
- highSpeedConfig.add(entry.data.i32[i + 3]); // fps_max
- highSpeedConfig.add(1); // batchSize_max. default to 1 for HAL3.2
- }
- chars.update(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
- highSpeedConfig);
- }
- }
-
- // Keys added in HAL3.4
- if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
- // Check if HAL supports RAW_OPAQUE output
- camera_metadata_entry entry = chars.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
- bool supportRawOpaque = false;
- bool supportAnyRaw = false;
- const int STREAM_CONFIGURATION_SIZE = 4;
- const int STREAM_FORMAT_OFFSET = 0;
- const int STREAM_WIDTH_OFFSET = 1;
- const int STREAM_HEIGHT_OFFSET = 2;
- const int STREAM_IS_INPUT_OFFSET = 3;
- Vector<int32_t> rawOpaqueSizes;
-
- for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
- int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
- int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
- int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
- int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
- if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
- format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
- supportRawOpaque = true;
- rawOpaqueSizes.push(width);
- rawOpaqueSizes.push(height);
- // 2 bytes per pixel. This rough estimation is only used when
- // HAL does not fill in the opaque raw size
- rawOpaqueSizes.push(width * height *2);
- }
- if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
- (format == HAL_PIXEL_FORMAT_RAW16 ||
- format == HAL_PIXEL_FORMAT_RAW10 ||
- format == HAL_PIXEL_FORMAT_RAW12 ||
- format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
- supportAnyRaw = true;
- }
- }
-
- if (supportRawOpaque) {
- entry = chars.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
- if (entry.count == 0) {
- // Fill in estimated value if HAL does not list it
- chars.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, rawOpaqueSizes);
- derivedCharKeys.push(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
- }
- }
-
- // Check if HAL supports any RAW output, if so, fill in postRawSensitivityBoost range
- if (supportAnyRaw) {
- int32_t defaultRange[2] = {100, 100};
- entry = chars.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
- if (entry.count == 0) {
- // Fill in default value (100, 100)
- chars.update(
- ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
- defaultRange, 2);
- derivedCharKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
- // Actual request/results will be derived by camera device.
- derivedRequestKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
- derivedResultKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
- }
- }
- }
-
- // Add those newly added keys to AVAILABLE_CHARACTERISTICS_KEYS
- // This has to be done at this end of this function.
- if (derivedCharKeys.size() > 0) {
- appendAvailableKeys(
- chars, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, derivedCharKeys);
- }
- if (derivedRequestKeys.size() > 0) {
- appendAvailableKeys(
- chars, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, derivedRequestKeys);
- }
- if (derivedResultKeys.size() > 0) {
- appendAvailableKeys(
- chars, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, derivedResultKeys);
- }
- return;
-}
-
-void CameraModule::appendAvailableKeys(CameraMetadata &chars,
- int32_t keyTag, const Vector<int32_t>& appendKeys) {
- camera_metadata_entry entry = chars.find(keyTag);
- Vector<int32_t> availableKeys;
- availableKeys.setCapacity(entry.count + appendKeys.size());
- for (size_t i = 0; i < entry.count; i++) {
- availableKeys.push(entry.data.i32[i]);
- }
- for (size_t i = 0; i < appendKeys.size(); i++) {
- availableKeys.push(appendKeys[i]);
- }
- chars.update(keyTag, availableKeys);
-}
-
-CameraModule::CameraModule(camera_module_t *module) : mNumberOfCameras(0) {
- if (module == NULL) {
- ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
- assert(0);
- }
- mModule = module;
-}
-
-CameraModule::~CameraModule()
-{
- while (mCameraInfoMap.size() > 0) {
- camera_info cameraInfo = mCameraInfoMap.editValueAt(0);
- if (cameraInfo.static_camera_characteristics != NULL) {
- free_camera_metadata(
- const_cast<camera_metadata_t*>(cameraInfo.static_camera_characteristics));
- }
- mCameraInfoMap.removeItemsAt(0);
- }
-
- while (mPhysicalCameraInfoMap.size() > 0) {
- camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0);
- if (metadata != NULL) {
- free_camera_metadata(metadata);
- }
- mPhysicalCameraInfoMap.removeItemsAt(0);
- }
-}
-
-int CameraModule::init() {
- ATRACE_CALL();
- int res = OK;
- if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 &&
- mModule->init != NULL) {
- ATRACE_BEGIN("camera_module->init");
- res = mModule->init();
- ATRACE_END();
- }
- mNumberOfCameras = getNumberOfCameras();
- mCameraInfoMap.setCapacity(mNumberOfCameras);
- return res;
-}
-
-int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) {
- ATRACE_CALL();
- Mutex::Autolock lock(mCameraInfoLock);
- if (cameraId < 0) {
- ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
- return -EINVAL;
- }
-
- // Only override static_camera_characteristics for API2 devices
- int apiVersion = mModule->common.module_api_version;
- if (apiVersion < CAMERA_MODULE_API_VERSION_2_0) {
- int ret;
- ATRACE_BEGIN("camera_module->get_camera_info");
- ret = mModule->get_camera_info(cameraId, info);
- // Fill in this so CameraService won't be confused by
- // possibly 0 device_version
- info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
- ATRACE_END();
- return ret;
- }
-
- ssize_t index = mCameraInfoMap.indexOfKey(cameraId);
- if (index == NAME_NOT_FOUND) {
- // Get camera info from raw module and cache it
- camera_info rawInfo, cameraInfo;
- ATRACE_BEGIN("camera_module->get_camera_info");
- int ret = mModule->get_camera_info(cameraId, &rawInfo);
- ATRACE_END();
- if (ret != 0) {
- return ret;
- }
- int deviceVersion = rawInfo.device_version;
- if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_0) {
- // static_camera_characteristics is invalid
- *info = rawInfo;
- return ret;
- }
- CameraMetadata m;
- m.append(rawInfo.static_camera_characteristics);
- deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
- cameraInfo = rawInfo;
- cameraInfo.static_camera_characteristics = m.release();
- index = mCameraInfoMap.add(cameraId, cameraInfo);
- }
-
- assert(index != NAME_NOT_FOUND);
- // return the cached camera info
- *info = mCameraInfoMap[index];
- return OK;
-}
-
-int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo) {
- ATRACE_CALL();
- Mutex::Autolock lock(mCameraInfoLock);
- if (physicalCameraId < mNumberOfCameras) {
- ALOGE("%s: Invalid physical camera ID %d", __FUNCTION__, physicalCameraId);
- return -EINVAL;
- }
-
- // Only query physical camera info for 2.5 version for newer
- int apiVersion = mModule->common.module_api_version;
- if (apiVersion < CAMERA_MODULE_API_VERSION_2_5) {
- ALOGE("%s: Module version must be at least 2.5 to handle getPhysicalCameraInfo",
- __FUNCTION__);
- return -ENODEV;
- }
- if (mModule->get_physical_camera_info == nullptr) {
- ALOGE("%s: get_physical_camera is NULL for module version 2.5", __FUNCTION__);
- return -EINVAL;
- }
-
- ssize_t index = mPhysicalCameraInfoMap.indexOfKey(physicalCameraId);
- if (index == NAME_NOT_FOUND) {
- // Get physical camera characteristics, and cache it
- camera_metadata_t *info = nullptr;
- ATRACE_BEGIN("camera_module->get_physical_camera_info");
- int ret = mModule->get_physical_camera_info(physicalCameraId, &info);
- ATRACE_END();
- if (ret != 0) {
- return ret;
- }
-
- // The camera_metadata_t returned by get_physical_camera_info could be using
- // more memory than necessary due to unused reserved space. Reduce the
- // size by appending it to a new CameraMetadata object, which internally
- // calls resizeIfNeeded.
- CameraMetadata m;
- m.append(info);
- camera_metadata_t* derivedMetadata = m.release();
- index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata);
- }
-
- assert(index != NAME_NOT_FOUND);
- *physicalInfo = mPhysicalCameraInfoMap[index];
- return OK;
-}
-
-int CameraModule::getDeviceVersion(int cameraId) {
- ssize_t index = mDeviceVersionMap.indexOfKey(cameraId);
- if (index == NAME_NOT_FOUND) {
- int deviceVersion;
- if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
- struct camera_info info;
- getCameraInfo(cameraId, &info);
- deviceVersion = info.device_version;
- } else {
- deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
- }
- index = mDeviceVersionMap.add(cameraId, deviceVersion);
- }
- assert(index != NAME_NOT_FOUND);
- return mDeviceVersionMap[index];
-}
-
-int CameraModule::open(const char* id, struct hw_device_t** device) {
- int res;
- ATRACE_BEGIN("camera_module->open");
- res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
- ATRACE_END();
- return res;
-}
-
-bool CameraModule::isOpenLegacyDefined() const {
- if (getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_3) {
- return false;
- }
- return mModule->open_legacy != NULL;
-}
-
-int CameraModule::openLegacy(
- const char* id, uint32_t halVersion, struct hw_device_t** device) {
- int res;
- ATRACE_BEGIN("camera_module->open_legacy");
- res = mModule->open_legacy(&mModule->common, id, halVersion, device);
- ATRACE_END();
- return res;
-}
-
-int CameraModule::getNumberOfCameras() {
- int numCameras;
- ATRACE_BEGIN("camera_module->get_number_of_cameras");
- numCameras = mModule->get_number_of_cameras();
- ATRACE_END();
- return numCameras;
-}
-
-int CameraModule::setCallbacks(const camera_module_callbacks_t *callbacks) {
- int res = OK;
- ATRACE_BEGIN("camera_module->set_callbacks");
- if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
- res = mModule->set_callbacks(callbacks);
- }
- ATRACE_END();
- return res;
-}
-
-bool CameraModule::isVendorTagDefined() const {
- return mModule->get_vendor_tag_ops != NULL;
-}
-
-void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) {
- if (mModule->get_vendor_tag_ops) {
- ATRACE_BEGIN("camera_module->get_vendor_tag_ops");
- mModule->get_vendor_tag_ops(ops);
- ATRACE_END();
- }
-}
-
-bool CameraModule::isSetTorchModeSupported() const {
- if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
- if (mModule->set_torch_mode == NULL) {
- ALOGE("%s: Module 2.4 device must support set torch API!",
- __FUNCTION__);
- return false;
- }
- return true;
- }
- return false;
-}
-
-int CameraModule::setTorchMode(const char* camera_id, bool enable) {
- int res = INVALID_OPERATION;
- if (mModule->set_torch_mode != NULL) {
- ATRACE_BEGIN("camera_module->set_torch_mode");
- res = mModule->set_torch_mode(camera_id, enable);
- ATRACE_END();
- }
- return res;
-}
-
-int CameraModule::isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams) {
- int res = INVALID_OPERATION;
- if (mModule->is_stream_combination_supported != NULL) {
- ATRACE_BEGIN("camera_module->is_stream_combination_supported");
- res = mModule->is_stream_combination_supported(cameraId, streams);
- ATRACE_END();
- }
- return res;
-}
-
-void CameraModule::notifyDeviceStateChange(uint64_t deviceState) {
- if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_5 &&
- mModule->notify_device_state_change != NULL) {
- ATRACE_BEGIN("camera_module->notify_device_state_change");
- ALOGI("%s: calling notify_device_state_change with state %" PRId64, __FUNCTION__,
- deviceState);
- mModule->notify_device_state_change(deviceState);
- ATRACE_END();
- }
-}
-
-bool CameraModule::isLogicalMultiCamera(
- const common::V1_0::helper::CameraMetadata& metadata,
- std::unordered_set<std::string>* physicalCameraIds) {
- if (physicalCameraIds == nullptr) {
- ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__);
- return false;
- }
-
- bool isLogicalMultiCamera = false;
- camera_metadata_ro_entry_t capabilities =
- metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
- for (size_t i = 0; i < capabilities.count; i++) {
- if (capabilities.data.u8[i] ==
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
- isLogicalMultiCamera = true;
- break;
- }
- }
-
- if (isLogicalMultiCamera) {
- camera_metadata_ro_entry_t entry =
- metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
- const uint8_t* ids = entry.data.u8;
- size_t start = 0;
- for (size_t i = 0; i < entry.count; ++i) {
- if (ids[i] == '\0') {
- if (start != i) {
- const char* physicalId = reinterpret_cast<const char*>(ids+start);
- physicalCameraIds->emplace(physicalId);
- }
- start = i + 1;
- }
- }
- }
- return isLogicalMultiCamera;
-}
-
-status_t CameraModule::filterOpenErrorCode(status_t err) {
- switch(err) {
- case NO_ERROR:
- case -EBUSY:
- case -EINVAL:
- case -EUSERS:
- return err;
- default:
- break;
- }
- return -ENODEV;
-}
-
-void CameraModule::removeCamera(int cameraId) {
- // Skip HAL1 devices which isn't cached in mCameraInfoMap and don't advertise
- // static_camera_characteristics
- if (getDeviceVersion(cameraId) >= CAMERA_DEVICE_API_VERSION_3_0) {
- std::unordered_set<std::string> physicalIds;
- camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
- mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
- common::V1_0::helper::CameraMetadata hidlMetadata(metadata);
-
- if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
- for (const auto& id : physicalIds) {
- int idInt = std::stoi(id);
- if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
- free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
- mPhysicalCameraInfoMap.removeItem(idInt);
- } else {
- ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
- __FUNCTION__, id.c_str());
- }
- }
- }
- }
-
- mCameraInfoMap.removeItem(cameraId);
- mDeviceVersionMap.removeItem(cameraId);
-}
-
-uint16_t CameraModule::getModuleApiVersion() const {
- return mModule->common.module_api_version;
-}
-
-const char* CameraModule::getModuleName() const {
- return mModule->common.name;
-}
-
-uint16_t CameraModule::getHalApiVersion() const {
- return mModule->common.hal_api_version;
-}
-
-const char* CameraModule::getModuleAuthor() const {
- return mModule->common.author;
-}
-
-void* CameraModule::getDso() {
- return mModule->common.dso;
-}
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/CameraParameters.cpp b/camera/common/1.0/default/CameraParameters.cpp
deleted file mode 100644
index e707b08..0000000
--- a/camera/common/1.0/default/CameraParameters.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
-**
-** Copyright 2008, The Android Open 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 "CameraParams"
-#include <log/log.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "CameraParameters.h"
-#include <system/graphics.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-// Parameter keys to communicate between camera application and driver.
-const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
-const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
-const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
-const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range";
-const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values";
-const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
-const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
-const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
-const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
-const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
-const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
-const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
-const char CameraParameters::KEY_ROTATION[] = "rotation";
-const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
-const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
-const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
-const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
-const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method";
-const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
-const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
-const char CameraParameters::KEY_EFFECT[] = "effect";
-const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
-const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
-const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
-const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
-const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
-const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
-const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
-const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
-const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
-const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
-const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
-const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
-const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
-const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
-const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
-const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
-const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
-const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
-const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
-const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
-const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
-const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] = "auto-whitebalance-lock-supported";
-const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
-const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
-const char CameraParameters::KEY_ZOOM[] = "zoom";
-const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
-const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
-const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
-const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
-const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
-const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
-const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
-const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
-const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
-const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
-const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
-const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
-const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
-const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
-const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
-const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
-
-const char CameraParameters::TRUE[] = "true";
-const char CameraParameters::FALSE[] = "false";
-const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
-
-// Values for white balance settings.
-const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
-const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
-const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
-const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
-const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
-const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
-const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
-const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
-
-// Values for effect settings.
-const char CameraParameters::EFFECT_NONE[] = "none";
-const char CameraParameters::EFFECT_MONO[] = "mono";
-const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
-const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
-const char CameraParameters::EFFECT_SEPIA[] = "sepia";
-const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
-const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
-const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
-const char CameraParameters::EFFECT_AQUA[] = "aqua";
-
-// Values for antibanding settings.
-const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
-const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
-const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
-const char CameraParameters::ANTIBANDING_OFF[] = "off";
-
-// Values for flash mode settings.
-const char CameraParameters::FLASH_MODE_OFF[] = "off";
-const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
-const char CameraParameters::FLASH_MODE_ON[] = "on";
-const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
-const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
-
-// Values for scene mode settings.
-const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
-const char CameraParameters::SCENE_MODE_ACTION[] = "action";
-const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
-const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
-const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
-const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
-const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
-const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
-const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
-const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
-const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
-const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
-const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
-const char CameraParameters::SCENE_MODE_PARTY[] = "party";
-const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
-const char CameraParameters::SCENE_MODE_BARCODE[] = "barcode";
-const char CameraParameters::SCENE_MODE_HDR[] = "hdr";
-
-const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
-const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
-const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
-const char CameraParameters::PIXEL_FORMAT_YUV420P[] = "yuv420p";
-const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
-const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
-const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
-const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
-const char CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE[] = "android-opaque";
-
-// Values for focus mode settings.
-const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
-const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
-const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
-const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
-const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
-const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
-const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
-
-// Values for light fx settings
-const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light";
-const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range";
-
-CameraParameters::CameraParameters()
- : mMap()
-{
-}
-
-CameraParameters::~CameraParameters()
-{
-}
-
-String8 CameraParameters::flatten() const
-{
- String8 flattened("");
- size_t size = mMap.size();
-
- for (size_t i = 0; i < size; i++) {
- String8 k, v;
- k = mMap.keyAt(i);
- v = mMap.valueAt(i);
-
- flattened += k;
- flattened += "=";
- flattened += v;
- if (i != size-1)
- flattened += ";";
- }
-
- return flattened;
-}
-
-void CameraParameters::unflatten(const String8 ¶ms)
-{
- const char *a = params.string();
- const char *b;
-
- mMap.clear();
-
- for (;;) {
- // Find the bounds of the key name.
- b = strchr(a, '=');
- if (b == 0)
- break;
-
- // Create the key string.
- String8 k(a, (size_t)(b-a));
-
- // Find the value.
- a = b+1;
- b = strchr(a, ';');
- if (b == 0) {
- // If there's no semicolon, this is the last item.
- String8 v(a);
- mMap.add(k, v);
- break;
- }
-
- String8 v(a, (size_t)(b-a));
- mMap.add(k, v);
- a = b+1;
- }
-}
-
-
-void CameraParameters::set(const char *key, const char *value)
-{
- // i think i can do this with strspn()
- if (strchr(key, '=') || strchr(key, ';')) {
- // ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
- return;
- }
-
- if (strchr(value, '=') || strchr(value, ';')) {
- // ALOGE("Value \"%s\"contains invalid character (= or ;)", value);
- return;
- }
-
- mMap.replaceValueFor(String8(key), String8(value));
-}
-
-void CameraParameters::set(const char *key, int value)
-{
- char str[16];
- sprintf(str, "%d", value);
- set(key, str);
-}
-
-void CameraParameters::setFloat(const char *key, float value)
-{
- char str[16]; // 14 should be enough. We overestimate to be safe.
- snprintf(str, sizeof(str), "%g", value);
- set(key, str);
-}
-
-const char *CameraParameters::get(const char *key) const
-{
- String8 v = mMap.valueFor(String8(key));
- if (v.length() == 0)
- return 0;
- return v.string();
-}
-
-int CameraParameters::getInt(const char *key) const
-{
- const char *v = get(key);
- if (v == 0)
- return -1;
- return strtol(v, 0, 0);
-}
-
-float CameraParameters::getFloat(const char *key) const
-{
- const char *v = get(key);
- if (v == 0) return -1;
- return strtof(v, 0);
-}
-
-void CameraParameters::remove(const char *key)
-{
- mMap.removeItem(String8(key));
-}
-
-// Parse string like "640x480" or "10000,20000"
-static int parse_pair(const char *str, int *first, int *second, char delim,
- char **endptr = NULL)
-{
- // Find the first integer.
- char *end;
- int w = (int)strtol(str, &end, 10);
- // If a delimeter does not immediately follow, give up.
- if (*end != delim) {
- ALOGE("Cannot find delimeter (%c) in str=%s", delim, str);
- return -1;
- }
-
- // Find the second integer, immediately after the delimeter.
- int h = (int)strtol(end+1, &end, 10);
-
- *first = w;
- *second = h;
-
- if (endptr) {
- *endptr = end;
- }
-
- return 0;
-}
-
-static void parseSizesList(const char *sizesStr, Vector<Size> &sizes)
-{
- if (sizesStr == 0) {
- return;
- }
-
- char *sizeStartPtr = (char *)sizesStr;
-
- while (true) {
- int width, height;
- int success = parse_pair(sizeStartPtr, &width, &height, 'x',
- &sizeStartPtr);
- if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) {
- ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr);
- return;
- }
- sizes.push(Size(width, height));
-
- if (*sizeStartPtr == '\0') {
- return;
- }
- sizeStartPtr++;
- }
-}
-
-void CameraParameters::setPreviewSize(int width, int height)
-{
- char str[32];
- sprintf(str, "%dx%d", width, height);
- set(KEY_PREVIEW_SIZE, str);
-}
-
-void CameraParameters::getPreviewSize(int *width, int *height) const
-{
- *width = *height = -1;
- // Get the current string, if it doesn't exist, leave the -1x-1
- const char *p = get(KEY_PREVIEW_SIZE);
- if (p == 0) return;
- parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getPreferredPreviewSizeForVideo(int *width, int *height) const
-{
- *width = *height = -1;
- const char *p = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
- if (p == 0) return;
- parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getSupportedPreviewSizes(Vector<Size> &sizes) const
-{
- const char *previewSizesStr = get(KEY_SUPPORTED_PREVIEW_SIZES);
- parseSizesList(previewSizesStr, sizes);
-}
-
-void CameraParameters::setVideoSize(int width, int height)
-{
- char str[32];
- sprintf(str, "%dx%d", width, height);
- set(KEY_VIDEO_SIZE, str);
-}
-
-void CameraParameters::getVideoSize(int *width, int *height) const
-{
- *width = *height = -1;
- const char *p = get(KEY_VIDEO_SIZE);
- if (p == 0) return;
- parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getSupportedVideoSizes(Vector<Size> &sizes) const
-{
- const char *videoSizesStr = get(KEY_SUPPORTED_VIDEO_SIZES);
- parseSizesList(videoSizesStr, sizes);
-}
-
-void CameraParameters::setPreviewFrameRate(int fps)
-{
- set(KEY_PREVIEW_FRAME_RATE, fps);
-}
-
-int CameraParameters::getPreviewFrameRate() const
-{
- return getInt(KEY_PREVIEW_FRAME_RATE);
-}
-
-void CameraParameters::getPreviewFpsRange(int *min_fps, int *max_fps) const
-{
- *min_fps = *max_fps = -1;
- const char *p = get(KEY_PREVIEW_FPS_RANGE);
- if (p == 0) return;
- parse_pair(p, min_fps, max_fps, ',');
-}
-
-void CameraParameters::setPreviewFormat(const char *format)
-{
- set(KEY_PREVIEW_FORMAT, format);
-}
-
-const char *CameraParameters::getPreviewFormat() const
-{
- return get(KEY_PREVIEW_FORMAT);
-}
-
-void CameraParameters::setPictureSize(int width, int height)
-{
- char str[32];
- sprintf(str, "%dx%d", width, height);
- set(KEY_PICTURE_SIZE, str);
-}
-
-void CameraParameters::getPictureSize(int *width, int *height) const
-{
- *width = *height = -1;
- // Get the current string, if it doesn't exist, leave the -1x-1
- const char *p = get(KEY_PICTURE_SIZE);
- if (p == 0) return;
- parse_pair(p, width, height, 'x');
-}
-
-void CameraParameters::getSupportedPictureSizes(Vector<Size> &sizes) const
-{
- const char *pictureSizesStr = get(KEY_SUPPORTED_PICTURE_SIZES);
- parseSizesList(pictureSizesStr, sizes);
-}
-
-void CameraParameters::setPictureFormat(const char *format)
-{
- set(KEY_PICTURE_FORMAT, format);
-}
-
-const char *CameraParameters::getPictureFormat() const
-{
- return get(KEY_PICTURE_FORMAT);
-}
-
-void CameraParameters::dump() const
-{
- ALOGD("dump: mMap.size = %zu", mMap.size());
- for (size_t i = 0; i < mMap.size(); i++) {
- String8 k, v;
- k = mMap.keyAt(i);
- v = mMap.valueAt(i);
- ALOGD("%s: %s\n", k.string(), v.string());
- }
-}
-
-status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const
-{
- const size_t SIZE = 256;
- char buffer[SIZE];
- String8 result;
- snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size());
- result.append(buffer);
- for (size_t i = 0; i < mMap.size(); i++) {
- String8 k, v;
- k = mMap.keyAt(i);
- v = mMap.valueAt(i);
- snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
- result.append(buffer);
- }
- write(fd, result.string(), result.size());
- return NO_ERROR;
-}
-
-void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {
- const char* supportedPreviewFormats =
- get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
-
- if (supportedPreviewFormats == NULL) {
- ALOGW("%s: No supported preview formats.", __FUNCTION__);
- return;
- }
-
- String8 fmtStr(supportedPreviewFormats);
- char* prevFmts = fmtStr.lockBuffer(fmtStr.size());
-
- char* savePtr;
- char* fmt = strtok_r(prevFmts, ",", &savePtr);
- while (fmt) {
- int actual = previewFormatToEnum(fmt);
- if (actual != -1) {
- formats.add(actual);
- }
- fmt = strtok_r(NULL, ",", &savePtr);
- }
- fmtStr.unlockBuffer(fmtStr.size());
-}
-
-
-int CameraParameters::previewFormatToEnum(const char* format) {
- return
- !format ?
- HAL_PIXEL_FORMAT_YCrCb_420_SP :
- !strcmp(format, PIXEL_FORMAT_YUV422SP) ?
- HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
- !strcmp(format, PIXEL_FORMAT_YUV420SP) ?
- HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
- !strcmp(format, PIXEL_FORMAT_YUV422I) ?
- HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
- !strcmp(format, PIXEL_FORMAT_YUV420P) ?
- HAL_PIXEL_FORMAT_YV12 : // YV12
- !strcmp(format, PIXEL_FORMAT_RGB565) ?
- HAL_PIXEL_FORMAT_RGB_565 : // RGB565
- !strcmp(format, PIXEL_FORMAT_RGBA8888) ?
- HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
- !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ?
- HAL_PIXEL_FORMAT_RAW16 : // Raw sensor data
- -1;
-}
-
-bool CameraParameters::isEmpty() const {
- return mMap.isEmpty();
-}
-
-};
-};
-};
-};
-};
-}; // namespace android
diff --git a/camera/common/1.0/default/Exif.cpp b/camera/common/1.0/default/Exif.cpp
deleted file mode 100644
index 413b6bb..0000000
--- a/camera/common/1.0/default/Exif.cpp
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open 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 "CamComm1.0-Exif"
-#define ATRACE_TAG ATRACE_TAG_CAMERA
-//#define LOG_NDEBUG 0
-
-#include <android/log.h>
-
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <string>
-#include <vector>
-
-#include "Exif.h"
-
-extern "C" {
-#include <libexif/exif-data.h>
-}
-
-namespace std {
-
-template <>
-struct default_delete<ExifEntry> {
- inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
-};
-
-} // namespace std
-
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-
-class ExifUtilsImpl : public ExifUtils {
- public:
- ExifUtilsImpl();
-
- virtual ~ExifUtilsImpl();
-
- // Initialize() can be called multiple times. The setting of Exif tags will be
- // cleared.
- virtual bool initialize();
-
- // set all known fields from a metadata structure
- virtual bool setFromMetadata(const CameraMetadata& metadata,
- const size_t imageWidth,
- const size_t imageHeight);
-
- // sets the len aperture.
- // Returns false if memory allocation fails.
- virtual bool setAperture(uint32_t numerator, uint32_t denominator);
-
- // sets the value of brightness.
- // Returns false if memory allocation fails.
- virtual bool setBrightness(int32_t numerator, int32_t denominator);
-
- // sets the color space.
- // Returns false if memory allocation fails.
- virtual bool setColorSpace(uint16_t color_space);
-
- // sets the information to compressed data.
- // Returns false if memory allocation fails.
- virtual bool setComponentsConfiguration(const std::string& components_configuration);
-
- // sets the compression scheme used for the image data.
- // Returns false if memory allocation fails.
- virtual bool setCompression(uint16_t compression);
-
- // sets image contrast.
- // Returns false if memory allocation fails.
- virtual bool setContrast(uint16_t contrast);
-
- // sets the date and time of image last modified. It takes local time. The
- // name of the tag is DateTime in IFD0.
- // Returns false if memory allocation fails.
- virtual bool setDateTime(const struct tm& t);
-
- // sets the image description.
- // Returns false if memory allocation fails.
- virtual bool setDescription(const std::string& description);
-
- // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
- // was not used.
- // Returns false if memory allocation fails.
- virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
-
- // sets the exposure bias.
- // Returns false if memory allocation fails.
- virtual bool setExposureBias(int32_t numerator, int32_t denominator);
-
- // sets the exposure mode set when the image was shot.
- // Returns false if memory allocation fails.
- virtual bool setExposureMode(uint16_t exposure_mode);
-
- // sets the program used by the camera to set exposure when the picture is
- // taken.
- // Returns false if memory allocation fails.
- virtual bool setExposureProgram(uint16_t exposure_program);
-
- // sets the exposure time, given in seconds.
- // Returns false if memory allocation fails.
- virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
-
- // sets the status of flash.
- // Returns false if memory allocation fails.
- virtual bool setFlash(uint16_t flash);
-
- // sets the F number.
- // Returns false if memory allocation fails.
- virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
-
- // sets the focal length of lens used to take the image in millimeters.
- // Returns false if memory allocation fails.
- virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
-
- // sets the degree of overall image gain adjustment.
- // Returns false if memory allocation fails.
- virtual bool setGainControl(uint16_t gain_control);
-
- // sets the altitude in meters.
- // Returns false if memory allocation fails.
- virtual bool setGpsAltitude(double altitude);
-
- // sets the latitude with degrees minutes seconds format.
- // Returns false if memory allocation fails.
- virtual bool setGpsLatitude(double latitude);
-
- // sets the longitude with degrees minutes seconds format.
- // Returns false if memory allocation fails.
- virtual bool setGpsLongitude(double longitude);
-
- // sets GPS processing method.
- // Returns false if memory allocation fails.
- virtual bool setGpsProcessingMethod(const std::string& method);
-
- // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
- // Returns false if memory allocation fails.
- virtual bool setGpsTimestamp(const struct tm& t);
-
- // sets the length (number of rows) of main image.
- // Returns false if memory allocation fails.
- virtual bool setImageHeight(uint32_t length);
-
- // sets the width (number of columes) of main image.
- // Returns false if memory allocation fails.
- virtual bool setImageWidth(uint32_t width);
-
- // sets the ISO speed.
- // Returns false if memory allocation fails.
- virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
-
- // sets the kind of light source.
- // Returns false if memory allocation fails.
- virtual bool setLightSource(uint16_t light_source);
-
- // sets the smallest F number of the lens.
- // Returns false if memory allocation fails.
- virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
-
- // sets the metering mode.
- // Returns false if memory allocation fails.
- virtual bool setMeteringMode(uint16_t metering_mode);
-
- // sets image orientation.
- // Returns false if memory allocation fails.
- virtual bool setOrientation(uint16_t orientation);
-
- // sets the unit for measuring XResolution and YResolution.
- // Returns false if memory allocation fails.
- virtual bool setResolutionUnit(uint16_t resolution_unit);
-
- // sets image saturation.
- // Returns false if memory allocation fails.
- virtual bool setSaturation(uint16_t saturation);
-
- // sets the type of scene that was shot.
- // Returns false if memory allocation fails.
- virtual bool setSceneCaptureType(uint16_t type);
-
- // sets image sharpness.
- // Returns false if memory allocation fails.
- virtual bool setSharpness(uint16_t sharpness);
-
- // sets the shutter speed.
- // Returns false if memory allocation fails.
- virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
-
- // sets the distance to the subject, given in meters.
- // Returns false if memory allocation fails.
- virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
-
- // sets the fractions of seconds for the <DateTime> tag.
- // Returns false if memory allocation fails.
- virtual bool setSubsecTime(const std::string& subsec_time);
-
- // sets the white balance mode set when the image was shot.
- // Returns false if memory allocation fails.
- virtual bool setWhiteBalance(uint16_t white_balance);
-
- // sets the number of pixels per resolution unit in the image width.
- // Returns false if memory allocation fails.
- virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
-
- // sets the position of chrominance components in relation to the luminance
- // component.
- // Returns false if memory allocation fails.
- virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
-
- // sets the number of pixels per resolution unit in the image length.
- // Returns false if memory allocation fails.
- virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
-
- // sets the manufacturer of camera.
- // Returns false if memory allocation fails.
- virtual bool setMake(const std::string& make);
-
- // sets the model number of camera.
- // Returns false if memory allocation fails.
- virtual bool setModel(const std::string& model);
-
- // Generates APP1 segment.
- // Returns false if generating APP1 segment fails.
- virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size);
-
- // Gets buffer of APP1 segment. This method must be called only after calling
- // GenerateAPP1().
- virtual const uint8_t* getApp1Buffer();
-
- // Gets length of APP1 segment. This method must be called only after calling
- // GenerateAPP1().
- virtual unsigned int getApp1Length();
-
- protected:
- // sets the version of this standard supported.
- // Returns false if memory allocation fails.
- virtual bool setExifVersion(const std::string& exif_version);
-
-
- // Resets the pointers and memories.
- virtual void reset();
-
- // Adds a variable length tag to |exif_data_|. It will remove the original one
- // if the tag exists.
- // Returns the entry of the tag. The reference count of returned ExifEntry is
- // two.
- virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd,
- ExifTag tag,
- ExifFormat format,
- uint64_t components,
- unsigned int size);
-
- // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
- // the tag exists.
- // Returns the entry of the tag. It adds one reference count to returned
- // ExifEntry.
- virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
-
- // Helpe functions to add exif data with different types.
- virtual bool setShort(ExifIfd ifd,
- ExifTag tag,
- uint16_t value,
- const std::string& msg);
-
- virtual bool setLong(ExifIfd ifd,
- ExifTag tag,
- uint32_t value,
- const std::string& msg);
-
- virtual bool setRational(ExifIfd ifd,
- ExifTag tag,
- uint32_t numerator,
- uint32_t denominator,
- const std::string& msg);
-
- virtual bool setSRational(ExifIfd ifd,
- ExifTag tag,
- int32_t numerator,
- int32_t denominator,
- const std::string& msg);
-
- virtual bool setString(ExifIfd ifd,
- ExifTag tag,
- ExifFormat format,
- const std::string& buffer,
- const std::string& msg);
-
- // Destroys the buffer of APP1 segment if exists.
- virtual void destroyApp1();
-
- // The Exif data (APP1). Owned by this class.
- ExifData* exif_data_;
- // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
- // owned by this class.
- uint8_t* app1_buffer_;
- // The length of |app1_buffer_|.
- unsigned int app1_length_;
-
-};
-
-#define SET_SHORT(ifd, tag, value) \
- do { \
- if (setShort(ifd, tag, value, #tag) == false) \
- return false; \
- } while (0);
-
-#define SET_LONG(ifd, tag, value) \
- do { \
- if (setLong(ifd, tag, value, #tag) == false) \
- return false; \
- } while (0);
-
-#define SET_RATIONAL(ifd, tag, numerator, denominator) \
- do { \
- if (setRational(ifd, tag, numerator, denominator, #tag) == false) \
- return false; \
- } while (0);
-
-#define SET_SRATIONAL(ifd, tag, numerator, denominator) \
- do { \
- if (setSRational(ifd, tag, numerator, denominator, #tag) == false) \
- return false; \
- } while (0);
-
-#define SET_STRING(ifd, tag, format, buffer) \
- do { \
- if (setString(ifd, tag, format, buffer, #tag) == false) \
- return false; \
- } while (0);
-
-// This comes from the Exif Version 2.2 standard table 6.
-const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
-
-static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
- // Take the integer part of |num|.
- ExifLong degrees = static_cast<ExifLong>(num);
- ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
- ExifLong microseconds =
- static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
- exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
- exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
- {minutes, 1});
- exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
- {microseconds, 1000000});
-}
-
-ExifUtils *ExifUtils::create() {
- return new ExifUtilsImpl();
-}
-
-ExifUtils::~ExifUtils() {
-}
-
-ExifUtilsImpl::ExifUtilsImpl()
- : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
-
-ExifUtilsImpl::~ExifUtilsImpl() {
- reset();
-}
-
-
-bool ExifUtilsImpl::initialize() {
- reset();
- exif_data_ = exif_data_new();
- if (exif_data_ == nullptr) {
- ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
- return false;
- }
- // set the image options.
- exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
- exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
- exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
-
- // set exif version to 2.2.
- if (!setExifVersion("0220")) {
- return false;
- }
-
- return true;
-}
-
-bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
- SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator,
- denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
- return true;
-}
-
-bool ExifUtilsImpl::setComponentsConfiguration(
- const std::string& components_configuration) {
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION,
- EXIF_FORMAT_UNDEFINED, components_configuration);
- return true;
-}
-
-bool ExifUtilsImpl::setCompression(uint16_t compression) {
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
- return true;
-}
-
-bool ExifUtilsImpl::setContrast(uint16_t contrast) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
- return true;
-}
-
-bool ExifUtilsImpl::setDateTime(const struct tm& t) {
- // The length is 20 bytes including NULL for termination in Exif standard.
- char str[20];
- int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i",
- t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour,
- t.tm_min, t.tm_sec);
- if (result != sizeof(str) - 1) {
- ALOGW("%s: Input time is invalid", __FUNCTION__);
- return false;
- }
- std::string buffer(str);
- SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII,
- buffer);
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII,
- buffer);
- return true;
-}
-
-bool ExifUtilsImpl::setDescription(const std::string& description) {
- SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII,
- description);
- return true;
-}
-
-bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator,
- denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
- SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator,
- denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
- return true;
-}
-
-bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
- return true;
-}
-
-bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setFlash(uint16_t flash) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
- return true;
-}
-
-bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
- return true;
-}
-
-bool ExifUtilsImpl::setGpsAltitude(double altitude) {
- ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
- std::unique_ptr<ExifEntry> refEntry =
- addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
- if (!refEntry) {
- ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
- return false;
- }
- if (altitude >= 0) {
- *refEntry->data = 0;
- } else {
- *refEntry->data = 1;
- altitude *= -1;
- }
-
- ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
- std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
- EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
- if (!entry) {
- exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
- ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
- return false;
- }
- exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
- {static_cast<ExifLong>(altitude * 1000), 1000});
-
- return true;
-}
-
-bool ExifUtilsImpl::setGpsLatitude(double latitude) {
- const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
- std::unique_ptr<ExifEntry> refEntry =
- addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
- if (!refEntry) {
- ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
- return false;
- }
- if (latitude >= 0) {
- memcpy(refEntry->data, "N", sizeof("N"));
- } else {
- memcpy(refEntry->data, "S", sizeof("S"));
- latitude *= -1;
- }
-
- const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
- std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
- EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
- if (!entry) {
- exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
- ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
- return false;
- }
- setLatitudeOrLongitudeData(entry->data, latitude);
-
- return true;
-}
-
-bool ExifUtilsImpl::setGpsLongitude(double longitude) {
- ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
- std::unique_ptr<ExifEntry> refEntry =
- addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
- if (!refEntry) {
- ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
- return false;
- }
- if (longitude >= 0) {
- memcpy(refEntry->data, "E", sizeof("E"));
- } else {
- memcpy(refEntry->data, "W", sizeof("W"));
- longitude *= -1;
- }
-
- ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
- std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
- EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
- if (!entry) {
- exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
- ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
- return false;
- }
- setLatitudeOrLongitudeData(entry->data, longitude);
-
- return true;
-}
-
-bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
- std::string buffer =
- std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
- SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
- EXIF_FORMAT_UNDEFINED, buffer);
- return true;
-}
-
-bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
- const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
- const size_t kGpsDateStampSize = 11;
- std::unique_ptr<ExifEntry> entry =
- addVariableLengthEntry(EXIF_IFD_GPS, dateTag, EXIF_FORMAT_ASCII,
- kGpsDateStampSize, kGpsDateStampSize);
- if (!entry) {
- ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
- return false;
- }
- int result =
- snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize,
- "%04i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
- if (result != kGpsDateStampSize - 1) {
- ALOGW("%s: Input time is invalid", __FUNCTION__);
- return false;
- }
-
- const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
- entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
- 3 * sizeof(ExifRational));
- if (!entry) {
- ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
- return false;
- }
- exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
- {static_cast<ExifLong>(t.tm_hour), 1});
- exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
- {static_cast<ExifLong>(t.tm_min), 1});
- exif_set_rational(entry->data + 2 * sizeof(ExifRational),
- EXIF_BYTE_ORDER_INTEL,
- {static_cast<ExifLong>(t.tm_sec), 1});
-
- return true;
-}
-
-bool ExifUtilsImpl::setImageHeight(uint32_t length) {
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
- SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
- return true;
-}
-
-bool ExifUtilsImpl::setImageWidth(uint32_t width) {
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
- SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
- return true;
-}
-
-bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
- return true;
-}
-
-bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
- return true;
-}
-
-bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator,
- denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
- return true;
-}
-
-bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
- /*
- * Orientation value:
- * 1 2 3 4 5 6 7 8
- *
- * 888888 888888 88 88 8888888888 88 88 8888888888
- * 88 88 88 88 88 88 88 88 88 88 88 88
- * 8888 8888 8888 8888 88 8888888888 8888888888 88
- * 88 88 88 88
- * 88 88 888888 888888
- */
- int value = 1;
- switch (orientation) {
- case 90:
- value = 6;
- break;
- case 180:
- value = 3;
- break;
- case 270:
- value = 8;
- break;
- default:
- break;
- }
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);
- return true;
-}
-
-bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
- return true;
-}
-
-bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
- return true;
-}
-
-bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
- return true;
-}
-
-bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
- return true;
-}
-
-bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
- SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator,
- denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator,
- denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII,
- subsec_time);
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII,
- subsec_time);
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII,
- subsec_time);
- return true;
-}
-
-bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
- SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
- return true;
-}
-
-bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
- SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
- return true;
-}
-
-bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
- SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
- return true;
-}
-
-bool ExifUtilsImpl::generateApp1(const void* thumbnail_buffer, uint32_t size) {
- destroyApp1();
- exif_data_->data = const_cast<uint8_t*>(static_cast<const uint8_t*>(thumbnail_buffer));
- exif_data_->size = size;
- // Save the result into |app1_buffer_|.
- exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
- if (!app1_length_) {
- ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
- return false;
- }
- /*
- * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
- * be smaller than 65533 because there are two bytes for segment size field.
- */
- if (app1_length_ > 65533) {
- destroyApp1();
- ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
- return false;
- }
- return true;
-}
-
-const uint8_t* ExifUtilsImpl::getApp1Buffer() {
- return app1_buffer_;
-}
-
-unsigned int ExifUtilsImpl::getApp1Length() {
- return app1_length_;
-}
-
-bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
- SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
- return true;
-}
-
-bool ExifUtilsImpl::setMake(const std::string& make) {
- SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
- return true;
-}
-
-bool ExifUtilsImpl::setModel(const std::string& model) {
- SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
- return true;
-}
-
-void ExifUtilsImpl::reset() {
- destroyApp1();
- if (exif_data_) {
- /*
- * Since we decided to ignore the original APP1, we are sure that there is
- * no thumbnail allocated by libexif. |exif_data_->data| is actually
- * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
- * prevent exif_data_unref() destroy it incorrectly.
- */
- exif_data_->data = nullptr;
- exif_data_->size = 0;
- exif_data_unref(exif_data_);
- exif_data_ = nullptr;
- }
-}
-
-std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd,
- ExifTag tag,
- ExifFormat format,
- uint64_t components,
- unsigned int size) {
- // Remove old entry if exists.
- exif_content_remove_entry(exif_data_->ifd[ifd],
- exif_content_get_entry(exif_data_->ifd[ifd], tag));
- ExifMem* mem = exif_mem_new_default();
- if (!mem) {
- ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
- return nullptr;
- }
- std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
- if (!entry) {
- ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
- exif_mem_unref(mem);
- return nullptr;
- }
- void* tmpBuffer = exif_mem_alloc(mem, size);
- if (!tmpBuffer) {
- ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
- exif_mem_unref(mem);
- return nullptr;
- }
-
- entry->data = static_cast<unsigned char*>(tmpBuffer);
- entry->tag = tag;
- entry->format = format;
- entry->components = components;
- entry->size = size;
-
- exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
- exif_mem_unref(mem);
-
- return entry;
-}
-
-std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
- std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
- if (entry) {
- // exif_content_get_entry() won't ref the entry, so we ref here.
- exif_entry_ref(entry.get());
- return entry;
- }
- entry.reset(exif_entry_new());
- if (!entry) {
- ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
- return nullptr;
- }
- entry->tag = tag;
- exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
- exif_entry_initialize(entry.get(), tag);
- return entry;
-}
-
-bool ExifUtilsImpl::setShort(ExifIfd ifd,
- ExifTag tag,
- uint16_t value,
- const std::string& msg) {
- std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
- if (!entry) {
- ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
- return false;
- }
- exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
- return true;
-}
-
-bool ExifUtilsImpl::setLong(ExifIfd ifd,
- ExifTag tag,
- uint32_t value,
- const std::string& msg) {
- std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
- if (!entry) {
- ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
- return false;
- }
- exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
- return true;
-}
-
-bool ExifUtilsImpl::setRational(ExifIfd ifd,
- ExifTag tag,
- uint32_t numerator,
- uint32_t denominator,
- const std::string& msg) {
- std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
- if (!entry) {
- ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
- return false;
- }
- exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
- {numerator, denominator});
- return true;
-}
-
-bool ExifUtilsImpl::setSRational(ExifIfd ifd,
- ExifTag tag,
- int32_t numerator,
- int32_t denominator,
- const std::string& msg) {
- std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
- if (!entry) {
- ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
- return false;
- }
- exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL,
- {numerator, denominator});
- return true;
-}
-
-bool ExifUtilsImpl::setString(ExifIfd ifd,
- ExifTag tag,
- ExifFormat format,
- const std::string& buffer,
- const std::string& msg) {
- size_t entry_size = buffer.length();
- // Since the exif format is undefined, NULL termination is not necessary.
- if (format == EXIF_FORMAT_ASCII) {
- entry_size++;
- }
- std::unique_ptr<ExifEntry> entry =
- addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
- if (!entry) {
- ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
- return false;
- }
- memcpy(entry->data, buffer.c_str(), entry_size);
- return true;
-}
-
-void ExifUtilsImpl::destroyApp1() {
- /*
- * Since there is no API to access ExifMem in ExifData->priv, we use free
- * here, which is the default free function in libexif. See
- * exif_data_save_data() for detail.
- */
- free(app1_buffer_);
- app1_buffer_ = nullptr;
- app1_length_ = 0;
-}
-
-bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
- const size_t imageWidth,
- const size_t imageHeight) {
- // How precise the float-to-rational conversion for EXIF tags would be.
- constexpr int kRationalPrecision = 10000;
- if (!setImageWidth(imageWidth) ||
- !setImageHeight(imageHeight)) {
- ALOGE("%s: setting image resolution failed.", __FUNCTION__);
- return false;
- }
-
- struct timespec tp;
- struct tm time_info;
- bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
- localtime_r(&tp.tv_sec, &time_info);
- if (!setDateTime(time_info)) {
- ALOGE("%s: setting data time failed.", __FUNCTION__);
- return false;
- }
-
- float focal_length;
- camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
- if (entry.count) {
- focal_length = entry.data.f[0];
-
- if (!setFocalLength(
- static_cast<uint32_t>(focal_length * kRationalPrecision),
- kRationalPrecision)) {
- ALOGE("%s: setting focal length failed.", __FUNCTION__);
- return false;
- }
- } else {
- ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
- }
-
- if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
- entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
- if (entry.count < 3) {
- ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
- return false;
- }
- if (!setGpsLatitude(entry.data.d[0])) {
- ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
- return false;
- }
- if (!setGpsLongitude(entry.data.d[1])) {
- ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
- return false;
- }
- if (!setGpsAltitude(entry.data.d[2])) {
- ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
- return false;
- }
- }
-
- if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
- entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
- std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
- if (!setGpsProcessingMethod(method_str)) {
- ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
- return false;
- }
- }
-
- if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
- entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
- time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
- if (gmtime_r(×tamp, &time_info)) {
- if (!setGpsTimestamp(time_info)) {
- ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
- return false;
- }
- } else {
- ALOGE("%s: Time tranformation failed.", __FUNCTION__);
- return false;
- }
- }
-
- if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
- entry = metadata.find(ANDROID_JPEG_ORIENTATION);
- if (!setOrientation(entry.data.i32[0])) {
- ALOGE("%s: setting orientation failed.", __FUNCTION__);
- return false;
- }
- }
-
- if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
- entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
- // int64_t of nanoseconds
- if (!setExposureTime(entry.data.i64[0],1000000000u)) {
- ALOGE("%s: setting exposure time failed.", __FUNCTION__);
- return false;
- }
- }
-
- if (metadata.exists(ANDROID_LENS_APERTURE)) {
- const int kAperturePrecision = 10000;
- entry = metadata.find(ANDROID_LENS_APERTURE);
- if (!setFNumber(entry.data.f[0] * kAperturePrecision,
- kAperturePrecision)) {
- ALOGE("%s: setting F number failed.", __FUNCTION__);
- return false;
- }
- }
-
- if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
- entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
- if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
- const uint32_t kNoFlashFunction = 0x20;
- if (!setFlash(kNoFlashFunction)) {
- ALOGE("%s: setting flash failed.", __FUNCTION__);
- return false;
- }
- } else {
- ALOGE("%s: Unsupported flash info: %d",__FUNCTION__, entry.data.u8[0]);
- return false;
- }
- }
-
- if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
- entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
- if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
- const uint16_t kAutoWhiteBalance = 0;
- if (!setWhiteBalance(kAutoWhiteBalance)) {
- ALOGE("%s: setting white balance failed.", __FUNCTION__);
- return false;
- }
- } else {
- ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
- return false;
- }
- }
-
- if (time_available) {
- char str[4];
- if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
- ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
- return false;
- }
- if (!setSubsecTime(std::string(str))) {
- ALOGE("%s: setting subsec time failed.", __FUNCTION__);
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
deleted file mode 100644
index d2fdf02..0000000
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open 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 "HandleImporter"
-#include "HandleImporter.h"
-
-#include <gralloctypes/Gralloc4.h>
-#include "aidl/android/hardware/graphics/common/Smpte2086.h"
-#include <log/log.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-using aidl::android::hardware::graphics::common::PlaneLayout;
-using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
-using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
-using aidl::android::hardware::graphics::common::Smpte2086;
-using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
-using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
-using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
-using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error;
-using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
-using IMapperV4 = android::hardware::graphics::mapper::V4_0::IMapper;
-
-HandleImporter::HandleImporter() : mInitialized(false) {}
-
-void HandleImporter::initializeLocked() {
- if (mInitialized) {
- return;
- }
-
- mMapperV4 = IMapperV4::getService();
- if (mMapperV4 != nullptr) {
- mInitialized = true;
- return;
- }
-
- mMapperV3 = IMapperV3::getService();
- if (mMapperV3 != nullptr) {
- mInitialized = true;
- return;
- }
-
- mMapperV2 = IMapper::getService();
- if (mMapperV2 == nullptr) {
- ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
- return;
- }
-
- mInitialized = true;
- return;
-}
-
-void HandleImporter::cleanup() {
- mMapperV4.clear();
- mMapperV3.clear();
- mMapperV2.clear();
- mInitialized = false;
-}
-
-template<class M, class E>
-bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
- E error;
- buffer_handle_t importedHandle;
- auto ret = mapper->importBuffer(
- hidl_handle(handle),
- [&](const auto& tmpError, const auto& tmpBufferHandle) {
- error = tmpError;
- importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
- });
-
- if (!ret.isOk()) {
- ALOGE("%s: mapper importBuffer failed: %s",
- __FUNCTION__, ret.description().c_str());
- return false;
- }
-
- if (error != E::NONE) {
- return false;
- }
-
- handle = importedHandle;
- return true;
-}
-
-template<class M, class E>
-YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
- uint64_t cpuUsage, const IMapper::Rect& accessRegion) {
- hidl_handle acquireFenceHandle;
- auto buffer = const_cast<native_handle_t*>(buf);
- YCbCrLayout layout = {};
-
- typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top,
- accessRegion.width, accessRegion.height};
- mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpLayout) {
- if (tmpError == E::NONE) {
- // Member by member copy from different versions of YCbCrLayout.
- layout.y = tmpLayout.y;
- layout.cb = tmpLayout.cb;
- layout.cr = tmpLayout.cr;
- layout.yStride = tmpLayout.yStride;
- layout.cStride = tmpLayout.cStride;
- layout.chromaStep = tmpLayout.chromaStep;
- } else {
- ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
- }
- });
- return layout;
-}
-
-bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
- MetadataType metadataType) {
- auto buffer = const_cast<native_handle_t*>(buf);
- bool ret = false;
- hidl_vec<uint8_t> vec;
- mapper->get(buffer, metadataType, [&] (const auto& tmpError,
- const auto& tmpMetadata) {
- if (tmpError == MapperErrorV4::NONE) {
- vec = tmpMetadata;
- } else {
- ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
- }});
-
- if (vec.size() > 0) {
- if (metadataType == gralloc4::MetadataType_Smpte2086){
- std::optional<Smpte2086> realSmpte2086;
- gralloc4::decodeSmpte2086(vec, &realSmpte2086);
- ret = realSmpte2086.has_value();
- } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
- std::optional<std::vector<uint8_t>> realSmpte2094_10;
- gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
- ret = realSmpte2094_10.has_value();
- } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
- std::optional<std::vector<uint8_t>> realSmpte2094_40;
- gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
- ret = realSmpte2094_40.has_value();
- } else {
- ALOGE("%s: Unknown metadata type!", __FUNCTION__);
- }
- }
-
- return ret;
-}
-
-std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
- auto buffer = const_cast<native_handle_t*>(buf);
- std::vector<PlaneLayout> planeLayouts;
- hidl_vec<uint8_t> encodedPlaneLayouts;
- mapper->get(buffer, gralloc4::MetadataType_PlaneLayouts,
- [&](const auto& tmpError, const auto& tmpEncodedPlaneLayouts) {
- if (tmpError == MapperErrorV4::NONE) {
- encodedPlaneLayouts = tmpEncodedPlaneLayouts;
- } else {
- ALOGE("%s: failed to get plane layouts %d!", __FUNCTION__, tmpError);
- }
- });
-
- gralloc4::decodePlaneLayouts(encodedPlaneLayouts, &planeLayouts);
-
- return planeLayouts;
-}
-
-template <>
-YCbCrLayout HandleImporter::lockYCbCrInternal<IMapperV4, MapperErrorV4>(
- const sp<IMapperV4> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion) {
- hidl_handle acquireFenceHandle;
- auto buffer = const_cast<native_handle_t*>(buf);
- YCbCrLayout layout = {};
- void* mapped = nullptr;
-
- typename IMapperV4::Rect accessRegionV4 = {accessRegion.left, accessRegion.top,
- accessRegion.width, accessRegion.height};
- mapper->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpPtr) {
- if (tmpError == MapperErrorV4::NONE) {
- mapped = tmpPtr;
- } else {
- ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
- }
- });
-
- if (mapped == nullptr) {
- return layout;
- }
-
- std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mapper, buf);
- for (const auto& planeLayout : planeLayouts) {
- for (const auto& planeLayoutComponent : planeLayout.components) {
- const auto& type = planeLayoutComponent.type;
-
- if (!gralloc4::isStandardPlaneLayoutComponentType(type)) {
- continue;
- }
-
- uint8_t* data = reinterpret_cast<uint8_t*>(mapped);
- data += planeLayout.offsetInBytes;
- data += planeLayoutComponent.offsetInBits / 8;
-
- switch (static_cast<PlaneLayoutComponentType>(type.value)) {
- case PlaneLayoutComponentType::Y:
- layout.y = data;
- layout.yStride = planeLayout.strideInBytes;
- break;
- case PlaneLayoutComponentType::CB:
- layout.cb = data;
- layout.cStride = planeLayout.strideInBytes;
- layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
- break;
- case PlaneLayoutComponentType::CR:
- layout.cr = data;
- layout.cStride = planeLayout.strideInBytes;
- layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
- break;
- default:
- break;
- }
- }
- }
-
- return layout;
-}
-
-template<class M, class E>
-int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
- int releaseFence = -1;
- auto buffer = const_cast<native_handle_t*>(buf);
-
- mapper->unlock(
- buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
- if (tmpError == E::NONE) {
- auto fenceHandle = tmpReleaseFence.getNativeHandle();
- if (fenceHandle) {
- if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
- ALOGE("%s: bad release fence numInts %d numFds %d",
- __FUNCTION__, fenceHandle->numInts, fenceHandle->numFds);
- return;
- }
- releaseFence = dup(fenceHandle->data[0]);
- if (releaseFence < 0) {
- ALOGE("%s: bad release fence FD %d",
- __FUNCTION__, releaseFence);
- }
- }
- } else {
- ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
- }
- });
- return releaseFence;
-}
-
-// In IComposer, any buffer_handle_t is owned by the caller and we need to
-// make a clone for hwcomposer2. We also need to translate empty handle
-// to nullptr. This function does that, in-place.
-bool HandleImporter::importBuffer(buffer_handle_t& handle) {
- if (!handle->numFds && !handle->numInts) {
- handle = nullptr;
- return true;
- }
-
- Mutex::Autolock lock(mLock);
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- return importBufferInternal<IMapperV4, MapperErrorV4>(mMapperV4, handle);
- }
-
- if (mMapperV3 != nullptr) {
- return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
- }
-
- if (mMapperV2 != nullptr) {
- return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
- }
-
- ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
- return false;
-}
-
-void HandleImporter::freeBuffer(buffer_handle_t handle) {
- if (!handle) {
- return;
- }
-
- Mutex::Autolock lock(mLock);
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- auto ret = mMapperV4->freeBuffer(const_cast<native_handle_t*>(handle));
- if (!ret.isOk()) {
- ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
- }
- } else if (mMapperV3 != nullptr) {
- auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
- if (!ret.isOk()) {
- ALOGE("%s: mapper freeBuffer failed: %s",
- __FUNCTION__, ret.description().c_str());
- }
- } else {
- auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
- if (!ret.isOk()) {
- ALOGE("%s: mapper freeBuffer failed: %s",
- __FUNCTION__, ret.description().c_str());
- }
- }
-}
-
-bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
- if (handle == nullptr || handle->numFds == 0) {
- fd = -1;
- } else if (handle->numFds == 1) {
- fd = dup(handle->data[0]);
- if (fd < 0) {
- ALOGE("failed to dup fence fd %d", handle->data[0]);
- return false;
- }
- } else {
- ALOGE("invalid fence handle with %d file descriptors",
- handle->numFds);
- return false;
- }
-
- return true;
-}
-
-void HandleImporter::closeFence(int fd) const {
- if (fd >= 0) {
- close(fd);
- }
-}
-
-void* HandleImporter::lock(
- buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
- IMapper::Rect accessRegion{0, 0, static_cast<int>(size), 1};
- return lock(buf, cpuUsage, accessRegion);
-}
-
-void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion) {
- Mutex::Autolock lock(mLock);
-
- if (!mInitialized) {
- initializeLocked();
- }
-
- void* ret = nullptr;
-
- if (mMapperV4 == nullptr && mMapperV3 == nullptr && mMapperV2 == nullptr) {
- ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
- return ret;
- }
-
- hidl_handle acquireFenceHandle;
- auto buffer = const_cast<native_handle_t*>(buf);
- if (mMapperV4 != nullptr) {
- IMapperV4::Rect accessRegionV4{accessRegion.left, accessRegion.top, accessRegion.width,
- accessRegion.height};
-
- mMapperV4->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpPtr) {
- if (tmpError == MapperErrorV4::NONE) {
- ret = tmpPtr;
- } else {
- ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
- }
- });
- } else if (mMapperV3 != nullptr) {
- IMapperV3::Rect accessRegionV3{accessRegion.left, accessRegion.top, accessRegion.width,
- accessRegion.height};
-
- mMapperV3->lock(buffer, cpuUsage, accessRegionV3, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
- const auto& /*bytesPerStride*/) {
- if (tmpError == MapperErrorV3::NONE) {
- ret = tmpPtr;
- } else {
- ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
- }
- });
- } else {
- mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpPtr) {
- if (tmpError == MapperErrorV2::NONE) {
- ret = tmpPtr;
- } else {
- ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
- }
- });
- }
-
- ALOGV("%s: ptr %p accessRegion.top: %d accessRegion.left: %d accessRegion.width: %d "
- "accessRegion.height: %d",
- __FUNCTION__, ret, accessRegion.top, accessRegion.left, accessRegion.width,
- accessRegion.height);
- return ret;
-}
-
-YCbCrLayout HandleImporter::lockYCbCr(
- buffer_handle_t& buf, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion) {
- Mutex::Autolock lock(mLock);
-
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- return lockYCbCrInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf, cpuUsage, accessRegion);
- }
-
- if (mMapperV3 != nullptr) {
- return lockYCbCrInternal<IMapperV3, MapperErrorV3>(
- mMapperV3, buf, cpuUsage, accessRegion);
- }
-
- if (mMapperV2 != nullptr) {
- return lockYCbCrInternal<IMapper, MapperErrorV2>(
- mMapperV2, buf, cpuUsage, accessRegion);
- }
-
- ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
- return {};
-}
-
-status_t HandleImporter::getMonoPlanarStrideBytes(buffer_handle_t &buf, uint32_t *stride /*out*/) {
- if (stride == nullptr) {
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mLock);
-
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mMapperV4, buf);
- if (planeLayouts.size() != 1) {
- ALOGE("%s: Unexpected number of planes %zu!", __FUNCTION__, planeLayouts.size());
- return BAD_VALUE;
- }
-
- *stride = planeLayouts[0].strideInBytes;
- } else {
- ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
- return NO_INIT;
- }
-
- return OK;
-}
-
-int HandleImporter::unlock(buffer_handle_t& buf) {
- if (mMapperV4 != nullptr) {
- return unlockInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf);
- }
- if (mMapperV3 != nullptr) {
- return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
- }
- if (mMapperV2 != nullptr) {
- return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
- }
-
- ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
- return -1;
-}
-
-bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) {
- Mutex::Autolock lock(mLock);
-
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086);
- } else {
- ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
- }
-
- return false;
-}
-
-bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) {
- Mutex::Autolock lock(mLock);
-
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10);
- } else {
- ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
- }
-
- return false;
-}
-
-bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) {
- Mutex::Autolock lock(mLock);
-
- if (!mInitialized) {
- initializeLocked();
- }
-
- if (mMapperV4 != nullptr) {
- return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40);
- } else {
- ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
- }
-
- return false;
-}
-
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/VendorTagDescriptor.cpp b/camera/common/1.0/default/VendorTagDescriptor.cpp
deleted file mode 100644
index d2bee85..0000000
--- a/camera/common/1.0/default/VendorTagDescriptor.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open 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 "CamComm1.0-VTDesc"
-
-#include <log/log.h>
-#include <system/camera_metadata.h>
-#include <camera_metadata_hidden.h>
-#include <utils/Errors.h>
-#include <utils/Mutex.h>
-#include <utils/SortedVector.h>
-#include <utils/Vector.h>
-
-#include "VendorTagDescriptor.h"
-
-#include <stdio.h>
-#include <string.h>
-
-namespace android {
-namespace hardware {
-namespace camera2 {
-namespace params {
-
-VendorTagDescriptor::~VendorTagDescriptor() {
- size_t len = mReverseMapping.size();
- for (size_t i = 0; i < len; ++i) {
- delete mReverseMapping[i];
- }
-}
-
-VendorTagDescriptor::VendorTagDescriptor() :
- mTagCount(0),
- mVendorOps() {
-}
-
-VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
- copyFrom(src);
-}
-
-VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
- copyFrom(rhs);
- return *this;
-}
-
-void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
- if (this == &src) return;
-
- size_t len = mReverseMapping.size();
- for (size_t i = 0; i < len; ++i) {
- delete mReverseMapping[i];
- }
- mReverseMapping.clear();
-
- len = src.mReverseMapping.size();
- // Have to copy KeyedVectors inside mReverseMapping
- for (size_t i = 0; i < len; ++i) {
- KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
- *nameMapper = *(src.mReverseMapping.valueAt(i));
- mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
- }
- // Everything else is simple
- mTagToNameMap = src.mTagToNameMap;
- mTagToSectionMap = src.mTagToSectionMap;
- mTagToTypeMap = src.mTagToTypeMap;
- mSections = src.mSections;
- mTagCount = src.mTagCount;
- mVendorOps = src.mVendorOps;
-}
-
-int VendorTagDescriptor::getTagCount() const {
- size_t size = mTagToNameMap.size();
- if (size == 0) {
- return VENDOR_TAG_COUNT_ERR;
- }
- return size;
-}
-
-void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
- size_t size = mTagToNameMap.size();
- for (size_t i = 0; i < size; ++i) {
- tagArray[i] = mTagToNameMap.keyAt(i);
- }
-}
-
-const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
- ssize_t index = mTagToSectionMap.indexOfKey(tag);
- if (index < 0) {
- return VENDOR_SECTION_NAME_ERR;
- }
- return mSections[mTagToSectionMap.valueAt(index)].string();
-}
-
-ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
- return mTagToSectionMap.valueFor(tag);
-}
-
-const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
- ssize_t index = mTagToNameMap.indexOfKey(tag);
- if (index < 0) {
- return VENDOR_TAG_NAME_ERR;
- }
- return mTagToNameMap.valueAt(index).string();
-}
-
-int VendorTagDescriptor::getTagType(uint32_t tag) const {
- auto iter = mTagToTypeMap.find(tag);
- if (iter == mTagToTypeMap.end()) {
- return VENDOR_TAG_TYPE_ERR;
- }
- return iter->second;
-}
-
-const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
- return &mSections;
-}
-
-status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section, /*out*/uint32_t* tag) const {
- ssize_t index = mReverseMapping.indexOfKey(section);
- if (index < 0) {
- ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
- return BAD_VALUE;
- }
-
- ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
- if (nameIndex < 0) {
- ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
- return BAD_VALUE;
- }
-
- if (tag != NULL) {
- *tag = mReverseMapping[index]->valueAt(nameIndex);
- }
- return OK;
-}
-
-void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
-
- size_t size = mTagToNameMap.size();
- if (size == 0) {
- dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n",
- indentation, "");
- return;
- }
-
- dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n",
- indentation, "", size);
- for (size_t i = 0; i < size; ++i) {
- uint32_t tag = mTagToNameMap.keyAt(i);
-
- if (verbosity < 1) {
- dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
- continue;
- }
- String8 name = mTagToNameMap.valueAt(i);
- uint32_t sectionId = mTagToSectionMap.valueFor(tag);
- String8 sectionName = mSections[sectionId];
- int type = mTagToTypeMap.at(tag);
- const char* typeName = (type >= 0 && type < NUM_TYPES) ?
- camera_metadata_type_names[type] : "UNKNOWN";
- dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2,
- "", tag, name.string(), type, typeName, sectionName.string());
- }
-
-}
-
-int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
- int ret = 0;
- auto desc = mVendorMap.find(id);
- if (desc != mVendorMap.end()) {
- ret = desc->second->getTagCount();
- } else {
- ALOGE("%s: Vendor descriptor id is missing!", __func__);
- }
-
- return ret;
-}
-
-void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const {
- auto desc = mVendorMap.find(id);
- if (desc != mVendorMap.end()) {
- desc->second->getTagArray(tagArray);
- } else {
- ALOGE("%s: Vendor descriptor id is missing!", __func__);
- }
-}
-
-const char* VendorTagDescriptorCache::getSectionName(uint32_t tag, metadata_vendor_id_t id) const {
- const char* ret = nullptr;
- auto desc = mVendorMap.find(id);
- if (desc != mVendorMap.end()) {
- ret = desc->second->getSectionName(tag);
- } else {
- ALOGE("%s: Vendor descriptor id is missing!", __func__);
- }
-
- return ret;
-}
-
-const char* VendorTagDescriptorCache::getTagName(uint32_t tag, metadata_vendor_id_t id) const {
- const char* ret = nullptr;
- auto desc = mVendorMap.find(id);
- if (desc != mVendorMap.end()) {
- ret = desc->second->getTagName(tag);
- } else {
- ALOGE("%s: Vendor descriptor id is missing!", __func__);
- }
-
- return ret;
-}
-
-int VendorTagDescriptorCache::getTagType(uint32_t tag, metadata_vendor_id_t id) const {
- int ret = 0;
- auto desc = mVendorMap.find(id);
- if (desc != mVendorMap.end()) {
- ret = desc->second->getTagType(tag);
- } else {
- ALOGE("%s: Vendor descriptor id is missing!", __func__);
- }
-
- return ret;
-}
-
-void VendorTagDescriptorCache::dump(int fd, int verbosity, int indentation) const {
- for (const auto& desc : mVendorMap) {
- desc.second->dump(fd, verbosity, indentation);
- }
-}
-
-int32_t VendorTagDescriptorCache::addVendorDescriptor(
- metadata_vendor_id_t id, sp<hardware::camera::common::V1_0::helper::VendorTagDescriptor> desc) {
- auto entry = mVendorMap.find(id);
- if (entry != mVendorMap.end()) {
- ALOGE("%s: Vendor descriptor with same id already present!", __func__);
- return BAD_VALUE;
- }
-
- mVendorMap.emplace(id, desc);
- return NO_ERROR;
-}
-
-int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
- metadata_vendor_id_t id,
- sp<hardware::camera::common::V1_0::helper::VendorTagDescriptor>* desc /*out*/) {
- auto entry = mVendorMap.find(id);
- if (entry == mVendorMap.end()) {
- return NAME_NOT_FOUND;
- }
-
- *desc = entry->second;
-
- return NO_ERROR;
-}
-} // namespace params
-} // namespace camera2
-
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-extern "C" {
-
-static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
-static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
-static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
-static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
-static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
-
-static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
-static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id);
-static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
- metadata_vendor_id_t id);
-static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id);
-static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id);
-} /* extern "C" */
-
-static Mutex sLock;
-static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
-static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
-
-status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
- /*out*/
- sp<VendorTagDescriptor>& descriptor) {
- if (vOps == NULL) {
- ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
- return BAD_VALUE;
- }
-
- int tagCount = vOps->get_tag_count(vOps);
- if (tagCount < 0 || tagCount > INT32_MAX) {
- ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
- return BAD_VALUE;
- }
-
- Vector<uint32_t> tagArray;
- LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
- "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
-
- vOps->get_all_tags(vOps, /*out*/tagArray.editArray());
-
- sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
- desc->mTagCount = tagCount;
-
- SortedVector<String8> sections;
- KeyedVector<uint32_t, String8> tagToSectionMap;
-
- for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
- uint32_t tag = tagArray[i];
- if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
- ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
- const char *tagName = vOps->get_tag_name(vOps, tag);
- if (tagName == NULL) {
- ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
- desc->mTagToNameMap.add(tag, String8(tagName));
- const char *sectionName = vOps->get_section_name(vOps, tag);
- if (sectionName == NULL) {
- ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
- return BAD_VALUE;
- }
-
- String8 sectionString(sectionName);
-
- sections.add(sectionString);
- tagToSectionMap.add(tag, sectionString);
-
- int tagType = vOps->get_tag_type(vOps, tag);
- if (tagType < 0 || tagType >= NUM_TYPES) {
- ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
- return BAD_VALUE;
- }
- desc->mTagToTypeMap.insert(std::make_pair(tag, tagType));
- }
-
- desc->mSections = sections;
-
- for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
- uint32_t tag = tagArray[i];
- const String8& sectionString = tagToSectionMap.valueFor(tag);
-
- // Set up tag to section index map
- ssize_t index = sections.indexOf(sectionString);
- LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
- desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
-
- // Set up reverse mapping
- ssize_t reverseIndex = -1;
- if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
- KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
- reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
- }
- desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
- }
-
- descriptor = desc;
- return OK;
-}
-
-status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
- status_t res = OK;
- Mutex::Autolock al(sLock);
- sGlobalVendorTagDescriptor = desc;
-
- vendor_tag_ops_t* opsPtr = NULL;
- if (desc != NULL) {
- opsPtr = &(desc->mVendorOps);
- opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
- opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
- opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
- opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
- opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
- }
- if((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
- ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d)."
- , __FUNCTION__, strerror(-res), res);
- }
- return res;
-}
-
-void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
- Mutex::Autolock al(sLock);
- set_camera_metadata_vendor_ops(NULL);
- sGlobalVendorTagDescriptor.clear();
-}
-
-sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
- Mutex::Autolock al(sLock);
- return sGlobalVendorTagDescriptor;
-}
-
-status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
- const sp<VendorTagDescriptorCache>& cache) {
- status_t res = OK;
- Mutex::Autolock al(sLock);
- sGlobalVendorTagDescriptorCache = cache;
-
- struct vendor_tag_cache_ops* opsPtr = NULL;
- if (cache != NULL) {
- opsPtr = &(cache->mVendorCacheOps);
- opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
- opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
- opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
- opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
- opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
- }
- if ((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
- ALOGE("%s: Could not set vendor tag cache, received error %s (%d).", __FUNCTION__,
- strerror(-res), res);
- }
- return res;
-}
-
-void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
- Mutex::Autolock al(sLock);
- set_camera_metadata_vendor_cache_ops(NULL);
- sGlobalVendorTagDescriptorCache.clear();
-}
-
-sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
- Mutex::Autolock al(sLock);
- return sGlobalVendorTagDescriptorCache;
-}
-
-extern "C" {
-
-int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptor == NULL) {
- ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
- return VENDOR_TAG_COUNT_ERR;
- }
- return sGlobalVendorTagDescriptor->getTagCount();
-}
-
-void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptor == NULL) {
- ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
- return;
- }
- sGlobalVendorTagDescriptor->getTagArray(tagArray);
-}
-
-const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptor == NULL) {
- ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
- return VENDOR_SECTION_NAME_ERR;
- }
- return sGlobalVendorTagDescriptor->getSectionName(tag);
-}
-
-const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptor == NULL) {
- ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
- return VENDOR_TAG_NAME_ERR;
- }
- return sGlobalVendorTagDescriptor->getTagName(tag);
-}
-
-int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptor == NULL) {
- ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
- return VENDOR_TAG_TYPE_ERR;
- }
- return sGlobalVendorTagDescriptor->getTagType(tag);
-}
-
-int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptorCache == NULL) {
- ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
- return VENDOR_TAG_COUNT_ERR;
- }
- return sGlobalVendorTagDescriptorCache->getTagCount(id);
-}
-
-void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptorCache == NULL) {
- ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
- }
- sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
-}
-
-const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag, metadata_vendor_id_t id) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptorCache == NULL) {
- ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
- return VENDOR_SECTION_NAME_ERR;
- }
- return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
-}
-
-const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptorCache == NULL) {
- ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
- return VENDOR_TAG_NAME_ERR;
- }
- return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
-}
-
-int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id) {
- Mutex::Autolock al(sLock);
- if (sGlobalVendorTagDescriptorCache == NULL) {
- ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
- return VENDOR_TAG_NAME_ERR;
- }
- return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
-}
-
-} /* extern "C" */
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
diff --git a/camera/common/1.0/default/include/CameraMetadata.h b/camera/common/1.0/default/include/CameraMetadata.h
deleted file mode 100644
index d5e4d56..0000000
--- a/camera/common/1.0/default/include/CameraMetadata.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CAMERA_COMMON_1_0_CAMERAMETADATA_H
-#define CAMERA_COMMON_1_0_CAMERAMETADATA_H
-
-#include "system/camera_metadata.h"
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-class VendorTagDescriptor;
-
-/**
- * A convenience wrapper around the C-based camera_metadata_t library.
- */
-class CameraMetadata {
- public:
- /** Creates an empty object; best used when expecting to acquire contents
- * from elsewhere */
- CameraMetadata();
- /** Creates an object with space for entryCapacity entries, with
- * dataCapacity extra storage */
- CameraMetadata(size_t entryCapacity, size_t dataCapacity = 10);
-
- ~CameraMetadata();
-
- /** Takes ownership of passed-in buffer */
- CameraMetadata(camera_metadata_t *buffer);
- /** Clones the metadata */
- CameraMetadata(const CameraMetadata &other);
-
- /**
- * Assignment clones metadata buffer.
- */
- CameraMetadata &operator=(const CameraMetadata &other);
- CameraMetadata &operator=(const camera_metadata_t *buffer);
-
- /**
- * Get reference to the underlying metadata buffer. Ownership remains with
- * the CameraMetadata object, but non-const CameraMetadata methods will not
- * work until unlock() is called. Note that the lock has nothing to do with
- * thread-safety, it simply prevents the camera_metadata_t pointer returned
- * here from being accidentally invalidated by CameraMetadata operations.
- */
- const camera_metadata_t* getAndLock() const;
-
- /**
- * Unlock the CameraMetadata for use again. After this unlock, the pointer
- * given from getAndLock() may no longer be used. The pointer passed out
- * from getAndLock must be provided to guarantee that the right object is
- * being unlocked.
- */
- status_t unlock(const camera_metadata_t *buffer) const;
-
- /**
- * Release a raw metadata buffer to the caller. After this call,
- * CameraMetadata no longer references the buffer, and the caller takes
- * responsibility for freeing the raw metadata buffer (using
- * free_camera_metadata()), or for handing it to another CameraMetadata
- * instance.
- */
- camera_metadata_t* release();
-
- /**
- * Clear the metadata buffer and free all storage used by it
- */
- void clear();
-
- /**
- * Acquire a raw metadata buffer from the caller. After this call,
- * the caller no longer owns the raw buffer, and must not free or manipulate it.
- * If CameraMetadata already contains metadata, it is freed.
- */
- void acquire(camera_metadata_t* buffer);
-
- /**
- * Acquires raw buffer from other CameraMetadata object. After the call, the argument
- * object no longer has any metadata.
- */
- void acquire(CameraMetadata &other);
-
- /**
- * Append metadata from another CameraMetadata object.
- */
- status_t append(const CameraMetadata &other);
-
- /**
- * Append metadata from a raw camera_metadata buffer
- */
- status_t append(const camera_metadata* other);
-
- /**
- * Number of metadata entries.
- */
- size_t entryCount() const;
-
- /**
- * Is the buffer empty (no entires)
- */
- bool isEmpty() const;
-
- /**
- * Sort metadata buffer for faster find
- */
- status_t sort();
-
- /**
- * Update metadata entry. Will create entry if it doesn't exist already, and
- * will reallocate the buffer if insufficient space exists. Overloaded for
- * the various types of valid data.
- */
- status_t update(uint32_t tag,
- const uint8_t *data, size_t data_count);
- status_t update(uint32_t tag,
- const int32_t *data, size_t data_count);
- status_t update(uint32_t tag,
- const float *data, size_t data_count);
- status_t update(uint32_t tag,
- const int64_t *data, size_t data_count);
- status_t update(uint32_t tag,
- const double *data, size_t data_count);
- status_t update(uint32_t tag,
- const camera_metadata_rational_t *data, size_t data_count);
- status_t update(uint32_t tag,
- const String8 &string);
- status_t update(const camera_metadata_ro_entry &entry);
-
-
- template<typename T>
- status_t update(uint32_t tag, Vector<T> data) {
- return update(tag, data.array(), data.size());
- }
-
- /**
- * Check if a metadata entry exists for a given tag id
- *
- */
- bool exists(uint32_t tag) const;
-
- /**
- * Get metadata entry by tag id
- */
- camera_metadata_entry find(uint32_t tag);
-
- /**
- * Get metadata entry by tag id, with no editing
- */
- camera_metadata_ro_entry find(uint32_t tag) const;
-
- /**
- * Delete metadata entry by tag
- */
- status_t erase(uint32_t tag);
-
- /**
- * Swap the underlying camera metadata between this and the other
- * metadata object.
- */
- void swap(CameraMetadata &other);
-
- /**
- * Dump contents into FD for debugging. The verbosity levels are
- * 0: Tag entry information only, no data values
- * 1: Level 0 plus at most 16 data values per entry
- * 2: All information
- *
- * The indentation parameter sets the number of spaces to add to the start
- * each line of output.
- */
- void dump(int fd, int verbosity = 1, int indentation = 0) const;
-
- /**
- * Find tag id for a given tag name, also checking vendor tags if available.
- * On success, returns OK and writes the tag id into tag.
- *
- * This is a slow method.
- */
- static status_t getTagFromName(const char *name,
- const VendorTagDescriptor* vTags, uint32_t *tag);
-
- private:
- camera_metadata_t *mBuffer;
- mutable bool mLocked;
-
- /**
- * Check if tag has a given type
- */
- status_t checkType(uint32_t tag, uint8_t expectedType);
-
- /**
- * Base update entry method
- */
- status_t updateImpl(uint32_t tag, const void *data, size_t data_count);
-
- /**
- * Resize metadata buffer if needed by reallocating it and copying it over.
- */
- status_t resizeIfNeeded(size_t extraEntries, size_t extraData);
-
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif
diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h
deleted file mode 100644
index c89e934..0000000
--- a/camera/common/1.0/default/include/CameraModule.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CAMERA_COMMON_1_0_CAMERAMODULE_H
-#define CAMERA_COMMON_1_0_CAMERAMODULE_H
-
-#include <string>
-#include <unordered_set>
-
-#include <hardware/camera.h>
-#include <utils/Mutex.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-
-#include "CameraMetadata.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-/**
- * A wrapper class for HAL camera module.
- *
- * This class wraps camera_module_t returned from HAL to provide a wrapped
- * get_camera_info implementation which CameraService generates some
- * camera characteristics keys defined in newer HAL version on an older HAL.
- */
-class CameraModule : public RefBase {
-public:
- explicit CameraModule(camera_module_t *module);
- virtual ~CameraModule();
-
- // Must be called after construction
- // Returns OK on success, NO_INIT on failure
- int init();
-
- int getCameraInfo(int cameraId, struct camera_info *info);
- int getDeviceVersion(int cameraId);
- int getNumberOfCameras(void);
- int open(const char* id, struct hw_device_t** device);
- bool isOpenLegacyDefined() const;
- int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device);
- int setCallbacks(const camera_module_callbacks_t *callbacks);
- bool isVendorTagDefined() const;
- void getVendorTagOps(vendor_tag_ops_t* ops);
- bool isSetTorchModeSupported() const;
- int setTorchMode(const char* camera_id, bool enable);
- uint16_t getModuleApiVersion() const;
- const char* getModuleName() const;
- uint16_t getHalApiVersion() const;
- const char* getModuleAuthor() const;
- // Only used by CameraModuleFixture native test. Do NOT use elsewhere.
- void *getDso();
- // Only used by CameraProvider
- void removeCamera(int cameraId);
- int getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo);
- int isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams);
- void notifyDeviceStateChange(uint64_t deviceState);
-
- static bool isLogicalMultiCamera(
- const common::V1_0::helper::CameraMetadata& metadata,
- std::unordered_set<std::string>* physicalCameraIds);
-
-private:
- // Derive camera characteristics keys defined after HAL device version
- static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
- // Helper function to append available[request|result|chars]Keys
- static void appendAvailableKeys(CameraMetadata &chars,
- int32_t keyTag, const Vector<int32_t>& appendKeys);
- status_t filterOpenErrorCode(status_t err);
- camera_module_t *mModule;
- int mNumberOfCameras;
- KeyedVector<int, camera_info> mCameraInfoMap;
- KeyedVector<int, int> mDeviceVersionMap;
- KeyedVector<int, camera_metadata_t*> mPhysicalCameraInfoMap;
- Mutex mCameraInfoLock;
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif
diff --git a/camera/common/1.0/default/include/CameraParameters.h b/camera/common/1.0/default/include/CameraParameters.h
deleted file mode 100644
index e4ff6f2..0000000
--- a/camera/common/1.0/default/include/CameraParameters.h
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS_H
-#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H
-
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-struct Size {
- int width;
- int height;
-
- Size() {
- width = 0;
- height = 0;
- }
-
- Size(int w, int h) {
- width = w;
- height = h;
- }
-};
-
-class CameraParameters
-{
-public:
- CameraParameters();
- CameraParameters(const String8 ¶ms) { unflatten(params); }
- ~CameraParameters();
-
- String8 flatten() const;
- void unflatten(const String8 ¶ms);
-
- void set(const char *key, const char *value);
- void set(const char *key, int value);
- void setFloat(const char *key, float value);
- const char *get(const char *key) const;
- int getInt(const char *key) const;
- float getFloat(const char *key) const;
-
- void remove(const char *key);
-
- void setPreviewSize(int width, int height);
- void getPreviewSize(int *width, int *height) const;
- void getSupportedPreviewSizes(Vector<Size> &sizes) const;
-
- // Set the dimensions in pixels to the given width and height
- // for video frames. The given width and height must be one
- // of the supported dimensions returned from
- // getSupportedVideoSizes(). Must not be called if
- // getSupportedVideoSizes() returns an empty Vector of Size.
- void setVideoSize(int width, int height);
- // Retrieve the current dimensions (width and height)
- // in pixels for video frames, which must be one of the
- // supported dimensions returned from getSupportedVideoSizes().
- // Must not be called if getSupportedVideoSizes() returns an
- // empty Vector of Size.
- void getVideoSize(int *width, int *height) const;
- // Retrieve a Vector of supported dimensions (width and height)
- // in pixels for video frames. If sizes returned from the method
- // is empty, the camera does not support calls to setVideoSize()
- // or getVideoSize(). In adddition, it also indicates that
- // the camera only has a single output, and does not have
- // separate output for video frames and preview frame.
- void getSupportedVideoSizes(Vector<Size> &sizes) const;
- // Retrieve the preferred preview size (width and height) in pixels
- // for video recording. The given width and height must be one of
- // supported preview sizes returned from getSupportedPreviewSizes().
- // Must not be called if getSupportedVideoSizes() returns an empty
- // Vector of Size. If getSupportedVideoSizes() returns an empty
- // Vector of Size, the width and height returned from this method
- // is invalid, and is "-1x-1".
- void getPreferredPreviewSizeForVideo(int *width, int *height) const;
-
- void setPreviewFrameRate(int fps);
- int getPreviewFrameRate() const;
- void getPreviewFpsRange(int *min_fps, int *max_fps) const;
- void setPreviewFormat(const char *format);
- const char *getPreviewFormat() const;
- void setPictureSize(int width, int height);
- void getPictureSize(int *width, int *height) const;
- void getSupportedPictureSizes(Vector<Size> &sizes) const;
- void setPictureFormat(const char *format);
- const char *getPictureFormat() const;
-
- void dump() const;
- status_t dump(int fd, const Vector<String16>& args) const;
-
- /**
- * Returns a Vector containing the supported preview formats
- * as enums given in graphics.h.
- */
- void getSupportedPreviewFormats(Vector<int>& formats) const;
-
- // Returns true if no keys are present
- bool isEmpty() const;
-
- // Parameter keys to communicate between camera application and driver.
- // The access (read/write, read only, or write only) is viewed from the
- // perspective of applications, not driver.
-
- // Preview frame size in pixels (width x height).
- // Example value: "480x320". Read/Write.
- static const char KEY_PREVIEW_SIZE[];
- // Supported preview frame sizes in pixels.
- // Example value: "800x600,480x320". Read only.
- static const char KEY_SUPPORTED_PREVIEW_SIZES[];
- // The current minimum and maximum preview fps. This controls the rate of
- // preview frames received (CAMERA_MSG_PREVIEW_FRAME). The minimum and
- // maximum fps must be one of the elements from
- // KEY_SUPPORTED_PREVIEW_FPS_RANGE parameter.
- // Example value: "10500,26623"
- static const char KEY_PREVIEW_FPS_RANGE[];
- // The supported preview fps (frame-per-second) ranges. Each range contains
- // a minimum fps and maximum fps. If minimum fps equals to maximum fps, the
- // camera outputs frames in fixed frame rate. If not, the camera outputs
- // frames in auto frame rate. The actual frame rate fluctuates between the
- // minimum and the maximum. The list has at least one element. The list is
- // sorted from small to large (first by maximum fps and then minimum fps).
- // Example value: "(10500,26623),(15000,26623),(30000,30000)"
- static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[];
- // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
- // frameworks/av/include/camera/Camera.h. The default is
- // PIXEL_FORMAT_YUV420SP. Example value: "yuv420sp" or PIXEL_FORMAT_XXX
- // constants. Read/write.
- static const char KEY_PREVIEW_FORMAT[];
- // Supported image formats for preview frames.
- // Example value: "yuv420sp,yuv422i-yuyv". Read only.
- static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
- // Number of preview frames per second. This is the target frame rate. The
- // actual frame rate depends on the driver.
- // Example value: "15". Read/write.
- static const char KEY_PREVIEW_FRAME_RATE[];
- // Supported number of preview frames per second.
- // Example value: "24,15,10". Read.
- static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
- // The dimensions for captured pictures in pixels (width x height).
- // Example value: "1024x768". Read/write.
- static const char KEY_PICTURE_SIZE[];
- // Supported dimensions for captured pictures in pixels.
- // Example value: "2048x1536,1024x768". Read only.
- static const char KEY_SUPPORTED_PICTURE_SIZES[];
- // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
- // in frameworks/base/include/camera/Camera.h.
- // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
- static const char KEY_PICTURE_FORMAT[];
- // Supported image formats for captured pictures.
- // Example value: "jpeg,rgb565". Read only.
- static const char KEY_SUPPORTED_PICTURE_FORMATS[];
- // The width (in pixels) of EXIF thumbnail in Jpeg picture.
- // Example value: "512". Read/write.
- static const char KEY_JPEG_THUMBNAIL_WIDTH[];
- // The height (in pixels) of EXIF thumbnail in Jpeg picture.
- // Example value: "384". Read/write.
- static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
- // Supported EXIF thumbnail sizes (width x height). 0x0 means not thumbnail
- // in EXIF.
- // Example value: "512x384,320x240,0x0". Read only.
- static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[];
- // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100,
- // with 100 being the best.
- // Example value: "90". Read/write.
- static const char KEY_JPEG_THUMBNAIL_QUALITY[];
- // Jpeg quality of captured picture. The range is 1 to 100, with 100 being
- // the best.
- // Example value: "90". Read/write.
- static const char KEY_JPEG_QUALITY[];
- // The rotation angle in degrees relative to the orientation of the camera.
- // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The
- // camera driver may set orientation in the EXIF header without rotating the
- // picture. Or the driver may rotate the picture and the EXIF thumbnail. If
- // the Jpeg picture is rotated, the orientation in the EXIF header will be
- // missing or 1 (row #0 is top and column #0 is left side).
- //
- // Note that the JPEG pictures of front-facing cameras are not mirrored
- // as in preview display.
- //
- // For example, suppose the natural orientation of the device is portrait.
- // The device is rotated 270 degrees clockwise, so the device orientation is
- // 270. Suppose a back-facing camera sensor is mounted in landscape and the
- // top side of the camera sensor is aligned with the right edge of the
- // display in natural orientation. So the camera orientation is 90. The
- // rotation should be set to 0 (270 + 90).
- //
- // Example value: "0" or "90" or "180" or "270". Write only.
- static const char KEY_ROTATION[];
- // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
- // JPEG EXIF header.
- // Example value: "25.032146" or "-33.462809". Write only.
- static const char KEY_GPS_LATITUDE[];
- // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored
- // in JPEG EXIF header.
- // Example value: "121.564448" or "-70.660286". Write only.
- static const char KEY_GPS_LONGITUDE[];
- // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF
- // header.
- // Example value: "21.0" or "-5". Write only.
- static const char KEY_GPS_ALTITUDE[];
- // GPS timestamp (UTC in seconds since January 1, 1970). This should be
- // stored in JPEG EXIF header.
- // Example value: "1251192757". Write only.
- static const char KEY_GPS_TIMESTAMP[];
- // GPS Processing Method
- // Example value: "GPS" or "NETWORK". Write only.
- static const char KEY_GPS_PROCESSING_METHOD[];
- // Current white balance setting.
- // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write.
- static const char KEY_WHITE_BALANCE[];
- // Supported white balance settings.
- // Example value: "auto,incandescent,daylight". Read only.
- static const char KEY_SUPPORTED_WHITE_BALANCE[];
- // Current color effect setting.
- // Example value: "none" or EFFECT_XXX constants. Read/write.
- static const char KEY_EFFECT[];
- // Supported color effect settings.
- // Example value: "none,mono,sepia". Read only.
- static const char KEY_SUPPORTED_EFFECTS[];
- // Current antibanding setting.
- // Example value: "auto" or ANTIBANDING_XXX constants. Read/write.
- static const char KEY_ANTIBANDING[];
- // Supported antibanding settings.
- // Example value: "auto,50hz,60hz,off". Read only.
- static const char KEY_SUPPORTED_ANTIBANDING[];
- // Current scene mode.
- // Example value: "auto" or SCENE_MODE_XXX constants. Read/write.
- static const char KEY_SCENE_MODE[];
- // Supported scene mode settings.
- // Example value: "auto,night,fireworks". Read only.
- static const char KEY_SUPPORTED_SCENE_MODES[];
- // Current flash mode.
- // Example value: "auto" or FLASH_MODE_XXX constants. Read/write.
- static const char KEY_FLASH_MODE[];
- // Supported flash modes.
- // Example value: "auto,on,off". Read only.
- static const char KEY_SUPPORTED_FLASH_MODES[];
- // Current focus mode. This will not be empty. Applications should call
- // CameraHardwareInterface.autoFocus to start the focus if focus mode is
- // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
- // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
- static const char KEY_FOCUS_MODE[];
- // Supported focus modes.
- // Example value: "auto,macro,fixed". Read only.
- static const char KEY_SUPPORTED_FOCUS_MODES[];
- // The maximum number of focus areas supported. This is the maximum length
- // of KEY_FOCUS_AREAS.
- // Example value: "0" or "2". Read only.
- static const char KEY_MAX_NUM_FOCUS_AREAS[];
- // Current focus areas.
- //
- // Before accessing this parameter, apps should check
- // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas
- // first. If the value is 0, focus area is not supported.
- //
- // Each focus area is a five-element int array. The first four elements are
- // the rectangle of the area (left, top, right, bottom). The direction is
- // relative to the sensor orientation, that is, what the sensor sees. The
- // direction is not affected by the rotation or mirroring of
- // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000.
- // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right
- // point. The width and height of focus areas cannot be 0 or negative.
- //
- // The fifth element is the weight. Values for weight must range from 1 to
- // 1000. The weight should be interpreted as a per-pixel weight - all
- // pixels in the area have the specified weight. This means a small area
- // with the same weight as a larger area will have less influence on the
- // focusing than the larger area. Focus areas can partially overlap and the
- // driver will add the weights in the overlap region.
- //
- // A special case of single focus area (0,0,0,0,0) means driver to decide
- // the focus area. For example, the driver may use more signals to decide
- // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they
- // want the driver to decide focus areas.
- //
- // Focus areas are relative to the current field of view (KEY_ZOOM). No
- // matter what the zoom level is, (-1000,-1000) represents the top of the
- // currently visible camera frame. The focus area cannot be set to be
- // outside the current field of view, even when using zoom.
- //
- // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
- // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
- // FOCUS_MODE_CONTINUOUS_PICTURE.
- // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
- static const char KEY_FOCUS_AREAS[];
- // Focal length in millimeter.
- // Example value: "4.31". Read only.
- static const char KEY_FOCAL_LENGTH[];
- // Horizontal angle of view in degrees.
- // Example value: "54.8". Read only.
- static const char KEY_HORIZONTAL_VIEW_ANGLE[];
- // Vertical angle of view in degrees.
- // Example value: "42.5". Read only.
- static const char KEY_VERTICAL_VIEW_ANGLE[];
- // Exposure compensation index. 0 means exposure is not adjusted.
- // Example value: "-5" or "5". Read/write.
- static const char KEY_EXPOSURE_COMPENSATION[];
- // The maximum exposure compensation index (>=0).
- // Example value: "6". Read only.
- static const char KEY_MAX_EXPOSURE_COMPENSATION[];
- // The minimum exposure compensation index (<=0).
- // Example value: "-6". Read only.
- static const char KEY_MIN_EXPOSURE_COMPENSATION[];
- // The exposure compensation step. Exposure compensation index multiply by
- // step eqals to EV. Ex: if exposure compensation index is -6 and step is
- // 0.3333, EV is -2.
- // Example value: "0.333333333" or "0.5". Read only.
- static const char KEY_EXPOSURE_COMPENSATION_STEP[];
- // The state of the auto-exposure lock. "true" means that
- // auto-exposure is locked to its current value and will not
- // change. "false" means the auto-exposure routine is free to
- // change exposure values. If auto-exposure is already locked,
- // setting this to true again has no effect (the driver will not
- // recalculate exposure values). Changing exposure compensation
- // settings will still affect the exposure settings while
- // auto-exposure is locked. Stopping preview or taking a still
- // image will not change the lock. In conjunction with
- // exposure compensation, this allows for capturing multi-exposure
- // brackets with known relative exposure values. Locking
- // auto-exposure after open but before the first call to
- // startPreview may result in severely over- or under-exposed
- // images. The driver will not change the AE lock after
- // auto-focus completes.
- static const char KEY_AUTO_EXPOSURE_LOCK[];
- // Whether locking the auto-exposure is supported. "true" means it is, and
- // "false" or this key not existing means it is not supported.
- static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
- // The state of the auto-white balance lock. "true" means that
- // auto-white balance is locked to its current value and will not
- // change. "false" means the auto-white balance routine is free to
- // change white balance values. If auto-white balance is already
- // locked, setting this to true again has no effect (the driver
- // will not recalculate white balance values). Stopping preview or
- // taking a still image will not change the lock. In conjunction
- // with exposure compensation, this allows for capturing
- // multi-exposure brackets with fixed white balance. Locking
- // auto-white balance after open but before the first call to
- // startPreview may result in severely incorrect color. The
- // driver will not change the AWB lock after auto-focus
- // completes.
- static const char KEY_AUTO_WHITEBALANCE_LOCK[];
- // Whether locking the auto-white balance is supported. "true"
- // means it is, and "false" or this key not existing means it is
- // not supported.
- static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
-
- // The maximum number of metering areas supported. This is the maximum
- // length of KEY_METERING_AREAS.
- // Example value: "0" or "2". Read only.
- static const char KEY_MAX_NUM_METERING_AREAS[];
- // Current metering areas. Camera driver uses these areas to decide
- // exposure.
- //
- // Before accessing this parameter, apps should check
- // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering
- // areas first. If the value is 0, metering area is not supported.
- //
- // Each metering area is a rectangle with specified weight. The direction is
- // relative to the sensor orientation, that is, what the sensor sees. The
- // direction is not affected by the rotation or mirroring of
- // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range
- // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000)
- // is the lower right point. The width and height of metering areas cannot
- // be 0 or negative.
- //
- // The fifth element is the weight. Values for weight must range from 1 to
- // 1000. The weight should be interpreted as a per-pixel weight - all
- // pixels in the area have the specified weight. This means a small area
- // with the same weight as a larger area will have less influence on the
- // metering than the larger area. Metering areas can partially overlap and
- // the driver will add the weights in the overlap region.
- //
- // A special case of all-zero single metering area means driver to decide
- // the metering area. For example, the driver may use more signals to decide
- // metering areas and change them dynamically. Apps can set all-zero if they
- // want the driver to decide metering areas.
- //
- // Metering areas are relative to the current field of view (KEY_ZOOM).
- // No matter what the zoom level is, (-1000,-1000) represents the top of the
- // currently visible camera frame. The metering area cannot be set to be
- // outside the current field of view, even when using zoom.
- //
- // No matter what metering areas are, the final exposure are compensated
- // by KEY_EXPOSURE_COMPENSATION.
- // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
- static const char KEY_METERING_AREAS[];
- // Current zoom value.
- // Example value: "0" or "6". Read/write.
- static const char KEY_ZOOM[];
- // Maximum zoom value.
- // Example value: "6". Read only.
- static const char KEY_MAX_ZOOM[];
- // The zoom ratios of all zoom values. The zoom ratio is in 1/100
- // increments. Ex: a zoom of 3.2x is returned as 320. The number of list
- // elements is KEY_MAX_ZOOM + 1. The first element is always 100. The last
- // element is the zoom ratio of zoom value KEY_MAX_ZOOM.
- // Example value: "100,150,200,250,300,350,400". Read only.
- static const char KEY_ZOOM_RATIOS[];
- // Whether zoom is supported. Zoom is supported if the value is "true". Zoom
- // is not supported if the value is not "true" or the key does not exist.
- // Example value: "true". Read only.
- static const char KEY_ZOOM_SUPPORTED[];
- // Whether if smooth zoom is supported. Smooth zoom is supported if the
- // value is "true". It is not supported if the value is not "true" or the
- // key does not exist.
- // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and
- // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h.
- // Example value: "true". Read only.
- static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
-
- // The distances (in meters) from the camera to where an object appears to
- // be in focus. The object is sharpest at the optimal focus distance. The
- // depth of field is the far focus distance minus near focus distance.
- //
- // Focus distances may change after starting auto focus, canceling auto
- // focus, or starting the preview. Applications can read this anytime to get
- // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
- // focus distances may change from time to time.
- //
- // This is intended to estimate the distance between the camera and the
- // subject. After autofocus, the subject distance may be within near and far
- // focus distance. However, the precision depends on the camera hardware,
- // autofocus algorithm, the focus area, and the scene. The error can be
- // large and it should be only used as a reference.
- //
- // Far focus distance > optimal focus distance > near focus distance. If
- // the far focus distance is infinity, the value should be "Infinity" (case
- // sensitive). The format is three float values separated by commas. The
- // first is near focus distance. The second is optimal focus distance. The
- // third is far focus distance.
- // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
- static const char KEY_FOCUS_DISTANCES[];
-
- // The current dimensions in pixels (width x height) for video frames.
- // The width and height must be one of the supported sizes retrieved
- // via KEY_SUPPORTED_VIDEO_SIZES.
- // Example value: "1280x720". Read/write.
- static const char KEY_VIDEO_SIZE[];
- // A list of the supported dimensions in pixels (width x height)
- // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in
- // frameworks/base/include/camera/Camera.h.
- // Example: "176x144,1280x720". Read only.
- static const char KEY_SUPPORTED_VIDEO_SIZES[];
-
- // The maximum number of detected faces supported by hardware face
- // detection. If the value is 0, hardware face detection is not supported.
- // Example: "5". Read only
- static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
-
- // The maximum number of detected faces supported by software face
- // detection. If the value is 0, software face detection is not supported.
- // Example: "5". Read only
- static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
-
- // Preferred preview frame size in pixels for video recording.
- // The width and height must be one of the supported sizes retrieved
- // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
- // getSupportedVideoSizes() does not return an empty Vector of Size.
- // Camcorder applications are recommended to set the preview size
- // to a value that is not larger than the preferred preview size.
- // In other words, the product of the width and height of the
- // preview size should not be larger than that of the preferred
- // preview size. In addition, we recommend to choos a preview size
- // that has the same aspect ratio as the resolution of video to be
- // recorded.
- // Example value: "800x600". Read only.
- static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[];
-
- // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in
- // frameworks/base/include/camera/Camera.h.
- // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
- static const char KEY_VIDEO_FRAME_FORMAT[];
-
- // Sets the hint of the recording mode. If this is true, MediaRecorder.start
- // may be faster or has less glitches. This should be called before starting
- // the preview for the best result. But it is allowed to change the hint
- // while the preview is active. The default value is false.
- //
- // The apps can still call Camera.takePicture when the hint is true. The
- // apps can call MediaRecorder.start when the hint is false. But the
- // performance may be worse.
- // Example value: "true" or "false". Read/write.
- static const char KEY_RECORDING_HINT[];
-
- // Returns true if video snapshot is supported. That is, applications
- // can call Camera.takePicture during recording. Applications do not need to
- // call Camera.startPreview after taking a picture. The preview will be
- // still active. Other than that, taking a picture during recording is
- // identical to taking a picture normally. All settings and methods related
- // to takePicture work identically. Ex: KEY_PICTURE_SIZE,
- // KEY_SUPPORTED_PICTURE_SIZES, KEY_JPEG_QUALITY, KEY_ROTATION, and etc.
- // The picture will have an EXIF header. FLASH_MODE_AUTO and FLASH_MODE_ON
- // also still work, but the video will record the flash.
- //
- // Applications can set shutter callback as null to avoid the shutter
- // sound. It is also recommended to set raw picture and post view callbacks
- // to null to avoid the interrupt of preview display.
- //
- // Field-of-view of the recorded video may be different from that of the
- // captured pictures.
- // Example value: "true" or "false". Read only.
- static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
-
- // The state of the video stabilization. If set to true, both the
- // preview stream and the recorded video stream are stabilized by
- // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is
- // set to true.
- //
- // The value of this key can be changed any time the camera is
- // open. If preview or recording is active, it is acceptable for
- // there to be a slight video glitch when video stabilization is
- // toggled on and off.
- //
- // This only stabilizes video streams (between-frames stabilization), and
- // has no effect on still image capture.
- static const char KEY_VIDEO_STABILIZATION[];
-
- // Returns true if video stabilization is supported. That is, applications
- // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview
- // stream and record stabilized videos.
- static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
-
- // Supported modes for special effects with light.
- // Example values: "lowlight,hdr".
- static const char KEY_LIGHTFX[];
-
- // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
- static const char TRUE[];
- static const char FALSE[];
-
- // Value for KEY_FOCUS_DISTANCES.
- static const char FOCUS_DISTANCE_INFINITY[];
-
- // Values for white balance settings.
- static const char WHITE_BALANCE_AUTO[];
- static const char WHITE_BALANCE_INCANDESCENT[];
- static const char WHITE_BALANCE_FLUORESCENT[];
- static const char WHITE_BALANCE_WARM_FLUORESCENT[];
- static const char WHITE_BALANCE_DAYLIGHT[];
- static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[];
- static const char WHITE_BALANCE_TWILIGHT[];
- static const char WHITE_BALANCE_SHADE[];
-
- // Values for effect settings.
- static const char EFFECT_NONE[];
- static const char EFFECT_MONO[];
- static const char EFFECT_NEGATIVE[];
- static const char EFFECT_SOLARIZE[];
- static const char EFFECT_SEPIA[];
- static const char EFFECT_POSTERIZE[];
- static const char EFFECT_WHITEBOARD[];
- static const char EFFECT_BLACKBOARD[];
- static const char EFFECT_AQUA[];
-
- // Values for antibanding settings.
- static const char ANTIBANDING_AUTO[];
- static const char ANTIBANDING_50HZ[];
- static const char ANTIBANDING_60HZ[];
- static const char ANTIBANDING_OFF[];
-
- // Values for flash mode settings.
- // Flash will not be fired.
- static const char FLASH_MODE_OFF[];
- // Flash will be fired automatically when required. The flash may be fired
- // during preview, auto-focus, or snapshot depending on the driver.
- static const char FLASH_MODE_AUTO[];
- // Flash will always be fired during snapshot. The flash may also be
- // fired during preview or auto-focus depending on the driver.
- static const char FLASH_MODE_ON[];
- // Flash will be fired in red-eye reduction mode.
- static const char FLASH_MODE_RED_EYE[];
- // Constant emission of light during preview, auto-focus and snapshot.
- // This can also be used for video recording.
- static const char FLASH_MODE_TORCH[];
-
- // Values for scene mode settings.
- static const char SCENE_MODE_AUTO[];
- static const char SCENE_MODE_ACTION[];
- static const char SCENE_MODE_PORTRAIT[];
- static const char SCENE_MODE_LANDSCAPE[];
- static const char SCENE_MODE_NIGHT[];
- static const char SCENE_MODE_NIGHT_PORTRAIT[];
- static const char SCENE_MODE_THEATRE[];
- static const char SCENE_MODE_BEACH[];
- static const char SCENE_MODE_SNOW[];
- static const char SCENE_MODE_SUNSET[];
- static const char SCENE_MODE_STEADYPHOTO[];
- static const char SCENE_MODE_FIREWORKS[];
- static const char SCENE_MODE_SPORTS[];
- static const char SCENE_MODE_PARTY[];
- static const char SCENE_MODE_CANDLELIGHT[];
- // Applications are looking for a barcode. Camera driver will be optimized
- // for barcode reading.
- static const char SCENE_MODE_BARCODE[];
- // A high-dynamic range mode. In this mode, the HAL module will use a
- // capture strategy that extends the dynamic range of the captured
- // image in some fashion. Only the final image is returned.
- static const char SCENE_MODE_HDR[];
-
- // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT,
- // and KEY_VIDEO_FRAME_FORMAT
- static const char PIXEL_FORMAT_YUV422SP[];
- static const char PIXEL_FORMAT_YUV420SP[]; // NV21
- static const char PIXEL_FORMAT_YUV422I[]; // YUY2
- static const char PIXEL_FORMAT_YUV420P[]; // YV12
- static const char PIXEL_FORMAT_RGB565[];
- static const char PIXEL_FORMAT_RGBA8888[];
- static const char PIXEL_FORMAT_JPEG[];
- // Raw bayer format used for images, which is 10 bit precision samples
- // stored in 16 bit words. The filter pattern is RGGB.
- static const char PIXEL_FORMAT_BAYER_RGGB[];
- // Pixel format is not known to the framework
- static const char PIXEL_FORMAT_ANDROID_OPAQUE[];
-
- // Values for focus mode settings.
- // Auto-focus mode. Applications should call
- // CameraHardwareInterface.autoFocus to start the focus in this mode.
- static const char FOCUS_MODE_AUTO[];
- // Focus is set at infinity. Applications should not call
- // CameraHardwareInterface.autoFocus in this mode.
- static const char FOCUS_MODE_INFINITY[];
- // Macro (close-up) focus mode. Applications should call
- // CameraHardwareInterface.autoFocus to start the focus in this mode.
- static const char FOCUS_MODE_MACRO[];
- // Focus is fixed. The camera is always in this mode if the focus is not
- // adjustable. If the camera has auto-focus, this mode can fix the
- // focus, which is usually at hyperfocal distance. Applications should
- // not call CameraHardwareInterface.autoFocus in this mode.
- static const char FOCUS_MODE_FIXED[];
- // Extended depth of field (EDOF). Focusing is done digitally and
- // continuously. Applications should not call
- // CameraHardwareInterface.autoFocus in this mode.
- static const char FOCUS_MODE_EDOF[];
- // Continuous auto focus mode intended for video recording. The camera
- // continuously tries to focus. This is the best choice for video
- // recording because the focus changes smoothly . Applications still can
- // call CameraHardwareInterface.takePicture in this mode but the subject may
- // not be in focus. Auto focus starts when the parameter is set.
- //
- // Applications can call CameraHardwareInterface.autoFocus in this mode. The
- // focus callback will immediately return with a boolean that indicates
- // whether the focus is sharp or not. The focus position is locked after
- // autoFocus call. If applications want to resume the continuous focus,
- // cancelAutoFocus must be called. Restarting the preview will not resume
- // the continuous autofocus. To stop continuous focus, applications should
- // change the focus mode to other modes.
- static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
- // Continuous auto focus mode intended for taking pictures. The camera
- // continuously tries to focus. The speed of focus change is more aggressive
- // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
- // set.
- //
- // Applications can call CameraHardwareInterface.autoFocus in this mode. If
- // the autofocus is in the middle of scanning, the focus callback will
- // return when it completes. If the autofocus is not scanning, focus
- // callback will immediately return with a boolean that indicates whether
- // the focus is sharp or not. The apps can then decide if they want to take
- // a picture immediately or to change the focus mode to auto, and run a full
- // autofocus cycle. The focus position is locked after autoFocus call. If
- // applications want to resume the continuous focus, cancelAutoFocus must be
- // called. Restarting the preview will not resume the continuous autofocus.
- // To stop continuous focus, applications should change the focus mode to
- // other modes.
- static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
-
- // Values for light special effects
- // Low-light enhancement mode
- static const char LIGHTFX_LOWLIGHT[];
- // High-dynamic range mode
- static const char LIGHTFX_HDR[];
-
- /**
- * Returns the the supported preview formats as an enum given in graphics.h
- * corrsponding to the format given in the input string or -1 if no such
- * conversion exists.
- */
- static int previewFormatToEnum(const char* format);
-
-private:
- DefaultKeyedVector<String8,String8> mMap;
-};
-
-};
-};
-};
-};
-};
-}; // namespace
-
-#endif
diff --git a/camera/common/1.0/default/include/Exif.h b/camera/common/1.0/default/include/Exif.h
deleted file mode 100644
index dc31679..0000000
--- a/camera/common/1.0/default/include/Exif.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
-#define ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
-
-#include "CameraMetadata.h"
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-
-// This is based on the original ChromeOS ARC implementation of a V4L2 HAL
-
-// ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can
-// also add a thumbnail in the APP1 segment if thumbnail size is specified.
-// ExifUtils can be reused with different images by calling initialize().
-//
-// Example of using this class :
-// std::unique_ptr<ExifUtils> utils(ExifUtils::Create());
-// utils->initialize();
-// ...
-// // Call ExifUtils functions to set Exif tags.
-// ...
-// utils->GenerateApp1(thumbnail_buffer, thumbnail_size);
-// unsigned int app1Length = utils->GetApp1Length();
-// uint8_t* app1Buffer = new uint8_t[app1Length];
-// memcpy(app1Buffer, utils->GetApp1Buffer(), app1Length);
-class ExifUtils {
-
- public:
- virtual ~ExifUtils();
-
- static ExifUtils* create();
-
- // Initialize() can be called multiple times. The setting of Exif tags will be
- // cleared.
- virtual bool initialize() = 0;
-
- // Set all known fields from a metadata structure
- virtual bool setFromMetadata(const CameraMetadata& metadata,
- const size_t imageWidth,
- const size_t imageHeight) = 0;
-
- // Sets the len aperture.
- // Returns false if memory allocation fails.
- virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the value of brightness.
- // Returns false if memory allocation fails.
- virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
-
- // Sets the color space.
- // Returns false if memory allocation fails.
- virtual bool setColorSpace(uint16_t color_space) = 0;
-
- // Sets the information to compressed data.
- // Returns false if memory allocation fails.
- virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
-
- // Sets the compression scheme used for the image data.
- // Returns false if memory allocation fails.
- virtual bool setCompression(uint16_t compression) = 0;
-
- // Sets image contrast.
- // Returns false if memory allocation fails.
- virtual bool setContrast(uint16_t contrast) = 0;
-
- // Sets the date and time of image last modified. It takes local time. The
- // name of the tag is DateTime in IFD0.
- // Returns false if memory allocation fails.
- virtual bool setDateTime(const struct tm& t) = 0;
-
- // Sets the image description.
- // Returns false if memory allocation fails.
- virtual bool setDescription(const std::string& description) = 0;
-
- // Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
- // was not used.
- // Returns false if memory allocation fails.
- virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the exposure bias.
- // Returns false if memory allocation fails.
- virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
-
- // Sets the exposure mode set when the image was shot.
- // Returns false if memory allocation fails.
- virtual bool setExposureMode(uint16_t exposure_mode) = 0;
-
- // Sets the program used by the camera to set exposure when the picture is
- // taken.
- // Returns false if memory allocation fails.
- virtual bool setExposureProgram(uint16_t exposure_program) = 0;
-
- // Sets the exposure time, given in seconds.
- // Returns false if memory allocation fails.
- virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the status of flash.
- // Returns false if memory allocation fails.
- virtual bool setFlash(uint16_t flash) = 0;
-
- // Sets the F number.
- // Returns false if memory allocation fails.
- virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the focal length of lens used to take the image in millimeters.
- // Returns false if memory allocation fails.
- virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the degree of overall image gain adjustment.
- // Returns false if memory allocation fails.
- virtual bool setGainControl(uint16_t gain_control) = 0;
-
- // Sets the altitude in meters.
- // Returns false if memory allocation fails.
- virtual bool setGpsAltitude(double altitude) = 0;
-
- // Sets the latitude with degrees minutes seconds format.
- // Returns false if memory allocation fails.
- virtual bool setGpsLatitude(double latitude) = 0;
-
- // Sets the longitude with degrees minutes seconds format.
- // Returns false if memory allocation fails.
- virtual bool setGpsLongitude(double longitude) = 0;
-
- // Sets GPS processing method.
- // Returns false if memory allocation fails.
- virtual bool setGpsProcessingMethod(const std::string& method) = 0;
-
- // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
- // Returns false if memory allocation fails.
- virtual bool setGpsTimestamp(const struct tm& t) = 0;
-
- // Sets the height (number of rows) of main image.
- // Returns false if memory allocation fails.
- virtual bool setImageHeight(uint32_t length) = 0;
-
- // Sets the width (number of columns) of main image.
- // Returns false if memory allocation fails.
- virtual bool setImageWidth(uint32_t width) = 0;
-
- // Sets the ISO speed.
- // Returns false if memory allocation fails.
- virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
-
- // Sets the kind of light source.
- // Returns false if memory allocation fails.
- virtual bool setLightSource(uint16_t light_source) = 0;
-
- // Sets the smallest F number of the lens.
- // Returns false if memory allocation fails.
- virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the metering mode.
- // Returns false if memory allocation fails.
- virtual bool setMeteringMode(uint16_t metering_mode) = 0;
-
- // Sets image orientation.
- // Returns false if memory allocation fails.
- virtual bool setOrientation(uint16_t orientation) = 0;
-
- // Sets the unit for measuring XResolution and YResolution.
- // Returns false if memory allocation fails.
- virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
-
- // Sets image saturation.
- // Returns false if memory allocation fails.
- virtual bool setSaturation(uint16_t saturation) = 0;
-
- // Sets the type of scene that was shot.
- // Returns false if memory allocation fails.
- virtual bool setSceneCaptureType(uint16_t type) = 0;
-
- // Sets image sharpness.
- // Returns false if memory allocation fails.
- virtual bool setSharpness(uint16_t sharpness) = 0;
-
- // Sets the shutter speed.
- // Returns false if memory allocation fails.
- virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
-
- // Sets the distance to the subject, given in meters.
- // Returns false if memory allocation fails.
- virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the fractions of seconds for the <DateTime> tag.
- // Returns false if memory allocation fails.
- virtual bool setSubsecTime(const std::string& subsec_time) = 0;
-
- // Sets the white balance mode set when the image was shot.
- // Returns false if memory allocation fails.
- virtual bool setWhiteBalance(uint16_t white_balance) = 0;
-
- // Sets the number of pixels per resolution unit in the image width.
- // Returns false if memory allocation fails.
- virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the position of chrominance components in relation to the luminance
- // component.
- // Returns false if memory allocation fails.
- virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
-
- // Sets the number of pixels per resolution unit in the image length.
- // Returns false if memory allocation fails.
- virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
-
- // Sets the manufacturer of camera.
- // Returns false if memory allocation fails.
- virtual bool setMake(const std::string& make) = 0;
-
- // Sets the model number of camera.
- // Returns false if memory allocation fails.
- virtual bool setModel(const std::string& model) = 0;
-
- // Generates APP1 segment.
- // Returns false if generating APP1 segment fails.
- virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size) = 0;
-
- // Gets buffer of APP1 segment. This method must be called only after calling
- // GenerateAPP1().
- virtual const uint8_t* getApp1Buffer() = 0;
-
- // Gets length of APP1 segment. This method must be called only after calling
- // GenerateAPP1().
- virtual unsigned int getApp1Length() = 0;
-};
-
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-
-#endif // ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h
deleted file mode 100644
index 83fa755..0000000
--- a/camera/common/1.0/default/include/HandleImporter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CAMERA_COMMON_1_0_HANDLEIMPORTED_H
-#define CAMERA_COMMON_1_0_HANDLEIMPORTED_H
-
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <android/hardware/graphics/mapper/3.0/IMapper.h>
-#include <android/hardware/graphics/mapper/4.0/IMapper.h>
-#include <cutils/native_handle.h>
-#include <utils/Mutex.h>
-
-using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
-
-namespace android {
-namespace hardware {
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-// Borrowed from graphics HAL. Use this until gralloc mapper HAL is working
-class HandleImporter {
-public:
- HandleImporter();
-
- // In IComposer, any buffer_handle_t is owned by the caller and we need to
- // make a clone for hwcomposer2. We also need to translate empty handle
- // to nullptr. This function does that, in-place.
- bool importBuffer(buffer_handle_t& handle);
- void freeBuffer(buffer_handle_t handle);
- bool importFence(const native_handle_t* handle, int& fd) const;
- void closeFence(int fd) const;
-
- // Locks 1-D buffer. Assumes caller has waited for acquire fences.
- void* lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size);
-
- // Locks 2-D buffer. Assumes caller has waited for acquire fences.
- void* lock(buffer_handle_t& buf, uint64_t cpuUsage, const IMapper::Rect& accessRegion);
-
- // Assumes caller has waited for acquire fences.
- YCbCrLayout lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion);
-
- // Query the stride of the first plane in bytes.
- status_t getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/);
-
- int unlock(buffer_handle_t& buf); // returns release fence
-
- // Query Gralloc4 metadata
- bool isSmpte2086Present(const buffer_handle_t& buf);
- bool isSmpte2094_10Present(const buffer_handle_t& buf);
- bool isSmpte2094_40Present(const buffer_handle_t& buf);
-
-private:
- void initializeLocked();
- void cleanup();
-
- template<class M, class E>
- bool importBufferInternal(const sp<M> mapper, buffer_handle_t& handle);
- template<class M, class E>
- YCbCrLayout lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
- const IMapper::Rect& accessRegion);
- template<class M, class E>
- int unlockInternal(const sp<M> mapper, buffer_handle_t& buf);
-
- Mutex mLock;
- bool mInitialized;
- sp<IMapper> mMapperV2;
- sp<graphics::mapper::V3_0::IMapper> mMapperV3;
- sp<graphics::mapper::V4_0::IMapper> mMapperV4;
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif // CAMERA_COMMON_1_0_HANDLEIMPORTED_H
diff --git a/camera/common/1.0/default/include/VendorTagDescriptor.h b/camera/common/1.0/default/include/VendorTagDescriptor.h
deleted file mode 100644
index 0f54db5..0000000
--- a/camera/common/1.0/default/include/VendorTagDescriptor.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
-#define CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
-
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-#include <utils/RefBase.h>
-#include <system/camera_vendor_tags.h>
-
-#include <stdint.h>
-#include <unordered_map>
-
-namespace android {
-namespace hardware {
-namespace camera2 {
-namespace params {
-
-/**
- * VendorTagDescriptor objects are containers for the vendor tag
- * definitions provided, and are typically used to pass the vendor tag
- * information enumerated by the HAL to clients of the camera service.
- */
-class VendorTagDescriptor {
- public:
- virtual ~VendorTagDescriptor();
-
- VendorTagDescriptor();
- VendorTagDescriptor(const VendorTagDescriptor& src);
- VendorTagDescriptor& operator=(const VendorTagDescriptor& rhs);
-
- void copyFrom(const VendorTagDescriptor& src);
-
- /**
- * The following 'get*' methods implement the corresponding
- * functions defined in
- * system/media/camera/include/system/camera_vendor_tags.h
- */
-
- // Returns the number of vendor tags defined.
- int getTagCount() const;
-
- // Returns an array containing the id's of vendor tags defined.
- void getTagArray(uint32_t* tagArray) const;
-
- // Returns the section name string for a given vendor tag id.
- const char* getSectionName(uint32_t tag) const;
-
- // Returns the index in section vectors returned in getAllSectionNames()
- // for a given vendor tag id. -1 if input tag does not exist.
- ssize_t getSectionIndex(uint32_t tag) const;
-
- // Returns the tag name string for a given vendor tag id.
- const char* getTagName(uint32_t tag) const;
-
- // Returns the tag type for a given vendor tag id.
- int getTagType(uint32_t tag) const;
-
- /**
- * Convenience method to get a vector containing all vendor tag
- * sections, or an empty vector if none are defined.
- * The pointer is valid for the lifetime of the VendorTagDescriptor,
- * or until copyFrom is invoked.
- */
- const SortedVector<String8>* getAllSectionNames() const;
-
- /**
- * Lookup the tag id for a given tag name and section.
- *
- * Returns OK on success, or a negative error code.
- */
- status_t lookupTag(const String8& name, const String8& section, /*out*/uint32_t* tag) const;
-
- /**
- * Dump the currently configured vendor tags to a file descriptor.
- */
- void dump(int fd, int verbosity, int indentation) const;
-
- protected:
- KeyedVector<String8, KeyedVector<String8, uint32_t>*> mReverseMapping;
- KeyedVector<uint32_t, String8> mTagToNameMap;
- KeyedVector<uint32_t, uint32_t> mTagToSectionMap; // Value is offset in mSections
-
- std::unordered_map<uint32_t, int32_t> mTagToTypeMap;
- SortedVector<String8> mSections;
- // must be int32_t to be compatible with Parcel::writeInt32
- int32_t mTagCount;
-
- vendor_tag_ops mVendorOps;
-};
-} /* namespace params */
-} /* namespace camera2 */
-
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-/**
- * This version of VendorTagDescriptor must be stored in Android sp<>, and adds support for using it
- * as a global tag descriptor.
- *
- * It's a child class of the basic hardware::camera2::params::VendorTagDescriptor since basic
- * Parcelable objects cannot require being kept in an sp<> and still work with auto-generated AIDL
- * interface implementations.
- */
-class VendorTagDescriptor :
- public ::android::hardware::camera2::params::VendorTagDescriptor,
- public LightRefBase<VendorTagDescriptor> {
-
- public:
-
- /**
- * Create a VendorTagDescriptor object from the given vendor_tag_ops_t
- * struct.
- *
- * Returns OK on success, or a negative error code.
- */
- static status_t createDescriptorFromOps(const vendor_tag_ops_t* vOps,
- /*out*/
- sp<VendorTagDescriptor>& descriptor);
-
- /**
- * Sets the global vendor tag descriptor to use for this process.
- * Camera metadata operations that access vendor tags will use the
- * vendor tag definitions set this way.
- *
- * Returns OK on success, or a negative error code.
- */
- static status_t setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc);
-
- /**
- * Returns the global vendor tag descriptor used by this process.
- * This will contain NULL if no vendor tags are defined.
- */
- static sp<VendorTagDescriptor> getGlobalVendorTagDescriptor();
-
- /**
- * Clears the global vendor tag descriptor used by this process.
- */
- static void clearGlobalVendorTagDescriptor();
-
-};
-
-} /* namespace helper */
-} /* namespace V1_0 */
-} /* namespace common */
-} /* namespace camera */
-
-namespace camera2 {
-namespace params {
-
-class VendorTagDescriptorCache {
- public:
- typedef android::hardware::camera::common::V1_0::helper::VendorTagDescriptor
- VendorTagDescriptor;
- VendorTagDescriptorCache(){};
- int32_t addVendorDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor> desc);
-
- int32_t getVendorTagDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor>* desc /*out*/);
-
- // Returns the number of vendor tags defined.
- int getTagCount(metadata_vendor_id_t id) const;
-
- // Returns an array containing the id's of vendor tags defined.
- void getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const;
-
- // Returns the section name string for a given vendor tag id.
- const char* getSectionName(uint32_t tag, metadata_vendor_id_t id) const;
-
- // Returns the tag name string for a given vendor tag id.
- const char* getTagName(uint32_t tag, metadata_vendor_id_t id) const;
-
- // Returns the tag type for a given vendor tag id.
- int getTagType(uint32_t tag, metadata_vendor_id_t id) const;
-
- /**
- * Dump the currently configured vendor tags to a file descriptor.
- */
- void dump(int fd, int verbosity, int indentation) const;
-
- protected:
- std::unordered_map<metadata_vendor_id_t, sp<VendorTagDescriptor>> mVendorMap;
- struct vendor_tag_cache_ops mVendorCacheOps;
-};
-
-} /* namespace params */
-} /* namespace camera2 */
-
-namespace camera {
-namespace common {
-namespace V1_0 {
-namespace helper {
-
-class VendorTagDescriptorCache
- : public ::android::hardware::camera2::params::VendorTagDescriptorCache,
- public LightRefBase<VendorTagDescriptorCache> {
- public:
- /**
- * Sets the global vendor tag descriptor cache to use for this process.
- * Camera metadata operations that access vendor tags will use the
- * vendor tag definitions set this way.
- *
- * Returns OK on success, or a negative error code.
- */
- static status_t setAsGlobalVendorTagCache(const sp<VendorTagDescriptorCache>& cache);
-
- /**
- * Returns the global vendor tag cache used by this process.
- * This will contain NULL if no vendor tags are defined.
- */
- static sp<VendorTagDescriptorCache> getGlobalVendorTagCache();
-
- /**
- * Clears the global vendor tag cache used by this process.
- */
- static void clearGlobalVendorTagCache();
-};
-
-} // namespace helper
-} // namespace V1_0
-} // namespace common
-} // namespace camera
-} // namespace hardware
-} // namespace android
-
-#endif /* CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H */
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index fa74392..4ffcfd9 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -20,6 +20,9 @@
java: {
enabled: false,
},
+ rust: {
+ enabled: true,
+ }
},
versions_with_info: [
{
diff --git a/camera/common/default/Android.bp b/camera/common/default/Android.bp
new file mode 100644
index 0000000..e8c8f9d
--- /dev/null
+++ b/camera/common/default/Android.bp
@@ -0,0 +1,48 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+ name: "android.hardware.camera.common-helper",
+ vendor_available: true,
+ defaults: ["hidl_defaults"],
+ srcs: [
+ "CameraModule.cpp",
+ "CameraMetadata.cpp",
+ "CameraParameters.cpp",
+ "VendorTagDescriptor.cpp",
+ "HandleImporter.cpp",
+ "Exif.cpp",
+ "SimpleThread.cpp",
+ ],
+ cflags: [
+ "-Werror",
+ "-Wextra",
+ "-Wall",
+ ],
+ shared_libs: [
+ "liblog",
+ "libgralloctypes",
+ "libhardware",
+ "libcamera_metadata",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "libexif",
+ ],
+ include_dirs: ["system/media/private/camera/include"],
+ export_include_dirs: ["include"],
+}
+
+// NOTE: Deprecated module kept for compatibility reasons.
+// Depend on "android.hardware.camera.common-helper" instead
+cc_library_static {
+ name: "[email protected]",
+ vendor_available: true,
+ whole_static_libs: ["android.hardware.camera.common-helper"],
+}
diff --git a/camera/common/default/CameraMetadata.cpp b/camera/common/default/CameraMetadata.cpp
new file mode 100644
index 0000000..ed56261
--- /dev/null
+++ b/camera/common/default/CameraMetadata.cpp
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2016 The Android Open 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_NDEBUG 0
+
+#define LOG_TAG "CamComm1.0-MD"
+#include <log/log.h>
+#include <utils/Errors.h>
+
+#include "CameraMetadata.h"
+#include "VendorTagDescriptor.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+#define ALIGN_TO(val, alignment) (((uintptr_t)(val) + ((alignment)-1)) & ~((alignment)-1))
+
+CameraMetadata::CameraMetadata() : mBuffer(NULL), mLocked(false) {}
+
+CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : mLocked(false) {
+ mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
+}
+
+CameraMetadata::CameraMetadata(const CameraMetadata& other) : mLocked(false) {
+ mBuffer = clone_camera_metadata(other.mBuffer);
+}
+
+CameraMetadata::CameraMetadata(camera_metadata_t* buffer) : mBuffer(NULL), mLocked(false) {
+ acquire(buffer);
+}
+
+CameraMetadata& CameraMetadata::operator=(const CameraMetadata& other) {
+ return operator=(other.mBuffer);
+}
+
+CameraMetadata& CameraMetadata::operator=(const camera_metadata_t* buffer) {
+ if (mLocked) {
+ ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
+ return *this;
+ }
+
+ if (CC_LIKELY(buffer != mBuffer)) {
+ camera_metadata_t* newBuffer = clone_camera_metadata(buffer);
+ clear();
+ mBuffer = newBuffer;
+ }
+ return *this;
+}
+
+CameraMetadata::~CameraMetadata() {
+ mLocked = false;
+ clear();
+}
+
+const camera_metadata_t* CameraMetadata::getAndLock() const {
+ mLocked = true;
+ return mBuffer;
+}
+
+status_t CameraMetadata::unlock(const camera_metadata_t* buffer) const {
+ if (!mLocked) {
+ ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if (buffer != mBuffer) {
+ ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ mLocked = false;
+ return OK;
+}
+
+camera_metadata_t* CameraMetadata::release() {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return NULL;
+ }
+ camera_metadata_t* released = mBuffer;
+ mBuffer = NULL;
+ return released;
+}
+
+void CameraMetadata::clear() {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return;
+ }
+ if (mBuffer) {
+ free_camera_metadata(mBuffer);
+ mBuffer = NULL;
+ }
+}
+
+void CameraMetadata::acquire(camera_metadata_t* buffer) {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return;
+ }
+ clear();
+ mBuffer = buffer;
+
+ ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/ NULL) != OK,
+ "%s: Failed to validate metadata structure %p", __FUNCTION__, buffer);
+}
+
+void CameraMetadata::acquire(CameraMetadata& other) {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return;
+ }
+ acquire(other.release());
+}
+
+status_t CameraMetadata::append(const CameraMetadata& other) {
+ return append(other.mBuffer);
+}
+
+status_t CameraMetadata::append(const camera_metadata_t* other) {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ size_t extraEntries = get_camera_metadata_entry_count(other);
+ size_t extraData = get_camera_metadata_data_count(other);
+ resizeIfNeeded(extraEntries, extraData);
+
+ return append_camera_metadata(mBuffer, other);
+}
+
+size_t CameraMetadata::entryCount() const {
+ return (mBuffer == NULL) ? 0 : get_camera_metadata_entry_count(mBuffer);
+}
+
+bool CameraMetadata::isEmpty() const {
+ return entryCount() == 0;
+}
+
+status_t CameraMetadata::sort() {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ return sort_camera_metadata(mBuffer);
+}
+
+status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
+ int tagType = get_local_camera_metadata_tag_type(tag, mBuffer);
+ if (CC_UNLIKELY(tagType == -1)) {
+ ALOGE("Update metadata entry: Unknown tag %d", tag);
+ return INVALID_OPERATION;
+ }
+ if (CC_UNLIKELY(tagType != expectedType)) {
+ ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
+ "got type %s data instead ",
+ get_local_camera_metadata_tag_name(tag, mBuffer), tag,
+ camera_metadata_type_names[tagType], camera_metadata_type_names[expectedType]);
+ return INVALID_OPERATION;
+ }
+ return OK;
+}
+
+status_t CameraMetadata::update(uint32_t tag, const int32_t* data, size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_INT32)) != OK) {
+ return res;
+ }
+ return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const uint8_t* data, size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_BYTE)) != OK) {
+ return res;
+ }
+ return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const float* data, size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_FLOAT)) != OK) {
+ return res;
+ }
+ return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const int64_t* data, size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_INT64)) != OK) {
+ return res;
+ }
+ return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const double* data, size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_DOUBLE)) != OK) {
+ return res;
+ }
+ return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const camera_metadata_rational_t* data,
+ size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_RATIONAL)) != OK) {
+ return res;
+ }
+ return updateImpl(tag, (const void*)data, data_count);
+}
+
+status_t CameraMetadata::update(uint32_t tag, const String8& string) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(tag, TYPE_BYTE)) != OK) {
+ return res;
+ }
+ // string.size() doesn't count the null termination character.
+ return updateImpl(tag, (const void*)string.string(), string.size() + 1);
+}
+
+status_t CameraMetadata::update(const camera_metadata_ro_entry& entry) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ if ((res = checkType(entry.tag, entry.type)) != OK) {
+ return res;
+ }
+ return updateImpl(entry.tag, (const void*)entry.data.u8, entry.count);
+}
+
+status_t CameraMetadata::updateImpl(uint32_t tag, const void* data, size_t data_count) {
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ int type = get_local_camera_metadata_tag_type(tag, mBuffer);
+ if (type == -1) {
+ ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ // Safety check - ensure that data isn't pointing to this metadata, since
+ // that would get invalidated if a resize is needed
+ size_t bufferSize = get_camera_metadata_size(mBuffer);
+ uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer);
+ uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data);
+ if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) {
+ ALOGE("%s: Update attempted with data from the same metadata buffer!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ size_t data_size = calculate_camera_metadata_entry_data_size(type, data_count);
+
+ res = resizeIfNeeded(1, data_size);
+
+ if (res == OK) {
+ camera_metadata_entry_t entry;
+ res = find_camera_metadata_entry(mBuffer, tag, &entry);
+ if (res == NAME_NOT_FOUND) {
+ res = add_camera_metadata_entry(mBuffer, tag, data, data_count);
+ } else if (res == OK) {
+ res = update_camera_metadata_entry(mBuffer, entry.index, data, data_count, NULL);
+ }
+ }
+
+ if (res != OK) {
+ ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__,
+ get_local_camera_metadata_section_name(tag, mBuffer),
+ get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
+ }
+
+ IF_ALOGV() {
+ ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/ NULL) != OK,
+
+ "%s: Failed to validate metadata structure after update %p", __FUNCTION__,
+ mBuffer);
+ }
+
+ return res;
+}
+
+bool CameraMetadata::exists(uint32_t tag) const {
+ camera_metadata_ro_entry entry;
+ return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
+}
+
+camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
+ status_t res;
+ camera_metadata_entry entry;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ entry.count = 0;
+ return entry;
+ }
+ res = find_camera_metadata_entry(mBuffer, tag, &entry);
+ if (CC_UNLIKELY(res != OK)) {
+ entry.count = 0;
+ entry.data.u8 = NULL;
+ }
+ return entry;
+}
+
+camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
+ status_t res;
+ camera_metadata_ro_entry entry;
+ res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
+ if (CC_UNLIKELY(res != OK)) {
+ entry.count = 0;
+ entry.data.u8 = NULL;
+ }
+ return entry;
+}
+
+status_t CameraMetadata::erase(uint32_t tag) {
+ camera_metadata_entry_t entry;
+ status_t res;
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+ res = find_camera_metadata_entry(mBuffer, tag, &entry);
+ if (res == NAME_NOT_FOUND) {
+ return OK;
+ } else if (res != OK) {
+ ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", __FUNCTION__,
+ get_local_camera_metadata_section_name(tag, mBuffer),
+ get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
+ return res;
+ }
+ res = delete_camera_metadata_entry(mBuffer, entry.index);
+ if (res != OK) {
+ ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", __FUNCTION__,
+ get_local_camera_metadata_section_name(tag, mBuffer),
+ get_local_camera_metadata_tag_name(tag, mBuffer), tag, strerror(-res), res);
+ }
+ return res;
+}
+
+void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
+ dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
+}
+
+status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
+ if (mBuffer == NULL) {
+ mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
+ if (mBuffer == NULL) {
+ ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
+ return NO_MEMORY;
+ }
+ } else {
+ size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
+ size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
+ size_t newEntryCount = currentEntryCount + extraEntries;
+ newEntryCount = (newEntryCount > currentEntryCap) ? newEntryCount * 2 : currentEntryCap;
+
+ size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
+ size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
+ size_t newDataCount = currentDataCount + extraData;
+ newDataCount = (newDataCount > currentDataCap) ? newDataCount * 2 : currentDataCap;
+
+ if (newEntryCount > currentEntryCap || newDataCount > currentDataCap) {
+ camera_metadata_t* oldBuffer = mBuffer;
+ mBuffer = allocate_camera_metadata(newEntryCount, newDataCount);
+ if (mBuffer == NULL) {
+ ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
+ return NO_MEMORY;
+ }
+ append_camera_metadata(mBuffer, oldBuffer);
+ free_camera_metadata(oldBuffer);
+ }
+ }
+ return OK;
+}
+
+void CameraMetadata::swap(CameraMetadata& other) {
+ if (mLocked) {
+ ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
+ return;
+ } else if (other.mLocked) {
+ ALOGE("%s: Other CameraMetadata is locked", __FUNCTION__);
+ return;
+ }
+
+ camera_metadata* thisBuf = mBuffer;
+ camera_metadata* otherBuf = other.mBuffer;
+
+ other.mBuffer = thisBuf;
+ mBuffer = otherBuf;
+}
+
+status_t CameraMetadata::getTagFromName(const char* name, const VendorTagDescriptor* vTags,
+ uint32_t* tag) {
+ if (name == nullptr || tag == nullptr) return BAD_VALUE;
+
+ size_t nameLength = strlen(name);
+
+ const SortedVector<String8>* vendorSections;
+ size_t vendorSectionCount = 0;
+
+ if (vTags != NULL) {
+ vendorSections = vTags->getAllSectionNames();
+ vendorSectionCount = vendorSections->size();
+ }
+
+ // First, find the section by the longest string match
+ const char* section = NULL;
+ size_t sectionIndex = 0;
+ size_t sectionLength = 0;
+ size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount;
+ for (size_t i = 0; i < totalSectionCount; ++i) {
+ const char* str = (i < ANDROID_SECTION_COUNT)
+ ? camera_metadata_section_names[i]
+ : (*vendorSections)[i - ANDROID_SECTION_COUNT].string();
+
+ ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str);
+
+ if (strstr(name, str) == name) { // name begins with the section name
+ size_t strLength = strlen(str);
+
+ ALOGV("%s: Name begins with section name", __FUNCTION__);
+
+ // section name is the longest we've found so far
+ if (section == NULL || sectionLength < strLength) {
+ section = str;
+ sectionIndex = i;
+ sectionLength = strLength;
+
+ ALOGV("%s: Found new best section (%s)", __FUNCTION__, section);
+ }
+ }
+ }
+
+ if (section == NULL) {
+ return NAME_NOT_FOUND;
+ } else {
+ ALOGV("%s: Found matched section '%s' (%zu)", __FUNCTION__, section, sectionIndex);
+ }
+
+ // Get the tag name component of the name
+ const char* nameTagName = name + sectionLength + 1; // x.y.z -> z
+ if (sectionLength + 1 >= nameLength) {
+ return BAD_VALUE;
+ }
+
+ // Match rest of name against the tag names in that section only
+ uint32_t candidateTag = 0;
+ if (sectionIndex < ANDROID_SECTION_COUNT) {
+ // Match built-in tags (typically android.*)
+ uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
+ tagBegin = camera_metadata_section_bounds[sectionIndex][0];
+ tagEnd = camera_metadata_section_bounds[sectionIndex][1];
+
+ for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) {
+ const char* tagName = get_camera_metadata_tag_name(candidateTag);
+
+ if (strcmp(nameTagName, tagName) == 0) {
+ ALOGV("%s: Found matched tag '%s' (%d)", __FUNCTION__, tagName, candidateTag);
+ break;
+ }
+ }
+
+ if (candidateTag == tagEnd) {
+ return NAME_NOT_FOUND;
+ }
+ } else if (vTags != NULL) {
+ // Match vendor tags (typically com.*)
+ const String8 sectionName(section);
+ const String8 tagName(nameTagName);
+
+ status_t res = OK;
+ if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) {
+ return NAME_NOT_FOUND;
+ }
+ }
+
+ *tag = candidateTag;
+ return OK;
+}
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/common/default/CameraModule.cpp b/camera/common/default/CameraModule.cpp
new file mode 100644
index 0000000..9960842
--- /dev/null
+++ b/camera/common/default/CameraModule.cpp
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2016 The Android Open 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 "CamComm1.0-CamModule"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+// #define LOG_NDEBUG 0
+
+#include <utils/Trace.h>
+
+#include "CameraModule.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+void CameraModule::deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata& chars) {
+ ATRACE_CALL();
+
+ Vector<int32_t> derivedCharKeys;
+ Vector<int32_t> derivedRequestKeys;
+ Vector<int32_t> derivedResultKeys;
+ // Keys added in HAL3.3
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_3) {
+ Vector<uint8_t> controlModes;
+ uint8_t data = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE;
+ chars.update(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &data, /*count*/ 1);
+ data = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE;
+ chars.update(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &data, /*count*/ 1);
+ controlModes.push(ANDROID_CONTROL_MODE_AUTO);
+ camera_metadata_entry entry = chars.find(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
+ if (entry.count > 1 || entry.data.u8[0] != ANDROID_CONTROL_SCENE_MODE_DISABLED) {
+ controlModes.push(ANDROID_CONTROL_MODE_USE_SCENE_MODE);
+ }
+
+ // Only advertise CONTROL_OFF mode if 3A manual controls are supported.
+ bool isManualAeSupported = false;
+ bool isManualAfSupported = false;
+ bool isManualAwbSupported = false;
+ entry = chars.find(ANDROID_CONTROL_AE_AVAILABLE_MODES);
+ if (entry.count > 0) {
+ for (size_t i = 0; i < entry.count; i++) {
+ if (entry.data.u8[i] == ANDROID_CONTROL_AE_MODE_OFF) {
+ isManualAeSupported = true;
+ break;
+ }
+ }
+ }
+ entry = chars.find(ANDROID_CONTROL_AF_AVAILABLE_MODES);
+ if (entry.count > 0) {
+ for (size_t i = 0; i < entry.count; i++) {
+ if (entry.data.u8[i] == ANDROID_CONTROL_AF_MODE_OFF) {
+ isManualAfSupported = true;
+ break;
+ }
+ }
+ }
+ entry = chars.find(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
+ if (entry.count > 0) {
+ for (size_t i = 0; i < entry.count; i++) {
+ if (entry.data.u8[i] == ANDROID_CONTROL_AWB_MODE_OFF) {
+ isManualAwbSupported = true;
+ break;
+ }
+ }
+ }
+ if (isManualAeSupported && isManualAfSupported && isManualAwbSupported) {
+ controlModes.push(ANDROID_CONTROL_MODE_OFF);
+ }
+
+ chars.update(ANDROID_CONTROL_AVAILABLE_MODES, controlModes);
+
+ entry = chars.find(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
+ // HAL3.2 devices passing existing CTS test should all support all LSC modes and LSC map
+ bool lensShadingModeSupported = false;
+ if (entry.count > 0) {
+ for (size_t i = 0; i < entry.count; i++) {
+ if (entry.data.i32[i] == ANDROID_SHADING_MODE) {
+ lensShadingModeSupported = true;
+ break;
+ }
+ }
+ }
+ Vector<uint8_t> lscModes;
+ Vector<uint8_t> lscMapModes;
+ lscModes.push(ANDROID_SHADING_MODE_FAST);
+ lscModes.push(ANDROID_SHADING_MODE_HIGH_QUALITY);
+ lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
+ if (lensShadingModeSupported) {
+ lscModes.push(ANDROID_SHADING_MODE_OFF);
+ lscMapModes.push(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON);
+ }
+ chars.update(ANDROID_SHADING_AVAILABLE_MODES, lscModes);
+ chars.update(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, lscMapModes);
+
+ derivedCharKeys.push(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
+ derivedCharKeys.push(ANDROID_CONTROL_AWB_LOCK_AVAILABLE);
+ derivedCharKeys.push(ANDROID_CONTROL_AVAILABLE_MODES);
+ derivedCharKeys.push(ANDROID_SHADING_AVAILABLE_MODES);
+ derivedCharKeys.push(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES);
+
+ // Need update android.control.availableHighSpeedVideoConfigurations since HAL3.3
+ // adds batch size to this array.
+ entry = chars.find(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS);
+ if (entry.count > 0) {
+ Vector<int32_t> highSpeedConfig;
+ for (size_t i = 0; i < entry.count; i += 4) {
+ highSpeedConfig.add(entry.data.i32[i]); // width
+ highSpeedConfig.add(entry.data.i32[i + 1]); // height
+ highSpeedConfig.add(entry.data.i32[i + 2]); // fps_min
+ highSpeedConfig.add(entry.data.i32[i + 3]); // fps_max
+ highSpeedConfig.add(1); // batchSize_max. default to 1 for HAL3.2
+ }
+ chars.update(ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
+ highSpeedConfig);
+ }
+ }
+
+ // Keys added in HAL3.4
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
+ // Check if HAL supports RAW_OPAQUE output
+ camera_metadata_entry entry = chars.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
+ bool supportRawOpaque = false;
+ bool supportAnyRaw = false;
+ const int STREAM_CONFIGURATION_SIZE = 4;
+ const int STREAM_FORMAT_OFFSET = 0;
+ const int STREAM_WIDTH_OFFSET = 1;
+ const int STREAM_HEIGHT_OFFSET = 2;
+ const int STREAM_IS_INPUT_OFFSET = 3;
+ Vector<int32_t> rawOpaqueSizes;
+
+ for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
+ int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
+ int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
+ int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
+ int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
+ if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+ format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
+ supportRawOpaque = true;
+ rawOpaqueSizes.push(width);
+ rawOpaqueSizes.push(height);
+ // 2 bytes per pixel. This rough estimation is only used when
+ // HAL does not fill in the opaque raw size
+ rawOpaqueSizes.push(width * height * 2);
+ }
+ if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+ (format == HAL_PIXEL_FORMAT_RAW16 || format == HAL_PIXEL_FORMAT_RAW10 ||
+ format == HAL_PIXEL_FORMAT_RAW12 || format == HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
+ supportAnyRaw = true;
+ }
+ }
+
+ if (supportRawOpaque) {
+ entry = chars.find(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+ if (entry.count == 0) {
+ // Fill in estimated value if HAL does not list it
+ chars.update(ANDROID_SENSOR_OPAQUE_RAW_SIZE, rawOpaqueSizes);
+ derivedCharKeys.push(ANDROID_SENSOR_OPAQUE_RAW_SIZE);
+ }
+ }
+
+ // Check if HAL supports any RAW output, if so, fill in postRawSensitivityBoost range
+ if (supportAnyRaw) {
+ int32_t defaultRange[2] = {100, 100};
+ entry = chars.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
+ if (entry.count == 0) {
+ // Fill in default value (100, 100)
+ chars.update(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE, defaultRange, 2);
+ derivedCharKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE);
+ // Actual request/results will be derived by camera device.
+ derivedRequestKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+ derivedResultKeys.push(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
+ }
+ }
+ }
+
+ // Add those newly added keys to AVAILABLE_CHARACTERISTICS_KEYS
+ // This has to be done at this end of this function.
+ if (derivedCharKeys.size() > 0) {
+ appendAvailableKeys(chars, ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, derivedCharKeys);
+ }
+ if (derivedRequestKeys.size() > 0) {
+ appendAvailableKeys(chars, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, derivedRequestKeys);
+ }
+ if (derivedResultKeys.size() > 0) {
+ appendAvailableKeys(chars, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, derivedResultKeys);
+ }
+ return;
+}
+
+void CameraModule::appendAvailableKeys(CameraMetadata& chars, int32_t keyTag,
+ const Vector<int32_t>& appendKeys) {
+ camera_metadata_entry entry = chars.find(keyTag);
+ Vector<int32_t> availableKeys;
+ availableKeys.setCapacity(entry.count + appendKeys.size());
+ for (size_t i = 0; i < entry.count; i++) {
+ availableKeys.push(entry.data.i32[i]);
+ }
+ for (size_t i = 0; i < appendKeys.size(); i++) {
+ availableKeys.push(appendKeys[i]);
+ }
+ chars.update(keyTag, availableKeys);
+}
+
+CameraModule::CameraModule(camera_module_t* module) : mNumberOfCameras(0) {
+ if (module == NULL) {
+ ALOGE("%s: camera hardware module must not be null", __FUNCTION__);
+ assert(0);
+ }
+ mModule = module;
+}
+
+CameraModule::~CameraModule() {
+ while (mCameraInfoMap.size() > 0) {
+ camera_info cameraInfo = mCameraInfoMap.editValueAt(0);
+ if (cameraInfo.static_camera_characteristics != NULL) {
+ free_camera_metadata(
+ const_cast<camera_metadata_t*>(cameraInfo.static_camera_characteristics));
+ }
+ mCameraInfoMap.removeItemsAt(0);
+ }
+
+ while (mPhysicalCameraInfoMap.size() > 0) {
+ camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0);
+ if (metadata != NULL) {
+ free_camera_metadata(metadata);
+ }
+ mPhysicalCameraInfoMap.removeItemsAt(0);
+ }
+}
+
+int CameraModule::init() {
+ ATRACE_CALL();
+ int res = OK;
+ if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && mModule->init != NULL) {
+ ATRACE_BEGIN("camera_module->init");
+ res = mModule->init();
+ ATRACE_END();
+ }
+ mNumberOfCameras = getNumberOfCameras();
+ mCameraInfoMap.setCapacity(mNumberOfCameras);
+ return res;
+}
+
+int CameraModule::getCameraInfo(int cameraId, struct camera_info* info) {
+ ATRACE_CALL();
+ Mutex::Autolock lock(mCameraInfoLock);
+ if (cameraId < 0) {
+ ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
+ return -EINVAL;
+ }
+
+ // Only override static_camera_characteristics for API2 devices
+ int apiVersion = mModule->common.module_api_version;
+ if (apiVersion < CAMERA_MODULE_API_VERSION_2_0) {
+ int ret;
+ ATRACE_BEGIN("camera_module->get_camera_info");
+ ret = mModule->get_camera_info(cameraId, info);
+ // Fill in this so CameraService won't be confused by
+ // possibly 0 device_version
+ info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
+ ATRACE_END();
+ return ret;
+ }
+
+ ssize_t index = mCameraInfoMap.indexOfKey(cameraId);
+ if (index == NAME_NOT_FOUND) {
+ // Get camera info from raw module and cache it
+ camera_info rawInfo, cameraInfo;
+ ATRACE_BEGIN("camera_module->get_camera_info");
+ int ret = mModule->get_camera_info(cameraId, &rawInfo);
+ ATRACE_END();
+ if (ret != 0) {
+ return ret;
+ }
+ int deviceVersion = rawInfo.device_version;
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_0) {
+ // static_camera_characteristics is invalid
+ *info = rawInfo;
+ return ret;
+ }
+ CameraMetadata m;
+ m.append(rawInfo.static_camera_characteristics);
+ deriveCameraCharacteristicsKeys(rawInfo.device_version, m);
+ cameraInfo = rawInfo;
+ cameraInfo.static_camera_characteristics = m.release();
+ index = mCameraInfoMap.add(cameraId, cameraInfo);
+ }
+
+ assert(index != NAME_NOT_FOUND);
+ // return the cached camera info
+ *info = mCameraInfoMap[index];
+ return OK;
+}
+
+int CameraModule::getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t** physicalInfo) {
+ ATRACE_CALL();
+ Mutex::Autolock lock(mCameraInfoLock);
+ if (physicalCameraId < mNumberOfCameras) {
+ ALOGE("%s: Invalid physical camera ID %d", __FUNCTION__, physicalCameraId);
+ return -EINVAL;
+ }
+
+ // Only query physical camera info for 2.5 version for newer
+ int apiVersion = mModule->common.module_api_version;
+ if (apiVersion < CAMERA_MODULE_API_VERSION_2_5) {
+ ALOGE("%s: Module version must be at least 2.5 to handle getPhysicalCameraInfo",
+ __FUNCTION__);
+ return -ENODEV;
+ }
+ if (mModule->get_physical_camera_info == nullptr) {
+ ALOGE("%s: get_physical_camera is NULL for module version 2.5", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ ssize_t index = mPhysicalCameraInfoMap.indexOfKey(physicalCameraId);
+ if (index == NAME_NOT_FOUND) {
+ // Get physical camera characteristics, and cache it
+ camera_metadata_t* info = nullptr;
+ ATRACE_BEGIN("camera_module->get_physical_camera_info");
+ int ret = mModule->get_physical_camera_info(physicalCameraId, &info);
+ ATRACE_END();
+ if (ret != 0) {
+ return ret;
+ }
+
+ // The camera_metadata_t returned by get_physical_camera_info could be using
+ // more memory than necessary due to unused reserved space. Reduce the
+ // size by appending it to a new CameraMetadata object, which internally
+ // calls resizeIfNeeded.
+ CameraMetadata m;
+ m.append(info);
+ camera_metadata_t* derivedMetadata = m.release();
+ index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata);
+ }
+
+ assert(index != NAME_NOT_FOUND);
+ *physicalInfo = mPhysicalCameraInfoMap[index];
+ return OK;
+}
+
+int CameraModule::getDeviceVersion(int cameraId) {
+ ssize_t index = mDeviceVersionMap.indexOfKey(cameraId);
+ if (index == NAME_NOT_FOUND) {
+ int deviceVersion;
+ if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
+ struct camera_info info;
+ getCameraInfo(cameraId, &info);
+ deviceVersion = info.device_version;
+ } else {
+ deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
+ }
+ index = mDeviceVersionMap.add(cameraId, deviceVersion);
+ }
+ assert(index != NAME_NOT_FOUND);
+ return mDeviceVersionMap[index];
+}
+
+int CameraModule::open(const char* id, struct hw_device_t** device) {
+ int res;
+ ATRACE_BEGIN("camera_module->open");
+ res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
+ ATRACE_END();
+ return res;
+}
+
+bool CameraModule::isOpenLegacyDefined() const {
+ if (getModuleApiVersion() < CAMERA_MODULE_API_VERSION_2_3) {
+ return false;
+ }
+ return mModule->open_legacy != NULL;
+}
+
+int CameraModule::openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device) {
+ int res;
+ ATRACE_BEGIN("camera_module->open_legacy");
+ res = mModule->open_legacy(&mModule->common, id, halVersion, device);
+ ATRACE_END();
+ return res;
+}
+
+int CameraModule::getNumberOfCameras() {
+ int numCameras;
+ ATRACE_BEGIN("camera_module->get_number_of_cameras");
+ numCameras = mModule->get_number_of_cameras();
+ ATRACE_END();
+ return numCameras;
+}
+
+int CameraModule::setCallbacks(const camera_module_callbacks_t* callbacks) {
+ int res = OK;
+ ATRACE_BEGIN("camera_module->set_callbacks");
+ if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) {
+ res = mModule->set_callbacks(callbacks);
+ }
+ ATRACE_END();
+ return res;
+}
+
+bool CameraModule::isVendorTagDefined() const {
+ return mModule->get_vendor_tag_ops != NULL;
+}
+
+void CameraModule::getVendorTagOps(vendor_tag_ops_t* ops) {
+ if (mModule->get_vendor_tag_ops) {
+ ATRACE_BEGIN("camera_module->get_vendor_tag_ops");
+ mModule->get_vendor_tag_ops(ops);
+ ATRACE_END();
+ }
+}
+
+bool CameraModule::isSetTorchModeSupported() const {
+ if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) {
+ if (mModule->set_torch_mode == NULL) {
+ ALOGE("%s: Module 2.4 device must support set torch API!", __FUNCTION__);
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+int CameraModule::setTorchMode(const char* camera_id, bool enable) {
+ int res = INVALID_OPERATION;
+ if (mModule->set_torch_mode != NULL) {
+ ATRACE_BEGIN("camera_module->set_torch_mode");
+ res = mModule->set_torch_mode(camera_id, enable);
+ ATRACE_END();
+ }
+ return res;
+}
+
+int CameraModule::isStreamCombinationSupported(int cameraId, camera_stream_combination_t* streams) {
+ int res = INVALID_OPERATION;
+ if (mModule->is_stream_combination_supported != NULL) {
+ ATRACE_BEGIN("camera_module->is_stream_combination_supported");
+ res = mModule->is_stream_combination_supported(cameraId, streams);
+ ATRACE_END();
+ }
+ return res;
+}
+
+void CameraModule::notifyDeviceStateChange(uint64_t deviceState) {
+ if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_5 &&
+ mModule->notify_device_state_change != NULL) {
+ ATRACE_BEGIN("camera_module->notify_device_state_change");
+ ALOGI("%s: calling notify_device_state_change with state %" PRId64, __FUNCTION__,
+ deviceState);
+ mModule->notify_device_state_change(deviceState);
+ ATRACE_END();
+ }
+}
+
+bool CameraModule::isLogicalMultiCamera(const common::helper::CameraMetadata& metadata,
+ std::unordered_set<std::string>* physicalCameraIds) {
+ if (physicalCameraIds == nullptr) {
+ ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__);
+ return false;
+ }
+
+ bool isLogicalMultiCamera = false;
+ camera_metadata_ro_entry_t capabilities = metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ for (size_t i = 0; i < capabilities.count; i++) {
+ if (capabilities.data.u8[i] ==
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+ isLogicalMultiCamera = true;
+ break;
+ }
+ }
+
+ if (isLogicalMultiCamera) {
+ camera_metadata_ro_entry_t entry = metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
+ const uint8_t* ids = entry.data.u8;
+ size_t start = 0;
+ for (size_t i = 0; i < entry.count; ++i) {
+ if (ids[i] == '\0') {
+ if (start != i) {
+ const char* physicalId = reinterpret_cast<const char*>(ids + start);
+ physicalCameraIds->emplace(physicalId);
+ }
+ start = i + 1;
+ }
+ }
+ }
+ return isLogicalMultiCamera;
+}
+
+status_t CameraModule::filterOpenErrorCode(status_t err) {
+ switch (err) {
+ case NO_ERROR:
+ case -EBUSY:
+ case -EINVAL:
+ case -EUSERS:
+ return err;
+ default:
+ break;
+ }
+ return -ENODEV;
+}
+
+void CameraModule::removeCamera(int cameraId) {
+ // Skip HAL1 devices which isn't cached in mCameraInfoMap and don't advertise
+ // static_camera_characteristics
+ if (getDeviceVersion(cameraId) >= CAMERA_DEVICE_API_VERSION_3_0) {
+ std::unordered_set<std::string> physicalIds;
+ camera_metadata_t* metadata = const_cast<camera_metadata_t*>(
+ mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
+ common::helper::CameraMetadata hidlMetadata(metadata);
+
+ if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
+ for (const auto& id : physicalIds) {
+ int idInt = std::stoi(id);
+ if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
+ free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
+ mPhysicalCameraInfoMap.removeItem(idInt);
+ } else {
+ ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
+ __FUNCTION__, id.c_str());
+ }
+ }
+ }
+ }
+
+ mCameraInfoMap.removeItem(cameraId);
+ mDeviceVersionMap.removeItem(cameraId);
+}
+
+uint16_t CameraModule::getModuleApiVersion() const {
+ return mModule->common.module_api_version;
+}
+
+const char* CameraModule::getModuleName() const {
+ return mModule->common.name;
+}
+
+uint16_t CameraModule::getHalApiVersion() const {
+ return mModule->common.hal_api_version;
+}
+
+const char* CameraModule::getModuleAuthor() const {
+ return mModule->common.author;
+}
+
+void* CameraModule::getDso() {
+ return mModule->common.dso;
+}
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/common/default/CameraParameters.cpp b/camera/common/default/CameraParameters.cpp
new file mode 100644
index 0000000..37e28a2
--- /dev/null
+++ b/camera/common/default/CameraParameters.cpp
@@ -0,0 +1,503 @@
+/*
+**
+** Copyright 2008, The Android Open 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 "CameraParams"
+#include <log/log.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <system/graphics.h>
+#include <unistd.h>
+#include "CameraParameters.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// Parameter keys to communicate between camera application and driver.
+const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values";
+const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values";
+const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values";
+const char CameraParameters::KEY_PREVIEW_FPS_RANGE[] = "preview-fps-range";
+const char CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE[] = "preview-fps-range-values";
+const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values";
+const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format";
+const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height";
+const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values";
+const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality";
+const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality";
+const char CameraParameters::KEY_ROTATION[] = "rotation";
+const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude";
+const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude";
+const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude";
+const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp";
+const char CameraParameters::KEY_GPS_PROCESSING_METHOD[] = "gps-processing-method";
+const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance";
+const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values";
+const char CameraParameters::KEY_EFFECT[] = "effect";
+const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values";
+const char CameraParameters::KEY_ANTIBANDING[] = "antibanding";
+const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values";
+const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode";
+const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values";
+const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode";
+const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
+const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
+const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
+const char CameraParameters::KEY_MAX_NUM_FOCUS_AREAS[] = "max-num-focus-areas";
+const char CameraParameters::KEY_FOCUS_AREAS[] = "focus-areas";
+const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
+const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
+const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation";
+const char CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION[] = "max-exposure-compensation";
+const char CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION[] = "min-exposure-compensation";
+const char CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP[] = "exposure-compensation-step";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK[] = "auto-exposure-lock";
+const char CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[] = "auto-exposure-lock-supported";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK[] = "auto-whitebalance-lock";
+const char CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[] =
+ "auto-whitebalance-lock-supported";
+const char CameraParameters::KEY_MAX_NUM_METERING_AREAS[] = "max-num-metering-areas";
+const char CameraParameters::KEY_METERING_AREAS[] = "metering-areas";
+const char CameraParameters::KEY_ZOOM[] = "zoom";
+const char CameraParameters::KEY_MAX_ZOOM[] = "max-zoom";
+const char CameraParameters::KEY_ZOOM_RATIOS[] = "zoom-ratios";
+const char CameraParameters::KEY_ZOOM_SUPPORTED[] = "zoom-supported";
+const char CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED[] = "smooth-zoom-supported";
+const char CameraParameters::KEY_FOCUS_DISTANCES[] = "focus-distances";
+const char CameraParameters::KEY_VIDEO_FRAME_FORMAT[] = "video-frame-format";
+const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
+const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
+const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] =
+ "preferred-preview-size-for-video";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
+const char CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED[] = "video-snapshot-supported";
+const char CameraParameters::KEY_VIDEO_STABILIZATION[] = "video-stabilization";
+const char CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED[] = "video-stabilization-supported";
+const char CameraParameters::KEY_LIGHTFX[] = "light-fx";
+
+const char CameraParameters::TRUE[] = "true";
+const char CameraParameters::FALSE[] = "false";
+const char CameraParameters::FOCUS_DISTANCE_INFINITY[] = "Infinity";
+
+// Values for white balance settings.
+const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
+const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent";
+const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent";
+const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent";
+const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight";
+const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight";
+const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight";
+const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade";
+
+// Values for effect settings.
+const char CameraParameters::EFFECT_NONE[] = "none";
+const char CameraParameters::EFFECT_MONO[] = "mono";
+const char CameraParameters::EFFECT_NEGATIVE[] = "negative";
+const char CameraParameters::EFFECT_SOLARIZE[] = "solarize";
+const char CameraParameters::EFFECT_SEPIA[] = "sepia";
+const char CameraParameters::EFFECT_POSTERIZE[] = "posterize";
+const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard";
+const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard";
+const char CameraParameters::EFFECT_AQUA[] = "aqua";
+
+// Values for antibanding settings.
+const char CameraParameters::ANTIBANDING_AUTO[] = "auto";
+const char CameraParameters::ANTIBANDING_50HZ[] = "50hz";
+const char CameraParameters::ANTIBANDING_60HZ[] = "60hz";
+const char CameraParameters::ANTIBANDING_OFF[] = "off";
+
+// Values for flash mode settings.
+const char CameraParameters::FLASH_MODE_OFF[] = "off";
+const char CameraParameters::FLASH_MODE_AUTO[] = "auto";
+const char CameraParameters::FLASH_MODE_ON[] = "on";
+const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye";
+const char CameraParameters::FLASH_MODE_TORCH[] = "torch";
+
+// Values for scene mode settings.
+const char CameraParameters::SCENE_MODE_AUTO[] = "auto";
+const char CameraParameters::SCENE_MODE_ACTION[] = "action";
+const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait";
+const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape";
+const char CameraParameters::SCENE_MODE_NIGHT[] = "night";
+const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait";
+const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre";
+const char CameraParameters::SCENE_MODE_BEACH[] = "beach";
+const char CameraParameters::SCENE_MODE_SNOW[] = "snow";
+const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset";
+const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto";
+const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks";
+const char CameraParameters::SCENE_MODE_SPORTS[] = "sports";
+const char CameraParameters::SCENE_MODE_PARTY[] = "party";
+const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight";
+const char CameraParameters::SCENE_MODE_BARCODE[] = "barcode";
+const char CameraParameters::SCENE_MODE_HDR[] = "hdr";
+
+const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp";
+const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp";
+const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv";
+const char CameraParameters::PIXEL_FORMAT_YUV420P[] = "yuv420p";
+const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
+const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
+const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
+const char CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE[] = "android-opaque";
+
+// Values for focus mode settings.
+const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
+const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity";
+const char CameraParameters::FOCUS_MODE_MACRO[] = "macro";
+const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed";
+const char CameraParameters::FOCUS_MODE_EDOF[] = "edof";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO[] = "continuous-video";
+const char CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE[] = "continuous-picture";
+
+// Values for light fx settings
+const char CameraParameters::LIGHTFX_LOWLIGHT[] = "low-light";
+const char CameraParameters::LIGHTFX_HDR[] = "high-dynamic-range";
+
+CameraParameters::CameraParameters() : mMap() {}
+
+CameraParameters::~CameraParameters() {}
+
+String8 CameraParameters::flatten() const {
+ String8 flattened("");
+ size_t size = mMap.size();
+
+ for (size_t i = 0; i < size; i++) {
+ String8 k, v;
+ k = mMap.keyAt(i);
+ v = mMap.valueAt(i);
+
+ flattened += k;
+ flattened += "=";
+ flattened += v;
+ if (i != size - 1) flattened += ";";
+ }
+
+ return flattened;
+}
+
+void CameraParameters::unflatten(const String8& params) {
+ const char* a = params.string();
+ const char* b;
+
+ mMap.clear();
+
+ for (;;) {
+ // Find the bounds of the key name.
+ b = strchr(a, '=');
+ if (b == 0) break;
+
+ // Create the key string.
+ String8 k(a, (size_t)(b - a));
+
+ // Find the value.
+ a = b + 1;
+ b = strchr(a, ';');
+ if (b == 0) {
+ // If there's no semicolon, this is the last item.
+ String8 v(a);
+ mMap.add(k, v);
+ break;
+ }
+
+ String8 v(a, (size_t)(b - a));
+ mMap.add(k, v);
+ a = b + 1;
+ }
+}
+
+void CameraParameters::set(const char* key, const char* value) {
+ // i think i can do this with strspn()
+ if (strchr(key, '=') || strchr(key, ';')) {
+ // ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
+ return;
+ }
+
+ if (strchr(value, '=') || strchr(value, ';')) {
+ // ALOGE("Value \"%s\"contains invalid character (= or ;)", value);
+ return;
+ }
+
+ mMap.replaceValueFor(String8(key), String8(value));
+}
+
+void CameraParameters::set(const char* key, int value) {
+ char str[16];
+ sprintf(str, "%d", value);
+ set(key, str);
+}
+
+void CameraParameters::setFloat(const char* key, float value) {
+ char str[16]; // 14 should be enough. We overestimate to be safe.
+ snprintf(str, sizeof(str), "%g", value);
+ set(key, str);
+}
+
+const char* CameraParameters::get(const char* key) const {
+ String8 v = mMap.valueFor(String8(key));
+ if (v.length() == 0) return 0;
+ return v.string();
+}
+
+int CameraParameters::getInt(const char* key) const {
+ const char* v = get(key);
+ if (v == 0) return -1;
+ return strtol(v, 0, 0);
+}
+
+float CameraParameters::getFloat(const char* key) const {
+ const char* v = get(key);
+ if (v == 0) return -1;
+ return strtof(v, 0);
+}
+
+void CameraParameters::remove(const char* key) {
+ mMap.removeItem(String8(key));
+}
+
+// Parse string like "640x480" or "10000,20000"
+static int parse_pair(const char* str, int* first, int* second, char delim, char** endptr = NULL) {
+ // Find the first integer.
+ char* end;
+ int w = (int)strtol(str, &end, 10);
+ // If a delimeter does not immediately follow, give up.
+ if (*end != delim) {
+ ALOGE("Cannot find delimeter (%c) in str=%s", delim, str);
+ return -1;
+ }
+
+ // Find the second integer, immediately after the delimeter.
+ int h = (int)strtol(end + 1, &end, 10);
+
+ *first = w;
+ *second = h;
+
+ if (endptr) {
+ *endptr = end;
+ }
+
+ return 0;
+}
+
+static void parseSizesList(const char* sizesStr, Vector<Size>& sizes) {
+ if (sizesStr == 0) {
+ return;
+ }
+
+ char* sizeStartPtr = (char*)sizesStr;
+
+ while (true) {
+ int width, height;
+ int success = parse_pair(sizeStartPtr, &width, &height, 'x', &sizeStartPtr);
+ if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) {
+ ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr);
+ return;
+ }
+ sizes.push(Size(width, height));
+
+ if (*sizeStartPtr == '\0') {
+ return;
+ }
+ sizeStartPtr++;
+ }
+}
+
+void CameraParameters::setPreviewSize(int width, int height) {
+ char str[32];
+ sprintf(str, "%dx%d", width, height);
+ set(KEY_PREVIEW_SIZE, str);
+}
+
+void CameraParameters::getPreviewSize(int* width, int* height) const {
+ *width = *height = -1;
+ // Get the current string, if it doesn't exist, leave the -1x-1
+ const char* p = get(KEY_PREVIEW_SIZE);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getPreferredPreviewSizeForVideo(int* width, int* height) const {
+ *width = *height = -1;
+ const char* p = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedPreviewSizes(Vector<Size>& sizes) const {
+ const char* previewSizesStr = get(KEY_SUPPORTED_PREVIEW_SIZES);
+ parseSizesList(previewSizesStr, sizes);
+}
+
+void CameraParameters::setVideoSize(int width, int height) {
+ char str[32];
+ sprintf(str, "%dx%d", width, height);
+ set(KEY_VIDEO_SIZE, str);
+}
+
+void CameraParameters::getVideoSize(int* width, int* height) const {
+ *width = *height = -1;
+ const char* p = get(KEY_VIDEO_SIZE);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedVideoSizes(Vector<Size>& sizes) const {
+ const char* videoSizesStr = get(KEY_SUPPORTED_VIDEO_SIZES);
+ parseSizesList(videoSizesStr, sizes);
+}
+
+void CameraParameters::setPreviewFrameRate(int fps) {
+ set(KEY_PREVIEW_FRAME_RATE, fps);
+}
+
+int CameraParameters::getPreviewFrameRate() const {
+ return getInt(KEY_PREVIEW_FRAME_RATE);
+}
+
+void CameraParameters::getPreviewFpsRange(int* min_fps, int* max_fps) const {
+ *min_fps = *max_fps = -1;
+ const char* p = get(KEY_PREVIEW_FPS_RANGE);
+ if (p == 0) return;
+ parse_pair(p, min_fps, max_fps, ',');
+}
+
+void CameraParameters::setPreviewFormat(const char* format) {
+ set(KEY_PREVIEW_FORMAT, format);
+}
+
+const char* CameraParameters::getPreviewFormat() const {
+ return get(KEY_PREVIEW_FORMAT);
+}
+
+void CameraParameters::setPictureSize(int width, int height) {
+ char str[32];
+ sprintf(str, "%dx%d", width, height);
+ set(KEY_PICTURE_SIZE, str);
+}
+
+void CameraParameters::getPictureSize(int* width, int* height) const {
+ *width = *height = -1;
+ // Get the current string, if it doesn't exist, leave the -1x-1
+ const char* p = get(KEY_PICTURE_SIZE);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters::getSupportedPictureSizes(Vector<Size>& sizes) const {
+ const char* pictureSizesStr = get(KEY_SUPPORTED_PICTURE_SIZES);
+ parseSizesList(pictureSizesStr, sizes);
+}
+
+void CameraParameters::setPictureFormat(const char* format) {
+ set(KEY_PICTURE_FORMAT, format);
+}
+
+const char* CameraParameters::getPictureFormat() const {
+ return get(KEY_PICTURE_FORMAT);
+}
+
+void CameraParameters::dump() const {
+ ALOGD("dump: mMap.size = %zu", mMap.size());
+ for (size_t i = 0; i < mMap.size(); i++) {
+ String8 k, v;
+ k = mMap.keyAt(i);
+ v = mMap.valueAt(i);
+ ALOGD("%s: %s\n", k.string(), v.string());
+ }
+}
+
+status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const {
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size());
+ result.append(buffer);
+ for (size_t i = 0; i < mMap.size(); i++) {
+ String8 k, v;
+ k = mMap.keyAt(i);
+ v = mMap.valueAt(i);
+ snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+ result.append(buffer);
+ }
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
+void CameraParameters::getSupportedPreviewFormats(Vector<int>& formats) const {
+ const char* supportedPreviewFormats = get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
+
+ if (supportedPreviewFormats == NULL) {
+ ALOGW("%s: No supported preview formats.", __FUNCTION__);
+ return;
+ }
+
+ String8 fmtStr(supportedPreviewFormats);
+ char* prevFmts = fmtStr.lockBuffer(fmtStr.size());
+
+ char* savePtr;
+ char* fmt = strtok_r(prevFmts, ",", &savePtr);
+ while (fmt) {
+ int actual = previewFormatToEnum(fmt);
+ if (actual != -1) {
+ formats.add(actual);
+ }
+ fmt = strtok_r(NULL, ",", &savePtr);
+ }
+ fmtStr.unlockBuffer(fmtStr.size());
+}
+
+int CameraParameters::previewFormatToEnum(const char* format) {
+ return !format ? HAL_PIXEL_FORMAT_YCrCb_420_SP
+ : !strcmp(format, PIXEL_FORMAT_YUV422SP) ? HAL_PIXEL_FORMAT_YCbCr_422_SP
+ : // NV16
+ !strcmp(format, PIXEL_FORMAT_YUV420SP) ? HAL_PIXEL_FORMAT_YCrCb_420_SP
+ : // NV21
+ !strcmp(format, PIXEL_FORMAT_YUV422I) ? HAL_PIXEL_FORMAT_YCbCr_422_I
+ : // YUY2
+ !strcmp(format, PIXEL_FORMAT_YUV420P) ? HAL_PIXEL_FORMAT_YV12
+ : // YV12
+ !strcmp(format, PIXEL_FORMAT_RGB565) ? HAL_PIXEL_FORMAT_RGB_565
+ : // RGB565
+ !strcmp(format, PIXEL_FORMAT_RGBA8888) ? HAL_PIXEL_FORMAT_RGBA_8888
+ : // RGB8888
+ !strcmp(format, PIXEL_FORMAT_BAYER_RGGB) ? HAL_PIXEL_FORMAT_RAW16
+ : // Raw sensor data
+ -1;
+}
+
+bool CameraParameters::isEmpty() const {
+ return mMap.isEmpty();
+}
+
+}; // namespace helper
+}; // namespace common
+}; // namespace camera
+}; // namespace hardware
+}; // namespace android
diff --git a/camera/common/default/Exif.cpp b/camera/common/default/Exif.cpp
new file mode 100644
index 0000000..f4b2a31
--- /dev/null
+++ b/camera/common/default/Exif.cpp
@@ -0,0 +1,1041 @@
+/*
+ * Copyright (C) 2018 The Android Open 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 "CamComm1.0-Exif"
+#define ATRACE_TAG ATRACE_TAG_CAMERA
+// #define LOG_NDEBUG 0
+
+#include <android/log.h>
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "Exif.h"
+
+extern "C" {
+#include <libexif/exif-data.h>
+}
+
+namespace std {
+
+template <>
+struct default_delete<ExifEntry> {
+ inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
+};
+
+} // namespace std
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+class ExifUtilsImpl : public ExifUtils {
+ public:
+ ExifUtilsImpl();
+
+ virtual ~ExifUtilsImpl();
+
+ // Initialize() can be called multiple times. The setting of Exif tags will be
+ // cleared.
+ virtual bool initialize();
+
+ // set all known fields from a metadata structure
+ virtual bool setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
+ const size_t imageHeight);
+
+ // sets the len aperture.
+ // Returns false if memory allocation fails.
+ virtual bool setAperture(uint32_t numerator, uint32_t denominator);
+
+ // sets the value of brightness.
+ // Returns false if memory allocation fails.
+ virtual bool setBrightness(int32_t numerator, int32_t denominator);
+
+ // sets the color space.
+ // Returns false if memory allocation fails.
+ virtual bool setColorSpace(uint16_t color_space);
+
+ // sets the information to compressed data.
+ // Returns false if memory allocation fails.
+ virtual bool setComponentsConfiguration(const std::string& components_configuration);
+
+ // sets the compression scheme used for the image data.
+ // Returns false if memory allocation fails.
+ virtual bool setCompression(uint16_t compression);
+
+ // sets image contrast.
+ // Returns false if memory allocation fails.
+ virtual bool setContrast(uint16_t contrast);
+
+ // sets the date and time of image last modified. It takes local time. The
+ // name of the tag is DateTime in IFD0.
+ // Returns false if memory allocation fails.
+ virtual bool setDateTime(const struct tm& t);
+
+ // sets the image description.
+ // Returns false if memory allocation fails.
+ virtual bool setDescription(const std::string& description);
+
+ // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
+ // was not used.
+ // Returns false if memory allocation fails.
+ virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
+
+ // sets the exposure bias.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureBias(int32_t numerator, int32_t denominator);
+
+ // sets the exposure mode set when the image was shot.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureMode(uint16_t exposure_mode);
+
+ // sets the program used by the camera to set exposure when the picture is
+ // taken.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureProgram(uint16_t exposure_program);
+
+ // sets the exposure time, given in seconds.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
+
+ // sets the status of flash.
+ // Returns false if memory allocation fails.
+ virtual bool setFlash(uint16_t flash);
+
+ // sets the F number.
+ // Returns false if memory allocation fails.
+ virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
+
+ // sets the focal length of lens used to take the image in millimeters.
+ // Returns false if memory allocation fails.
+ virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
+
+ // sets the degree of overall image gain adjustment.
+ // Returns false if memory allocation fails.
+ virtual bool setGainControl(uint16_t gain_control);
+
+ // sets the altitude in meters.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsAltitude(double altitude);
+
+ // sets the latitude with degrees minutes seconds format.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsLatitude(double latitude);
+
+ // sets the longitude with degrees minutes seconds format.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsLongitude(double longitude);
+
+ // sets GPS processing method.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsProcessingMethod(const std::string& method);
+
+ // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsTimestamp(const struct tm& t);
+
+ // sets the length (number of rows) of main image.
+ // Returns false if memory allocation fails.
+ virtual bool setImageHeight(uint32_t length);
+
+ // sets the width (number of columes) of main image.
+ // Returns false if memory allocation fails.
+ virtual bool setImageWidth(uint32_t width);
+
+ // sets the ISO speed.
+ // Returns false if memory allocation fails.
+ virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
+
+ // sets the kind of light source.
+ // Returns false if memory allocation fails.
+ virtual bool setLightSource(uint16_t light_source);
+
+ // sets the smallest F number of the lens.
+ // Returns false if memory allocation fails.
+ virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
+
+ // sets the metering mode.
+ // Returns false if memory allocation fails.
+ virtual bool setMeteringMode(uint16_t metering_mode);
+
+ // sets image orientation.
+ // Returns false if memory allocation fails.
+ virtual bool setOrientation(uint16_t orientation);
+
+ // sets the unit for measuring XResolution and YResolution.
+ // Returns false if memory allocation fails.
+ virtual bool setResolutionUnit(uint16_t resolution_unit);
+
+ // sets image saturation.
+ // Returns false if memory allocation fails.
+ virtual bool setSaturation(uint16_t saturation);
+
+ // sets the type of scene that was shot.
+ // Returns false if memory allocation fails.
+ virtual bool setSceneCaptureType(uint16_t type);
+
+ // sets image sharpness.
+ // Returns false if memory allocation fails.
+ virtual bool setSharpness(uint16_t sharpness);
+
+ // sets the shutter speed.
+ // Returns false if memory allocation fails.
+ virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
+
+ // sets the distance to the subject, given in meters.
+ // Returns false if memory allocation fails.
+ virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
+
+ // sets the fractions of seconds for the <DateTime> tag.
+ // Returns false if memory allocation fails.
+ virtual bool setSubsecTime(const std::string& subsec_time);
+
+ // sets the white balance mode set when the image was shot.
+ // Returns false if memory allocation fails.
+ virtual bool setWhiteBalance(uint16_t white_balance);
+
+ // sets the number of pixels per resolution unit in the image width.
+ // Returns false if memory allocation fails.
+ virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
+
+ // sets the position of chrominance components in relation to the luminance
+ // component.
+ // Returns false if memory allocation fails.
+ virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
+
+ // sets the number of pixels per resolution unit in the image length.
+ // Returns false if memory allocation fails.
+ virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
+
+ // sets the manufacturer of camera.
+ // Returns false if memory allocation fails.
+ virtual bool setMake(const std::string& make);
+
+ // sets the model number of camera.
+ // Returns false if memory allocation fails.
+ virtual bool setModel(const std::string& model);
+
+ // Generates APP1 segment.
+ // Returns false if generating APP1 segment fails.
+ virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size);
+
+ // Gets buffer of APP1 segment. This method must be called only after calling
+ // GenerateAPP1().
+ virtual const uint8_t* getApp1Buffer();
+
+ // Gets length of APP1 segment. This method must be called only after calling
+ // GenerateAPP1().
+ virtual unsigned int getApp1Length();
+
+ protected:
+ // sets the version of this standard supported.
+ // Returns false if memory allocation fails.
+ virtual bool setExifVersion(const std::string& exif_version);
+
+ // Resets the pointers and memories.
+ virtual void reset();
+
+ // Adds a variable length tag to |exif_data_|. It will remove the original one
+ // if the tag exists.
+ // Returns the entry of the tag. The reference count of returned ExifEntry is
+ // two.
+ virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd, ExifTag tag,
+ ExifFormat format,
+ uint64_t components,
+ unsigned int size);
+
+ // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
+ // the tag exists.
+ // Returns the entry of the tag. It adds one reference count to returned
+ // ExifEntry.
+ virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
+
+ // Helpe functions to add exif data with different types.
+ virtual bool setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg);
+
+ virtual bool setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg);
+
+ virtual bool setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator, uint32_t denominator,
+ const std::string& msg);
+
+ virtual bool setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator, int32_t denominator,
+ const std::string& msg);
+
+ virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format, const std::string& buffer,
+ const std::string& msg);
+
+ // Destroys the buffer of APP1 segment if exists.
+ virtual void destroyApp1();
+
+ // The Exif data (APP1). Owned by this class.
+ ExifData* exif_data_;
+ // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
+ // owned by this class.
+ uint8_t* app1_buffer_;
+ // The length of |app1_buffer_|.
+ unsigned int app1_length_;
+};
+
+#define SET_SHORT(ifd, tag, value) \
+ do { \
+ if (setShort(ifd, tag, value, #tag) == false) return false; \
+ } while (0);
+
+#define SET_LONG(ifd, tag, value) \
+ do { \
+ if (setLong(ifd, tag, value, #tag) == false) return false; \
+ } while (0);
+
+#define SET_RATIONAL(ifd, tag, numerator, denominator) \
+ do { \
+ if (setRational(ifd, tag, numerator, denominator, #tag) == false) return false; \
+ } while (0);
+
+#define SET_SRATIONAL(ifd, tag, numerator, denominator) \
+ do { \
+ if (setSRational(ifd, tag, numerator, denominator, #tag) == false) return false; \
+ } while (0);
+
+#define SET_STRING(ifd, tag, format, buffer) \
+ do { \
+ if (setString(ifd, tag, format, buffer, #tag) == false) return false; \
+ } while (0);
+
+// This comes from the Exif Version 2.2 standard table 6.
+const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
+
+static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
+ // Take the integer part of |num|.
+ ExifLong degrees = static_cast<ExifLong>(num);
+ ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
+ ExifLong microseconds = static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
+ exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
+ exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, {minutes, 1});
+ exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+ {microseconds, 1000000});
+}
+
+ExifUtils* ExifUtils::create() {
+ return new ExifUtilsImpl();
+}
+
+ExifUtils::~ExifUtils() {}
+
+ExifUtilsImpl::ExifUtilsImpl() : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
+
+ExifUtilsImpl::~ExifUtilsImpl() {
+ reset();
+}
+
+bool ExifUtilsImpl::initialize() {
+ reset();
+ exif_data_ = exif_data_new();
+ if (exif_data_ == nullptr) {
+ ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
+ return false;
+ }
+ // set the image options.
+ exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
+ exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
+ exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
+
+ // set exif version to 2.2.
+ if (!setExifVersion("0220")) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
+ SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
+ return true;
+}
+
+bool ExifUtilsImpl::setComponentsConfiguration(const std::string& components_configuration) {
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION, EXIF_FORMAT_UNDEFINED,
+ components_configuration);
+ return true;
+}
+
+bool ExifUtilsImpl::setCompression(uint16_t compression) {
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
+ return true;
+}
+
+bool ExifUtilsImpl::setContrast(uint16_t contrast) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
+ return true;
+}
+
+bool ExifUtilsImpl::setDateTime(const struct tm& t) {
+ // The length is 20 bytes including NULL for termination in Exif standard.
+ char str[20];
+ int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i", t.tm_year + 1900,
+ t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
+ if (result != sizeof(str) - 1) {
+ ALOGW("%s: Input time is invalid", __FUNCTION__);
+ return false;
+ }
+ std::string buffer(str);
+ SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, buffer);
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, buffer);
+ return true;
+}
+
+bool ExifUtilsImpl::setDescription(const std::string& description) {
+ SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII, description);
+ return true;
+}
+
+bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
+ SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
+ return true;
+}
+
+bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
+ return true;
+}
+
+bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setFlash(uint16_t flash) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
+ return true;
+}
+
+bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
+ return true;
+}
+
+bool ExifUtilsImpl::setGpsAltitude(double altitude) {
+ ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
+ std::unique_ptr<ExifEntry> refEntry =
+ addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
+ if (!refEntry) {
+ ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
+ return false;
+ }
+ if (altitude >= 0) {
+ *refEntry->data = 0;
+ } else {
+ *refEntry->data = 1;
+ altitude *= -1;
+ }
+
+ ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
+ std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+ EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
+ if (!entry) {
+ exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+ ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
+ return false;
+ }
+ exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
+ {static_cast<ExifLong>(altitude * 1000), 1000});
+
+ return true;
+}
+
+bool ExifUtilsImpl::setGpsLatitude(double latitude) {
+ const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
+ std::unique_ptr<ExifEntry> refEntry =
+ addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
+ if (!refEntry) {
+ ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
+ return false;
+ }
+ if (latitude >= 0) {
+ memcpy(refEntry->data, "N", sizeof("N"));
+ } else {
+ memcpy(refEntry->data, "S", sizeof("S"));
+ latitude *= -1;
+ }
+
+ const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
+ std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+ EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
+ if (!entry) {
+ exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+ ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
+ return false;
+ }
+ setLatitudeOrLongitudeData(entry->data, latitude);
+
+ return true;
+}
+
+bool ExifUtilsImpl::setGpsLongitude(double longitude) {
+ ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
+ std::unique_ptr<ExifEntry> refEntry =
+ addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
+ if (!refEntry) {
+ ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
+ return false;
+ }
+ if (longitude >= 0) {
+ memcpy(refEntry->data, "E", sizeof("E"));
+ } else {
+ memcpy(refEntry->data, "W", sizeof("W"));
+ longitude *= -1;
+ }
+
+ ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
+ std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+ EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
+ if (!entry) {
+ exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
+ ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
+ return false;
+ }
+ setLatitudeOrLongitudeData(entry->data, longitude);
+
+ return true;
+}
+
+bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
+ std::string buffer = std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
+ SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
+ EXIF_FORMAT_UNDEFINED, buffer);
+ return true;
+}
+
+bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
+ const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
+ const size_t kGpsDateStampSize = 11;
+ std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
+ EXIF_IFD_GPS, dateTag, EXIF_FORMAT_ASCII, kGpsDateStampSize, kGpsDateStampSize);
+ if (!entry) {
+ ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
+ return false;
+ }
+ int result = snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize, "%04i:%02i:%02i",
+ t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
+ if (result != kGpsDateStampSize - 1) {
+ ALOGW("%s: Input time is invalid", __FUNCTION__);
+ return false;
+ }
+
+ const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
+ entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
+ 3 * sizeof(ExifRational));
+ if (!entry) {
+ ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
+ return false;
+ }
+ exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {static_cast<ExifLong>(t.tm_hour), 1});
+ exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+ {static_cast<ExifLong>(t.tm_min), 1});
+ exif_set_rational(entry->data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
+ {static_cast<ExifLong>(t.tm_sec), 1});
+
+ return true;
+}
+
+bool ExifUtilsImpl::setImageHeight(uint32_t length) {
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
+ SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
+ return true;
+}
+
+bool ExifUtilsImpl::setImageWidth(uint32_t width) {
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
+ SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
+ return true;
+}
+
+bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
+ return true;
+}
+
+bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
+ return true;
+}
+
+bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
+ return true;
+}
+
+bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
+ /*
+ * Orientation value:
+ * 1 2 3 4 5 6 7 8
+ *
+ * 888888 888888 88 88 8888888888 88 88 8888888888
+ * 88 88 88 88 88 88 88 88 88 88 88 88
+ * 8888 8888 8888 8888 88 8888888888 8888888888 88
+ * 88 88 88 88
+ * 88 88 888888 888888
+ */
+ int value = 1;
+ switch (orientation) {
+ case 90:
+ value = 6;
+ break;
+ case 180:
+ value = 3;
+ break;
+ case 270:
+ value = 8;
+ break;
+ default:
+ break;
+ }
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);
+ return true;
+}
+
+bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
+ return true;
+}
+
+bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
+ return true;
+}
+
+bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
+ return true;
+}
+
+bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
+ return true;
+}
+
+bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
+ SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII, subsec_time);
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII, subsec_time);
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII, subsec_time);
+ return true;
+}
+
+bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
+ SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
+ return true;
+}
+
+bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
+ SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
+ return true;
+}
+
+bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
+ SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
+ return true;
+}
+
+bool ExifUtilsImpl::generateApp1(const void* thumbnail_buffer, uint32_t size) {
+ destroyApp1();
+ exif_data_->data = const_cast<uint8_t*>(static_cast<const uint8_t*>(thumbnail_buffer));
+ exif_data_->size = size;
+ // Save the result into |app1_buffer_|.
+ exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
+ if (!app1_length_) {
+ ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
+ return false;
+ }
+ /*
+ * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
+ * be smaller than 65533 because there are two bytes for segment size field.
+ */
+ if (app1_length_ > 65533) {
+ destroyApp1();
+ ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
+ return false;
+ }
+ return true;
+}
+
+const uint8_t* ExifUtilsImpl::getApp1Buffer() {
+ return app1_buffer_;
+}
+
+unsigned int ExifUtilsImpl::getApp1Length() {
+ return app1_length_;
+}
+
+bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
+ SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
+ return true;
+}
+
+bool ExifUtilsImpl::setMake(const std::string& make) {
+ SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
+ return true;
+}
+
+bool ExifUtilsImpl::setModel(const std::string& model) {
+ SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
+ return true;
+}
+
+void ExifUtilsImpl::reset() {
+ destroyApp1();
+ if (exif_data_) {
+ /*
+ * Since we decided to ignore the original APP1, we are sure that there is
+ * no thumbnail allocated by libexif. |exif_data_->data| is actually
+ * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
+ * prevent exif_data_unref() destroy it incorrectly.
+ */
+ exif_data_->data = nullptr;
+ exif_data_->size = 0;
+ exif_data_unref(exif_data_);
+ exif_data_ = nullptr;
+ }
+}
+
+std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd, ExifTag tag,
+ ExifFormat format,
+ uint64_t components,
+ unsigned int size) {
+ // Remove old entry if exists.
+ exif_content_remove_entry(exif_data_->ifd[ifd],
+ exif_content_get_entry(exif_data_->ifd[ifd], tag));
+ ExifMem* mem = exif_mem_new_default();
+ if (!mem) {
+ ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+ return nullptr;
+ }
+ std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
+ if (!entry) {
+ ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+ exif_mem_unref(mem);
+ return nullptr;
+ }
+ void* tmpBuffer = exif_mem_alloc(mem, size);
+ if (!tmpBuffer) {
+ ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+ exif_mem_unref(mem);
+ return nullptr;
+ }
+
+ entry->data = static_cast<unsigned char*>(tmpBuffer);
+ entry->tag = tag;
+ entry->format = format;
+ entry->components = components;
+ entry->size = size;
+
+ exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
+ exif_mem_unref(mem);
+
+ return entry;
+}
+
+std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
+ std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
+ if (entry) {
+ // exif_content_get_entry() won't ref the entry, so we ref here.
+ exif_entry_ref(entry.get());
+ return entry;
+ }
+ entry.reset(exif_entry_new());
+ if (!entry) {
+ ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
+ return nullptr;
+ }
+ entry->tag = tag;
+ exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
+ exif_entry_initialize(entry.get(), tag);
+ return entry;
+}
+
+bool ExifUtilsImpl::setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg) {
+ std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+ if (!entry) {
+ ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+ return false;
+ }
+ exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
+ return true;
+}
+
+bool ExifUtilsImpl::setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg) {
+ std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+ if (!entry) {
+ ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+ return false;
+ }
+ exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
+ return true;
+}
+
+bool ExifUtilsImpl::setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator, uint32_t denominator,
+ const std::string& msg) {
+ std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+ if (!entry) {
+ ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+ return false;
+ }
+ exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
+ return true;
+}
+
+bool ExifUtilsImpl::setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator, int32_t denominator,
+ const std::string& msg) {
+ std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
+ if (!entry) {
+ ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+ return false;
+ }
+ exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
+ return true;
+}
+
+bool ExifUtilsImpl::setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
+ const std::string& buffer, const std::string& msg) {
+ size_t entry_size = buffer.length();
+ // Since the exif format is undefined, NULL termination is not necessary.
+ if (format == EXIF_FORMAT_ASCII) {
+ entry_size++;
+ }
+ std::unique_ptr<ExifEntry> entry =
+ addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
+ if (!entry) {
+ ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
+ return false;
+ }
+ memcpy(entry->data, buffer.c_str(), entry_size);
+ return true;
+}
+
+void ExifUtilsImpl::destroyApp1() {
+ /*
+ * Since there is no API to access ExifMem in ExifData->priv, we use free
+ * here, which is the default free function in libexif. See
+ * exif_data_save_data() for detail.
+ */
+ free(app1_buffer_);
+ app1_buffer_ = nullptr;
+ app1_length_ = 0;
+}
+
+bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
+ const size_t imageHeight) {
+ // How precise the float-to-rational conversion for EXIF tags would be.
+ constexpr int kRationalPrecision = 10000;
+ if (!setImageWidth(imageWidth) || !setImageHeight(imageHeight)) {
+ ALOGE("%s: setting image resolution failed.", __FUNCTION__);
+ return false;
+ }
+
+ struct timespec tp;
+ struct tm time_info;
+ bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
+ localtime_r(&tp.tv_sec, &time_info);
+ if (!setDateTime(time_info)) {
+ ALOGE("%s: setting data time failed.", __FUNCTION__);
+ return false;
+ }
+
+ float focal_length;
+ camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
+ if (entry.count) {
+ focal_length = entry.data.f[0];
+
+ if (!setFocalLength(static_cast<uint32_t>(focal_length * kRationalPrecision),
+ kRationalPrecision)) {
+ ALOGE("%s: setting focal length failed.", __FUNCTION__);
+ return false;
+ }
+ } else {
+ ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
+ }
+
+ if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
+ entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
+ if (entry.count < 3) {
+ ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
+ return false;
+ }
+ if (!setGpsLatitude(entry.data.d[0])) {
+ ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
+ return false;
+ }
+ if (!setGpsLongitude(entry.data.d[1])) {
+ ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
+ return false;
+ }
+ if (!setGpsAltitude(entry.data.d[2])) {
+ ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
+ entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
+ std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
+ if (!setGpsProcessingMethod(method_str)) {
+ ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
+ entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
+ time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
+ if (gmtime_r(×tamp, &time_info)) {
+ if (!setGpsTimestamp(time_info)) {
+ ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
+ return false;
+ }
+ } else {
+ ALOGE("%s: Time tranformation failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
+ entry = metadata.find(ANDROID_JPEG_ORIENTATION);
+ if (!setOrientation(entry.data.i32[0])) {
+ ALOGE("%s: setting orientation failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
+ entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
+ // int64_t of nanoseconds
+ if (!setExposureTime(entry.data.i64[0], 1000000000u)) {
+ ALOGE("%s: setting exposure time failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_LENS_APERTURE)) {
+ const int kAperturePrecision = 10000;
+ entry = metadata.find(ANDROID_LENS_APERTURE);
+ if (!setFNumber(entry.data.f[0] * kAperturePrecision, kAperturePrecision)) {
+ ALOGE("%s: setting F number failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
+ entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
+ if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
+ const uint32_t kNoFlashFunction = 0x20;
+ if (!setFlash(kNoFlashFunction)) {
+ ALOGE("%s: setting flash failed.", __FUNCTION__);
+ return false;
+ }
+ } else {
+ ALOGE("%s: Unsupported flash info: %d", __FUNCTION__, entry.data.u8[0]);
+ return false;
+ }
+ }
+
+ if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
+ entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
+ if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
+ const uint16_t kAutoWhiteBalance = 0;
+ if (!setWhiteBalance(kAutoWhiteBalance)) {
+ ALOGE("%s: setting white balance failed.", __FUNCTION__);
+ return false;
+ }
+ } else {
+ ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
+ return false;
+ }
+ }
+
+ if (time_available) {
+ char str[4];
+ if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
+ ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
+ return false;
+ }
+ if (!setSubsecTime(std::string(str))) {
+ ALOGE("%s: setting subsec time failed.", __FUNCTION__);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/common/default/HandleImporter.cpp b/camera/common/default/HandleImporter.cpp
new file mode 100644
index 0000000..1145baa
--- /dev/null
+++ b/camera/common/default/HandleImporter.cpp
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2017 The Android Open 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 "HandleImporter"
+#include "HandleImporter.h"
+
+#include <gralloctypes/Gralloc4.h>
+#include <log/log.h>
+#include "aidl/android/hardware/graphics/common/Smpte2086.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::Smpte2086;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
+using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
+using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error;
+using IMapperV3 = android::hardware::graphics::mapper::V3_0::IMapper;
+using IMapperV4 = android::hardware::graphics::mapper::V4_0::IMapper;
+
+HandleImporter::HandleImporter() : mInitialized(false) {}
+
+void HandleImporter::initializeLocked() {
+ if (mInitialized) {
+ return;
+ }
+
+ mMapperV4 = IMapperV4::getService();
+ if (mMapperV4 != nullptr) {
+ mInitialized = true;
+ return;
+ }
+
+ mMapperV3 = IMapperV3::getService();
+ if (mMapperV3 != nullptr) {
+ mInitialized = true;
+ return;
+ }
+
+ mMapperV2 = IMapper::getService();
+ if (mMapperV2 == nullptr) {
+ ALOGE("%s: cannnot acccess graphics mapper HAL!", __FUNCTION__);
+ return;
+ }
+
+ mInitialized = true;
+ return;
+}
+
+void HandleImporter::cleanup() {
+ mMapperV4.clear();
+ mMapperV3.clear();
+ mMapperV2.clear();
+ mInitialized = false;
+}
+
+template <class M, class E>
+bool HandleImporter::importBufferInternal(const sp<M> mapper, buffer_handle_t& handle) {
+ E error;
+ buffer_handle_t importedHandle;
+ auto ret = mapper->importBuffer(
+ hidl_handle(handle), [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ error = tmpError;
+ importedHandle = static_cast<buffer_handle_t>(tmpBufferHandle);
+ });
+
+ if (!ret.isOk()) {
+ ALOGE("%s: mapper importBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+ return false;
+ }
+
+ if (error != E::NONE) {
+ return false;
+ }
+
+ handle = importedHandle;
+ return true;
+}
+
+template <class M, class E>
+YCbCrLayout HandleImporter::lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf,
+ uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion) {
+ hidl_handle acquireFenceHandle;
+ auto buffer = const_cast<native_handle_t*>(buf);
+ YCbCrLayout layout = {};
+
+ typename M::Rect accessRegionCopy = {accessRegion.left, accessRegion.top, accessRegion.width,
+ accessRegion.height};
+ mapper->lockYCbCr(buffer, cpuUsage, accessRegionCopy, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpLayout) {
+ if (tmpError == E::NONE) {
+ // Member by member copy from different versions of YCbCrLayout.
+ layout.y = tmpLayout.y;
+ layout.cb = tmpLayout.cb;
+ layout.cr = tmpLayout.cr;
+ layout.yStride = tmpLayout.yStride;
+ layout.cStride = tmpLayout.cStride;
+ layout.chromaStep = tmpLayout.chromaStep;
+ } else {
+ ALOGE("%s: failed to lockYCbCr error %d!", __FUNCTION__, tmpError);
+ }
+ });
+ return layout;
+}
+
+bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
+ MetadataType metadataType) {
+ auto buffer = const_cast<native_handle_t*>(buf);
+ bool ret = false;
+ hidl_vec<uint8_t> vec;
+ mapper->get(buffer, metadataType, [&](const auto& tmpError, const auto& tmpMetadata) {
+ if (tmpError == MapperErrorV4::NONE) {
+ vec = tmpMetadata;
+ } else {
+ ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
+ }
+ });
+
+ if (vec.size() > 0) {
+ if (metadataType == gralloc4::MetadataType_Smpte2086) {
+ std::optional<Smpte2086> realSmpte2086;
+ gralloc4::decodeSmpte2086(vec, &realSmpte2086);
+ ret = realSmpte2086.has_value();
+ } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
+ std::optional<std::vector<uint8_t>> realSmpte2094_10;
+ gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
+ ret = realSmpte2094_10.has_value();
+ } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
+ std::optional<std::vector<uint8_t>> realSmpte2094_40;
+ gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
+ ret = realSmpte2094_40.has_value();
+ } else {
+ ALOGE("%s: Unknown metadata type!", __FUNCTION__);
+ }
+ }
+
+ return ret;
+}
+
+std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
+ auto buffer = const_cast<native_handle_t*>(buf);
+ std::vector<PlaneLayout> planeLayouts;
+ hidl_vec<uint8_t> encodedPlaneLayouts;
+ mapper->get(buffer, gralloc4::MetadataType_PlaneLayouts,
+ [&](const auto& tmpError, const auto& tmpEncodedPlaneLayouts) {
+ if (tmpError == MapperErrorV4::NONE) {
+ encodedPlaneLayouts = tmpEncodedPlaneLayouts;
+ } else {
+ ALOGE("%s: failed to get plane layouts %d!", __FUNCTION__, tmpError);
+ }
+ });
+
+ gralloc4::decodePlaneLayouts(encodedPlaneLayouts, &planeLayouts);
+
+ return planeLayouts;
+}
+
+template <>
+YCbCrLayout HandleImporter::lockYCbCrInternal<IMapperV4, MapperErrorV4>(
+ const sp<IMapperV4> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion) {
+ hidl_handle acquireFenceHandle;
+ auto buffer = const_cast<native_handle_t*>(buf);
+ YCbCrLayout layout = {};
+ void* mapped = nullptr;
+
+ typename IMapperV4::Rect accessRegionV4 = {accessRegion.left, accessRegion.top,
+ accessRegion.width, accessRegion.height};
+ mapper->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpPtr) {
+ if (tmpError == MapperErrorV4::NONE) {
+ mapped = tmpPtr;
+ } else {
+ ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+ }
+ });
+
+ if (mapped == nullptr) {
+ return layout;
+ }
+
+ std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mapper, buf);
+ for (const auto& planeLayout : planeLayouts) {
+ for (const auto& planeLayoutComponent : planeLayout.components) {
+ const auto& type = planeLayoutComponent.type;
+
+ if (!gralloc4::isStandardPlaneLayoutComponentType(type)) {
+ continue;
+ }
+
+ uint8_t* data = reinterpret_cast<uint8_t*>(mapped);
+ data += planeLayout.offsetInBytes;
+ data += planeLayoutComponent.offsetInBits / 8;
+
+ switch (static_cast<PlaneLayoutComponentType>(type.value)) {
+ case PlaneLayoutComponentType::Y:
+ layout.y = data;
+ layout.yStride = planeLayout.strideInBytes;
+ break;
+ case PlaneLayoutComponentType::CB:
+ layout.cb = data;
+ layout.cStride = planeLayout.strideInBytes;
+ layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
+ break;
+ case PlaneLayoutComponentType::CR:
+ layout.cr = data;
+ layout.cStride = planeLayout.strideInBytes;
+ layout.chromaStep = planeLayout.sampleIncrementInBits / 8;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return layout;
+}
+
+template <class M, class E>
+int HandleImporter::unlockInternal(const sp<M> mapper, buffer_handle_t& buf) {
+ int releaseFence = -1;
+ auto buffer = const_cast<native_handle_t*>(buf);
+
+ mapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ if (tmpError == E::NONE) {
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle) {
+ if (fenceHandle->numInts != 0 || fenceHandle->numFds != 1) {
+ ALOGE("%s: bad release fence numInts %d numFds %d", __FUNCTION__,
+ fenceHandle->numInts, fenceHandle->numFds);
+ return;
+ }
+ releaseFence = dup(fenceHandle->data[0]);
+ if (releaseFence < 0) {
+ ALOGE("%s: bad release fence FD %d", __FUNCTION__, releaseFence);
+ }
+ }
+ } else {
+ ALOGE("%s: failed to unlock error %d!", __FUNCTION__, tmpError);
+ }
+ });
+ return releaseFence;
+}
+
+// In IComposer, any buffer_handle_t is owned by the caller and we need to
+// make a clone for hwcomposer2. We also need to translate empty handle
+// to nullptr. This function does that, in-place.
+bool HandleImporter::importBuffer(buffer_handle_t& handle) {
+ if (!handle->numFds && !handle->numInts) {
+ handle = nullptr;
+ return true;
+ }
+
+ Mutex::Autolock lock(mLock);
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return importBufferInternal<IMapperV4, MapperErrorV4>(mMapperV4, handle);
+ }
+
+ if (mMapperV3 != nullptr) {
+ return importBufferInternal<IMapperV3, MapperErrorV3>(mMapperV3, handle);
+ }
+
+ if (mMapperV2 != nullptr) {
+ return importBufferInternal<IMapper, MapperErrorV2>(mMapperV2, handle);
+ }
+
+ ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+ return false;
+}
+
+void HandleImporter::freeBuffer(buffer_handle_t handle) {
+ if (!handle) {
+ return;
+ }
+
+ Mutex::Autolock lock(mLock);
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ auto ret = mMapperV4->freeBuffer(const_cast<native_handle_t*>(handle));
+ if (!ret.isOk()) {
+ ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+ }
+ } else if (mMapperV3 != nullptr) {
+ auto ret = mMapperV3->freeBuffer(const_cast<native_handle_t*>(handle));
+ if (!ret.isOk()) {
+ ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+ }
+ } else {
+ auto ret = mMapperV2->freeBuffer(const_cast<native_handle_t*>(handle));
+ if (!ret.isOk()) {
+ ALOGE("%s: mapper freeBuffer failed: %s", __FUNCTION__, ret.description().c_str());
+ }
+ }
+}
+
+bool HandleImporter::importFence(const native_handle_t* handle, int& fd) const {
+ if (handle == nullptr || handle->numFds == 0) {
+ fd = -1;
+ } else if (handle->numFds == 1) {
+ fd = dup(handle->data[0]);
+ if (fd < 0) {
+ ALOGE("failed to dup fence fd %d", handle->data[0]);
+ return false;
+ }
+ } else {
+ ALOGE("invalid fence handle with %d file descriptors", handle->numFds);
+ return false;
+ }
+
+ return true;
+}
+
+void HandleImporter::closeFence(int fd) const {
+ if (fd >= 0) {
+ close(fd);
+ }
+}
+
+void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size) {
+ IMapper::Rect accessRegion{0, 0, static_cast<int>(size), 1};
+ return lock(buf, cpuUsage, accessRegion);
+}
+
+void* HandleImporter::lock(buffer_handle_t& buf, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ void* ret = nullptr;
+
+ if (mMapperV4 == nullptr && mMapperV3 == nullptr && mMapperV2 == nullptr) {
+ ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+ return ret;
+ }
+
+ hidl_handle acquireFenceHandle;
+ auto buffer = const_cast<native_handle_t*>(buf);
+ if (mMapperV4 != nullptr) {
+ IMapperV4::Rect accessRegionV4{accessRegion.left, accessRegion.top, accessRegion.width,
+ accessRegion.height};
+
+ mMapperV4->lock(buffer, cpuUsage, accessRegionV4, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpPtr) {
+ if (tmpError == MapperErrorV4::NONE) {
+ ret = tmpPtr;
+ } else {
+ ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+ }
+ });
+ } else if (mMapperV3 != nullptr) {
+ IMapperV3::Rect accessRegionV3{accessRegion.left, accessRegion.top, accessRegion.width,
+ accessRegion.height};
+
+ mMapperV3->lock(buffer, cpuUsage, accessRegionV3, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpPtr, const auto& /*bytesPerPixel*/,
+ const auto& /*bytesPerStride*/) {
+ if (tmpError == MapperErrorV3::NONE) {
+ ret = tmpPtr;
+ } else {
+ ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+ }
+ });
+ } else {
+ mMapperV2->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpPtr) {
+ if (tmpError == MapperErrorV2::NONE) {
+ ret = tmpPtr;
+ } else {
+ ALOGE("%s: failed to lock error %d!", __FUNCTION__, tmpError);
+ }
+ });
+ }
+
+ ALOGV("%s: ptr %p accessRegion.top: %d accessRegion.left: %d accessRegion.width: %d "
+ "accessRegion.height: %d",
+ __FUNCTION__, ret, accessRegion.top, accessRegion.left, accessRegion.width,
+ accessRegion.height);
+ return ret;
+}
+
+YCbCrLayout HandleImporter::lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return lockYCbCrInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf, cpuUsage, accessRegion);
+ }
+
+ if (mMapperV3 != nullptr) {
+ return lockYCbCrInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf, cpuUsage, accessRegion);
+ }
+
+ if (mMapperV2 != nullptr) {
+ return lockYCbCrInternal<IMapper, MapperErrorV2>(mMapperV2, buf, cpuUsage, accessRegion);
+ }
+
+ ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+ return {};
+}
+
+status_t HandleImporter::getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/) {
+ if (stride == nullptr) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ std::vector<PlaneLayout> planeLayouts = getPlaneLayouts(mMapperV4, buf);
+ if (planeLayouts.size() != 1) {
+ ALOGE("%s: Unexpected number of planes %zu!", __FUNCTION__, planeLayouts.size());
+ return BAD_VALUE;
+ }
+
+ *stride = planeLayouts[0].strideInBytes;
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ return NO_INIT;
+ }
+
+ return OK;
+}
+
+int HandleImporter::unlock(buffer_handle_t& buf) {
+ if (mMapperV4 != nullptr) {
+ return unlockInternal<IMapperV4, MapperErrorV4>(mMapperV4, buf);
+ }
+ if (mMapperV3 != nullptr) {
+ return unlockInternal<IMapperV3, MapperErrorV3>(mMapperV3, buf);
+ }
+ if (mMapperV2 != nullptr) {
+ return unlockInternal<IMapper, MapperErrorV2>(mMapperV2, buf);
+ }
+
+ ALOGE("%s: mMapperV4, mMapperV3 and mMapperV2 are all null!", __FUNCTION__);
+ return -1;
+}
+
+bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086);
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ }
+
+ return false;
+}
+
+bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10);
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ }
+
+ return false;
+}
+
+bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40);
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ }
+
+ return false;
+}
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/common/default/SimpleThread.cpp b/camera/common/default/SimpleThread.cpp
new file mode 100644
index 0000000..46e89ba
--- /dev/null
+++ b/camera/common/default/SimpleThread.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SimpleThread.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+SimpleThread::SimpleThread() : mDone(true), mThread() {}
+SimpleThread::~SimpleThread() {
+ // Safe to call requestExitAndWait() from the destructor because requestExitAndWait() ensures
+ // that the thread is joinable before joining on it. This is different from how
+ // android::Thread worked.
+ requestExitAndWait();
+}
+
+void SimpleThread::run() {
+ requestExitAndWait(); // Exit current execution, if any.
+
+ // start thread
+ mDone.store(false, std::memory_order_release);
+ mThread = std::thread(&SimpleThread::runLoop, this);
+}
+
+void SimpleThread::requestExitAndWait() {
+ // Signal thread to stop
+ mDone.store(true, std::memory_order_release);
+
+ // Wait for thread to exit if needed. This should happen in no more than one iteration of
+ // threadLoop
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ mThread = std::thread();
+}
+
+void SimpleThread::runLoop() {
+ while (!exitPending()) {
+ if (!threadLoop()) {
+ break;
+ }
+ }
+}
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/camera/common/default/VendorTagDescriptor.cpp b/camera/common/default/VendorTagDescriptor.cpp
new file mode 100644
index 0000000..1282bd0
--- /dev/null
+++ b/camera/common/default/VendorTagDescriptor.cpp
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2016 The Android Open 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 "CamComm1.0-VTDesc"
+
+#include <camera_metadata_hidden.h>
+#include <log/log.h>
+#include <system/camera_metadata.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/SortedVector.h>
+#include <utils/Vector.h>
+
+#include "VendorTagDescriptor.h"
+
+#include <stdio.h>
+#include <string.h>
+
+namespace android {
+namespace hardware {
+namespace camera2 {
+namespace params {
+
+VendorTagDescriptor::~VendorTagDescriptor() {
+ size_t len = mReverseMapping.size();
+ for (size_t i = 0; i < len; ++i) {
+ delete mReverseMapping[i];
+ }
+}
+
+VendorTagDescriptor::VendorTagDescriptor() : mTagCount(0), mVendorOps() {}
+
+VendorTagDescriptor::VendorTagDescriptor(const VendorTagDescriptor& src) {
+ copyFrom(src);
+}
+
+VendorTagDescriptor& VendorTagDescriptor::operator=(const VendorTagDescriptor& rhs) {
+ copyFrom(rhs);
+ return *this;
+}
+
+void VendorTagDescriptor::copyFrom(const VendorTagDescriptor& src) {
+ if (this == &src) return;
+
+ size_t len = mReverseMapping.size();
+ for (size_t i = 0; i < len; ++i) {
+ delete mReverseMapping[i];
+ }
+ mReverseMapping.clear();
+
+ len = src.mReverseMapping.size();
+ // Have to copy KeyedVectors inside mReverseMapping
+ for (size_t i = 0; i < len; ++i) {
+ KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+ *nameMapper = *(src.mReverseMapping.valueAt(i));
+ mReverseMapping.add(src.mReverseMapping.keyAt(i), nameMapper);
+ }
+ // Everything else is simple
+ mTagToNameMap = src.mTagToNameMap;
+ mTagToSectionMap = src.mTagToSectionMap;
+ mTagToTypeMap = src.mTagToTypeMap;
+ mSections = src.mSections;
+ mTagCount = src.mTagCount;
+ mVendorOps = src.mVendorOps;
+}
+
+int VendorTagDescriptor::getTagCount() const {
+ size_t size = mTagToNameMap.size();
+ if (size == 0) {
+ return VENDOR_TAG_COUNT_ERR;
+ }
+ return size;
+}
+
+void VendorTagDescriptor::getTagArray(uint32_t* tagArray) const {
+ size_t size = mTagToNameMap.size();
+ for (size_t i = 0; i < size; ++i) {
+ tagArray[i] = mTagToNameMap.keyAt(i);
+ }
+}
+
+const char* VendorTagDescriptor::getSectionName(uint32_t tag) const {
+ ssize_t index = mTagToSectionMap.indexOfKey(tag);
+ if (index < 0) {
+ return VENDOR_SECTION_NAME_ERR;
+ }
+ return mSections[mTagToSectionMap.valueAt(index)].string();
+}
+
+ssize_t VendorTagDescriptor::getSectionIndex(uint32_t tag) const {
+ return mTagToSectionMap.valueFor(tag);
+}
+
+const char* VendorTagDescriptor::getTagName(uint32_t tag) const {
+ ssize_t index = mTagToNameMap.indexOfKey(tag);
+ if (index < 0) {
+ return VENDOR_TAG_NAME_ERR;
+ }
+ return mTagToNameMap.valueAt(index).string();
+}
+
+int VendorTagDescriptor::getTagType(uint32_t tag) const {
+ auto iter = mTagToTypeMap.find(tag);
+ if (iter == mTagToTypeMap.end()) {
+ return VENDOR_TAG_TYPE_ERR;
+ }
+ return iter->second;
+}
+
+const SortedVector<String8>* VendorTagDescriptor::getAllSectionNames() const {
+ return &mSections;
+}
+
+status_t VendorTagDescriptor::lookupTag(const String8& name, const String8& section,
+ /*out*/ uint32_t* tag) const {
+ ssize_t index = mReverseMapping.indexOfKey(section);
+ if (index < 0) {
+ ALOGE("%s: Section '%s' does not exist.", __FUNCTION__, section.string());
+ return BAD_VALUE;
+ }
+
+ ssize_t nameIndex = mReverseMapping[index]->indexOfKey(name);
+ if (nameIndex < 0) {
+ ALOGE("%s: Tag name '%s' does not exist.", __FUNCTION__, name.string());
+ return BAD_VALUE;
+ }
+
+ if (tag != NULL) {
+ *tag = mReverseMapping[index]->valueAt(nameIndex);
+ }
+ return OK;
+}
+
+void VendorTagDescriptor::dump(int fd, int verbosity, int indentation) const {
+ size_t size = mTagToNameMap.size();
+ if (size == 0) {
+ dprintf(fd, "%*sDumping configured vendor tag descriptors: None set\n", indentation, "");
+ return;
+ }
+
+ dprintf(fd, "%*sDumping configured vendor tag descriptors: %zu entries\n", indentation, "",
+ size);
+ for (size_t i = 0; i < size; ++i) {
+ uint32_t tag = mTagToNameMap.keyAt(i);
+
+ if (verbosity < 1) {
+ dprintf(fd, "%*s0x%x\n", indentation + 2, "", tag);
+ continue;
+ }
+ String8 name = mTagToNameMap.valueAt(i);
+ uint32_t sectionId = mTagToSectionMap.valueFor(tag);
+ String8 sectionName = mSections[sectionId];
+ int type = mTagToTypeMap.at(tag);
+ const char* typeName =
+ (type >= 0 && type < NUM_TYPES) ? camera_metadata_type_names[type] : "UNKNOWN";
+ dprintf(fd, "%*s0x%x (%s) with type %d (%s) defined in section %s\n", indentation + 2, "",
+ tag, name.string(), type, typeName, sectionName.string());
+ }
+}
+
+int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
+ int ret = 0;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getTagCount();
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const {
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ desc->second->getTagArray(tagArray);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+}
+
+const char* VendorTagDescriptorCache::getSectionName(uint32_t tag, metadata_vendor_id_t id) const {
+ const char* ret = nullptr;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getSectionName(tag);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+const char* VendorTagDescriptorCache::getTagName(uint32_t tag, metadata_vendor_id_t id) const {
+ const char* ret = nullptr;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getTagName(tag);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+int VendorTagDescriptorCache::getTagType(uint32_t tag, metadata_vendor_id_t id) const {
+ int ret = 0;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getTagType(tag);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+void VendorTagDescriptorCache::dump(int fd, int verbosity, int indentation) const {
+ for (const auto& desc : mVendorMap) {
+ desc.second->dump(fd, verbosity, indentation);
+ }
+}
+
+int32_t VendorTagDescriptorCache::addVendorDescriptor(
+ metadata_vendor_id_t id, sp<hardware::camera::common::helper::VendorTagDescriptor> desc) {
+ auto entry = mVendorMap.find(id);
+ if (entry != mVendorMap.end()) {
+ ALOGE("%s: Vendor descriptor with same id already present!", __func__);
+ return BAD_VALUE;
+ }
+
+ mVendorMap.emplace(id, desc);
+ return NO_ERROR;
+}
+
+int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
+ metadata_vendor_id_t id,
+ sp<hardware::camera::common::helper::VendorTagDescriptor>* desc /*out*/) {
+ auto entry = mVendorMap.find(id);
+ if (entry == mVendorMap.end()) {
+ return NAME_NOT_FOUND;
+ }
+
+ *desc = entry->second;
+
+ return NO_ERROR;
+}
+} // namespace params
+} // namespace camera2
+
+namespace camera {
+namespace common {
+namespace helper {
+
+extern "C" {
+
+static int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* v);
+static void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* v, uint32_t* tagArray);
+static const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* v, uint32_t tag);
+static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
+static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
+
+static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
+static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id);
+static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
+ metadata_vendor_id_t id);
+static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id);
+static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id);
+} /* extern "C" */
+
+static Mutex sLock;
+static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
+static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
+
+status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
+ /*out*/
+ sp<VendorTagDescriptor>& descriptor) {
+ if (vOps == NULL) {
+ ALOGE("%s: vendor_tag_ops argument was NULL.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ int tagCount = vOps->get_tag_count(vOps);
+ if (tagCount < 0 || tagCount > INT32_MAX) {
+ ALOGE("%s: tag count %d from vendor ops is invalid.", __FUNCTION__, tagCount);
+ return BAD_VALUE;
+ }
+
+ Vector<uint32_t> tagArray;
+ LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
+ "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
+
+ vOps->get_all_tags(vOps, /*out*/ tagArray.editArray());
+
+ sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
+ desc->mTagCount = tagCount;
+
+ SortedVector<String8> sections;
+ KeyedVector<uint32_t, String8> tagToSectionMap;
+
+ for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
+ uint32_t tag = tagArray[i];
+ if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
+ ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ const char* tagName = vOps->get_tag_name(vOps, tag);
+ if (tagName == NULL) {
+ ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+ desc->mTagToNameMap.add(tag, String8(tagName));
+ const char* sectionName = vOps->get_section_name(vOps, tag);
+ if (sectionName == NULL) {
+ ALOGE("%s: no section name defined for vendor tag %d.", __FUNCTION__, tag);
+ return BAD_VALUE;
+ }
+
+ String8 sectionString(sectionName);
+
+ sections.add(sectionString);
+ tagToSectionMap.add(tag, sectionString);
+
+ int tagType = vOps->get_tag_type(vOps, tag);
+ if (tagType < 0 || tagType >= NUM_TYPES) {
+ ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
+ return BAD_VALUE;
+ }
+ desc->mTagToTypeMap.insert(std::make_pair(tag, tagType));
+ }
+
+ desc->mSections = sections;
+
+ for (size_t i = 0; i < static_cast<size_t>(tagCount); ++i) {
+ uint32_t tag = tagArray[i];
+ const String8& sectionString = tagToSectionMap.valueFor(tag);
+
+ // Set up tag to section index map
+ ssize_t index = sections.indexOf(sectionString);
+ LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
+ desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
+
+ // Set up reverse mapping
+ ssize_t reverseIndex = -1;
+ if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
+ KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
+ reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
+ }
+ desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
+ }
+
+ descriptor = desc;
+ return OK;
+}
+
+status_t VendorTagDescriptor::setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc) {
+ status_t res = OK;
+ Mutex::Autolock al(sLock);
+ sGlobalVendorTagDescriptor = desc;
+
+ vendor_tag_ops_t* opsPtr = NULL;
+ if (desc != NULL) {
+ opsPtr = &(desc->mVendorOps);
+ opsPtr->get_tag_count = vendor_tag_descriptor_get_tag_count;
+ opsPtr->get_all_tags = vendor_tag_descriptor_get_all_tags;
+ opsPtr->get_section_name = vendor_tag_descriptor_get_section_name;
+ opsPtr->get_tag_name = vendor_tag_descriptor_get_tag_name;
+ opsPtr->get_tag_type = vendor_tag_descriptor_get_tag_type;
+ }
+ if ((res = set_camera_metadata_vendor_ops(opsPtr)) != OK) {
+ ALOGE("%s: Could not set vendor tag descriptor, received error %s (%d).", __FUNCTION__,
+ strerror(-res), res);
+ }
+ return res;
+}
+
+void VendorTagDescriptor::clearGlobalVendorTagDescriptor() {
+ Mutex::Autolock al(sLock);
+ set_camera_metadata_vendor_ops(NULL);
+ sGlobalVendorTagDescriptor.clear();
+}
+
+sp<VendorTagDescriptor> VendorTagDescriptor::getGlobalVendorTagDescriptor() {
+ Mutex::Autolock al(sLock);
+ return sGlobalVendorTagDescriptor;
+}
+
+status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
+ const sp<VendorTagDescriptorCache>& cache) {
+ status_t res = OK;
+ Mutex::Autolock al(sLock);
+ sGlobalVendorTagDescriptorCache = cache;
+
+ struct vendor_tag_cache_ops* opsPtr = NULL;
+ if (cache != NULL) {
+ opsPtr = &(cache->mVendorCacheOps);
+ opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
+ opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
+ opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
+ opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
+ opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
+ }
+ if ((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
+ ALOGE("%s: Could not set vendor tag cache, received error %s (%d).", __FUNCTION__,
+ strerror(-res), res);
+ }
+ return res;
+}
+
+void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
+ Mutex::Autolock al(sLock);
+ set_camera_metadata_vendor_cache_ops(NULL);
+ sGlobalVendorTagDescriptorCache.clear();
+}
+
+sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
+ Mutex::Autolock al(sLock);
+ return sGlobalVendorTagDescriptorCache;
+}
+
+extern "C" {
+
+int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptor == NULL) {
+ ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+ return VENDOR_TAG_COUNT_ERR;
+ }
+ return sGlobalVendorTagDescriptor->getTagCount();
+}
+
+void vendor_tag_descriptor_get_all_tags(const vendor_tag_ops_t* /*v*/, uint32_t* tagArray) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptor == NULL) {
+ ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+ return;
+ }
+ sGlobalVendorTagDescriptor->getTagArray(tagArray);
+}
+
+const char* vendor_tag_descriptor_get_section_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptor == NULL) {
+ ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+ return VENDOR_SECTION_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptor->getSectionName(tag);
+}
+
+const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptor == NULL) {
+ ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+ return VENDOR_TAG_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptor->getTagName(tag);
+}
+
+int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* /*v*/, uint32_t tag) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptor == NULL) {
+ ALOGE("%s: Vendor tag descriptor not initialized.", __FUNCTION__);
+ return VENDOR_TAG_TYPE_ERR;
+ }
+ return sGlobalVendorTagDescriptor->getTagType(tag);
+}
+
+int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_TAG_COUNT_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getTagCount(id);
+}
+
+void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ }
+ sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
+}
+
+const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_SECTION_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
+}
+
+const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_TAG_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
+}
+
+int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_TAG_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
+}
+
+} /* extern "C" */
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/common/default/include/CameraMetadata.h b/camera/common/default/include/CameraMetadata.h
new file mode 100644
index 0000000..b67914e
--- /dev/null
+++ b/camera/common/default/include/CameraMetadata.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CAMERA_COMMON_1_0_CAMERAMETADATA_H
+#define CAMERA_COMMON_1_0_CAMERAMETADATA_H
+
+#include "system/camera_metadata.h"
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+class VendorTagDescriptor;
+
+/**
+ * A convenience wrapper around the C-based camera_metadata_t library.
+ */
+class CameraMetadata {
+ public:
+ /** Creates an empty object; best used when expecting to acquire contents
+ * from elsewhere */
+ CameraMetadata();
+ /** Creates an object with space for entryCapacity entries, with
+ * dataCapacity extra storage */
+ CameraMetadata(size_t entryCapacity, size_t dataCapacity = 10);
+
+ ~CameraMetadata();
+
+ /** Takes ownership of passed-in buffer */
+ CameraMetadata(camera_metadata_t* buffer);
+ /** Clones the metadata */
+ CameraMetadata(const CameraMetadata& other);
+
+ /**
+ * Assignment clones metadata buffer.
+ */
+ CameraMetadata& operator=(const CameraMetadata& other);
+ CameraMetadata& operator=(const camera_metadata_t* buffer);
+
+ /**
+ * Get reference to the underlying metadata buffer. Ownership remains with
+ * the CameraMetadata object, but non-const CameraMetadata methods will not
+ * work until unlock() is called. Note that the lock has nothing to do with
+ * thread-safety, it simply prevents the camera_metadata_t pointer returned
+ * here from being accidentally invalidated by CameraMetadata operations.
+ */
+ const camera_metadata_t* getAndLock() const;
+
+ /**
+ * Unlock the CameraMetadata for use again. After this unlock, the pointer
+ * given from getAndLock() may no longer be used. The pointer passed out
+ * from getAndLock must be provided to guarantee that the right object is
+ * being unlocked.
+ */
+ status_t unlock(const camera_metadata_t* buffer) const;
+
+ /**
+ * Release a raw metadata buffer to the caller. After this call,
+ * CameraMetadata no longer references the buffer, and the caller takes
+ * responsibility for freeing the raw metadata buffer (using
+ * free_camera_metadata()), or for handing it to another CameraMetadata
+ * instance.
+ */
+ camera_metadata_t* release();
+
+ /**
+ * Clear the metadata buffer and free all storage used by it
+ */
+ void clear();
+
+ /**
+ * Acquire a raw metadata buffer from the caller. After this call,
+ * the caller no longer owns the raw buffer, and must not free or manipulate it.
+ * If CameraMetadata already contains metadata, it is freed.
+ */
+ void acquire(camera_metadata_t* buffer);
+
+ /**
+ * Acquires raw buffer from other CameraMetadata object. After the call, the argument
+ * object no longer has any metadata.
+ */
+ void acquire(CameraMetadata& other);
+
+ /**
+ * Append metadata from another CameraMetadata object.
+ */
+ status_t append(const CameraMetadata& other);
+
+ /**
+ * Append metadata from a raw camera_metadata buffer
+ */
+ status_t append(const camera_metadata* other);
+
+ /**
+ * Number of metadata entries.
+ */
+ size_t entryCount() const;
+
+ /**
+ * Is the buffer empty (no entires)
+ */
+ bool isEmpty() const;
+
+ /**
+ * Sort metadata buffer for faster find
+ */
+ status_t sort();
+
+ /**
+ * Update metadata entry. Will create entry if it doesn't exist already, and
+ * will reallocate the buffer if insufficient space exists. Overloaded for
+ * the various types of valid data.
+ */
+ status_t update(uint32_t tag, const uint8_t* data, size_t data_count);
+ status_t update(uint32_t tag, const int32_t* data, size_t data_count);
+ status_t update(uint32_t tag, const float* data, size_t data_count);
+ status_t update(uint32_t tag, const int64_t* data, size_t data_count);
+ status_t update(uint32_t tag, const double* data, size_t data_count);
+ status_t update(uint32_t tag, const camera_metadata_rational_t* data, size_t data_count);
+ status_t update(uint32_t tag, const String8& string);
+ status_t update(const camera_metadata_ro_entry& entry);
+
+ template <typename T>
+ status_t update(uint32_t tag, Vector<T> data) {
+ return update(tag, data.array(), data.size());
+ }
+
+ /**
+ * Check if a metadata entry exists for a given tag id
+ *
+ */
+ bool exists(uint32_t tag) const;
+
+ /**
+ * Get metadata entry by tag id
+ */
+ camera_metadata_entry find(uint32_t tag);
+
+ /**
+ * Get metadata entry by tag id, with no editing
+ */
+ camera_metadata_ro_entry find(uint32_t tag) const;
+
+ /**
+ * Delete metadata entry by tag
+ */
+ status_t erase(uint32_t tag);
+
+ /**
+ * Swap the underlying camera metadata between this and the other
+ * metadata object.
+ */
+ void swap(CameraMetadata& other);
+
+ /**
+ * Dump contents into FD for debugging. The verbosity levels are
+ * 0: Tag entry information only, no data values
+ * 1: Level 0 plus at most 16 data values per entry
+ * 2: All information
+ *
+ * The indentation parameter sets the number of spaces to add to the start
+ * each line of output.
+ */
+ void dump(int fd, int verbosity = 1, int indentation = 0) const;
+
+ /**
+ * Find tag id for a given tag name, also checking vendor tags if available.
+ * On success, returns OK and writes the tag id into tag.
+ *
+ * This is a slow method.
+ */
+ static status_t getTagFromName(const char* name, const VendorTagDescriptor* vTags,
+ uint32_t* tag);
+
+ private:
+ camera_metadata_t* mBuffer;
+ mutable bool mLocked;
+
+ /**
+ * Check if tag has a given type
+ */
+ status_t checkType(uint32_t tag, uint8_t expectedType);
+
+ /**
+ * Base update entry method
+ */
+ status_t updateImpl(uint32_t tag, const void* data, size_t data_count);
+
+ /**
+ * Resize metadata buffer if needed by reallocating it and copying it over.
+ */
+ status_t resizeIfNeeded(size_t extraEntries, size_t extraData);
+};
+
+} // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used.
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::CameraMetadata CameraMetadata;
+} // namespace V1_0::helper
+
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif
diff --git a/camera/common/default/include/CameraModule.h b/camera/common/default/include/CameraModule.h
new file mode 100644
index 0000000..5c1f8ec
--- /dev/null
+++ b/camera/common/default/include/CameraModule.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CAMERA_COMMON_1_0_CAMERAMODULE_H
+#define CAMERA_COMMON_1_0_CAMERAMODULE_H
+
+#include <string>
+#include <unordered_set>
+
+#include <hardware/camera.h>
+#include <utils/KeyedVector.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+
+#include "CameraMetadata.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+/**
+ * A wrapper class for HAL camera module.
+ *
+ * This class wraps camera_module_t returned from HAL to provide a wrapped
+ * get_camera_info implementation which CameraService generates some
+ * camera characteristics keys defined in newer HAL version on an older HAL.
+ */
+class CameraModule : public RefBase {
+ public:
+ explicit CameraModule(camera_module_t* module);
+ virtual ~CameraModule();
+
+ // Must be called after construction
+ // Returns OK on success, NO_INIT on failure
+ int init();
+
+ int getCameraInfo(int cameraId, struct camera_info* info);
+ int getDeviceVersion(int cameraId);
+ int getNumberOfCameras(void);
+ int open(const char* id, struct hw_device_t** device);
+ bool isOpenLegacyDefined() const;
+ int openLegacy(const char* id, uint32_t halVersion, struct hw_device_t** device);
+ int setCallbacks(const camera_module_callbacks_t* callbacks);
+ bool isVendorTagDefined() const;
+ void getVendorTagOps(vendor_tag_ops_t* ops);
+ bool isSetTorchModeSupported() const;
+ int setTorchMode(const char* camera_id, bool enable);
+ uint16_t getModuleApiVersion() const;
+ const char* getModuleName() const;
+ uint16_t getHalApiVersion() const;
+ const char* getModuleAuthor() const;
+ // Only used by CameraModuleFixture native test. Do NOT use elsewhere.
+ void* getDso();
+ // Only used by CameraProvider
+ void removeCamera(int cameraId);
+ int getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t** physicalInfo);
+ int isStreamCombinationSupported(int cameraId, camera_stream_combination_t* streams);
+ void notifyDeviceStateChange(uint64_t deviceState);
+
+ static bool isLogicalMultiCamera(const common::helper::CameraMetadata& metadata,
+ std::unordered_set<std::string>* physicalCameraIds);
+
+ private:
+ // Derive camera characteristics keys defined after HAL device version
+ static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata& chars);
+ // Helper function to append available[request|result|chars]Keys
+ static void appendAvailableKeys(CameraMetadata& chars, int32_t keyTag,
+ const Vector<int32_t>& appendKeys);
+ status_t filterOpenErrorCode(status_t err);
+ camera_module_t* mModule;
+ int mNumberOfCameras;
+ KeyedVector<int, camera_info> mCameraInfoMap;
+ KeyedVector<int, int> mDeviceVersionMap;
+ KeyedVector<int, camera_metadata_t*> mPhysicalCameraInfoMap;
+ Mutex mCameraInfoLock;
+};
+
+} // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::CameraModule CameraModule;
+} // namespace V1_0::helper
+
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif
diff --git a/camera/common/default/include/CameraParameters.h b/camera/common/default/include/CameraParameters.h
new file mode 100644
index 0000000..d2b5075
--- /dev/null
+++ b/camera/common/default/include/CameraParameters.h
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS_H
+#define ANDROID_HARDWARE_CAMERA_PARAMETERS_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+struct Size {
+ int width;
+ int height;
+
+ Size() {
+ width = 0;
+ height = 0;
+ }
+
+ Size(int w, int h) {
+ width = w;
+ height = h;
+ }
+};
+
+class CameraParameters {
+ public:
+ CameraParameters();
+ CameraParameters(const String8& params) { unflatten(params); }
+ ~CameraParameters();
+
+ String8 flatten() const;
+ void unflatten(const String8& params);
+
+ void set(const char* key, const char* value);
+ void set(const char* key, int value);
+ void setFloat(const char* key, float value);
+ const char* get(const char* key) const;
+ int getInt(const char* key) const;
+ float getFloat(const char* key) const;
+
+ void remove(const char* key);
+
+ void setPreviewSize(int width, int height);
+ void getPreviewSize(int* width, int* height) const;
+ void getSupportedPreviewSizes(Vector<Size>& sizes) const;
+
+ // Set the dimensions in pixels to the given width and height
+ // for video frames. The given width and height must be one
+ // of the supported dimensions returned from
+ // getSupportedVideoSizes(). Must not be called if
+ // getSupportedVideoSizes() returns an empty Vector of Size.
+ void setVideoSize(int width, int height);
+ // Retrieve the current dimensions (width and height)
+ // in pixels for video frames, which must be one of the
+ // supported dimensions returned from getSupportedVideoSizes().
+ // Must not be called if getSupportedVideoSizes() returns an
+ // empty Vector of Size.
+ void getVideoSize(int* width, int* height) const;
+ // Retrieve a Vector of supported dimensions (width and height)
+ // in pixels for video frames. If sizes returned from the method
+ // is empty, the camera does not support calls to setVideoSize()
+ // or getVideoSize(). In adddition, it also indicates that
+ // the camera only has a single output, and does not have
+ // separate output for video frames and preview frame.
+ void getSupportedVideoSizes(Vector<Size>& sizes) const;
+ // Retrieve the preferred preview size (width and height) in pixels
+ // for video recording. The given width and height must be one of
+ // supported preview sizes returned from getSupportedPreviewSizes().
+ // Must not be called if getSupportedVideoSizes() returns an empty
+ // Vector of Size. If getSupportedVideoSizes() returns an empty
+ // Vector of Size, the width and height returned from this method
+ // is invalid, and is "-1x-1".
+ void getPreferredPreviewSizeForVideo(int* width, int* height) const;
+
+ void setPreviewFrameRate(int fps);
+ int getPreviewFrameRate() const;
+ void getPreviewFpsRange(int* min_fps, int* max_fps) const;
+ void setPreviewFormat(const char* format);
+ const char* getPreviewFormat() const;
+ void setPictureSize(int width, int height);
+ void getPictureSize(int* width, int* height) const;
+ void getSupportedPictureSizes(Vector<Size>& sizes) const;
+ void setPictureFormat(const char* format);
+ const char* getPictureFormat() const;
+
+ void dump() const;
+ status_t dump(int fd, const Vector<String16>& args) const;
+
+ /**
+ * Returns a Vector containing the supported preview formats
+ * as enums given in graphics.h.
+ */
+ void getSupportedPreviewFormats(Vector<int>& formats) const;
+
+ // Returns true if no keys are present
+ bool isEmpty() const;
+
+ // Parameter keys to communicate between camera application and driver.
+ // The access (read/write, read only, or write only) is viewed from the
+ // perspective of applications, not driver.
+
+ // Preview frame size in pixels (width x height).
+ // Example value: "480x320". Read/Write.
+ static const char KEY_PREVIEW_SIZE[];
+ // Supported preview frame sizes in pixels.
+ // Example value: "800x600,480x320". Read only.
+ static const char KEY_SUPPORTED_PREVIEW_SIZES[];
+ // The current minimum and maximum preview fps. This controls the rate of
+ // preview frames received (CAMERA_MSG_PREVIEW_FRAME). The minimum and
+ // maximum fps must be one of the elements from
+ // KEY_SUPPORTED_PREVIEW_FPS_RANGE parameter.
+ // Example value: "10500,26623"
+ static const char KEY_PREVIEW_FPS_RANGE[];
+ // The supported preview fps (frame-per-second) ranges. Each range contains
+ // a minimum fps and maximum fps. If minimum fps equals to maximum fps, the
+ // camera outputs frames in fixed frame rate. If not, the camera outputs
+ // frames in auto frame rate. The actual frame rate fluctuates between the
+ // minimum and the maximum. The list has at least one element. The list is
+ // sorted from small to large (first by maximum fps and then minimum fps).
+ // Example value: "(10500,26623),(15000,26623),(30000,30000)"
+ static const char KEY_SUPPORTED_PREVIEW_FPS_RANGE[];
+ // The image format for preview frames. See CAMERA_MSG_PREVIEW_FRAME in
+ // frameworks/av/include/camera/Camera.h. The default is
+ // PIXEL_FORMAT_YUV420SP. Example value: "yuv420sp" or PIXEL_FORMAT_XXX
+ // constants. Read/write.
+ static const char KEY_PREVIEW_FORMAT[];
+ // Supported image formats for preview frames.
+ // Example value: "yuv420sp,yuv422i-yuyv". Read only.
+ static const char KEY_SUPPORTED_PREVIEW_FORMATS[];
+ // Number of preview frames per second. This is the target frame rate. The
+ // actual frame rate depends on the driver.
+ // Example value: "15". Read/write.
+ static const char KEY_PREVIEW_FRAME_RATE[];
+ // Supported number of preview frames per second.
+ // Example value: "24,15,10". Read.
+ static const char KEY_SUPPORTED_PREVIEW_FRAME_RATES[];
+ // The dimensions for captured pictures in pixels (width x height).
+ // Example value: "1024x768". Read/write.
+ static const char KEY_PICTURE_SIZE[];
+ // Supported dimensions for captured pictures in pixels.
+ // Example value: "2048x1536,1024x768". Read only.
+ static const char KEY_SUPPORTED_PICTURE_SIZES[];
+ // The image format for captured pictures. See CAMERA_MSG_COMPRESSED_IMAGE
+ // in frameworks/base/include/camera/Camera.h.
+ // Example value: "jpeg" or PIXEL_FORMAT_XXX constants. Read/write.
+ static const char KEY_PICTURE_FORMAT[];
+ // Supported image formats for captured pictures.
+ // Example value: "jpeg,rgb565". Read only.
+ static const char KEY_SUPPORTED_PICTURE_FORMATS[];
+ // The width (in pixels) of EXIF thumbnail in Jpeg picture.
+ // Example value: "512". Read/write.
+ static const char KEY_JPEG_THUMBNAIL_WIDTH[];
+ // The height (in pixels) of EXIF thumbnail in Jpeg picture.
+ // Example value: "384". Read/write.
+ static const char KEY_JPEG_THUMBNAIL_HEIGHT[];
+ // Supported EXIF thumbnail sizes (width x height). 0x0 means not thumbnail
+ // in EXIF.
+ // Example value: "512x384,320x240,0x0". Read only.
+ static const char KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[];
+ // The quality of the EXIF thumbnail in Jpeg picture. The range is 1 to 100,
+ // with 100 being the best.
+ // Example value: "90". Read/write.
+ static const char KEY_JPEG_THUMBNAIL_QUALITY[];
+ // Jpeg quality of captured picture. The range is 1 to 100, with 100 being
+ // the best.
+ // Example value: "90". Read/write.
+ static const char KEY_JPEG_QUALITY[];
+ // The rotation angle in degrees relative to the orientation of the camera.
+ // This affects the pictures returned from CAMERA_MSG_COMPRESSED_IMAGE. The
+ // camera driver may set orientation in the EXIF header without rotating the
+ // picture. Or the driver may rotate the picture and the EXIF thumbnail. If
+ // the Jpeg picture is rotated, the orientation in the EXIF header will be
+ // missing or 1 (row #0 is top and column #0 is left side).
+ //
+ // Note that the JPEG pictures of front-facing cameras are not mirrored
+ // as in preview display.
+ //
+ // For example, suppose the natural orientation of the device is portrait.
+ // The device is rotated 270 degrees clockwise, so the device orientation is
+ // 270. Suppose a back-facing camera sensor is mounted in landscape and the
+ // top side of the camera sensor is aligned with the right edge of the
+ // display in natural orientation. So the camera orientation is 90. The
+ // rotation should be set to 0 (270 + 90).
+ //
+ // Example value: "0" or "90" or "180" or "270". Write only.
+ static const char KEY_ROTATION[];
+ // GPS latitude coordinate. GPSLatitude and GPSLatitudeRef will be stored in
+ // JPEG EXIF header.
+ // Example value: "25.032146" or "-33.462809". Write only.
+ static const char KEY_GPS_LATITUDE[];
+ // GPS longitude coordinate. GPSLongitude and GPSLongitudeRef will be stored
+ // in JPEG EXIF header.
+ // Example value: "121.564448" or "-70.660286". Write only.
+ static const char KEY_GPS_LONGITUDE[];
+ // GPS altitude. GPSAltitude and GPSAltitudeRef will be stored in JPEG EXIF
+ // header.
+ // Example value: "21.0" or "-5". Write only.
+ static const char KEY_GPS_ALTITUDE[];
+ // GPS timestamp (UTC in seconds since January 1, 1970). This should be
+ // stored in JPEG EXIF header.
+ // Example value: "1251192757". Write only.
+ static const char KEY_GPS_TIMESTAMP[];
+ // GPS Processing Method
+ // Example value: "GPS" or "NETWORK". Write only.
+ static const char KEY_GPS_PROCESSING_METHOD[];
+ // Current white balance setting.
+ // Example value: "auto" or WHITE_BALANCE_XXX constants. Read/write.
+ static const char KEY_WHITE_BALANCE[];
+ // Supported white balance settings.
+ // Example value: "auto,incandescent,daylight". Read only.
+ static const char KEY_SUPPORTED_WHITE_BALANCE[];
+ // Current color effect setting.
+ // Example value: "none" or EFFECT_XXX constants. Read/write.
+ static const char KEY_EFFECT[];
+ // Supported color effect settings.
+ // Example value: "none,mono,sepia". Read only.
+ static const char KEY_SUPPORTED_EFFECTS[];
+ // Current antibanding setting.
+ // Example value: "auto" or ANTIBANDING_XXX constants. Read/write.
+ static const char KEY_ANTIBANDING[];
+ // Supported antibanding settings.
+ // Example value: "auto,50hz,60hz,off". Read only.
+ static const char KEY_SUPPORTED_ANTIBANDING[];
+ // Current scene mode.
+ // Example value: "auto" or SCENE_MODE_XXX constants. Read/write.
+ static const char KEY_SCENE_MODE[];
+ // Supported scene mode settings.
+ // Example value: "auto,night,fireworks". Read only.
+ static const char KEY_SUPPORTED_SCENE_MODES[];
+ // Current flash mode.
+ // Example value: "auto" or FLASH_MODE_XXX constants. Read/write.
+ static const char KEY_FLASH_MODE[];
+ // Supported flash modes.
+ // Example value: "auto,on,off". Read only.
+ static const char KEY_SUPPORTED_FLASH_MODES[];
+ // Current focus mode. This will not be empty. Applications should call
+ // CameraHardwareInterface.autoFocus to start the focus if focus mode is
+ // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
+ // Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
+ static const char KEY_FOCUS_MODE[];
+ // Supported focus modes.
+ // Example value: "auto,macro,fixed". Read only.
+ static const char KEY_SUPPORTED_FOCUS_MODES[];
+ // The maximum number of focus areas supported. This is the maximum length
+ // of KEY_FOCUS_AREAS.
+ // Example value: "0" or "2". Read only.
+ static const char KEY_MAX_NUM_FOCUS_AREAS[];
+ // Current focus areas.
+ //
+ // Before accessing this parameter, apps should check
+ // KEY_MAX_NUM_FOCUS_AREAS first to know the maximum number of focus areas
+ // first. If the value is 0, focus area is not supported.
+ //
+ // Each focus area is a five-element int array. The first four elements are
+ // the rectangle of the area (left, top, right, bottom). The direction is
+ // relative to the sensor orientation, that is, what the sensor sees. The
+ // direction is not affected by the rotation or mirroring of
+ // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates range from -1000 to 1000.
+ // (-1000,-1000) is the upper left point. (1000, 1000) is the lower right
+ // point. The width and height of focus areas cannot be 0 or negative.
+ //
+ // The fifth element is the weight. Values for weight must range from 1 to
+ // 1000. The weight should be interpreted as a per-pixel weight - all
+ // pixels in the area have the specified weight. This means a small area
+ // with the same weight as a larger area will have less influence on the
+ // focusing than the larger area. Focus areas can partially overlap and the
+ // driver will add the weights in the overlap region.
+ //
+ // A special case of single focus area (0,0,0,0,0) means driver to decide
+ // the focus area. For example, the driver may use more signals to decide
+ // focus areas and change them dynamically. Apps can set (0,0,0,0,0) if they
+ // want the driver to decide focus areas.
+ //
+ // Focus areas are relative to the current field of view (KEY_ZOOM). No
+ // matter what the zoom level is, (-1000,-1000) represents the top of the
+ // currently visible camera frame. The focus area cannot be set to be
+ // outside the current field of view, even when using zoom.
+ //
+ // Focus area only has effect if the current focus mode is FOCUS_MODE_AUTO,
+ // FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_VIDEO, or
+ // FOCUS_MODE_CONTINUOUS_PICTURE.
+ // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+ static const char KEY_FOCUS_AREAS[];
+ // Focal length in millimeter.
+ // Example value: "4.31". Read only.
+ static const char KEY_FOCAL_LENGTH[];
+ // Horizontal angle of view in degrees.
+ // Example value: "54.8". Read only.
+ static const char KEY_HORIZONTAL_VIEW_ANGLE[];
+ // Vertical angle of view in degrees.
+ // Example value: "42.5". Read only.
+ static const char KEY_VERTICAL_VIEW_ANGLE[];
+ // Exposure compensation index. 0 means exposure is not adjusted.
+ // Example value: "-5" or "5". Read/write.
+ static const char KEY_EXPOSURE_COMPENSATION[];
+ // The maximum exposure compensation index (>=0).
+ // Example value: "6". Read only.
+ static const char KEY_MAX_EXPOSURE_COMPENSATION[];
+ // The minimum exposure compensation index (<=0).
+ // Example value: "-6". Read only.
+ static const char KEY_MIN_EXPOSURE_COMPENSATION[];
+ // The exposure compensation step. Exposure compensation index multiply by
+ // step eqals to EV. Ex: if exposure compensation index is -6 and step is
+ // 0.3333, EV is -2.
+ // Example value: "0.333333333" or "0.5". Read only.
+ static const char KEY_EXPOSURE_COMPENSATION_STEP[];
+ // The state of the auto-exposure lock. "true" means that
+ // auto-exposure is locked to its current value and will not
+ // change. "false" means the auto-exposure routine is free to
+ // change exposure values. If auto-exposure is already locked,
+ // setting this to true again has no effect (the driver will not
+ // recalculate exposure values). Changing exposure compensation
+ // settings will still affect the exposure settings while
+ // auto-exposure is locked. Stopping preview or taking a still
+ // image will not change the lock. In conjunction with
+ // exposure compensation, this allows for capturing multi-exposure
+ // brackets with known relative exposure values. Locking
+ // auto-exposure after open but before the first call to
+ // startPreview may result in severely over- or under-exposed
+ // images. The driver will not change the AE lock after
+ // auto-focus completes.
+ static const char KEY_AUTO_EXPOSURE_LOCK[];
+ // Whether locking the auto-exposure is supported. "true" means it is, and
+ // "false" or this key not existing means it is not supported.
+ static const char KEY_AUTO_EXPOSURE_LOCK_SUPPORTED[];
+ // The state of the auto-white balance lock. "true" means that
+ // auto-white balance is locked to its current value and will not
+ // change. "false" means the auto-white balance routine is free to
+ // change white balance values. If auto-white balance is already
+ // locked, setting this to true again has no effect (the driver
+ // will not recalculate white balance values). Stopping preview or
+ // taking a still image will not change the lock. In conjunction
+ // with exposure compensation, this allows for capturing
+ // multi-exposure brackets with fixed white balance. Locking
+ // auto-white balance after open but before the first call to
+ // startPreview may result in severely incorrect color. The
+ // driver will not change the AWB lock after auto-focus
+ // completes.
+ static const char KEY_AUTO_WHITEBALANCE_LOCK[];
+ // Whether locking the auto-white balance is supported. "true"
+ // means it is, and "false" or this key not existing means it is
+ // not supported.
+ static const char KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED[];
+
+ // The maximum number of metering areas supported. This is the maximum
+ // length of KEY_METERING_AREAS.
+ // Example value: "0" or "2". Read only.
+ static const char KEY_MAX_NUM_METERING_AREAS[];
+ // Current metering areas. Camera driver uses these areas to decide
+ // exposure.
+ //
+ // Before accessing this parameter, apps should check
+ // KEY_MAX_NUM_METERING_AREAS first to know the maximum number of metering
+ // areas first. If the value is 0, metering area is not supported.
+ //
+ // Each metering area is a rectangle with specified weight. The direction is
+ // relative to the sensor orientation, that is, what the sensor sees. The
+ // direction is not affected by the rotation or mirroring of
+ // CAMERA_CMD_SET_DISPLAY_ORIENTATION. Coordinates of the rectangle range
+ // from -1000 to 1000. (-1000, -1000) is the upper left point. (1000, 1000)
+ // is the lower right point. The width and height of metering areas cannot
+ // be 0 or negative.
+ //
+ // The fifth element is the weight. Values for weight must range from 1 to
+ // 1000. The weight should be interpreted as a per-pixel weight - all
+ // pixels in the area have the specified weight. This means a small area
+ // with the same weight as a larger area will have less influence on the
+ // metering than the larger area. Metering areas can partially overlap and
+ // the driver will add the weights in the overlap region.
+ //
+ // A special case of all-zero single metering area means driver to decide
+ // the metering area. For example, the driver may use more signals to decide
+ // metering areas and change them dynamically. Apps can set all-zero if they
+ // want the driver to decide metering areas.
+ //
+ // Metering areas are relative to the current field of view (KEY_ZOOM).
+ // No matter what the zoom level is, (-1000,-1000) represents the top of the
+ // currently visible camera frame. The metering area cannot be set to be
+ // outside the current field of view, even when using zoom.
+ //
+ // No matter what metering areas are, the final exposure are compensated
+ // by KEY_EXPOSURE_COMPENSATION.
+ // Example value: "(-10,-10,0,0,300),(0,0,10,10,700)". Read/write.
+ static const char KEY_METERING_AREAS[];
+ // Current zoom value.
+ // Example value: "0" or "6". Read/write.
+ static const char KEY_ZOOM[];
+ // Maximum zoom value.
+ // Example value: "6". Read only.
+ static const char KEY_MAX_ZOOM[];
+ // The zoom ratios of all zoom values. The zoom ratio is in 1/100
+ // increments. Ex: a zoom of 3.2x is returned as 320. The number of list
+ // elements is KEY_MAX_ZOOM + 1. The first element is always 100. The last
+ // element is the zoom ratio of zoom value KEY_MAX_ZOOM.
+ // Example value: "100,150,200,250,300,350,400". Read only.
+ static const char KEY_ZOOM_RATIOS[];
+ // Whether zoom is supported. Zoom is supported if the value is "true". Zoom
+ // is not supported if the value is not "true" or the key does not exist.
+ // Example value: "true". Read only.
+ static const char KEY_ZOOM_SUPPORTED[];
+ // Whether if smooth zoom is supported. Smooth zoom is supported if the
+ // value is "true". It is not supported if the value is not "true" or the
+ // key does not exist.
+ // See CAMERA_CMD_START_SMOOTH_ZOOM, CAMERA_CMD_STOP_SMOOTH_ZOOM, and
+ // CAMERA_MSG_ZOOM in frameworks/base/include/camera/Camera.h.
+ // Example value: "true". Read only.
+ static const char KEY_SMOOTH_ZOOM_SUPPORTED[];
+
+ // The distances (in meters) from the camera to where an object appears to
+ // be in focus. The object is sharpest at the optimal focus distance. The
+ // depth of field is the far focus distance minus near focus distance.
+ //
+ // Focus distances may change after starting auto focus, canceling auto
+ // focus, or starting the preview. Applications can read this anytime to get
+ // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
+ // focus distances may change from time to time.
+ //
+ // This is intended to estimate the distance between the camera and the
+ // subject. After autofocus, the subject distance may be within near and far
+ // focus distance. However, the precision depends on the camera hardware,
+ // autofocus algorithm, the focus area, and the scene. The error can be
+ // large and it should be only used as a reference.
+ //
+ // Far focus distance > optimal focus distance > near focus distance. If
+ // the far focus distance is infinity, the value should be "Infinity" (case
+ // sensitive). The format is three float values separated by commas. The
+ // first is near focus distance. The second is optimal focus distance. The
+ // third is far focus distance.
+ // Example value: "0.95,1.9,Infinity" or "0.049,0.05,0.051". Read only.
+ static const char KEY_FOCUS_DISTANCES[];
+
+ // The current dimensions in pixels (width x height) for video frames.
+ // The width and height must be one of the supported sizes retrieved
+ // via KEY_SUPPORTED_VIDEO_SIZES.
+ // Example value: "1280x720". Read/write.
+ static const char KEY_VIDEO_SIZE[];
+ // A list of the supported dimensions in pixels (width x height)
+ // for video frames. See CAMERA_MSG_VIDEO_FRAME for details in
+ // frameworks/base/include/camera/Camera.h.
+ // Example: "176x144,1280x720". Read only.
+ static const char KEY_SUPPORTED_VIDEO_SIZES[];
+
+ // The maximum number of detected faces supported by hardware face
+ // detection. If the value is 0, hardware face detection is not supported.
+ // Example: "5". Read only
+ static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
+
+ // The maximum number of detected faces supported by software face
+ // detection. If the value is 0, software face detection is not supported.
+ // Example: "5". Read only
+ static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
+
+ // Preferred preview frame size in pixels for video recording.
+ // The width and height must be one of the supported sizes retrieved
+ // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
+ // getSupportedVideoSizes() does not return an empty Vector of Size.
+ // Camcorder applications are recommended to set the preview size
+ // to a value that is not larger than the preferred preview size.
+ // In other words, the product of the width and height of the
+ // preview size should not be larger than that of the preferred
+ // preview size. In addition, we recommend to choos a preview size
+ // that has the same aspect ratio as the resolution of video to be
+ // recorded.
+ // Example value: "800x600". Read only.
+ static const char KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[];
+
+ // The image format for video frames. See CAMERA_MSG_VIDEO_FRAME in
+ // frameworks/base/include/camera/Camera.h.
+ // Example value: "yuv420sp" or PIXEL_FORMAT_XXX constants. Read only.
+ static const char KEY_VIDEO_FRAME_FORMAT[];
+
+ // Sets the hint of the recording mode. If this is true, MediaRecorder.start
+ // may be faster or has less glitches. This should be called before starting
+ // the preview for the best result. But it is allowed to change the hint
+ // while the preview is active. The default value is false.
+ //
+ // The apps can still call Camera.takePicture when the hint is true. The
+ // apps can call MediaRecorder.start when the hint is false. But the
+ // performance may be worse.
+ // Example value: "true" or "false". Read/write.
+ static const char KEY_RECORDING_HINT[];
+
+ // Returns true if video snapshot is supported. That is, applications
+ // can call Camera.takePicture during recording. Applications do not need to
+ // call Camera.startPreview after taking a picture. The preview will be
+ // still active. Other than that, taking a picture during recording is
+ // identical to taking a picture normally. All settings and methods related
+ // to takePicture work identically. Ex: KEY_PICTURE_SIZE,
+ // KEY_SUPPORTED_PICTURE_SIZES, KEY_JPEG_QUALITY, KEY_ROTATION, and etc.
+ // The picture will have an EXIF header. FLASH_MODE_AUTO and FLASH_MODE_ON
+ // also still work, but the video will record the flash.
+ //
+ // Applications can set shutter callback as null to avoid the shutter
+ // sound. It is also recommended to set raw picture and post view callbacks
+ // to null to avoid the interrupt of preview display.
+ //
+ // Field-of-view of the recorded video may be different from that of the
+ // captured pictures.
+ // Example value: "true" or "false". Read only.
+ static const char KEY_VIDEO_SNAPSHOT_SUPPORTED[];
+
+ // The state of the video stabilization. If set to true, both the
+ // preview stream and the recorded video stream are stabilized by
+ // the camera. Only valid to set if KEY_VIDEO_STABILIZATION_SUPPORTED is
+ // set to true.
+ //
+ // The value of this key can be changed any time the camera is
+ // open. If preview or recording is active, it is acceptable for
+ // there to be a slight video glitch when video stabilization is
+ // toggled on and off.
+ //
+ // This only stabilizes video streams (between-frames stabilization), and
+ // has no effect on still image capture.
+ static const char KEY_VIDEO_STABILIZATION[];
+
+ // Returns true if video stabilization is supported. That is, applications
+ // can set KEY_VIDEO_STABILIZATION to true and have a stabilized preview
+ // stream and record stabilized videos.
+ static const char KEY_VIDEO_STABILIZATION_SUPPORTED[];
+
+ // Supported modes for special effects with light.
+ // Example values: "lowlight,hdr".
+ static const char KEY_LIGHTFX[];
+
+ // Value for KEY_ZOOM_SUPPORTED or KEY_SMOOTH_ZOOM_SUPPORTED.
+ static const char TRUE[];
+ static const char FALSE[];
+
+ // Value for KEY_FOCUS_DISTANCES.
+ static const char FOCUS_DISTANCE_INFINITY[];
+
+ // Values for white balance settings.
+ static const char WHITE_BALANCE_AUTO[];
+ static const char WHITE_BALANCE_INCANDESCENT[];
+ static const char WHITE_BALANCE_FLUORESCENT[];
+ static const char WHITE_BALANCE_WARM_FLUORESCENT[];
+ static const char WHITE_BALANCE_DAYLIGHT[];
+ static const char WHITE_BALANCE_CLOUDY_DAYLIGHT[];
+ static const char WHITE_BALANCE_TWILIGHT[];
+ static const char WHITE_BALANCE_SHADE[];
+
+ // Values for effect settings.
+ static const char EFFECT_NONE[];
+ static const char EFFECT_MONO[];
+ static const char EFFECT_NEGATIVE[];
+ static const char EFFECT_SOLARIZE[];
+ static const char EFFECT_SEPIA[];
+ static const char EFFECT_POSTERIZE[];
+ static const char EFFECT_WHITEBOARD[];
+ static const char EFFECT_BLACKBOARD[];
+ static const char EFFECT_AQUA[];
+
+ // Values for antibanding settings.
+ static const char ANTIBANDING_AUTO[];
+ static const char ANTIBANDING_50HZ[];
+ static const char ANTIBANDING_60HZ[];
+ static const char ANTIBANDING_OFF[];
+
+ // Values for flash mode settings.
+ // Flash will not be fired.
+ static const char FLASH_MODE_OFF[];
+ // Flash will be fired automatically when required. The flash may be fired
+ // during preview, auto-focus, or snapshot depending on the driver.
+ static const char FLASH_MODE_AUTO[];
+ // Flash will always be fired during snapshot. The flash may also be
+ // fired during preview or auto-focus depending on the driver.
+ static const char FLASH_MODE_ON[];
+ // Flash will be fired in red-eye reduction mode.
+ static const char FLASH_MODE_RED_EYE[];
+ // Constant emission of light during preview, auto-focus and snapshot.
+ // This can also be used for video recording.
+ static const char FLASH_MODE_TORCH[];
+
+ // Values for scene mode settings.
+ static const char SCENE_MODE_AUTO[];
+ static const char SCENE_MODE_ACTION[];
+ static const char SCENE_MODE_PORTRAIT[];
+ static const char SCENE_MODE_LANDSCAPE[];
+ static const char SCENE_MODE_NIGHT[];
+ static const char SCENE_MODE_NIGHT_PORTRAIT[];
+ static const char SCENE_MODE_THEATRE[];
+ static const char SCENE_MODE_BEACH[];
+ static const char SCENE_MODE_SNOW[];
+ static const char SCENE_MODE_SUNSET[];
+ static const char SCENE_MODE_STEADYPHOTO[];
+ static const char SCENE_MODE_FIREWORKS[];
+ static const char SCENE_MODE_SPORTS[];
+ static const char SCENE_MODE_PARTY[];
+ static const char SCENE_MODE_CANDLELIGHT[];
+ // Applications are looking for a barcode. Camera driver will be optimized
+ // for barcode reading.
+ static const char SCENE_MODE_BARCODE[];
+ // A high-dynamic range mode. In this mode, the HAL module will use a
+ // capture strategy that extends the dynamic range of the captured
+ // image in some fashion. Only the final image is returned.
+ static const char SCENE_MODE_HDR[];
+
+ // Pixel color formats for KEY_PREVIEW_FORMAT, KEY_PICTURE_FORMAT,
+ // and KEY_VIDEO_FRAME_FORMAT
+ static const char PIXEL_FORMAT_YUV422SP[];
+ static const char PIXEL_FORMAT_YUV420SP[]; // NV21
+ static const char PIXEL_FORMAT_YUV422I[]; // YUY2
+ static const char PIXEL_FORMAT_YUV420P[]; // YV12
+ static const char PIXEL_FORMAT_RGB565[];
+ static const char PIXEL_FORMAT_RGBA8888[];
+ static const char PIXEL_FORMAT_JPEG[];
+ // Raw bayer format used for images, which is 10 bit precision samples
+ // stored in 16 bit words. The filter pattern is RGGB.
+ static const char PIXEL_FORMAT_BAYER_RGGB[];
+ // Pixel format is not known to the framework
+ static const char PIXEL_FORMAT_ANDROID_OPAQUE[];
+
+ // Values for focus mode settings.
+ // Auto-focus mode. Applications should call
+ // CameraHardwareInterface.autoFocus to start the focus in this mode.
+ static const char FOCUS_MODE_AUTO[];
+ // Focus is set at infinity. Applications should not call
+ // CameraHardwareInterface.autoFocus in this mode.
+ static const char FOCUS_MODE_INFINITY[];
+ // Macro (close-up) focus mode. Applications should call
+ // CameraHardwareInterface.autoFocus to start the focus in this mode.
+ static const char FOCUS_MODE_MACRO[];
+ // Focus is fixed. The camera is always in this mode if the focus is not
+ // adjustable. If the camera has auto-focus, this mode can fix the
+ // focus, which is usually at hyperfocal distance. Applications should
+ // not call CameraHardwareInterface.autoFocus in this mode.
+ static const char FOCUS_MODE_FIXED[];
+ // Extended depth of field (EDOF). Focusing is done digitally and
+ // continuously. Applications should not call
+ // CameraHardwareInterface.autoFocus in this mode.
+ static const char FOCUS_MODE_EDOF[];
+ // Continuous auto focus mode intended for video recording. The camera
+ // continuously tries to focus. This is the best choice for video
+ // recording because the focus changes smoothly . Applications still can
+ // call CameraHardwareInterface.takePicture in this mode but the subject may
+ // not be in focus. Auto focus starts when the parameter is set.
+ //
+ // Applications can call CameraHardwareInterface.autoFocus in this mode. The
+ // focus callback will immediately return with a boolean that indicates
+ // whether the focus is sharp or not. The focus position is locked after
+ // autoFocus call. If applications want to resume the continuous focus,
+ // cancelAutoFocus must be called. Restarting the preview will not resume
+ // the continuous autofocus. To stop continuous focus, applications should
+ // change the focus mode to other modes.
+ static const char FOCUS_MODE_CONTINUOUS_VIDEO[];
+ // Continuous auto focus mode intended for taking pictures. The camera
+ // continuously tries to focus. The speed of focus change is more aggressive
+ // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is
+ // set.
+ //
+ // Applications can call CameraHardwareInterface.autoFocus in this mode. If
+ // the autofocus is in the middle of scanning, the focus callback will
+ // return when it completes. If the autofocus is not scanning, focus
+ // callback will immediately return with a boolean that indicates whether
+ // the focus is sharp or not. The apps can then decide if they want to take
+ // a picture immediately or to change the focus mode to auto, and run a full
+ // autofocus cycle. The focus position is locked after autoFocus call. If
+ // applications want to resume the continuous focus, cancelAutoFocus must be
+ // called. Restarting the preview will not resume the continuous autofocus.
+ // To stop continuous focus, applications should change the focus mode to
+ // other modes.
+ static const char FOCUS_MODE_CONTINUOUS_PICTURE[];
+
+ // Values for light special effects
+ // Low-light enhancement mode
+ static const char LIGHTFX_LOWLIGHT[];
+ // High-dynamic range mode
+ static const char LIGHTFX_HDR[];
+
+ /**
+ * Returns the the supported preview formats as an enum given in graphics.h
+ * corrsponding to the format given in the input string or -1 if no such
+ * conversion exists.
+ */
+ static int previewFormatToEnum(const char* format);
+
+ private:
+ DefaultKeyedVector<String8, String8> mMap;
+};
+
+}; // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::CameraParameters CameraParameters;
+typedef android::hardware::camera::common::helper::Size Size;
+} // namespace V1_0::helper
+
+}; // namespace common
+}; // namespace camera
+}; // namespace hardware
+}; // namespace android
+
+#endif
diff --git a/camera/common/default/include/Exif.h b/camera/common/default/include/Exif.h
new file mode 100644
index 0000000..6974b8e
--- /dev/null
+++ b/camera/common/default/include/Exif.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
+#define ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
+
+#include "CameraMetadata.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// This is based on the original ChromeOS ARC implementation of a V4L2 HAL
+
+// ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can
+// also add a thumbnail in the APP1 segment if thumbnail size is specified.
+// ExifUtils can be reused with different images by calling initialize().
+//
+// Example of using this class :
+// std::unique_ptr<ExifUtils> utils(ExifUtils::Create());
+// utils->initialize();
+// ...
+// // Call ExifUtils functions to set Exif tags.
+// ...
+// utils->GenerateApp1(thumbnail_buffer, thumbnail_size);
+// unsigned int app1Length = utils->GetApp1Length();
+// uint8_t* app1Buffer = new uint8_t[app1Length];
+// memcpy(app1Buffer, utils->GetApp1Buffer(), app1Length);
+class ExifUtils {
+ public:
+ virtual ~ExifUtils();
+
+ static ExifUtils* create();
+
+ // Initialize() can be called multiple times. The setting of Exif tags will be
+ // cleared.
+ virtual bool initialize() = 0;
+
+ // Set all known fields from a metadata structure
+ virtual bool setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
+ const size_t imageHeight) = 0;
+
+ // Sets the len aperture.
+ // Returns false if memory allocation fails.
+ virtual bool setAperture(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the value of brightness.
+ // Returns false if memory allocation fails.
+ virtual bool setBrightness(int32_t numerator, int32_t denominator) = 0;
+
+ // Sets the color space.
+ // Returns false if memory allocation fails.
+ virtual bool setColorSpace(uint16_t color_space) = 0;
+
+ // Sets the information to compressed data.
+ // Returns false if memory allocation fails.
+ virtual bool setComponentsConfiguration(const std::string& components_configuration) = 0;
+
+ // Sets the compression scheme used for the image data.
+ // Returns false if memory allocation fails.
+ virtual bool setCompression(uint16_t compression) = 0;
+
+ // Sets image contrast.
+ // Returns false if memory allocation fails.
+ virtual bool setContrast(uint16_t contrast) = 0;
+
+ // Sets the date and time of image last modified. It takes local time. The
+ // name of the tag is DateTime in IFD0.
+ // Returns false if memory allocation fails.
+ virtual bool setDateTime(const struct tm& t) = 0;
+
+ // Sets the image description.
+ // Returns false if memory allocation fails.
+ virtual bool setDescription(const std::string& description) = 0;
+
+ // Sets the digital zoom ratio. If the numerator is 0, it means digital zoom
+ // was not used.
+ // Returns false if memory allocation fails.
+ virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the exposure bias.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureBias(int32_t numerator, int32_t denominator) = 0;
+
+ // Sets the exposure mode set when the image was shot.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureMode(uint16_t exposure_mode) = 0;
+
+ // Sets the program used by the camera to set exposure when the picture is
+ // taken.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureProgram(uint16_t exposure_program) = 0;
+
+ // Sets the exposure time, given in seconds.
+ // Returns false if memory allocation fails.
+ virtual bool setExposureTime(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the status of flash.
+ // Returns false if memory allocation fails.
+ virtual bool setFlash(uint16_t flash) = 0;
+
+ // Sets the F number.
+ // Returns false if memory allocation fails.
+ virtual bool setFNumber(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the focal length of lens used to take the image in millimeters.
+ // Returns false if memory allocation fails.
+ virtual bool setFocalLength(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the degree of overall image gain adjustment.
+ // Returns false if memory allocation fails.
+ virtual bool setGainControl(uint16_t gain_control) = 0;
+
+ // Sets the altitude in meters.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsAltitude(double altitude) = 0;
+
+ // Sets the latitude with degrees minutes seconds format.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsLatitude(double latitude) = 0;
+
+ // Sets the longitude with degrees minutes seconds format.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsLongitude(double longitude) = 0;
+
+ // Sets GPS processing method.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsProcessingMethod(const std::string& method) = 0;
+
+ // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
+ // Returns false if memory allocation fails.
+ virtual bool setGpsTimestamp(const struct tm& t) = 0;
+
+ // Sets the height (number of rows) of main image.
+ // Returns false if memory allocation fails.
+ virtual bool setImageHeight(uint32_t length) = 0;
+
+ // Sets the width (number of columns) of main image.
+ // Returns false if memory allocation fails.
+ virtual bool setImageWidth(uint32_t width) = 0;
+
+ // Sets the ISO speed.
+ // Returns false if memory allocation fails.
+ virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings) = 0;
+
+ // Sets the kind of light source.
+ // Returns false if memory allocation fails.
+ virtual bool setLightSource(uint16_t light_source) = 0;
+
+ // Sets the smallest F number of the lens.
+ // Returns false if memory allocation fails.
+ virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the metering mode.
+ // Returns false if memory allocation fails.
+ virtual bool setMeteringMode(uint16_t metering_mode) = 0;
+
+ // Sets image orientation.
+ // Returns false if memory allocation fails.
+ virtual bool setOrientation(uint16_t orientation) = 0;
+
+ // Sets the unit for measuring XResolution and YResolution.
+ // Returns false if memory allocation fails.
+ virtual bool setResolutionUnit(uint16_t resolution_unit) = 0;
+
+ // Sets image saturation.
+ // Returns false if memory allocation fails.
+ virtual bool setSaturation(uint16_t saturation) = 0;
+
+ // Sets the type of scene that was shot.
+ // Returns false if memory allocation fails.
+ virtual bool setSceneCaptureType(uint16_t type) = 0;
+
+ // Sets image sharpness.
+ // Returns false if memory allocation fails.
+ virtual bool setSharpness(uint16_t sharpness) = 0;
+
+ // Sets the shutter speed.
+ // Returns false if memory allocation fails.
+ virtual bool setShutterSpeed(int32_t numerator, int32_t denominator) = 0;
+
+ // Sets the distance to the subject, given in meters.
+ // Returns false if memory allocation fails.
+ virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the fractions of seconds for the <DateTime> tag.
+ // Returns false if memory allocation fails.
+ virtual bool setSubsecTime(const std::string& subsec_time) = 0;
+
+ // Sets the white balance mode set when the image was shot.
+ // Returns false if memory allocation fails.
+ virtual bool setWhiteBalance(uint16_t white_balance) = 0;
+
+ // Sets the number of pixels per resolution unit in the image width.
+ // Returns false if memory allocation fails.
+ virtual bool setXResolution(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the position of chrominance components in relation to the luminance
+ // component.
+ // Returns false if memory allocation fails.
+ virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning) = 0;
+
+ // Sets the number of pixels per resolution unit in the image length.
+ // Returns false if memory allocation fails.
+ virtual bool setYResolution(uint32_t numerator, uint32_t denominator) = 0;
+
+ // Sets the manufacturer of camera.
+ // Returns false if memory allocation fails.
+ virtual bool setMake(const std::string& make) = 0;
+
+ // Sets the model number of camera.
+ // Returns false if memory allocation fails.
+ virtual bool setModel(const std::string& model) = 0;
+
+ // Generates APP1 segment.
+ // Returns false if generating APP1 segment fails.
+ virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size) = 0;
+
+ // Gets buffer of APP1 segment. This method must be called only after calling
+ // GenerateAPP1().
+ virtual const uint8_t* getApp1Buffer() = 0;
+
+ // Gets length of APP1 segment. This method must be called only after calling
+ // GenerateAPP1().
+ virtual unsigned int getApp1Length() = 0;
+};
+
+} // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::ExifUtils ExifUtils;
+} // namespace V1_0::helper
+
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_INTERFACES_CAMERA_COMMON_1_0_EXIF_H
diff --git a/camera/common/default/include/HandleImporter.h b/camera/common/default/include/HandleImporter.h
new file mode 100644
index 0000000..5408ba9
--- /dev/null
+++ b/camera/common/default/include/HandleImporter.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CAMERA_COMMON_1_0_HANDLEIMPORTED_H
+#define CAMERA_COMMON_1_0_HANDLEIMPORTED_H
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <cutils/native_handle.h>
+#include <utils/Mutex.h>
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// Borrowed from graphics HAL. Use this until gralloc mapper HAL is working
+class HandleImporter {
+ public:
+ HandleImporter();
+
+ // In IComposer, any buffer_handle_t is owned by the caller and we need to
+ // make a clone for hwcomposer2. We also need to translate empty handle
+ // to nullptr. This function does that, in-place.
+ bool importBuffer(buffer_handle_t& handle);
+ void freeBuffer(buffer_handle_t handle);
+ bool importFence(const native_handle_t* handle, int& fd) const;
+ void closeFence(int fd) const;
+
+ // Locks 1-D buffer. Assumes caller has waited for acquire fences.
+ void* lock(buffer_handle_t& buf, uint64_t cpuUsage, size_t size);
+
+ // Locks 2-D buffer. Assumes caller has waited for acquire fences.
+ void* lock(buffer_handle_t& buf, uint64_t cpuUsage, const IMapper::Rect& accessRegion);
+
+ // Assumes caller has waited for acquire fences.
+ YCbCrLayout lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion);
+
+ // Query the stride of the first plane in bytes.
+ status_t getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/);
+
+ int unlock(buffer_handle_t& buf); // returns release fence
+
+ // Query Gralloc4 metadata
+ bool isSmpte2086Present(const buffer_handle_t& buf);
+ bool isSmpte2094_10Present(const buffer_handle_t& buf);
+ bool isSmpte2094_40Present(const buffer_handle_t& buf);
+
+ private:
+ void initializeLocked();
+ void cleanup();
+
+ template <class M, class E>
+ bool importBufferInternal(const sp<M> mapper, buffer_handle_t& handle);
+ template <class M, class E>
+ YCbCrLayout lockYCbCrInternal(const sp<M> mapper, buffer_handle_t& buf, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion);
+ template <class M, class E>
+ int unlockInternal(const sp<M> mapper, buffer_handle_t& buf);
+
+ Mutex mLock;
+ bool mInitialized;
+ sp<IMapper> mMapperV2;
+ sp<graphics::mapper::V3_0::IMapper> mMapperV3;
+ sp<graphics::mapper::V4_0::IMapper> mMapperV4;
+};
+
+} // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::HandleImporter HandleImporter;
+} // namespace V1_0::helper
+
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // CAMERA_COMMON_1_0_HANDLEIMPORTED_H
diff --git a/camera/common/default/include/SimpleThread.h b/camera/common/default/include/SimpleThread.h
new file mode 100644
index 0000000..d1becd6
--- /dev/null
+++ b/camera/common/default/include/SimpleThread.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_COMMON_SIMPLETHREAD_H_
+#define HARDWARE_INTERFACES_CAMERA_COMMON_SIMPLETHREAD_H_
+
+#include <thread>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace common {
+namespace helper {
+
+// A simple looper based on std::thread.
+class SimpleThread {
+ public:
+ SimpleThread();
+ virtual ~SimpleThread();
+
+ // Explicit call to start execution of the thread. No thread is created before this function
+ // is called.
+ virtual void run() final;
+ virtual void requestExitAndWait() final;
+
+ protected:
+ // Main logic of the thread. This function is called repeatedly until it returns false.
+ // Thread execution stops if this function returns false.
+ virtual bool threadLoop() = 0;
+
+ // Returns true if the thread execution should stop. Should be used by threadLoop to check if
+ // the thread has been requested to exit.
+ virtual inline bool exitPending() final { return mDone.load(std::memory_order_acquire); }
+
+ private:
+ // Wraps threadLoop in a simple while loop that allows safe exit
+ virtual void runLoop() final;
+
+ // Flag to signal end of thread execution. This flag is checked before every iteration
+ // of threadLoop.
+ std::atomic_bool mDone;
+ std::thread mThread;
+};
+
+} // namespace helper
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_COMMON_SIMPLETHREAD_H_
diff --git a/camera/common/default/include/VendorTagDescriptor.h b/camera/common/default/include/VendorTagDescriptor.h
new file mode 100644
index 0000000..3133c26
--- /dev/null
+++ b/camera/common/default/include/VendorTagDescriptor.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
+#define CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H
+
+#include <system/camera_vendor_tags.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include <stdint.h>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace camera2 {
+namespace params {
+
+/**
+ * VendorTagDescriptor objects are containers for the vendor tag
+ * definitions provided, and are typically used to pass the vendor tag
+ * information enumerated by the HAL to clients of the camera service.
+ */
+class VendorTagDescriptor {
+ public:
+ virtual ~VendorTagDescriptor();
+
+ VendorTagDescriptor();
+ VendorTagDescriptor(const VendorTagDescriptor& src);
+ VendorTagDescriptor& operator=(const VendorTagDescriptor& rhs);
+
+ void copyFrom(const VendorTagDescriptor& src);
+
+ /**
+ * The following 'get*' methods implement the corresponding
+ * functions defined in
+ * system/media/camera/include/system/camera_vendor_tags.h
+ */
+
+ // Returns the number of vendor tags defined.
+ int getTagCount() const;
+
+ // Returns an array containing the id's of vendor tags defined.
+ void getTagArray(uint32_t* tagArray) const;
+
+ // Returns the section name string for a given vendor tag id.
+ const char* getSectionName(uint32_t tag) const;
+
+ // Returns the index in section vectors returned in getAllSectionNames()
+ // for a given vendor tag id. -1 if input tag does not exist.
+ ssize_t getSectionIndex(uint32_t tag) const;
+
+ // Returns the tag name string for a given vendor tag id.
+ const char* getTagName(uint32_t tag) const;
+
+ // Returns the tag type for a given vendor tag id.
+ int getTagType(uint32_t tag) const;
+
+ /**
+ * Convenience method to get a vector containing all vendor tag
+ * sections, or an empty vector if none are defined.
+ * The pointer is valid for the lifetime of the VendorTagDescriptor,
+ * or until copyFrom is invoked.
+ */
+ const SortedVector<String8>* getAllSectionNames() const;
+
+ /**
+ * Lookup the tag id for a given tag name and section.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ status_t lookupTag(const String8& name, const String8& section, /*out*/ uint32_t* tag) const;
+
+ /**
+ * Dump the currently configured vendor tags to a file descriptor.
+ */
+ void dump(int fd, int verbosity, int indentation) const;
+
+ protected:
+ KeyedVector<String8, KeyedVector<String8, uint32_t>*> mReverseMapping;
+ KeyedVector<uint32_t, String8> mTagToNameMap;
+ KeyedVector<uint32_t, uint32_t> mTagToSectionMap; // Value is offset in mSections
+
+ std::unordered_map<uint32_t, int32_t> mTagToTypeMap;
+ SortedVector<String8> mSections;
+ // must be int32_t to be compatible with Parcel::writeInt32
+ int32_t mTagCount;
+
+ vendor_tag_ops mVendorOps;
+};
+} /* namespace params */
+} /* namespace camera2 */
+
+namespace camera {
+namespace common {
+namespace helper {
+
+/**
+ * This version of VendorTagDescriptor must be stored in Android sp<>, and adds support for using it
+ * as a global tag descriptor.
+ *
+ * It's a child class of the basic hardware::camera2::params::VendorTagDescriptor since basic
+ * Parcelable objects cannot require being kept in an sp<> and still work with auto-generated AIDL
+ * interface implementations.
+ */
+class VendorTagDescriptor : public ::android::hardware::camera2::params::VendorTagDescriptor,
+ public LightRefBase<VendorTagDescriptor> {
+ public:
+ /**
+ * Create a VendorTagDescriptor object from the given vendor_tag_ops_t
+ * struct.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ static status_t createDescriptorFromOps(const vendor_tag_ops_t* vOps,
+ /*out*/
+ sp<VendorTagDescriptor>& descriptor);
+
+ /**
+ * Sets the global vendor tag descriptor to use for this process.
+ * Camera metadata operations that access vendor tags will use the
+ * vendor tag definitions set this way.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ static status_t setAsGlobalVendorTagDescriptor(const sp<VendorTagDescriptor>& desc);
+
+ /**
+ * Returns the global vendor tag descriptor used by this process.
+ * This will contain NULL if no vendor tags are defined.
+ */
+ static sp<VendorTagDescriptor> getGlobalVendorTagDescriptor();
+
+ /**
+ * Clears the global vendor tag descriptor used by this process.
+ */
+ static void clearGlobalVendorTagDescriptor();
+};
+
+} /* namespace helper */
+} /* namespace common */
+} /* namespace camera */
+
+namespace camera2 {
+namespace params {
+
+class VendorTagDescriptorCache {
+ public:
+ typedef android::hardware::camera::common::helper::VendorTagDescriptor VendorTagDescriptor;
+ VendorTagDescriptorCache(){};
+ int32_t addVendorDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor> desc);
+
+ int32_t getVendorTagDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor>* desc /*out*/);
+
+ // Returns the number of vendor tags defined.
+ int getTagCount(metadata_vendor_id_t id) const;
+
+ // Returns an array containing the id's of vendor tags defined.
+ void getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const;
+
+ // Returns the section name string for a given vendor tag id.
+ const char* getSectionName(uint32_t tag, metadata_vendor_id_t id) const;
+
+ // Returns the tag name string for a given vendor tag id.
+ const char* getTagName(uint32_t tag, metadata_vendor_id_t id) const;
+
+ // Returns the tag type for a given vendor tag id.
+ int getTagType(uint32_t tag, metadata_vendor_id_t id) const;
+
+ /**
+ * Dump the currently configured vendor tags to a file descriptor.
+ */
+ void dump(int fd, int verbosity, int indentation) const;
+
+ protected:
+ std::unordered_map<metadata_vendor_id_t, sp<VendorTagDescriptor>> mVendorMap;
+ struct vendor_tag_cache_ops mVendorCacheOps;
+};
+
+} /* namespace params */
+} /* namespace camera2 */
+
+namespace camera {
+namespace common {
+namespace helper {
+
+class VendorTagDescriptorCache
+ : public ::android::hardware::camera2::params::VendorTagDescriptorCache,
+ public LightRefBase<VendorTagDescriptorCache> {
+ public:
+ /**
+ * Sets the global vendor tag descriptor cache to use for this process.
+ * Camera metadata operations that access vendor tags will use the
+ * vendor tag definitions set this way.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ static status_t setAsGlobalVendorTagCache(const sp<VendorTagDescriptorCache>& cache);
+
+ /**
+ * Returns the global vendor tag cache used by this process.
+ * This will contain NULL if no vendor tags are defined.
+ */
+ static sp<VendorTagDescriptorCache> getGlobalVendorTagCache();
+
+ /**
+ * Clears the global vendor tag cache used by this process.
+ */
+ static void clearGlobalVendorTagCache();
+};
+
+} // namespace helper
+
+// NOTE: Deprecated namespace. This namespace should no longer be used for the following symbols
+namespace V1_0::helper {
+// Export symbols to the old namespace to preserve compatibility
+typedef android::hardware::camera::common::helper::VendorTagDescriptor VendorTagDescriptor;
+typedef android::hardware::camera::common::helper::VendorTagDescriptorCache
+ VendorTagDescriptorCache;
+} // namespace V1_0::helper
+
+} // namespace common
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif /* CAMERA_COMMON_1_0_VENDORTAGDESCRIPTOR_H */
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 276e92a..3989161 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -346,15 +346,18 @@
* An override pixel format for the buffers in this stream.
*
* The HAL must respect the requested format in Stream unless it is
- * IMPLEMENTATION_DEFINED, in which case the override format here must be
- * used by the client instead, for this stream. This allows cross-platform
- * HALs to use a standard format since IMPLEMENTATION_DEFINED formats often
- * require device-specific information. In all other cases, the
+ * IMPLEMENTATION_DEFINED output, in which case the override format
+ * here must be used by the client instead, for this stream. This allows
+ * cross-platform HALs to use a standard format since IMPLEMENTATION_DEFINED
+ * formats often require device-specific information. In all other cases, the
* overrideFormat must match the requested format.
*
* When HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
* gralloc module must select a format based on the usage flags provided by
* the camera device and the other endpoint of the stream.
+ *
+ * For private reprocessing, the HAL must not override the input stream's
+ * IMPLEMENTATION_DEFINED format.
*/
[email protected]::PixelFormat overrideFormat;
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 461e89d..00d9da0 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -11,13 +11,13 @@
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",
"android.hardware.common.fmq-V1",
"android.hardware.camera.common-V1",
- "android.hardware.camera.metadata-V1",
+ "android.hardware.camera.metadata-V2",
"android.hardware.graphics.common-V4",
],
backend: {
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl
index 632499d..24083ad 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/CameraBlobId.aidl
@@ -34,6 +34,6 @@
package android.hardware.camera.device;
@Backing(type="int") @VintfStability
enum CameraBlobId {
- JPEG = 255,
- JPEG_APP_SEGMENTS = 256,
+ JPEG = 0x00FF,
+ JPEG_APP_SEGMENTS = 0x100,
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl
index b70b899..1f87aa3 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/RequestTemplate.aidl
@@ -40,5 +40,5 @@
VIDEO_SNAPSHOT = 4,
ZERO_SHUTTER_LAG = 5,
MANUAL = 6,
- VENDOR_TEMPLATE_START = 1073741824,
+ VENDOR_TEMPLATE_START = 0x40000000,
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl
index d2f295a..5057663 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/Stream.aidl
@@ -48,4 +48,5 @@
android.hardware.camera.metadata.SensorPixelMode[] sensorPixelModesUsed;
android.hardware.camera.metadata.RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile;
android.hardware.camera.metadata.ScalerAvailableStreamUseCases useCase;
+ int colorSpace;
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl
index f340578..97fd067 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfiguration.aidl
@@ -39,4 +39,5 @@
android.hardware.camera.device.CameraMetadata sessionParams;
int streamConfigCounter;
boolean multiResolutionInputImage;
+ long logId = 0;
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl
index bdef412..ef7ec25 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/StreamConfigurationMode.aidl
@@ -36,12 +36,12 @@
enum StreamConfigurationMode {
NORMAL_MODE = 0,
CONSTRAINED_HIGH_SPEED_MODE = 1,
- VENDOR_MODE_0 = 32768,
- VENDOR_MODE_1 = 32769,
- VENDOR_MODE_2 = 32770,
- VENDOR_MODE_3 = 32771,
- VENDOR_MODE_4 = 32772,
- VENDOR_MODE_5 = 32773,
- VENDOR_MODE_6 = 32774,
- VENDOR_MODE_7 = 32775,
+ VENDOR_MODE_0 = 0x8000,
+ VENDOR_MODE_1,
+ VENDOR_MODE_2,
+ VENDOR_MODE_3,
+ VENDOR_MODE_4,
+ VENDOR_MODE_5,
+ VENDOR_MODE_6,
+ VENDOR_MODE_7,
}
diff --git a/camera/device/aidl/android/hardware/camera/device/HalStream.aidl b/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
index b8ec3de..25a80bc 100644
--- a/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/HalStream.aidl
@@ -38,7 +38,7 @@
* An override pixel format for the buffers in this stream.
*
* The HAL must respect the requested format in Stream unless it is
- * IMPLEMENTATION_DEFINED, in which case the override format here must be
+ * IMPLEMENTATION_DEFINED output, in which case the override format here must be
* used by the client instead, for this stream. This allows cross-platform
* HALs to use a standard format since IMPLEMENTATION_DEFINED formats often
* require device-specific information. In all other cases, the
@@ -47,6 +47,9 @@
* When HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform
* gralloc module must select a format based on the usage flags provided by
* the camera device and the other endpoint of the stream.
+ *
+ * For private reprocessing, the HAL must not override the input stream's
+ * IMPLEMENTATION_DEFINED format.
*/
android.hardware.graphics.common.PixelFormat overrideFormat;
diff --git a/camera/device/aidl/android/hardware/camera/device/Stream.aidl b/camera/device/aidl/android/hardware/camera/device/Stream.aidl
index e35e4ff..0a657d7 100644
--- a/camera/device/aidl/android/hardware/camera/device/Stream.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/Stream.aidl
@@ -98,14 +98,19 @@
*
* For most formats, dataSpace defines the color space of the image data.
* In addition, for some formats, dataSpace indicates whether image- or
- * depth-based data is requested. See
- * [email protected]::types for details of formats and
- * valid dataSpace values for each format.
+ * depth-based data is requested. For others, it merely describes an encoding
+ * scheme. See [email protected]::types for details of formats
+ * and valid dataSpace values for each format.
*
* The HAL must use this dataSpace to configure the stream to the correct
* colorspace, or to select between color and depth outputs if
* supported. The dataspace values are set using the V0 dataspace
* definitions.
+ *
+ * The standard bits of this field will match the requested colorSpace (if set) for
+ * non-BLOB formats. For BLOB formats, if colorSpace is not
+ * ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED, colorSpace takes
+ * over as the authority for the color space of the stream regardless of dataSpace.
*/
android.hardware.graphics.common.Dataspace dataSpace;
@@ -222,4 +227,19 @@
* DEFAULT.
*/
android.hardware.camera.metadata.ScalerAvailableStreamUseCases useCase;
+
+ /**
+ * The color space of the stream.
+ *
+ * A client may not specify a color space. In this case, the value will be
+ * ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED, and the color space
+ * implied by dataSpace should be used instead.
+ *
+ * When specified, this field and the standard bits of dataSpace will match for non-BLOB
+ * formats. For BLOB formats, the dataSpace will remain unchanged. In this case, this field is
+ * the ultimate authority over the color space of the stream.
+ *
+ * See ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP for possible values.
+ */
+ int colorSpace;
}
diff --git a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
index cacd32c..197d9af 100644
--- a/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/StreamConfiguration.aidl
@@ -62,7 +62,7 @@
*/
CameraMetadata sessionParams;
- /**
+ /**
* An incrementing counter used for HAL to keep track of the stream
* configuration and the paired oneway signalStreamFlush call. When the
* counter in signalStreamFlush call is less than the counter here, that
@@ -83,4 +83,13 @@
* any one of the supported multi-resolution input stream sizes.
*/
boolean multiResolutionInputImage;
+
+ /**
+ * Logging identifier to join HAL logs to logs collected by cameraservice. This field has no
+ * functional purpose.
+ *
+ * See documentation of 'mLogId' in frameworks/av/camera/include/camera/CameraSessionStats.h
+ * for specifics of this identifier and how it can be used to join with cameraservice logs.
+ */
+ long logId = 0;
}
diff --git a/camera/device/default/Android.bp b/camera/device/default/Android.bp
new file mode 100644
index 0000000..b577597
--- /dev/null
+++ b/camera/device/default/Android.bp
@@ -0,0 +1,71 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_shared {
+ name: "camera.device-external-impl",
+ defaults: ["hidl_defaults"],
+ proprietary: true,
+ srcs: [
+ "ExternalCameraDevice.cpp",
+ "ExternalCameraDeviceSession.cpp",
+ "ExternalCameraOfflineSession.cpp",
+ "ExternalCameraUtils.cpp",
+ "convert.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.camera.common-V1-ndk",
+ "android.hardware.camera.device-V1-ndk",
+ "android.hardware.graphics.allocator-V1-ndk",
+ "android.hardware.graphics.common-V4-ndk",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "libbinder_ndk",
+ "libcamera_metadata",
+ "libcutils",
+ "libexif",
+ "libfmq",
+ "libgralloctypes",
+ "libhardware",
+ "libhidlbase",
+ "libhidlmemory",
+ "libjpeg",
+ "liblog",
+ "libsync",
+ "libtinyxml2",
+ "libutils",
+ "libyuv",
+ ],
+ static_libs: [
+ "[email protected]",
+ "libaidlcommonsupport",
+ ],
+ header_libs: [
+ "media_plugin_headers",
+ ],
+ export_include_dirs: ["."],
+}
diff --git a/camera/device/default/ExternalCameraDevice.cpp b/camera/device/default/ExternalCameraDevice.cpp
new file mode 100644
index 0000000..677fb42
--- /dev/null
+++ b/camera/device/default/ExternalCameraDevice.cpp
@@ -0,0 +1,1001 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamDev"
+// #define LOG_NDEBUG 0
+#include <log/log.h>
+
+#include "ExternalCameraDevice.h"
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <convert.h>
+#include <linux/videodev2.h>
+#include <regex>
+#include <set>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+
+namespace {
+// Only support MJPEG for now as it seems to be the one supports higher fps
+// Other formats to consider in the future:
+// * V4L2_PIX_FMT_YVU420 (== YV12)
+// * V4L2_PIX_FMT_YVYU (YVYU: can be converted to YV12 or other YUV420_888 formats)
+const std::array<uint32_t, /*size*/ 2> kSupportedFourCCs{
+ {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_Z16}}; // double braces required in C++11
+
+constexpr int MAX_RETRY = 5; // Allow retry v4l2 open failures a few times.
+constexpr int OPEN_RETRY_SLEEP_US = 100'000; // 100ms * MAX_RETRY = 0.5 seconds
+
+const std::regex kDevicePathRE("/dev/video([0-9]+)");
+} // namespace
+
+std::string ExternalCameraDevice::kDeviceVersion = "1.1";
+
+ExternalCameraDevice::ExternalCameraDevice(const std::string& devicePath,
+ const ExternalCameraConfig& config)
+ : mCameraId("-1"), mDevicePath(devicePath), mCfg(config) {
+ std::smatch sm;
+ if (std::regex_match(mDevicePath, sm, kDevicePathRE)) {
+ mCameraId = std::to_string(mCfg.cameraIdOffset + std::stoi(sm[1]));
+ } else {
+ ALOGE("%s: device path match failed for %s", __FUNCTION__, mDevicePath.c_str());
+ }
+}
+
+ExternalCameraDevice::~ExternalCameraDevice() {}
+
+ndk::ScopedAStatus ExternalCameraDevice::getCameraCharacteristics(CameraMetadata* _aidl_return) {
+ Mutex::Autolock _l(mLock);
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+
+ if (isInitFailedLocked()) {
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ const camera_metadata_t* rawMetadata = mCameraCharacteristics.getAndLock();
+ convertToAidl(rawMetadata, _aidl_return);
+ mCameraCharacteristics.unlock(rawMetadata);
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::getPhysicalCameraCharacteristics(const std::string&,
+ CameraMetadata*) {
+ ALOGE("%s: Physical camera functions are not supported for external cameras.", __FUNCTION__);
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::getResourceCost(CameraResourceCost* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+
+ _aidl_return->resourceCost = 100;
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::isStreamCombinationSupported(
+ const StreamConfiguration& in_streams, bool* _aidl_return) {
+ if (isInitFailed()) {
+ ALOGE("%s: camera %s. camera init failed!", __FUNCTION__, mCameraId.c_str());
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+ Status s = ExternalCameraDeviceSession::isStreamCombinationSupported(in_streams,
+ mSupportedFormats, mCfg);
+ *_aidl_return = s == Status::OK;
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::open(
+ const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+ std::shared_ptr<ICameraDeviceSession>* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ ALOGE("%s: cannot open camera %s. return session ptr is null!", __FUNCTION__,
+ mCameraId.c_str());
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+
+ Mutex::Autolock _l(mLock);
+ if (isInitFailedLocked()) {
+ ALOGE("%s: cannot open camera %s. camera init failed!", __FUNCTION__, mCameraId.c_str());
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ std::shared_ptr<ExternalCameraDeviceSession> session;
+ ALOGV("%s: Initializing device for camera %s", __FUNCTION__, mCameraId.c_str());
+ session = mSession.lock();
+
+ if (session != nullptr && !session->isClosed()) {
+ ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
+ return fromStatus(Status::CAMERA_IN_USE);
+ }
+
+ int numAttempt = 0;
+ unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
+ while (fd.get() < 0 && numAttempt < MAX_RETRY) {
+ // Previous retry attempts failed. Retry opening the device at most MAX_RETRY times
+ ALOGW("%s: v4l2 device %s open failed, wait 33ms and try again", __FUNCTION__,
+ mDevicePath.c_str());
+ usleep(OPEN_RETRY_SLEEP_US); // sleep and try again
+ fd.reset(::open(mDevicePath.c_str(), O_RDWR));
+ numAttempt++;
+ }
+
+ if (fd.get() < 0) {
+ ALOGE("%s: v4l2 device open %s failed: %s", __FUNCTION__, mDevicePath.c_str(),
+ strerror(errno));
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ session = createSession(in_callback, mCfg, mSupportedFormats, mCroppingType,
+ mCameraCharacteristics, mCameraId, std::move(fd));
+ if (session == nullptr) {
+ ALOGE("%s: camera device session allocation failed", __FUNCTION__);
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ if (session->isInitFailed()) {
+ ALOGE("%s: camera device session init failed", __FUNCTION__);
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ mSession = session;
+ *_aidl_return = session;
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::openInjectionSession(
+ const std::shared_ptr<ICameraDeviceCallback>&, std::shared_ptr<ICameraInjectionSession>*) {
+ return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::setTorchMode(bool) {
+ return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::turnOnTorchWithStrengthLevel(int32_t) {
+ return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+ndk::ScopedAStatus ExternalCameraDevice::getTorchStrengthLevel(int32_t*) {
+ return fromStatus(Status::OPERATION_NOT_SUPPORTED);
+}
+
+std::shared_ptr<ExternalCameraDeviceSession> ExternalCameraDevice::createSession(
+ const std::shared_ptr<ICameraDeviceCallback>& cb, const ExternalCameraConfig& cfg,
+ const std::vector<SupportedV4L2Format>& sortedFormats, const CroppingType& croppingType,
+ const common::V1_0::helper::CameraMetadata& chars, const std::string& cameraId,
+ unique_fd v4l2Fd) {
+ return ndk::SharedRefBase::make<ExternalCameraDeviceSession>(
+ cb, cfg, sortedFormats, croppingType, chars, cameraId, std::move(v4l2Fd));
+}
+
+bool ExternalCameraDevice::isInitFailed() {
+ Mutex::Autolock _l(mLock);
+ return isInitFailedLocked();
+}
+
+bool ExternalCameraDevice::isInitFailedLocked() {
+ if (!mInitialized) {
+ status_t ret = initCameraCharacteristics();
+ if (ret != OK) {
+ ALOGE("%s: init camera characteristics failed: errorno %d", __FUNCTION__, ret);
+ mInitFailed = true;
+ }
+ mInitialized = true;
+ }
+ return mInitFailed;
+}
+
+void ExternalCameraDevice::initSupportedFormatsLocked(int fd) {
+ std::vector<SupportedV4L2Format> horizontalFmts =
+ getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits, mCfg.depthFpsLimits,
+ mCfg.minStreamSize, mCfg.depthEnabled);
+ std::vector<SupportedV4L2Format> verticalFmts =
+ getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits, mCfg.depthFpsLimits,
+ mCfg.minStreamSize, mCfg.depthEnabled);
+
+ size_t horiSize = horizontalFmts.size();
+ size_t vertSize = verticalFmts.size();
+
+ if (horiSize == 0 && vertSize == 0) {
+ ALOGE("%s: cannot find suitable cropping type!", __FUNCTION__);
+ return;
+ }
+
+ if (horiSize == 0) {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ return;
+ } else if (vertSize == 0) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ return;
+ }
+
+ const auto& maxHoriSize = horizontalFmts[horizontalFmts.size() - 1];
+ const auto& maxVertSize = verticalFmts[verticalFmts.size() - 1];
+
+ // Try to keep the largest possible output size
+ // When they are the same or ambiguous, pick the one support more sizes
+ if (maxHoriSize.width == maxVertSize.width && maxHoriSize.height == maxVertSize.height) {
+ if (horiSize > vertSize) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ } else {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ }
+ } else if (maxHoriSize.width >= maxVertSize.width && maxHoriSize.height >= maxVertSize.height) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ } else if (maxHoriSize.width <= maxVertSize.width && maxHoriSize.height <= maxVertSize.height) {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ } else {
+ if (horiSize > vertSize) {
+ mSupportedFormats = horizontalFmts;
+ mCroppingType = HORIZONTAL;
+ } else {
+ mSupportedFormats = verticalFmts;
+ mCroppingType = VERTICAL;
+ }
+ }
+}
+
+status_t ExternalCameraDevice::initCameraCharacteristics() {
+ if (!mCameraCharacteristics.isEmpty()) {
+ // Camera Characteristics previously initialized. Skip.
+ return OK;
+ }
+
+ // init camera characteristics
+ unique_fd fd(::open(mDevicePath.c_str(), O_RDWR));
+ if (fd.get() < 0) {
+ ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mDevicePath.c_str());
+ return DEAD_OBJECT;
+ }
+
+ status_t ret;
+ ret = initDefaultCharsKeys(&mCameraCharacteristics);
+ if (ret != OK) {
+ ALOGE("%s: init default characteristics key failed: errorno %d", __FUNCTION__, ret);
+ mCameraCharacteristics.clear();
+ return ret;
+ }
+
+ ret = initCameraControlsCharsKeys(fd.get(), &mCameraCharacteristics);
+ if (ret != OK) {
+ ALOGE("%s: init camera control characteristics key failed: errorno %d", __FUNCTION__, ret);
+ mCameraCharacteristics.clear();
+ return ret;
+ }
+
+ ret = initOutputCharsKeys(fd.get(), &mCameraCharacteristics);
+ if (ret != OK) {
+ ALOGE("%s: init output characteristics key failed: errorno %d", __FUNCTION__, ret);
+ mCameraCharacteristics.clear();
+ return ret;
+ }
+
+ ret = initAvailableCapabilities(&mCameraCharacteristics);
+ if (ret != OK) {
+ ALOGE("%s: init available capabilities key failed: errorno %d", __FUNCTION__, ret);
+ mCameraCharacteristics.clear();
+ return ret;
+ }
+
+ return OK;
+}
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define UPDATE(tag, data, size) \
+ do { \
+ if (metadata->update((tag), (data), (size))) { \
+ ALOGE("Update " #tag " failed!"); \
+ return -EINVAL; \
+ } \
+ } while (0)
+
+status_t ExternalCameraDevice::initAvailableCapabilities(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+ if (mSupportedFormats.empty()) {
+ ALOGE("%s: Supported formats list is empty", __FUNCTION__);
+ return UNKNOWN_ERROR;
+ }
+
+ bool hasDepth = false;
+ bool hasColor = false;
+ for (const auto& fmt : mSupportedFormats) {
+ switch (fmt.fourcc) {
+ case V4L2_PIX_FMT_Z16:
+ hasDepth = true;
+ break;
+ case V4L2_PIX_FMT_MJPEG:
+ hasColor = true;
+ break;
+ default:
+ ALOGW("%s: Unsupported format found", __FUNCTION__);
+ }
+ }
+
+ std::vector<uint8_t> availableCapabilities;
+ if (hasDepth) {
+ availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
+ }
+ if (hasColor) {
+ availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+ }
+ if (!availableCapabilities.empty()) {
+ UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities.data(),
+ availableCapabilities.size());
+ }
+
+ return OK;
+}
+
+status_t ExternalCameraDevice::initDefaultCharsKeys(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+ const uint8_t hardware_level = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL;
+ UPDATE(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &hardware_level, 1);
+
+ // android.colorCorrection
+ const uint8_t availableAberrationModes[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF};
+ UPDATE(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, availableAberrationModes,
+ ARRAY_SIZE(availableAberrationModes));
+
+ // android.control
+ const uint8_t antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
+ UPDATE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, &antibandingMode, 1);
+
+ const int32_t controlMaxRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0};
+ UPDATE(ANDROID_CONTROL_MAX_REGIONS, controlMaxRegions, ARRAY_SIZE(controlMaxRegions));
+
+ const uint8_t videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+ UPDATE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, &videoStabilizationMode, 1);
+
+ const uint8_t awbAvailableMode = ANDROID_CONTROL_AWB_MODE_AUTO;
+ UPDATE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, &awbAvailableMode, 1);
+
+ const uint8_t aeAvailableMode = ANDROID_CONTROL_AE_MODE_ON;
+ UPDATE(ANDROID_CONTROL_AE_AVAILABLE_MODES, &aeAvailableMode, 1);
+
+ const uint8_t availableFffect = ANDROID_CONTROL_EFFECT_MODE_OFF;
+ UPDATE(ANDROID_CONTROL_AVAILABLE_EFFECTS, &availableFffect, 1);
+
+ const uint8_t controlAvailableModes[] = {ANDROID_CONTROL_MODE_OFF, ANDROID_CONTROL_MODE_AUTO};
+ UPDATE(ANDROID_CONTROL_AVAILABLE_MODES, controlAvailableModes,
+ ARRAY_SIZE(controlAvailableModes));
+
+ // android.edge
+ const uint8_t edgeMode = ANDROID_EDGE_MODE_OFF;
+ UPDATE(ANDROID_EDGE_AVAILABLE_EDGE_MODES, &edgeMode, 1);
+
+ // android.flash
+ const uint8_t flashInfo = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
+ UPDATE(ANDROID_FLASH_INFO_AVAILABLE, &flashInfo, 1);
+
+ // android.hotPixel
+ const uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_OFF;
+ UPDATE(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, &hotPixelMode, 1);
+
+ // android.jpeg
+ const int32_t jpegAvailableThumbnailSizes[] = {0, 0, 176, 144, 240, 144, 256,
+ 144, 240, 160, 256, 154, 240, 180};
+ UPDATE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegAvailableThumbnailSizes,
+ ARRAY_SIZE(jpegAvailableThumbnailSizes));
+
+ const int32_t jpegMaxSize = mCfg.maxJpegBufSize;
+ UPDATE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1);
+
+ // android.lens
+ const uint8_t focusDistanceCalibration =
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED;
+ UPDATE(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION, &focusDistanceCalibration, 1);
+
+ const uint8_t opticalStabilizationMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+ UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, &opticalStabilizationMode, 1);
+
+ const uint8_t facing = ANDROID_LENS_FACING_EXTERNAL;
+ UPDATE(ANDROID_LENS_FACING, &facing, 1);
+
+ // android.noiseReduction
+ const uint8_t noiseReductionMode = ANDROID_NOISE_REDUCTION_MODE_OFF;
+ UPDATE(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, &noiseReductionMode, 1);
+ UPDATE(ANDROID_NOISE_REDUCTION_MODE, &noiseReductionMode, 1);
+
+ const int32_t partialResultCount = 1;
+ UPDATE(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount, 1);
+
+ // This means pipeline latency of X frame intervals. The maximum number is 4.
+ const uint8_t requestPipelineMaxDepth = 4;
+ UPDATE(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &requestPipelineMaxDepth, 1);
+
+ // Three numbers represent the maximum numbers of different types of output
+ // streams simultaneously. The types are raw sensor, processed (but not
+ // stalling), and processed (but stalling). For usb limited mode, raw sensor
+ // is not supported. Stalling stream is JPEG. Non-stalling streams are
+ // YUV_420_888 or YV12.
+ const int32_t requestMaxNumOutputStreams[] = {
+ /*RAW*/ 0,
+ /*Processed*/ ExternalCameraDeviceSession::kMaxProcessedStream,
+ /*Stall*/ ExternalCameraDeviceSession::kMaxStallStream};
+ UPDATE(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, requestMaxNumOutputStreams,
+ ARRAY_SIZE(requestMaxNumOutputStreams));
+
+ // Limited mode doesn't support reprocessing.
+ const int32_t requestMaxNumInputStreams = 0;
+ UPDATE(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &requestMaxNumInputStreams, 1);
+
+ // android.scaler
+ // TODO: b/72263447 V4L2_CID_ZOOM_*
+ const float scalerAvailableMaxDigitalZoom[] = {1};
+ UPDATE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, scalerAvailableMaxDigitalZoom,
+ ARRAY_SIZE(scalerAvailableMaxDigitalZoom));
+
+ const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
+ UPDATE(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
+
+ const int32_t testPatternModes[] = {ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR};
+ UPDATE(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, testPatternModes,
+ ARRAY_SIZE(testPatternModes));
+
+ const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
+ UPDATE(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1);
+
+ // Orientation is a bit odd for external camera, but consider it as the orientation
+ // between the external camera sensor (which is usually landscape) and the device's
+ // natural display orientation. For devices with natural landscape display (ex: tablet/TV), the
+ // orientation should be 0. For devices with natural portrait display (phone), the orientation
+ // should be 270.
+ const int32_t orientation = mCfg.orientation;
+ UPDATE(ANDROID_SENSOR_ORIENTATION, &orientation, 1);
+
+ // android.shading
+ const uint8_t availableMode = ANDROID_SHADING_MODE_OFF;
+ UPDATE(ANDROID_SHADING_AVAILABLE_MODES, &availableMode, 1);
+
+ // android.statistics
+ const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+ UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, &faceDetectMode, 1);
+
+ const int32_t maxFaceCount = 0;
+ UPDATE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1);
+
+ const uint8_t availableHotpixelMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
+ UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, &availableHotpixelMode, 1);
+
+ const uint8_t lensShadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+ UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, &lensShadingMapMode, 1);
+
+ // android.sync
+ const int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
+ UPDATE(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
+
+ /* Other sensor/RAW related keys:
+ * android.sensor.info.colorFilterArrangement -> no need if we don't do RAW
+ * android.sensor.info.physicalSize -> not available
+ * android.sensor.info.whiteLevel -> not available/not needed
+ * android.sensor.info.lensShadingApplied -> not needed
+ * android.sensor.info.preCorrectionActiveArraySize -> not available/not needed
+ * android.sensor.blackLevelPattern -> not available/not needed
+ */
+
+ const int32_t availableRequestKeys[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+ ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+ ANDROID_CONTROL_AE_LOCK,
+ ANDROID_CONTROL_AE_MODE,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+ ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+ ANDROID_CONTROL_AF_MODE,
+ ANDROID_CONTROL_AF_TRIGGER,
+ ANDROID_CONTROL_AWB_LOCK,
+ ANDROID_CONTROL_AWB_MODE,
+ ANDROID_CONTROL_CAPTURE_INTENT,
+ ANDROID_CONTROL_EFFECT_MODE,
+ ANDROID_CONTROL_MODE,
+ ANDROID_CONTROL_SCENE_MODE,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+ ANDROID_FLASH_MODE,
+ ANDROID_JPEG_ORIENTATION,
+ ANDROID_JPEG_QUALITY,
+ ANDROID_JPEG_THUMBNAIL_QUALITY,
+ ANDROID_JPEG_THUMBNAIL_SIZE,
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+ ANDROID_NOISE_REDUCTION_MODE,
+ ANDROID_SCALER_CROP_REGION,
+ ANDROID_SENSOR_TEST_PATTERN_MODE,
+ ANDROID_STATISTICS_FACE_DETECT_MODE,
+ ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE};
+ UPDATE(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, availableRequestKeys,
+ ARRAY_SIZE(availableRequestKeys));
+
+ const int32_t availableResultKeys[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+ ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+ ANDROID_CONTROL_AE_LOCK,
+ ANDROID_CONTROL_AE_MODE,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+ ANDROID_CONTROL_AE_STATE,
+ ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+ ANDROID_CONTROL_AF_MODE,
+ ANDROID_CONTROL_AF_STATE,
+ ANDROID_CONTROL_AF_TRIGGER,
+ ANDROID_CONTROL_AWB_LOCK,
+ ANDROID_CONTROL_AWB_MODE,
+ ANDROID_CONTROL_AWB_STATE,
+ ANDROID_CONTROL_CAPTURE_INTENT,
+ ANDROID_CONTROL_EFFECT_MODE,
+ ANDROID_CONTROL_MODE,
+ ANDROID_CONTROL_SCENE_MODE,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+ ANDROID_FLASH_MODE,
+ ANDROID_FLASH_STATE,
+ ANDROID_JPEG_ORIENTATION,
+ ANDROID_JPEG_QUALITY,
+ ANDROID_JPEG_THUMBNAIL_QUALITY,
+ ANDROID_JPEG_THUMBNAIL_SIZE,
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+ ANDROID_NOISE_REDUCTION_MODE,
+ ANDROID_REQUEST_PIPELINE_DEPTH,
+ ANDROID_SCALER_CROP_REGION,
+ ANDROID_SENSOR_TIMESTAMP,
+ ANDROID_STATISTICS_FACE_DETECT_MODE,
+ ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+ ANDROID_STATISTICS_SCENE_FLICKER};
+ UPDATE(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, availableResultKeys,
+ ARRAY_SIZE(availableResultKeys));
+
+ UPDATE(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, AVAILABLE_CHARACTERISTICS_KEYS.data(),
+ AVAILABLE_CHARACTERISTICS_KEYS.size());
+
+ return OK;
+}
+
+status_t ExternalCameraDevice::initCameraControlsCharsKeys(
+ int, ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+ // android.sensor.info.sensitivityRange -> V4L2_CID_ISO_SENSITIVITY
+ // android.sensor.info.exposureTimeRange -> V4L2_CID_EXPOSURE_ABSOLUTE
+ // android.sensor.info.maxFrameDuration -> TBD
+ // android.lens.info.minimumFocusDistance -> V4L2_CID_FOCUS_ABSOLUTE
+ // android.lens.info.hyperfocalDistance
+ // android.lens.info.availableFocalLengths -> not available?
+
+ // android.control
+ // No AE compensation support for now.
+ // TODO: V4L2_CID_EXPOSURE_BIAS
+ const int32_t controlAeCompensationRange[] = {0, 0};
+ UPDATE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, controlAeCompensationRange,
+ ARRAY_SIZE(controlAeCompensationRange));
+ const camera_metadata_rational_t controlAeCompensationStep[] = {{0, 1}};
+ UPDATE(ANDROID_CONTROL_AE_COMPENSATION_STEP, controlAeCompensationStep,
+ ARRAY_SIZE(controlAeCompensationStep));
+
+ // TODO: Check V4L2_CID_AUTO_FOCUS_*.
+ const uint8_t afAvailableModes[] = {ANDROID_CONTROL_AF_MODE_AUTO, ANDROID_CONTROL_AF_MODE_OFF};
+ UPDATE(ANDROID_CONTROL_AF_AVAILABLE_MODES, afAvailableModes, ARRAY_SIZE(afAvailableModes));
+
+ // TODO: V4L2_CID_SCENE_MODE
+ const uint8_t availableSceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
+ UPDATE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, &availableSceneMode, 1);
+
+ // TODO: V4L2_CID_3A_LOCK
+ const uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
+ UPDATE(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailable, 1);
+ const uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
+ UPDATE(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &awbLockAvailable, 1);
+
+ // TODO: V4L2_CID_ZOOM_*
+ const float scalerAvailableMaxDigitalZoom[] = {1};
+ UPDATE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, scalerAvailableMaxDigitalZoom,
+ ARRAY_SIZE(scalerAvailableMaxDigitalZoom));
+
+ return OK;
+}
+
+status_t ExternalCameraDevice::initOutputCharsKeys(
+ int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+ initSupportedFormatsLocked(fd);
+ if (mSupportedFormats.empty()) {
+ ALOGE("%s: Init supported format list failed", __FUNCTION__);
+ return UNKNOWN_ERROR;
+ }
+
+ bool hasDepth = false;
+ bool hasColor = false;
+
+ // For V4L2_PIX_FMT_Z16
+ std::array<int, /*size*/ 1> halDepthFormats{{HAL_PIXEL_FORMAT_Y16}};
+ // For V4L2_PIX_FMT_MJPEG
+ std::array<int, /*size*/ 3> halFormats{{HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_YCbCr_420_888,
+ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}};
+
+ for (const auto& supportedFormat : mSupportedFormats) {
+ switch (supportedFormat.fourcc) {
+ case V4L2_PIX_FMT_Z16:
+ hasDepth = true;
+ break;
+ case V4L2_PIX_FMT_MJPEG:
+ hasColor = true;
+ break;
+ default:
+ ALOGW("%s: format %c%c%c%c is not supported!", __FUNCTION__,
+ supportedFormat.fourcc & 0xFF, (supportedFormat.fourcc >> 8) & 0xFF,
+ (supportedFormat.fourcc >> 16) & 0xFF, (supportedFormat.fourcc >> 24) & 0xFF);
+ }
+ }
+
+ if (hasDepth) {
+ status_t ret = initOutputCharsKeysByFormat(
+ metadata, V4L2_PIX_FMT_Z16, halDepthFormats,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
+ if (ret != OK) {
+ ALOGE("%s: Unable to initialize depth format keys: %s", __FUNCTION__,
+ statusToString(ret).c_str());
+ return ret;
+ }
+ }
+ if (hasColor) {
+ status_t ret =
+ initOutputCharsKeysByFormat(metadata, V4L2_PIX_FMT_MJPEG, halFormats,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+ ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+ ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
+ if (ret != OK) {
+ ALOGE("%s: Unable to initialize color format keys: %s", __FUNCTION__,
+ statusToString(ret).c_str());
+ return ret;
+ }
+ }
+
+ status_t ret = calculateMinFps(metadata);
+ if (ret != OK) {
+ ALOGE("%s: Unable to update fps metadata: %s", __FUNCTION__, statusToString(ret).c_str());
+ return ret;
+ }
+
+ SupportedV4L2Format maximumFormat{.width = 0, .height = 0};
+ for (const auto& supportedFormat : mSupportedFormats) {
+ if (supportedFormat.width >= maximumFormat.width &&
+ supportedFormat.height >= maximumFormat.height) {
+ maximumFormat = supportedFormat;
+ }
+ }
+ int32_t activeArraySize[] = {0, 0, static_cast<int32_t>(maximumFormat.width),
+ static_cast<int32_t>(maximumFormat.height)};
+ UPDATE(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, activeArraySize,
+ ARRAY_SIZE(activeArraySize));
+ UPDATE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArraySize, ARRAY_SIZE(activeArraySize));
+
+ int32_t pixelArraySize[] = {static_cast<int32_t>(maximumFormat.width),
+ static_cast<int32_t>(maximumFormat.height)};
+ UPDATE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize, ARRAY_SIZE(pixelArraySize));
+ return OK;
+}
+
+template <size_t SIZE>
+status_t ExternalCameraDevice::initOutputCharsKeysByFormat(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata,
+ uint32_t fourcc, const std::array<int, SIZE>& halFormats, int streamConfigTag,
+ int streamConfigurationKey, int minFrameDurationKey, int stallDurationKey) {
+ if (mSupportedFormats.empty()) {
+ ALOGE("%s: Init supported format list failed", __FUNCTION__);
+ return UNKNOWN_ERROR;
+ }
+
+ std::vector<int32_t> streamConfigurations;
+ std::vector<int64_t> minFrameDurations;
+ std::vector<int64_t> stallDurations;
+
+ for (const auto& supportedFormat : mSupportedFormats) {
+ if (supportedFormat.fourcc != fourcc) {
+ // Skip 4CCs not meant for the halFormats
+ continue;
+ }
+ for (const auto& format : halFormats) {
+ streamConfigurations.push_back(format);
+ streamConfigurations.push_back(supportedFormat.width);
+ streamConfigurations.push_back(supportedFormat.height);
+ streamConfigurations.push_back(streamConfigTag);
+ }
+
+ int64_t minFrameDuration = std::numeric_limits<int64_t>::max();
+ for (const auto& fr : supportedFormat.frameRates) {
+ // 1000000000LL < (2^32 - 1) and
+ // fr.durationNumerator is uint32_t, so no overflow here
+ int64_t frameDuration = 1000000000LL * fr.durationNumerator / fr.durationDenominator;
+ if (frameDuration < minFrameDuration) {
+ minFrameDuration = frameDuration;
+ }
+ }
+
+ for (const auto& format : halFormats) {
+ minFrameDurations.push_back(format);
+ minFrameDurations.push_back(supportedFormat.width);
+ minFrameDurations.push_back(supportedFormat.height);
+ minFrameDurations.push_back(minFrameDuration);
+ }
+
+ // The stall duration is 0 for non-jpeg formats. For JPEG format, stall
+ // duration can be 0 if JPEG is small. Here we choose 1 sec for JPEG.
+ // TODO: b/72261675. Maybe set this dynamically
+ for (const auto& format : halFormats) {
+ const int64_t NS_TO_SECOND = 1E9;
+ int64_t stall_duration = (format == HAL_PIXEL_FORMAT_BLOB) ? NS_TO_SECOND : 0;
+ stallDurations.push_back(format);
+ stallDurations.push_back(supportedFormat.width);
+ stallDurations.push_back(supportedFormat.height);
+ stallDurations.push_back(stall_duration);
+ }
+ }
+
+ UPDATE(streamConfigurationKey, streamConfigurations.data(), streamConfigurations.size());
+
+ UPDATE(minFrameDurationKey, minFrameDurations.data(), minFrameDurations.size());
+
+ UPDATE(stallDurationKey, stallDurations.data(), stallDurations.size());
+
+ return OK;
+}
+
+status_t ExternalCameraDevice::calculateMinFps(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) {
+ std::set<int32_t> framerates;
+ int32_t minFps = std::numeric_limits<int32_t>::max();
+
+ for (const auto& supportedFormat : mSupportedFormats) {
+ for (const auto& fr : supportedFormat.frameRates) {
+ int32_t frameRateInt = static_cast<int32_t>(fr.getFramesPerSecond());
+ if (minFps > frameRateInt) {
+ minFps = frameRateInt;
+ }
+ framerates.insert(frameRateInt);
+ }
+ }
+
+ std::vector<int32_t> fpsRanges;
+ // FPS ranges
+ for (const auto& framerate : framerates) {
+ // Empirical: webcams often have close to 2x fps error and cannot support fixed fps range
+ fpsRanges.push_back(framerate / 2);
+ fpsRanges.push_back(framerate);
+ }
+ minFps /= 2;
+ int64_t maxFrameDuration = 1000000000LL / minFps;
+
+ UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(), fpsRanges.size());
+
+ UPDATE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &maxFrameDuration, 1);
+
+ return OK;
+}
+
+#undef ARRAY_SIZE
+#undef UPDATE
+
+void ExternalCameraDevice::getFrameRateList(int fd, double fpsUpperBound,
+ SupportedV4L2Format* format) {
+ format->frameRates.clear();
+
+ v4l2_frmivalenum frameInterval{
+ .index = 0,
+ .pixel_format = format->fourcc,
+ .width = static_cast<__u32>(format->width),
+ .height = static_cast<__u32>(format->height),
+ };
+
+ for (frameInterval.index = 0;
+ TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frameInterval)) == 0;
+ ++frameInterval.index) {
+ if (frameInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
+ if (frameInterval.discrete.numerator != 0) {
+ SupportedV4L2Format::FrameRate fr = {frameInterval.discrete.numerator,
+ frameInterval.discrete.denominator};
+ double framerate = fr.getFramesPerSecond();
+ if (framerate > fpsUpperBound) {
+ continue;
+ }
+ ALOGV("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f", frameInterval.index,
+ frameInterval.pixel_format & 0xFF, (frameInterval.pixel_format >> 8) & 0xFF,
+ (frameInterval.pixel_format >> 16) & 0xFF,
+ (frameInterval.pixel_format >> 24) & 0xFF, frameInterval.width,
+ frameInterval.height, framerate);
+ format->frameRates.push_back(fr);
+ }
+ }
+ }
+
+ if (format->frameRates.empty()) {
+ ALOGE("%s: failed to get supported frame rates for format:%c%c%c%c w %d h %d", __FUNCTION__,
+ frameInterval.pixel_format & 0xFF, (frameInterval.pixel_format >> 8) & 0xFF,
+ (frameInterval.pixel_format >> 16) & 0xFF, (frameInterval.pixel_format >> 24) & 0xFF,
+ frameInterval.width, frameInterval.height);
+ }
+}
+
+void ExternalCameraDevice::updateFpsBounds(
+ int fd, CroppingType cropType,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+ SupportedV4L2Format format, std::vector<SupportedV4L2Format>& outFmts) {
+ double fpsUpperBound = -1.0;
+ for (const auto& limit : fpsLimits) {
+ if (cropType == VERTICAL) {
+ if (format.width <= limit.size.width) {
+ fpsUpperBound = limit.fpsUpperBound;
+ break;
+ }
+ } else { // HORIZONTAL
+ if (format.height <= limit.size.height) {
+ fpsUpperBound = limit.fpsUpperBound;
+ break;
+ }
+ }
+ }
+ if (fpsUpperBound < 0.f) {
+ return;
+ }
+
+ getFrameRateList(fd, fpsUpperBound, &format);
+ if (!format.frameRates.empty()) {
+ outFmts.push_back(format);
+ }
+}
+
+std::vector<SupportedV4L2Format> ExternalCameraDevice::getCandidateSupportedFormatsLocked(
+ int fd, CroppingType cropType,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& depthFpsLimits,
+ const Size& minStreamSize, bool depthEnabled) {
+ std::vector<SupportedV4L2Format> outFmts;
+ struct v4l2_fmtdesc fmtdesc {
+ .index = 0, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE
+ };
+ int ret = 0;
+ while (ret == 0) {
+ ret = TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc));
+ ALOGV("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret, fmtdesc.pixelformat & 0xFF,
+ (fmtdesc.pixelformat >> 8) & 0xFF, (fmtdesc.pixelformat >> 16) & 0xFF,
+ (fmtdesc.pixelformat >> 24) & 0xFF);
+
+ if (ret != 0 || (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED)) {
+ // Skip if IOCTL failed, or if the format is emulated
+ fmtdesc.index++;
+ continue;
+ }
+ auto it =
+ std::find(kSupportedFourCCs.begin(), kSupportedFourCCs.end(), fmtdesc.pixelformat);
+ if (it == kSupportedFourCCs.end()) {
+ fmtdesc.index++;
+ continue;
+ }
+
+ // Found supported format
+ v4l2_frmsizeenum frameSize{.index = 0, .pixel_format = fmtdesc.pixelformat};
+ for (; TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frameSize)) == 0;
+ ++frameSize.index) {
+ if (frameSize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+ ALOGV("index:%d, format:%c%c%c%c, w %d, h %d", frameSize.index,
+ fmtdesc.pixelformat & 0xFF, (fmtdesc.pixelformat >> 8) & 0xFF,
+ (fmtdesc.pixelformat >> 16) & 0xFF, (fmtdesc.pixelformat >> 24) & 0xFF,
+ frameSize.discrete.width, frameSize.discrete.height);
+
+ // Disregard h > w formats so all aspect ratio (h/w) <= 1.0
+ // This will simplify the crop/scaling logic down the road
+ if (frameSize.discrete.height > frameSize.discrete.width) {
+ continue;
+ }
+
+ // Discard all formats which is smaller than minStreamSize
+ if (frameSize.discrete.width < minStreamSize.width ||
+ frameSize.discrete.height < minStreamSize.height) {
+ continue;
+ }
+
+ SupportedV4L2Format format{
+ .width = static_cast<int32_t>(frameSize.discrete.width),
+ .height = static_cast<int32_t>(frameSize.discrete.height),
+ .fourcc = fmtdesc.pixelformat};
+
+ if (format.fourcc == V4L2_PIX_FMT_Z16 && depthEnabled) {
+ updateFpsBounds(fd, cropType, depthFpsLimits, format, outFmts);
+ } else {
+ updateFpsBounds(fd, cropType, fpsLimits, format, outFmts);
+ }
+ }
+ }
+ fmtdesc.index++;
+ }
+ trimSupportedFormats(cropType, &outFmts);
+ return outFmts;
+}
+
+void ExternalCameraDevice::trimSupportedFormats(CroppingType cropType,
+ std::vector<SupportedV4L2Format>* pFmts) {
+ std::vector<SupportedV4L2Format>& sortedFmts = *pFmts;
+ if (cropType == VERTICAL) {
+ std::sort(sortedFmts.begin(), sortedFmts.end(),
+ [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+ if (a.width == b.width) {
+ return a.height < b.height;
+ }
+ return a.width < b.width;
+ });
+ } else {
+ std::sort(sortedFmts.begin(), sortedFmts.end(),
+ [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool {
+ if (a.height == b.height) {
+ return a.width < b.width;
+ }
+ return a.height < b.height;
+ });
+ }
+
+ if (sortedFmts.empty()) {
+ ALOGE("%s: input format list is empty!", __FUNCTION__);
+ return;
+ }
+
+ const auto& maxSize = sortedFmts[sortedFmts.size() - 1];
+ float maxSizeAr = ASPECT_RATIO(maxSize);
+
+ // Remove formats that has aspect ratio not croppable from largest size
+ std::vector<SupportedV4L2Format> out;
+ for (const auto& fmt : sortedFmts) {
+ float ar = ASPECT_RATIO(fmt);
+ if (isAspectRatioClose(ar, maxSizeAr)) {
+ out.push_back(fmt);
+ } else if (cropType == HORIZONTAL && ar < maxSizeAr) {
+ out.push_back(fmt);
+ } else if (cropType == VERTICAL && ar > maxSizeAr) {
+ out.push_back(fmt);
+ } else {
+ ALOGV("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)", __FUNCTION__,
+ fmt.width, fmt.height, cropType == VERTICAL ? "vertically" : "horizontally",
+ maxSize.width, maxSize.height);
+ }
+ }
+ sortedFmts = out;
+}
+
+binder_status_t ExternalCameraDevice::dump(int fd, const char** args, uint32_t numArgs) {
+ std::shared_ptr<ExternalCameraDeviceSession> session = mSession.lock();
+ if (session == nullptr) {
+ dprintf(fd, "No active camera device session instance\n");
+ return STATUS_OK;
+ }
+
+ return session->dump(fd, args, numArgs);
+}
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/camera/device/default/ExternalCameraDevice.h b/camera/device/default/ExternalCameraDevice.h
new file mode 100644
index 0000000..bcae194
--- /dev/null
+++ b/camera/device/default/ExternalCameraDevice.h
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICE_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICE_H_
+
+#include <ExternalCameraDeviceSession.h>
+#include <ExternalCameraUtils.h>
+#include <aidl/android/hardware/camera/device/BnCameraDevice.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::CameraResourceCost;
+using ::aidl::android::hardware::camera::device::BnCameraDevice;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::ICameraDeviceSession;
+using ::aidl::android::hardware::camera::device::ICameraInjectionSession;
+using ::aidl::android::hardware::camera::device::StreamConfiguration;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+
+class ExternalCameraDevice : public BnCameraDevice {
+ public:
+ // Called by external camera provider HAL.
+ // Provider HAL must ensure the uniqueness of CameraDevice object per cameraId, or there could
+ // be multiple CameraDevice trying to access the same physical camera. Also, provider will have
+ // to keep track of all CameraDevice objects in order to notify CameraDevice when the underlying
+ // camera is detached.
+ ExternalCameraDevice(const std::string& devicePath, const ExternalCameraConfig& config);
+ ~ExternalCameraDevice() override;
+
+ ndk::ScopedAStatus getCameraCharacteristics(CameraMetadata* _aidl_return) override;
+ ndk::ScopedAStatus getPhysicalCameraCharacteristics(const std::string& in_physicalCameraId,
+ CameraMetadata* _aidl_return) override;
+ ndk::ScopedAStatus getResourceCost(CameraResourceCost* _aidl_return) override;
+ ndk::ScopedAStatus isStreamCombinationSupported(const StreamConfiguration& in_streams,
+ bool* _aidl_return) override;
+ ndk::ScopedAStatus open(const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+ std::shared_ptr<ICameraDeviceSession>* _aidl_return) override;
+ ndk::ScopedAStatus openInjectionSession(
+ const std::shared_ptr<ICameraDeviceCallback>& in_callback,
+ std::shared_ptr<ICameraInjectionSession>* _aidl_return) override;
+ ndk::ScopedAStatus setTorchMode(bool in_on) override;
+ ndk::ScopedAStatus turnOnTorchWithStrengthLevel(int32_t in_torchStrength) override;
+ ndk::ScopedAStatus getTorchStrengthLevel(int32_t* _aidl_return) override;
+
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ // Caller must use this method to check if CameraDevice ctor failed
+ bool isInitFailed();
+
+ // Device version to be used by the external camera provider.
+ // Should be of the form <major>.<minor>
+ static std::string kDeviceVersion;
+
+ private:
+ virtual std::shared_ptr<ExternalCameraDeviceSession> createSession(
+ const std::shared_ptr<ICameraDeviceCallback>&, const ExternalCameraConfig& cfg,
+ const std::vector<SupportedV4L2Format>& sortedFormats, const CroppingType& croppingType,
+ const common::V1_0::helper::CameraMetadata& chars, const std::string& cameraId,
+ unique_fd v4l2Fd);
+
+ bool isInitFailedLocked();
+
+ // Init supported w/h/format/fps in mSupportedFormats. Caller still owns fd
+ void initSupportedFormatsLocked(int fd);
+
+ // Calls into virtual member function. Do not use it in constructor
+ status_t initCameraCharacteristics();
+ // Init available capabilities keys
+ virtual status_t initAvailableCapabilities(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+ // Init non-device dependent keys
+ virtual status_t initDefaultCharsKeys(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+ // Init camera control chars keys. Caller still owns fd
+ status_t initCameraControlsCharsKeys(
+ int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+ // Init camera output configuration related keys. Caller still owns fd
+ status_t initOutputCharsKeys(
+ int fd, ::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+
+ // Helper function for initOutputCharskeys
+ template <size_t SIZE>
+ status_t initOutputCharsKeysByFormat(
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata,
+ uint32_t fourcc, const std::array<int, SIZE>& halFormats, int streamConfigTag,
+ int streamConfiguration, int minFrameDuration, int stallDuration);
+
+ status_t calculateMinFps(::android::hardware::camera::common::V1_0::helper::CameraMetadata*);
+
+ static void getFrameRateList(int fd, double fpsUpperBound, SupportedV4L2Format* format);
+
+ static void updateFpsBounds(int fd, CroppingType cropType,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+ SupportedV4L2Format format,
+ std::vector<SupportedV4L2Format>& outFmts);
+
+ // Get candidate supported formats list of input cropping type.
+ static std::vector<SupportedV4L2Format> getCandidateSupportedFormatsLocked(
+ int fd, CroppingType cropType,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits,
+ const std::vector<ExternalCameraConfig::FpsLimitation>& depthFpsLimits,
+ const Size& minStreamSize, bool depthEnabled);
+ // Trim supported format list by the cropping type. Also sort output formats by width/height
+ static void trimSupportedFormats(CroppingType cropType,
+ /*inout*/ std::vector<SupportedV4L2Format>* pFmts);
+
+ Mutex mLock;
+ bool mInitialized = false;
+ bool mInitFailed = false;
+ std::string mCameraId;
+ std::string mDevicePath;
+ const ExternalCameraConfig& mCfg;
+ std::vector<SupportedV4L2Format> mSupportedFormats;
+ CroppingType mCroppingType;
+
+ std::weak_ptr<ExternalCameraDeviceSession> mSession =
+ std::weak_ptr<ExternalCameraDeviceSession>();
+
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata mCameraCharacteristics;
+
+ const std::vector<int32_t> AVAILABLE_CHARACTERISTICS_KEYS = {
+ ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+ ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+ ANDROID_CONTROL_AE_AVAILABLE_MODES,
+ ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+ ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+ ANDROID_CONTROL_AE_COMPENSATION_STEP,
+ ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+ ANDROID_CONTROL_AF_AVAILABLE_MODES,
+ ANDROID_CONTROL_AVAILABLE_EFFECTS,
+ ANDROID_CONTROL_AVAILABLE_MODES,
+ ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+ ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+ ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+ ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+ ANDROID_CONTROL_MAX_REGIONS,
+ ANDROID_FLASH_INFO_AVAILABLE,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
+ ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+ ANDROID_LENS_FACING,
+ ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
+ ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+ ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
+ ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+ ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
+ ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
+ ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+ ANDROID_SCALER_CROPPING_TYPE,
+ ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+ ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+ ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+ ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
+ ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
+ ANDROID_SENSOR_ORIENTATION,
+ ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
+ ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
+ ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+ ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
+ ANDROID_SYNC_MAX_LATENCY};
+};
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICE_H_
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
new file mode 100644
index 0000000..c962974
--- /dev/null
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -0,0 +1,2945 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamDevSsn"
+// #define LOG_NDEBUG 0
+#include <log/log.h>
+
+#include "ExternalCameraDeviceSession.h"
+
+#include <Exif.h>
+#include <ExternalCameraOfflineSession.h>
+#include <aidl/android/hardware/camera/device/CameraBlob.h>
+#include <aidl/android/hardware/camera/device/CameraBlobId.h>
+#include <aidl/android/hardware/camera/device/ErrorMsg.h>
+#include <aidl/android/hardware/camera/device/ShutterMsg.h>
+#include <aidl/android/hardware/camera/device/StreamBufferRet.h>
+#include <aidl/android/hardware/camera/device/StreamBuffersVal.h>
+#include <aidl/android/hardware/camera/device/StreamConfigurationMode.h>
+#include <aidl/android/hardware/camera/device/StreamRotation.h>
+#include <aidl/android/hardware/camera/device/StreamType.h>
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <convert.h>
+#include <linux/videodev2.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
+#include <deque>
+
+#define HAVE_JPEG // required for libyuv.h to export MJPEG decode APIs
+#include <libyuv.h>
+#include <libyuv/convert.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+namespace {
+
+// Size of request/result metadata fast message queue. Change to 0 to always use hwbinder buffer.
+static constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */;
+
+const int kBadFramesAfterStreamOn = 1; // drop x frames after streamOn to get rid of some initial
+ // bad frames. TODO: develop a better bad frame detection
+ // method
+constexpr int MAX_RETRY = 15; // Allow retry some ioctl failures a few times to account for some
+ // webcam showing temporarily ioctl failures.
+constexpr int IOCTL_RETRY_SLEEP_US = 33000; // 33ms * MAX_RETRY = 0.5 seconds
+
+// Constants for tryLock during dumpstate
+static constexpr int kDumpLockRetries = 50;
+static constexpr int kDumpLockSleep = 60000;
+
+bool tryLock(Mutex& mutex) {
+ bool locked = false;
+ for (int i = 0; i < kDumpLockRetries; ++i) {
+ if (mutex.tryLock() == NO_ERROR) {
+ locked = true;
+ break;
+ }
+ usleep(kDumpLockSleep);
+ }
+ return locked;
+}
+
+bool tryLock(std::mutex& mutex) {
+ bool locked = false;
+ for (int i = 0; i < kDumpLockRetries; ++i) {
+ if (mutex.try_lock()) {
+ locked = true;
+ break;
+ }
+ usleep(kDumpLockSleep);
+ }
+ return locked;
+}
+
+} // anonymous namespace
+
+using ::aidl::android::hardware::camera::device::BufferRequestStatus;
+using ::aidl::android::hardware::camera::device::CameraBlob;
+using ::aidl::android::hardware::camera::device::CameraBlobId;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::ShutterMsg;
+using ::aidl::android::hardware::camera::device::StreamBuffer;
+using ::aidl::android::hardware::camera::device::StreamBufferRet;
+using ::aidl::android::hardware::camera::device::StreamBuffersVal;
+using ::aidl::android::hardware::camera::device::StreamConfigurationMode;
+using ::aidl::android::hardware::camera::device::StreamRotation;
+using ::aidl::android::hardware::camera::device::StreamType;
+using ::aidl::android::hardware::graphics::common::Dataspace;
+using ::android::hardware::camera::common::V1_0::helper::ExifUtils;
+
+// Static instances
+const int ExternalCameraDeviceSession::kMaxProcessedStream;
+const int ExternalCameraDeviceSession::kMaxStallStream;
+HandleImporter ExternalCameraDeviceSession::sHandleImporter;
+
+ExternalCameraDeviceSession::ExternalCameraDeviceSession(
+ const std::shared_ptr<ICameraDeviceCallback>& callback, const ExternalCameraConfig& cfg,
+ const std::vector<SupportedV4L2Format>& sortedFormats, const CroppingType& croppingType,
+ const common::V1_0::helper::CameraMetadata& chars, const std::string& cameraId,
+ unique_fd v4l2Fd)
+ : mCallback(callback),
+ mCfg(cfg),
+ mCameraCharacteristics(chars),
+ mSupportedFormats(sortedFormats),
+ mCroppingType(croppingType),
+ mCameraId(cameraId),
+ mV4l2Fd(std::move(v4l2Fd)),
+ mMaxThumbResolution(getMaxThumbResolution()),
+ mMaxJpegResolution(getMaxJpegResolution()) {}
+
+Size ExternalCameraDeviceSession::getMaxThumbResolution() const {
+ return getMaxThumbnailResolution(mCameraCharacteristics);
+}
+
+Size ExternalCameraDeviceSession::getMaxJpegResolution() const {
+ Size ret{0, 0};
+ for (auto& fmt : mSupportedFormats) {
+ if (fmt.width * fmt.height > ret.width * ret.height) {
+ ret = Size{fmt.width, fmt.height};
+ }
+ }
+ return ret;
+}
+
+bool ExternalCameraDeviceSession::initialize() {
+ if (mV4l2Fd.get() < 0) {
+ ALOGE("%s: invalid v4l2 device fd %d!", __FUNCTION__, mV4l2Fd.get());
+ return true;
+ }
+
+ struct v4l2_capability capability;
+ int ret = ioctl(mV4l2Fd.get(), VIDIOC_QUERYCAP, &capability);
+ std::string make, model;
+ if (ret < 0) {
+ ALOGW("%s v4l2 QUERYCAP failed", __FUNCTION__);
+ mExifMake = "Generic UVC webcam";
+ mExifModel = "Generic UVC webcam";
+ } else {
+ // capability.card is UTF-8 encoded
+ char card[32];
+ int j = 0;
+ for (int i = 0; i < 32; i++) {
+ if (capability.card[i] < 128) {
+ card[j++] = capability.card[i];
+ }
+ if (capability.card[i] == '\0') {
+ break;
+ }
+ }
+ if (j == 0 || card[j - 1] != '\0') {
+ mExifMake = "Generic UVC webcam";
+ mExifModel = "Generic UVC webcam";
+ } else {
+ mExifMake = card;
+ mExifModel = card;
+ }
+ }
+
+ initOutputThread();
+ if (mOutputThread == nullptr) {
+ ALOGE("%s: init OutputThread failed!", __FUNCTION__);
+ return true;
+ }
+ mOutputThread->setExifMakeModel(mExifMake, mExifModel);
+
+ status_t status = initDefaultRequests();
+ if (status != OK) {
+ ALOGE("%s: init default requests failed!", __FUNCTION__);
+ return true;
+ }
+
+ mRequestMetadataQueue =
+ std::make_unique<RequestMetadataQueue>(kMetadataMsgQueueSize, false /* non blocking */);
+ if (!mRequestMetadataQueue->isValid()) {
+ ALOGE("%s: invalid request fmq", __FUNCTION__);
+ return true;
+ }
+
+ mResultMetadataQueue =
+ std::make_shared<ResultMetadataQueue>(kMetadataMsgQueueSize, false /* non blocking */);
+ if (!mResultMetadataQueue->isValid()) {
+ ALOGE("%s: invalid result fmq", __FUNCTION__);
+ return true;
+ }
+
+ mOutputThread->run();
+ return false;
+}
+
+bool ExternalCameraDeviceSession::isInitFailed() {
+ Mutex::Autolock _l(mLock);
+ if (!mInitialized) {
+ mInitFail = initialize();
+ mInitialized = true;
+ }
+ return mInitFail;
+}
+
+void ExternalCameraDeviceSession::initOutputThread() {
+ // Grab a shared_ptr to 'this' from ndk::SharedRefBase::ref()
+ std::shared_ptr<ExternalCameraDeviceSession> thiz = ref<ExternalCameraDeviceSession>();
+
+ mBufferRequestThread = std::make_shared<BufferRequestThread>(/*parent=*/thiz, mCallback);
+ mBufferRequestThread->run();
+ mOutputThread = std::make_shared<OutputThread>(/*parent=*/thiz, mCroppingType,
+ mCameraCharacteristics, mBufferRequestThread);
+}
+
+void ExternalCameraDeviceSession::closeOutputThread() {
+ closeOutputThreadImpl();
+}
+
+void ExternalCameraDeviceSession::closeOutputThreadImpl() {
+ if (mOutputThread != nullptr) {
+ mOutputThread->flush();
+ mOutputThread->requestExitAndWait();
+ mOutputThread.reset();
+ }
+}
+
+Status ExternalCameraDeviceSession::initStatus() const {
+ Mutex::Autolock _l(mLock);
+ Status status = Status::OK;
+ if (mInitFail || mClosed) {
+ ALOGI("%s: session initFailed %d closed %d", __FUNCTION__, mInitFail, mClosed);
+ status = Status::INTERNAL_ERROR;
+ }
+ return status;
+}
+
+ExternalCameraDeviceSession::~ExternalCameraDeviceSession() {
+ if (!isClosed()) {
+ ALOGE("ExternalCameraDeviceSession deleted before close!");
+ close(/*callerIsDtor*/ true);
+ }
+}
+
+ScopedAStatus ExternalCameraDeviceSession::constructDefaultRequestSettings(
+ RequestTemplate in_type, CameraMetadata* _aidl_return) {
+ CameraMetadata emptyMetadata;
+ Status status = initStatus();
+ if (status != Status::OK) {
+ return fromStatus(status);
+ }
+ switch (in_type) {
+ case RequestTemplate::PREVIEW:
+ case RequestTemplate::STILL_CAPTURE:
+ case RequestTemplate::VIDEO_RECORD:
+ case RequestTemplate::VIDEO_SNAPSHOT: {
+ *_aidl_return = mDefaultRequests[in_type];
+ break;
+ }
+ case RequestTemplate::MANUAL:
+ case RequestTemplate::ZERO_SHUTTER_LAG:
+ // Don't support MANUAL, ZSL templates
+ status = Status::ILLEGAL_ARGUMENT;
+ break;
+ default:
+ ALOGE("%s: unknown request template type %d", __FUNCTION__, static_cast<int>(in_type));
+ status = Status::ILLEGAL_ARGUMENT;
+ break;
+ }
+ return fromStatus(status);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::configureStreams(
+ const StreamConfiguration& in_requestedConfiguration,
+ std::vector<HalStream>* _aidl_return) {
+ uint32_t blobBufferSize = 0;
+ _aidl_return->clear();
+ Mutex::Autolock _il(mInterfaceLock);
+
+ Status status =
+ isStreamCombinationSupported(in_requestedConfiguration, mSupportedFormats, mCfg);
+ if (status != Status::OK) {
+ return fromStatus(status);
+ }
+
+ status = initStatus();
+ if (status != Status::OK) {
+ return fromStatus(status);
+ }
+
+ {
+ std::lock_guard<std::mutex> lk(mInflightFramesLock);
+ if (!mInflightFrames.empty()) {
+ ALOGE("%s: trying to configureStreams while there are still %zu inflight frames!",
+ __FUNCTION__, mInflightFrames.size());
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+ }
+
+ Mutex::Autolock _l(mLock);
+ {
+ Mutex::Autolock _cl(mCbsLock);
+ // Add new streams
+ for (const auto& stream : in_requestedConfiguration.streams) {
+ if (mStreamMap.count(stream.id) == 0) {
+ mStreamMap[stream.id] = stream;
+ mCirculatingBuffers.emplace(stream.id, CirculatingBuffers{});
+ }
+ }
+
+ // Cleanup removed streams
+ for (auto it = mStreamMap.begin(); it != mStreamMap.end();) {
+ int id = it->first;
+ bool found = false;
+ for (const auto& stream : in_requestedConfiguration.streams) {
+ if (id == stream.id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // Unmap all buffers of deleted stream
+ cleanupBuffersLocked(id);
+ it = mStreamMap.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ // Now select a V4L2 format to produce all output streams
+ float desiredAr = (mCroppingType == VERTICAL) ? kMaxAspectRatio : kMinAspectRatio;
+ uint32_t maxDim = 0;
+ for (const auto& stream : in_requestedConfiguration.streams) {
+ float aspectRatio = ASPECT_RATIO(stream);
+ ALOGI("%s: request stream %dx%d", __FUNCTION__, stream.width, stream.height);
+ if ((mCroppingType == VERTICAL && aspectRatio < desiredAr) ||
+ (mCroppingType == HORIZONTAL && aspectRatio > desiredAr)) {
+ desiredAr = aspectRatio;
+ }
+
+ // The dimension that's not cropped
+ uint32_t dim = (mCroppingType == VERTICAL) ? stream.width : stream.height;
+ if (dim > maxDim) {
+ maxDim = dim;
+ }
+ }
+
+ // Find the smallest format that matches the desired aspect ratio and is wide/high enough
+ SupportedV4L2Format v4l2Fmt{.width = 0, .height = 0};
+ for (const auto& fmt : mSupportedFormats) {
+ uint32_t dim = (mCroppingType == VERTICAL) ? fmt.width : fmt.height;
+ if (dim >= maxDim) {
+ float aspectRatio = ASPECT_RATIO(fmt);
+ if (isAspectRatioClose(aspectRatio, desiredAr)) {
+ v4l2Fmt = fmt;
+ // since mSupportedFormats is sorted by width then height, the first matching fmt
+ // will be the smallest one with matching aspect ratio
+ break;
+ }
+ }
+ }
+
+ if (v4l2Fmt.width == 0) {
+ // Cannot find exact good aspect ratio candidate, try to find a close one
+ for (const auto& fmt : mSupportedFormats) {
+ uint32_t dim = (mCroppingType == VERTICAL) ? fmt.width : fmt.height;
+ if (dim >= maxDim) {
+ float aspectRatio = ASPECT_RATIO(fmt);
+ if ((mCroppingType == VERTICAL && aspectRatio < desiredAr) ||
+ (mCroppingType == HORIZONTAL && aspectRatio > desiredAr)) {
+ v4l2Fmt = fmt;
+ break;
+ }
+ }
+ }
+ }
+
+ if (v4l2Fmt.width == 0) {
+ ALOGE("%s: unable to find a resolution matching (%s at least %d, aspect ratio %f)",
+ __FUNCTION__, (mCroppingType == VERTICAL) ? "width" : "height", maxDim, desiredAr);
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+
+ if (configureV4l2StreamLocked(v4l2Fmt) != 0) {
+ ALOGE("V4L configuration failed!, format:%c%c%c%c, w %d, h %d", v4l2Fmt.fourcc & 0xFF,
+ (v4l2Fmt.fourcc >> 8) & 0xFF, (v4l2Fmt.fourcc >> 16) & 0xFF,
+ (v4l2Fmt.fourcc >> 24) & 0xFF, v4l2Fmt.width, v4l2Fmt.height);
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ Size v4lSize = {v4l2Fmt.width, v4l2Fmt.height};
+ Size thumbSize{0, 0};
+ camera_metadata_ro_entry entry =
+ mCameraCharacteristics.find(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
+ for (uint32_t i = 0; i < entry.count; i += 2) {
+ Size sz{entry.data.i32[i], entry.data.i32[i + 1]};
+ if (sz.width * sz.height > thumbSize.width * thumbSize.height) {
+ thumbSize = sz;
+ }
+ }
+
+ if (thumbSize.width * thumbSize.height == 0) {
+ ALOGE("%s: non-zero thumbnail size not available", __FUNCTION__);
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ mBlobBufferSize = blobBufferSize;
+ status = mOutputThread->allocateIntermediateBuffers(
+ v4lSize, mMaxThumbResolution, in_requestedConfiguration.streams, blobBufferSize);
+ if (status != Status::OK) {
+ ALOGE("%s: allocating intermediate buffers failed!", __FUNCTION__);
+ return fromStatus(status);
+ }
+
+ std::vector<HalStream>& out = *_aidl_return;
+ out.resize(in_requestedConfiguration.streams.size());
+ for (size_t i = 0; i < in_requestedConfiguration.streams.size(); i++) {
+ out[i].overrideDataSpace = in_requestedConfiguration.streams[i].dataSpace;
+ out[i].id = in_requestedConfiguration.streams[i].id;
+ // TODO: double check should we add those CAMERA flags
+ mStreamMap[in_requestedConfiguration.streams[i].id].usage = out[i].producerUsage =
+ static_cast<BufferUsage>(((int64_t)in_requestedConfiguration.streams[i].usage) |
+ ((int64_t)BufferUsage::CPU_WRITE_OFTEN) |
+ ((int64_t)BufferUsage::CAMERA_OUTPUT));
+ out[i].consumerUsage = static_cast<BufferUsage>(0);
+ out[i].maxBuffers = static_cast<int32_t>(mV4L2BufferCount);
+
+ switch (in_requestedConfiguration.streams[i].format) {
+ case PixelFormat::BLOB:
+ case PixelFormat::YCBCR_420_888:
+ case PixelFormat::YV12: // Used by SurfaceTexture
+ case PixelFormat::Y16:
+ // No override
+ out[i].overrideFormat = in_requestedConfiguration.streams[i].format;
+ break;
+ case PixelFormat::IMPLEMENTATION_DEFINED:
+ // Implementation Defined
+ // This should look at the Stream's dataspace flag to determine the format or leave
+ // it as is if the rest of the system knows how to handle a private format. To keep
+ // this HAL generic, this is being overridden to YUV420
+ out[i].overrideFormat = PixelFormat::YCBCR_420_888;
+ // Save overridden format in mStreamMap
+ mStreamMap[in_requestedConfiguration.streams[i].id].format = out[i].overrideFormat;
+ break;
+ default:
+ ALOGE("%s: unsupported format 0x%x", __FUNCTION__,
+ in_requestedConfiguration.streams[i].format);
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+ }
+
+ mFirstRequest = true;
+ mLastStreamConfigCounter = in_requestedConfiguration.streamConfigCounter;
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::flush() {
+ ATRACE_CALL();
+ Mutex::Autolock _il(mInterfaceLock);
+ Status status = initStatus();
+ if (status != Status::OK) {
+ return fromStatus(status);
+ }
+ mOutputThread->flush();
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::getCaptureRequestMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+ Mutex::Autolock _il(mInterfaceLock);
+ *_aidl_return = mRequestMetadataQueue->dupeDesc();
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::getCaptureResultMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+ Mutex::Autolock _il(mInterfaceLock);
+ *_aidl_return = mResultMetadataQueue->dupeDesc();
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::isReconfigurationRequired(
+ const CameraMetadata& in_oldSessionParams, const CameraMetadata& in_newSessionParams,
+ bool* _aidl_return) {
+ // reconfiguration required if there is any change in the session params
+ *_aidl_return = in_oldSessionParams != in_newSessionParams;
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::processCaptureRequest(
+ const std::vector<CaptureRequest>& in_requests,
+ const std::vector<BufferCache>& in_cachesToRemove, int32_t* _aidl_return) {
+ Mutex::Autolock _il(mInterfaceLock);
+ updateBufferCaches(in_cachesToRemove);
+
+ int32_t& numRequestProcessed = *_aidl_return;
+ numRequestProcessed = 0;
+ Status s = Status::OK;
+ for (size_t i = 0; i < in_requests.size(); i++, numRequestProcessed++) {
+ s = processOneCaptureRequest(in_requests[i]);
+ if (s != Status::OK) {
+ break;
+ }
+ }
+
+ return fromStatus(s);
+}
+
+Status ExternalCameraDeviceSession::processOneCaptureRequest(const CaptureRequest& request) {
+ ATRACE_CALL();
+ Status status = initStatus();
+ if (status != Status::OK) {
+ return status;
+ }
+
+ if (request.inputBuffer.streamId != -1) {
+ ALOGE("%s: external camera does not support reprocessing!", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ Mutex::Autolock _l(mLock);
+ if (!mV4l2Streaming) {
+ ALOGE("%s: cannot process request in streamOff state!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+
+ const camera_metadata_t* rawSettings = nullptr;
+ bool converted;
+ CameraMetadata settingsFmq; // settings from FMQ
+
+ if (request.fmqSettingsSize > 0) {
+ // non-blocking read; client must write metadata before calling
+ // processOneCaptureRequest
+ settingsFmq.metadata.resize(request.fmqSettingsSize);
+ bool read = mRequestMetadataQueue->read(
+ reinterpret_cast<int8_t*>(settingsFmq.metadata.data()), request.fmqSettingsSize);
+ if (read) {
+ converted = convertFromAidl(settingsFmq, &rawSettings);
+ } else {
+ ALOGE("%s: capture request settings metadata couldn't be read from fmq!", __FUNCTION__);
+ converted = false;
+ }
+ } else {
+ converted = convertFromAidl(request.settings, &rawSettings);
+ }
+
+ if (converted && rawSettings != nullptr) {
+ mLatestReqSetting = rawSettings;
+ }
+
+ if (!converted) {
+ ALOGE("%s: capture request settings metadata is corrupt!", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ if (mFirstRequest && rawSettings == nullptr) {
+ ALOGE("%s: capture request settings must not be null for first request!", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ std::vector<buffer_handle_t*> allBufPtrs;
+ std::vector<int> allFences;
+ size_t numOutputBufs = request.outputBuffers.size();
+
+ if (numOutputBufs == 0) {
+ ALOGE("%s: capture request must have at least one output buffer!", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ camera_metadata_entry fpsRange = mLatestReqSetting.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
+ if (fpsRange.count == 2) {
+ double requestFpsMax = fpsRange.data.i32[1];
+ double closestFps = 0.0;
+ double fpsError = 1000.0;
+ bool fpsSupported = false;
+ for (const auto& fr : mV4l2StreamingFmt.frameRates) {
+ double f = fr.getFramesPerSecond();
+ if (std::fabs(requestFpsMax - f) < 1.0) {
+ fpsSupported = true;
+ break;
+ }
+ if (std::fabs(requestFpsMax - f) < fpsError) {
+ fpsError = std::fabs(requestFpsMax - f);
+ closestFps = f;
+ }
+ }
+ if (!fpsSupported) {
+ /* This can happen in a few scenarios:
+ * 1. The application is sending an FPS range not supported by the configured outputs.
+ * 2. The application is sending a valid FPS range for all configured outputs, but
+ * the selected V4L2 size can only run at slower speed. This should be very rare
+ * though: for this to happen a sensor needs to support at least 3 different aspect
+ * ratio outputs, and when (at least) two outputs are both not the main aspect ratio
+ * of the webcam, a third size that's larger might be picked and runs into this
+ * issue.
+ */
+ ALOGW("%s: cannot reach fps %d! Will do %f instead", __FUNCTION__, fpsRange.data.i32[1],
+ closestFps);
+ requestFpsMax = closestFps;
+ }
+
+ if (requestFpsMax != mV4l2StreamingFps) {
+ {
+ std::unique_lock<std::mutex> lk(mV4l2BufferLock);
+ while (mNumDequeuedV4l2Buffers != 0) {
+ // Wait until pipeline is idle before reconfigure stream
+ int waitRet = waitForV4L2BufferReturnLocked(lk);
+ if (waitRet != 0) {
+ ALOGE("%s: wait for pipeline idle failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+ }
+ }
+ configureV4l2StreamLocked(mV4l2StreamingFmt, requestFpsMax);
+ }
+ }
+
+ status = importRequestLocked(request, allBufPtrs, allFences);
+ if (status != Status::OK) {
+ return status;
+ }
+
+ nsecs_t shutterTs = 0;
+ std::unique_ptr<V4L2Frame> frameIn = dequeueV4l2FrameLocked(&shutterTs);
+ if (frameIn == nullptr) {
+ ALOGE("%s: V4L2 deque frame failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+
+ std::shared_ptr<HalRequest> halReq = std::make_shared<HalRequest>();
+ halReq->frameNumber = request.frameNumber;
+ halReq->setting = mLatestReqSetting;
+ halReq->frameIn = std::move(frameIn);
+ halReq->shutterTs = shutterTs;
+ halReq->buffers.resize(numOutputBufs);
+ for (size_t i = 0; i < numOutputBufs; i++) {
+ HalStreamBuffer& halBuf = halReq->buffers[i];
+ int streamId = halBuf.streamId = request.outputBuffers[i].streamId;
+ halBuf.bufferId = request.outputBuffers[i].bufferId;
+ const Stream& stream = mStreamMap[streamId];
+ halBuf.width = stream.width;
+ halBuf.height = stream.height;
+ halBuf.format = stream.format;
+ halBuf.usage = stream.usage;
+ halBuf.bufPtr = allBufPtrs[i];
+ halBuf.acquireFence = allFences[i];
+ halBuf.fenceTimeout = false;
+ }
+ {
+ std::lock_guard<std::mutex> lk(mInflightFramesLock);
+ mInflightFrames.insert(halReq->frameNumber);
+ }
+ // Send request to OutputThread for the rest of processing
+ mOutputThread->submitRequest(halReq);
+ mFirstRequest = false;
+ return Status::OK;
+}
+
+ScopedAStatus ExternalCameraDeviceSession::signalStreamFlush(
+ const std::vector<int32_t>& /*in_streamIds*/, int32_t in_streamConfigCounter) {
+ {
+ Mutex::Autolock _l(mLock);
+ if (in_streamConfigCounter < mLastStreamConfigCounter) {
+ // stale call. new streams have been configured since this call was issued.
+ // Do nothing.
+ return fromStatus(Status::OK);
+ }
+ }
+
+ // TODO: implement if needed.
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::switchToOffline(
+ const std::vector<int32_t>& in_streamsToKeep,
+ CameraOfflineSessionInfo* out_offlineSessionInfo,
+ std::shared_ptr<ICameraOfflineSession>* _aidl_return) {
+ std::vector<NotifyMsg> msgs;
+ std::vector<CaptureResult> results;
+ CameraOfflineSessionInfo info;
+ std::shared_ptr<ICameraOfflineSession> session;
+ Status st = switchToOffline(in_streamsToKeep, &msgs, &results, &info, &session);
+
+ mCallback->notify(msgs);
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq= */ true);
+ freeReleaseFences(results);
+
+ // setup return values
+ *out_offlineSessionInfo = info;
+ *_aidl_return = session;
+ return fromStatus(st);
+}
+
+Status ExternalCameraDeviceSession::switchToOffline(
+ const std::vector<int32_t>& offlineStreams, std::vector<NotifyMsg>* msgs,
+ std::vector<CaptureResult>* results, CameraOfflineSessionInfo* info,
+ std::shared_ptr<ICameraOfflineSession>* session) {
+ ATRACE_CALL();
+ if (offlineStreams.size() > 1) {
+ ALOGE("%s: more than one offline stream is not supported", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ if (msgs == nullptr || results == nullptr || info == nullptr || session == nullptr) {
+ ALOGE("%s, output arguments (%p, %p, %p, %p) must not be null", __FUNCTION__, msgs, results,
+ info, session);
+ }
+
+ Mutex::Autolock _il(mInterfaceLock);
+ Status status = initStatus();
+ if (status != Status::OK) {
+ return status;
+ }
+
+ Mutex::Autolock _l(mLock);
+ for (auto streamId : offlineStreams) {
+ if (!supportOfflineLocked(streamId)) {
+ return Status::ILLEGAL_ARGUMENT;
+ }
+ }
+
+ // pause output thread and get all remaining inflight requests
+ auto remainingReqs = mOutputThread->switchToOffline();
+ std::vector<std::shared_ptr<HalRequest>> halReqs;
+
+ // Send out buffer/request error for remaining requests and filter requests
+ // to be handled in offline mode
+ for (auto& halReq : remainingReqs) {
+ bool dropReq = canDropRequest(offlineStreams, halReq);
+ if (dropReq) {
+ // Request is dropped completely. Just send request error and
+ // there is no need to send the request to offline session
+ processCaptureRequestError(halReq, msgs, results);
+ continue;
+ }
+
+ // All requests reach here must have at least one offline stream output
+ NotifyMsg shutter;
+ aidl::android::hardware::camera::device::ShutterMsg shutterMsg = {
+ .frameNumber = static_cast<int32_t>(halReq->frameNumber),
+ .timestamp = halReq->shutterTs};
+ shutter.set<NotifyMsg::Tag::shutter>(shutterMsg);
+ msgs->push_back(shutter);
+
+ std::vector<HalStreamBuffer> offlineBuffers;
+ for (const auto& buffer : halReq->buffers) {
+ bool dropBuffer = true;
+ for (auto offlineStreamId : offlineStreams) {
+ if (buffer.streamId == offlineStreamId) {
+ dropBuffer = false;
+ break;
+ }
+ }
+ if (dropBuffer) {
+ aidl::android::hardware::camera::device::ErrorMsg errorMsg = {
+ .frameNumber = static_cast<int32_t>(halReq->frameNumber),
+ .errorStreamId = buffer.streamId,
+ .errorCode = ErrorCode::ERROR_BUFFER};
+
+ NotifyMsg error;
+ error.set<NotifyMsg::Tag::error>(errorMsg);
+ msgs->push_back(error);
+
+ results->push_back({
+ .frameNumber = static_cast<int32_t>(halReq->frameNumber),
+ .outputBuffers = {},
+ .inputBuffer = {.streamId = -1},
+ .partialResult = 0, // buffer only result
+ });
+
+ CaptureResult& result = results->back();
+ result.outputBuffers.resize(1);
+ StreamBuffer& outputBuffer = result.outputBuffers[0];
+ outputBuffer.streamId = buffer.streamId;
+ outputBuffer.bufferId = buffer.bufferId;
+ outputBuffer.status = BufferStatus::ERROR;
+ if (buffer.acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = buffer.acquireFence;
+ outputBuffer.releaseFence = android::makeToAidl(handle);
+ }
+ } else {
+ offlineBuffers.push_back(buffer);
+ }
+ }
+ halReq->buffers = offlineBuffers;
+ halReqs.push_back(halReq);
+ }
+
+ // convert hal requests to offline request
+ std::deque<std::shared_ptr<HalRequest>> offlineReqs(halReqs.size());
+ size_t i = 0;
+ for (auto& v4lReq : halReqs) {
+ offlineReqs[i] = std::make_shared<HalRequest>();
+ offlineReqs[i]->frameNumber = v4lReq->frameNumber;
+ offlineReqs[i]->setting = v4lReq->setting;
+ offlineReqs[i]->shutterTs = v4lReq->shutterTs;
+ offlineReqs[i]->buffers = v4lReq->buffers;
+ std::shared_ptr<V4L2Frame> v4l2Frame(static_cast<V4L2Frame*>(v4lReq->frameIn.get()));
+ offlineReqs[i]->frameIn = std::make_shared<AllocatedV4L2Frame>(v4l2Frame);
+ i++;
+ // enqueue V4L2 frame
+ enqueueV4l2Frame(v4l2Frame);
+ }
+
+ // Collect buffer caches/streams
+ std::vector<Stream> streamInfos(offlineStreams.size());
+ std::map<int, CirculatingBuffers> circulatingBuffers;
+ {
+ Mutex::Autolock _cbsl(mCbsLock);
+ for (auto streamId : offlineStreams) {
+ circulatingBuffers[streamId] = mCirculatingBuffers.at(streamId);
+ mCirculatingBuffers.erase(streamId);
+ streamInfos.push_back(mStreamMap.at(streamId));
+ mStreamMap.erase(streamId);
+ }
+ }
+
+ fillOfflineSessionInfo(offlineStreams, offlineReqs, circulatingBuffers, info);
+ // create the offline session object
+ bool afTrigger;
+ {
+ std::lock_guard<std::mutex> _lk(mAfTriggerLock);
+ afTrigger = mAfTrigger;
+ }
+
+ std::shared_ptr<ExternalCameraOfflineSession> sessionImpl =
+ ndk::SharedRefBase::make<ExternalCameraOfflineSession>(
+ mCroppingType, mCameraCharacteristics, mCameraId, mExifMake, mExifModel,
+ mBlobBufferSize, afTrigger, streamInfos, offlineReqs, circulatingBuffers);
+
+ bool initFailed = sessionImpl->initialize();
+ if (initFailed) {
+ ALOGE("%s: offline session initialize failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+
+ // cleanup stream and buffer caches
+ {
+ Mutex::Autolock _cbsl(mCbsLock);
+ for (auto pair : mStreamMap) {
+ cleanupBuffersLocked(/*Stream ID*/ pair.first);
+ }
+ mCirculatingBuffers.clear();
+ }
+ mStreamMap.clear();
+
+ // update inflight records
+ {
+ std::lock_guard<std::mutex> _lk(mInflightFramesLock);
+ mInflightFrames.clear();
+ }
+
+ // stop v4l2 streaming
+ if (v4l2StreamOffLocked() != 0) {
+ ALOGE("%s: stop V4L2 streaming failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+
+ // No need to return session if there is no offline requests left
+ if (!offlineReqs.empty()) {
+ *session = sessionImpl;
+ } else {
+ *session = nullptr;
+ }
+
+ return Status::OK;
+}
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+#define UPDATE(md, tag, data, size) \
+ do { \
+ if ((md).update((tag), (data), (size))) { \
+ ALOGE("Update " #tag " failed!"); \
+ return BAD_VALUE; \
+ } \
+ } while (0)
+
+status_t ExternalCameraDeviceSession::initDefaultRequests() {
+ common::V1_0::helper::CameraMetadata md;
+
+ const uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
+ UPDATE(md, ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &aberrationMode, 1);
+
+ const int32_t exposureCompensation = 0;
+ UPDATE(md, ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &exposureCompensation, 1);
+
+ const uint8_t videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+ UPDATE(md, ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &videoStabilizationMode, 1);
+
+ const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
+ UPDATE(md, ANDROID_CONTROL_AWB_MODE, &awbMode, 1);
+
+ const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
+ UPDATE(md, ANDROID_CONTROL_AE_MODE, &aeMode, 1);
+
+ const uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
+ UPDATE(md, ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1);
+
+ const uint8_t afMode = ANDROID_CONTROL_AF_MODE_AUTO;
+ UPDATE(md, ANDROID_CONTROL_AF_MODE, &afMode, 1);
+
+ const uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
+ UPDATE(md, ANDROID_CONTROL_AF_TRIGGER, &afTrigger, 1);
+
+ const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED;
+ UPDATE(md, ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1);
+
+ const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF;
+ UPDATE(md, ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1);
+
+ const uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
+ UPDATE(md, ANDROID_FLASH_MODE, &flashMode, 1);
+
+ const int32_t thumbnailSize[] = {240, 180};
+ UPDATE(md, ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2);
+
+ const uint8_t jpegQuality = 90;
+ UPDATE(md, ANDROID_JPEG_QUALITY, &jpegQuality, 1);
+ UPDATE(md, ANDROID_JPEG_THUMBNAIL_QUALITY, &jpegQuality, 1);
+
+ const int32_t jpegOrientation = 0;
+ UPDATE(md, ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1);
+
+ const uint8_t oisMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
+ UPDATE(md, ANDROID_LENS_OPTICAL_STABILIZATION_MODE, &oisMode, 1);
+
+ const uint8_t nrMode = ANDROID_NOISE_REDUCTION_MODE_OFF;
+ UPDATE(md, ANDROID_NOISE_REDUCTION_MODE, &nrMode, 1);
+
+ const int32_t testPatternModes = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
+ UPDATE(md, ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternModes, 1);
+
+ const uint8_t fdMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
+ UPDATE(md, ANDROID_STATISTICS_FACE_DETECT_MODE, &fdMode, 1);
+
+ const uint8_t hotpixelMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
+ UPDATE(md, ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotpixelMode, 1);
+
+ bool support30Fps = false;
+ int32_t maxFps = std::numeric_limits<int32_t>::min();
+ for (const auto& supportedFormat : mSupportedFormats) {
+ for (const auto& fr : supportedFormat.frameRates) {
+ int32_t framerateInt = static_cast<int32_t>(fr.getFramesPerSecond());
+ if (maxFps < framerateInt) {
+ maxFps = framerateInt;
+ }
+ if (framerateInt == 30) {
+ support30Fps = true;
+ break;
+ }
+ }
+ if (support30Fps) {
+ break;
+ }
+ }
+
+ int32_t defaultFramerate = support30Fps ? 30 : maxFps;
+ int32_t defaultFpsRange[] = {defaultFramerate / 2, defaultFramerate};
+ UPDATE(md, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, defaultFpsRange, ARRAY_SIZE(defaultFpsRange));
+
+ uint8_t antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
+ UPDATE(md, ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibandingMode, 1);
+
+ const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
+ UPDATE(md, ANDROID_CONTROL_MODE, &controlMode, 1);
+
+ for (const auto& type : ndk::enum_range<RequestTemplate>()) {
+ common::V1_0::helper::CameraMetadata mdCopy = md;
+ uint8_t intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
+ switch (type) {
+ case RequestTemplate::PREVIEW:
+ intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
+ break;
+ case RequestTemplate::STILL_CAPTURE:
+ intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
+ break;
+ case RequestTemplate::VIDEO_RECORD:
+ intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
+ break;
+ case RequestTemplate::VIDEO_SNAPSHOT:
+ intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
+ break;
+ default:
+ ALOGV("%s: unsupported RequestTemplate type %d", __FUNCTION__, type);
+ continue;
+ }
+ UPDATE(mdCopy, ANDROID_CONTROL_CAPTURE_INTENT, &intent, 1);
+ camera_metadata_t* mdPtr = mdCopy.release();
+ uint8_t* rawMd = reinterpret_cast<uint8_t*>(mdPtr);
+ CameraMetadata aidlMd;
+ aidlMd.metadata.assign(rawMd, rawMd + get_camera_metadata_size(mdPtr));
+ mDefaultRequests[type] = aidlMd;
+ free_camera_metadata(mdPtr);
+ }
+ return OK;
+}
+
+status_t ExternalCameraDeviceSession::fillCaptureResult(common::V1_0::helper::CameraMetadata& md,
+ nsecs_t timestamp) {
+ bool afTrigger = false;
+ {
+ std::lock_guard<std::mutex> lk(mAfTriggerLock);
+ afTrigger = mAfTrigger;
+ if (md.exists(ANDROID_CONTROL_AF_TRIGGER)) {
+ camera_metadata_entry entry = md.find(ANDROID_CONTROL_AF_TRIGGER);
+ if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_START) {
+ mAfTrigger = afTrigger = true;
+ } else if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_CANCEL) {
+ mAfTrigger = afTrigger = false;
+ }
+ }
+ }
+
+ // For USB camera, the USB camera handles everything and we don't have control
+ // over AF. We only simply fake the AF metadata based on the request
+ // received here.
+ uint8_t afState;
+ if (afTrigger) {
+ afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+ } else {
+ afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+ }
+ UPDATE(md, ANDROID_CONTROL_AF_STATE, &afState, 1);
+
+ camera_metadata_ro_entry activeArraySize =
+ mCameraCharacteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+ return fillCaptureResultCommon(md, timestamp, activeArraySize);
+}
+
+int ExternalCameraDeviceSession::configureV4l2StreamLocked(const SupportedV4L2Format& v4l2Fmt,
+ double requestFps) {
+ ATRACE_CALL();
+ int ret = v4l2StreamOffLocked();
+ if (ret != OK) {
+ ALOGE("%s: stop v4l2 streaming failed: ret %d", __FUNCTION__, ret);
+ return ret;
+ }
+
+ // VIDIOC_S_FMT w/h/fmt
+ v4l2_format fmt;
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = v4l2Fmt.width;
+ fmt.fmt.pix.height = v4l2Fmt.height;
+ fmt.fmt.pix.pixelformat = v4l2Fmt.fourcc;
+
+ {
+ int numAttempt = 0;
+ do {
+ ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_FMT, &fmt));
+ if (numAttempt == MAX_RETRY) {
+ break;
+ }
+ numAttempt++;
+ if (ret < 0) {
+ ALOGW("%s: VIDIOC_S_FMT failed, wait 33ms and try again", __FUNCTION__);
+ usleep(IOCTL_RETRY_SLEEP_US); // sleep and try again
+ }
+ } while (ret < 0);
+ if (ret < 0) {
+ ALOGE("%s: S_FMT ioctl failed: %s", __FUNCTION__, strerror(errno));
+ return -errno;
+ }
+ }
+
+ if (v4l2Fmt.width != fmt.fmt.pix.width || v4l2Fmt.height != fmt.fmt.pix.height ||
+ v4l2Fmt.fourcc != fmt.fmt.pix.pixelformat) {
+ ALOGE("%s: S_FMT expect %c%c%c%c %dx%d, got %c%c%c%c %dx%d instead!", __FUNCTION__,
+ v4l2Fmt.fourcc & 0xFF, (v4l2Fmt.fourcc >> 8) & 0xFF, (v4l2Fmt.fourcc >> 16) & 0xFF,
+ (v4l2Fmt.fourcc >> 24) & 0xFF, v4l2Fmt.width, v4l2Fmt.height,
+ fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,
+ (fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF,
+ fmt.fmt.pix.width, fmt.fmt.pix.height);
+ return -EINVAL;
+ }
+
+ uint32_t bufferSize = fmt.fmt.pix.sizeimage;
+ ALOGI("%s: V4L2 buffer size is %d", __FUNCTION__, bufferSize);
+ uint32_t expectedMaxBufferSize = kMaxBytesPerPixel * fmt.fmt.pix.width * fmt.fmt.pix.height;
+ if ((bufferSize == 0) || (bufferSize > expectedMaxBufferSize)) {
+ ALOGE("%s: V4L2 buffer size: %u looks invalid. Expected maximum size: %u", __FUNCTION__,
+ bufferSize, expectedMaxBufferSize);
+ return -EINVAL;
+ }
+ mMaxV4L2BufferSize = bufferSize;
+
+ const double kDefaultFps = 30.0;
+ double fps = std::numeric_limits<double>::max();
+ if (requestFps != 0.0) {
+ fps = requestFps;
+ } else {
+ double maxFps = -1.0;
+ // Try to pick the slowest fps that is at least 30
+ for (const auto& fr : v4l2Fmt.frameRates) {
+ double f = fr.getFramesPerSecond();
+ if (maxFps < f) {
+ maxFps = f;
+ }
+ if (f >= kDefaultFps && f < fps) {
+ fps = f;
+ }
+ }
+ // No fps > 30 found, use the highest fps available within supported formats.
+ if (fps == std::numeric_limits<double>::max()) {
+ fps = maxFps;
+ }
+ }
+
+ int fpsRet = setV4l2FpsLocked(fps);
+ if (fpsRet != 0 && fpsRet != -EINVAL) {
+ ALOGE("%s: set fps failed: %s", __FUNCTION__, strerror(fpsRet));
+ return fpsRet;
+ }
+
+ uint32_t v4lBufferCount = (fps >= kDefaultFps) ? mCfg.numVideoBuffers : mCfg.numStillBuffers;
+
+ // VIDIOC_REQBUFS: create buffers
+ v4l2_requestbuffers req_buffers{};
+ req_buffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ req_buffers.memory = V4L2_MEMORY_MMAP;
+ req_buffers.count = v4lBufferCount;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_REQBUFS, &req_buffers)) < 0) {
+ ALOGE("%s: VIDIOC_REQBUFS failed: %s", __FUNCTION__, strerror(errno));
+ return -errno;
+ }
+
+ // Driver can indeed return more buffer if it needs more to operate
+ if (req_buffers.count < v4lBufferCount) {
+ ALOGE("%s: VIDIOC_REQBUFS expected %d buffers, got %d instead", __FUNCTION__,
+ v4lBufferCount, req_buffers.count);
+ return NO_MEMORY;
+ }
+
+ // VIDIOC_QUERYBUF: get buffer offset in the V4L2 fd
+ // VIDIOC_QBUF: send buffer to driver
+ mV4L2BufferCount = req_buffers.count;
+ for (uint32_t i = 0; i < req_buffers.count; i++) {
+ v4l2_buffer buffer = {
+ .index = i, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, .memory = V4L2_MEMORY_MMAP};
+
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QUERYBUF, &buffer)) < 0) {
+ ALOGE("%s: QUERYBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
+ return -errno;
+ }
+
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+ ALOGE("%s: QBUF %d failed: %s", __FUNCTION__, i, strerror(errno));
+ return -errno;
+ }
+ }
+
+ {
+ // VIDIOC_STREAMON: start streaming
+ v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ int numAttempt = 0;
+ do {
+ ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMON, &capture_type));
+ if (numAttempt == MAX_RETRY) {
+ break;
+ }
+ if (ret < 0) {
+ ALOGW("%s: VIDIOC_STREAMON failed, wait 33ms and try again", __FUNCTION__);
+ usleep(IOCTL_RETRY_SLEEP_US); // sleep 100 ms and try again
+ }
+ } while (ret < 0);
+
+ if (ret < 0) {
+ ALOGE("%s: VIDIOC_STREAMON ioctl failed: %s", __FUNCTION__, strerror(errno));
+ return -errno;
+ }
+ }
+
+ // Swallow first few frames after streamOn to account for bad frames from some devices
+ for (int i = 0; i < kBadFramesAfterStreamOn; i++) {
+ v4l2_buffer buffer{};
+ buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
+ ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
+ return -errno;
+ }
+
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+ ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__, buffer.index, strerror(errno));
+ return -errno;
+ }
+ }
+
+ ALOGI("%s: start V4L2 streaming %dx%d@%ffps", __FUNCTION__, v4l2Fmt.width, v4l2Fmt.height, fps);
+ mV4l2StreamingFmt = v4l2Fmt;
+ mV4l2Streaming = true;
+ return OK;
+}
+
+std::unique_ptr<V4L2Frame> ExternalCameraDeviceSession::dequeueV4l2FrameLocked(nsecs_t* shutterTs) {
+ ATRACE_CALL();
+ std::unique_ptr<V4L2Frame> ret = nullptr;
+ if (shutterTs == nullptr) {
+ ALOGE("%s: shutterTs must not be null!", __FUNCTION__);
+ return ret;
+ }
+
+ {
+ std::unique_lock<std::mutex> lk(mV4l2BufferLock);
+ if (mNumDequeuedV4l2Buffers == mV4L2BufferCount) {
+ int waitRet = waitForV4L2BufferReturnLocked(lk);
+ if (waitRet != 0) {
+ return ret;
+ }
+ }
+ }
+
+ ATRACE_BEGIN("VIDIOC_DQBUF");
+ v4l2_buffer buffer{};
+ buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
+ ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
+ return ret;
+ }
+ ATRACE_END();
+
+ if (buffer.index >= mV4L2BufferCount) {
+ ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
+ return ret;
+ }
+
+ if (buffer.flags & V4L2_BUF_FLAG_ERROR) {
+ ALOGE("%s: v4l2 buf error! buf flag 0x%x", __FUNCTION__, buffer.flags);
+ // TODO: try to dequeue again
+ }
+
+ if (buffer.bytesused > mMaxV4L2BufferSize) {
+ ALOGE("%s: v4l2 buffer bytes used: %u maximum %u", __FUNCTION__, buffer.bytesused,
+ mMaxV4L2BufferSize);
+ return ret;
+ }
+
+ if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
+ // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
+ // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
+ *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec) * 1000000000LL +
+ buffer.timestamp.tv_usec * 1000LL;
+ } else {
+ *shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
+ }
+
+ {
+ std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+ mNumDequeuedV4l2Buffers++;
+ }
+
+ return std::make_unique<V4L2Frame>(mV4l2StreamingFmt.width, mV4l2StreamingFmt.height,
+ mV4l2StreamingFmt.fourcc, buffer.index, mV4l2Fd.get(),
+ buffer.bytesused, buffer.m.offset);
+}
+
+void ExternalCameraDeviceSession::enqueueV4l2Frame(const std::shared_ptr<V4L2Frame>& frame) {
+ ATRACE_CALL();
+ frame->unmap();
+ ATRACE_BEGIN("VIDIOC_QBUF");
+ v4l2_buffer buffer{};
+ buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ buffer.index = frame->mBufferIndex;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer)) < 0) {
+ ALOGE("%s: QBUF index %d fails: %s", __FUNCTION__, frame->mBufferIndex, strerror(errno));
+ return;
+ }
+ ATRACE_END();
+
+ {
+ std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+ mNumDequeuedV4l2Buffers--;
+ }
+ mV4L2BufferReturned.notify_one();
+}
+
+bool ExternalCameraDeviceSession::isSupported(
+ const Stream& stream, const std::vector<SupportedV4L2Format>& supportedFormats,
+ const ExternalCameraConfig& devCfg) {
+ Dataspace ds = stream.dataSpace;
+ PixelFormat fmt = stream.format;
+ uint32_t width = stream.width;
+ uint32_t height = stream.height;
+ // TODO: check usage flags
+
+ if (stream.streamType != StreamType::OUTPUT) {
+ ALOGE("%s: does not support non-output stream type", __FUNCTION__);
+ return false;
+ }
+
+ if (stream.rotation != StreamRotation::ROTATION_0) {
+ ALOGE("%s: does not support stream rotation", __FUNCTION__);
+ return false;
+ }
+
+ switch (fmt) {
+ case PixelFormat::BLOB:
+ if (ds != Dataspace::JFIF) {
+ ALOGI("%s: BLOB format does not support dataSpace %x", __FUNCTION__, ds);
+ return false;
+ }
+ break;
+ case PixelFormat::IMPLEMENTATION_DEFINED:
+ case PixelFormat::YCBCR_420_888:
+ case PixelFormat::YV12:
+ // TODO: check what dataspace we can support here.
+ // intentional no-ops.
+ break;
+ case PixelFormat::Y16:
+ if (!devCfg.depthEnabled) {
+ ALOGI("%s: Depth is not Enabled", __FUNCTION__);
+ return false;
+ }
+ if (!(static_cast<int32_t>(ds) & static_cast<int32_t>(Dataspace::DEPTH))) {
+ ALOGI("%s: Y16 supports only dataSpace DEPTH", __FUNCTION__);
+ return false;
+ }
+ break;
+ default:
+ ALOGI("%s: does not support format %x", __FUNCTION__, fmt);
+ return false;
+ }
+
+ // Assume we can convert any V4L2 format to any of supported output format for now, i.e.
+ // ignoring v4l2Fmt.fourcc for now. Might need more subtle check if we support more v4l format
+ // in the futrue.
+ for (const auto& v4l2Fmt : supportedFormats) {
+ if (width == v4l2Fmt.width && height == v4l2Fmt.height) {
+ return true;
+ }
+ }
+ ALOGI("%s: resolution %dx%d is not supported", __FUNCTION__, width, height);
+ return false;
+}
+
+Status ExternalCameraDeviceSession::importRequestLocked(const CaptureRequest& request,
+ std::vector<buffer_handle_t*>& allBufPtrs,
+ std::vector<int>& allFences) {
+ return importRequestLockedImpl(request, allBufPtrs, allFences);
+}
+
+Status ExternalCameraDeviceSession::importRequestLockedImpl(
+ const CaptureRequest& request, std::vector<buffer_handle_t*>& allBufPtrs,
+ std::vector<int>& allFences) {
+ size_t numOutputBufs = request.outputBuffers.size();
+ size_t numBufs = numOutputBufs;
+ // Validate all I/O buffers
+ std::vector<buffer_handle_t> allBufs;
+ std::vector<uint64_t> allBufIds;
+ allBufs.resize(numBufs);
+ allBufIds.resize(numBufs);
+ allBufPtrs.resize(numBufs);
+ allFences.resize(numBufs);
+ std::vector<int32_t> streamIds(numBufs);
+
+ for (size_t i = 0; i < numOutputBufs; i++) {
+ allBufs[i] = ::android::makeFromAidl(request.outputBuffers[i].buffer);
+ allBufIds[i] = request.outputBuffers[i].bufferId;
+ allBufPtrs[i] = &allBufs[i];
+ streamIds[i] = request.outputBuffers[i].streamId;
+ }
+
+ {
+ Mutex::Autolock _l(mCbsLock);
+ for (size_t i = 0; i < numBufs; i++) {
+ Status st = importBufferLocked(streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i]);
+ if (st != Status::OK) {
+ // Detailed error logs printed in importBuffer
+ return st;
+ }
+ }
+ }
+
+ // All buffers are imported. Now validate output buffer acquire fences
+ for (size_t i = 0; i < numOutputBufs; i++) {
+ if (!sHandleImporter.importFence(
+ ::android::makeFromAidl(request.outputBuffers[i].acquireFence), allFences[i])) {
+ ALOGE("%s: output buffer %zu acquire fence is invalid", __FUNCTION__, i);
+ cleanupInflightFences(allFences, i);
+ return Status::INTERNAL_ERROR;
+ }
+ }
+ return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::importBuffer(int32_t streamId, uint64_t bufId,
+ buffer_handle_t buf,
+ /*out*/ buffer_handle_t** outBufPtr) {
+ Mutex::Autolock _l(mCbsLock);
+ return importBufferLocked(streamId, bufId, buf, outBufPtr);
+}
+
+Status ExternalCameraDeviceSession::importBufferLocked(int32_t streamId, uint64_t bufId,
+ buffer_handle_t buf,
+ buffer_handle_t** outBufPtr) {
+ return importBufferImpl(mCirculatingBuffers, sHandleImporter, streamId, bufId, buf, outBufPtr);
+}
+
+ScopedAStatus ExternalCameraDeviceSession::close() {
+ close(false);
+ return fromStatus(Status::OK);
+}
+
+void ExternalCameraDeviceSession::close(bool callerIsDtor) {
+ Mutex::Autolock _il(mInterfaceLock);
+ bool closed = isClosed();
+ if (!closed) {
+ if (callerIsDtor) {
+ closeOutputThreadImpl();
+ } else {
+ closeOutputThread();
+ }
+
+ Mutex::Autolock _l(mLock);
+ // free all buffers
+ {
+ Mutex::Autolock _cbsl(mCbsLock);
+ for (auto pair : mStreamMap) {
+ cleanupBuffersLocked(/*Stream ID*/ pair.first);
+ }
+ }
+ v4l2StreamOffLocked();
+ ALOGV("%s: closing V4L2 camera FD %d", __FUNCTION__, mV4l2Fd.get());
+ mV4l2Fd.reset();
+ mClosed = true;
+ }
+}
+
+bool ExternalCameraDeviceSession::isClosed() {
+ Mutex::Autolock _l(mLock);
+ return mClosed;
+}
+
+ScopedAStatus ExternalCameraDeviceSession::repeatingRequestEnd(
+ int32_t /*in_frameNumber*/, const std::vector<int32_t>& /*in_streamIds*/) {
+ // TODO: Figure this one out.
+ return fromStatus(Status::OK);
+}
+
+int ExternalCameraDeviceSession::v4l2StreamOffLocked() {
+ if (!mV4l2Streaming) {
+ return OK;
+ }
+
+ {
+ std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+ if (mNumDequeuedV4l2Buffers != 0) {
+ ALOGE("%s: there are %zu inflight V4L buffers", __FUNCTION__, mNumDequeuedV4l2Buffers);
+ return -1;
+ }
+ }
+ mV4L2BufferCount = 0;
+
+ // VIDIOC_STREAMOFF
+ v4l2_buf_type capture_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_STREAMOFF, &capture_type)) < 0) {
+ ALOGE("%s: STREAMOFF failed: %s", __FUNCTION__, strerror(errno));
+ return -errno;
+ }
+
+ // VIDIOC_REQBUFS: clear buffers
+ v4l2_requestbuffers req_buffers{};
+ req_buffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ req_buffers.memory = V4L2_MEMORY_MMAP;
+ req_buffers.count = 0;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_REQBUFS, &req_buffers)) < 0) {
+ ALOGE("%s: REQBUFS failed: %s", __FUNCTION__, strerror(errno));
+ return -errno;
+ }
+
+ mV4l2Streaming = false;
+ return OK;
+}
+
+int ExternalCameraDeviceSession::setV4l2FpsLocked(double fps) {
+ // VIDIOC_G_PARM/VIDIOC_S_PARM: set fps
+ v4l2_streamparm streamparm = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
+ // The following line checks that the driver knows about framerate get/set.
+ int ret = TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_G_PARM, &streamparm));
+ if (ret != 0) {
+ if (errno == -EINVAL) {
+ ALOGW("%s: device does not support VIDIOC_G_PARM", __FUNCTION__);
+ }
+ return -errno;
+ }
+ // Now check if the device is able to accept a capture framerate set.
+ if (!(streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME)) {
+ ALOGW("%s: device does not support V4L2_CAP_TIMEPERFRAME", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ // fps is float, approximate by a fraction.
+ const int kFrameRatePrecision = 10000;
+ streamparm.parm.capture.timeperframe.numerator = kFrameRatePrecision;
+ streamparm.parm.capture.timeperframe.denominator = (fps * kFrameRatePrecision);
+
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_S_PARM, &streamparm)) < 0) {
+ ALOGE("%s: failed to set framerate to %f: %s", __FUNCTION__, fps, strerror(errno));
+ return -1;
+ }
+
+ double retFps = streamparm.parm.capture.timeperframe.denominator /
+ static_cast<double>(streamparm.parm.capture.timeperframe.numerator);
+ if (std::fabs(fps - retFps) > 1.0) {
+ ALOGE("%s: expect fps %f, got %f instead", __FUNCTION__, fps, retFps);
+ return -1;
+ }
+ mV4l2StreamingFps = fps;
+ return 0;
+}
+
+void ExternalCameraDeviceSession::cleanupInflightFences(std::vector<int>& allFences,
+ size_t numFences) {
+ for (size_t j = 0; j < numFences; j++) {
+ sHandleImporter.closeFence(allFences[j]);
+ }
+}
+
+void ExternalCameraDeviceSession::cleanupBuffersLocked(int id) {
+ for (auto& pair : mCirculatingBuffers.at(id)) {
+ sHandleImporter.freeBuffer(pair.second);
+ }
+ mCirculatingBuffers[id].clear();
+ mCirculatingBuffers.erase(id);
+}
+
+void ExternalCameraDeviceSession::notifyShutter(int32_t frameNumber, nsecs_t shutterTs) {
+ NotifyMsg msg;
+ msg.set<NotifyMsg::Tag::shutter>(ShutterMsg{
+ .frameNumber = frameNumber,
+ .timestamp = shutterTs,
+ });
+ mCallback->notify({msg});
+}
+void ExternalCameraDeviceSession::notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) {
+ NotifyMsg msg;
+ msg.set<NotifyMsg::Tag::error>(ErrorMsg{
+ .frameNumber = frameNumber,
+ .errorStreamId = streamId,
+ .errorCode = ec,
+ });
+ mCallback->notify({msg});
+}
+
+void ExternalCameraDeviceSession::invokeProcessCaptureResultCallback(
+ std::vector<CaptureResult>& results, bool tryWriteFmq) {
+ if (mProcessCaptureResultLock.tryLock() != OK) {
+ const nsecs_t NS_TO_SECOND = 1000000000;
+ ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
+ if (mProcessCaptureResultLock.timedLock(/* 1s */ NS_TO_SECOND) != OK) {
+ ALOGE("%s: cannot acquire lock in 1s, cannot proceed", __FUNCTION__);
+ return;
+ }
+ }
+ if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
+ for (CaptureResult& result : results) {
+ CameraMetadata& md = result.result;
+ if (!md.metadata.empty()) {
+ if (mResultMetadataQueue->write(reinterpret_cast<int8_t*>(md.metadata.data()),
+ md.metadata.size())) {
+ result.fmqResultSize = md.metadata.size();
+ md.metadata.resize(0);
+ } else {
+ ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
+ result.fmqResultSize = 0;
+ }
+ } else {
+ result.fmqResultSize = 0;
+ }
+ }
+ }
+ auto status = mCallback->processCaptureResult(results);
+ if (!status.isOk()) {
+ ALOGE("%s: processCaptureResult ERROR : %d:%d", __FUNCTION__, status.getExceptionCode(),
+ status.getServiceSpecificError());
+ }
+
+ mProcessCaptureResultLock.unlock();
+}
+
+int ExternalCameraDeviceSession::waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk) {
+ ATRACE_CALL();
+ auto timeout = std::chrono::seconds(kBufferWaitTimeoutSec);
+ mLock.unlock();
+ auto st = mV4L2BufferReturned.wait_for(lk, timeout);
+ // Here we introduce an order where mV4l2BufferLock is acquired before mLock, while
+ // the normal lock acquisition order is reversed. This is fine because in most of
+ // cases we are protected by mInterfaceLock. The only thread that can cause deadlock
+ // is the OutputThread, where we do need to make sure we don't acquire mLock then
+ // mV4l2BufferLock
+ mLock.lock();
+ if (st == std::cv_status::timeout) {
+ ALOGE("%s: wait for V4L2 buffer return timeout!", __FUNCTION__);
+ return -1;
+ }
+ return 0;
+}
+
+bool ExternalCameraDeviceSession::supportOfflineLocked(int32_t streamId) {
+ const Stream& stream = mStreamMap[streamId];
+ if (stream.format == PixelFormat::BLOB &&
+ static_cast<int32_t>(stream.dataSpace) == static_cast<int32_t>(Dataspace::JFIF)) {
+ return true;
+ }
+ // TODO: support YUV output stream?
+ return false;
+}
+
+bool ExternalCameraDeviceSession::canDropRequest(const std::vector<int32_t>& offlineStreams,
+ std::shared_ptr<HalRequest> halReq) {
+ for (const auto& buffer : halReq->buffers) {
+ for (auto offlineStreamId : offlineStreams) {
+ if (buffer.streamId == offlineStreamId) {
+ return false;
+ }
+ }
+ }
+ // Only drop a request completely if it has no offline output
+ return true;
+}
+
+void ExternalCameraDeviceSession::fillOfflineSessionInfo(
+ const std::vector<int32_t>& offlineStreams,
+ std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+ const std::map<int, CirculatingBuffers>& circulatingBuffers,
+ CameraOfflineSessionInfo* info) {
+ if (info == nullptr) {
+ ALOGE("%s: output info must not be null!", __FUNCTION__);
+ return;
+ }
+
+ info->offlineStreams.resize(offlineStreams.size());
+ info->offlineRequests.resize(offlineReqs.size());
+
+ // Fill in offline reqs and count outstanding buffers
+ for (size_t i = 0; i < offlineReqs.size(); i++) {
+ info->offlineRequests[i].frameNumber = offlineReqs[i]->frameNumber;
+ info->offlineRequests[i].pendingStreams.resize(offlineReqs[i]->buffers.size());
+ for (size_t bIdx = 0; bIdx < offlineReqs[i]->buffers.size(); bIdx++) {
+ int32_t streamId = offlineReqs[i]->buffers[bIdx].streamId;
+ info->offlineRequests[i].pendingStreams[bIdx] = streamId;
+ }
+ }
+
+ for (size_t i = 0; i < offlineStreams.size(); i++) {
+ int32_t streamId = offlineStreams[i];
+ info->offlineStreams[i].id = streamId;
+ // outstanding buffers are 0 since we are doing hal buffer management and
+ // offline session will ask for those buffers later
+ info->offlineStreams[i].numOutstandingBuffers = 0;
+ const CirculatingBuffers& bufIdMap = circulatingBuffers.at(streamId);
+ info->offlineStreams[i].circulatingBufferIds.resize(bufIdMap.size());
+ size_t bIdx = 0;
+ for (const auto& pair : bufIdMap) {
+ // Fill in bufferId
+ info->offlineStreams[i].circulatingBufferIds[bIdx++] = pair.first;
+ }
+ }
+}
+
+Status ExternalCameraDeviceSession::isStreamCombinationSupported(
+ const StreamConfiguration& config, const std::vector<SupportedV4L2Format>& supportedFormats,
+ const ExternalCameraConfig& devCfg) {
+ if (config.operationMode != StreamConfigurationMode::NORMAL_MODE) {
+ ALOGE("%s: unsupported operation mode: %d", __FUNCTION__, config.operationMode);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ if (config.streams.size() == 0) {
+ ALOGE("%s: cannot configure zero stream", __FUNCTION__);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ int numProcessedStream = 0;
+ int numStallStream = 0;
+ for (const auto& stream : config.streams) {
+ // Check if the format/width/height combo is supported
+ if (!isSupported(stream, supportedFormats, devCfg)) {
+ return Status::ILLEGAL_ARGUMENT;
+ }
+ if (stream.format == PixelFormat::BLOB) {
+ numStallStream++;
+ } else {
+ numProcessedStream++;
+ }
+ }
+
+ if (numProcessedStream > kMaxProcessedStream) {
+ ALOGE("%s: too many processed streams (expect <= %d, got %d)", __FUNCTION__,
+ kMaxProcessedStream, numProcessedStream);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ if (numStallStream > kMaxStallStream) {
+ ALOGE("%s: too many stall streams (expect <= %d, got %d)", __FUNCTION__, kMaxStallStream,
+ numStallStream);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ return Status::OK;
+}
+void ExternalCameraDeviceSession::updateBufferCaches(
+ const std::vector<BufferCache>& cachesToRemove) {
+ Mutex::Autolock _l(mCbsLock);
+ for (auto& cache : cachesToRemove) {
+ auto cbsIt = mCirculatingBuffers.find(cache.streamId);
+ if (cbsIt == mCirculatingBuffers.end()) {
+ // The stream could have been removed
+ continue;
+ }
+ CirculatingBuffers& cbs = cbsIt->second;
+ auto it = cbs.find(cache.bufferId);
+ if (it != cbs.end()) {
+ sHandleImporter.freeBuffer(it->second);
+ cbs.erase(it);
+ } else {
+ ALOGE("%s: stream %d buffer %" PRIu64 " is not cached", __FUNCTION__, cache.streamId,
+ cache.bufferId);
+ }
+ }
+}
+
+Status ExternalCameraDeviceSession::processCaptureRequestError(
+ const std::shared_ptr<HalRequest>& req, std::vector<NotifyMsg>* outMsgs,
+ std::vector<CaptureResult>* outResults) {
+ ATRACE_CALL();
+ // Return V4L2 buffer to V4L2 buffer queue
+ std::shared_ptr<V4L2Frame> v4l2Frame = std::static_pointer_cast<V4L2Frame>(req->frameIn);
+ enqueueV4l2Frame(v4l2Frame);
+
+ if (outMsgs == nullptr) {
+ notifyShutter(req->frameNumber, req->shutterTs);
+ notifyError(/*frameNum*/ req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_REQUEST);
+ } else {
+ NotifyMsg shutter;
+ shutter.set<NotifyMsg::Tag::shutter>(
+ ShutterMsg{.frameNumber = req->frameNumber, .timestamp = req->shutterTs});
+
+ NotifyMsg error;
+ error.set<NotifyMsg::Tag::error>(ErrorMsg{.frameNumber = req->frameNumber,
+ .errorStreamId = -1,
+ .errorCode = ErrorCode::ERROR_REQUEST});
+ outMsgs->push_back(shutter);
+ outMsgs->push_back(error);
+ }
+
+ // Fill output buffers
+ CaptureResult result;
+ result.frameNumber = req->frameNumber;
+ result.partialResult = 1;
+ result.inputBuffer.streamId = -1;
+ result.outputBuffers.resize(req->buffers.size());
+ for (size_t i = 0; i < req->buffers.size(); i++) {
+ result.outputBuffers[i].streamId = req->buffers[i].streamId;
+ result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
+ result.outputBuffers[i].status = BufferStatus::ERROR;
+ if (req->buffers[i].acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+ }
+ }
+
+ // update inflight records
+ {
+ std::lock_guard<std::mutex> lk(mInflightFramesLock);
+ mInflightFrames.erase(req->frameNumber);
+ }
+
+ if (outResults == nullptr) {
+ // Callback into framework
+ std::vector<CaptureResult> results(1);
+ results[0] = std::move(result);
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+ freeReleaseFences(results);
+ } else {
+ outResults->push_back(std::move(result));
+ }
+ return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
+ ATRACE_CALL();
+ // Return V4L2 buffer to V4L2 buffer queue
+ std::shared_ptr<V4L2Frame> v4l2Frame = std::static_pointer_cast<V4L2Frame>(req->frameIn);
+ enqueueV4l2Frame(v4l2Frame);
+
+ // NotifyShutter
+ notifyShutter(req->frameNumber, req->shutterTs);
+
+ // Fill output buffers;
+ std::vector<CaptureResult> results(1);
+ CaptureResult& result = results[0];
+ result.frameNumber = req->frameNumber;
+ result.partialResult = 1;
+ result.inputBuffer.streamId = -1;
+ result.outputBuffers.resize(req->buffers.size());
+ for (size_t i = 0; i < req->buffers.size(); i++) {
+ result.outputBuffers[i].streamId = req->buffers[i].streamId;
+ result.outputBuffers[i].bufferId = req->buffers[i].bufferId;
+ if (req->buffers[i].fenceTimeout) {
+ result.outputBuffers[i].status = BufferStatus::ERROR;
+ if (req->buffers[i].acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+ }
+ notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
+ } else {
+ result.outputBuffers[i].status = BufferStatus::OK;
+ // TODO: refactor
+ if (req->buffers[i].acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ result.outputBuffers[i].releaseFence = ::android::makeToAidl(handle);
+ }
+ }
+ }
+
+ // Fill capture result metadata
+ fillCaptureResult(req->setting, req->shutterTs);
+ const camera_metadata_t* rawResult = req->setting.getAndLock();
+ convertToAidl(rawResult, &result.result);
+ req->setting.unlock(rawResult);
+
+ // update inflight records
+ {
+ std::lock_guard<std::mutex> lk(mInflightFramesLock);
+ mInflightFrames.erase(req->frameNumber);
+ }
+
+ // Callback into framework
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+ freeReleaseFences(results);
+ return Status::OK;
+}
+
+ssize_t ExternalCameraDeviceSession::getJpegBufferSize(int32_t width, int32_t height) const {
+ // Constant from camera3.h
+ const ssize_t kMinJpegBufferSize = 256 * 1024 + sizeof(CameraBlob);
+ // Get max jpeg size (area-wise).
+ if (mMaxJpegResolution.width == 0) {
+ ALOGE("%s: No supported JPEG stream", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ // Get max jpeg buffer size
+ ssize_t maxJpegBufferSize = 0;
+ camera_metadata_ro_entry jpegBufMaxSize = mCameraCharacteristics.find(ANDROID_JPEG_MAX_SIZE);
+ if (jpegBufMaxSize.count == 0) {
+ ALOGE("%s: Can't find maximum JPEG size in static metadata!", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
+
+ if (maxJpegBufferSize <= kMinJpegBufferSize) {
+ ALOGE("%s: ANDROID_JPEG_MAX_SIZE (%zd) <= kMinJpegBufferSize (%zd)", __FUNCTION__,
+ maxJpegBufferSize, kMinJpegBufferSize);
+ return BAD_VALUE;
+ }
+
+ // Calculate final jpeg buffer size for the given resolution.
+ float scaleFactor =
+ ((float)(width * height)) / (mMaxJpegResolution.width * mMaxJpegResolution.height);
+ ssize_t jpegBufferSize =
+ scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) + kMinJpegBufferSize;
+ if (jpegBufferSize > maxJpegBufferSize) {
+ jpegBufferSize = maxJpegBufferSize;
+ }
+
+ return jpegBufferSize;
+}
+binder_status_t ExternalCameraDeviceSession::dump(int fd, const char** /*args*/,
+ uint32_t /*numArgs*/) {
+ bool intfLocked = tryLock(mInterfaceLock);
+ if (!intfLocked) {
+ dprintf(fd, "!! ExternalCameraDeviceSession interface may be deadlocked !!\n");
+ }
+
+ if (isClosed()) {
+ dprintf(fd, "External camera %s is closed\n", mCameraId.c_str());
+ return STATUS_OK;
+ }
+
+ bool streaming = false;
+ size_t v4L2BufferCount = 0;
+ SupportedV4L2Format streamingFmt;
+ {
+ bool sessionLocked = tryLock(mLock);
+ if (!sessionLocked) {
+ dprintf(fd, "!! ExternalCameraDeviceSession mLock may be deadlocked !!\n");
+ }
+ streaming = mV4l2Streaming;
+ streamingFmt = mV4l2StreamingFmt;
+ v4L2BufferCount = mV4L2BufferCount;
+
+ if (sessionLocked) {
+ mLock.unlock();
+ }
+ }
+
+ std::unordered_set<uint32_t> inflightFrames;
+ {
+ bool iffLocked = tryLock(mInflightFramesLock);
+ if (!iffLocked) {
+ dprintf(fd,
+ "!! ExternalCameraDeviceSession mInflightFramesLock may be deadlocked !!\n");
+ }
+ inflightFrames = mInflightFrames;
+ if (iffLocked) {
+ mInflightFramesLock.unlock();
+ }
+ }
+
+ dprintf(fd, "External camera %s V4L2 FD %d, cropping type %s, %s\n", mCameraId.c_str(),
+ mV4l2Fd.get(), (mCroppingType == VERTICAL) ? "vertical" : "horizontal",
+ streaming ? "streaming" : "not streaming");
+
+ if (streaming) {
+ // TODO: dump fps later
+ dprintf(fd, "Current V4L2 format %c%c%c%c %dx%d @ %ffps\n", streamingFmt.fourcc & 0xFF,
+ (streamingFmt.fourcc >> 8) & 0xFF, (streamingFmt.fourcc >> 16) & 0xFF,
+ (streamingFmt.fourcc >> 24) & 0xFF, streamingFmt.width, streamingFmt.height,
+ mV4l2StreamingFps);
+
+ size_t numDequeuedV4l2Buffers = 0;
+ {
+ std::lock_guard<std::mutex> lk(mV4l2BufferLock);
+ numDequeuedV4l2Buffers = mNumDequeuedV4l2Buffers;
+ }
+ dprintf(fd, "V4L2 buffer queue size %zu, dequeued %zu\n", v4L2BufferCount,
+ numDequeuedV4l2Buffers);
+ }
+
+ dprintf(fd, "In-flight frames (not sorted):");
+ for (const auto& frameNumber : inflightFrames) {
+ dprintf(fd, "%d, ", frameNumber);
+ }
+ dprintf(fd, "\n");
+ mOutputThread->dump(fd);
+ dprintf(fd, "\n");
+
+ if (intfLocked) {
+ mInterfaceLock.unlock();
+ }
+
+ return STATUS_OK;
+}
+
+// Start ExternalCameraDeviceSession::BufferRequestThread functions
+ExternalCameraDeviceSession::BufferRequestThread::BufferRequestThread(
+ std::weak_ptr<OutputThreadInterface> parent,
+ std::shared_ptr<ICameraDeviceCallback> callbacks)
+ : mParent(parent), mCallbacks(callbacks) {}
+
+int ExternalCameraDeviceSession::BufferRequestThread::requestBufferStart(
+ const std::vector<HalStreamBuffer>& bufReqs) {
+ if (bufReqs.empty()) {
+ ALOGE("%s: bufReqs is empty!", __FUNCTION__);
+ return -1;
+ }
+
+ {
+ std::lock_guard<std::mutex> lk(mLock);
+ if (mRequestingBuffer) {
+ ALOGE("%s: BufferRequestThread does not support more than one concurrent request!",
+ __FUNCTION__);
+ return -1;
+ }
+
+ mBufferReqs = bufReqs;
+ mRequestingBuffer = true;
+ }
+ mRequestCond.notify_one();
+ return 0;
+}
+
+int ExternalCameraDeviceSession::BufferRequestThread::waitForBufferRequestDone(
+ std::vector<HalStreamBuffer>* outBufReqs) {
+ std::unique_lock<std::mutex> lk(mLock);
+ if (!mRequestingBuffer) {
+ ALOGE("%s: no pending buffer request!", __FUNCTION__);
+ return -1;
+ }
+
+ if (mPendingReturnBufferReqs.empty()) {
+ std::chrono::milliseconds timeout = std::chrono::milliseconds(kReqProcTimeoutMs);
+ auto st = mRequestDoneCond.wait_for(lk, timeout);
+ if (st == std::cv_status::timeout) {
+ ALOGE("%s: wait for buffer request finish timeout!", __FUNCTION__);
+ return -1;
+ }
+ }
+ mRequestingBuffer = false;
+ *outBufReqs = std::move(mPendingReturnBufferReqs);
+ mPendingReturnBufferReqs.clear();
+ return 0;
+}
+
+void ExternalCameraDeviceSession::BufferRequestThread::waitForNextRequest() {
+ ATRACE_CALL();
+ std::unique_lock<std::mutex> lk(mLock);
+ int waitTimes = 0;
+ while (mBufferReqs.empty()) {
+ if (exitPending()) {
+ return;
+ }
+ auto timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
+ auto st = mRequestCond.wait_for(lk, timeout);
+ if (st == std::cv_status::timeout) {
+ waitTimes++;
+ if (waitTimes == kReqWaitTimesWarn) {
+ // BufferRequestThread just wait forever for new buffer request
+ // But it will print some periodic warning indicating it's waiting
+ ALOGV("%s: still waiting for new buffer request", __FUNCTION__);
+ waitTimes = 0;
+ }
+ }
+ }
+
+ // Fill in BufferRequest
+ mHalBufferReqs.resize(mBufferReqs.size());
+ for (size_t i = 0; i < mHalBufferReqs.size(); i++) {
+ mHalBufferReqs[i].streamId = mBufferReqs[i].streamId;
+ mHalBufferReqs[i].numBuffersRequested = 1;
+ }
+}
+
+bool ExternalCameraDeviceSession::BufferRequestThread::threadLoop() {
+ waitForNextRequest();
+ if (exitPending()) {
+ return false;
+ }
+
+ ATRACE_BEGIN("AIDL requestStreamBuffers");
+ BufferRequestStatus status;
+ std::vector<StreamBufferRet> bufRets;
+ ScopedAStatus ret = mCallbacks->requestStreamBuffers(mHalBufferReqs, &bufRets, &status);
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error: %d:%d", __FUNCTION__, ret.getExceptionCode(),
+ ret.getServiceSpecificError());
+ return false;
+ }
+
+ std::unique_lock<std::mutex> lk(mLock);
+ if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) {
+ if (bufRets.size() != mHalBufferReqs.size()) {
+ ALOGE("%s: expect %zu buffer requests returned, only got %zu", __FUNCTION__,
+ mHalBufferReqs.size(), bufRets.size());
+ return false;
+ }
+
+ auto parent = mParent.lock();
+ if (parent == nullptr) {
+ ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ return false;
+ }
+
+ std::vector<int> importedFences;
+ importedFences.resize(bufRets.size());
+ for (size_t i = 0; i < bufRets.size(); i++) {
+ int streamId = bufRets[i].streamId;
+ switch (bufRets[i].val.getTag()) {
+ case StreamBuffersVal::Tag::error:
+ continue;
+ case StreamBuffersVal::Tag::buffers: {
+ const std::vector<StreamBuffer>& hBufs =
+ bufRets[i].val.get<StreamBuffersVal::Tag::buffers>();
+ if (hBufs.size() != 1) {
+ ALOGE("%s: expect 1 buffer returned, got %zu!", __FUNCTION__, hBufs.size());
+ return false;
+ }
+ const StreamBuffer& hBuf = hBufs[0];
+
+ mBufferReqs[i].bufferId = hBuf.bufferId;
+ // TODO: create a batch import API so we don't need to lock/unlock mCbsLock
+ // repeatedly?
+ lk.unlock();
+ Status s =
+ parent->importBuffer(streamId, hBuf.bufferId, makeFromAidl(hBuf.buffer),
+ /*out*/ &mBufferReqs[i].bufPtr);
+ lk.lock();
+
+ if (s != Status::OK) {
+ ALOGE("%s: stream %d import buffer failed!", __FUNCTION__, streamId);
+ cleanupInflightFences(importedFences, i - 1);
+ return false;
+ }
+ if (!sHandleImporter.importFence(makeFromAidl(hBuf.acquireFence),
+ mBufferReqs[i].acquireFence)) {
+ ALOGE("%s: stream %d import fence failed!", __FUNCTION__, streamId);
+ cleanupInflightFences(importedFences, i - 1);
+ return false;
+ }
+ importedFences[i] = mBufferReqs[i].acquireFence;
+ } break;
+ default:
+ ALOGE("%s: Unknown StreamBuffersVal!", __FUNCTION__);
+ return false;
+ }
+ }
+ } else {
+ ALOGE("%s: requestStreamBuffers call failed!", __FUNCTION__);
+ }
+
+ mPendingReturnBufferReqs = std::move(mBufferReqs);
+ mBufferReqs.clear();
+
+ lk.unlock();
+ mRequestDoneCond.notify_one();
+ return true;
+}
+
+// End ExternalCameraDeviceSession::BufferRequestThread functions
+
+// Start ExternalCameraDeviceSession::OutputThread functions
+
+ExternalCameraDeviceSession::OutputThread::OutputThread(
+ std::weak_ptr<OutputThreadInterface> parent, CroppingType ct,
+ const common::V1_0::helper::CameraMetadata& chars,
+ std::shared_ptr<BufferRequestThread> bufReqThread)
+ : mParent(parent),
+ mCroppingType(ct),
+ mCameraCharacteristics(chars),
+ mBufferRequestThread(bufReqThread) {}
+
+ExternalCameraDeviceSession::OutputThread::~OutputThread() {}
+
+Status ExternalCameraDeviceSession::OutputThread::allocateIntermediateBuffers(
+ const Size& v4lSize, const Size& thumbSize, const std::vector<Stream>& streams,
+ uint32_t blobBufferSize) {
+ std::lock_guard<std::mutex> lk(mBufferLock);
+ if (!mScaledYu12Frames.empty()) {
+ ALOGE("%s: intermediate buffer pool has %zu inflight buffers! (expect 0)", __FUNCTION__,
+ mScaledYu12Frames.size());
+ return Status::INTERNAL_ERROR;
+ }
+
+ // Allocating intermediate YU12 frame
+ if (mYu12Frame == nullptr || mYu12Frame->mWidth != v4lSize.width ||
+ mYu12Frame->mHeight != v4lSize.height) {
+ mYu12Frame.reset();
+ mYu12Frame = std::make_shared<AllocatedFrame>(v4lSize.width, v4lSize.height);
+ int ret = mYu12Frame->allocate(&mYu12FrameLayout);
+ if (ret != 0) {
+ ALOGE("%s: allocating YU12 frame failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+ }
+
+ // Allocating intermediate YU12 thumbnail frame
+ if (mYu12ThumbFrame == nullptr || mYu12ThumbFrame->mWidth != thumbSize.width ||
+ mYu12ThumbFrame->mHeight != thumbSize.height) {
+ mYu12ThumbFrame.reset();
+ mYu12ThumbFrame = std::make_shared<AllocatedFrame>(thumbSize.width, thumbSize.height);
+ int ret = mYu12ThumbFrame->allocate(&mYu12ThumbFrameLayout);
+ if (ret != 0) {
+ ALOGE("%s: allocating YU12 thumb frame failed!", __FUNCTION__);
+ return Status::INTERNAL_ERROR;
+ }
+ }
+
+ // Allocating scaled buffers
+ for (const auto& stream : streams) {
+ Size sz = {stream.width, stream.height};
+ if (sz == v4lSize) {
+ continue; // Don't need an intermediate buffer same size as v4lBuffer
+ }
+ if (mIntermediateBuffers.count(sz) == 0) {
+ // Create new intermediate buffer
+ std::shared_ptr<AllocatedFrame> buf =
+ std::make_shared<AllocatedFrame>(stream.width, stream.height);
+ int ret = buf->allocate();
+ if (ret != 0) {
+ ALOGE("%s: allocating intermediate YU12 frame %dx%d failed!", __FUNCTION__,
+ stream.width, stream.height);
+ return Status::INTERNAL_ERROR;
+ }
+ mIntermediateBuffers[sz] = buf;
+ }
+ }
+
+ // Remove unconfigured buffers
+ auto it = mIntermediateBuffers.begin();
+ while (it != mIntermediateBuffers.end()) {
+ bool configured = false;
+ auto sz = it->first;
+ for (const auto& stream : streams) {
+ if (stream.width == sz.width && stream.height == sz.height) {
+ configured = true;
+ break;
+ }
+ }
+ if (configured) {
+ it++;
+ } else {
+ it = mIntermediateBuffers.erase(it);
+ }
+ }
+
+ // Allocate mute test pattern frame
+ mMuteTestPatternFrame.resize(mYu12Frame->mWidth * mYu12Frame->mHeight * 3);
+
+ mBlobBufferSize = blobBufferSize;
+ return Status::OK;
+}
+
+Status ExternalCameraDeviceSession::OutputThread::submitRequest(
+ const std::shared_ptr<HalRequest>& req) {
+ std::unique_lock<std::mutex> lk(mRequestListLock);
+ mRequestList.push_back(req);
+ lk.unlock();
+ mRequestCond.notify_one();
+ return Status::OK;
+}
+
+void ExternalCameraDeviceSession::OutputThread::flush() {
+ ATRACE_CALL();
+ auto parent = mParent.lock();
+ if (parent == nullptr) {
+ ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ return;
+ }
+
+ std::unique_lock<std::mutex> lk(mRequestListLock);
+ std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList);
+ mRequestList.clear();
+ if (mProcessingRequest) {
+ auto timeout = std::chrono::seconds(kFlushWaitTimeoutSec);
+ auto st = mRequestDoneCond.wait_for(lk, timeout);
+ if (st == std::cv_status::timeout) {
+ ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
+ }
+ }
+
+ ALOGV("%s: flushing inflight requests", __FUNCTION__);
+ lk.unlock();
+ for (const auto& req : reqs) {
+ parent->processCaptureRequestError(req);
+ }
+}
+
+void ExternalCameraDeviceSession::OutputThread::dump(int fd) {
+ std::lock_guard<std::mutex> lk(mRequestListLock);
+ if (mProcessingRequest) {
+ dprintf(fd, "OutputThread processing frame %d\n", mProcessingFrameNumber);
+ } else {
+ dprintf(fd, "OutputThread not processing any frames\n");
+ }
+ dprintf(fd, "OutputThread request list contains frame: ");
+ for (const auto& req : mRequestList) {
+ dprintf(fd, "%d, ", req->frameNumber);
+ }
+ dprintf(fd, "\n");
+}
+
+void ExternalCameraDeviceSession::OutputThread::setExifMakeModel(const std::string& make,
+ const std::string& model) {
+ mExifMake = make;
+ mExifModel = model;
+}
+
+std::list<std::shared_ptr<HalRequest>>
+ExternalCameraDeviceSession::OutputThread::switchToOffline() {
+ ATRACE_CALL();
+ auto parent = mParent.lock();
+ if (parent == nullptr) {
+ ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ return {};
+ }
+
+ std::unique_lock<std::mutex> lk(mRequestListLock);
+ std::list<std::shared_ptr<HalRequest>> reqs = std::move(mRequestList);
+ mRequestList.clear();
+ if (mProcessingRequest) {
+ auto timeout = std::chrono::seconds(kFlushWaitTimeoutSec);
+ auto st = mRequestDoneCond.wait_for(lk, timeout);
+ if (st == std::cv_status::timeout) {
+ ALOGE("%s: wait for inflight request finish timeout!", __FUNCTION__);
+ }
+ }
+ lk.unlock();
+ clearIntermediateBuffers();
+ ALOGV("%s: returning %zu request for offline processing", __FUNCTION__, reqs.size());
+ return reqs;
+}
+
+int ExternalCameraDeviceSession::OutputThread::requestBufferStart(
+ const std::vector<HalStreamBuffer>& bufs) {
+ if (mBufferRequestThread == nullptr) {
+ return 0;
+ }
+ return mBufferRequestThread->requestBufferStart(bufs);
+}
+
+int ExternalCameraDeviceSession::OutputThread::waitForBufferRequestDone(
+ std::vector<HalStreamBuffer>* outBufs) {
+ if (mBufferRequestThread == nullptr) {
+ return 0;
+ }
+ return mBufferRequestThread->waitForBufferRequestDone(outBufs);
+}
+
+void ExternalCameraDeviceSession::OutputThread::waitForNextRequest(
+ std::shared_ptr<HalRequest>* out) {
+ ATRACE_CALL();
+ if (out == nullptr) {
+ ALOGE("%s: out is null", __FUNCTION__);
+ return;
+ }
+
+ std::unique_lock<std::mutex> lk(mRequestListLock);
+ int waitTimes = 0;
+ while (mRequestList.empty()) {
+ if (exitPending()) {
+ return;
+ }
+ auto timeout = std::chrono::milliseconds(kReqWaitTimeoutMs);
+ auto st = mRequestCond.wait_for(lk, timeout);
+ if (st == std::cv_status::timeout) {
+ waitTimes++;
+ if (waitTimes == kReqWaitTimesMax) {
+ // no new request, return
+ return;
+ }
+ }
+ }
+ *out = mRequestList.front();
+ mRequestList.pop_front();
+ mProcessingRequest = true;
+ mProcessingFrameNumber = (*out)->frameNumber;
+}
+
+void ExternalCameraDeviceSession::OutputThread::signalRequestDone() {
+ std::unique_lock<std::mutex> lk(mRequestListLock);
+ mProcessingRequest = false;
+ mProcessingFrameNumber = 0;
+ lk.unlock();
+ mRequestDoneCond.notify_one();
+}
+
+int ExternalCameraDeviceSession::OutputThread::cropAndScaleLocked(
+ std::shared_ptr<AllocatedFrame>& in, const Size& outSz, YCbCrLayout* out) {
+ Size inSz = {in->mWidth, in->mHeight};
+
+ int ret;
+ if (inSz == outSz) {
+ ret = in->getLayout(out);
+ if (ret != 0) {
+ ALOGE("%s: failed to get input image layout", __FUNCTION__);
+ return ret;
+ }
+ return ret;
+ }
+
+ // Cropping to output aspect ratio
+ IMapper::Rect inputCrop;
+ ret = getCropRect(mCroppingType, inSz, outSz, &inputCrop);
+ if (ret != 0) {
+ ALOGE("%s: failed to compute crop rect for output size %dx%d", __FUNCTION__, outSz.width,
+ outSz.height);
+ return ret;
+ }
+
+ YCbCrLayout croppedLayout;
+ ret = in->getCroppedLayout(inputCrop, &croppedLayout);
+ if (ret != 0) {
+ ALOGE("%s: failed to crop input image %dx%d to output size %dx%d", __FUNCTION__, inSz.width,
+ inSz.height, outSz.width, outSz.height);
+ return ret;
+ }
+
+ if ((mCroppingType == VERTICAL && inSz.width == outSz.width) ||
+ (mCroppingType == HORIZONTAL && inSz.height == outSz.height)) {
+ // No scale is needed
+ *out = croppedLayout;
+ return 0;
+ }
+
+ auto it = mScaledYu12Frames.find(outSz);
+ std::shared_ptr<AllocatedFrame> scaledYu12Buf;
+ if (it != mScaledYu12Frames.end()) {
+ scaledYu12Buf = it->second;
+ } else {
+ it = mIntermediateBuffers.find(outSz);
+ if (it == mIntermediateBuffers.end()) {
+ ALOGE("%s: failed to find intermediate buffer size %dx%d", __FUNCTION__, outSz.width,
+ outSz.height);
+ return -1;
+ }
+ scaledYu12Buf = it->second;
+ }
+ // Scale
+ YCbCrLayout outLayout;
+ ret = scaledYu12Buf->getLayout(&outLayout);
+ if (ret != 0) {
+ ALOGE("%s: failed to get output buffer layout", __FUNCTION__);
+ return ret;
+ }
+
+ ret = libyuv::I420Scale(
+ static_cast<uint8_t*>(croppedLayout.y), croppedLayout.yStride,
+ static_cast<uint8_t*>(croppedLayout.cb), croppedLayout.cStride,
+ static_cast<uint8_t*>(croppedLayout.cr), croppedLayout.cStride, inputCrop.width,
+ inputCrop.height, static_cast<uint8_t*>(outLayout.y), outLayout.yStride,
+ static_cast<uint8_t*>(outLayout.cb), outLayout.cStride,
+ static_cast<uint8_t*>(outLayout.cr), outLayout.cStride, outSz.width, outSz.height,
+ // TODO: b/72261744 see if we can use better filter without losing too much perf
+ libyuv::FilterMode::kFilterNone);
+
+ if (ret != 0) {
+ ALOGE("%s: failed to scale buffer from %dx%d to %dx%d. Ret %d", __FUNCTION__,
+ inputCrop.width, inputCrop.height, outSz.width, outSz.height, ret);
+ return ret;
+ }
+
+ *out = outLayout;
+ mScaledYu12Frames.insert({outSz, scaledYu12Buf});
+ return 0;
+}
+
+int ExternalCameraDeviceSession::OutputThread::cropAndScaleThumbLocked(
+ std::shared_ptr<AllocatedFrame>& in, const Size& outSz, YCbCrLayout* out) {
+ Size inSz{in->mWidth, in->mHeight};
+
+ if ((outSz.width * outSz.height) > (mYu12ThumbFrame->mWidth * mYu12ThumbFrame->mHeight)) {
+ ALOGE("%s: Requested thumbnail size too big (%d,%d) > (%d,%d)", __FUNCTION__, outSz.width,
+ outSz.height, mYu12ThumbFrame->mWidth, mYu12ThumbFrame->mHeight);
+ return -1;
+ }
+
+ int ret;
+
+ /* This will crop-and-zoom the input YUV frame to the thumbnail size
+ * Based on the following logic:
+ * 1) Square pixels come in, square pixels come out, therefore single
+ * scale factor is computed to either make input bigger or smaller
+ * depending on if we are upscaling or downscaling
+ * 2) That single scale factor would either make height too tall or width
+ * too wide so we need to crop the input either horizontally or vertically
+ * but not both
+ */
+
+ /* Convert the input and output dimensions into floats for ease of math */
+ float fWin = static_cast<float>(inSz.width);
+ float fHin = static_cast<float>(inSz.height);
+ float fWout = static_cast<float>(outSz.width);
+ float fHout = static_cast<float>(outSz.height);
+
+ /* Compute the one scale factor from (1) above, it will be the smaller of
+ * the two possibilities. */
+ float scaleFactor = std::min(fHin / fHout, fWin / fWout);
+
+ /* Since we are crop-and-zooming (as opposed to letter/pillar boxing) we can
+ * simply multiply the output by our scaleFactor to get the cropped input
+ * size. Note that at least one of {fWcrop, fHcrop} is going to wind up
+ * being {fWin, fHin} respectively because fHout or fWout cancels out the
+ * scaleFactor calculation above.
+ *
+ * Specifically:
+ * if ( fHin / fHout ) < ( fWin / fWout ) we crop the sides off
+ * input, in which case
+ * scaleFactor = fHin / fHout
+ * fWcrop = fHin / fHout * fWout
+ * fHcrop = fHin
+ *
+ * Note that fWcrop <= fWin ( because ( fHin / fHout ) * fWout < fWin, which
+ * is just the inequality above with both sides multiplied by fWout
+ *
+ * on the other hand if ( fWin / fWout ) < ( fHin / fHout) we crop the top
+ * and the bottom off of input, and
+ * scaleFactor = fWin / fWout
+ * fWcrop = fWin
+ * fHCrop = fWin / fWout * fHout
+ */
+ float fWcrop = scaleFactor * fWout;
+ float fHcrop = scaleFactor * fHout;
+
+ /* Convert to integer and truncate to an even number */
+ Size cropSz = {.width = 2 * static_cast<int32_t>(fWcrop / 2.0f),
+ .height = 2 * static_cast<int32_t>(fHcrop / 2.0f)};
+
+ /* Convert to a centered rectange with even top/left */
+ IMapper::Rect inputCrop{.left = 2 * static_cast<int32_t>((inSz.width - cropSz.width) / 4),
+ .top = 2 * static_cast<int32_t>((inSz.height - cropSz.height) / 4),
+ .width = static_cast<int32_t>(cropSz.width),
+ .height = static_cast<int32_t>(cropSz.height)};
+
+ if ((inputCrop.top < 0) || (inputCrop.top >= static_cast<int32_t>(inSz.height)) ||
+ (inputCrop.left < 0) || (inputCrop.left >= static_cast<int32_t>(inSz.width)) ||
+ (inputCrop.width <= 0) ||
+ (inputCrop.width + inputCrop.left > static_cast<int32_t>(inSz.width)) ||
+ (inputCrop.height <= 0) ||
+ (inputCrop.height + inputCrop.top > static_cast<int32_t>(inSz.height))) {
+ ALOGE("%s: came up with really wrong crop rectangle", __FUNCTION__);
+ ALOGE("%s: input layout %dx%d to for output size %dx%d", __FUNCTION__, inSz.width,
+ inSz.height, outSz.width, outSz.height);
+ ALOGE("%s: computed input crop +%d,+%d %dx%d", __FUNCTION__, inputCrop.left, inputCrop.top,
+ inputCrop.width, inputCrop.height);
+ return -1;
+ }
+
+ YCbCrLayout inputLayout;
+ ret = in->getCroppedLayout(inputCrop, &inputLayout);
+ if (ret != 0) {
+ ALOGE("%s: failed to crop input layout %dx%d to for output size %dx%d", __FUNCTION__,
+ inSz.width, inSz.height, outSz.width, outSz.height);
+ ALOGE("%s: computed input crop +%d,+%d %dx%d", __FUNCTION__, inputCrop.left, inputCrop.top,
+ inputCrop.width, inputCrop.height);
+ return ret;
+ }
+ ALOGV("%s: crop input layout %dx%d to for output size %dx%d", __FUNCTION__, inSz.width,
+ inSz.height, outSz.width, outSz.height);
+ ALOGV("%s: computed input crop +%d,+%d %dx%d", __FUNCTION__, inputCrop.left, inputCrop.top,
+ inputCrop.width, inputCrop.height);
+
+ // Scale
+ YCbCrLayout outFullLayout;
+
+ ret = mYu12ThumbFrame->getLayout(&outFullLayout);
+ if (ret != 0) {
+ ALOGE("%s: failed to get output buffer layout", __FUNCTION__);
+ return ret;
+ }
+
+ ret = libyuv::I420Scale(static_cast<uint8_t*>(inputLayout.y), inputLayout.yStride,
+ static_cast<uint8_t*>(inputLayout.cb), inputLayout.cStride,
+ static_cast<uint8_t*>(inputLayout.cr), inputLayout.cStride,
+ inputCrop.width, inputCrop.height,
+ static_cast<uint8_t*>(outFullLayout.y), outFullLayout.yStride,
+ static_cast<uint8_t*>(outFullLayout.cb), outFullLayout.cStride,
+ static_cast<uint8_t*>(outFullLayout.cr), outFullLayout.cStride,
+ outSz.width, outSz.height, libyuv::FilterMode::kFilterNone);
+
+ if (ret != 0) {
+ ALOGE("%s: failed to scale buffer from %dx%d to %dx%d. Ret %d", __FUNCTION__,
+ inputCrop.width, inputCrop.height, outSz.width, outSz.height, ret);
+ return ret;
+ }
+
+ *out = outFullLayout;
+ return 0;
+}
+
+int ExternalCameraDeviceSession::OutputThread::createJpegLocked(
+ HalStreamBuffer& halBuf, const common::V1_0::helper::CameraMetadata& setting) {
+ ATRACE_CALL();
+ int ret;
+ auto lfail = [&](auto... args) {
+ ALOGE(args...);
+
+ return 1;
+ };
+ auto parent = mParent.lock();
+ if (parent == nullptr) {
+ ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ return 1;
+ }
+
+ ALOGV("%s: HAL buffer sid: %d bid: %" PRIu64 " w: %u h: %u", __FUNCTION__, halBuf.streamId,
+ static_cast<uint64_t>(halBuf.bufferId), halBuf.width, halBuf.height);
+ ALOGV("%s: HAL buffer fmt: %x usage: %" PRIx64 " ptr: %p", __FUNCTION__, halBuf.format,
+ static_cast<uint64_t>(halBuf.usage), halBuf.bufPtr);
+ ALOGV("%s: YV12 buffer %d x %d", __FUNCTION__, mYu12Frame->mWidth, mYu12Frame->mHeight);
+
+ int jpegQuality, thumbQuality;
+ Size thumbSize;
+ bool outputThumbnail = true;
+
+ if (setting.exists(ANDROID_JPEG_QUALITY)) {
+ camera_metadata_ro_entry entry = setting.find(ANDROID_JPEG_QUALITY);
+ jpegQuality = entry.data.u8[0];
+ } else {
+ return lfail("%s: ANDROID_JPEG_QUALITY not set", __FUNCTION__);
+ }
+
+ if (setting.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) {
+ camera_metadata_ro_entry entry = setting.find(ANDROID_JPEG_THUMBNAIL_QUALITY);
+ thumbQuality = entry.data.u8[0];
+ } else {
+ return lfail("%s: ANDROID_JPEG_THUMBNAIL_QUALITY not set", __FUNCTION__);
+ }
+
+ if (setting.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) {
+ camera_metadata_ro_entry entry = setting.find(ANDROID_JPEG_THUMBNAIL_SIZE);
+ thumbSize = Size{.width = entry.data.i32[0], .height = entry.data.i32[1]};
+ if (thumbSize.width == 0 && thumbSize.height == 0) {
+ outputThumbnail = false;
+ }
+ } else {
+ return lfail("%s: ANDROID_JPEG_THUMBNAIL_SIZE not set", __FUNCTION__);
+ }
+
+ /* Cropped and scaled YU12 buffer for main and thumbnail */
+ YCbCrLayout yu12Main;
+ Size jpegSize{halBuf.width, halBuf.height};
+
+ /* Compute temporary buffer sizes accounting for the following:
+ * thumbnail can't exceed APP1 size of 64K
+ * main image needs to hold APP1, headers, and at most a poorly
+ * compressed image */
+ const ssize_t maxThumbCodeSize = 64 * 1024;
+ const ssize_t maxJpegCodeSize =
+ mBlobBufferSize == 0 ? parent->getJpegBufferSize(jpegSize.width, jpegSize.height)
+ : mBlobBufferSize;
+
+ /* Check that getJpegBufferSize did not return an error */
+ if (maxJpegCodeSize < 0) {
+ return lfail("%s: getJpegBufferSize returned %zd", __FUNCTION__, maxJpegCodeSize);
+ }
+
+ /* Hold actual thumbnail and main image code sizes */
+ size_t thumbCodeSize = 0, jpegCodeSize = 0;
+ /* Temporary thumbnail code buffer */
+ std::vector<uint8_t> thumbCode(outputThumbnail ? maxThumbCodeSize : 0);
+
+ YCbCrLayout yu12Thumb;
+ if (outputThumbnail) {
+ ret = cropAndScaleThumbLocked(mYu12Frame, thumbSize, &yu12Thumb);
+
+ if (ret != 0) {
+ return lfail("%s: crop and scale thumbnail failed!", __FUNCTION__);
+ }
+ }
+
+ /* Scale and crop main jpeg */
+ ret = cropAndScaleLocked(mYu12Frame, jpegSize, &yu12Main);
+
+ if (ret != 0) {
+ return lfail("%s: crop and scale main failed!", __FUNCTION__);
+ }
+
+ /* Encode the thumbnail image */
+ if (outputThumbnail) {
+ ret = encodeJpegYU12(thumbSize, yu12Thumb, thumbQuality, 0, 0, &thumbCode[0],
+ maxThumbCodeSize, thumbCodeSize);
+
+ if (ret != 0) {
+ return lfail("%s: thumbnail encodeJpegYU12 failed with %d", __FUNCTION__, ret);
+ }
+ }
+
+ /* Combine camera characteristics with request settings to form EXIF
+ * metadata */
+ common::V1_0::helper::CameraMetadata meta(mCameraCharacteristics);
+ meta.append(setting);
+
+ /* Generate EXIF object */
+ std::unique_ptr<ExifUtils> utils(ExifUtils::create());
+ /* Make sure it's initialized */
+ utils->initialize();
+
+ utils->setFromMetadata(meta, jpegSize.width, jpegSize.height);
+ utils->setMake(mExifMake);
+ utils->setModel(mExifModel);
+
+ ret = utils->generateApp1(outputThumbnail ? &thumbCode[0] : nullptr, thumbCodeSize);
+
+ if (!ret) {
+ return lfail("%s: generating APP1 failed", __FUNCTION__);
+ }
+
+ /* Get internal buffer */
+ size_t exifDataSize = utils->getApp1Length();
+ const uint8_t* exifData = utils->getApp1Buffer();
+
+ /* Lock the HAL jpeg code buffer */
+ void* bufPtr = sHandleImporter.lock(*(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage),
+ maxJpegCodeSize);
+
+ if (!bufPtr) {
+ return lfail("%s: could not lock %zu bytes", __FUNCTION__, maxJpegCodeSize);
+ }
+
+ /* Encode the main jpeg image */
+ ret = encodeJpegYU12(jpegSize, yu12Main, jpegQuality, exifData, exifDataSize, bufPtr,
+ maxJpegCodeSize, jpegCodeSize);
+
+ /* TODO: Not sure this belongs here, maybe better to pass jpegCodeSize out
+ * and do this when returning buffer to parent */
+ CameraBlob blob{CameraBlobId::JPEG, static_cast<int32_t>(jpegCodeSize)};
+ void* blobDst = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(bufPtr) + maxJpegCodeSize -
+ sizeof(CameraBlob));
+ memcpy(blobDst, &blob, sizeof(CameraBlob));
+
+ /* Unlock the HAL jpeg code buffer */
+ int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+ if (relFence >= 0) {
+ halBuf.acquireFence = relFence;
+ }
+
+ /* Check if our JPEG actually succeeded */
+ if (ret != 0) {
+ return lfail("%s: encodeJpegYU12 failed with %d", __FUNCTION__, ret);
+ }
+
+ ALOGV("%s: encoded JPEG (ret:%d) with Q:%d max size: %zu", __FUNCTION__, ret, jpegQuality,
+ maxJpegCodeSize);
+
+ return 0;
+}
+
+void ExternalCameraDeviceSession::OutputThread::clearIntermediateBuffers() {
+ std::lock_guard<std::mutex> lk(mBufferLock);
+ mYu12Frame.reset();
+ mYu12ThumbFrame.reset();
+ mIntermediateBuffers.clear();
+ mMuteTestPatternFrame.clear();
+ mBlobBufferSize = 0;
+}
+
+bool ExternalCameraDeviceSession::OutputThread::threadLoop() {
+ std::shared_ptr<HalRequest> req;
+ auto parent = mParent.lock();
+ if (parent == nullptr) {
+ ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ return false;
+ }
+
+ // TODO: maybe we need to setup a sensor thread to dq/enq v4l frames
+ // regularly to prevent v4l buffer queue filled with stale buffers
+ // when app doesn't program a preview request
+ waitForNextRequest(&req);
+ if (req == nullptr) {
+ // No new request, wait again
+ return true;
+ }
+
+ auto onDeviceError = [&](auto... args) {
+ ALOGE(args...);
+ parent->notifyError(req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_DEVICE);
+ signalRequestDone();
+ return false;
+ };
+
+ if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) {
+ return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
+ req->frameIn->mFourcc & 0xFF, (req->frameIn->mFourcc >> 8) & 0xFF,
+ (req->frameIn->mFourcc >> 16) & 0xFF,
+ (req->frameIn->mFourcc >> 24) & 0xFF);
+ }
+
+ int res = requestBufferStart(req->buffers);
+ if (res != 0) {
+ ALOGE("%s: send BufferRequest failed! res %d", __FUNCTION__, res);
+ return onDeviceError("%s: failed to send buffer request!", __FUNCTION__);
+ }
+
+ std::unique_lock<std::mutex> lk(mBufferLock);
+ // Convert input V4L2 frame to YU12 of the same size
+ // TODO: see if we can save some computation by converting to YV12 here
+ uint8_t* inData;
+ size_t inDataSize;
+ if (req->frameIn->getData(&inData, &inDataSize) != 0) {
+ lk.unlock();
+ return onDeviceError("%s: V4L2 buffer map failed", __FUNCTION__);
+ }
+
+ // Process camera mute state
+ auto testPatternMode = req->setting.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
+ if (testPatternMode.count == 1) {
+ if (mCameraMuted != (testPatternMode.data.u8[0] != ANDROID_SENSOR_TEST_PATTERN_MODE_OFF)) {
+ mCameraMuted = !mCameraMuted;
+ // Get solid color for test pattern, if any was set
+ if (testPatternMode.data.u8[0] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
+ auto entry = req->setting.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
+ if (entry.count == 4) {
+ // Update the mute frame if the pattern color has changed
+ if (memcmp(entry.data.i32, mTestPatternData, sizeof(mTestPatternData)) != 0) {
+ memcpy(mTestPatternData, entry.data.i32, sizeof(mTestPatternData));
+ // Fill the mute frame with the solid color, use only 8 MSB of RGGB as RGB
+ for (int i = 0; i < mMuteTestPatternFrame.size(); i += 3) {
+ mMuteTestPatternFrame[i] = entry.data.i32[0] >> 24;
+ mMuteTestPatternFrame[i + 1] = entry.data.i32[1] >> 24;
+ mMuteTestPatternFrame[i + 2] = entry.data.i32[3] >> 24;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // TODO: in some special case maybe we can decode jpg directly to gralloc output?
+ if (req->frameIn->mFourcc == V4L2_PIX_FMT_MJPEG) {
+ ATRACE_BEGIN("MJPGtoI420");
+ res = 0;
+ if (mCameraMuted) {
+ res = libyuv::ConvertToI420(
+ mMuteTestPatternFrame.data(), mMuteTestPatternFrame.size(),
+ static_cast<uint8_t*>(mYu12FrameLayout.y), mYu12FrameLayout.yStride,
+ static_cast<uint8_t*>(mYu12FrameLayout.cb), mYu12FrameLayout.cStride,
+ static_cast<uint8_t*>(mYu12FrameLayout.cr), mYu12FrameLayout.cStride, 0, 0,
+ mYu12Frame->mWidth, mYu12Frame->mHeight, mYu12Frame->mWidth,
+ mYu12Frame->mHeight, libyuv::kRotate0, libyuv::FOURCC_RAW);
+ } else {
+ res = libyuv::MJPGToI420(
+ inData, inDataSize, static_cast<uint8_t*>(mYu12FrameLayout.y),
+ mYu12FrameLayout.yStride, static_cast<uint8_t*>(mYu12FrameLayout.cb),
+ mYu12FrameLayout.cStride, static_cast<uint8_t*>(mYu12FrameLayout.cr),
+ mYu12FrameLayout.cStride, mYu12Frame->mWidth, mYu12Frame->mHeight,
+ mYu12Frame->mWidth, mYu12Frame->mHeight);
+ }
+ ATRACE_END();
+
+ if (res != 0) {
+ // For some webcam, the first few V4L2 frames might be malformed...
+ ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, res);
+ lk.unlock();
+ Status st = parent->processCaptureRequestError(req);
+ if (st != Status::OK) {
+ return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+ }
+ signalRequestDone();
+ return true;
+ }
+ }
+
+ ATRACE_BEGIN("Wait for BufferRequest done");
+ res = waitForBufferRequestDone(&req->buffers);
+ ATRACE_END();
+
+ if (res != 0) {
+ ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
+ lk.unlock();
+ return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
+ }
+
+ ALOGV("%s processing new request", __FUNCTION__);
+ const int kSyncWaitTimeoutMs = 500;
+ for (auto& halBuf : req->buffers) {
+ if (*(halBuf.bufPtr) == nullptr) {
+ ALOGW("%s: buffer for stream %d missing", __FUNCTION__, halBuf.streamId);
+ halBuf.fenceTimeout = true;
+ } else if (halBuf.acquireFence >= 0) {
+ int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
+ if (ret) {
+ halBuf.fenceTimeout = true;
+ } else {
+ ::close(halBuf.acquireFence);
+ halBuf.acquireFence = -1;
+ }
+ }
+
+ if (halBuf.fenceTimeout) {
+ continue;
+ }
+
+ // Gralloc lockYCbCr the buffer
+ switch (halBuf.format) {
+ case PixelFormat::BLOB: {
+ int ret = createJpegLocked(halBuf, req->setting);
+
+ if (ret != 0) {
+ lk.unlock();
+ return onDeviceError("%s: createJpegLocked failed with %d", __FUNCTION__, ret);
+ }
+ } break;
+ case PixelFormat::Y16: {
+ void* outLayout = sHandleImporter.lock(
+ *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), inDataSize);
+
+ std::memcpy(outLayout, inData, inDataSize);
+
+ int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+ if (relFence >= 0) {
+ halBuf.acquireFence = relFence;
+ }
+ } break;
+ case PixelFormat::YCBCR_420_888:
+ case PixelFormat::YV12: {
+ IMapper::Rect outRect{0, 0, static_cast<int32_t>(halBuf.width),
+ static_cast<int32_t>(halBuf.height)};
+ YCbCrLayout outLayout = sHandleImporter.lockYCbCr(
+ *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), outRect);
+ ALOGV("%s: outLayout y %p cb %p cr %p y_str %d c_str %d c_step %d", __FUNCTION__,
+ outLayout.y, outLayout.cb, outLayout.cr, outLayout.yStride, outLayout.cStride,
+ outLayout.chromaStep);
+
+ // Convert to output buffer size/format
+ uint32_t outputFourcc = getFourCcFromLayout(outLayout);
+ ALOGV("%s: converting to format %c%c%c%c", __FUNCTION__, outputFourcc & 0xFF,
+ (outputFourcc >> 8) & 0xFF, (outputFourcc >> 16) & 0xFF,
+ (outputFourcc >> 24) & 0xFF);
+
+ YCbCrLayout cropAndScaled;
+ ATRACE_BEGIN("cropAndScaleLocked");
+ int ret = cropAndScaleLocked(mYu12Frame, Size{halBuf.width, halBuf.height},
+ &cropAndScaled);
+ ATRACE_END();
+ if (ret != 0) {
+ lk.unlock();
+ return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
+ }
+
+ Size sz{halBuf.width, halBuf.height};
+ ATRACE_BEGIN("formatConvert");
+ ret = formatConvert(cropAndScaled, outLayout, sz, outputFourcc);
+ ATRACE_END();
+ if (ret != 0) {
+ lk.unlock();
+ return onDeviceError("%s: format conversion failed!", __FUNCTION__);
+ }
+ int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+ if (relFence >= 0) {
+ halBuf.acquireFence = relFence;
+ }
+ } break;
+ default:
+ lk.unlock();
+ return onDeviceError("%s: unknown output format %x", __FUNCTION__, halBuf.format);
+ }
+ } // for each buffer
+ mScaledYu12Frames.clear();
+
+ // Don't hold the lock while calling back to parent
+ lk.unlock();
+ Status st = parent->processCaptureResult(req);
+ if (st != Status::OK) {
+ return onDeviceError("%s: failed to process capture result!", __FUNCTION__);
+ }
+ signalRequestDone();
+ return true;
+}
+
+// End ExternalCameraDeviceSession::OutputThread functions
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/device/default/ExternalCameraDeviceSession.h b/camera/device/default/ExternalCameraDeviceSession.h
new file mode 100644
index 0000000..e7eb799
--- /dev/null
+++ b/camera/device/default/ExternalCameraDeviceSession.h
@@ -0,0 +1,398 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
+
+#include <ExternalCameraUtils.h>
+#include <SimpleThread.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
+#include <aidl/android/hardware/camera/device/BufferRequest.h>
+#include <aidl/android/hardware/camera/device/Stream.h>
+#include <android-base/unique_fd.h>
+#include <fmq/AidlMessageQueue.h>
+#include <utils/Thread.h>
+#include <deque>
+#include <list>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::BnCameraDeviceSession;
+using ::aidl::android::hardware::camera::device::BufferCache;
+using ::aidl::android::hardware::camera::device::BufferRequest;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
+using ::aidl::android::hardware::camera::device::CaptureRequest;
+using ::aidl::android::hardware::camera::device::HalStream;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::ICameraOfflineSession;
+using ::aidl::android::hardware::camera::device::RequestTemplate;
+using ::aidl::android::hardware::camera::device::Stream;
+using ::aidl::android::hardware::camera::device::StreamConfiguration;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::base::unique_fd;
+using ::android::hardware::camera::common::helper::SimpleThread;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::external::common::SizeHasher;
+using ::ndk::ScopedAStatus;
+
+class ExternalCameraDeviceSession : public BnCameraDeviceSession, public OutputThreadInterface {
+ public:
+ ExternalCameraDeviceSession(const std::shared_ptr<ICameraDeviceCallback>&,
+ const ExternalCameraConfig& cfg,
+ const std::vector<SupportedV4L2Format>& sortedFormats,
+ const CroppingType& croppingType,
+ const common::V1_0::helper::CameraMetadata& chars,
+ const std::string& cameraId, unique_fd v4l2Fd);
+ ~ExternalCameraDeviceSession() override;
+
+ // Caller must use this method to check if CameraDeviceSession ctor failed
+ bool isInitFailed();
+ bool isClosed();
+
+ ScopedAStatus close() override;
+
+ ScopedAStatus configureStreams(const StreamConfiguration& in_requestedConfiguration,
+ std::vector<HalStream>* _aidl_return) override;
+ ScopedAStatus constructDefaultRequestSettings(RequestTemplate in_type,
+ CameraMetadata* _aidl_return) override;
+ ScopedAStatus flush() override;
+ ScopedAStatus getCaptureRequestMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+ ScopedAStatus getCaptureResultMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+ ScopedAStatus isReconfigurationRequired(const CameraMetadata& in_oldSessionParams,
+ const CameraMetadata& in_newSessionParams,
+ bool* _aidl_return) override;
+ ScopedAStatus processCaptureRequest(const std::vector<CaptureRequest>& in_requests,
+ const std::vector<BufferCache>& in_cachesToRemove,
+ int32_t* _aidl_return) override;
+ ScopedAStatus signalStreamFlush(const std::vector<int32_t>& in_streamIds,
+ int32_t in_streamConfigCounter) override;
+ ScopedAStatus switchToOffline(const std::vector<int32_t>& in_streamsToKeep,
+ CameraOfflineSessionInfo* out_offlineSessionInfo,
+ std::shared_ptr<ICameraOfflineSession>* _aidl_return) override;
+ ScopedAStatus repeatingRequestEnd(int32_t in_frameNumber,
+ const std::vector<int32_t>& in_streamIds) override;
+
+ Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+ buffer_handle_t** outBufPtr) override;
+
+ void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) override;
+
+ Status processCaptureRequestError(const std::shared_ptr<HalRequest>& ptr,
+ std::vector<NotifyMsg>* msgs,
+ std::vector<CaptureResult>* results) override;
+
+ Status processCaptureResult(std::shared_ptr<HalRequest>& ptr) override;
+ ssize_t getJpegBufferSize(int32_t width, int32_t height) const override;
+
+ // Called by CameraDevice to dump active device states
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ static Status isStreamCombinationSupported(
+ const StreamConfiguration& config,
+ const std::vector<SupportedV4L2Format>& supportedFormats,
+ const ExternalCameraConfig& devCfg);
+
+ static const int kMaxProcessedStream = 2;
+ static const int kMaxStallStream = 1;
+ static const uint32_t kMaxBytesPerPixel = 2;
+
+ class BufferRequestThread : public SimpleThread {
+ public:
+ BufferRequestThread(std::weak_ptr<OutputThreadInterface> parent,
+ std::shared_ptr<ICameraDeviceCallback> callbacks);
+
+ int requestBufferStart(const std::vector<HalStreamBuffer>&);
+ int waitForBufferRequestDone(
+ /*out*/ std::vector<HalStreamBuffer>*);
+
+ bool threadLoop() override;
+
+ private:
+ void waitForNextRequest();
+
+ const std::weak_ptr<OutputThreadInterface> mParent;
+ const std::shared_ptr<ICameraDeviceCallback> mCallbacks;
+
+ std::mutex mLock;
+ bool mRequestingBuffer = false;
+
+ std::vector<HalStreamBuffer> mBufferReqs;
+ std::vector<HalStreamBuffer> mPendingReturnBufferReqs;
+ // mHalBufferReqs is not under mLock protection during the HIDL transaction
+ std::vector<BufferRequest> mHalBufferReqs;
+
+ // request buffers takes much less time in steady state, but can take much longer
+ // when requesting 1st buffer from a stream.
+ // TODO: consider a separate timeout for new vs. steady state?
+ // TODO: or make sure framework is warming up the pipeline during configure new stream?
+ static const int kReqProcTimeoutMs = 66;
+
+ static const int kReqWaitTimeoutMs = 33;
+ static const int kReqWaitTimesWarn = 90; // 33ms * 90 ~= 3 sec
+ std::condition_variable mRequestCond; // signaled when a new buffer request incoming
+ std::condition_variable mRequestDoneCond; // signaled when a request is done
+ };
+
+ class OutputThread : public SimpleThread {
+ public:
+ OutputThread(std::weak_ptr<OutputThreadInterface> parent, CroppingType,
+ const common::V1_0::helper::CameraMetadata&,
+ std::shared_ptr<BufferRequestThread> bufReqThread);
+ ~OutputThread();
+
+ Status allocateIntermediateBuffers(const Size& v4lSize, const Size& thumbSize,
+ const std::vector<Stream>& streams,
+ uint32_t blobBufferSize);
+ Status submitRequest(const std::shared_ptr<HalRequest>&);
+ void flush();
+ void dump(int fd);
+ bool threadLoop() override;
+
+ void setExifMakeModel(const std::string& make, const std::string& model);
+
+ // The remaining request list is returned for offline processing
+ std::list<std::shared_ptr<HalRequest>> switchToOffline();
+
+ protected:
+ static const int kFlushWaitTimeoutSec = 3; // 3 sec
+ static const int kReqWaitTimeoutMs = 33; // 33ms
+ static const int kReqWaitTimesMax = 90; // 33ms * 90 ~= 3 sec
+
+ // Methods to request output buffer in parallel
+ int requestBufferStart(const std::vector<HalStreamBuffer>&);
+ int waitForBufferRequestDone(
+ /*out*/ std::vector<HalStreamBuffer>*);
+
+ void waitForNextRequest(std::shared_ptr<HalRequest>* out);
+ void signalRequestDone();
+
+ int cropAndScaleLocked(std::shared_ptr<AllocatedFrame>& in, const Size& outSize,
+ YCbCrLayout* out);
+
+ int cropAndScaleThumbLocked(std::shared_ptr<AllocatedFrame>& in, const Size& outSize,
+ YCbCrLayout* out);
+
+ int createJpegLocked(HalStreamBuffer& halBuf,
+ const common::V1_0::helper::CameraMetadata& settings);
+
+ void clearIntermediateBuffers();
+
+ const std::weak_ptr<OutputThreadInterface> mParent;
+ const CroppingType mCroppingType;
+ const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
+
+ mutable std::mutex mRequestListLock; // Protect access to mRequestList,
+ // mProcessingRequest and mProcessingFrameNumber
+ std::condition_variable mRequestCond; // signaled when a new request is submitted
+ std::condition_variable mRequestDoneCond; // signaled when a request is done processing
+ std::list<std::shared_ptr<HalRequest>> mRequestList;
+ bool mProcessingRequest = false;
+ uint32_t mProcessingFrameNumber = 0;
+
+ // V4L2 frameIn
+ // (MJPG decode)-> mYu12Frame
+ // (Scale)-> mScaledYu12Frames
+ // (Format convert) -> output gralloc frames
+ mutable std::mutex mBufferLock; // Protect access to intermediate buffers
+ std::shared_ptr<AllocatedFrame> mYu12Frame;
+ std::shared_ptr<AllocatedFrame> mYu12ThumbFrame;
+ std::unordered_map<Size, std::shared_ptr<AllocatedFrame>, SizeHasher> mIntermediateBuffers;
+ std::unordered_map<Size, std::shared_ptr<AllocatedFrame>, SizeHasher> mScaledYu12Frames;
+ YCbCrLayout mYu12FrameLayout;
+ YCbCrLayout mYu12ThumbFrameLayout;
+ std::vector<uint8_t> mMuteTestPatternFrame;
+ uint32_t mTestPatternData[4] = {0, 0, 0, 0};
+ bool mCameraMuted = false;
+ uint32_t mBlobBufferSize = 0; // 0 -> HAL derive buffer size, else: use given size
+
+ std::string mExifMake;
+ std::string mExifModel;
+
+ const std::shared_ptr<BufferRequestThread> mBufferRequestThread;
+ };
+
+ private:
+ bool initialize();
+ // To init/close different version of output thread
+ void initOutputThread();
+ void closeOutputThread();
+ void closeOutputThreadImpl();
+
+ void close(bool callerIsDtor);
+ Status initStatus() const;
+ status_t initDefaultRequests();
+
+ status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
+ int configureV4l2StreamLocked(const SupportedV4L2Format& fmt, double fps = 0.0);
+ int v4l2StreamOffLocked();
+
+ int setV4l2FpsLocked(double fps);
+
+ std::unique_ptr<V4L2Frame> dequeueV4l2FrameLocked(
+ /*out*/ nsecs_t* shutterTs); // Called with mLock held
+
+ void enqueueV4l2Frame(const std::shared_ptr<V4L2Frame>&);
+
+ // Check if input Stream is one of supported stream setting on this device
+ static bool isSupported(const Stream& stream,
+ const std::vector<SupportedV4L2Format>& supportedFormats,
+ const ExternalCameraConfig& cfg);
+
+ // Validate and import request's output buffers and acquire fence
+ Status importRequestLocked(const CaptureRequest& request,
+ std::vector<buffer_handle_t*>& allBufPtrs,
+ std::vector<int>& allFences);
+
+ Status importRequestLockedImpl(const CaptureRequest& request,
+ std::vector<buffer_handle_t*>& allBufPtrs,
+ std::vector<int>& allFences);
+
+ Status importBufferLocked(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+ /*out*/ buffer_handle_t** outBufPtr);
+ static void cleanupInflightFences(std::vector<int>& allFences, size_t numFences);
+ void cleanupBuffersLocked(int id);
+
+ void updateBufferCaches(const std::vector<BufferCache>& cachesToRemove);
+
+ Status processOneCaptureRequest(const CaptureRequest& request);
+ void notifyShutter(int32_t frameNumber, nsecs_t shutterTs);
+
+ void invokeProcessCaptureResultCallback(std::vector<CaptureResult>& results, bool tryWriteFmq);
+ Size getMaxJpegResolution() const;
+
+ Size getMaxThumbResolution() const;
+
+ int waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk);
+
+ // Main body of switchToOffline. This method does not invoke any callbacks
+ // but instead returns the necessary callbacks in output arguments so callers
+ // can callback later without holding any locks
+ Status switchToOffline(const std::vector<int32_t>& offlineStreams,
+ /*out*/ std::vector<NotifyMsg>* msgs,
+ /*out*/ std::vector<CaptureResult>* results,
+ /*out*/ CameraOfflineSessionInfo* info,
+ /*out*/ std::shared_ptr<ICameraOfflineSession>* session);
+
+ bool supportOfflineLocked(int32_t streamId);
+
+ // Whether a request can be completely dropped when switching to offline
+ bool canDropRequest(const std::vector<int32_t>& offlineStreams,
+ std::shared_ptr<HalRequest> halReq);
+
+ void fillOfflineSessionInfo(const std::vector<int32_t>& offlineStreams,
+ std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+ const std::map<int, CirculatingBuffers>& circulatingBuffers,
+ /*out*/ CameraOfflineSessionInfo* info);
+
+ // Protect (most of) HIDL interface methods from synchronized-entering
+ mutable Mutex mInterfaceLock;
+
+ mutable Mutex mLock; // Protect all private members except otherwise noted
+ const std::shared_ptr<ICameraDeviceCallback> mCallback;
+ const ExternalCameraConfig& mCfg;
+ const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
+ const std::vector<SupportedV4L2Format> mSupportedFormats;
+ const CroppingType mCroppingType;
+ const std::string mCameraId;
+
+ // Not protected by mLock, this is almost a const.
+ // Setup in constructor, reset in close() after OutputThread is joined
+ unique_fd mV4l2Fd;
+
+ // device is closed either
+ // - closed by user
+ // - init failed
+ // - camera disconnected
+ bool mClosed = false;
+ bool mInitialized = false;
+ bool mInitFail = false;
+ bool mFirstRequest = false;
+ common::V1_0::helper::CameraMetadata mLatestReqSetting;
+
+ bool mV4l2Streaming = false;
+ SupportedV4L2Format mV4l2StreamingFmt;
+ double mV4l2StreamingFps = 0.0;
+ size_t mV4L2BufferCount = 0;
+
+ static const int kBufferWaitTimeoutSec = 3; // TODO: handle long exposure (or not allowing)
+ std::mutex mV4l2BufferLock; // protect the buffer count and condition below
+ std::condition_variable mV4L2BufferReturned;
+ size_t mNumDequeuedV4l2Buffers = 0;
+ uint32_t mMaxV4L2BufferSize = 0;
+
+ // Not protected by mLock (but might be used when mLock is locked)
+ std::shared_ptr<OutputThread> mOutputThread;
+
+ // Stream ID -> Stream cache
+ std::unordered_map<int, Stream> mStreamMap;
+
+ std::mutex mInflightFramesLock; // protect mInflightFrames
+ std::unordered_set<uint32_t> mInflightFrames;
+
+ // Stream ID -> circulating buffers map
+ std::map<int, CirculatingBuffers> mCirculatingBuffers;
+ // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
+ mutable Mutex mCbsLock;
+
+ std::mutex mAfTriggerLock; // protect mAfTrigger
+ bool mAfTrigger = false;
+
+ uint32_t mBlobBufferSize = 0;
+
+ static HandleImporter sHandleImporter;
+
+ std::shared_ptr<BufferRequestThread> mBufferRequestThread;
+
+ /* Beginning of members not changed after initialize() */
+ using RequestMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+ std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
+ using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+ std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
+ // Protect against invokeProcessCaptureResultCallback()
+ Mutex mProcessCaptureResultLock;
+
+ // tracks last seen stream config counter
+ int32_t mLastStreamConfigCounter = -1;
+
+ std::unordered_map<RequestTemplate, CameraMetadata> mDefaultRequests;
+
+ const Size mMaxThumbResolution;
+ const Size mMaxJpegResolution;
+
+ std::string mExifMake;
+ std::string mExifModel;
+ /* End of members not changed after initialize() */
+};
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
diff --git a/camera/device/default/ExternalCameraOfflineSession.cpp b/camera/device/default/ExternalCameraOfflineSession.cpp
new file mode 100644
index 0000000..4c7f732
--- /dev/null
+++ b/camera/device/default/ExternalCameraOfflineSession.cpp
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamOfflnSsn"
+#include <android/log.h>
+
+#include "ExternalCameraOfflineSession.h"
+
+#include <aidl/android/hardware/camera/device/BufferStatus.h>
+#include <aidl/android/hardware/camera/device/ErrorMsg.h>
+#include <aidl/android/hardware/camera/device/ShutterMsg.h>
+#include <aidl/android/hardware/camera/device/StreamBuffer.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <convert.h>
+#include <linux/videodev2.h>
+#include <sync/sync.h>
+#include <utils/Trace.h>
+
+#define HAVE_JPEG // required for libyuv.h to export MJPEG decode APIs
+#include <libyuv.h>
+
+namespace {
+
+// Size of request/result metadata fast message queue. Change to 0 to always use hwbinder buffer.
+constexpr size_t kMetadataMsgQueueSize = 1 << 18 /* 256kB */;
+
+} // anonymous namespace
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::device::BufferStatus;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::ShutterMsg;
+using ::aidl::android::hardware::camera::device::StreamBuffer;
+
+// Static instance
+HandleImporter ExternalCameraOfflineSession::sHandleImporter;
+
+ExternalCameraOfflineSession::ExternalCameraOfflineSession(
+ const CroppingType& croppingType, const common::V1_0::helper::CameraMetadata& chars,
+ const std::string& cameraId, const std::string& exifMake, const std::string& exifModel,
+ uint32_t blobBufferSize, bool afTrigger, const std::vector<Stream>& offlineStreams,
+ std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+ const std::map<int, CirculatingBuffers>& circulatingBuffers)
+ : mCroppingType(croppingType),
+ mChars(chars),
+ mCameraId(cameraId),
+ mExifMake(exifMake),
+ mExifModel(exifModel),
+ mBlobBufferSize(blobBufferSize),
+ mAfTrigger(afTrigger),
+ mOfflineStreams(offlineStreams),
+ mOfflineReqs(offlineReqs),
+ mCirculatingBuffers(circulatingBuffers) {}
+
+ExternalCameraOfflineSession::~ExternalCameraOfflineSession() {
+ close();
+}
+
+bool ExternalCameraOfflineSession::initialize() {
+ mResultMetadataQueue =
+ std::make_shared<ResultMetadataQueue>(kMetadataMsgQueueSize, false /* non blocking */);
+ if (!mResultMetadataQueue->isValid()) {
+ ALOGE("%s: invalid result fmq", __FUNCTION__);
+ return true;
+ }
+ return false;
+}
+
+Status ExternalCameraOfflineSession::importBuffer(int32_t streamId, uint64_t bufId,
+ buffer_handle_t buf,
+ buffer_handle_t** outBufPtr) {
+ Mutex::Autolock _l(mCbsLock);
+ return importBufferImpl(mCirculatingBuffers, sHandleImporter, streamId, bufId, buf, outBufPtr);
+}
+
+Status ExternalCameraOfflineSession::processCaptureResult(std::shared_ptr<HalRequest>& req) {
+ ATRACE_CALL();
+ // Fill output buffers
+ std::vector<CaptureResult> results;
+ results.resize(1);
+ CaptureResult& result = results[0];
+ result.frameNumber = req->frameNumber;
+ result.partialResult = 1;
+ result.inputBuffer.streamId = -1;
+ result.outputBuffers.resize(req->buffers.size());
+ for (size_t i = 0; i < req->buffers.size(); i++) {
+ StreamBuffer& outputBuffer = result.outputBuffers[i];
+ outputBuffer.streamId = req->buffers[i].streamId;
+ outputBuffer.bufferId = req->buffers[i].bufferId;
+ if (req->buffers[i].fenceTimeout) {
+ outputBuffer.status = BufferStatus::ERROR;
+ if (req->buffers[i].acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ result.outputBuffers[i].releaseFence = android::makeToAidl(handle);
+ }
+ notifyError(req->frameNumber, req->buffers[i].streamId, ErrorCode::ERROR_BUFFER);
+ } else {
+ result.outputBuffers[i].status = BufferStatus::OK;
+ // TODO: refactor
+ if (req->buffers[i].acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ outputBuffer.releaseFence = android::makeToAidl(handle);
+ }
+ }
+ }
+
+ // Fill capture result metadata
+ fillCaptureResult(req->setting, req->shutterTs);
+ const camera_metadata_t* rawResult = req->setting.getAndLock();
+ convertToAidl(rawResult, &result.result);
+ req->setting.unlock(rawResult);
+
+ // Callback into framework
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+ freeReleaseFences(results);
+ return Status::OK;
+}
+
+#define UPDATE(md, tag, data, size) \
+ do { \
+ if ((md).update((tag), (data), (size))) { \
+ ALOGE("Update " #tag " failed!"); \
+ return BAD_VALUE; \
+ } \
+ } while (0)
+
+status_t ExternalCameraOfflineSession::fillCaptureResult(common::V1_0::helper::CameraMetadata md,
+ nsecs_t timestamp) {
+ bool afTrigger = false;
+ {
+ std::lock_guard<std::mutex> lk(mAfTriggerLock);
+ afTrigger = mAfTrigger;
+ if (md.exists(ANDROID_CONTROL_AF_TRIGGER)) {
+ camera_metadata_entry entry = md.find(ANDROID_CONTROL_AF_TRIGGER);
+ if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_START) {
+ mAfTrigger = afTrigger = true;
+ } else if (entry.data.u8[0] == ANDROID_CONTROL_AF_TRIGGER_CANCEL) {
+ mAfTrigger = afTrigger = false;
+ }
+ }
+ }
+
+ // For USB camera, the USB camera handles everything and we don't have control
+ // over AF. We only simply fake the AF metadata based on the request
+ // received here.
+ uint8_t afState;
+ if (afTrigger) {
+ afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+ } else {
+ afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+ }
+ UPDATE(md, ANDROID_CONTROL_AF_STATE, &afState, 1);
+
+ camera_metadata_ro_entry activeArraySize = mChars.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+
+ return fillCaptureResultCommon(md, timestamp, activeArraySize);
+}
+void ExternalCameraOfflineSession::invokeProcessCaptureResultCallback(
+ std::vector<CaptureResult>& results, bool tryWriteFmq) {
+ if (mProcessCaptureResultLock.tryLock() != OK) {
+ const nsecs_t NS_TO_SECOND = 1E9;
+ ALOGV("%s: previous call is not finished! waiting 1s...", __FUNCTION__);
+ if (mProcessCaptureResultLock.timedLock(/* 1s */ NS_TO_SECOND) != OK) {
+ ALOGE("%s: cannot acquire lock in 1s, cannot proceed", __FUNCTION__);
+ return;
+ }
+ }
+ if (tryWriteFmq && mResultMetadataQueue->availableToWrite() > 0) {
+ for (CaptureResult& result : results) {
+ if (!result.result.metadata.empty()) {
+ if (mResultMetadataQueue->write(
+ reinterpret_cast<int8_t*>(result.result.metadata.data()),
+ result.result.metadata.size())) {
+ result.fmqResultSize = result.result.metadata.size();
+ result.result.metadata.clear();
+ } else {
+ ALOGW("%s: couldn't utilize fmq, fall back to hwbinder", __FUNCTION__);
+ result.fmqResultSize = 0;
+ }
+ } else {
+ result.fmqResultSize = 0;
+ }
+ }
+ }
+ auto status = mCallback->processCaptureResult(results);
+ if (!status.isOk()) {
+ ALOGE("%s: processCaptureResult ERROR : %d:%d", __FUNCTION__, status.getExceptionCode(),
+ status.getServiceSpecificError());
+ }
+
+ mProcessCaptureResultLock.unlock();
+}
+
+Status ExternalCameraOfflineSession::processCaptureRequestError(
+ const std::shared_ptr<HalRequest>& req, std::vector<NotifyMsg>* outMsgs,
+ std::vector<CaptureResult>* outResults) {
+ ATRACE_CALL();
+
+ if (outMsgs == nullptr) {
+ notifyError(/*frameNum*/ req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_REQUEST);
+ } else {
+ NotifyMsg shutter;
+ shutter.set<NotifyMsg::Tag::shutter>(ShutterMsg{
+ .frameNumber = req->frameNumber,
+ .timestamp = req->shutterTs,
+ });
+
+ NotifyMsg error;
+ error.set<NotifyMsg::Tag::error>(ErrorMsg{.frameNumber = req->frameNumber,
+ .errorStreamId = -1,
+ .errorCode = ErrorCode::ERROR_REQUEST});
+ outMsgs->push_back(shutter);
+ outMsgs->push_back(error);
+ }
+
+ // Fill output buffers
+ CaptureResult result;
+ result.frameNumber = req->frameNumber;
+ result.partialResult = 1;
+ result.inputBuffer.streamId = -1;
+ result.outputBuffers.resize(req->buffers.size());
+ for (size_t i = 0; i < req->buffers.size(); i++) {
+ StreamBuffer& outputBuffer = result.outputBuffers[i];
+ outputBuffer.streamId = req->buffers[i].streamId;
+ outputBuffer.bufferId = req->buffers[i].bufferId;
+ outputBuffer.status = BufferStatus::ERROR;
+ if (req->buffers[i].acquireFence >= 0) {
+ native_handle_t* handle = native_handle_create(/*numFds*/ 1, /*numInts*/ 0);
+ handle->data[0] = req->buffers[i].acquireFence;
+ outputBuffer.releaseFence = makeToAidl(handle);
+ }
+ }
+
+ if (outResults == nullptr) {
+ // Callback into framework
+ std::vector<CaptureResult> results(1);
+ results[0] = std::move(result);
+ invokeProcessCaptureResultCallback(results, /* tryWriteFmq */ true);
+ freeReleaseFences(results);
+ } else {
+ outResults->push_back(std::move(result));
+ }
+ return Status::OK;
+}
+
+ssize_t ExternalCameraOfflineSession::getJpegBufferSize(int32_t, int32_t) const {
+ // Empty implementation here as the jpeg buffer size is passed in by ctor
+ return 0;
+}
+
+void ExternalCameraOfflineSession::notifyError(int32_t frameNumber, int32_t streamId,
+ ErrorCode ec) {
+ NotifyMsg msg;
+ msg.set<NotifyMsg::Tag::error>(
+ ErrorMsg{.frameNumber = frameNumber, .errorStreamId = streamId, .errorCode = ec});
+ mCallback->notify({msg});
+}
+
+ScopedAStatus ExternalCameraOfflineSession::setCallback(
+ const std::shared_ptr<ICameraDeviceCallback>& in_cb) {
+ Mutex::Autolock _il(mInterfaceLock);
+ if (mCallback != nullptr && in_cb != nullptr) {
+ ALOGE("%s: callback must not be set twice!", __FUNCTION__);
+ return fromStatus(Status::OK);
+ }
+ mCallback = in_cb;
+
+ initOutputThread();
+
+ if (mOutputThread == nullptr) {
+ ALOGE("%s: init OutputThread failed!", __FUNCTION__);
+ }
+ return fromStatus(Status::OK);
+}
+void ExternalCameraOfflineSession::initOutputThread() {
+ if (mOutputThread != nullptr) {
+ ALOGE("%s: OutputThread already exist!", __FUNCTION__);
+ return;
+ }
+
+ // Grab a shared_ptr to 'this' from ndk::SharedRefBase::ref()
+ std::shared_ptr<ExternalCameraOfflineSession> thiz = ref<ExternalCameraOfflineSession>();
+
+ mBufferRequestThread = std::make_shared<ExternalCameraDeviceSession::BufferRequestThread>(
+ /*parent=*/thiz, mCallback);
+ mBufferRequestThread->run();
+
+ mOutputThread = std::make_shared<OutputThread>(/*parent=*/thiz, mCroppingType, mChars,
+ mBufferRequestThread, mOfflineReqs);
+
+ mOutputThread->setExifMakeModel(mExifMake, mExifModel);
+
+ Size inputSize = {mOfflineReqs[0]->frameIn->mWidth, mOfflineReqs[0]->frameIn->mHeight};
+ Size maxThumbSize = getMaxThumbnailResolution(mChars);
+ mOutputThread->allocateIntermediateBuffers(inputSize, maxThumbSize, mOfflineStreams,
+ mBlobBufferSize);
+
+ mOutputThread->run();
+}
+
+ScopedAStatus ExternalCameraOfflineSession::getCaptureResultMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
+ Mutex::Autolock _il(mInterfaceLock);
+ *_aidl_return = mResultMetadataQueue->dupeDesc();
+ return fromStatus(Status::OK);
+}
+
+ScopedAStatus ExternalCameraOfflineSession::close() {
+ Mutex::Autolock _il(mInterfaceLock);
+ {
+ Mutex::Autolock _l(mLock);
+ if (mClosed) {
+ ALOGW("%s: offline session already closed!", __FUNCTION__);
+ return fromStatus(Status::OK);
+ }
+ }
+ if (mBufferRequestThread != nullptr) {
+ mBufferRequestThread->requestExitAndWait();
+ mBufferRequestThread.reset();
+ }
+ if (mOutputThread) {
+ mOutputThread->flush();
+ mOutputThread->requestExitAndWait();
+ mOutputThread.reset();
+ }
+
+ Mutex::Autolock _l(mLock);
+ // free all buffers
+ {
+ Mutex::Autolock _cbl(mCbsLock);
+ for (auto& stream : mOfflineStreams) {
+ cleanupBuffersLocked(stream.id);
+ }
+ }
+ mCallback.reset();
+ mClosed = true;
+ return fromStatus(Status::OK);
+}
+void ExternalCameraOfflineSession::cleanupBuffersLocked(int32_t id) {
+ for (auto& pair : mCirculatingBuffers.at(id)) {
+ sHandleImporter.freeBuffer(pair.second);
+ }
+ mCirculatingBuffers[id].clear();
+ mCirculatingBuffers.erase(id);
+}
+
+bool ExternalCameraOfflineSession::OutputThread::threadLoop() {
+ auto parent = mParent.lock();
+ if (parent == nullptr) {
+ ALOGE("%s: session has been disconnected!", __FUNCTION__);
+ return false;
+ }
+
+ if (mOfflineReqs.empty()) {
+ ALOGI("%s: all offline requests are processed. Stopping.", __FUNCTION__);
+ return false;
+ }
+
+ std::shared_ptr<HalRequest> req = mOfflineReqs.front();
+ mOfflineReqs.pop_front();
+
+ auto onDeviceError = [&](auto... args) {
+ ALOGE(args...);
+ parent->notifyError(req->frameNumber, /*stream*/ -1, ErrorCode::ERROR_DEVICE);
+ signalRequestDone();
+ return false;
+ };
+
+ if (req->frameIn->mFourcc != V4L2_PIX_FMT_MJPEG && req->frameIn->mFourcc != V4L2_PIX_FMT_Z16) {
+ return onDeviceError("%s: do not support V4L2 format %c%c%c%c", __FUNCTION__,
+ req->frameIn->mFourcc & 0xFF, (req->frameIn->mFourcc >> 8) & 0xFF,
+ (req->frameIn->mFourcc >> 16) & 0xFF,
+ (req->frameIn->mFourcc >> 24) & 0xFF);
+ }
+
+ int res = requestBufferStart(req->buffers);
+ if (res != 0) {
+ ALOGE("%s: send BufferRequest failed! res %d", __FUNCTION__, res);
+ return onDeviceError("%s: failed to send buffer request!", __FUNCTION__);
+ }
+
+ std::unique_lock<std::mutex> lk(mBufferLock);
+ // Convert input V4L2 frame to YU12 of the same size
+ // TODO: see if we can save some computation by converting to YV12 here
+ uint8_t* inData;
+ size_t inDataSize;
+ if (req->frameIn->getData(&inData, &inDataSize) != 0) {
+ lk.unlock();
+ return onDeviceError("%s: V4L2 buffer map failed", __FUNCTION__);
+ }
+
+ // TODO: in some special case maybe we can decode jpg directly to gralloc output?
+ if (req->frameIn->mFourcc == V4L2_PIX_FMT_MJPEG) {
+ ATRACE_BEGIN("MJPGtoI420");
+ int convRes = libyuv::MJPGToI420(
+ inData, inDataSize, static_cast<uint8_t*>(mYu12FrameLayout.y),
+ mYu12FrameLayout.yStride, static_cast<uint8_t*>(mYu12FrameLayout.cb),
+ mYu12FrameLayout.cStride, static_cast<uint8_t*>(mYu12FrameLayout.cr),
+ mYu12FrameLayout.cStride, mYu12Frame->mWidth, mYu12Frame->mHeight,
+ mYu12Frame->mWidth, mYu12Frame->mHeight);
+ ATRACE_END();
+
+ if (convRes != 0) {
+ // For some webcam, the first few V4L2 frames might be malformed...
+ ALOGE("%s: Convert V4L2 frame to YU12 failed! res %d", __FUNCTION__, convRes);
+ lk.unlock();
+ Status st = parent->processCaptureRequestError(req);
+ if (st != Status::OK) {
+ return onDeviceError("%s: failed to process capture request error!", __FUNCTION__);
+ }
+ signalRequestDone();
+ return true;
+ }
+ }
+
+ ATRACE_BEGIN("Wait for BufferRequest done");
+ res = waitForBufferRequestDone(&req->buffers);
+ ATRACE_END();
+
+ if (res != 0) {
+ ALOGE("%s: wait for BufferRequest done failed! res %d", __FUNCTION__, res);
+ lk.unlock();
+ return onDeviceError("%s: failed to process buffer request error!", __FUNCTION__);
+ }
+
+ ALOGV("%s processing new request", __FUNCTION__);
+ const int kSyncWaitTimeoutMs = 500;
+ for (auto& halBuf : req->buffers) {
+ if (*(halBuf.bufPtr) == nullptr) {
+ ALOGW("%s: buffer for stream %d missing", __FUNCTION__, halBuf.streamId);
+ halBuf.fenceTimeout = true;
+ } else if (halBuf.acquireFence >= 0) {
+ int ret = sync_wait(halBuf.acquireFence, kSyncWaitTimeoutMs);
+ if (ret) {
+ halBuf.fenceTimeout = true;
+ } else {
+ ::close(halBuf.acquireFence);
+ halBuf.acquireFence = -1;
+ }
+ }
+
+ if (halBuf.fenceTimeout) {
+ continue;
+ }
+
+ // Gralloc lockYCbCr the buffer
+ switch (halBuf.format) {
+ case PixelFormat::BLOB: {
+ int ret = createJpegLocked(halBuf, req->setting);
+
+ if (ret != 0) {
+ lk.unlock();
+ return onDeviceError("%s: createJpegLocked failed with %d", __FUNCTION__, ret);
+ }
+ } break;
+ case PixelFormat::Y16: {
+ void* outLayout = sHandleImporter.lock(
+ *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), inDataSize);
+
+ std::memcpy(outLayout, inData, inDataSize);
+
+ int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+ if (relFence >= 0) {
+ halBuf.acquireFence = relFence;
+ }
+ } break;
+ case PixelFormat::YCBCR_420_888:
+ case PixelFormat::YV12: {
+ IMapper::Rect outRect{0, 0, static_cast<int32_t>(halBuf.width),
+ static_cast<int32_t>(halBuf.height)};
+ YCbCrLayout outLayout = sHandleImporter.lockYCbCr(
+ *(halBuf.bufPtr), static_cast<uint64_t>(halBuf.usage), outRect);
+ ALOGV("%s: outLayout y %p cb %p cr %p y_str %d c_str %d c_step %d", __FUNCTION__,
+ outLayout.y, outLayout.cb, outLayout.cr, outLayout.yStride, outLayout.cStride,
+ outLayout.chromaStep);
+
+ // Convert to output buffer size/format
+ uint32_t outputFourcc = getFourCcFromLayout(outLayout);
+ ALOGV("%s: converting to format %c%c%c%c", __FUNCTION__, outputFourcc & 0xFF,
+ (outputFourcc >> 8) & 0xFF, (outputFourcc >> 16) & 0xFF,
+ (outputFourcc >> 24) & 0xFF);
+
+ YCbCrLayout cropAndScaled;
+ ATRACE_BEGIN("cropAndScaleLocked");
+ int ret = cropAndScaleLocked(mYu12Frame, Size{halBuf.width, halBuf.height},
+ &cropAndScaled);
+ ATRACE_END();
+ if (ret != 0) {
+ lk.unlock();
+ return onDeviceError("%s: crop and scale failed!", __FUNCTION__);
+ }
+
+ Size sz{halBuf.width, halBuf.height};
+ ATRACE_BEGIN("formatConvert");
+ ret = formatConvert(cropAndScaled, outLayout, sz, outputFourcc);
+ ATRACE_END();
+ if (ret != 0) {
+ lk.unlock();
+ return onDeviceError("%s: format coversion failed!", __FUNCTION__);
+ }
+ int relFence = sHandleImporter.unlock(*(halBuf.bufPtr));
+ if (relFence >= 0) {
+ halBuf.acquireFence = relFence;
+ }
+ } break;
+ default:
+ lk.unlock();
+ return onDeviceError("%s: unknown output format %x", __FUNCTION__, halBuf.format);
+ }
+ } // for each buffer
+ mScaledYu12Frames.clear();
+
+ // Don't hold the lock while calling back to parent
+ lk.unlock();
+ Status st = parent->processCaptureResult(req);
+ if (st != Status::OK) {
+ return onDeviceError("%s: failed to process capture result!", __FUNCTION__);
+ }
+ signalRequestDone();
+ return true;
+}
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/camera/device/default/ExternalCameraOfflineSession.h b/camera/device/default/ExternalCameraOfflineSession.h
new file mode 100644
index 0000000..1d0c057
--- /dev/null
+++ b/camera/device/default/ExternalCameraOfflineSession.h
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAOFFLINESESSION_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAOFFLINESESSION_H_
+
+#include <ExternalCameraDeviceSession.h>
+#include <ExternalCameraUtils.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/BnCameraOfflineSession.h>
+#include <aidl/android/hardware/camera/device/Stream.h>
+#include <fmq/AidlMessageQueue.h>
+#include <utils/RefBase.h>
+#include <deque>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::BnCameraOfflineSession;
+using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::Stream;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+
+class ExternalCameraOfflineSession final : public BnCameraOfflineSession,
+ public virtual RefBase,
+ public virtual OutputThreadInterface {
+ public:
+ ExternalCameraOfflineSession(const CroppingType& croppingType,
+ const common::V1_0::helper::CameraMetadata& chars,
+ const std::string& cameraId, const std::string& exifMake,
+ const std::string& exifModel, uint32_t blobBufferSize,
+ bool afTrigger, const std::vector<Stream>& offlineStreams,
+ std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
+ const std::map<int, CirculatingBuffers>& circulatingBuffers);
+
+ ~ExternalCameraOfflineSession() override;
+
+ bool initialize();
+
+ // Methods from OutputThreadInterface
+ Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+ /*out*/ buffer_handle_t** outBufPtr) override;
+
+ Status processCaptureResult(std::shared_ptr<HalRequest>&) override;
+
+ Status processCaptureRequestError(const std::shared_ptr<HalRequest>&,
+ /*out*/ std::vector<NotifyMsg>* msgs,
+ /*out*/ std::vector<CaptureResult>* results) override;
+
+ ssize_t getJpegBufferSize(int32_t width, int32_t height) const override;
+
+ void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) override;
+ // End of OutputThreadInterface methods
+
+ ScopedAStatus setCallback(const std::shared_ptr<ICameraDeviceCallback>& in_cb) override;
+ ScopedAStatus getCaptureResultMetadataQueue(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
+ ScopedAStatus close() override;
+
+ private:
+ class OutputThread : public ExternalCameraDeviceSession::OutputThread {
+ public:
+ OutputThread(std::weak_ptr<OutputThreadInterface> parent, CroppingType ct,
+ const common::V1_0::helper::CameraMetadata& chars,
+ std::shared_ptr<ExternalCameraDeviceSession::BufferRequestThread> bufReqThread,
+ std::deque<std::shared_ptr<HalRequest>>& offlineReqs)
+ : ExternalCameraDeviceSession::OutputThread(std::move(parent), ct, chars,
+ std::move(bufReqThread)),
+ mOfflineReqs(offlineReqs) {}
+
+ bool threadLoop() override;
+
+ protected:
+ std::deque<std::shared_ptr<HalRequest>> mOfflineReqs;
+ }; // OutputThread
+
+ status_t fillCaptureResult(common::V1_0::helper::CameraMetadata md, nsecs_t timestamp);
+ void invokeProcessCaptureResultCallback(std::vector<CaptureResult>& results, bool tryWriteFmq);
+ void initOutputThread();
+ void cleanupBuffersLocked(int32_t id);
+
+ // Protect (most of) HIDL interface methods from synchronized-entering
+ mutable Mutex mInterfaceLock;
+
+ mutable Mutex mLock; // Protect all data members except otherwise noted
+
+ bool mClosed = false;
+ const CroppingType mCroppingType;
+ const common::V1_0::helper::CameraMetadata mChars;
+ const std::string mCameraId;
+ const std::string mExifMake;
+ const std::string mExifModel;
+ const uint32_t mBlobBufferSize;
+
+ std::mutex mAfTriggerLock; // protect mAfTrigger
+ bool mAfTrigger;
+
+ const std::vector<Stream> mOfflineStreams;
+ std::deque<std::shared_ptr<HalRequest>> mOfflineReqs;
+
+ // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
+ mutable Mutex mCbsLock;
+ std::map<int, CirculatingBuffers> mCirculatingBuffers;
+
+ static HandleImporter sHandleImporter;
+
+ using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+ std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
+ // Protect against invokeProcessCaptureResultCallback()
+ Mutex mProcessCaptureResultLock;
+
+ std::shared_ptr<ICameraDeviceCallback> mCallback;
+
+ std::shared_ptr<ExternalCameraDeviceSession::BufferRequestThread> mBufferRequestThread;
+ std::shared_ptr<OutputThread> mOutputThread;
+};
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAOFFLINESESSION_H_
diff --git a/camera/device/default/ExternalCameraUtils.cpp b/camera/device/default/ExternalCameraUtils.cpp
new file mode 100644
index 0000000..cfb95f2
--- /dev/null
+++ b/camera/device/default/ExternalCameraUtils.cpp
@@ -0,0 +1,860 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamUtils"
+// #define LOG_NDEBUG 0
+
+#include "ExternalCameraUtils.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <jpeglib.h>
+#include <linux/videodev2.h>
+#include <log/log.h>
+#include <algorithm>
+#include <cinttypes>
+#include <cmath>
+
+#define HAVE_JPEG // required for libyuv.h to export MJPEG decode APIs
+#include <libyuv.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+
+namespace external {
+namespace common {
+
+namespace {
+const int kDefaultCameraIdOffset = 100;
+const int kDefaultJpegBufSize = 5 << 20; // 5MB
+const int kDefaultNumVideoBuffer = 4;
+const int kDefaultNumStillBuffer = 2;
+const int kDefaultOrientation = 0; // suitable for natural landscape displays like tablet/TV
+ // For phone devices 270 is better
+} // anonymous namespace
+
+const char* ExternalCameraConfig::kDefaultCfgPath = "/vendor/etc/external_camera_config.xml";
+
+ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) {
+ using namespace tinyxml2;
+ ExternalCameraConfig ret;
+
+ XMLDocument configXml;
+ XMLError err = configXml.LoadFile(cfgPath);
+ if (err != XML_SUCCESS) {
+ ALOGE("%s: Unable to load external camera config file '%s'. Error: %s", __FUNCTION__,
+ cfgPath, XMLDocument::ErrorIDToName(err));
+ return ret;
+ } else {
+ ALOGI("%s: load external camera config succeeded!", __FUNCTION__);
+ }
+
+ XMLElement* extCam = configXml.FirstChildElement("ExternalCamera");
+ if (extCam == nullptr) {
+ ALOGI("%s: no external camera config specified", __FUNCTION__);
+ return ret;
+ }
+
+ XMLElement* providerCfg = extCam->FirstChildElement("Provider");
+ if (providerCfg == nullptr) {
+ ALOGI("%s: no external camera provider config specified", __FUNCTION__);
+ return ret;
+ }
+
+ XMLElement* cameraIdOffset = providerCfg->FirstChildElement("CameraIdOffset");
+ if (cameraIdOffset != nullptr) {
+ ret.cameraIdOffset = std::atoi(cameraIdOffset->GetText());
+ }
+
+ XMLElement* ignore = providerCfg->FirstChildElement("ignore");
+ if (ignore == nullptr) {
+ ALOGI("%s: no internal ignored device specified", __FUNCTION__);
+ return ret;
+ }
+
+ XMLElement* id = ignore->FirstChildElement("id");
+ while (id != nullptr) {
+ const char* text = id->GetText();
+ if (text != nullptr) {
+ ret.mInternalDevices.insert(text);
+ ALOGI("%s: device %s will be ignored by external camera provider", __FUNCTION__, text);
+ }
+ id = id->NextSiblingElement("id");
+ }
+
+ XMLElement* deviceCfg = extCam->FirstChildElement("Device");
+ if (deviceCfg == nullptr) {
+ ALOGI("%s: no external camera device config specified", __FUNCTION__);
+ return ret;
+ }
+
+ XMLElement* jpegBufSz = deviceCfg->FirstChildElement("MaxJpegBufferSize");
+ if (jpegBufSz == nullptr) {
+ ALOGI("%s: no max jpeg buffer size specified", __FUNCTION__);
+ } else {
+ ret.maxJpegBufSize = jpegBufSz->UnsignedAttribute("bytes", /*Default*/ kDefaultJpegBufSize);
+ }
+
+ XMLElement* numVideoBuf = deviceCfg->FirstChildElement("NumVideoBuffers");
+ if (numVideoBuf == nullptr) {
+ ALOGI("%s: no num video buffers specified", __FUNCTION__);
+ } else {
+ ret.numVideoBuffers =
+ numVideoBuf->UnsignedAttribute("count", /*Default*/ kDefaultNumVideoBuffer);
+ }
+
+ XMLElement* numStillBuf = deviceCfg->FirstChildElement("NumStillBuffers");
+ if (numStillBuf == nullptr) {
+ ALOGI("%s: no num still buffers specified", __FUNCTION__);
+ } else {
+ ret.numStillBuffers =
+ numStillBuf->UnsignedAttribute("count", /*Default*/ kDefaultNumStillBuffer);
+ }
+
+ XMLElement* fpsList = deviceCfg->FirstChildElement("FpsList");
+ if (fpsList == nullptr) {
+ ALOGI("%s: no fps list specified", __FUNCTION__);
+ } else {
+ if (!updateFpsList(fpsList, ret.fpsLimits)) {
+ return ret;
+ }
+ }
+
+ XMLElement* depth = deviceCfg->FirstChildElement("Depth16Supported");
+ if (depth == nullptr) {
+ ret.depthEnabled = false;
+ ALOGI("%s: depth output is not enabled", __FUNCTION__);
+ } else {
+ ret.depthEnabled = depth->BoolAttribute("enabled", false);
+ }
+
+ if (ret.depthEnabled) {
+ XMLElement* depthFpsList = deviceCfg->FirstChildElement("DepthFpsList");
+ if (depthFpsList == nullptr) {
+ ALOGW("%s: no depth fps list specified", __FUNCTION__);
+ } else {
+ if (!updateFpsList(depthFpsList, ret.depthFpsLimits)) {
+ return ret;
+ }
+ }
+ }
+
+ XMLElement* minStreamSize = deviceCfg->FirstChildElement("MinimumStreamSize");
+ if (minStreamSize == nullptr) {
+ ALOGI("%s: no minimum stream size specified", __FUNCTION__);
+ } else {
+ ret.minStreamSize = {
+ static_cast<int32_t>(minStreamSize->UnsignedAttribute("width", /*Default*/ 0)),
+ static_cast<int32_t>(minStreamSize->UnsignedAttribute("height", /*Default*/ 0))};
+ }
+
+ XMLElement* orientation = deviceCfg->FirstChildElement("Orientation");
+ if (orientation == nullptr) {
+ ALOGI("%s: no sensor orientation specified", __FUNCTION__);
+ } else {
+ ret.orientation = orientation->IntAttribute("degree", /*Default*/ kDefaultOrientation);
+ }
+
+ ALOGI("%s: external camera cfg loaded: maxJpgBufSize %d,"
+ " num video buffers %d, num still buffers %d, orientation %d",
+ __FUNCTION__, ret.maxJpegBufSize, ret.numVideoBuffers, ret.numStillBuffers,
+ ret.orientation);
+ for (const auto& limit : ret.fpsLimits) {
+ ALOGI("%s: fpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height,
+ limit.fpsUpperBound);
+ }
+ for (const auto& limit : ret.depthFpsLimits) {
+ ALOGI("%s: depthFpsLimitList: %dx%d@%f", __FUNCTION__, limit.size.width, limit.size.height,
+ limit.fpsUpperBound);
+ }
+ ALOGI("%s: minStreamSize: %dx%d", __FUNCTION__, ret.minStreamSize.width,
+ ret.minStreamSize.height);
+ return ret;
+}
+
+bool ExternalCameraConfig::updateFpsList(tinyxml2::XMLElement* fpsList,
+ std::vector<FpsLimitation>& fpsLimits) {
+ using namespace tinyxml2;
+ std::vector<FpsLimitation> limits;
+ XMLElement* row = fpsList->FirstChildElement("Limit");
+ while (row != nullptr) {
+ FpsLimitation prevLimit{{0, 0}, 1000.0};
+ FpsLimitation limit = {
+ {/* width */ static_cast<int32_t>(row->UnsignedAttribute("width", /*Default*/ 0)),
+ /* height */ static_cast<int32_t>(
+ row->UnsignedAttribute("height", /*Default*/ 0))},
+ /* fpsUpperBound */ row->DoubleAttribute("fpsBound", /*Default*/ 1000.0)};
+ if (limit.size.width <= prevLimit.size.width ||
+ limit.size.height <= prevLimit.size.height ||
+ limit.fpsUpperBound >= prevLimit.fpsUpperBound) {
+ ALOGE("%s: FPS limit list must have increasing size and decreasing fps!"
+ " Prev %dx%d@%f, Current %dx%d@%f",
+ __FUNCTION__, prevLimit.size.width, prevLimit.size.height,
+ prevLimit.fpsUpperBound, limit.size.width, limit.size.height,
+ limit.fpsUpperBound);
+ return false;
+ }
+ limits.push_back(limit);
+ row = row->NextSiblingElement("Limit");
+ }
+ fpsLimits = limits;
+ return true;
+}
+
+ExternalCameraConfig::ExternalCameraConfig()
+ : cameraIdOffset(kDefaultCameraIdOffset),
+ maxJpegBufSize(kDefaultJpegBufSize),
+ numVideoBuffers(kDefaultNumVideoBuffer),
+ numStillBuffers(kDefaultNumStillBuffer),
+ depthEnabled(false),
+ orientation(kDefaultOrientation) {
+ fpsLimits.push_back({/* size */ {/* width */ 640, /* height */ 480}, /* fpsUpperBound */ 30.0});
+ fpsLimits.push_back({/* size */ {/* width */ 1280, /* height */ 720}, /* fpsUpperBound */ 7.5});
+ fpsLimits.push_back(
+ {/* size */ {/* width */ 1920, /* height */ 1080}, /* fpsUpperBound */ 5.0});
+ minStreamSize = {0, 0};
+}
+
+} // namespace common
+} // namespace external
+
+namespace device {
+namespace implementation {
+
+double SupportedV4L2Format::FrameRate::getFramesPerSecond() const {
+ return static_cast<double>(durationDenominator) / durationNumerator;
+}
+
+Frame::Frame(uint32_t width, uint32_t height, uint32_t fourcc)
+ : mWidth(width), mHeight(height), mFourcc(fourcc) {}
+Frame::~Frame() {}
+
+V4L2Frame::V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize,
+ uint64_t offset)
+ : Frame(w, h, fourcc), mBufferIndex(bufIdx), mFd(fd), mDataSize(dataSize), mOffset(offset) {}
+
+V4L2Frame::~V4L2Frame() {
+ unmap();
+}
+
+int V4L2Frame::getData(uint8_t** outData, size_t* dataSize) {
+ return map(outData, dataSize);
+}
+
+int V4L2Frame::map(uint8_t** data, size_t* dataSize) {
+ if (data == nullptr || dataSize == nullptr) {
+ ALOGI("%s: V4L2 buffer map bad argument: data %p, dataSize %p", __FUNCTION__, data,
+ dataSize);
+ return -EINVAL;
+ }
+
+ std::lock_guard<std::mutex> lk(mLock);
+ if (!mMapped) {
+ void* addr = mmap(nullptr, mDataSize, PROT_READ, MAP_SHARED, mFd, mOffset);
+ if (addr == MAP_FAILED) {
+ ALOGE("%s: V4L2 buffer map failed: %s", __FUNCTION__, strerror(errno));
+ return -EINVAL;
+ }
+ mData = static_cast<uint8_t*>(addr);
+ mMapped = true;
+ }
+ *data = mData;
+ *dataSize = mDataSize;
+ ALOGV("%s: V4L map FD %d, data %p size %zu", __FUNCTION__, mFd, mData, mDataSize);
+ return 0;
+}
+
+int V4L2Frame::unmap() {
+ std::lock_guard<std::mutex> lk(mLock);
+ if (mMapped) {
+ ALOGV("%s: V4L unmap data %p size %zu", __FUNCTION__, mData, mDataSize);
+ if (munmap(mData, mDataSize) != 0) {
+ ALOGE("%s: V4L2 buffer unmap failed: %s", __FUNCTION__, strerror(errno));
+ return -EINVAL;
+ }
+ mMapped = false;
+ }
+ return 0;
+}
+
+AllocatedFrame::AllocatedFrame(uint32_t w, uint32_t h) : Frame(w, h, V4L2_PIX_FMT_YUV420) {}
+AllocatedFrame::~AllocatedFrame() {}
+
+int AllocatedFrame::getData(uint8_t** outData, size_t* dataSize) {
+ YCbCrLayout layout;
+ int ret = allocate(&layout);
+ if (ret != 0) {
+ return ret;
+ }
+ *outData = mData.data();
+ *dataSize = mBufferSize;
+ return 0;
+}
+
+int AllocatedFrame::allocate(YCbCrLayout* out) {
+ std::lock_guard<std::mutex> lk(mLock);
+ if ((mWidth % 2) || (mHeight % 2)) {
+ ALOGE("%s: bad dimension %dx%d (not multiple of 2)", __FUNCTION__, mWidth, mHeight);
+ return -EINVAL;
+ }
+
+ // This frame might be sent to jpeglib to be encoded. Since AllocatedFrame only contains YUV420,
+ // jpeglib expects height and width of Y component to be an integral multiple of 2*DCTSIZE,
+ // and heights and widths of Cb and Cr components to be an integral multiple of DCTSIZE. If the
+ // image size does not meet this requirement, libjpeg expects its input to be padded to meet the
+ // constraints. This padding is removed from the final encoded image so the content in the
+ // padding doesn't matter. What matters is that the memory is accessible to jpeglib at the time
+ // of encoding.
+ // For example, if the image size is 1500x844 and DCTSIZE is 8, jpeglib expects a YUV 420
+ // frame with components of following sizes:
+ // Y: 1504x848 because 1504 and 848 are the next smallest multiples of 2*8
+ // Cb/Cr: 752x424 which are the next smallest multiples of 8
+
+ // jpeglib takes an array of row pointers which makes vertical padding trivial when setting up
+ // the pointers. Padding horizontally is a bit more complicated. AllocatedFrame holds the data
+ // in a flattened buffer, which means memory accesses past a row will flow into the next logical
+ // row. For any row of a component, we can consider the first few bytes of the next row as
+ // padding for the current one. This is true for Y and Cb components and all but last row of the
+ // Cr component. Reading past the last row of Cr component will lead to undefined behavior as
+ // libjpeg attempts to read memory past the allocated buffer. To prevent undefined behavior,
+ // the buffer allocated here is padded such that libjpeg never accesses unallocated memory when
+ // reading the last row. Effectively, we only need to ensure that the last row of Cr component
+ // has width that is an integral multiple of DCTSIZE.
+
+ size_t dataSize = mWidth * mHeight * 3 / 2; // YUV420
+
+ size_t cbWidth = mWidth / 2;
+ size_t requiredCbWidth = DCTSIZE * ((cbWidth + DCTSIZE - 1) / DCTSIZE);
+ size_t padding = requiredCbWidth - cbWidth;
+ size_t finalSize = dataSize + padding;
+
+ if (mData.size() != finalSize) {
+ mData.resize(finalSize);
+ mBufferSize = dataSize;
+ }
+
+ if (out != nullptr) {
+ out->y = mData.data();
+ out->yStride = mWidth;
+ uint8_t* cbStart = mData.data() + mWidth * mHeight;
+ uint8_t* crStart = cbStart + mWidth * mHeight / 4;
+ out->cb = cbStart;
+ out->cr = crStart;
+ out->cStride = mWidth / 2;
+ out->chromaStep = 1;
+ }
+ return 0;
+}
+
+int AllocatedFrame::getLayout(YCbCrLayout* out) {
+ IMapper::Rect noCrop = {0, 0, static_cast<int32_t>(mWidth), static_cast<int32_t>(mHeight)};
+ return getCroppedLayout(noCrop, out);
+}
+
+int AllocatedFrame::getCroppedLayout(const IMapper::Rect& rect, YCbCrLayout* out) {
+ if (out == nullptr) {
+ ALOGE("%s: null out", __FUNCTION__);
+ return -1;
+ }
+
+ std::lock_guard<std::mutex> lk(mLock);
+ if ((rect.left + rect.width) > static_cast<int>(mWidth) ||
+ (rect.top + rect.height) > static_cast<int>(mHeight) || (rect.left % 2) || (rect.top % 2) ||
+ (rect.width % 2) || (rect.height % 2)) {
+ ALOGE("%s: bad rect left %d top %d w %d h %d", __FUNCTION__, rect.left, rect.top,
+ rect.width, rect.height);
+ return -1;
+ }
+
+ out->y = mData.data() + mWidth * rect.top + rect.left;
+ out->yStride = mWidth;
+ uint8_t* cbStart = mData.data() + mWidth * mHeight;
+ uint8_t* crStart = cbStart + mWidth * mHeight / 4;
+ out->cb = cbStart + mWidth * rect.top / 4 + rect.left / 2;
+ out->cr = crStart + mWidth * rect.top / 4 + rect.left / 2;
+ out->cStride = mWidth / 2;
+ out->chromaStep = 1;
+ return 0;
+}
+
+bool isAspectRatioClose(float ar1, float ar2) {
+ constexpr float kAspectRatioMatchThres = 0.025f; // This threshold is good enough to
+ // distinguish 4:3/16:9/20:9 1.33/1.78/2
+ return std::abs(ar1 - ar2) < kAspectRatioMatchThres;
+}
+
+aidl::android::hardware::camera::common::Status importBufferImpl(
+ /*inout*/ std::map<int, CirculatingBuffers>& circulatingBuffers,
+ /*inout*/ HandleImporter& handleImporter, int32_t streamId, uint64_t bufId,
+ buffer_handle_t buf,
+ /*out*/ buffer_handle_t** outBufPtr) {
+ using ::aidl::android::hardware::camera::common::Status;
+ if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
+ ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+
+ CirculatingBuffers& cbs = circulatingBuffers[streamId];
+ if (cbs.count(bufId) == 0) {
+ if (buf == nullptr) {
+ ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
+ return Status::ILLEGAL_ARGUMENT;
+ }
+ // Register a newly seen buffer
+ buffer_handle_t importedBuf = buf;
+ handleImporter.importBuffer(importedBuf);
+ if (importedBuf == nullptr) {
+ ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
+ return Status::INTERNAL_ERROR;
+ } else {
+ cbs[bufId] = importedBuf;
+ }
+ }
+ *outBufPtr = &cbs[bufId];
+ return Status::OK;
+}
+
+uint32_t getFourCcFromLayout(const YCbCrLayout& layout) {
+ intptr_t cb = reinterpret_cast<intptr_t>(layout.cb);
+ intptr_t cr = reinterpret_cast<intptr_t>(layout.cr);
+ if (std::abs(cb - cr) == 1 && layout.chromaStep == 2) {
+ // Interleaved format
+ if (layout.cb > layout.cr) {
+ return V4L2_PIX_FMT_NV21;
+ } else {
+ return V4L2_PIX_FMT_NV12;
+ }
+ } else if (layout.chromaStep == 1) {
+ // Planar format
+ if (layout.cb > layout.cr) {
+ return V4L2_PIX_FMT_YVU420; // YV12
+ } else {
+ return V4L2_PIX_FMT_YUV420; // YU12
+ }
+ } else {
+ return FLEX_YUV_GENERIC;
+ }
+}
+
+int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out) {
+ if (out == nullptr) {
+ ALOGE("%s: out is null", __FUNCTION__);
+ return -1;
+ }
+
+ uint32_t inW = inSize.width;
+ uint32_t inH = inSize.height;
+ uint32_t outW = outSize.width;
+ uint32_t outH = outSize.height;
+
+ // Handle special case where aspect ratio is close to input but scaled
+ // dimension is slightly larger than input
+ float arIn = ASPECT_RATIO(inSize);
+ float arOut = ASPECT_RATIO(outSize);
+ if (isAspectRatioClose(arIn, arOut)) {
+ out->left = 0;
+ out->top = 0;
+ out->width = static_cast<int32_t>(inW);
+ out->height = static_cast<int32_t>(inH);
+ return 0;
+ }
+
+ if (ct == VERTICAL) {
+ uint64_t scaledOutH = static_cast<uint64_t>(outH) * inW / outW;
+ if (scaledOutH > inH) {
+ ALOGE("%s: Output size %dx%d cannot be vertically cropped from input size %dx%d",
+ __FUNCTION__, outW, outH, inW, inH);
+ return -1;
+ }
+ scaledOutH = scaledOutH & ~0x1; // make it multiple of 2
+
+ out->left = 0;
+ out->top = static_cast<int32_t>((inH - scaledOutH) / 2) & ~0x1;
+ out->width = static_cast<int32_t>(inW);
+ out->height = static_cast<int32_t>(scaledOutH);
+ ALOGV("%s: crop %dx%d to %dx%d: top %d, scaledH %d", __FUNCTION__, inW, inH, outW, outH,
+ out->top, static_cast<int32_t>(scaledOutH));
+ } else {
+ uint64_t scaledOutW = static_cast<uint64_t>(outW) * inH / outH;
+ if (scaledOutW > inW) {
+ ALOGE("%s: Output size %dx%d cannot be horizontally cropped from input size %dx%d",
+ __FUNCTION__, outW, outH, inW, inH);
+ return -1;
+ }
+ scaledOutW = scaledOutW & ~0x1; // make it multiple of 2
+
+ out->left = static_cast<int32_t>((inW - scaledOutW) / 2) & ~0x1;
+ out->top = 0;
+ out->width = static_cast<int32_t>(scaledOutW);
+ out->height = static_cast<int32_t>(inH);
+ ALOGV("%s: crop %dx%d to %dx%d: top %d, scaledW %d", __FUNCTION__, inW, inH, outW, outH,
+ out->top, static_cast<int32_t>(scaledOutW));
+ }
+
+ return 0;
+}
+
+int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format) {
+ int ret = 0;
+ switch (format) {
+ case V4L2_PIX_FMT_NV21:
+ ret = libyuv::I420ToNV21(
+ static_cast<uint8_t*>(in.y), static_cast<int32_t>(in.yStride),
+ static_cast<uint8_t*>(in.cb), static_cast<int32_t>(in.cStride),
+ static_cast<uint8_t*>(in.cr), static_cast<int32_t>(in.cStride),
+ static_cast<uint8_t*>(out.y), static_cast<int32_t>(out.yStride),
+ static_cast<uint8_t*>(out.cr), static_cast<int32_t>(out.cStride),
+ static_cast<int32_t>(sz.width), static_cast<int32_t>(sz.height));
+ if (ret != 0) {
+ ALOGE("%s: convert to NV21 buffer failed! ret %d", __FUNCTION__, ret);
+ return ret;
+ }
+ break;
+ case V4L2_PIX_FMT_NV12:
+ ret = libyuv::I420ToNV12(
+ static_cast<uint8_t*>(in.y), static_cast<int32_t>(in.yStride),
+ static_cast<uint8_t*>(in.cb), static_cast<int32_t>(in.cStride),
+ static_cast<uint8_t*>(in.cr), static_cast<int32_t>(in.cStride),
+ static_cast<uint8_t*>(out.y), static_cast<int32_t>(out.yStride),
+ static_cast<uint8_t*>(out.cb), static_cast<int32_t>(out.cStride),
+ static_cast<int32_t>(sz.width), static_cast<int32_t>(sz.height));
+ if (ret != 0) {
+ ALOGE("%s: convert to NV12 buffer failed! ret %d", __FUNCTION__, ret);
+ return ret;
+ }
+ break;
+ case V4L2_PIX_FMT_YVU420: // YV12
+ case V4L2_PIX_FMT_YUV420: // YU12
+ // TODO: maybe we can speed up here by somehow save this copy?
+ ret = libyuv::I420Copy(static_cast<uint8_t*>(in.y), static_cast<int32_t>(in.yStride),
+ static_cast<uint8_t*>(in.cb), static_cast<int32_t>(in.cStride),
+ static_cast<uint8_t*>(in.cr), static_cast<int32_t>(in.cStride),
+ static_cast<uint8_t*>(out.y), static_cast<int32_t>(out.yStride),
+ static_cast<uint8_t*>(out.cb), static_cast<int32_t>(out.cStride),
+ static_cast<uint8_t*>(out.cr), static_cast<int32_t>(out.cStride),
+ static_cast<int32_t>(sz.width), static_cast<int32_t>(sz.height));
+ if (ret != 0) {
+ ALOGE("%s: copy to YV12 or YU12 buffer failed! ret %d", __FUNCTION__, ret);
+ return ret;
+ }
+ break;
+ case FLEX_YUV_GENERIC:
+ // TODO: b/72261744 write to arbitrary flexible YUV layout. Slow.
+ ALOGE("%s: unsupported flexible yuv layout"
+ " y %p cb %p cr %p y_str %d c_str %d c_step %d",
+ __FUNCTION__, out.y, out.cb, out.cr, out.yStride, out.cStride, out.chromaStep);
+ return -1;
+ default:
+ ALOGE("%s: unknown YUV format 0x%x!", __FUNCTION__, format);
+ return -1;
+ }
+ return 0;
+}
+
+int encodeJpegYU12(const Size& inSz, const YCbCrLayout& inLayout, int jpegQuality,
+ const void* app1Buffer, size_t app1Size, void* out, size_t maxOutSize,
+ size_t& actualCodeSize) {
+ /* libjpeg is a C library so we use C-style "inheritance" by
+ * putting libjpeg's jpeg_destination_mgr first in our custom
+ * struct. This allows us to cast jpeg_destination_mgr* to
+ * CustomJpegDestMgr* when we get it passed to us in a callback */
+ struct CustomJpegDestMgr {
+ struct jpeg_destination_mgr mgr;
+ JOCTET* mBuffer;
+ size_t mBufferSize;
+ size_t mEncodedSize;
+ bool mSuccess;
+ } dmgr;
+
+ jpeg_compress_struct cinfo = {};
+ jpeg_error_mgr jerr;
+
+ /* Initialize error handling with standard callbacks, but
+ * then override output_message (to print to ALOG) and
+ * error_exit to set a flag and print a message instead
+ * of killing the whole process */
+ cinfo.err = jpeg_std_error(&jerr);
+
+ cinfo.err->output_message = [](j_common_ptr cinfo) {
+ char buffer[JMSG_LENGTH_MAX];
+
+ /* Create the message */
+ (*cinfo->err->format_message)(cinfo, buffer);
+ ALOGE("libjpeg error: %s", buffer);
+ };
+ cinfo.err->error_exit = [](j_common_ptr cinfo) {
+ (*cinfo->err->output_message)(cinfo);
+ if (cinfo->client_data) {
+ auto& dmgr = *reinterpret_cast<CustomJpegDestMgr*>(cinfo->client_data);
+ dmgr.mSuccess = false;
+ }
+ };
+
+ /* Now that we initialized some callbacks, let's create our compressor */
+ jpeg_create_compress(&cinfo);
+
+ /* Initialize our destination manager */
+ dmgr.mBuffer = static_cast<JOCTET*>(out);
+ dmgr.mBufferSize = maxOutSize;
+ dmgr.mEncodedSize = 0;
+ dmgr.mSuccess = true;
+ cinfo.client_data = static_cast<void*>(&dmgr);
+
+ /* These lambdas become C-style function pointers and as per C++11 spec
+ * may not capture anything */
+ dmgr.mgr.init_destination = [](j_compress_ptr cinfo) {
+ auto& dmgr = reinterpret_cast<CustomJpegDestMgr&>(*cinfo->dest);
+ dmgr.mgr.next_output_byte = dmgr.mBuffer;
+ dmgr.mgr.free_in_buffer = dmgr.mBufferSize;
+ ALOGV("%s:%d jpeg start: %p [%zu]", __FUNCTION__, __LINE__, dmgr.mBuffer, dmgr.mBufferSize);
+ };
+
+ dmgr.mgr.empty_output_buffer = [](j_compress_ptr cinfo __unused) {
+ ALOGV("%s:%d Out of buffer", __FUNCTION__, __LINE__);
+ return 0;
+ };
+
+ dmgr.mgr.term_destination = [](j_compress_ptr cinfo) {
+ auto& dmgr = reinterpret_cast<CustomJpegDestMgr&>(*cinfo->dest);
+ dmgr.mEncodedSize = dmgr.mBufferSize - dmgr.mgr.free_in_buffer;
+ ALOGV("%s:%d Done with jpeg: %zu", __FUNCTION__, __LINE__, dmgr.mEncodedSize);
+ };
+ cinfo.dest = reinterpret_cast<struct jpeg_destination_mgr*>(&dmgr);
+
+ /* We are going to be using JPEG in raw data mode, so we are passing
+ * straight subsampled planar YCbCr and it will not touch our pixel
+ * data or do any scaling or anything */
+ cinfo.image_width = inSz.width;
+ cinfo.image_height = inSz.height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_YCbCr;
+
+ /* Initialize defaults and then override what we want */
+ jpeg_set_defaults(&cinfo);
+
+ jpeg_set_quality(&cinfo, jpegQuality, 1);
+ jpeg_set_colorspace(&cinfo, JCS_YCbCr);
+ cinfo.raw_data_in = 1;
+ cinfo.dct_method = JDCT_IFAST;
+
+ /* Configure sampling factors. The sampling factor is JPEG subsampling 420
+ * because the source format is YUV420. Note that libjpeg sampling factors
+ * are... a little weird. Sampling of Y=2,U=1,V=1 means there is 1 U and
+ * 1 V value for each 2 Y values */
+ cinfo.comp_info[0].h_samp_factor = 2;
+ cinfo.comp_info[0].v_samp_factor = 2;
+ cinfo.comp_info[1].h_samp_factor = 1;
+ cinfo.comp_info[1].v_samp_factor = 1;
+ cinfo.comp_info[2].h_samp_factor = 1;
+ cinfo.comp_info[2].v_samp_factor = 1;
+
+ /* Start the compressor */
+ jpeg_start_compress(&cinfo, TRUE);
+
+ /* Let's not hardcode YUV420 in 6 places... 5 was enough */
+ int maxVSampFactor = cinfo.max_v_samp_factor;
+ int cVSubSampling = cinfo.comp_info[0].v_samp_factor / cinfo.comp_info[1].v_samp_factor;
+
+ /* Compute our macroblock height, so we can pad our input to be vertically
+ * macroblock aligned. No need to for horizontal alignment since AllocatedFrame already
+ * pads horizontally */
+
+ size_t mcuV = DCTSIZE * maxVSampFactor;
+ size_t paddedHeight = mcuV * ((inSz.height + mcuV - 1) / mcuV);
+
+ /* libjpeg uses arrays of row pointers, which makes it really easy to pad
+ * data vertically (unfortunately doesn't help horizontally) */
+ std::vector<JSAMPROW> yLines(paddedHeight);
+ std::vector<JSAMPROW> cbLines(paddedHeight / cVSubSampling);
+ std::vector<JSAMPROW> crLines(paddedHeight / cVSubSampling);
+
+ uint8_t* py = static_cast<uint8_t*>(inLayout.y);
+ uint8_t* pcb = static_cast<uint8_t*>(inLayout.cb);
+ uint8_t* pcr = static_cast<uint8_t*>(inLayout.cr);
+
+ for (int32_t i = 0; i < paddedHeight; i++) {
+ /* Once we are in the padding territory we still point to the last line
+ * effectively replicating it several times ~ CLAMP_TO_EDGE */
+ int li = std::min(i, inSz.height - 1);
+ yLines[i] = static_cast<JSAMPROW>(py + li * inLayout.yStride);
+ if (i < paddedHeight / cVSubSampling) {
+ li = std::min(i, (inSz.height - 1) / cVSubSampling);
+ cbLines[i] = static_cast<JSAMPROW>(pcb + li * inLayout.cStride);
+ crLines[i] = static_cast<JSAMPROW>(pcr + li * inLayout.cStride);
+ }
+ }
+
+ /* If APP1 data was passed in, use it */
+ if (app1Buffer && app1Size) {
+ jpeg_write_marker(&cinfo, JPEG_APP0 + 1, static_cast<const JOCTET*>(app1Buffer), app1Size);
+ }
+
+ /* While we still have padded height left to go, keep giving it one
+ * macroblock at a time. */
+ while (cinfo.next_scanline < cinfo.image_height) {
+ const uint32_t batchSize = DCTSIZE * maxVSampFactor;
+ const uint32_t nl = cinfo.next_scanline;
+ JSAMPARRAY planes[3]{&yLines[nl], &cbLines[nl / cVSubSampling],
+ &crLines[nl / cVSubSampling]};
+
+ uint32_t done = jpeg_write_raw_data(&cinfo, planes, batchSize);
+
+ if (done != batchSize) {
+ ALOGE("%s: compressed %u lines, expected %u (total %u/%u)", __FUNCTION__, done,
+ batchSize, cinfo.next_scanline, cinfo.image_height);
+ return -1;
+ }
+ }
+
+ /* This will flush everything */
+ jpeg_finish_compress(&cinfo);
+
+ /* Grab the actual code size and set it */
+ actualCodeSize = dmgr.mEncodedSize;
+
+ return 0;
+}
+
+Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata& chars) {
+ Size thumbSize{0, 0};
+ camera_metadata_ro_entry entry = chars.find(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
+ for (uint32_t i = 0; i < entry.count; i += 2) {
+ Size sz{.width = entry.data.i32[i], .height = entry.data.i32[i + 1]};
+ if (sz.width * sz.height > thumbSize.width * thumbSize.height) {
+ thumbSize = sz;
+ }
+ }
+
+ if (thumbSize.width * thumbSize.height == 0) {
+ ALOGW("%s: non-zero thumbnail size not available", __FUNCTION__);
+ }
+
+ return thumbSize;
+}
+
+void freeReleaseFences(std::vector<CaptureResult>& results) {
+ for (auto& result : results) {
+ native_handle_t* inputReleaseFence =
+ ::android::makeFromAidl(result.inputBuffer.releaseFence);
+ if (inputReleaseFence != nullptr) {
+ native_handle_close(inputReleaseFence);
+ native_handle_delete(inputReleaseFence);
+ }
+ for (auto& buf : result.outputBuffers) {
+ native_handle_t* outReleaseFence = ::android::makeFromAidl(buf.releaseFence);
+ if (outReleaseFence != nullptr) {
+ native_handle_close(outReleaseFence);
+ native_handle_delete(outReleaseFence);
+ }
+ }
+ }
+}
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+#define UPDATE(md, tag, data, size) \
+ do { \
+ if ((md).update((tag), (data), (size))) { \
+ ALOGE("Update " #tag " failed!"); \
+ return BAD_VALUE; \
+ } \
+ } while (0)
+
+status_t fillCaptureResultCommon(CameraMetadata& md, nsecs_t timestamp,
+ camera_metadata_ro_entry& activeArraySize) {
+ if (activeArraySize.count < 4) {
+ ALOGE("%s: cannot find active array size!", __FUNCTION__);
+ return -EINVAL;
+ }
+ // android.control
+ // For USB camera, we don't know the AE state. Set the state to converged to
+ // indicate the frame should be good to use. Then apps don't have to wait the
+ // AE state.
+ const uint8_t aeState = ANDROID_CONTROL_AE_STATE_CONVERGED;
+ UPDATE(md, ANDROID_CONTROL_AE_STATE, &aeState, 1);
+
+ const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
+ UPDATE(md, ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
+
+ // Set AWB state to converged to indicate the frame should be good to use.
+ const uint8_t awbState = ANDROID_CONTROL_AWB_STATE_CONVERGED;
+ UPDATE(md, ANDROID_CONTROL_AWB_STATE, &awbState, 1);
+
+ const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
+ UPDATE(md, ANDROID_CONTROL_AWB_LOCK, &awbLock, 1);
+
+ const uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE;
+ UPDATE(md, ANDROID_FLASH_STATE, &flashState, 1);
+
+ // This means pipeline latency of X frame intervals. The maximum number is 4.
+ const uint8_t requestPipelineMaxDepth = 4;
+ UPDATE(md, ANDROID_REQUEST_PIPELINE_DEPTH, &requestPipelineMaxDepth, 1);
+
+ // android.scaler
+ const int32_t crop_region[] = {
+ activeArraySize.data.i32[0],
+ activeArraySize.data.i32[1],
+ activeArraySize.data.i32[2],
+ activeArraySize.data.i32[3],
+ };
+ UPDATE(md, ANDROID_SCALER_CROP_REGION, crop_region, ARRAY_SIZE(crop_region));
+
+ // android.sensor
+ UPDATE(md, ANDROID_SENSOR_TIMESTAMP, ×tamp, 1);
+
+ // android.statistics
+ const uint8_t lensShadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
+ UPDATE(md, ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, &lensShadingMapMode, 1);
+
+ const uint8_t sceneFlicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
+ UPDATE(md, ANDROID_STATISTICS_SCENE_FLICKER, &sceneFlicker, 1);
+
+ return OK;
+}
+
+#undef ARRAY_SIZE
+#undef UPDATE
+
+AllocatedV4L2Frame::AllocatedV4L2Frame(std::shared_ptr<V4L2Frame> frameIn)
+ : Frame(frameIn->mWidth, frameIn->mHeight, frameIn->mFourcc) {
+ uint8_t* dataIn;
+ size_t dataSize;
+ if (frameIn->getData(&dataIn, &dataSize) != 0) {
+ ALOGE("%s: map input V4L2 frame failed!", __FUNCTION__);
+ return;
+ }
+
+ mData.resize(dataSize);
+ std::memcpy(mData.data(), dataIn, dataSize);
+}
+
+AllocatedV4L2Frame::~AllocatedV4L2Frame() {}
+
+int AllocatedV4L2Frame::getData(uint8_t** outData, size_t* dataSize) {
+ if (outData == nullptr || dataSize == nullptr) {
+ ALOGE("%s: outData(%p)/dataSize(%p) must not be null", __FUNCTION__, outData, dataSize);
+ return -1;
+ }
+
+ *outData = mData.data();
+ *dataSize = mData.size();
+ return 0;
+}
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/camera/device/default/ExternalCameraUtils.h b/camera/device/default/ExternalCameraUtils.h
new file mode 100644
index 0000000..b37933c
--- /dev/null
+++ b/camera/device/default/ExternalCameraUtils.h
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_
+
+#include <CameraMetadata.h>
+#include <HandleImporter.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/CaptureResult.h>
+#include <aidl/android/hardware/camera/device/ErrorCode.h>
+#include <aidl/android/hardware/camera/device/NotifyMsg.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <tinyxml2.h>
+#include <unordered_map>
+#include <unordered_set>
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::CaptureResult;
+using ::aidl::android::hardware::camera::device::ErrorCode;
+using ::aidl::android::hardware::camera::device::NotifyMsg;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+using ::android::hardware::camera::common::V1_0::helper::CameraMetadata;
+using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
+
+namespace android {
+namespace hardware {
+namespace camera {
+
+namespace external {
+namespace common {
+
+struct Size {
+ int32_t width;
+ int32_t height;
+
+ bool operator==(const Size& other) const {
+ return (width == other.width && height == other.height);
+ }
+};
+
+struct SizeHasher {
+ size_t operator()(const Size& sz) const {
+ size_t result = 1;
+ result = 31 * result + sz.width;
+ result = 31 * result + sz.height;
+ return result;
+ }
+};
+
+struct ExternalCameraConfig {
+ static const char* kDefaultCfgPath;
+ static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath);
+
+ // CameraId base offset for numerical representation
+ uint32_t cameraIdOffset;
+
+ // List of internal V4L2 video nodes external camera HAL must ignore.
+ std::unordered_set<std::string> mInternalDevices;
+
+ // Maximal size of a JPEG buffer, in bytes
+ int32_t maxJpegBufSize;
+
+ // Maximum Size that can sustain 30fps streaming
+ Size maxVideoSize;
+
+ // Size of v4l2 buffer queue when streaming <= kMaxVideoSize
+ uint32_t numVideoBuffers;
+
+ // Size of v4l2 buffer queue when streaming > kMaxVideoSize
+ uint32_t numStillBuffers;
+
+ // Indication that the device connected supports depth output
+ bool depthEnabled;
+
+ struct FpsLimitation {
+ Size size;
+ double fpsUpperBound;
+ };
+ std::vector<FpsLimitation> fpsLimits;
+ std::vector<FpsLimitation> depthFpsLimits;
+
+ // Minimum output stream size
+ Size minStreamSize;
+
+ // The value of android.sensor.orientation
+ int32_t orientation;
+
+ private:
+ ExternalCameraConfig();
+ static bool updateFpsList(tinyxml2::XMLElement* fpsList, std::vector<FpsLimitation>& fpsLimits);
+};
+
+} // namespace common
+} // namespace external
+
+namespace device {
+namespace implementation {
+
+struct SupportedV4L2Format {
+ int32_t width;
+ int32_t height;
+ uint32_t fourcc;
+ // All supported frame rate for this w/h/fourcc combination
+ struct FrameRate {
+ // Duration (in seconds) of a single frame.
+ // Numerator and denominator of the frame duration are stored separately.
+ // For ex. a frame lasting 1/30 of a second will be stored as {1, 30}
+ uint32_t durationNumerator; // frame duration numerator. Ex: 1
+ uint32_t durationDenominator; // frame duration denominator. Ex: 30
+ double getFramesPerSecond() const; // FPS as double. Ex: 30.0
+ };
+ std::vector<FrameRate> frameRates;
+};
+
+// A Base class with basic information about a frame
+struct Frame : public std::enable_shared_from_this<Frame> {
+ public:
+ Frame(uint32_t width, uint32_t height, uint32_t fourcc);
+ virtual ~Frame();
+ const int32_t mWidth;
+ const int32_t mHeight;
+ const uint32_t mFourcc;
+
+ // getData might involve map/allocation
+ virtual int getData(uint8_t** outData, size_t* dataSize) = 0;
+};
+
+// A class provide access to a dequeued V4L2 frame buffer (mostly in MJPG format)
+// Also contains necessary information to enqueue the buffer back to V4L2 buffer queue
+class V4L2Frame : public Frame {
+ public:
+ V4L2Frame(uint32_t w, uint32_t h, uint32_t fourcc, int bufIdx, int fd, uint32_t dataSize,
+ uint64_t offset);
+ virtual ~V4L2Frame();
+
+ virtual int getData(uint8_t** outData, size_t* dataSize) override;
+
+ const int mBufferIndex; // for later enqueue
+ int map(uint8_t** data, size_t* dataSize);
+ int unmap();
+
+ private:
+ std::mutex mLock;
+ const int mFd; // used for mmap but doesn't claim ownership
+ const size_t mDataSize;
+ const uint64_t mOffset; // used for mmap
+ uint8_t* mData = nullptr;
+ bool mMapped = false;
+};
+
+// A RAII class representing a CPU allocated YUV frame used as intermediate buffers
+// when generating output images.
+class AllocatedFrame : public Frame {
+ public:
+ AllocatedFrame(uint32_t w, uint32_t h); // only support V4L2_PIX_FMT_YUV420 for now
+ ~AllocatedFrame() override;
+
+ virtual int getData(uint8_t** outData, size_t* dataSize) override;
+
+ int allocate(YCbCrLayout* out = nullptr);
+ int getLayout(YCbCrLayout* out);
+ int getCroppedLayout(const IMapper::Rect&, YCbCrLayout* out); // return non-zero for bad input
+ private:
+ std::mutex mLock;
+ std::vector<uint8_t> mData;
+ size_t mBufferSize; // size of mData before padding. Actual size of mData might be slightly
+ // bigger to horizontally pad the frame for jpeglib.
+};
+
+enum CroppingType { HORIZONTAL = 0, VERTICAL = 1 };
+
+// Aspect ratio is defined as width/height here and ExternalCameraDevice
+// will guarantee all supported sizes has width >= height (so aspect ratio >= 1.0)
+#define ASPECT_RATIO(sz) (static_cast<float>((sz).width) / (sz).height)
+const float kMaxAspectRatio = std::numeric_limits<float>::max();
+const float kMinAspectRatio = 1.f;
+
+bool isAspectRatioClose(float ar1, float ar2);
+
+struct HalStreamBuffer {
+ int32_t streamId;
+ int64_t bufferId;
+ int32_t width;
+ int32_t height;
+ ::aidl::android::hardware::graphics::common::PixelFormat format;
+ ::aidl::android::hardware::graphics::common::BufferUsage usage;
+ buffer_handle_t* bufPtr;
+ int acquireFence;
+ bool fenceTimeout;
+};
+
+struct HalRequest {
+ int32_t frameNumber;
+ common::V1_0::helper::CameraMetadata setting;
+ std::shared_ptr<Frame> frameIn;
+ nsecs_t shutterTs;
+ std::vector<HalStreamBuffer> buffers;
+};
+
+static const uint64_t BUFFER_ID_NO_BUFFER = 0;
+
+// buffers currently circulating between HAL and camera service
+// key: bufferId sent via HIDL interface
+// value: imported buffer_handle_t
+// Buffer will be imported during processCaptureRequest (or requestStreamBuffer
+// in the case of HAL buffer manager is enabled) and will be freed
+// when the stream is deleted or camera device session is closed
+typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
+
+aidl::android::hardware::camera::common::Status importBufferImpl(
+ /*inout*/ std::map<int, CirculatingBuffers>& circulatingBuffers,
+ /*inout*/ HandleImporter& handleImporter, int32_t streamId, uint64_t bufId,
+ buffer_handle_t buf,
+ /*out*/ buffer_handle_t** outBufPtr);
+
+static const uint32_t FLEX_YUV_GENERIC =
+ static_cast<uint32_t>('F') | static_cast<uint32_t>('L') << 8 |
+ static_cast<uint32_t>('E') << 16 | static_cast<uint32_t>('X') << 24;
+
+// returns FLEX_YUV_GENERIC for formats other than YV12/YU12/NV12/NV21
+uint32_t getFourCcFromLayout(const YCbCrLayout&);
+
+using ::android::hardware::camera::external::common::Size;
+int getCropRect(CroppingType ct, const Size& inSize, const Size& outSize, IMapper::Rect* out);
+
+int formatConvert(const YCbCrLayout& in, const YCbCrLayout& out, Size sz, uint32_t format);
+
+int encodeJpegYU12(const Size& inSz, const YCbCrLayout& inLayout, int jpegQuality,
+ const void* app1Buffer, size_t app1Size, void* out, size_t maxOutSize,
+ size_t& actualCodeSize);
+
+Size getMaxThumbnailResolution(const common::V1_0::helper::CameraMetadata&);
+
+void freeReleaseFences(std::vector<CaptureResult>&);
+
+status_t fillCaptureResultCommon(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp,
+ camera_metadata_ro_entry& activeArraySize);
+
+// Interface for OutputThread calling back to parent
+struct OutputThreadInterface {
+ virtual ~OutputThreadInterface() {}
+ virtual aidl::android::hardware::camera::common::Status importBuffer(
+ int32_t streamId, uint64_t bufId, buffer_handle_t buf,
+ /*out*/ buffer_handle_t** outBufPtr) = 0;
+
+ virtual void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) = 0;
+
+ // Callbacks are fired within the method if msgs/results are nullptr.
+ // Otherwise the callbacks will be returned and caller is responsible to
+ // fire the callback later
+ virtual aidl::android::hardware::camera::common::Status processCaptureRequestError(
+ const std::shared_ptr<HalRequest>&,
+ /*out*/ std::vector<NotifyMsg>* msgs,
+ /*out*/ std::vector<CaptureResult>* results) = 0;
+
+ virtual aidl::android::hardware::camera::common::Status processCaptureRequestError(
+ const std::shared_ptr<HalRequest>& reqs) final {
+ return processCaptureRequestError(reqs, nullptr, nullptr);
+ }
+
+ virtual aidl::android::hardware::camera::common::Status processCaptureResult(
+ std::shared_ptr<HalRequest>&) = 0;
+
+ virtual ssize_t getJpegBufferSize(int32_t width, int32_t height) const = 0;
+};
+
+// A CPU copy of a mapped V4L2Frame. Will map the input V4L2 frame.
+class AllocatedV4L2Frame : public Frame {
+ public:
+ AllocatedV4L2Frame(std::shared_ptr<V4L2Frame> frameIn);
+ ~AllocatedV4L2Frame() override;
+ virtual int getData(uint8_t** outData, size_t* dataSize) override;
+
+ private:
+ std::vector<uint8_t> mData;
+};
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERAUTILS_H_
diff --git a/camera/device/default/convert.cpp b/camera/device/default/convert.cpp
new file mode 100644
index 0000000..8134dd5
--- /dev/null
+++ b/camera/device/default/convert.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "[email protected]"
+#include <log/log.h>
+
+#include "convert.h"
+
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <hardware/camera_common.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::device::ErrorCode;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::ShutterMsg;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::common::PixelFormat;
+
+void convertToAidl(const camera_metadata_t* src, CameraMetadata* dest) {
+ if (src == nullptr) {
+ return;
+ }
+
+ size_t size = get_camera_metadata_size(src);
+ auto* src_start = (uint8_t*)src;
+ uint8_t* src_end = src_start + size;
+ dest->metadata.assign(src_start, src_end);
+}
+
+bool convertFromAidl(const CameraMetadata& src, const camera_metadata_t** dst) {
+ const std::vector<uint8_t>& metadata = src.metadata;
+ if (metadata.empty()) {
+ // Special case for null metadata
+ *dst = nullptr;
+ return true;
+ }
+
+ const uint8_t* data = metadata.data();
+ // check that the size of CameraMetadata match underlying camera_metadata_t
+ if (get_camera_metadata_size((camera_metadata_t*)data) != metadata.size()) {
+ ALOGE("%s: input CameraMetadata is corrupt!", __FUNCTION__);
+ return false;
+ }
+ *dst = (camera_metadata_t*)data;
+ return true;
+}
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/device/default/convert.h b/camera/device/default/convert.h
new file mode 100644
index 0000000..5a508fc
--- /dev/null
+++ b/camera/device/default/convert.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
+#define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
+
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <aidl/android/hardware/camera/device/BufferStatus.h>
+#include <aidl/android/hardware/camera/device/CameraMetadata.h>
+#include <aidl/android/hardware/camera/device/HalStream.h>
+#include <aidl/android/hardware/camera/device/NotifyMsg.h>
+#include <aidl/android/hardware/camera/device/Stream.h>
+#include <hardware/camera3.h>
+#include <system/camera_metadata.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace device {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::aidl::android::hardware::camera::device::BufferStatus;
+using ::aidl::android::hardware::camera::device::CameraMetadata;
+using ::aidl::android::hardware::camera::device::HalStream;
+using ::aidl::android::hardware::camera::device::NotifyMsg;
+using ::aidl::android::hardware::camera::device::Stream;
+
+void convertToAidl(const camera_metadata_t* src, CameraMetadata* dest);
+
+bool convertFromAidl(const CameraMetadata& src, const camera_metadata_t** dst);
+
+inline ndk::ScopedAStatus fromStatus(Status status) {
+ return status == Status::OK
+ ? ndk::ScopedAStatus::ok()
+ : ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+} // namespace implementation
+} // namespace device
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_CONVERT_H_
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index 8c13ce5..7bec61d 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -11,7 +11,7 @@
name: "android.hardware.camera.metadata",
vendor_available: true,
srcs: ["android/hardware/camera/metadata/*.aidl"],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
cpp: {
@@ -20,6 +20,9 @@
java: {
enabled: false,
},
+ rust: {
+ enabled: true,
+ }
},
versions_with_info: [
{
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
index 14ad26e..18917f7 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLensFacing.aidl
@@ -38,19 +38,19 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum AutomotiveLensFacing {
- ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER = 0,
- ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT = 1,
- ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR = 2,
- ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT = 3,
- ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT = 4,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER = 5,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT = 6,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER = 7,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT = 8,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT = 9,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER = 10,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT = 11,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT = 12,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER = 13,
- ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT = 14,
+ ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER,
+ ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR,
+ ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER,
+ ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
index 5417bdb..ad6003f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/AutomotiveLocation.aidl
@@ -38,15 +38,15 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum AutomotiveLocation {
- ANDROID_AUTOMOTIVE_LOCATION_INTERIOR = 0,
- ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER = 1,
- ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT = 2,
- ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR = 3,
- ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT = 4,
- ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT = 5,
- ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER = 6,
- ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT = 7,
- ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR = 8,
- ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT = 9,
- ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT = 10,
+ ANDROID_AUTOMOTIVE_LOCATION_INTERIOR,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT,
+ ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl
index dcefa2f..1f3e76f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/BlackLevelLock.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum BlackLevelLock {
- ANDROID_BLACK_LEVEL_LOCK_OFF = 0,
- ANDROID_BLACK_LEVEL_LOCK_ON = 1,
+ ANDROID_BLACK_LEVEL_LOCK_OFF,
+ ANDROID_BLACK_LEVEL_LOCK_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
index 8bed156..138101b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -38,37 +38,39 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum CameraMetadataSection {
- ANDROID_COLOR_CORRECTION = 0,
- ANDROID_CONTROL = 1,
- ANDROID_DEMOSAIC = 2,
- ANDROID_EDGE = 3,
- ANDROID_FLASH = 4,
- ANDROID_FLASH_INFO = 5,
- ANDROID_HOT_PIXEL = 6,
- ANDROID_JPEG = 7,
- ANDROID_LENS = 8,
- ANDROID_LENS_INFO = 9,
- ANDROID_NOISE_REDUCTION = 10,
- ANDROID_QUIRKS = 11,
- ANDROID_REQUEST = 12,
- ANDROID_SCALER = 13,
- ANDROID_SENSOR = 14,
- ANDROID_SENSOR_INFO = 15,
- ANDROID_SHADING = 16,
- ANDROID_STATISTICS = 17,
- ANDROID_STATISTICS_INFO = 18,
- ANDROID_TONEMAP = 19,
- ANDROID_LED = 20,
- ANDROID_INFO = 21,
- ANDROID_BLACK_LEVEL = 22,
- ANDROID_SYNC = 23,
- ANDROID_REPROCESS = 24,
- ANDROID_DEPTH = 25,
- ANDROID_LOGICAL_MULTI_CAMERA = 26,
- ANDROID_DISTORTION_CORRECTION = 27,
- ANDROID_HEIC = 28,
- ANDROID_HEIC_INFO = 29,
- ANDROID_AUTOMOTIVE = 30,
- ANDROID_AUTOMOTIVE_LENS = 31,
- VENDOR_SECTION = 32768,
+ ANDROID_COLOR_CORRECTION,
+ ANDROID_CONTROL,
+ ANDROID_DEMOSAIC,
+ ANDROID_EDGE,
+ ANDROID_FLASH,
+ ANDROID_FLASH_INFO,
+ ANDROID_HOT_PIXEL,
+ ANDROID_JPEG,
+ ANDROID_LENS,
+ ANDROID_LENS_INFO,
+ ANDROID_NOISE_REDUCTION,
+ ANDROID_QUIRKS,
+ ANDROID_REQUEST,
+ ANDROID_SCALER,
+ ANDROID_SENSOR,
+ ANDROID_SENSOR_INFO,
+ ANDROID_SHADING,
+ ANDROID_STATISTICS,
+ ANDROID_STATISTICS_INFO,
+ ANDROID_TONEMAP,
+ ANDROID_LED,
+ ANDROID_INFO,
+ ANDROID_BLACK_LEVEL,
+ ANDROID_SYNC,
+ ANDROID_REPROCESS,
+ ANDROID_DEPTH,
+ ANDROID_LOGICAL_MULTI_CAMERA,
+ ANDROID_DISTORTION_CORRECTION,
+ ANDROID_HEIC,
+ ANDROID_HEIC_INFO,
+ ANDROID_AUTOMOTIVE,
+ ANDROID_AUTOMOTIVE_LENS,
+ ANDROID_EXTENSION,
+ ANDROID_JPEGR,
+ VENDOR_SECTION = 0x8000,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 1725347..85eee08 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -38,37 +38,39 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum CameraMetadataSectionStart {
- ANDROID_COLOR_CORRECTION_START = 0,
- ANDROID_CONTROL_START = 65536,
- ANDROID_DEMOSAIC_START = 131072,
- ANDROID_EDGE_START = 196608,
- ANDROID_FLASH_START = 262144,
- ANDROID_FLASH_INFO_START = 327680,
- ANDROID_HOT_PIXEL_START = 393216,
- ANDROID_JPEG_START = 458752,
- ANDROID_LENS_START = 524288,
- ANDROID_LENS_INFO_START = 589824,
- ANDROID_NOISE_REDUCTION_START = 655360,
- ANDROID_QUIRKS_START = 720896,
- ANDROID_REQUEST_START = 786432,
- ANDROID_SCALER_START = 851968,
- ANDROID_SENSOR_START = 917504,
- ANDROID_SENSOR_INFO_START = 983040,
- ANDROID_SHADING_START = 1048576,
- ANDROID_STATISTICS_START = 1114112,
- ANDROID_STATISTICS_INFO_START = 1179648,
- ANDROID_TONEMAP_START = 1245184,
- ANDROID_LED_START = 1310720,
- ANDROID_INFO_START = 1376256,
- ANDROID_BLACK_LEVEL_START = 1441792,
- ANDROID_SYNC_START = 1507328,
- ANDROID_REPROCESS_START = 1572864,
- ANDROID_DEPTH_START = 1638400,
- ANDROID_LOGICAL_MULTI_CAMERA_START = 1703936,
- ANDROID_DISTORTION_CORRECTION_START = 1769472,
- ANDROID_HEIC_START = 1835008,
- ANDROID_HEIC_INFO_START = 1900544,
- ANDROID_AUTOMOTIVE_START = 1966080,
- ANDROID_AUTOMOTIVE_LENS_START = 2031616,
- VENDOR_SECTION_START = -2147483648,
+ ANDROID_COLOR_CORRECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_COLOR_CORRECTION << 16) /* 0 */,
+ ANDROID_CONTROL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_CONTROL << 16) /* 65536 */,
+ ANDROID_DEMOSAIC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DEMOSAIC << 16) /* 131072 */,
+ ANDROID_EDGE_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EDGE << 16) /* 196608 */,
+ ANDROID_FLASH_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_FLASH << 16) /* 262144 */,
+ ANDROID_FLASH_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_FLASH_INFO << 16) /* 327680 */,
+ ANDROID_HOT_PIXEL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HOT_PIXEL << 16) /* 393216 */,
+ ANDROID_JPEG_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEG << 16) /* 458752 */,
+ ANDROID_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LENS << 16) /* 524288 */,
+ ANDROID_LENS_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LENS_INFO << 16) /* 589824 */,
+ ANDROID_NOISE_REDUCTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_NOISE_REDUCTION << 16) /* 655360 */,
+ ANDROID_QUIRKS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_QUIRKS << 16) /* 720896 */,
+ ANDROID_REQUEST_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_REQUEST << 16) /* 786432 */,
+ ANDROID_SCALER_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SCALER << 16) /* 851968 */,
+ ANDROID_SENSOR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SENSOR << 16) /* 917504 */,
+ ANDROID_SENSOR_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SENSOR_INFO << 16) /* 983040 */,
+ ANDROID_SHADING_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SHADING << 16) /* 1048576 */,
+ ANDROID_STATISTICS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_STATISTICS << 16) /* 1114112 */,
+ ANDROID_STATISTICS_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_STATISTICS_INFO << 16) /* 1179648 */,
+ ANDROID_TONEMAP_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_TONEMAP << 16) /* 1245184 */,
+ ANDROID_LED_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LED << 16) /* 1310720 */,
+ ANDROID_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_INFO << 16) /* 1376256 */,
+ ANDROID_BLACK_LEVEL_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_BLACK_LEVEL << 16) /* 1441792 */,
+ ANDROID_SYNC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SYNC << 16) /* 1507328 */,
+ ANDROID_REPROCESS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_REPROCESS << 16) /* 1572864 */,
+ ANDROID_DEPTH_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DEPTH << 16) /* 1638400 */,
+ ANDROID_LOGICAL_MULTI_CAMERA_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_LOGICAL_MULTI_CAMERA << 16) /* 1703936 */,
+ ANDROID_DISTORTION_CORRECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DISTORTION_CORRECTION << 16) /* 1769472 */,
+ ANDROID_HEIC_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HEIC << 16) /* 1835008 */,
+ ANDROID_HEIC_INFO_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_HEIC_INFO << 16) /* 1900544 */,
+ ANDROID_AUTOMOTIVE_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE << 16) /* 1966080 */,
+ ANDROID_AUTOMOTIVE_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16) /* 2031616 */,
+ ANDROID_EXTENSION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EXTENSION << 16) /* 2097152 */,
+ ANDROID_JPEGR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEGR << 16) /* 2162688 */,
+ VENDOR_SECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.VENDOR_SECTION << 16) /* -2147483648 */,
}
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 9bb55d2..71d4e41 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
@@ -38,294 +38,308 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum CameraMetadataTag {
- ANDROID_COLOR_CORRECTION_MODE = 0,
- ANDROID_COLOR_CORRECTION_TRANSFORM = 1,
- ANDROID_COLOR_CORRECTION_GAINS = 2,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE = 3,
- ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES = 4,
- ANDROID_CONTROL_AE_ANTIBANDING_MODE = 65536,
- ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION = 65537,
- ANDROID_CONTROL_AE_LOCK = 65538,
- ANDROID_CONTROL_AE_MODE = 65539,
- ANDROID_CONTROL_AE_REGIONS = 65540,
- ANDROID_CONTROL_AE_TARGET_FPS_RANGE = 65541,
- ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER = 65542,
- ANDROID_CONTROL_AF_MODE = 65543,
- ANDROID_CONTROL_AF_REGIONS = 65544,
- ANDROID_CONTROL_AF_TRIGGER = 65545,
- ANDROID_CONTROL_AWB_LOCK = 65546,
- ANDROID_CONTROL_AWB_MODE = 65547,
- ANDROID_CONTROL_AWB_REGIONS = 65548,
- ANDROID_CONTROL_CAPTURE_INTENT = 65549,
- ANDROID_CONTROL_EFFECT_MODE = 65550,
- ANDROID_CONTROL_MODE = 65551,
- ANDROID_CONTROL_SCENE_MODE = 65552,
- ANDROID_CONTROL_VIDEO_STABILIZATION_MODE = 65553,
- ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES = 65554,
- ANDROID_CONTROL_AE_AVAILABLE_MODES = 65555,
- ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES = 65556,
- ANDROID_CONTROL_AE_COMPENSATION_RANGE = 65557,
- ANDROID_CONTROL_AE_COMPENSATION_STEP = 65558,
- ANDROID_CONTROL_AF_AVAILABLE_MODES = 65559,
- ANDROID_CONTROL_AVAILABLE_EFFECTS = 65560,
- ANDROID_CONTROL_AVAILABLE_SCENE_MODES = 65561,
- ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES = 65562,
- ANDROID_CONTROL_AWB_AVAILABLE_MODES = 65563,
- ANDROID_CONTROL_MAX_REGIONS = 65564,
- ANDROID_CONTROL_SCENE_MODE_OVERRIDES = 65565,
- ANDROID_CONTROL_AE_PRECAPTURE_ID = 65566,
- ANDROID_CONTROL_AE_STATE = 65567,
- ANDROID_CONTROL_AF_STATE = 65568,
- ANDROID_CONTROL_AF_TRIGGER_ID = 65569,
- ANDROID_CONTROL_AWB_STATE = 65570,
- ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS = 65571,
- ANDROID_CONTROL_AE_LOCK_AVAILABLE = 65572,
- ANDROID_CONTROL_AWB_LOCK_AVAILABLE = 65573,
- ANDROID_CONTROL_AVAILABLE_MODES = 65574,
- ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE = 65575,
- ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST = 65576,
- ANDROID_CONTROL_ENABLE_ZSL = 65577,
- ANDROID_CONTROL_AF_SCENE_CHANGE = 65578,
- ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES = 65579,
- ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES = 65580,
- ANDROID_CONTROL_EXTENDED_SCENE_MODE = 65581,
- ANDROID_CONTROL_ZOOM_RATIO_RANGE = 65582,
- ANDROID_CONTROL_ZOOM_RATIO = 65583,
- ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION = 65584,
- ANDROID_DEMOSAIC_MODE = 131072,
- ANDROID_EDGE_MODE = 196608,
- ANDROID_EDGE_STRENGTH = 196609,
- ANDROID_EDGE_AVAILABLE_EDGE_MODES = 196610,
- ANDROID_FLASH_FIRING_POWER = 262144,
- ANDROID_FLASH_FIRING_TIME = 262145,
- ANDROID_FLASH_MODE = 262146,
- ANDROID_FLASH_COLOR_TEMPERATURE = 262147,
- ANDROID_FLASH_MAX_ENERGY = 262148,
- ANDROID_FLASH_STATE = 262149,
- ANDROID_FLASH_INFO_AVAILABLE = 327680,
- ANDROID_FLASH_INFO_CHARGE_DURATION = 327681,
- ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL = 327682,
- ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL = 327683,
- ANDROID_HOT_PIXEL_MODE = 393216,
- ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES = 393217,
- ANDROID_JPEG_GPS_COORDINATES = 458752,
- ANDROID_JPEG_GPS_PROCESSING_METHOD = 458753,
- ANDROID_JPEG_GPS_TIMESTAMP = 458754,
- ANDROID_JPEG_ORIENTATION = 458755,
- ANDROID_JPEG_QUALITY = 458756,
- ANDROID_JPEG_THUMBNAIL_QUALITY = 458757,
- ANDROID_JPEG_THUMBNAIL_SIZE = 458758,
- ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES = 458759,
- ANDROID_JPEG_MAX_SIZE = 458760,
- ANDROID_JPEG_SIZE = 458761,
- ANDROID_LENS_APERTURE = 524288,
- ANDROID_LENS_FILTER_DENSITY = 524289,
- ANDROID_LENS_FOCAL_LENGTH = 524290,
- ANDROID_LENS_FOCUS_DISTANCE = 524291,
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE = 524292,
- ANDROID_LENS_FACING = 524293,
- ANDROID_LENS_POSE_ROTATION = 524294,
- ANDROID_LENS_POSE_TRANSLATION = 524295,
- ANDROID_LENS_FOCUS_RANGE = 524296,
- ANDROID_LENS_STATE = 524297,
- ANDROID_LENS_INTRINSIC_CALIBRATION = 524298,
- ANDROID_LENS_RADIAL_DISTORTION = 524299,
- ANDROID_LENS_POSE_REFERENCE = 524300,
- ANDROID_LENS_DISTORTION = 524301,
- ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION = 524302,
- ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION = 524303,
- ANDROID_LENS_INFO_AVAILABLE_APERTURES = 589824,
- ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES = 589825,
- ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS = 589826,
- ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION = 589827,
- ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE = 589828,
- ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE = 589829,
- ANDROID_LENS_INFO_SHADING_MAP_SIZE = 589830,
- ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION = 589831,
- ANDROID_NOISE_REDUCTION_MODE = 655360,
- ANDROID_NOISE_REDUCTION_STRENGTH = 655361,
- ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES = 655362,
- ANDROID_QUIRKS_METERING_CROP_REGION = 720896,
- ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO = 720897,
- ANDROID_QUIRKS_USE_ZSL_FORMAT = 720898,
- ANDROID_QUIRKS_USE_PARTIAL_RESULT = 720899,
- ANDROID_QUIRKS_PARTIAL_RESULT = 720900,
- ANDROID_REQUEST_FRAME_COUNT = 786432,
- ANDROID_REQUEST_ID = 786433,
- ANDROID_REQUEST_INPUT_STREAMS = 786434,
- ANDROID_REQUEST_METADATA_MODE = 786435,
- ANDROID_REQUEST_OUTPUT_STREAMS = 786436,
- ANDROID_REQUEST_TYPE = 786437,
- ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS = 786438,
- ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS = 786439,
- ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS = 786440,
- ANDROID_REQUEST_PIPELINE_DEPTH = 786441,
- ANDROID_REQUEST_PIPELINE_MAX_DEPTH = 786442,
- ANDROID_REQUEST_PARTIAL_RESULT_COUNT = 786443,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES = 786444,
- ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS = 786445,
- ANDROID_REQUEST_AVAILABLE_RESULT_KEYS = 786446,
- ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS = 786447,
- ANDROID_REQUEST_AVAILABLE_SESSION_KEYS = 786448,
- ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS = 786449,
- ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION = 786450,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = 786451,
- ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE = 786452,
- ANDROID_SCALER_CROP_REGION = 851968,
- ANDROID_SCALER_AVAILABLE_FORMATS = 851969,
- ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS = 851970,
- ANDROID_SCALER_AVAILABLE_JPEG_SIZES = 851971,
- ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM = 851972,
- ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS = 851973,
- ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES = 851974,
- ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS = 851975,
- ANDROID_SCALER_AVAILABLE_RAW_SIZES = 851976,
- ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP = 851977,
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS = 851978,
- ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS = 851979,
- ANDROID_SCALER_AVAILABLE_STALL_DURATIONS = 851980,
- ANDROID_SCALER_CROPPING_TYPE = 851981,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS = 851982,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP = 851983,
- ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES = 851984,
- ANDROID_SCALER_ROTATE_AND_CROP = 851985,
- ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE = 851986,
- ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS = 851987,
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 851988,
- ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 851989,
- ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION = 851990,
- ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION = 851991,
- ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED = 851992,
+ ANDROID_COLOR_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_COLOR_CORRECTION_START /* 0 */,
+ ANDROID_COLOR_CORRECTION_TRANSFORM,
+ ANDROID_COLOR_CORRECTION_GAINS,
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
+ ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_CONTROL_START /* 65536 */,
+ ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+ ANDROID_CONTROL_AE_LOCK,
+ ANDROID_CONTROL_AE_MODE,
+ ANDROID_CONTROL_AE_REGIONS,
+ ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
+ ANDROID_CONTROL_AF_MODE,
+ ANDROID_CONTROL_AF_REGIONS,
+ ANDROID_CONTROL_AF_TRIGGER,
+ ANDROID_CONTROL_AWB_LOCK,
+ ANDROID_CONTROL_AWB_MODE,
+ ANDROID_CONTROL_AWB_REGIONS,
+ ANDROID_CONTROL_CAPTURE_INTENT,
+ ANDROID_CONTROL_EFFECT_MODE,
+ ANDROID_CONTROL_MODE,
+ ANDROID_CONTROL_SCENE_MODE,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+ ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
+ ANDROID_CONTROL_AE_AVAILABLE_MODES,
+ ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+ ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+ ANDROID_CONTROL_AE_COMPENSATION_STEP,
+ ANDROID_CONTROL_AF_AVAILABLE_MODES,
+ ANDROID_CONTROL_AVAILABLE_EFFECTS,
+ ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
+ ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
+ ANDROID_CONTROL_AWB_AVAILABLE_MODES,
+ ANDROID_CONTROL_MAX_REGIONS,
+ ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
+ ANDROID_CONTROL_AE_PRECAPTURE_ID,
+ ANDROID_CONTROL_AE_STATE,
+ ANDROID_CONTROL_AF_STATE,
+ ANDROID_CONTROL_AF_TRIGGER_ID,
+ ANDROID_CONTROL_AWB_STATE,
+ ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,
+ ANDROID_CONTROL_AE_LOCK_AVAILABLE,
+ ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
+ ANDROID_CONTROL_AVAILABLE_MODES,
+ ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,
+ ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST,
+ ANDROID_CONTROL_ENABLE_ZSL,
+ ANDROID_CONTROL_AF_SCENE_CHANGE,
+ ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES,
+ ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES,
+ ANDROID_CONTROL_EXTENDED_SCENE_MODE,
+ ANDROID_CONTROL_ZOOM_RATIO_RANGE,
+ ANDROID_CONTROL_ZOOM_RATIO,
+ ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE = 65588,
+ ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
+ ANDROID_CONTROL_AUTOFRAMING,
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
+ ANDROID_CONTROL_AUTOFRAMING_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,
+ ANDROID_EDGE_AVAILABLE_EDGE_MODES,
+ ANDROID_FLASH_FIRING_POWER = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_FLASH_START /* 262144 */,
+ ANDROID_FLASH_FIRING_TIME,
+ ANDROID_FLASH_MODE,
+ ANDROID_FLASH_COLOR_TEMPERATURE,
+ ANDROID_FLASH_MAX_ENERGY,
+ ANDROID_FLASH_STATE,
+ ANDROID_FLASH_INFO_AVAILABLE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_FLASH_INFO_START /* 327680 */,
+ ANDROID_FLASH_INFO_CHARGE_DURATION,
+ ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL,
+ ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
+ ANDROID_HOT_PIXEL_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HOT_PIXEL_START /* 393216 */,
+ ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+ ANDROID_JPEG_GPS_COORDINATES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEG_START /* 458752 */,
+ ANDROID_JPEG_GPS_PROCESSING_METHOD,
+ ANDROID_JPEG_GPS_TIMESTAMP,
+ ANDROID_JPEG_ORIENTATION,
+ ANDROID_JPEG_QUALITY,
+ ANDROID_JPEG_THUMBNAIL_QUALITY,
+ ANDROID_JPEG_THUMBNAIL_SIZE,
+ ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+ ANDROID_JPEG_MAX_SIZE,
+ ANDROID_JPEG_SIZE,
+ ANDROID_LENS_APERTURE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LENS_START /* 524288 */,
+ ANDROID_LENS_FILTER_DENSITY,
+ ANDROID_LENS_FOCAL_LENGTH,
+ ANDROID_LENS_FOCUS_DISTANCE,
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
+ ANDROID_LENS_FACING,
+ ANDROID_LENS_POSE_ROTATION,
+ ANDROID_LENS_POSE_TRANSLATION,
+ ANDROID_LENS_FOCUS_RANGE,
+ ANDROID_LENS_STATE,
+ ANDROID_LENS_INTRINSIC_CALIBRATION,
+ ANDROID_LENS_RADIAL_DISTORTION,
+ ANDROID_LENS_POSE_REFERENCE,
+ ANDROID_LENS_DISTORTION,
+ ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION,
+ ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION,
+ ANDROID_LENS_INFO_AVAILABLE_APERTURES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LENS_INFO_START /* 589824 */,
+ ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES,
+ ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
+ ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
+ ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
+ ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
+ ANDROID_LENS_INFO_SHADING_MAP_SIZE,
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,
+ ANDROID_NOISE_REDUCTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_NOISE_REDUCTION_START /* 655360 */,
+ ANDROID_NOISE_REDUCTION_STRENGTH,
+ ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+ ANDROID_QUIRKS_METERING_CROP_REGION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_QUIRKS_START /* 720896 */,
+ ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
+ ANDROID_QUIRKS_USE_ZSL_FORMAT,
+ ANDROID_QUIRKS_USE_PARTIAL_RESULT,
+ ANDROID_QUIRKS_PARTIAL_RESULT,
+ ANDROID_REQUEST_FRAME_COUNT = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_REQUEST_START /* 786432 */,
+ ANDROID_REQUEST_ID,
+ ANDROID_REQUEST_INPUT_STREAMS,
+ ANDROID_REQUEST_METADATA_MODE,
+ ANDROID_REQUEST_OUTPUT_STREAMS,
+ ANDROID_REQUEST_TYPE,
+ ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+ ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
+ ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
+ ANDROID_REQUEST_PIPELINE_DEPTH,
+ ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
+ ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+ ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
+ ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
+ ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
+ ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
+ ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS,
+ ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP,
+ ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+ ANDROID_SCALER_CROP_REGION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SCALER_START /* 851968 */,
+ ANDROID_SCALER_AVAILABLE_FORMATS,
+ ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
+ ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+ ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+ ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
+ ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+ ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
+ ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+ ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
+ ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
+ ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
+ ANDROID_SCALER_CROPPING_TYPE,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP,
+ ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES,
+ ANDROID_SCALER_ROTATE_AND_CROP,
+ ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE,
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION,
+ ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
- ANDROID_SENSOR_EXPOSURE_TIME = 917504,
- ANDROID_SENSOR_FRAME_DURATION = 917505,
- ANDROID_SENSOR_SENSITIVITY = 917506,
- ANDROID_SENSOR_REFERENCE_ILLUMINANT1 = 917507,
- ANDROID_SENSOR_REFERENCE_ILLUMINANT2 = 917508,
- ANDROID_SENSOR_CALIBRATION_TRANSFORM1 = 917509,
- ANDROID_SENSOR_CALIBRATION_TRANSFORM2 = 917510,
- ANDROID_SENSOR_COLOR_TRANSFORM1 = 917511,
- ANDROID_SENSOR_COLOR_TRANSFORM2 = 917512,
- ANDROID_SENSOR_FORWARD_MATRIX1 = 917513,
- ANDROID_SENSOR_FORWARD_MATRIX2 = 917514,
- ANDROID_SENSOR_BASE_GAIN_FACTOR = 917515,
- ANDROID_SENSOR_BLACK_LEVEL_PATTERN = 917516,
- ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY = 917517,
- ANDROID_SENSOR_ORIENTATION = 917518,
- ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS = 917519,
- ANDROID_SENSOR_TIMESTAMP = 917520,
- ANDROID_SENSOR_TEMPERATURE = 917521,
- ANDROID_SENSOR_NEUTRAL_COLOR_POINT = 917522,
- ANDROID_SENSOR_NOISE_PROFILE = 917523,
- ANDROID_SENSOR_PROFILE_HUE_SAT_MAP = 917524,
- ANDROID_SENSOR_PROFILE_TONE_CURVE = 917525,
- ANDROID_SENSOR_GREEN_SPLIT = 917526,
- ANDROID_SENSOR_TEST_PATTERN_DATA = 917527,
- ANDROID_SENSOR_TEST_PATTERN_MODE = 917528,
- ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES = 917529,
- ANDROID_SENSOR_ROLLING_SHUTTER_SKEW = 917530,
- ANDROID_SENSOR_OPTICAL_BLACK_REGIONS = 917531,
- ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL = 917532,
- ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL = 917533,
- ANDROID_SENSOR_OPAQUE_RAW_SIZE = 917534,
- ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION = 917535,
- ANDROID_SENSOR_PIXEL_MODE = 917536,
- ANDROID_SENSOR_RAW_BINNING_FACTOR_USED = 917537,
- ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = 983040,
- ANDROID_SENSOR_INFO_SENSITIVITY_RANGE = 983041,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT = 983042,
- ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE = 983043,
- ANDROID_SENSOR_INFO_MAX_FRAME_DURATION = 983044,
- ANDROID_SENSOR_INFO_PHYSICAL_SIZE = 983045,
- ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE = 983046,
- ANDROID_SENSOR_INFO_WHITE_LEVEL = 983047,
- ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE = 983048,
- ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED = 983049,
- ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE = 983050,
- ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION = 983051,
- ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION = 983052,
- ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION = 983053,
- ANDROID_SENSOR_INFO_BINNING_FACTOR = 983054,
- ANDROID_SHADING_MODE = 1048576,
- ANDROID_SHADING_STRENGTH = 1048577,
- ANDROID_SHADING_AVAILABLE_MODES = 1048578,
- ANDROID_STATISTICS_FACE_DETECT_MODE = 1114112,
- ANDROID_STATISTICS_HISTOGRAM_MODE = 1114113,
- ANDROID_STATISTICS_SHARPNESS_MAP_MODE = 1114114,
- ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE = 1114115,
- ANDROID_STATISTICS_FACE_IDS = 1114116,
- ANDROID_STATISTICS_FACE_LANDMARKS = 1114117,
- ANDROID_STATISTICS_FACE_RECTANGLES = 1114118,
- ANDROID_STATISTICS_FACE_SCORES = 1114119,
- ANDROID_STATISTICS_HISTOGRAM = 1114120,
- ANDROID_STATISTICS_SHARPNESS_MAP = 1114121,
- ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP = 1114122,
- ANDROID_STATISTICS_LENS_SHADING_MAP = 1114123,
- ANDROID_STATISTICS_PREDICTED_COLOR_GAINS = 1114124,
- ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM = 1114125,
- ANDROID_STATISTICS_SCENE_FLICKER = 1114126,
- ANDROID_STATISTICS_HOT_PIXEL_MAP = 1114127,
- ANDROID_STATISTICS_LENS_SHADING_MAP_MODE = 1114128,
- ANDROID_STATISTICS_OIS_DATA_MODE = 1114129,
- ANDROID_STATISTICS_OIS_TIMESTAMPS = 1114130,
- ANDROID_STATISTICS_OIS_X_SHIFTS = 1114131,
- ANDROID_STATISTICS_OIS_Y_SHIFTS = 1114132,
- ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = 1179648,
- ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT = 1179649,
- ANDROID_STATISTICS_INFO_MAX_FACE_COUNT = 1179650,
- ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT = 1179651,
- ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE = 1179652,
- ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE = 1179653,
- ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES = 1179654,
- ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES = 1179655,
- ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES = 1179656,
- ANDROID_TONEMAP_CURVE_BLUE = 1245184,
- ANDROID_TONEMAP_CURVE_GREEN = 1245185,
- ANDROID_TONEMAP_CURVE_RED = 1245186,
- ANDROID_TONEMAP_MODE = 1245187,
- ANDROID_TONEMAP_MAX_CURVE_POINTS = 1245188,
- ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES = 1245189,
- ANDROID_TONEMAP_GAMMA = 1245190,
- ANDROID_TONEMAP_PRESET_CURVE = 1245191,
- ANDROID_LED_TRANSMIT = 1310720,
- ANDROID_LED_AVAILABLE_LEDS = 1310721,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL = 1376256,
- ANDROID_INFO_VERSION = 1376257,
- ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION = 1376258,
- ANDROID_INFO_DEVICE_STATE_ORIENTATIONS = 1376259,
- ANDROID_BLACK_LEVEL_LOCK = 1441792,
- ANDROID_SYNC_FRAME_NUMBER = 1507328,
- ANDROID_SYNC_MAX_LATENCY = 1507329,
- ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR = 1572864,
- ANDROID_REPROCESS_MAX_CAPTURE_STALL = 1572865,
- ANDROID_DEPTH_MAX_DEPTH_SAMPLES = 1638400,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS = 1638401,
- ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS = 1638402,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS = 1638403,
- ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE = 1638404,
- ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS = 1638405,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS = 1638406,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS = 1638407,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS = 1638408,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 1638409,
- ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 1638410,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1638411,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 1638412,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 1638413,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1638414,
- ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = 1703936,
- ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE = 1703937,
- ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID = 1703938,
- ANDROID_DISTORTION_CORRECTION_MODE = 1769472,
- ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES = 1769473,
- ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = 1835008,
- ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS = 1835009,
- ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS = 1835010,
- ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = 1835011,
- ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION = 1835012,
- ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION = 1835013,
- ANDROID_HEIC_INFO_SUPPORTED = 1900544,
- ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT = 1900545,
- ANDROID_AUTOMOTIVE_LOCATION = 1966080,
- ANDROID_AUTOMOTIVE_LENS_FACING = 2031616,
+ ANDROID_SCALER_RAW_CROP_REGION,
+ ANDROID_SENSOR_EXPOSURE_TIME = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_START /* 917504 */,
+ ANDROID_SENSOR_FRAME_DURATION,
+ ANDROID_SENSOR_SENSITIVITY,
+ ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
+ ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
+ ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
+ ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
+ ANDROID_SENSOR_COLOR_TRANSFORM1,
+ ANDROID_SENSOR_COLOR_TRANSFORM2,
+ ANDROID_SENSOR_FORWARD_MATRIX1,
+ ANDROID_SENSOR_FORWARD_MATRIX2,
+ ANDROID_SENSOR_BASE_GAIN_FACTOR,
+ ANDROID_SENSOR_BLACK_LEVEL_PATTERN,
+ ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY,
+ ANDROID_SENSOR_ORIENTATION,
+ ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
+ ANDROID_SENSOR_TIMESTAMP,
+ ANDROID_SENSOR_TEMPERATURE,
+ ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
+ ANDROID_SENSOR_NOISE_PROFILE,
+ ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
+ ANDROID_SENSOR_PROFILE_TONE_CURVE,
+ ANDROID_SENSOR_GREEN_SPLIT,
+ ANDROID_SENSOR_TEST_PATTERN_DATA,
+ ANDROID_SENSOR_TEST_PATTERN_MODE,
+ ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
+ ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
+ ANDROID_SENSOR_OPTICAL_BLACK_REGIONS,
+ ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL,
+ ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL,
+ ANDROID_SENSOR_OPAQUE_RAW_SIZE,
+ ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_PIXEL_MODE,
+ ANDROID_SENSOR_RAW_BINNING_FACTOR_USED,
+ ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SENSOR_INFO_START /* 983040 */,
+ ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
+ ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
+ ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+ ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
+ ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+ ANDROID_SENSOR_INFO_WHITE_LEVEL,
+ ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
+ ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED,
+ ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
+ ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION,
+ ANDROID_SENSOR_INFO_BINNING_FACTOR,
+ ANDROID_SHADING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SHADING_START /* 1048576 */,
+ ANDROID_SHADING_STRENGTH,
+ ANDROID_SHADING_AVAILABLE_MODES,
+ ANDROID_STATISTICS_FACE_DETECT_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_START /* 1114112 */,
+ ANDROID_STATISTICS_HISTOGRAM_MODE,
+ ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
+ ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
+ ANDROID_STATISTICS_FACE_IDS,
+ ANDROID_STATISTICS_FACE_LANDMARKS,
+ ANDROID_STATISTICS_FACE_RECTANGLES,
+ ANDROID_STATISTICS_FACE_SCORES,
+ ANDROID_STATISTICS_HISTOGRAM,
+ ANDROID_STATISTICS_SHARPNESS_MAP,
+ ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP,
+ ANDROID_STATISTICS_LENS_SHADING_MAP,
+ ANDROID_STATISTICS_PREDICTED_COLOR_GAINS,
+ ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM,
+ ANDROID_STATISTICS_SCENE_FLICKER,
+ ANDROID_STATISTICS_HOT_PIXEL_MAP,
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
+ ANDROID_STATISTICS_OIS_DATA_MODE,
+ ANDROID_STATISTICS_OIS_TIMESTAMPS,
+ ANDROID_STATISTICS_OIS_X_SHIFTS,
+ ANDROID_STATISTICS_OIS_Y_SHIFTS,
+ 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,
+ ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
+ ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
+ ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+ ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,
+ ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
+ ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES,
+ ANDROID_TONEMAP_CURVE_BLUE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_TONEMAP_START /* 1245184 */,
+ ANDROID_TONEMAP_CURVE_GREEN,
+ ANDROID_TONEMAP_CURVE_RED,
+ ANDROID_TONEMAP_MODE,
+ ANDROID_TONEMAP_MAX_CURVE_POINTS,
+ ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES,
+ ANDROID_TONEMAP_GAMMA,
+ ANDROID_TONEMAP_PRESET_CURVE,
+ ANDROID_LED_TRANSMIT = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LED_START /* 1310720 */,
+ ANDROID_LED_AVAILABLE_LEDS,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_INFO_START /* 1376256 */,
+ ANDROID_INFO_VERSION,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
+ ANDROID_INFO_DEVICE_STATE_ORIENTATIONS,
+ ANDROID_BLACK_LEVEL_LOCK = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_BLACK_LEVEL_START /* 1441792 */,
+ ANDROID_SYNC_FRAME_NUMBER = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_SYNC_START /* 1507328 */,
+ ANDROID_SYNC_MAX_LATENCY,
+ ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_REPROCESS_START /* 1572864 */,
+ ANDROID_REPROCESS_MAX_CAPTURE_STALL,
+ ANDROID_DEPTH_MAX_DEPTH_SAMPLES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEPTH_START /* 1638400 */,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,
+ ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE,
+ ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ 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_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 */,
+ ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS,
+ ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS,
+ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_HEIC_INFO_SUPPORTED = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_INFO_START /* 1900544 */,
+ ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
+ ANDROID_AUTOMOTIVE_LOCATION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_START /* 1966080 */,
+ ANDROID_AUTOMOTIVE_LENS_FACING = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START /* 2031616 */,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEGR_START /* 2162688 */,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
index d04ffe3..0b976f3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionAberrationMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ColorCorrectionAberrationMode {
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF = 0,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST = 1,
- ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY = 2,
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST,
+ ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
index 219c802..2381605 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ColorCorrectionMode {
- ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0,
- ANDROID_COLOR_CORRECTION_MODE_FAST = 1,
- ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY = 2,
+ ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX,
+ ANDROID_COLOR_CORRECTION_MODE_FAST,
+ ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
index 84fd718..0d5aad9 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeAntibandingMode.aidl
@@ -38,8 +38,8 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAeAntibandingMode {
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF = 0,
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ = 1,
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ = 2,
- ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO = 3,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
+ ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl
index f825f11..766b835 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLock.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAeLock {
- ANDROID_CONTROL_AE_LOCK_OFF = 0,
- ANDROID_CONTROL_AE_LOCK_ON = 1,
+ ANDROID_CONTROL_AE_LOCK_OFF,
+ ANDROID_CONTROL_AE_LOCK_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
index df7924e..a22c93e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeLockAvailable.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAeLockAvailable {
- ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE = 0,
- ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE = 1,
+ ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE,
+ ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE,
}
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 75a3486..5e1b871 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
@@ -38,10 +38,10 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAeMode {
- ANDROID_CONTROL_AE_MODE_OFF = 0,
- ANDROID_CONTROL_AE_MODE_ON = 1,
- ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH = 2,
- ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3,
- ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4,
- ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH = 5,
+ ANDROID_CONTROL_AE_MODE_OFF,
+ ANDROID_CONTROL_AE_MODE_ON,
+ ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
+ ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
index 4678e01..20382c0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePrecaptureTrigger.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAePrecaptureTrigger {
- ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0,
- ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START = 1,
- ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL = 2,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START,
+ ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl
index 3be64ea..e52eafe 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeState.aidl
@@ -38,10 +38,10 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAeState {
- ANDROID_CONTROL_AE_STATE_INACTIVE = 0,
- ANDROID_CONTROL_AE_STATE_SEARCHING = 1,
- ANDROID_CONTROL_AE_STATE_CONVERGED = 2,
- ANDROID_CONTROL_AE_STATE_LOCKED = 3,
- ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED = 4,
- ANDROID_CONTROL_AE_STATE_PRECAPTURE = 5,
+ ANDROID_CONTROL_AE_STATE_INACTIVE,
+ ANDROID_CONTROL_AE_STATE_SEARCHING,
+ ANDROID_CONTROL_AE_STATE_CONVERGED,
+ ANDROID_CONTROL_AE_STATE_LOCKED,
+ ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED,
+ ANDROID_CONTROL_AE_STATE_PRECAPTURE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl
index 155d3c9..6cd46c6 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfMode.aidl
@@ -38,10 +38,10 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAfMode {
- ANDROID_CONTROL_AF_MODE_OFF = 0,
- ANDROID_CONTROL_AF_MODE_AUTO = 1,
- ANDROID_CONTROL_AF_MODE_MACRO = 2,
- ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3,
- ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4,
- ANDROID_CONTROL_AF_MODE_EDOF = 5,
+ ANDROID_CONTROL_AF_MODE_OFF,
+ ANDROID_CONTROL_AF_MODE_AUTO,
+ ANDROID_CONTROL_AF_MODE_MACRO,
+ ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO,
+ ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE,
+ ANDROID_CONTROL_AF_MODE_EDOF,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl
index 4b31c84..ba853a1 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfSceneChange.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAfSceneChange {
- ANDROID_CONTROL_AF_SCENE_CHANGE_NOT_DETECTED = 0,
- ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED = 1,
+ ANDROID_CONTROL_AF_SCENE_CHANGE_NOT_DETECTED,
+ ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl
index 4aac8c8..25b6a1c 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfState.aidl
@@ -38,11 +38,11 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAfState {
- ANDROID_CONTROL_AF_STATE_INACTIVE = 0,
- ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN = 1,
- ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED = 2,
- ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN = 3,
- ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED = 4,
- ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5,
- ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6,
+ ANDROID_CONTROL_AF_STATE_INACTIVE,
+ ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN,
+ ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED,
+ ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN,
+ ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED,
+ ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED,
+ ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl
index 3fbf94b..9d61b2d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAfTrigger.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAfTrigger {
- ANDROID_CONTROL_AF_TRIGGER_IDLE = 0,
- ANDROID_CONTROL_AF_TRIGGER_START = 1,
- ANDROID_CONTROL_AF_TRIGGER_CANCEL = 2,
+ ANDROID_CONTROL_AF_TRIGGER_IDLE,
+ ANDROID_CONTROL_AF_TRIGGER_START,
+ ANDROID_CONTROL_AF_TRIGGER_CANCEL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframing.aidl
new file mode 100644
index 0000000..2daf00b
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframing.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 ControlAutoframing {
+ ANDROID_CONTROL_AUTOFRAMING_OFF,
+ ANDROID_CONTROL_AUTOFRAMING_ON,
+ ANDROID_CONTROL_AUTOFRAMING_AUTO,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
new file mode 100644
index 0000000..ab91bb4
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingAvailable.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 ControlAutoframingAvailable {
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE,
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingState.aidl
new file mode 100644
index 0000000..db0d288
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAutoframingState.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 ControlAutoframingState {
+ ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE,
+ ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING,
+ ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl
index 0e297a5..949b5e8 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLock.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAwbLock {
- ANDROID_CONTROL_AWB_LOCK_OFF = 0,
- ANDROID_CONTROL_AWB_LOCK_ON = 1,
+ ANDROID_CONTROL_AWB_LOCK_OFF,
+ ANDROID_CONTROL_AWB_LOCK_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
index d471d19..80c4c31 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbLockAvailable.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAwbLockAvailable {
- ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE = 0,
- ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE = 1,
+ ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE,
+ ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl
index a3463f8..6ed9ece 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbMode.aidl
@@ -38,13 +38,13 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAwbMode {
- ANDROID_CONTROL_AWB_MODE_OFF = 0,
- ANDROID_CONTROL_AWB_MODE_AUTO = 1,
- ANDROID_CONTROL_AWB_MODE_INCANDESCENT = 2,
- ANDROID_CONTROL_AWB_MODE_FLUORESCENT = 3,
- ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT = 4,
- ANDROID_CONTROL_AWB_MODE_DAYLIGHT = 5,
- ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6,
- ANDROID_CONTROL_AWB_MODE_TWILIGHT = 7,
- ANDROID_CONTROL_AWB_MODE_SHADE = 8,
+ ANDROID_CONTROL_AWB_MODE_OFF,
+ ANDROID_CONTROL_AWB_MODE_AUTO,
+ ANDROID_CONTROL_AWB_MODE_INCANDESCENT,
+ ANDROID_CONTROL_AWB_MODE_FLUORESCENT,
+ ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT,
+ ANDROID_CONTROL_AWB_MODE_DAYLIGHT,
+ ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT,
+ ANDROID_CONTROL_AWB_MODE_TWILIGHT,
+ ANDROID_CONTROL_AWB_MODE_SHADE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl
index f1b0e40..c5b02d5 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAwbState.aidl
@@ -38,8 +38,8 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlAwbState {
- ANDROID_CONTROL_AWB_STATE_INACTIVE = 0,
- ANDROID_CONTROL_AWB_STATE_SEARCHING = 1,
- ANDROID_CONTROL_AWB_STATE_CONVERGED = 2,
- ANDROID_CONTROL_AWB_STATE_LOCKED = 3,
+ ANDROID_CONTROL_AWB_STATE_INACTIVE,
+ ANDROID_CONTROL_AWB_STATE_SEARCHING,
+ ANDROID_CONTROL_AWB_STATE_CONVERGED,
+ ANDROID_CONTROL_AWB_STATE_LOCKED,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl
index 283bb1b..fa1c0a9 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlCaptureIntent.aidl
@@ -38,12 +38,12 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlCaptureIntent {
- ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM = 0,
- ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW = 1,
- ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2,
- ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3,
- ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4,
- ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5,
- ANDROID_CONTROL_CAPTURE_INTENT_MANUAL = 6,
- ANDROID_CONTROL_CAPTURE_INTENT_MOTION_TRACKING = 7,
+ ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM,
+ ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW,
+ ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE,
+ ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD,
+ ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT,
+ ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG,
+ ANDROID_CONTROL_CAPTURE_INTENT_MANUAL,
+ ANDROID_CONTROL_CAPTURE_INTENT_MOTION_TRACKING,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl
index 911223d..471deed 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEffectMode.aidl
@@ -38,13 +38,13 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlEffectMode {
- ANDROID_CONTROL_EFFECT_MODE_OFF = 0,
- ANDROID_CONTROL_EFFECT_MODE_MONO = 1,
- ANDROID_CONTROL_EFFECT_MODE_NEGATIVE = 2,
- ANDROID_CONTROL_EFFECT_MODE_SOLARIZE = 3,
- ANDROID_CONTROL_EFFECT_MODE_SEPIA = 4,
- ANDROID_CONTROL_EFFECT_MODE_POSTERIZE = 5,
- ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD = 6,
- ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD = 7,
- ANDROID_CONTROL_EFFECT_MODE_AQUA = 8,
+ ANDROID_CONTROL_EFFECT_MODE_OFF,
+ ANDROID_CONTROL_EFFECT_MODE_MONO,
+ ANDROID_CONTROL_EFFECT_MODE_NEGATIVE,
+ ANDROID_CONTROL_EFFECT_MODE_SOLARIZE,
+ ANDROID_CONTROL_EFFECT_MODE_SEPIA,
+ ANDROID_CONTROL_EFFECT_MODE_POSTERIZE,
+ ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD,
+ ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD,
+ ANDROID_CONTROL_EFFECT_MODE_AQUA,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl
index 920def7..3f2d4a3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlEnableZsl.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlEnableZsl {
- ANDROID_CONTROL_ENABLE_ZSL_FALSE = 0,
- ANDROID_CONTROL_ENABLE_ZSL_TRUE = 1,
+ ANDROID_CONTROL_ENABLE_ZSL_FALSE,
+ ANDROID_CONTROL_ENABLE_ZSL_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
index 2655d61..7838288 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlExtendedSceneMode.aidl
@@ -39,7 +39,7 @@
@Backing(type="int") @VintfStability
enum ControlExtendedSceneMode {
ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED = 0,
- ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE = 1,
- ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS = 2,
- ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START = 64,
+ ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE,
+ ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS,
+ ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START = 0x40,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl
index f58491e..c5a8172 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlMode.aidl
@@ -38,9 +38,9 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlMode {
- ANDROID_CONTROL_MODE_OFF = 0,
- ANDROID_CONTROL_MODE_AUTO = 1,
- ANDROID_CONTROL_MODE_USE_SCENE_MODE = 2,
- ANDROID_CONTROL_MODE_OFF_KEEP_STATE = 3,
- ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE = 4,
+ ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_MODE_AUTO,
+ ANDROID_CONTROL_MODE_USE_SCENE_MODE,
+ ANDROID_CONTROL_MODE_OFF_KEEP_STATE,
+ ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl
index 994bbf3..62c67e3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSceneMode.aidl
@@ -39,25 +39,25 @@
@Backing(type="int") @VintfStability
enum ControlSceneMode {
ANDROID_CONTROL_SCENE_MODE_DISABLED = 0,
- ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY = 1,
- ANDROID_CONTROL_SCENE_MODE_ACTION = 2,
- ANDROID_CONTROL_SCENE_MODE_PORTRAIT = 3,
- ANDROID_CONTROL_SCENE_MODE_LANDSCAPE = 4,
- ANDROID_CONTROL_SCENE_MODE_NIGHT = 5,
- ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6,
- ANDROID_CONTROL_SCENE_MODE_THEATRE = 7,
- ANDROID_CONTROL_SCENE_MODE_BEACH = 8,
- ANDROID_CONTROL_SCENE_MODE_SNOW = 9,
- ANDROID_CONTROL_SCENE_MODE_SUNSET = 10,
- ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO = 11,
- ANDROID_CONTROL_SCENE_MODE_FIREWORKS = 12,
- ANDROID_CONTROL_SCENE_MODE_SPORTS = 13,
- ANDROID_CONTROL_SCENE_MODE_PARTY = 14,
- ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT = 15,
- ANDROID_CONTROL_SCENE_MODE_BARCODE = 16,
- ANDROID_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17,
- ANDROID_CONTROL_SCENE_MODE_HDR = 18,
- ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT = 19,
+ ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY,
+ ANDROID_CONTROL_SCENE_MODE_ACTION,
+ ANDROID_CONTROL_SCENE_MODE_PORTRAIT,
+ ANDROID_CONTROL_SCENE_MODE_LANDSCAPE,
+ ANDROID_CONTROL_SCENE_MODE_NIGHT,
+ ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT,
+ ANDROID_CONTROL_SCENE_MODE_THEATRE,
+ ANDROID_CONTROL_SCENE_MODE_BEACH,
+ ANDROID_CONTROL_SCENE_MODE_SNOW,
+ ANDROID_CONTROL_SCENE_MODE_SUNSET,
+ ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO,
+ ANDROID_CONTROL_SCENE_MODE_FIREWORKS,
+ ANDROID_CONTROL_SCENE_MODE_SPORTS,
+ ANDROID_CONTROL_SCENE_MODE_PARTY,
+ ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT,
+ ANDROID_CONTROL_SCENE_MODE_BARCODE,
+ ANDROID_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO,
+ ANDROID_CONTROL_SCENE_MODE_HDR,
+ ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT,
ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_START = 100,
ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_END = 127,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSettingsOverride.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSettingsOverride.aidl
new file mode 100644
index 0000000..404bbfa
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlSettingsOverride.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 ControlSettingsOverride {
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START = 0x4000,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
index b3b24f7..2b199ef 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlVideoStabilizationMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ControlVideoStabilizationMode {
- ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0,
- ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON = 1,
- ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION = 2,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON,
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl
index 26874a2..5770009 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DemosaicMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DemosaicMode {
- ANDROID_DEMOSAIC_MODE_FAST = 0,
- ANDROID_DEMOSAIC_MODE_HIGH_QUALITY = 1,
+ ANDROID_DEMOSAIC_MODE_FAST,
+ ANDROID_DEMOSAIC_MODE_HIGH_QUALITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
index 6a154ca..0cce2da 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurations.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DepthAvailableDepthStreamConfigurations {
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT = 0,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT = 1,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
index 23d6589..9be06db 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDepthStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DepthAvailableDepthStreamConfigurationsMaximumResolution {
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
index f3ca039..c6aebaa 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurations.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DepthAvailableDynamicDepthStreamConfigurations {
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT = 0,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT = 1,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
index 46a4ce6..4d5161d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DepthAvailableDynamicDepthStreamConfigurationsMaximumResolution {
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
- ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
index f5fc218..f7b69cd 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DepthDepthIsExclusive.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DepthDepthIsExclusive {
- ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE = 0,
- ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE = 1,
+ ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE,
+ ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
index 46327e0..6e965f6 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DistortionCorrectionMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum DistortionCorrectionMode {
- ANDROID_DISTORTION_CORRECTION_MODE_OFF = 0,
- ANDROID_DISTORTION_CORRECTION_MODE_FAST = 1,
- ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY = 2,
+ ANDROID_DISTORTION_CORRECTION_MODE_OFF,
+ ANDROID_DISTORTION_CORRECTION_MODE_FAST,
+ ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl
index 4b02e19..fdd32f4 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/EdgeMode.aidl
@@ -38,8 +38,8 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum EdgeMode {
- ANDROID_EDGE_MODE_OFF = 0,
- ANDROID_EDGE_MODE_FAST = 1,
- ANDROID_EDGE_MODE_HIGH_QUALITY = 2,
- ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG = 3,
+ ANDROID_EDGE_MODE_OFF,
+ ANDROID_EDGE_MODE_FAST,
+ ANDROID_EDGE_MODE_HIGH_QUALITY,
+ ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl
index 10d07a5..83292fe 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashInfoAvailable.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum FlashInfoAvailable {
- ANDROID_FLASH_INFO_AVAILABLE_FALSE = 0,
- ANDROID_FLASH_INFO_AVAILABLE_TRUE = 1,
+ ANDROID_FLASH_INFO_AVAILABLE_FALSE,
+ ANDROID_FLASH_INFO_AVAILABLE_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl
index 1ab0560..e18ea3c 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum FlashMode {
- ANDROID_FLASH_MODE_OFF = 0,
- ANDROID_FLASH_MODE_SINGLE = 1,
- ANDROID_FLASH_MODE_TORCH = 2,
+ ANDROID_FLASH_MODE_OFF,
+ ANDROID_FLASH_MODE_SINGLE,
+ ANDROID_FLASH_MODE_TORCH,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl
index a571e66..4343d4f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/FlashState.aidl
@@ -38,9 +38,9 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum FlashState {
- ANDROID_FLASH_STATE_UNAVAILABLE = 0,
- ANDROID_FLASH_STATE_CHARGING = 1,
- ANDROID_FLASH_STATE_READY = 2,
- ANDROID_FLASH_STATE_FIRED = 3,
- ANDROID_FLASH_STATE_PARTIAL = 4,
+ ANDROID_FLASH_STATE_UNAVAILABLE,
+ ANDROID_FLASH_STATE_CHARGING,
+ ANDROID_FLASH_STATE_READY,
+ ANDROID_FLASH_STATE_FIRED,
+ ANDROID_FLASH_STATE_PARTIAL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
index d92c2db..3957267 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurations.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum HeicAvailableHeicStreamConfigurations {
- ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT = 0,
- ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT = 1,
+ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
index f02cf58..4eda538 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum HeicAvailableHeicStreamConfigurationsMaximumResolution {
- ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
- ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl
index ae5a8e7..7079bbf 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicInfoSupported.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum HeicInfoSupported {
- ANDROID_HEIC_INFO_SUPPORTED_FALSE = 0,
- ANDROID_HEIC_INFO_SUPPORTED_TRUE = 1,
+ ANDROID_HEIC_INFO_SUPPORTED_FALSE,
+ ANDROID_HEIC_INFO_SUPPORTED_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl
index 1248c60..50b3446 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HotPixelMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum HotPixelMode {
- ANDROID_HOT_PIXEL_MODE_OFF = 0,
- ANDROID_HOT_PIXEL_MODE_FAST = 1,
- ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY = 2,
+ ANDROID_HOT_PIXEL_MODE_OFF,
+ ANDROID_HOT_PIXEL_MODE_FAST,
+ ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY,
}
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 1272f27..7303ff5 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
@@ -38,5 +38,5 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum InfoSupportedBufferManagementVersion {
- ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE = 0,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
index 8ae39b0..3b50647 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedHardwareLevel.aidl
@@ -38,9 +38,9 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum InfoSupportedHardwareLevel {
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 = 3,
- ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL = 4,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3,
+ ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
new file mode 100644
index 0000000..cf9dbb7
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.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 JpegrAvailableJpegRStreamConfigurations {
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..0a95e1f
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.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 JpegrAvailableJpegRStreamConfigurationsMaximumResolution {
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl
index da558d2..b3beb2d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedAvailableLeds.aidl
@@ -38,5 +38,5 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LedAvailableLeds {
- ANDROID_LED_AVAILABLE_LEDS_TRANSMIT = 0,
+ ANDROID_LED_AVAILABLE_LEDS_TRANSMIT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl
index 658b3cd..0cbf239 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LedTransmit.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LedTransmit {
- ANDROID_LED_TRANSMIT_OFF = 0,
- ANDROID_LED_TRANSMIT_ON = 1,
+ ANDROID_LED_TRANSMIT_OFF,
+ ANDROID_LED_TRANSMIT_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl
index 4db987b..d15674d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensFacing.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LensFacing {
- ANDROID_LENS_FACING_FRONT = 0,
- ANDROID_LENS_FACING_BACK = 1,
- ANDROID_LENS_FACING_EXTERNAL = 2,
+ ANDROID_LENS_FACING_FRONT,
+ ANDROID_LENS_FACING_BACK,
+ ANDROID_LENS_FACING_EXTERNAL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
index d83d67f..937347b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensInfoFocusDistanceCalibration.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LensInfoFocusDistanceCalibration {
- ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0,
- ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1,
- ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2,
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED,
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE,
+ ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
index f2f039c..550d9f3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensOpticalStabilizationMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LensOpticalStabilizationMode {
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF = 0,
- ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON = 1,
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
+ ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
index b2d837a..6a3799d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensPoseReference.aidl
@@ -38,8 +38,8 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LensPoseReference {
- ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA = 0,
- ANDROID_LENS_POSE_REFERENCE_GYROSCOPE = 1,
- ANDROID_LENS_POSE_REFERENCE_UNDEFINED = 2,
- ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE = 3,
+ ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA,
+ ANDROID_LENS_POSE_REFERENCE_GYROSCOPE,
+ ANDROID_LENS_POSE_REFERENCE_UNDEFINED,
+ ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl
index 4b15b0f..4f98956 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LensState.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LensState {
- ANDROID_LENS_STATE_STATIONARY = 0,
- ANDROID_LENS_STATE_MOVING = 1,
+ ANDROID_LENS_STATE_STATIONARY,
+ ANDROID_LENS_STATE_MOVING,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
index 224a7fa..5eb5759 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/LogicalMultiCameraSensorSyncType.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum LogicalMultiCameraSensorSyncType {
- ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE = 0,
- ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED = 1,
+ ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE,
+ ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl
index ed0ebc1..8b589ce 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/NoiseReductionMode.aidl
@@ -38,9 +38,9 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum NoiseReductionMode {
- ANDROID_NOISE_REDUCTION_MODE_OFF = 0,
- ANDROID_NOISE_REDUCTION_MODE_FAST = 1,
- ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY = 2,
- ANDROID_NOISE_REDUCTION_MODE_MINIMAL = 3,
- ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG = 4,
+ ANDROID_NOISE_REDUCTION_MODE_OFF,
+ ANDROID_NOISE_REDUCTION_MODE_FAST,
+ ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY,
+ ANDROID_NOISE_REDUCTION_MODE_MINIMAL,
+ ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl
index d217fe8..8ab6a05 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/QuirksPartialResult.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum QuirksPartialResult {
- ANDROID_QUIRKS_PARTIAL_RESULT_FINAL = 0,
- ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL = 1,
+ ANDROID_QUIRKS_PARTIAL_RESULT_FINAL,
+ ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
index 8dc2aa2..0564db8 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
@@ -38,24 +38,25 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum RequestAvailableCapabilities {
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW = 3,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA = 14,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING = 15,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR = 16,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING = 17,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT = 18,
- ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE = 19,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
new file mode 100644
index 0000000..74606bf
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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="long") @VintfStability
+enum RequestAvailableColorSpaceProfilesMap {
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = (-1L) /* -1 */,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB = 0L,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 = 7L,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG = 16L,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
index 16e38ba..45ffb1b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.aidl
@@ -38,17 +38,17 @@
package android.hardware.camera.metadata;
@Backing(type="long") @VintfStability
enum RequestAvailableDynamicRangeProfilesMap {
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 1,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 2,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 4,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 8,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF = 16,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO = 32,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM = 64,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO = 128,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF = 256,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO = 512,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM = 1024,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO = 2048,
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 4096,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 0x1L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 0x8L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF = 0x10L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO = 0x20L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM = 0x40L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO = 0x80L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF = 0x100L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO = 0x200L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM = 0x400L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO = 0x800L,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000L,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl
index 90fba00..cede799 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestMetadataMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum RequestMetadataMode {
- ANDROID_REQUEST_METADATA_MODE_NONE = 0,
- ANDROID_REQUEST_METADATA_MODE_FULL = 1,
+ ANDROID_REQUEST_METADATA_MODE_NONE,
+ ANDROID_REQUEST_METADATA_MODE_FULL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl
index 4f38cfb..6b4ae71 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/RequestType.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum RequestType {
- ANDROID_REQUEST_TYPE_CAPTURE = 0,
- ANDROID_REQUEST_TYPE_REPROCESS = 1,
+ ANDROID_REQUEST_TYPE_CAPTURE,
+ ANDROID_REQUEST_TYPE_REPROCESS,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
index 41fd2c2..fdc2f60 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableFormats.aidl
@@ -38,14 +38,14 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerAvailableFormats {
- ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 = 32,
- ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 36,
- ANDROID_SCALER_AVAILABLE_FORMATS_YV12 = 842094169,
- ANDROID_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 17,
- ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 34,
- ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 35,
- ANDROID_SCALER_AVAILABLE_FORMATS_BLOB = 33,
- ANDROID_SCALER_AVAILABLE_FORMATS_RAW10 = 37,
- ANDROID_SCALER_AVAILABLE_FORMATS_RAW12 = 38,
- ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 538982489,
+ ANDROID_SCALER_AVAILABLE_FORMATS_RAW16 = 0x20,
+ ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE = 0x24,
+ ANDROID_SCALER_AVAILABLE_FORMATS_YV12 = 0x32315659,
+ ANDROID_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP = 0x11,
+ ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 0x22,
+ ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 0x23,
+ ANDROID_SCALER_AVAILABLE_FORMATS_BLOB = 0x21,
+ ANDROID_SCALER_AVAILABLE_FORMATS_RAW10 = 0x25,
+ ANDROID_SCALER_AVAILABLE_FORMATS_RAW12 = 0x26,
+ ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 0x20203859,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
index 85daa85..741a99d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableRecommendedStreamConfigurations.aidl
@@ -38,13 +38,13 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerAvailableRecommendedStreamConfigurations {
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW = 0,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD = 1,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT = 2,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT = 3,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL = 4,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW = 5,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT = 6,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT = 8,
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START = 24,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW = 0x0,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD = 0x1,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT = 0x2,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT = 0x3,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL = 0x4,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW = 0x5,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT = 0x6,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT = 0x8,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START = 0x18,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
index 1515ad5..4e2899d 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurations.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerAvailableStreamConfigurations {
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT = 0,
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT = 1,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
index b9c3374..fb15815 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamConfigurationsMaximumResolution.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerAvailableStreamConfigurationsMaximumResolution {
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT = 0,
- ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT = 1,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index bfa4f1a..ff92f9e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -38,11 +38,12 @@
package android.hardware.camera.metadata;
@Backing(type="long") @VintfStability
enum ScalerAvailableStreamUseCases {
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0,
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 1,
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 2,
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 3,
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 4,
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 5,
- ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 65536,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0x0L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 0x2L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl
index 0487196..60782e4 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerCroppingType.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerCroppingType {
- ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY = 0,
- ANDROID_SCALER_CROPPING_TYPE_FREEFORM = 1,
+ ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY,
+ ANDROID_SCALER_CROPPING_TYPE_FREEFORM,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
index 711243f..e09d89c 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerMultiResolutionStreamSupported.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerMultiResolutionStreamSupported {
- ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE = 0,
- ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE = 1,
+ ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE,
+ ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
index 50bc097..64a0220 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerPhysicalCameraMultiResolutionStreamConfigurations.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerPhysicalCameraMultiResolutionStreamConfigurations {
- ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT = 0,
- ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT = 1,
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
index 3b9c5b8..bf5380e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ScalerRotateAndCrop.aidl
@@ -38,9 +38,9 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ScalerRotateAndCrop {
- ANDROID_SCALER_ROTATE_AND_CROP_NONE = 0,
- ANDROID_SCALER_ROTATE_AND_CROP_90 = 1,
- ANDROID_SCALER_ROTATE_AND_CROP_180 = 2,
- ANDROID_SCALER_ROTATE_AND_CROP_270 = 3,
- ANDROID_SCALER_ROTATE_AND_CROP_AUTO = 4,
+ ANDROID_SCALER_ROTATE_AND_CROP_NONE,
+ ANDROID_SCALER_ROTATE_AND_CROP_90,
+ ANDROID_SCALER_ROTATE_AND_CROP_180,
+ ANDROID_SCALER_ROTATE_AND_CROP_270,
+ ANDROID_SCALER_ROTATE_AND_CROP_AUTO,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
index 3400233..c96f3c5 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.aidl
@@ -38,11 +38,11 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SensorInfoColorFilterArrangement {
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG = 2,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5,
- ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO,
+ ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
index c8faaee..0153731 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoLensShadingApplied.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SensorInfoLensShadingApplied {
- ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE = 0,
- ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE = 1,
+ ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE,
+ ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
index 2a4b3dd..9a00cf1 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorInfoTimestampSource.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SensorInfoTimestampSource {
- ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN = 0,
- ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1,
+ ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN,
+ ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl
index e021434..5f055d6 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorPixelMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SensorPixelMode {
- ANDROID_SENSOR_PIXEL_MODE_DEFAULT = 0,
- ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION = 1,
+ ANDROID_SENSOR_PIXEL_MODE_DEFAULT,
+ ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
index a1f0c5f..851dae0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorRawBinningFactorUsed.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SensorRawBinningFactorUsed {
- ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE = 0,
- ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE = 1,
+ ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE,
+ ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl
index 3f49b9a..98f0ebe 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorTestPatternMode.aidl
@@ -38,11 +38,11 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SensorTestPatternMode {
- ANDROID_SENSOR_TEST_PATTERN_MODE_OFF = 0,
- ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR = 1,
- ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2,
- ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3,
- ANDROID_SENSOR_TEST_PATTERN_MODE_PN9 = 4,
- ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK = 5,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_PN9,
+ ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK,
ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl
index a2d2a32..ffc6a56 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ShadingMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum ShadingMode {
- ANDROID_SHADING_MODE_OFF = 0,
- ANDROID_SHADING_MODE_FAST = 1,
- ANDROID_SHADING_MODE_HIGH_QUALITY = 2,
+ ANDROID_SHADING_MODE_OFF,
+ ANDROID_SHADING_MODE_FAST,
+ ANDROID_SHADING_MODE_HIGH_QUALITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
index 1c65f99..48c6797 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsFaceDetectMode.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsFaceDetectMode {
- ANDROID_STATISTICS_FACE_DETECT_MODE_OFF = 0,
- ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE = 1,
- ANDROID_STATISTICS_FACE_DETECT_MODE_FULL = 2,
+ ANDROID_STATISTICS_FACE_DETECT_MODE_OFF,
+ ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE,
+ ANDROID_STATISTICS_FACE_DETECT_MODE_FULL,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
index 39a013e..354518b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHistogramMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsHistogramMode {
- ANDROID_STATISTICS_HISTOGRAM_MODE_OFF = 0,
- ANDROID_STATISTICS_HISTOGRAM_MODE_ON = 1,
+ ANDROID_STATISTICS_HISTOGRAM_MODE_OFF,
+ ANDROID_STATISTICS_HISTOGRAM_MODE_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
index 3a8c6c2..b96e4be 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsHotPixelMapMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsHotPixelMapMode {
- ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF = 0,
- ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_ON = 1,
+ ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF,
+ ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
index cc280ca..7d0b082 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsLensShadingMapMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsLensShadingMapMode {
- ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0,
- ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON = 1,
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF,
+ ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
index 6607037..b80889b 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsOisDataMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsOisDataMode {
- ANDROID_STATISTICS_OIS_DATA_MODE_OFF = 0,
- ANDROID_STATISTICS_OIS_DATA_MODE_ON = 1,
+ ANDROID_STATISTICS_OIS_DATA_MODE_OFF,
+ ANDROID_STATISTICS_OIS_DATA_MODE_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
index bc286c3..a9268c0 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSceneFlicker.aidl
@@ -38,7 +38,7 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsSceneFlicker {
- ANDROID_STATISTICS_SCENE_FLICKER_NONE = 0,
- ANDROID_STATISTICS_SCENE_FLICKER_50HZ = 1,
- ANDROID_STATISTICS_SCENE_FLICKER_60HZ = 2,
+ ANDROID_STATISTICS_SCENE_FLICKER_NONE,
+ ANDROID_STATISTICS_SCENE_FLICKER_50HZ,
+ ANDROID_STATISTICS_SCENE_FLICKER_60HZ,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
index 774a43a..09a2003 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/StatisticsSharpnessMapMode.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum StatisticsSharpnessMapMode {
- ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF = 0,
- ANDROID_STATISTICS_SHARPNESS_MAP_MODE_ON = 1,
+ ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF,
+ ANDROID_STATISTICS_SHARPNESS_MAP_MODE_ON,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl
index 12ccbb9..230f57e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncFrameNumber.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum SyncFrameNumber {
- ANDROID_SYNC_FRAME_NUMBER_CONVERGING = -1,
- ANDROID_SYNC_FRAME_NUMBER_UNKNOWN = -2,
+ ANDROID_SYNC_FRAME_NUMBER_CONVERGING = (-1) /* -1 */,
+ ANDROID_SYNC_FRAME_NUMBER_UNKNOWN = (-2) /* -2 */,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl
index e0116e7..d484f45 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SyncMaxLatency.aidl
@@ -39,5 +39,5 @@
@Backing(type="int") @VintfStability
enum SyncMaxLatency {
ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0,
- ANDROID_SYNC_MAX_LATENCY_UNKNOWN = -1,
+ ANDROID_SYNC_MAX_LATENCY_UNKNOWN = (-1) /* -1 */,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl
index 728b298..e729166 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapMode.aidl
@@ -38,9 +38,9 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum TonemapMode {
- ANDROID_TONEMAP_MODE_CONTRAST_CURVE = 0,
- ANDROID_TONEMAP_MODE_FAST = 1,
- ANDROID_TONEMAP_MODE_HIGH_QUALITY = 2,
- ANDROID_TONEMAP_MODE_GAMMA_VALUE = 3,
- ANDROID_TONEMAP_MODE_PRESET_CURVE = 4,
+ ANDROID_TONEMAP_MODE_CONTRAST_CURVE,
+ ANDROID_TONEMAP_MODE_FAST,
+ ANDROID_TONEMAP_MODE_HIGH_QUALITY,
+ ANDROID_TONEMAP_MODE_GAMMA_VALUE,
+ ANDROID_TONEMAP_MODE_PRESET_CURVE,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl
index fc2e39b..2e5fbd3 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/TonemapPresetCurve.aidl
@@ -38,6 +38,6 @@
package android.hardware.camera.metadata;
@Backing(type="int") @VintfStability
enum TonemapPresetCurve {
- ANDROID_TONEMAP_PRESET_CURVE_SRGB = 0,
- ANDROID_TONEMAP_PRESET_CURVE_REC709 = 1,
+ ANDROID_TONEMAP_PRESET_CURVE_SRGB,
+ ANDROID_TONEMAP_PRESET_CURVE_REC709,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
index 99e28b9..73bcc12 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -61,5 +61,7 @@
ANDROID_HEIC_INFO,
ANDROID_AUTOMOTIVE,
ANDROID_AUTOMOTIVE_LENS,
+ ANDROID_EXTENSION,
+ ANDROID_JPEGR,
VENDOR_SECTION = 0x8000,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 62c71e9..75e7915 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -63,5 +63,7 @@
ANDROID_HEIC_INFO_START = CameraMetadataSection.ANDROID_HEIC_INFO << 16,
ANDROID_AUTOMOTIVE_START = CameraMetadataSection.ANDROID_AUTOMOTIVE << 16,
ANDROID_AUTOMOTIVE_LENS_START = CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16,
+ ANDROID_EXTENSION_START = CameraMetadataSection.ANDROID_EXTENSION << 16,
+ ANDROID_JPEGR_START = CameraMetadataSection.ANDROID_JPEGR << 16,
VENDOR_SECTION_START = CameraMetadataSection.VENDOR_SECTION << 16,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 48b1ee4..671d69d 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -450,6 +450,46 @@
*/
ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION,
/**
+ * android.control.settingsOverride [dynamic, enum, public]
+ *
+ * <p>The desired CaptureRequest settings override with which certain keys are
+ * applied earlier so that they can take effect sooner.</p>
+ */
+ ANDROID_CONTROL_SETTINGS_OVERRIDE = 65588,
+ /**
+ * android.control.availableSettingsOverrides [static, int32[], public]
+ *
+ * <p>List of available settings overrides supported by the camera device that can
+ * be used to speed up certain controls.</p>
+ */
+ ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+ /**
+ * android.control.settingsOverridingFrameNumber [dynamic, int32, system]
+ *
+ * <p>The frame number of the newer request overriding this capture.</p>
+ */
+ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
+ /**
+ * android.control.autoframing [dynamic, enum, public]
+ *
+ * <p>Automatic crop, pan and zoom to keep objects in the center of the frame.</p>
+ */
+ ANDROID_CONTROL_AUTOFRAMING,
+ /**
+ * android.control.autoframingAvailable [static, enum, public]
+ *
+ * <p>Whether the camera device supports ANDROID_CONTROL_AUTOFRAMING.</p>
+ *
+ * @see ANDROID_CONTROL_AUTOFRAMING
+ */
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
+ /**
+ * android.control.autoframingState [dynamic, enum, public]
+ *
+ * <p>Current state of auto-framing.</p>
+ */
+ ANDROID_CONTROL_AUTOFRAMING_STATE,
+ /**
* android.demosaic.mode [controls, enum, system]
*
* <p>Controls the quality of the demosaicing
@@ -1030,6 +1070,12 @@
*/
ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
/**
+ * android.request.availableColorSpaceProfilesMap [static, enum[], ndk_public]
+ *
+ * <p>A list of all possible color space profiles supported by a camera device.</p>
+ */
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
+ /**
* android.scaler.cropRegion [dynamic, int32[], public]
*
* <p>The desired region of the sensor to read out for this capture.</p>
@@ -1238,6 +1284,13 @@
*/
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES = 851994,
/**
+ * android.scaler.rawCropRegion [dynamic, int32[], public]
+ *
+ * <p>The region of the sensor that corresponds to the RAW read out for this
+ * capture when the stream use case of a RAW stream is set to CROPPED_RAW.</p>
+ */
+ ANDROID_SCALER_RAW_CROP_REGION,
+ /**
* android.sensor.exposureTime [dynamic, int64, public]
*
* <p>Duration each pixel is exposed to
@@ -2252,4 +2305,56 @@
* passenger seats.</p>
*/
ANDROID_AUTOMOTIVE_LENS_FACING = CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START,
+ /**
+ * android.jpegr.availableJpegRStreamConfigurations [static, enum[], ndk_public]
+ *
+ * <p>The available Jpeg/R stream
+ * configurations that this camera device supports
+ * (i.e. format, width, height, output/input stream).</p>
+ */
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = CameraMetadataSectionStart.ANDROID_JPEGR_START,
+ /**
+ * android.jpegr.availableJpegRMinFrameDurations [static, int64[], ndk_public]
+ *
+ * <p>This lists the minimum frame duration for each
+ * format/size combination for Jpeg/R output formats.</p>
+ */
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
+ /**
+ * android.jpegr.availableJpegRStallDurations [static, int64[], ndk_public]
+ *
+ * <p>This lists the maximum stall duration for each
+ * output format/size combination for Jpeg/R streams.</p>
+ */
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
+ /**
+ * android.jpegr.availableJpegRStreamConfigurationsMaximumResolution [static, enum[], ndk_public]
+ *
+ * <p>The available Jpeg/R stream
+ * configurations that this camera device supports
+ * (i.e. format, width, height, output/input stream).</p>
+ */
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+ /**
+ * android.jpegr.availableJpegRMinFrameDurationsMaximumResolution [static, int64[], ndk_public]
+ *
+ * <p>This lists the minimum frame duration for each
+ * format/size combination for Jpeg/R output formats for CaptureRequests where
+ * ANDROID_SENSOR_PIXEL_MODE is set to
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+ *
+ * @see ANDROID_SENSOR_PIXEL_MODE
+ */
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+ /**
+ * android.jpegr.availableJpegRStallDurationsMaximumResolution [static, int64[], ndk_public]
+ *
+ * <p>This lists the maximum stall duration for each
+ * output format/size combination for Jpeg/R streams for CaptureRequests where
+ * ANDROID_SENSOR_PIXEL_MODE is set to
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+ *
+ * @see ANDROID_SENSOR_PIXEL_MODE
+ */
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
new file mode 100644
index 0000000..0fef373
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframing.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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.autoframing enumeration values
+ * @see ANDROID_CONTROL_AUTOFRAMING
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAutoframing {
+ ANDROID_CONTROL_AUTOFRAMING_OFF,
+ ANDROID_CONTROL_AUTOFRAMING_ON,
+ ANDROID_CONTROL_AUTOFRAMING_AUTO,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.aidl
new file mode 100644
index 0000000..da0d348
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingAvailable.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.autoframingAvailable enumeration values
+ * @see ANDROID_CONTROL_AUTOFRAMING_AVAILABLE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAutoframingAvailable {
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE,
+ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
new file mode 100644
index 0000000..13183a5
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAutoframingState.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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.autoframingState enumeration values
+ * @see ANDROID_CONTROL_AUTOFRAMING_STATE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAutoframingState {
+ ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE,
+ ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING,
+ ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
new file mode 100644
index 0000000..d97f7c8
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlSettingsOverride.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * 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.settingsOverride enumeration values
+ * @see ANDROID_CONTROL_SETTINGS_OVERRIDE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlSettingsOverride {
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START = 0x4000,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.aidl
new file mode 100644
index 0000000..911a062
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurations.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.jpegr.availableJpegRStreamConfigurations enumeration values
+ * @see ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS
+ */
+@VintfStability
+@Backing(type="int")
+enum JpegrAvailableJpegRStreamConfigurations {
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..9e78662
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/JpegrAvailableJpegRStreamConfigurationsMaximumResolution.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.jpegr.availableJpegRStreamConfigurationsMaximumResolution enumeration values
+ * @see ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ */
+@VintfStability
+@Backing(type="int")
+enum JpegrAvailableJpegRStreamConfigurationsMaximumResolution {
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
index f5c77eb..ebe0b4c 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableCapabilities.aidl
@@ -49,4 +49,5 @@
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING,
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE,
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
new file mode 100644
index 0000000..b397dea
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.request.availableColorSpaceProfilesMap enumeration values
+ * @see ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP
+ */
+@VintfStability
+@Backing(type="long")
+enum RequestAvailableColorSpaceProfilesMap {
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = -1L,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB = 0L,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 = 7L,
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG = 16L,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
index daa0fd3..da27a48 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ScalerAvailableStreamUseCases.aidl
@@ -35,5 +35,6 @@
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3L,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4L,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5L,
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6L,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000L,
}
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index e2c2bea..d7e613e 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -14,9 +14,10 @@
"android/hardware/camera/provider/*.aidl",
],
imports: [
- "android.hardware.camera.device-V1",
+ "android.hardware.camera.device-V2",
"android.hardware.camera.common-V1",
],
+ frozen: false,
stability: "vintf",
backend: {
java: {
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index f17de3a..8429b21 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -27,6 +27,7 @@
name: "VtsAidlHalCameraProvider_TargetTest",
defaults: [
"VtsHalTargetTestDefaults",
+ "android.hardware.graphics.common-ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
srcs: [
@@ -58,10 +59,9 @@
static_libs: [
"[email protected]",
"android.hardware.camera.common-V1-ndk",
- "android.hardware.camera.device-V1-ndk",
- "android.hardware.camera.metadata-V1-ndk",
- "android.hardware.camera.provider-V1-ndk",
- "android.hardware.graphics.common-V4-ndk",
+ "android.hardware.camera.device-V2-ndk",
+ "android.hardware.camera.metadata-V2-ndk",
+ "android.hardware.camera.provider-V2-ndk",
"[email protected]",
"libgrallocusage",
"libhidlmemory",
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index b764ad6..622b20b 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -36,6 +36,7 @@
using ::aidl::android::hardware::camera::common::TorchModeStatus;
using ::aidl::android::hardware::camera::common::VendorTagSection;
using ::aidl::android::hardware::camera::device::ICameraDevice;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
using ::aidl::android::hardware::camera::metadata::SensorPixelMode;
using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
@@ -2025,6 +2026,62 @@
}
}
+TEST_P(CameraAidlTest, process8BitColorSpaceRequests) {
+ static int profiles[] = {ColorSpaceNamed::DISPLAY_P3, ColorSpaceNamed::SRGB};
+
+ for (int32_t i = 0; i < sizeof(profiles) / sizeof(profiles[0]); i++) {
+ processColorSpaceRequest(static_cast<RequestAvailableColorSpaceProfilesMap>(profiles[i]),
+ static_cast<RequestAvailableDynamicRangeProfilesMap>(
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD));
+ }
+}
+
+TEST_P(CameraAidlTest, process10BitColorSpaceRequests) {
+ static const camera_metadata_enum_android_request_available_dynamic_range_profiles_map
+ dynamicRangeProfiles[] = {
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO
+ };
+
+ // Process all dynamic range profiles with BT2020_HLG
+ for (int32_t i = 0; i < sizeof(dynamicRangeProfiles) / sizeof(dynamicRangeProfiles[0]); i++) {
+ processColorSpaceRequest(
+ static_cast<RequestAvailableColorSpaceProfilesMap>(ColorSpaceNamed::BT2020_HLG),
+ static_cast<RequestAvailableDynamicRangeProfilesMap>(dynamicRangeProfiles[i]));
+ }
+}
+
+TEST_P(CameraAidlTest, processZoomSettingsOverrideRequests) {
+ const int32_t kFrameCount = 5;
+ const int32_t kTestCases = 2;
+ const bool kOverrideSequence[kTestCases][kFrameCount] = {
+ // ZOOM, ZOOM, ZOOM, ZOOM, ZOOM;
+ { true, true, true, true, true },
+ // OFF, OFF, ZOOM, ZOOM, OFF;
+ { false, false, true, true, false } };
+ const bool kExpectedOverrideResults[kTestCases][kFrameCount] = {
+ // All resuls should be overridden except the last one. The last result's
+ // zoom doesn't have speed-up.
+ { true, true, true, true, false },
+ // Because we require at least 2 frames speed-up, request #1, #2 and #3
+ // will be overridden.
+ { true, true, true, false, false } };
+
+ for (int i = 0; i < kTestCases; i++) {
+ processZoomSettingsOverrideRequests(kFrameCount, kOverrideSequence[i],
+ kExpectedOverrideResults[i]);
+ }
+}
+
// Generate and verify a burst containing alternating sensor sensitivity values
TEST_P(CameraAidlTest, processCaptureRequestBurstISO) {
std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
@@ -2973,10 +3030,28 @@
}
}
+TEST_P(CameraAidlTest, configureStreamsUseCasesCroppedRaw) {
+ AvailableStream rawStreamThreshold =
+ {INT_MAX, INT_MAX, static_cast<int32_t>(PixelFormat::RAW16)};
+ configureStreamUseCaseInternal(rawStreamThreshold);
+}
+
// Verify that valid stream use cases can be configured successfully, and invalid use cases
// fail stream configuration.
TEST_P(CameraAidlTest, configureStreamsUseCases) {
+ AvailableStream previewStreamThreshold =
+ {kMaxPreviewWidth, kMaxPreviewHeight, static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
+ configureStreamUseCaseInternal(previewStreamThreshold);
+}
+
+// Validate the integrity of stream configuration metadata
+TEST_P(CameraAidlTest, validateStreamConfigurations) {
std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ std::vector<AvailableStream> outputStreams;
+
+ const int32_t scalerSizesTag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
+ const int32_t scalerMinFrameDurationsTag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
+ const int32_t scalerStallDurationsTag = ANDROID_SCALER_AVAILABLE_STALL_DURATIONS;
for (const auto& name : cameraDeviceNames) {
CameraMetadata meta;
@@ -2984,99 +3059,29 @@
openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
&cameraDevice /*out*/);
-
camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
- // Check if camera support depth only
- if (isDepthOnly(staticMeta)) {
- ndk::ScopedAStatus ret = mSession->close();
- mSession = nullptr;
- ASSERT_TRUE(ret.isOk());
- continue;
+
+ if (is10BitDynamicRangeCapable(staticMeta)) {
+ std::vector<std::tuple<size_t, size_t>> supportedP010Sizes, supportedBlobSizes;
+
+ getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_BLOB,
+ &supportedBlobSizes);
+ getSupportedSizes(staticMeta, scalerSizesTag, HAL_PIXEL_FORMAT_YCBCR_P010,
+ &supportedP010Sizes);
+ ASSERT_FALSE(supportedP010Sizes.empty());
+
+ std::vector<int64_t> blobMinDurations, blobStallDurations;
+ getSupportedDurations(staticMeta, scalerMinFrameDurationsTag, HAL_PIXEL_FORMAT_BLOB,
+ supportedP010Sizes, &blobMinDurations);
+ getSupportedDurations(staticMeta, scalerStallDurationsTag, HAL_PIXEL_FORMAT_BLOB,
+ supportedP010Sizes, &blobStallDurations);
+ ASSERT_FALSE(blobStallDurations.empty());
+ ASSERT_FALSE(blobMinDurations.empty());
+ ASSERT_EQ(supportedP010Sizes.size(), blobMinDurations.size());
+ ASSERT_EQ(blobMinDurations.size(), blobStallDurations.size());
}
- std::vector<AvailableStream> outputPreviewStreams;
- AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
- static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
- ASSERT_EQ(Status::OK,
- getAvailableOutputStreams(staticMeta, outputPreviewStreams, &previewThreshold));
- ASSERT_NE(0u, outputPreviewStreams.size());
-
- // Combine valid and invalid stream use cases
- std::vector<int64_t> useCases(kMandatoryUseCases);
- useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL + 1);
-
- std::vector<int64_t> supportedUseCases;
- camera_metadata_ro_entry entry;
- auto retcode = find_camera_metadata_ro_entry(
- staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
- if ((0 == retcode) && (entry.count > 0)) {
- supportedUseCases.insert(supportedUseCases.end(), entry.data.i64,
- entry.data.i64 + entry.count);
- } else {
- supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
- }
-
- std::vector<Stream> streams(1);
- streams[0] = {0,
- StreamType::OUTPUT,
- outputPreviewStreams[0].width,
- outputPreviewStreams[0].height,
- static_cast<PixelFormat>(outputPreviewStreams[0].format),
- static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_CPU_READ),
- Dataspace::UNKNOWN,
- StreamRotation::ROTATION_0,
- std::string(),
- 0,
- -1,
- {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
-
- int32_t streamConfigCounter = 0;
- CameraMetadata req;
- StreamConfiguration config;
- RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
- ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req);
- ASSERT_TRUE(ret.isOk());
- config.sessionParams = req;
-
- for (int64_t useCase : useCases) {
- bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
- useCase) != supportedUseCases.end();
-
- streams[0].useCase = static_cast<
- aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>(
- useCase);
- config.streams = streams;
- config.operationMode = StreamConfigurationMode::NORMAL_MODE;
- config.streamConfigCounter = streamConfigCounter;
- config.multiResolutionInputImage = false;
-
- bool combSupported;
- ret = cameraDevice->isStreamCombinationSupported(config, &combSupported);
- if (static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED) ==
- ret.getServiceSpecificError()) {
- continue;
- }
-
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(combSupported, useCaseSupported);
-
- std::vector<HalStream> halStreams;
- ret = mSession->configureStreams(config, &halStreams);
- ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError());
- if (useCaseSupported) {
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(1u, halStreams.size());
- } else {
- ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
- ret.getServiceSpecificError());
- }
- }
- ret = mSession->close();
- mSession = nullptr;
- ASSERT_TRUE(ret.isOk());
+ // Validate other aspects of stream configuration metadata...
}
}
@@ -3084,4 +3089,4 @@
INSTANTIATE_TEST_SUITE_P(
PerInstance, CameraAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(ICameraProvider::descriptor)),
- android::hardware::PrintInstanceNameToString);
\ No newline at end of file
+ android::hardware::PrintInstanceNameToString);
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 137c521..8d4cef1 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -22,6 +22,7 @@
#include <HandleImporter.h>
#include <aidl/android/hardware/camera/device/ICameraDevice.h>
#include <aidl/android/hardware/camera/metadata/CameraMetadataTag.h>
+#include <aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.h>
#include <aidl/android/hardware/camera/metadata/RequestAvailableDynamicRangeProfilesMap.h>
#include <aidl/android/hardware/camera/metadata/SensorInfoColorFilterArrangement.h>
#include <aidl/android/hardware/camera/metadata/SensorPixelMode.h>
@@ -44,6 +45,7 @@
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::ICameraDevice;
using ::aidl::android::hardware::camera::metadata::CameraMetadataTag;
+using ::aidl::android::hardware::camera::metadata::RequestAvailableColorSpaceProfilesMap;
using ::aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
using ::aidl::android::hardware::camera::metadata::SensorInfoColorFilterArrangement;
using ::aidl::android::hardware::camera::metadata::SensorPixelMode;
@@ -339,8 +341,8 @@
if (entry.data.i64[i] == ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
supportDefaultUseCase = true;
}
- ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL ||
- entry.data.i64[i] >=
+ ASSERT_TRUE(entry.data.i64[i] <= ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW
+ || entry.data.i64[i] >=
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START);
}
ASSERT_TRUE(supportDefaultUseCase);
@@ -349,6 +351,69 @@
ASSERT_EQ(hasStreamUseCaseCap, supportMandatoryUseCases);
}
+void CameraAidlTest::verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata) {
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES, &entry);
+ bool supportSettingsOverride = false;
+ if (0 == retcode) {
+ supportSettingsOverride = true;
+ bool hasOff = false;
+ for (size_t i = 0; i < entry.count; i++) {
+ if (entry.data.u8[i] == ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF) {
+ hasOff = true;
+ }
+ }
+ ASSERT_TRUE(hasOff);
+ }
+
+ // Check availableRequestKeys
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
+ bool hasSettingsOverrideRequestKey = false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ hasSettingsOverrideRequestKey =
+ std::find(entry.data.i32, entry.data.i32 + entry.count,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE) != entry.data.i32 + entry.count;
+ } else {
+ ADD_FAILURE() << "Get camera availableRequestKeys failed!";
+ }
+
+ // Check availableResultKeys
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
+ bool hasSettingsOverrideResultKey = false;
+ bool hasOverridingFrameNumberKey = false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ hasSettingsOverrideResultKey =
+ std::find(entry.data.i32, entry.data.i32 + entry.count,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE) != entry.data.i32 + entry.count;
+ hasOverridingFrameNumberKey =
+ std::find(entry.data.i32, entry.data.i32 + entry.count,
+ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER)
+ != entry.data.i32 + entry.count;
+ } else {
+ ADD_FAILURE() << "Get camera availableResultKeys failed!";
+ }
+
+ // Check availableCharacteristicKeys
+ retcode = find_camera_metadata_ro_entry(metadata,
+ ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
+ bool hasSettingsOverrideCharacteristicsKey= false;
+ if ((0 == retcode) && (entry.count > 0)) {
+ hasSettingsOverrideCharacteristicsKey = std::find(entry.data.i32,
+ entry.data.i32 + entry.count, ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES)
+ != entry.data.i32 + entry.count;
+ } else {
+ ADD_FAILURE() << "Get camera availableCharacteristicsKeys failed!";
+ }
+
+ ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideRequestKey);
+ ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideResultKey);
+ ASSERT_EQ(supportSettingsOverride, hasOverridingFrameNumberKey);
+ ASSERT_EQ(supportSettingsOverride, hasSettingsOverrideCharacteristicsKey);
+}
+
Status CameraAidlTest::isMonochromeCamera(const camera_metadata_t* staticMeta) {
Status ret = Status::OPERATION_NOT_SUPPORTED;
if (nullptr == staticMeta) {
@@ -624,6 +689,7 @@
verifyExtendedSceneModeCharacteristics(metadata);
verifyZoomCharacteristics(metadata);
verifyStreamUseCaseCharacteristics(metadata);
+ verifySettingsOverrideCharacteristics(metadata);
}
void CameraAidlTest::verifyExtendedSceneModeCharacteristics(const camera_metadata_t* metadata) {
@@ -1537,6 +1603,15 @@
ASSERT_EQ(zoomRatioEntry.count, 1);
ASSERT_EQ(zoomRatioEntry.data.f[0], 1.0f);
}
+
+ // Check settings override
+ camera_metadata_ro_entry settingsOverrideEntry;
+ int foundSettingsOverride = find_camera_metadata_ro_entry(metadata,
+ ANDROID_CONTROL_SETTINGS_OVERRIDE, &settingsOverrideEntry);
+ if (foundSettingsOverride == 0) {
+ ASSERT_EQ(settingsOverrideEntry.count, 1);
+ ASSERT_EQ(settingsOverrideEntry.data.u8[0], ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF);
+ }
}
void CameraAidlTest::openEmptyDeviceSession(const std::string& name,
@@ -2111,6 +2186,121 @@
}
}
+void CameraAidlTest::configureStreamUseCaseInternal(const AvailableStream &threshold) {
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+
+ for (const auto& name : cameraDeviceNames) {
+ CameraMetadata meta;
+ std::shared_ptr<ICameraDevice> cameraDevice;
+
+ openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+ &cameraDevice /*out*/);
+
+ camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+ // Check if camera support depth only
+ if (isDepthOnly(staticMeta) ||
+ (threshold.format == static_cast<int32_t>(PixelFormat::RAW16) &&
+ !supportsCroppedRawUseCase(staticMeta))) {
+ ndk::ScopedAStatus ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+
+ std::vector<AvailableStream> outputPreviewStreams;
+
+ ASSERT_EQ(Status::OK,
+ getAvailableOutputStreams(staticMeta, outputPreviewStreams, &threshold));
+ ASSERT_NE(0u, outputPreviewStreams.size());
+
+ // Combine valid and invalid stream use cases
+ std::vector<int64_t> useCases(kMandatoryUseCases);
+ useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW + 1);
+
+ std::vector<int64_t> supportedUseCases;
+ if (threshold.format == static_cast<int32_t>(PixelFormat::RAW16)) {
+ // If the format is RAW16, supported use case is only CROPPED_RAW.
+ // All others are unsupported for this format.
+ useCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+ supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW);
+ supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ } else {
+ camera_metadata_ro_entry entry;
+ auto retcode = find_camera_metadata_ro_entry(
+ staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, &entry);
+ if ((0 == retcode) && (entry.count > 0)) {
+ supportedUseCases.insert(supportedUseCases.end(), entry.data.i64,
+ entry.data.i64 + entry.count);
+ } else {
+ supportedUseCases.push_back(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT);
+ }
+ }
+
+ std::vector<Stream> streams(1);
+ streams[0] = {0,
+ StreamType::OUTPUT,
+ outputPreviewStreams[0].width,
+ outputPreviewStreams[0].height,
+ static_cast<PixelFormat>(outputPreviewStreams[0].format),
+ static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_CPU_READ),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ std::string(),
+ 0,
+ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+
+ int32_t streamConfigCounter = 0;
+ CameraMetadata req;
+ StreamConfiguration config;
+ RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
+ ndk::ScopedAStatus ret = mSession->constructDefaultRequestSettings(reqTemplate, &req);
+ ASSERT_TRUE(ret.isOk());
+ config.sessionParams = req;
+
+ for (int64_t useCase : useCases) {
+ bool useCaseSupported = std::find(supportedUseCases.begin(), supportedUseCases.end(),
+ useCase) != supportedUseCases.end();
+
+ streams[0].useCase = static_cast<
+ aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases>(
+ useCase);
+ config.streams = streams;
+ config.operationMode = StreamConfigurationMode::NORMAL_MODE;
+ config.streamConfigCounter = streamConfigCounter;
+ config.multiResolutionInputImage = false;
+
+ bool combSupported;
+ ret = cameraDevice->isStreamCombinationSupported(config, &combSupported);
+ if (static_cast<int32_t>(Status::OPERATION_NOT_SUPPORTED) ==
+ ret.getServiceSpecificError()) {
+ continue;
+ }
+
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(combSupported, useCaseSupported);
+
+ std::vector<HalStream> halStreams;
+ ret = mSession->configureStreams(config, &halStreams);
+ ALOGI("configureStreams returns status: %d", ret.getServiceSpecificError());
+ if (useCaseSupported) {
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(1u, halStreams.size());
+ } else {
+ ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT),
+ ret.getServiceSpecificError());
+ }
+ }
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ }
+
+}
+
void CameraAidlTest::configureSingleStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, uint64_t bufferUsage, RequestTemplate reqTemplate,
@@ -2812,6 +3002,211 @@
}
}
+bool CameraAidlTest::reportsColorSpaces(const camera_metadata_t* staticMeta) {
+ camera_metadata_ro_entry capabilityEntry;
+ int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+ &capabilityEntry);
+ if (rc == 0) {
+ for (uint32_t i = 0; i < capabilityEntry.count; i++) {
+ if (capabilityEntry.data.u8[i] ==
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void CameraAidlTest::getColorSpaceProfiles(
+ const camera_metadata_t* staticMeta,
+ std::vector<RequestAvailableColorSpaceProfilesMap>* profiles) {
+ ASSERT_NE(nullptr, staticMeta);
+ ASSERT_NE(nullptr, profiles);
+ camera_metadata_ro_entry entry;
+ int rc = find_camera_metadata_ro_entry(
+ staticMeta, ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP, &entry);
+ ASSERT_EQ(rc, 0);
+ ASSERT_TRUE(entry.count > 0);
+ ASSERT_EQ(entry.count % 3, 0);
+
+ for (uint32_t i = 0; i < entry.count; i += 3) {
+ ASSERT_NE(entry.data.i64[i],
+ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED);
+ if (std::find(profiles->begin(), profiles->end(),
+ static_cast<RequestAvailableColorSpaceProfilesMap>(entry.data.i64[i]))
+ == profiles->end()) {
+ profiles->emplace_back(
+ static_cast<RequestAvailableColorSpaceProfilesMap>(entry.data.i64[i]));
+ }
+ }
+}
+
+bool CameraAidlTest::isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
+ const camera_metadata_t* staticMeta,
+ RequestAvailableColorSpaceProfilesMap colorSpace,
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile,
+ aidl::android::hardware::graphics::common::PixelFormat pixelFormat) {
+ camera_metadata_ro_entry entry;
+ int rc = find_camera_metadata_ro_entry(
+ staticMeta, ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP, &entry);
+
+ if (rc == 0) {
+ for (uint32_t i = 0; i < entry.count; i += 3) {
+ RequestAvailableColorSpaceProfilesMap entryColorSpace =
+ static_cast<RequestAvailableColorSpaceProfilesMap>(entry.data.i64[i]);
+ int64_t dynamicRangeProfileI64 = static_cast<int64_t>(dynamicRangeProfile);
+ int32_t entryImageFormat = static_cast<int32_t>(entry.data.i64[i + 1]);
+ int32_t expectedImageFormat = halFormatToPublicFormat(pixelFormat);
+ if (entryColorSpace == colorSpace
+ && (entry.data.i64[i + 2] & dynamicRangeProfileI64) != 0
+ && entryImageFormat == expectedImageFormat) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+const char* CameraAidlTest::getColorSpaceProfileString(
+ RequestAvailableColorSpaceProfilesMap colorSpace) {
+ auto colorSpaceCast = static_cast<int>(colorSpace);
+ switch (colorSpaceCast) {
+ case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED:
+ return "UNSPECIFIED";
+ case ColorSpaceNamed::SRGB:
+ return "SRGB";
+ case ColorSpaceNamed::LINEAR_SRGB:
+ return "LINEAR_SRGB";
+ case ColorSpaceNamed::EXTENDED_SRGB:
+ return "EXTENDED_SRGB";
+ case ColorSpaceNamed::LINEAR_EXTENDED_SRGB:
+ return "LINEAR_EXTENDED_SRGB";
+ case ColorSpaceNamed::BT709:
+ return "BT709";
+ case ColorSpaceNamed::BT2020:
+ return "BT2020";
+ case ColorSpaceNamed::DCI_P3:
+ return "DCI_P3";
+ case ColorSpaceNamed::DISPLAY_P3:
+ return "DISPLAY_P3";
+ case ColorSpaceNamed::NTSC_1953:
+ return "NTSC_1953";
+ case ColorSpaceNamed::SMPTE_C:
+ return "SMPTE_C";
+ case ColorSpaceNamed::ADOBE_RGB:
+ return "ADOBE_RGB";
+ case ColorSpaceNamed::PRO_PHOTO_RGB:
+ return "PRO_PHOTO_RGB";
+ case ColorSpaceNamed::ACES:
+ return "ACES";
+ case ColorSpaceNamed::ACESCG:
+ return "ACESCG";
+ case ColorSpaceNamed::CIE_XYZ:
+ return "CIE_XYZ";
+ case ColorSpaceNamed::CIE_LAB:
+ return "CIE_LAB";
+ case ColorSpaceNamed::BT2020_HLG:
+ return "BT2020_HLG";
+ case ColorSpaceNamed::BT2020_PQ:
+ return "BT2020_PQ";
+ default:
+ return "INVALID";
+ }
+
+ return "INVALID";
+}
+
+const char* CameraAidlTest::getDynamicRangeProfileString(
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile) {
+ auto dynamicRangeProfileCast =
+ static_cast<camera_metadata_enum_android_request_available_dynamic_range_profiles_map>
+ (dynamicRangeProfile);
+ switch (dynamicRangeProfileCast) {
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD:
+ return "STANDARD";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
+ return "HLG10";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
+ return "HDR10";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
+ return "HDR10_PLUS";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
+ return "DOLBY_VISION_10B_HDR_REF";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
+ return "DOLBY_VISION_10B_HDR_REF_P0";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
+ return "DOLBY_VISION_10B_HDR_OEM";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
+ return "DOLBY_VISION_10B_HDR_OEM_P0";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
+ return "DOLBY_VISION_8B_HDR_REF";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
+ return "DOLBY_VISION_8B_HDR_REF_P0";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
+ return "DOLBY_VISION_8B_HDR_OEM";
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
+ return "DOLBY_VISION_8B_HDR_OEM_P0";
+ default:
+ return "INVALID";
+ }
+
+ return "INVALID";
+}
+
+int32_t CameraAidlTest::halFormatToPublicFormat(
+ aidl::android::hardware::graphics::common::PixelFormat pixelFormat) {
+ // This is an incomplete mapping of pixel format to image format and assumes dataspaces
+ // (see getDataspace)
+ switch (pixelFormat) {
+ case PixelFormat::BLOB:
+ return 0x100; // ImageFormat.JPEG
+ case PixelFormat::Y16:
+ return 0x44363159; // ImageFormat.DEPTH16
+ default:
+ return static_cast<int32_t>(pixelFormat);
+ }
+}
+
+bool CameraAidlTest::supportZoomSettingsOverride(const camera_metadata_t* staticMeta) {
+ camera_metadata_ro_entry availableOverridesEntry;
+ int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES,
+ &availableOverridesEntry);
+ if (rc == 0) {
+ for (size_t i = 0; i < availableOverridesEntry.count; i++) {
+ if (availableOverridesEntry.data.i32[i] == ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool CameraAidlTest::supportsCroppedRawUseCase(const camera_metadata_t *staticMeta) {
+ camera_metadata_ro_entry availableStreamUseCasesEntry;
+ int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES,
+ &availableStreamUseCasesEntry);
+ if (rc == 0) {
+ for (size_t i = 0; i < availableStreamUseCasesEntry.count; i++) {
+ if (availableStreamUseCasesEntry.data.i64[i] ==
+ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool CameraAidlTest::isPerFrameControl(const camera_metadata_t* staticMeta) {
+ camera_metadata_ro_entry syncLatencyEntry;
+ int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_SYNC_MAX_LATENCY,
+ &syncLatencyEntry);
+ if (rc == 0 && syncLatencyEntry.data.i32[0] == ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL) {
+ return true;
+ }
+ return false;
+}
+
void CameraAidlTest::configurePreviewStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, std::shared_ptr<ICameraDeviceSession>* session,
@@ -2957,4 +3352,425 @@
for (auto& it : mInflightMap) {
it.second->resultQueue = resultQueue;
}
-}
\ No newline at end of file
+}
+
+void CameraAidlTest::processColorSpaceRequest(
+ RequestAvailableColorSpaceProfilesMap colorSpace,
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile) {
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ CameraMetadata settings;
+
+ for (const auto& name : cameraDeviceNames) {
+ std::string version, deviceId;
+ ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
+ CameraMetadata meta;
+ std::shared_ptr<ICameraDevice> device;
+ openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device);
+ camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+
+ // Device does not report color spaces, skip.
+ if (!reportsColorSpaces(staticMeta)) {
+ ndk::ScopedAStatus ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ ALOGV("Camera %s does not report color spaces", name.c_str());
+ continue;
+ }
+ std::vector<RequestAvailableColorSpaceProfilesMap> profileList;
+ getColorSpaceProfiles(staticMeta, &profileList);
+ ASSERT_FALSE(profileList.empty());
+
+ // Device does not support color space / dynamic range profile, skip
+ if (std::find(profileList.begin(), profileList.end(), colorSpace)
+ == profileList.end() || !isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
+ staticMeta, colorSpace, dynamicRangeProfile,
+ PixelFormat::IMPLEMENTATION_DEFINED)) {
+ ndk::ScopedAStatus ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ ALOGV("Camera %s does not support color space %s with dynamic range profile %s and "
+ "pixel format %d", name.c_str(), getColorSpaceProfileString(colorSpace),
+ getDynamicRangeProfileString(dynamicRangeProfile),
+ PixelFormat::IMPLEMENTATION_DEFINED);
+ continue;
+ }
+
+ ALOGV("Camera %s supports color space %s with dynamic range profile %s and pixel format %d",
+ name.c_str(), getColorSpaceProfileString(colorSpace),
+ getDynamicRangeProfileString(dynamicRangeProfile),
+ PixelFormat::IMPLEMENTATION_DEFINED);
+
+ // If an HDR dynamic range profile is reported in the color space profile list,
+ // the device must also have the dynamic range profiles map capability and contain
+ // the dynamic range profile in the map.
+ if (dynamicRangeProfile != static_cast<RequestAvailableDynamicRangeProfilesMap>(
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD)) {
+ ASSERT_TRUE(is10BitDynamicRangeCapable(staticMeta));
+
+ std::vector<RequestAvailableDynamicRangeProfilesMap> dynamicRangeProfiles;
+ get10BitDynamicRangeProfiles(staticMeta, &dynamicRangeProfiles);
+ ASSERT_FALSE(dynamicRangeProfiles.empty());
+ ASSERT_FALSE(std::find(dynamicRangeProfiles.begin(), dynamicRangeProfiles.end(),
+ dynamicRangeProfile) == dynamicRangeProfiles.end());
+ }
+
+ CameraMetadata req;
+ android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
+ ndk::ScopedAStatus ret =
+ mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &req);
+ ASSERT_TRUE(ret.isOk());
+
+ const camera_metadata_t* metadata =
+ reinterpret_cast<const camera_metadata_t*>(req.metadata.data());
+ size_t expectedSize = req.metadata.size();
+ int result = validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+
+ size_t entryCount = get_camera_metadata_entry_count(metadata);
+ ASSERT_GT(entryCount, 0u);
+ defaultSettings = metadata;
+
+ const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock();
+ uint8_t* rawSettingsBuffer = (uint8_t*)settingsBuffer;
+ settings.metadata = std::vector(
+ rawSettingsBuffer, rawSettingsBuffer + get_camera_metadata_size(settingsBuffer));
+ overrideRotateAndCrop(&settings);
+
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+
+ std::vector<HalStream> halStreams;
+ bool supportsPartialResults = false;
+ bool useHalBufManager = false;
+ int32_t partialResultCount = 0;
+ Stream previewStream;
+ std::shared_ptr<DeviceCb> cb;
+
+ previewStream.usage =
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
+ previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED);
+ previewStream.colorSpace = static_cast<int32_t>(colorSpace);
+ configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
+ &previewStream, &halStreams, &supportsPartialResults,
+ &partialResultCount, &useHalBufManager, &cb, 0,
+ /*maxResolution*/ false, dynamicRangeProfile);
+ ASSERT_NE(mSession, nullptr);
+
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ descriptor;
+ auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
+ ASSERT_TRUE(resultQueueRet.isOk());
+
+ std::shared_ptr<ResultMetadataQueue> resultQueue =
+ std::make_shared<ResultMetadataQueue>(descriptor);
+ if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
+ resultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+
+ mInflightMap.clear();
+ // Stream as long as needed to fill the Hal inflight queue
+ std::vector<CaptureRequest> requests(halStreams[0].maxBuffers);
+
+ for (int32_t requestId = 0; requestId < requests.size(); requestId++) {
+ std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
+ static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
+ partialResultCount, std::unordered_set<std::string>(), resultQueue);
+
+ CaptureRequest& request = requests[requestId];
+ std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
+ outputBuffers.resize(halStreams.size());
+
+ size_t k = 0;
+ inflightReq->mOutstandingBufferIds.resize(halStreams.size());
+ std::vector<buffer_handle_t> graphicBuffers;
+ graphicBuffers.reserve(halStreams.size());
+
+ auto bufferId = requestId + 1; // Buffer id value 0 is not valid
+ for (const auto& halStream : halStreams) {
+ buffer_handle_t buffer_handle;
+ if (useHalBufManager) {
+ outputBuffers[k] = {halStream.id, 0,
+ NativeHandle(), BufferStatus::OK,
+ NativeHandle(), NativeHandle()};
+ } else {
+ auto usage = android_convertGralloc1To0Usage(
+ static_cast<uint64_t>(halStream.producerUsage),
+ static_cast<uint64_t>(halStream.consumerUsage));
+ allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
+ halStream.overrideFormat, &buffer_handle);
+
+ inflightReq->mOutstandingBufferIds[halStream.id][bufferId] = buffer_handle;
+ graphicBuffers.push_back(buffer_handle);
+ outputBuffers[k] = {
+ halStream.id, bufferId, android::makeToAidl(buffer_handle),
+ BufferStatus::OK, NativeHandle(), NativeHandle()};
+ }
+ k++;
+ }
+
+ request.inputBuffer = {
+ -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
+ request.frameNumber = bufferId;
+ request.fmqSettingsSize = 0;
+ request.settings = settings;
+ request.inputWidth = 0;
+ request.inputHeight = 0;
+
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ mInflightMap[bufferId] = inflightReq;
+ }
+ }
+
+ int32_t numRequestProcessed = 0;
+ std::vector<BufferCache> cachesToRemove;
+ ndk::ScopedAStatus returnStatus =
+ mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(numRequestProcessed, requests.size());
+
+ returnStatus = mSession->repeatingRequestEnd(requests.size() - 1,
+ std::vector<int32_t> {halStreams[0].id});
+ ASSERT_TRUE(returnStatus.isOk());
+
+ // We are keeping frame numbers and buffer ids consistent. Buffer id value of 0
+ // is used to indicate a buffer that is not present/available so buffer ids as well
+ // as frame numbers begin with 1.
+ for (int32_t frameNumber = 1; frameNumber <= requests.size(); frameNumber++) {
+ const auto& inflightReq = mInflightMap[frameNumber];
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReq->errorCodeValid &&
+ ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ }
+
+ ASSERT_FALSE(inflightReq->errorCodeValid);
+ ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
+
+ if (dynamicRangeProfile != static_cast<RequestAvailableDynamicRangeProfilesMap>(
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD)) {
+ verify10BitMetadata(mHandleImporter, *inflightReq, dynamicRangeProfile);
+ }
+ }
+
+ if (useHalBufManager) {
+ std::vector<int32_t> streamIds(halStreams.size());
+ for (size_t i = 0; i < streamIds.size(); i++) {
+ streamIds[i] = halStreams[i].id;
+ }
+ mSession->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0);
+ cb->waitForBuffersReturned();
+ }
+
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ }
+}
+
+void CameraAidlTest::processZoomSettingsOverrideRequests(
+ int32_t frameCount, const bool *overrideSequence, const bool *expectedResults) {
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+ static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+ int64_t bufferId = 1;
+ int32_t frameNumber = 1;
+ CameraMetadata settings;
+ ndk::ScopedAStatus ret;
+ for (const auto& name : cameraDeviceNames) {
+ CameraMetadata meta;
+ std::shared_ptr<ICameraDevice> device;
+ openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+ &device /*out*/);
+ camera_metadata_t* staticMeta =
+ clone_camera_metadata(reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
+
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+
+ // Device does not support zoom settnigs override
+ if (!supportZoomSettingsOverride(staticMeta)) {
+ continue;
+ }
+
+ if (!isPerFrameControl(staticMeta)) {
+ continue;
+ }
+
+ bool supportsPartialResults = false;
+ bool useHalBufManager = false;
+ int32_t partialResultCount = 0;
+ Stream previewStream;
+ std::vector<HalStream> halStreams;
+ std::shared_ptr<DeviceCb> cb;
+ configurePreviewStream(name, mProvider, &previewThreshold, &mSession /*out*/,
+ &previewStream /*out*/, &halStreams /*out*/,
+ &supportsPartialResults /*out*/, &partialResultCount /*out*/,
+ &useHalBufManager /*out*/, &cb /*out*/);
+ ASSERT_NE(mSession, nullptr);
+
+ ::aidl::android::hardware::common::fmq::MQDescriptor<
+ int8_t, aidl::android::hardware::common::fmq::SynchronizedReadWrite>
+ descriptor;
+ auto resultQueueRet = mSession->getCaptureResultMetadataQueue(&descriptor);
+ ASSERT_TRUE(resultQueueRet.isOk());
+
+ std::shared_ptr<ResultMetadataQueue> resultQueue =
+ std::make_shared<ResultMetadataQueue>(descriptor);
+ if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: HAL returns empty result metadata fmq, not use it", __func__);
+ resultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+
+ ret = mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &settings);
+ ASSERT_TRUE(ret.isOk());
+
+ mInflightMap.clear();
+ ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
+ std::vector<CaptureRequest> requests(frameCount);
+ std::vector<buffer_handle_t> buffers(frameCount);
+ std::vector<std::shared_ptr<InFlightRequest>> inflightReqs(frameCount);
+ std::vector<CameraMetadata> requestSettings(frameCount);
+
+ for (int32_t i = 0; i < frameCount; i++) {
+ std::unique_lock<std::mutex> l(mLock);
+ CaptureRequest& request = requests[i];
+ std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
+ outputBuffers.resize(1);
+ StreamBuffer& outputBuffer = outputBuffers[0];
+
+ if (useHalBufManager) {
+ outputBuffer = {halStreams[0].id, 0,
+ NativeHandle(), BufferStatus::OK,
+ NativeHandle(), NativeHandle()};
+ } else {
+ allocateGraphicBuffer(previewStream.width, previewStream.height,
+ android_convertGralloc1To0Usage(
+ static_cast<uint64_t>(halStreams[0].producerUsage),
+ static_cast<uint64_t>(halStreams[0].consumerUsage)),
+ halStreams[0].overrideFormat, &buffers[i]);
+ outputBuffer = {halStreams[0].id, bufferId + i, ::android::makeToAidl(buffers[i]),
+ BufferStatus::OK, NativeHandle(), NativeHandle()};
+ }
+
+ // Set appropriate settings override tag
+ requestMeta.append(reinterpret_cast<camera_metadata_t*>(settings.metadata.data()));
+ int32_t settingsOverride = overrideSequence[i] ?
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM : ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF;
+ ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_SETTINGS_OVERRIDE,
+ &settingsOverride, 1));
+ camera_metadata_t* metaBuffer = requestMeta.release();
+ uint8_t* rawMetaBuffer = reinterpret_cast<uint8_t*>(metaBuffer);
+ requestSettings[i].metadata = std::vector(
+ rawMetaBuffer, rawMetaBuffer + get_camera_metadata_size(metaBuffer));
+ overrideRotateAndCrop(&(requestSettings[i]));
+ request.frameNumber = frameNumber + i;
+ request.fmqSettingsSize = 0;
+ request.settings = requestSettings[i];
+ request.inputBuffer = {
+ -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
+
+ inflightReqs[i] = std::make_shared<InFlightRequest>(1, false, supportsPartialResults,
+ partialResultCount, resultQueue);
+ mInflightMap[frameNumber + i] = inflightReqs[i];
+ }
+
+ int32_t numRequestProcessed = 0;
+ std::vector<BufferCache> cachesToRemove;
+
+ ndk::ScopedAStatus returnStatus =
+ mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(numRequestProcessed, frameCount);
+
+ for (size_t i = 0; i < frameCount; i++) {
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReqs[i]->errorCodeValid && ((0 < inflightReqs[i]->numBuffersLeft) ||
+ (!inflightReqs[i]->haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ }
+
+ ASSERT_FALSE(inflightReqs[i]->errorCodeValid);
+ ASSERT_NE(inflightReqs[i]->resultOutputBuffers.size(), 0u);
+ ASSERT_EQ(previewStream.id, inflightReqs[i]->resultOutputBuffers[0].buffer.streamId);
+ ASSERT_FALSE(inflightReqs[i]->collectedResult.isEmpty());
+ ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(ANDROID_CONTROL_SETTINGS_OVERRIDE));
+ camera_metadata_entry_t overrideResult =
+ inflightReqs[i]->collectedResult.find(ANDROID_CONTROL_SETTINGS_OVERRIDE);
+ ASSERT_EQ(overrideResult.data.i32[0] == ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM,
+ expectedResults[i]);
+ ASSERT_TRUE(inflightReqs[i]->collectedResult.exists(
+ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER));
+ camera_metadata_entry_t frameNumberEntry = inflightReqs[i]->collectedResult.find(
+ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER);
+ ALOGV("%s: i %zu, expcetedResults[i] %d, overrideResult is %d, frameNumber %d",
+ __FUNCTION__, i, expectedResults[i], overrideResult.data.i32[0],
+ frameNumberEntry.data.i32[0]);
+ if (expectedResults[i]) {
+ ASSERT_GT(frameNumberEntry.data.i32[0], inflightReqs[i]->frameNumber);
+ } else {
+ ASSERT_EQ(frameNumberEntry.data.i32[0], frameNumber + i);
+ }
+ }
+
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
+ }
+}
+
+void CameraAidlTest::getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
+ std::vector<std::tuple<size_t, size_t>>* sizes /*out*/) {
+ if (sizes == nullptr) {
+ return;
+ }
+
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(ch, tag, &entry);
+ if ((0 == retcode) && (entry.count > 0)) {
+ // Scaler entry contains 4 elements (format, width, height, type)
+ for (size_t i = 0; i < entry.count; i += 4) {
+ if ((entry.data.i32[i] == format) &&
+ (entry.data.i32[i + 3] == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
+ sizes->push_back(std::make_tuple(entry.data.i32[i + 1], entry.data.i32[i + 2]));
+ }
+ }
+ }
+}
+
+void CameraAidlTest::getSupportedDurations(const camera_metadata_t* ch, uint32_t tag,
+ int32_t format,
+ const std::vector<std::tuple<size_t, size_t>>& sizes,
+ std::vector<int64_t>* durations /*out*/) {
+ if (durations == nullptr) {
+ return;
+ }
+
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(ch, tag, &entry);
+ if ((0 == retcode) && (entry.count > 0)) {
+ // Duration entry contains 4 elements (format, width, height, duration)
+ for (const auto& size : sizes) {
+ int64_t width = std::get<0>(size);
+ int64_t height = std::get<1>(size);
+ for (size_t i = 0; i < entry.count; i += 4) {
+ if ((entry.data.i64[i] == format) && (entry.data.i64[i + 1] == width) &&
+ (entry.data.i64[i + 2] == height)) {
+ durations->push_back(entry.data.i64[i + 3]);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index d4d9bdd..fe1f048 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -47,6 +47,8 @@
#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
+#include <aidl/android/hardware/camera/metadata/RequestAvailableColorSpaceProfilesMap.h>
+
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <gtest/gtest.h>
@@ -126,6 +128,28 @@
YUV_REPROCESS,
};
+ // Copied from ColorSpace.java (see Named)
+ enum ColorSpaceNamed {
+ SRGB,
+ LINEAR_SRGB,
+ EXTENDED_SRGB,
+ LINEAR_EXTENDED_SRGB,
+ BT709,
+ BT2020,
+ DCI_P3,
+ DISPLAY_P3,
+ NTSC_1953,
+ SMPTE_C,
+ ADOBE_RGB,
+ PRO_PHOTO_RGB,
+ ACES,
+ ACESCG,
+ CIE_XYZ,
+ CIE_LAB,
+ BT2020_HLG,
+ BT2020_PQ
+ };
+
struct AvailableZSLInputOutput {
int32_t inputFormat;
int32_t outputFormat;
@@ -204,6 +228,8 @@
int32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/,
std::shared_ptr<DeviceCb>* cb /*out*/, uint32_t streamConfigCounter = 0);
+ void configureStreamUseCaseInternal(const AvailableStream &threshold);
+
void configureSingleStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, uint64_t bufferUsage,
@@ -233,6 +259,8 @@
static void verifyStreamUseCaseCharacteristics(const camera_metadata_t* metadata);
+ static void verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata);
+
static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
const StreamConfiguration& config, bool expectedStatus,
bool expectStreamCombQuery);
@@ -351,11 +379,54 @@
std::vector<aidl::android::hardware::camera::metadata::
RequestAvailableDynamicRangeProfilesMap>* profiles);
+ static bool reportsColorSpaces(const camera_metadata_t* staticMeta);
+
+ static void getColorSpaceProfiles(
+ const camera_metadata_t* staticMeta,
+ std::vector<aidl::android::hardware::camera::metadata::
+ RequestAvailableColorSpaceProfilesMap>* profiles);
+
+ static bool isColorSpaceCompatibleWithDynamicRangeAndPixelFormat(
+ const camera_metadata_t* staticMeta,
+ aidl::android::hardware::camera::metadata::
+ RequestAvailableColorSpaceProfilesMap colorSpace,
+ aidl::android::hardware::camera::metadata::
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile,
+ aidl::android::hardware::graphics::common::PixelFormat pixelFormat);
+
+ static const char* getColorSpaceProfileString(aidl::android::hardware::camera::metadata::
+ RequestAvailableColorSpaceProfilesMap colorSpace);
+
+ static const char* getDynamicRangeProfileString(aidl::android::hardware::camera::metadata::
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
+
+ static int32_t halFormatToPublicFormat(
+ aidl::android::hardware::graphics::common::PixelFormat pixelFormat);
+
// Used by switchToOffline where a new result queue is created for offline reqs
void updateInflightResultQueue(const std::shared_ptr<ResultMetadataQueue>& resultQueue);
static Size getMinSize(Size a, Size b);
+ void processColorSpaceRequest(aidl::android::hardware::camera::metadata::
+ RequestAvailableColorSpaceProfilesMap colorSpace,
+ aidl::android::hardware::camera::metadata::
+ RequestAvailableDynamicRangeProfilesMap dynamicRangeProfile);
+
+ void processZoomSettingsOverrideRequests(
+ int32_t frameCount, const bool *overrideSequence, const bool *expectedResults);
+
+ bool supportZoomSettingsOverride(const camera_metadata_t* staticMeta);
+ bool supportsCroppedRawUseCase(const camera_metadata_t *staticMeta);
+ bool isPerFrameControl(const camera_metadata_t* staticMeta);
+
+ void getSupportedSizes(const camera_metadata_t* ch, uint32_t tag, int32_t format,
+ std::vector<std::tuple<size_t, size_t>>* sizes /*out*/);
+
+ void getSupportedDurations(const camera_metadata_t* ch, uint32_t tag, int32_t format,
+ const std::vector<std::tuple<size_t, size_t>>& sizes,
+ std::vector<int64_t>* durations /*out*/);
+
protected:
// In-flight queue for tracking completion of capture requests.
struct InFlightRequest {
diff --git a/camera/provider/default/Android.bp b/camera/provider/default/Android.bp
new file mode 100644
index 0000000..ed45cbe
--- /dev/null
+++ b/camera/provider/default/Android.bp
@@ -0,0 +1,104 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_shared {
+ name: "android.hardware.camera.provider-V1-external-impl",
+ defaults: ["hidl_defaults"],
+ proprietary: true,
+ srcs: [
+ "ExternalCameraProvider.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.camera.common-V1-ndk",
+ "android.hardware.camera.device-V1-ndk",
+ "android.hardware.camera.provider-V1-ndk",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "camera.device-external-impl",
+ "libbinder_ndk",
+ "libcamera_metadata",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libtinyxml2",
+ "libutils",
+ ],
+ static_libs: [
+ "[email protected]",
+ ],
+ export_include_dirs: ["."],
+}
+
+cc_defaults {
+ name: "camera_external_service_defaults",
+ defaults: ["hidl_defaults"],
+ proprietary: true,
+ relative_install_path: "hw",
+ srcs: ["external-service.cpp"],
+ compile_multilib: "first",
+ shared_libs: [
+ "android.hardware.camera.common-V1-ndk",
+ "android.hardware.camera.device-V1-ndk",
+ "android.hardware.camera.provider-V1-ndk",
+ "android.hardware.camera.provider-V1-external-impl",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "[email protected]",
+ "camera.device-external-impl",
+ "libbinder_ndk",
+ "libcamera_metadata",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libtinyxml2",
+ "libutils",
+ ],
+ static_libs: [
+ "[email protected]",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.camera.provider-V1-external-service",
+ defaults: ["camera_external_service_defaults"],
+ init_rc: ["android.hardware.camera.provider-V1-external-service.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.camera.provider-V1-external-service-lazy",
+ overrides: ["android.hardware.camera.provider-V1-external-service"],
+ defaults: ["camera_external_service_defaults"],
+ init_rc: ["android.hardware.camera.provider-V1-external-service-lazy.rc"],
+ cflags: ["-DLAZY_SERVICE"],
+}
diff --git a/camera/provider/default/ExternalCameraProvider.cpp b/camera/provider/default/ExternalCameraProvider.cpp
new file mode 100644
index 0000000..4d2c847
--- /dev/null
+++ b/camera/provider/default/ExternalCameraProvider.cpp
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExtCamPrvdr"
+// #define LOG_NDEBUG 0
+
+#include "ExternalCameraProvider.h"
+
+#include <ExternalCameraDevice.h>
+#include <aidl/android/hardware/camera/common/Status.h>
+#include <convert.h>
+#include <cutils/properties.h>
+#include <linux/videodev2.h>
+#include <log/log.h>
+#include <sys/inotify.h>
+#include <regex>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::Status;
+using ::android::hardware::camera::device::implementation::ExternalCameraDevice;
+using ::android::hardware::camera::device::implementation::fromStatus;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+
+namespace {
+// "device@<version>/external/<id>"
+const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
+const int kMaxDevicePathLen = 256;
+constexpr char kDevicePath[] = "/dev/";
+constexpr char kPrefix[] = "video";
+constexpr int kPrefixLen = sizeof(kPrefix) - 1;
+constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen - 1;
+
+bool matchDeviceName(int cameraIdOffset, const std::string& deviceName, std::string* deviceVersion,
+ std::string* cameraDevicePath) {
+ std::smatch sm;
+ if (std::regex_match(deviceName, sm, kDeviceNameRE)) {
+ if (deviceVersion != nullptr) {
+ *deviceVersion = sm[1];
+ }
+ if (cameraDevicePath != nullptr) {
+ *cameraDevicePath = "/dev/video" + std::to_string(std::stoi(sm[2]) - cameraIdOffset);
+ }
+ return true;
+ }
+ return false;
+}
+} // namespace
+
+ExternalCameraProvider::ExternalCameraProvider() : mCfg(ExternalCameraConfig::loadFromCfg()) {
+ mHotPlugThread = std::make_shared<HotplugThread>(this);
+ mHotPlugThread->run();
+}
+
+ExternalCameraProvider::~ExternalCameraProvider() {
+ mHotPlugThread->requestExitAndWait();
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::setCallback(
+ const std::shared_ptr<ICameraProviderCallback>& in_callback) {
+ {
+ Mutex::Autolock _l(mLock);
+ mCallback = in_callback;
+ }
+
+ if (mCallback == nullptr) {
+ return fromStatus(Status::OK);
+ }
+
+ for (const auto& pair : mCameraStatusMap) {
+ mCallback->cameraDeviceStatusChange(pair.first, pair.second);
+ }
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getVendorTags(
+ std::vector<VendorTagSection>* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+ // No vendor tag support for USB camera
+ *_aidl_return = {};
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getCameraIdList(std::vector<std::string>* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+ // External camera HAL always report 0 camera, and extra cameras
+ // are just reported via cameraDeviceStatusChange callbacks
+ *_aidl_return = {};
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getCameraDeviceInterface(
+ const std::string& in_cameraDeviceName, std::shared_ptr<ICameraDevice>* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+ std::string cameraDevicePath, deviceVersion;
+ bool match = matchDeviceName(mCfg.cameraIdOffset, in_cameraDeviceName, &deviceVersion,
+ &cameraDevicePath);
+
+ if (!match) {
+ *_aidl_return = nullptr;
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+
+ if (mCameraStatusMap.count(in_cameraDeviceName) == 0 ||
+ mCameraStatusMap[in_cameraDeviceName] != CameraDeviceStatus::PRESENT) {
+ *_aidl_return = nullptr;
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+
+ ALOGV("Constructing external camera device");
+ std::shared_ptr<ExternalCameraDevice> deviceImpl =
+ ndk::SharedRefBase::make<ExternalCameraDevice>(cameraDevicePath, mCfg);
+ if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
+ ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraDevicePath.c_str());
+ *_aidl_return = nullptr;
+ return fromStatus(Status::INTERNAL_ERROR);
+ }
+
+ IF_ALOGV() {
+ int interfaceVersion;
+ deviceImpl->getInterfaceVersion(&interfaceVersion);
+ ALOGV("%s: device interface version: %d", __FUNCTION__, interfaceVersion);
+ }
+
+ *_aidl_return = deviceImpl;
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::notifyDeviceStateChange(int64_t) {
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::getConcurrentCameraIds(
+ std::vector<ConcurrentCameraIdCombination>* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+ *_aidl_return = {};
+ return fromStatus(Status::OK);
+}
+
+ndk::ScopedAStatus ExternalCameraProvider::isConcurrentStreamCombinationSupported(
+ const std::vector<CameraIdAndStreamCombination>&, bool* _aidl_return) {
+ if (_aidl_return == nullptr) {
+ return fromStatus(Status::ILLEGAL_ARGUMENT);
+ }
+ // No concurrent stream combinations are supported
+ *_aidl_return = false;
+ return fromStatus(Status::OK);
+}
+
+void ExternalCameraProvider::addExternalCamera(const char* devName) {
+ ALOGV("%s: ExtCam: adding %s to External Camera HAL!", __FUNCTION__, devName);
+ Mutex::Autolock _l(mLock);
+ std::string deviceName;
+ std::string cameraId =
+ std::to_string(mCfg.cameraIdOffset + std::atoi(devName + kDevicePrefixLen));
+ deviceName =
+ std::string("device@") + ExternalCameraDevice::kDeviceVersion + "/external/" + cameraId;
+ mCameraStatusMap[deviceName] = CameraDeviceStatus::PRESENT;
+ if (mCallback != nullptr) {
+ mCallback->cameraDeviceStatusChange(deviceName, CameraDeviceStatus::PRESENT);
+ }
+}
+
+void ExternalCameraProvider::deviceAdded(const char* devName) {
+ {
+ base::unique_fd fd(::open(devName, O_RDWR));
+ if (fd.get() < 0) {
+ ALOGE("%s open v4l2 device %s failed:%s", __FUNCTION__, devName, strerror(errno));
+ return;
+ }
+
+ struct v4l2_capability capability;
+ int ret = ioctl(fd.get(), VIDIOC_QUERYCAP, &capability);
+ if (ret < 0) {
+ ALOGE("%s v4l2 QUERYCAP %s failed", __FUNCTION__, devName);
+ return;
+ }
+
+ if (!(capability.device_caps & V4L2_CAP_VIDEO_CAPTURE)) {
+ ALOGW("%s device %s does not support VIDEO_CAPTURE", __FUNCTION__, devName);
+ return;
+ }
+ }
+
+ // See if we can initialize ExternalCameraDevice correctly
+ std::shared_ptr<ExternalCameraDevice> deviceImpl =
+ ndk::SharedRefBase::make<ExternalCameraDevice>(devName, mCfg);
+ if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
+ ALOGW("%s: Attempt to init camera device %s failed!", __FUNCTION__, devName);
+ return;
+ }
+ deviceImpl.reset();
+ addExternalCamera(devName);
+}
+
+void ExternalCameraProvider::deviceRemoved(const char* devName) {
+ Mutex::Autolock _l(mLock);
+ std::string deviceName;
+ std::string cameraId =
+ std::to_string(mCfg.cameraIdOffset + std::atoi(devName + kDevicePrefixLen));
+
+ deviceName =
+ std::string("device@") + ExternalCameraDevice::kDeviceVersion + "/external/" + cameraId;
+
+ if (mCameraStatusMap.erase(deviceName) == 0) {
+ // Unknown device, do not fire callback
+ ALOGE("%s: cannot find camera device to remove %s", __FUNCTION__, devName);
+ return;
+ }
+
+ if (mCallback != nullptr) {
+ mCallback->cameraDeviceStatusChange(deviceName, CameraDeviceStatus::NOT_PRESENT);
+ }
+}
+
+void ExternalCameraProvider::updateAttachedCameras() {
+ ALOGV("%s start scanning for existing V4L2 devices", __FUNCTION__);
+
+ // Find existing /dev/video* devices
+ DIR* devdir = opendir(kDevicePath);
+ if (devdir == nullptr) {
+ ALOGE("%s: cannot open %s! Exiting threadloop", __FUNCTION__, kDevicePath);
+ return;
+ }
+
+ struct dirent* de;
+ while ((de = readdir(devdir)) != nullptr) {
+ // Find external v4l devices that's existing before we start watching and add them
+ if (!strncmp(kPrefix, de->d_name, kPrefixLen)) {
+ std::string deviceId(de->d_name + kPrefixLen);
+ if (mCfg.mInternalDevices.count(deviceId) == 0) {
+ ALOGV("Non-internal v4l device %s found", de->d_name);
+ char v4l2DevicePath[kMaxDevicePathLen];
+ snprintf(v4l2DevicePath, kMaxDevicePathLen, "%s%s", kDevicePath, de->d_name);
+ deviceAdded(v4l2DevicePath);
+ }
+ }
+ }
+ closedir(devdir);
+}
+
+// Start ExternalCameraProvider::HotplugThread functions
+
+ExternalCameraProvider::HotplugThread::HotplugThread(ExternalCameraProvider* parent)
+ : mParent(parent), mInternalDevices(parent->mCfg.mInternalDevices) {}
+
+ExternalCameraProvider::HotplugThread::~HotplugThread() {
+ // Clean up inotify descriptor if needed.
+ if (mINotifyFD >= 0) {
+ close(mINotifyFD);
+ }
+}
+
+bool ExternalCameraProvider::HotplugThread::initialize() {
+ // Update existing cameras
+ mParent->updateAttachedCameras();
+
+ // Set up non-blocking fd. The threadLoop will be responsible for polling read at the
+ // desired frequency
+ mINotifyFD = inotify_init();
+ if (mINotifyFD < 0) {
+ ALOGE("%s: inotify init failed! Exiting threadloop", __FUNCTION__);
+ return false;
+ }
+
+ // Start watching /dev/ directory for created and deleted files
+ mWd = inotify_add_watch(mINotifyFD, kDevicePath, IN_CREATE | IN_DELETE);
+ if (mWd < 0) {
+ ALOGE("%s: inotify add watch failed! Exiting threadloop", __FUNCTION__);
+ return false;
+ }
+
+ mPollFd = {.fd = mINotifyFD, .events = POLLIN};
+
+ mIsInitialized = true;
+ return true;
+}
+
+bool ExternalCameraProvider::HotplugThread::threadLoop() {
+ // Initialize inotify descriptors if needed.
+ if (!mIsInitialized && !initialize()) {
+ return true;
+ }
+
+ // poll /dev/* and handle timeouts and error
+ int pollRet = poll(&mPollFd, /* fd_count= */ 1, /* timeout= */ 250);
+ if (pollRet == 0) {
+ // no read event in 100ms
+ mPollFd.revents = 0;
+ return true;
+ } else if (pollRet < 0) {
+ ALOGE("%s: error while polling for /dev/*: %d", __FUNCTION__, errno);
+ mPollFd.revents = 0;
+ return true;
+ } else if (mPollFd.revents & POLLERR) {
+ ALOGE("%s: polling /dev/ returned POLLERR", __FUNCTION__);
+ mPollFd.revents = 0;
+ return true;
+ } else if (mPollFd.revents & POLLHUP) {
+ ALOGE("%s: polling /dev/ returned POLLHUP", __FUNCTION__);
+ mPollFd.revents = 0;
+ return true;
+ } else if (mPollFd.revents & POLLNVAL) {
+ ALOGE("%s: polling /dev/ returned POLLNVAL", __FUNCTION__);
+ mPollFd.revents = 0;
+ return true;
+ }
+ // mPollFd.revents must contain POLLIN, so safe to reset it before reading
+ mPollFd.revents = 0;
+
+ uint64_t offset = 0;
+ ssize_t ret = read(mINotifyFD, mEventBuf, sizeof(mEventBuf));
+ if (ret < sizeof(struct inotify_event)) {
+ // invalid event. skip
+ return true;
+ }
+
+ while (offset < ret) {
+ struct inotify_event* event = (struct inotify_event*)&mEventBuf[offset];
+ offset += sizeof(struct inotify_event) + event->len;
+
+ if (event->wd != mWd) {
+ // event for an unrelated descriptor. ignore.
+ continue;
+ }
+
+ ALOGV("%s inotify_event %s", __FUNCTION__, event->name);
+ if (strncmp(kPrefix, event->name, kPrefixLen) != 0) {
+ // event not for /dev/video*. ignore.
+ continue;
+ }
+
+ std::string deviceId = event->name + kPrefixLen;
+ if (mInternalDevices.count(deviceId) != 0) {
+ // update to an internal device. ignore.
+ continue;
+ }
+
+ char v4l2DevicePath[kMaxDevicePathLen];
+ snprintf(v4l2DevicePath, kMaxDevicePathLen, "%s%s", kDevicePath, event->name);
+
+ if (event->mask & IN_CREATE) {
+ mParent->deviceAdded(v4l2DevicePath);
+ } else if (event->mask & IN_DELETE) {
+ mParent->deviceRemoved(v4l2DevicePath);
+ }
+ }
+ return true;
+}
+
+// End ExternalCameraProvider::HotplugThread functions
+
+} // namespace implementation
+} // namespace provider
+} // namespace camera
+} // namespace hardware
+} // namespace android
diff --git a/camera/provider/default/ExternalCameraProvider.h b/camera/provider/default/ExternalCameraProvider.h
new file mode 100644
index 0000000..347a53c
--- /dev/null
+++ b/camera/provider/default/ExternalCameraProvider.h
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_CAMERA_PROVIDER_DEFAULT_EXTERNALCAMERAPROVIDER_H_
+#define HARDWARE_INTERFACES_CAMERA_PROVIDER_DEFAULT_EXTERNALCAMERAPROVIDER_H_
+
+#include <ExternalCameraUtils.h>
+#include <SimpleThread.h>
+#include <aidl/android/hardware/camera/common/CameraDeviceStatus.h>
+#include <aidl/android/hardware/camera/common/VendorTagSection.h>
+#include <aidl/android/hardware/camera/device/ICameraDevice.h>
+#include <aidl/android/hardware/camera/provider/BnCameraProvider.h>
+#include <aidl/android/hardware/camera/provider/CameraIdAndStreamCombination.h>
+#include <aidl/android/hardware/camera/provider/ConcurrentCameraIdCombination.h>
+#include <aidl/android/hardware/camera/provider/ICameraProviderCallback.h>
+#include <poll.h>
+#include <utils/Mutex.h>
+#include <utils/Thread.h>
+#include <thread>
+#include <unordered_map>
+#include <unordered_set>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace implementation {
+
+using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
+using ::aidl::android::hardware::camera::common::VendorTagSection;
+using ::aidl::android::hardware::camera::device::ICameraDevice;
+using ::aidl::android::hardware::camera::provider::BnCameraProvider;
+using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
+using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
+using ::aidl::android::hardware::camera::provider::ICameraProviderCallback;
+using ::android::hardware::camera::common::helper::SimpleThread;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+
+class ExternalCameraProvider : public BnCameraProvider {
+ public:
+ ExternalCameraProvider();
+ ~ExternalCameraProvider() override;
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<ICameraProviderCallback>& in_callback) override;
+ ndk::ScopedAStatus getVendorTags(std::vector<VendorTagSection>* _aidl_return) override;
+ ndk::ScopedAStatus getCameraIdList(std::vector<std::string>* _aidl_return) override;
+ ndk::ScopedAStatus getCameraDeviceInterface(
+ const std::string& in_cameraDeviceName,
+ std::shared_ptr<ICameraDevice>* _aidl_return) override;
+ ndk::ScopedAStatus notifyDeviceStateChange(int64_t in_deviceState) override;
+ ndk::ScopedAStatus getConcurrentCameraIds(
+ std::vector<ConcurrentCameraIdCombination>* _aidl_return) override;
+ ndk::ScopedAStatus isConcurrentStreamCombinationSupported(
+ const std::vector<CameraIdAndStreamCombination>& in_configs,
+ bool* _aidl_return) override;
+
+ private:
+ void addExternalCamera(const char* devName);
+ void deviceAdded(const char* devName);
+ void deviceRemoved(const char* devName);
+ void updateAttachedCameras();
+
+ // A separate thread to monitor '/dev' directory for '/dev/video*' entries
+ // This thread calls back into ExternalCameraProvider when an actionable change is detected.
+ class HotplugThread : public SimpleThread {
+ public:
+ explicit HotplugThread(ExternalCameraProvider* parent);
+ ~HotplugThread() override;
+
+ protected:
+ bool threadLoop() override;
+
+ private:
+ // Returns true if thread initialization succeeded, and false if thread initialization
+ // failed.
+ bool initialize();
+
+ ExternalCameraProvider* mParent = nullptr;
+ const std::unordered_set<std::string> mInternalDevices;
+
+ bool mIsInitialized = false;
+
+ int mINotifyFD = -1;
+ int mWd = -1;
+
+ // struct to wrap mINotifyFD and poll it with timeout
+ struct pollfd mPollFd = {};
+ char mEventBuf[512] = {0};
+ };
+
+ Mutex mLock;
+ std::shared_ptr<ICameraProviderCallback> mCallback = nullptr;
+ std::unordered_map<std::string, CameraDeviceStatus> mCameraStatusMap; // camera id -> status
+ const ExternalCameraConfig mCfg;
+ std::shared_ptr<HotplugThread> mHotPlugThread;
+};
+
+} // namespace implementation
+} // namespace provider
+} // namespace camera
+} // namespace hardware
+} // namespace android
+
+#endif // HARDWARE_INTERFACES_CAMERA_PROVIDER_DEFAULT_EXTERNALCAMERAPROVIDER_H_
diff --git a/camera/provider/default/android.hardware.camera.provider-V1-external-service-lazy.rc b/camera/provider/default/android.hardware.camera.provider-V1-external-service-lazy.rc
new file mode 100644
index 0000000..dcdd88c
--- /dev/null
+++ b/camera/provider/default/android.hardware.camera.provider-V1-external-service-lazy.rc
@@ -0,0 +1,10 @@
+service vendor.camera.provider-ext /vendor/bin/hw/android.hardware.camera.provider-V1-external-service-lazy
+ interface aidl android.hardware.camera.provider.ICameraProvider/external/0
+ class hal
+ oneshot
+ disabled
+ user cameraserver
+ group audio camera input drmrpc usb
+ ioprio rt 4
+ capabilities SYS_NICE
+ task_profiles CameraServiceCapacity MaxPerformance
\ No newline at end of file
diff --git a/camera/provider/default/android.hardware.camera.provider-V1-external-service.rc b/camera/provider/default/android.hardware.camera.provider-V1-external-service.rc
new file mode 100644
index 0000000..302c56f
--- /dev/null
+++ b/camera/provider/default/android.hardware.camera.provider-V1-external-service.rc
@@ -0,0 +1,8 @@
+service vendor.camera.provider-ext /vendor/bin/hw/android.hardware.camera.provider-V1-external-service
+ interface aidl android.hardware.camera.provider.ICameraProvider/external/0
+ class hal
+ user cameraserver
+ group audio camera input drmrpc usb
+ ioprio rt 4
+ capabilities SYS_NICE
+ task_profiles CameraServiceCapacity MaxPerformance
\ No newline at end of file
diff --git a/camera/provider/default/external-service.cpp b/camera/provider/default/external-service.cpp
new file mode 100644
index 0000000..b18f182
--- /dev/null
+++ b/camera/provider/default/external-service.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ExternalCameraProvider.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::android::hardware::camera::provider::implementation::ExternalCameraProvider;
+
+namespace {
+// Default recommended RPC thread count for camera provider implementations
+const int HWBINDER_THREAD_COUNT = 6;
+} // namespace
+
+int main() {
+ ALOGI("CameraProvider: external webcam service is starting.");
+
+ ABinderProcess_setThreadPoolMaxThreadCount(HWBINDER_THREAD_COUNT);
+
+ std::shared_ptr<ExternalCameraProvider> defaultProvider =
+ ndk::SharedRefBase::make<ExternalCameraProvider>();
+ const std::string serviceName = std::string(ExternalCameraProvider::descriptor) + "/external/0";
+
+#ifdef LAZY_SERVICE
+ binder_exception_t ret = AServiceManager_registerLazyService(defaultProvider->asBinder().get(),
+ serviceName.c_str());
+ LOG_ALWAYS_FATAL_IF(ret != EX_NONE,
+ "Error while registering lazy ext camera provider service: %d", ret);
+#else
+ binder_exception_t ret =
+ AServiceManager_addService(defaultProvider->asBinder().get(), serviceName.c_str());
+ LOG_ALWAYS_FATAL_IF(ret != EX_NONE, "Error while registering ext camera provider service: %d",
+ ret);
+#endif
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
\ No newline at end of file
diff --git a/cas/OWNERS b/cas/OWNERS
new file mode 100644
index 0000000..473c8f26
--- /dev/null
+++ b/cas/OWNERS
@@ -0,0 +1 @@
+include /tv/input/OWNERS
diff --git a/cas/aidl/TEST_MAPPING b/cas/aidl/TEST_MAPPING
new file mode 100644
index 0000000..5bcd388
--- /dev/null
+++ b/cas/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalCasAidlTargetTest"
+ }
+ ]
+}
diff --git a/cas/aidl/android/hardware/cas/DestinationBuffer.aidl b/cas/aidl/android/hardware/cas/DestinationBuffer.aidl
index 74336c2..ac562dc 100644
--- a/cas/aidl/android/hardware/cas/DestinationBuffer.aidl
+++ b/cas/aidl/android/hardware/cas/DestinationBuffer.aidl
@@ -25,13 +25,13 @@
@VintfStability
union DestinationBuffer {
/**
- * If type == SHARED_MEMORY, the descrambled data must be written
+ * If the buffer is SharedBuffer, the descrambled data must be written
* to user-space non-secure shared memory.
*/
SharedBuffer nonsecureMemory;
/**
- * If type == NATIVE_HANDLE, the descrambled data must be written
+ * If the buffer is presented by NativeHandle, the descrambled data must be written
* to secure memory referenced by the vendor's buffer allocator.
*/
NativeHandle secureMemory;
diff --git a/cas/aidl/vts/functional/AndroidTest.xml b/cas/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..6e6af93
--- /dev/null
+++ b/cas/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalCasAidlTargetTest.">
+ <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="VtsHalCasAidlTargetTest->/data/local/tmp/VtsHalCasAidlTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalCasAidlTargetTest" />
+ <option name="native-test-timeout" value="30m" />
+ </test>
+</configuration>
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 7f6890c..f3ea8e8 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -36,6 +36,9 @@
],
min_sdk_version: "29",
},
+ rust: {
+ enabled: true,
+ }
},
frozen: true,
versions: [
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 40ceb32..3b022fc 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -24,18 +24,28 @@
stability: "vintf",
backend: {
java: {
+ // There is no Java FMQ library, but we support the AIDL type
+ // to allow subsets of interfaces that include it to be used in Java
+ enabled: true,
sdk_version: "module_current",
},
cpp: {
+ // FMQ will not be supported in the cpp backend because the parcelables
+ // are not stable enough for use in shared memory
enabled: false,
},
ndk: {
apex_available: [
"//apex_available:platform",
"com.android.btservices",
+ "com.android.media.swcodec",
],
min_sdk_version: "29",
},
+ rust: {
+ // FMQ is not supported in the rust backend
+ enabled: false,
+ },
},
frozen: true,
versions_with_info: [
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index 93beb92..4ac95f5 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -60,47 +60,27 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.authsecret</name>
- <version>1.0</version>
- <interface>
- <name>IAuthSecret</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.automotive.audiocontrol</name>
+ <version>2-3</version>
<interface>
<name>IAudioControl</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="aidl" optional="true">
<name>android.hardware.automotive.can</name>
- <version>1.0</version>
- <interface>
- <name>ICanBus</name>
- <regex-instance>.*</regex-instance>
- </interface>
+ <version>1</version>
<interface>
<name>ICanController</name>
- <regex-instance>.*</regex-instance>
+ <instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.automotive.evs</name>
+ <version>1-2</version>
<interface>
<name>IEvsEnumerator</name>
- <instance>default</instance>
- <regex-instance>[a-z]+/[0-9]+</regex-instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.automotive.evs</name>
- <version>1.0-1</version>
- <interface>
- <name>IEvsEnumerator</name>
- <instance>default</instance>
<regex-instance>[a-z]+/[0-9]+</regex-instance>
</interface>
</hal>
@@ -114,29 +94,29 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.automotive.vehicle</name>
+ <version>1-2</version>
<interface>
<name>IVehicle</name>
- <regex-instance>.*</regex-instance>
+ <instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.automotive.remoteaccess</name>
<interface>
<name>IRemoteAccess</name>
- <regex-instance>.*</regex-instance>
+ <instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.automotive.vehicle</name>
- <version>2.0</version>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.automotive.ivn</name>
<interface>
- <name>IVehicle</name>
- <regex-instance>.*</regex-instance>
+ <name>IIvnAndroidDevice</name>
+ <instance>default</instance>
</interface>
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.biometrics.face</name>
- <version>2</version>
+ <version>3</version>
<interface>
<name>IFace</name>
<instance>default</instance>
@@ -144,10 +124,11 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.biometrics.fingerprint</name>
- <version>2</version>
+ <version>3</version>
<interface>
<name>IFingerprint</name>
<instance>default</instance>
+ <instance>virtual</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
@@ -180,33 +161,16 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="aidl" optional="true">
<name>android.hardware.broadcastradio</name>
- <version>1.0-1</version>
- <interface>
- <name>IBroadcastRadioFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.broadcastradio</name>
- <version>2.0</version>
<interface>
<name>IBroadcastRadio</name>
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.camera.provider</name>
- <version>2.4-7</version>
- <interface>
- <name>ICameraProvider</name>
- <regex-instance>[^/]+/[0-9]+</regex-instance>
- </interface>
- </hal>
<hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.camera.provider</name>
- <version>1</version>
+ <version>1-2</version>
<interface>
<name>ICameraProvider</name>
<regex-instance>[^/]+/[0-9]+</regex-instance>
@@ -229,6 +193,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.contexthub</name>
+ <version>2</version>
<interface>
<name>IContextHub</name>
<instance>default</instance>
@@ -242,18 +207,6 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.drm</name>
- <version>1.3-4</version>
- <interface>
- <name>ICryptoFactory</name>
- <regex-instance>.*</regex-instance>
- </interface>
- <interface>
- <name>IDrmFactory</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.dumpstate</name>
<interface>
@@ -271,7 +224,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.gnss</name>
- <version>2</version>
+ <version>2-3</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
@@ -293,21 +246,6 @@
<instance>default</instance>
</interface>
</hal>
- <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
- If the HIDL composer HAL exists, it must be at least version 2.0.
- See DeviceManifestTest.GrallocHal -->
- <hal format="hidl" optional="true">
- <name>android.hardware.graphics.allocator</name>
- <!-- New, non-Go devices should use 4.0 or the AIDL hal.
- See DeviceManifestTest.GrallocVersionCompatibility. -->
- <version>2.0</version>
- <version>3.0</version>
- <version>4.0</version>
- <interface>
- <name>IAllocator</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.graphics.allocator</name>
<version>1-2</version>
@@ -316,20 +254,9 @@
<instance>default</instance>
</interface>
</hal>
- <!-- Either the AIDL or the HIDL composer HAL must exist on the device.
- If the HIDL composer HAL exists, it must be at least version 2.1.
- See DeviceManifestTest.ComposerHal -->
- <hal format="hidl" optional="true">
- <name>android.hardware.graphics.composer</name>
- <version>2.1-4</version>
- <interface>
- <name>IComposer</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.graphics.composer3</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IComposer</name>
<instance>default</instance>
@@ -438,15 +365,6 @@
</interface>
</hal>
<hal format="aidl" optional="true">
- <name>android.hardware.media.c2</name>
- <version>1</version>
- <interface>
- <name>IComponentStore</name>
- <regex-instance>default[0-9]*</regex-instance>
- <regex-instance>vendor[0-9]*_software</regex-instance>
- </interface>
- </hal>
- <hal format="aidl" optional="true">
<name>android.hardware.memtrack</name>
<version>1</version>
<interface>
@@ -454,14 +372,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.neuralnetworks</name>
- <version>1.0-3</version>
- <interface>
- <name>IDevice</name>
- <regex-instance>.*</regex-instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.neuralnetworks</name>
<version>1-4</version>
@@ -477,17 +387,9 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.oemlock</name>
- <version>1.0</version>
- <interface>
- <name>IOemLock</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.power</name>
- <version>2-3</version>
+ <version>4</version>
<interface>
<name>IPower</name>
<instance>default</instance>
@@ -503,7 +405,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.config</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioConfig</name>
<instance>default</instance>
@@ -511,7 +413,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.data</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioData</name>
<instance>slot1</instance>
@@ -521,7 +423,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.messaging</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioMessaging</name>
<instance>slot1</instance>
@@ -531,7 +433,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.modem</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioModem</name>
<instance>slot1</instance>
@@ -541,7 +443,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.network</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioNetwork</name>
<instance>slot1</instance>
@@ -551,7 +453,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.sim</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioSim</name>
<instance>slot1</instance>
@@ -571,7 +473,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.radio.voice</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IRadioVoice</name>
<instance>slot1</instance>
@@ -579,12 +481,22 @@
<instance>slot3</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.radio</name>
- <version>1.2</version>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.radio.ims</name>
+ <version>1</version>
<interface>
- <name>ISap</name>
+ <name>IRadioIms</name>
<instance>slot1</instance>
+ <instance>slot2</instance>
+ <instance>slot3</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.radio.ims.media</name>
+ <version>1</version>
+ <interface>
+ <name>IImsMedia</name>
+ <instance>default</instance>
</interface>
</hal>
<hal format="hidl" optional="true">
@@ -631,15 +543,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.sensors</name>
- <interface>
- <name>ISensors</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.sensors</name>
- <version>1.0</version>
- <version>2.0-1</version>
+ <version>2</version>
<interface>
<name>ISensors</name>
<instance>default</instance>
@@ -717,32 +621,25 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="aidl" optional="true">
+ <name>android.hardware.tv.tuner</name>
+ <version>1-2</version>
+ <interface>
+ <name>ITuner</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.tv.input</name>
- <version>1.0</version>
+ <version>1</version>
<interface>
<name>ITvInput</name>
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.tv.tuner</name>
- <version>1.0-1</version>
- <interface>
- <name>ITuner</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="aidl" optional="true">
- <name>android.hardware.tv.tuner</name>
- <version>1</version>
- <interface>
- <name>ITuner</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.usb</name>
+ <version>1-2</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
@@ -771,17 +668,9 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.weaver</name>
- <version>1.0</version>
- <interface>
- <name>IWeaver</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.weaver</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IWeaver</name>
<instance>default</instance>
@@ -795,14 +684,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true" updatable-via-apex="true">
- <name>android.hardware.wifi</name>
- <version>1.3-6</version>
- <interface>
- <name>IWifi</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.uwb</name>
<version>1</version>
@@ -821,6 +702,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.wifi.supplicant</name>
+ <version>2</version>
<interface>
<name>ISupplicant</name>
<instance>default</instance>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index b17c0e2..3bc1786 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -64,6 +64,7 @@
"android.hardware.keymaster",
"android.hardware.media.bufferpool2",
"android.hardware.radio",
+ "android.hardware.threadnetwork",
"android.hardware.uwb.fira_android",
// Fastboot HAL is only used by recovery. Recovery is owned by OEM. Framework
@@ -102,6 +103,10 @@
"[email protected]",
"[email protected]",
"[email protected]",
+
+ // Under hardware/interfaces/staging, still in development
+ // AIDL
+ "android.hardware.media.c2",
};
auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
index 84e8531..dabdbb6 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -42,5 +42,6 @@
enum Type {
FRAMEWORK = 1,
APP = 2,
+ NATIVE = 3,
}
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
index f0676be..de8d752 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
@@ -45,5 +45,8 @@
void sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo);
void onHostEndpointDisconnected(char hostEndpointId);
- const int EX_CONTEXT_HUB_UNSPECIFIED = -1;
+ long[] getPreloadedNanoappIds(in int contextHubId);
+ void onNanSessionStateChanged(in android.hardware.contexthub.NanSessionStateUpdate update);
+ void setTestMode(in boolean enable);
+ const int EX_CONTEXT_HUB_UNSPECIFIED = (-1) /* -1 */;
}
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 f81f7cf..6163cfc 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
@@ -38,4 +38,6 @@
void handleContextHubMessage(in android.hardware.contexthub.ContextHubMessage msg, in String[] msgContentPerms);
void handleContextHubAsyncEvent(in android.hardware.contexthub.AsyncEventType evt);
void handleTransactionResult(in int transactionId, in boolean success);
+ void handleNanSessionRequest(in android.hardware.contexthub.NanSessionRequest request);
+ const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionRequest.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionRequest.aidl
new file mode 100644
index 0000000..d539707
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionRequest.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.contexthub;
+@VintfStability
+parcelable NanSessionRequest {
+ boolean enable;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionStateUpdate.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionStateUpdate.aidl
new file mode 100644
index 0000000..80771e2
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanSessionStateUpdate.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.contexthub;
+@VintfStability
+parcelable NanSessionStateUpdate {
+ boolean state;
+}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl
index d53b28f..fdf3860 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappBinary.aidl
@@ -40,7 +40,7 @@
byte targetChreApiMajorVersion;
byte targetChreApiMinorVersion;
byte[] customBinary;
- const int FLAG_SIGNED = 1;
- const int FLAG_ENCRYPTED = 2;
- const int FLAG_TCM_CAPABLE = 4;
+ const int FLAG_SIGNED = (1 << 0) /* 1 */;
+ const int FLAG_ENCRYPTED = (1 << 1) /* 2 */;
+ const int FLAG_TCM_CAPABLE = (1 << 2) /* 4 */;
}
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl
index d998478..aeb720b 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Setting.aidl
@@ -35,10 +35,10 @@
@Backing(type="byte") @VintfStability
enum Setting {
LOCATION = 1,
- WIFI_MAIN = 2,
- WIFI_SCANNING = 3,
- AIRPLANE_MODE = 4,
- MICROPHONE = 5,
- BT_MAIN = 6,
- BT_SCANNING = 7,
+ WIFI_MAIN,
+ WIFI_SCANNING,
+ AIRPLANE_MODE,
+ MICROPHONE,
+ BT_MAIN,
+ BT_SCANNING,
}
diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
index a9d6657..c083bb9 100644
--- a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -44,5 +44,8 @@
/** This endpoint is an Android app. */
APP = 2,
+
+ /** This endpoint is from an Android native program. */
+ NATIVE = 3,
}
}
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index 16666ef..9683d2d 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -20,7 +20,9 @@
import android.hardware.contexthub.ContextHubMessage;
import android.hardware.contexthub.HostEndpointInfo;
import android.hardware.contexthub.IContextHubCallback;
+import android.hardware.contexthub.NanSessionStateUpdate;
import android.hardware.contexthub.NanoappBinary;
+import android.hardware.contexthub.NanoappInfo;
import android.hardware.contexthub.Setting;
@VintfStability
@@ -195,6 +197,45 @@
void onHostEndpointDisconnected(char hostEndpointId);
/**
+ * Provides the list of preloaded nanoapp IDs on the system. The output of this API must
+ * not change.
+ *
+ * @param contextHubId The identifier of the Context Hub.
+ *
+ * @return The list of preloaded nanoapp IDs.
+ */
+ long[] getPreloadedNanoappIds(in int contextHubId);
+
+ /**
+ * Invoked when the state of the NAN session requested through handleNanSessionRequest()
+ * changes. This function may be invoked without a corresponding handleNanSessionRequest to
+ * indicate if a NAN session was terminated without a request due to resource limitations.
+ *
+ * If the state becomes disabled without an explicit request from the HAL, the HAL MUST
+ * explicitly invoke handleNanSessionRequest() at a later point in time to attempt to
+ * re-enable NAN.
+ *
+ * @param update Information about the latest NAN session state.
+ */
+ void onNanSessionStateChanged(in NanSessionStateUpdate update);
+
+ /**
+ * Puts the context hub in and out of test mode. Test mode is a clean state
+ * where tests can be executed in the same environment. If enable is true,
+ * this will enable test mode by unloading all nanoapps. If enable is false,
+ * this will disable test mode and reverse the actions of enabling test mode
+ * by loading all preloaded nanoapps. This puts CHRE in a normal state.
+ *
+ * This should only be used for a test environment, either through a
+ * @TestApi or development tools. This should not be used in a production
+ * environment.
+ *
+ * @param enable If true, put the context hub in test mode. If false, disable
+ * test mode.
+ */
+ void setTestMode(in boolean enable);
+
+ /**
* Error codes that are used as service specific errors with the AIDL return
* value EX_SERVICE_SPECIFIC.
*/
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
index e385d48..bfcb51e 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
@@ -18,6 +18,7 @@
import android.hardware.contexthub.AsyncEventType;
import android.hardware.contexthub.ContextHubMessage;
+import android.hardware.contexthub.NanSessionRequest;
import android.hardware.contexthub.NanoappInfo;
@VintfStability
@@ -74,4 +75,24 @@
*
*/
void handleTransactionResult(in int transactionId, in boolean success);
+
+ /**
+ * This callback is passed by the Contexthub service to the HAL implementation to allow the HAL
+ * to request a WiFi NAN session is created to allow the Contexthub to be able to utilize NAN
+ * functionality.
+ *
+ * onNanSessionStateChanged() will be invoked asynchronously after the NAN session request has
+ * been completed. This must be done within CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS. If the
+ * request times out, onNanSessionStateChanged() will be invoked with the state that the session
+ * was previously in.
+ *
+ * @param request Request from the HAL indicating the latest NAN session state it would like.
+ */
+ void handleNanSessionRequest(in NanSessionRequest request);
+
+ /**
+ * Amount of time, in milliseconds, that a handleNanSessionRequest can be pending before the
+ * Contexthub service must respond.
+ */
+ const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
}
diff --git a/contexthub/aidl/android/hardware/contexthub/NanSessionRequest.aidl b/contexthub/aidl/android/hardware/contexthub/NanSessionRequest.aidl
new file mode 100644
index 0000000..c462ba1
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/NanSessionRequest.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.contexthub;
+
+/**
+ * Contains information needed to request a state change for a NAN session.
+ */
+@VintfStability
+parcelable NanSessionRequest {
+ /**
+ * Whether the NAN session should be enabled or disabled depending on whether the Contexthub
+ * needs access to NAN.
+ */
+ boolean enable;
+}
diff --git a/contexthub/aidl/android/hardware/contexthub/NanSessionStateUpdate.aidl b/contexthub/aidl/android/hardware/contexthub/NanSessionStateUpdate.aidl
new file mode 100644
index 0000000..a58eda5
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/NanSessionStateUpdate.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.contexthub;
+
+/**
+ * Contains information provided as a response to a NanSessionRequest.
+ */
+@VintfStability
+parcelable NanSessionStateUpdate {
+ /**
+ * True if the NAN session is currently enabled.
+ */
+ boolean state;
+}
diff --git a/contexthub/aidl/default/Android.bp b/contexthub/aidl/default/Android.bp
index 269057a..6ee7407 100644
--- a/contexthub/aidl/default/Android.bp
+++ b/contexthub/aidl/default/Android.bp
@@ -29,7 +29,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.contexthub-V1-ndk",
+ "android.hardware.contexthub-V2-ndk",
],
export_include_dirs: ["include"],
srcs: [
@@ -50,7 +50,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.contexthub-V1-ndk",
+ "android.hardware.contexthub-V2-ndk",
],
static_libs: [
"libcontexthubexampleimpl",
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 35e4650..5272957 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -76,6 +76,22 @@
}
}
+ScopedAStatus ContextHub::getPreloadedNanoappIds(int32_t /* in_contextHubId */,
+ std::vector<int64_t>* out_preloadedNanoappIds) {
+ if (out_preloadedNanoappIds == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ for (uint64_t i = 0; i < 10; ++i) {
+ out_preloadedNanoappIds->push_back(i);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ScopedAStatus ContextHub::onNanSessionStateChanged(const NanSessionStateUpdate& /*in_update*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
const std::shared_ptr<IContextHubCallback>& in_cb) {
if (in_contextHubId == kMockHubId) {
@@ -98,6 +114,10 @@
}
}
+ScopedAStatus ContextHub::setTestMode(bool /* enable */) {
+ return ndk::ScopedAStatus::ok();
+}
+
ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
mConnectedHostEndpoints.insert(in_info.hostEndpointId);
diff --git a/contexthub/aidl/default/contexthub-default.xml b/contexthub/aidl/default/contexthub-default.xml
index e383c50..930f672 100644
--- a/contexthub/aidl/default/contexthub-default.xml
+++ b/contexthub/aidl/default/contexthub-default.xml
@@ -1,7 +1,10 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.contexthub</name>
- <version>1</version>
- <fqname>IContextHub/default</fqname>
+ <version>2</version>
+ <interface>
+ <name>IContextHub</name>
+ <instance>default</instance>
+ </interface>
</hal>
</manifest>
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index 03d8432..7a2cfd1 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -19,6 +19,7 @@
#include <aidl/android/hardware/contexthub/BnContextHub.h>
#include <unordered_set>
+#include <vector>
namespace aidl {
namespace android {
@@ -37,13 +38,17 @@
int32_t in_transactionId) override;
::ndk::ScopedAStatus onSettingChanged(Setting in_setting, bool in_enabled) override;
::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId) override;
+ ::ndk::ScopedAStatus getPreloadedNanoappIds(
+ int32_t in_contextHubId, std::vector<int64_t>* out_preloadedNanoappIds) override;
::ndk::ScopedAStatus registerCallback(
int32_t in_contextHubId, const std::shared_ptr<IContextHubCallback>& in_cb) override;
::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId,
const ContextHubMessage& in_message) override;
+ ::ndk::ScopedAStatus setTestMode(bool enable) override;
::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override;
::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
+ ::ndk::ScopedAStatus onNanSessionStateChanged(const NanSessionStateUpdate& in_update) override;
private:
static constexpr uint32_t kMockHubId = 0;
diff --git a/contexthub/aidl/vts/Android.bp b/contexthub/aidl/vts/Android.bp
index 673eac0..1534b40 100644
--- a/contexthub/aidl/vts/Android.bp
+++ b/contexthub/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
"libbinder",
],
static_libs: [
- "android.hardware.contexthub-V1-cpp",
+ "android.hardware.contexthub-V2-cpp",
"VtsHalContexthubUtils",
],
test_suites: [
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index 3c01c6b..f544d83 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -42,6 +42,8 @@
using ::android::hardware::contexthub::NanoappBinary;
using ::android::hardware::contexthub::NanoappInfo;
using ::android::hardware::contexthub::NanoappRpcService;
+using ::android::hardware::contexthub::NanSessionRequest;
+using ::android::hardware::contexthub::NanSessionStateUpdate;
using ::android::hardware::contexthub::Setting;
using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
using ::android::hardware::contexthub::vts_utils::waitForCallback;
@@ -84,6 +86,26 @@
}
}
+TEST_P(ContextHubAidl, TestEnableTestMode) {
+ Status status = contextHub->setTestMode(true);
+ if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+ status.transactionError() == android::UNKNOWN_TRANSACTION) {
+ GTEST_SKIP() << "Not supported -> old API; or not implemented";
+ } else {
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(ContextHubAidl, TestDisableTestMode) {
+ Status status = contextHub->setTestMode(false);
+ if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+ status.transactionError() == android::UNKNOWN_TRANSACTION) {
+ GTEST_SKIP() << "Not supported -> old API; or not implemented";
+ } else {
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
class EmptyContextHubCallback : public android::hardware::contexthub::BnContextHubCallback {
public:
Status handleNanoappInfo(const std::vector<NanoappInfo>& /* appInfo */) override {
@@ -100,6 +122,10 @@
Status handleTransactionResult(int32_t /* transactionId */, bool /* success */) override {
return Status::ok();
}
+
+ Status handleNanSessionRequest(const NanSessionRequest& /* request */) override {
+ return Status::ok();
+ }
};
TEST_P(ContextHubAidl, TestRegisterCallback) {
@@ -131,6 +157,10 @@
return Status::ok();
}
+ Status handleNanSessionRequest(const NanSessionRequest& /* request */) override {
+ return Status::ok();
+ }
+
std::promise<std::vector<NanoappInfo>> promise;
};
@@ -156,6 +186,19 @@
}
}
+// Calls getPreloadedNanoappsIds() and verifies there are preloaded nanoapps
+TEST_P(ContextHubAidl, TestGetPreloadedNanoappIds) {
+ std::vector<int64_t> preloadedNanoappIds;
+ Status status = contextHub->getPreloadedNanoappIds(getHubId(), &preloadedNanoappIds);
+ if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+ status.transactionError() == android::UNKNOWN_TRANSACTION) {
+ GTEST_SKIP() << "Not supported -> old API; or not implemented";
+ } else {
+ ASSERT_TRUE(status.isOk());
+ ASSERT_FALSE(preloadedNanoappIds.empty());
+ }
+}
+
// Helper callback that puts the TransactionResult for the expectedTransactionId into a
// promise
class TransactionResultCallback : public android::hardware::contexthub::BnContextHubCallback {
@@ -181,6 +224,10 @@
return Status::ok();
}
+ Status handleNanSessionRequest(const NanSessionRequest& /* request */) override {
+ return Status::ok();
+ }
+
uint32_t expectedTransactionId = 0;
std::promise<bool> promise;
};
@@ -329,6 +376,7 @@
TEST_P(ContextHubAidl, TestHostConnection) {
constexpr char16_t kHostEndpointId = 1;
HostEndpointInfo hostEndpointInfo;
+ hostEndpointInfo.type = HostEndpointInfo::Type::NATIVE;
hostEndpointInfo.hostEndpointId = kHostEndpointId;
ASSERT_TRUE(contextHub->onHostEndpointConnected(hostEndpointInfo).isOk());
@@ -341,6 +389,14 @@
ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
}
+TEST_P(ContextHubAidl, TestNanSessionStateChange) {
+ NanSessionStateUpdate update;
+ update.state = true;
+ ASSERT_TRUE(contextHub->onNanSessionStateChanged(update).isOk());
+ update.state = false;
+ ASSERT_TRUE(contextHub->onNanSessionStateChanged(update).isOk());
+}
+
std::string PrintGeneratedTest(const testing::TestParamInfo<ContextHubAidl::ParamType>& info) {
return std::string("CONTEXT_HUB_ID_") + std::to_string(std::get<1>(info.param));
}
diff --git a/current.txt b/current.txt
index 0fb8b49..754093f 100644
--- a/current.txt
+++ b/current.txt
@@ -932,5 +932,11 @@
# ABI preserving changes to HALs during Android U
2aa559cda86c358c6429114ef6bc72c1b43281e98f9eb6b4df5e7073c8d05767 [email protected]::types
42abd285a4293dadb8c89bc63b90cae2872fbffe90c4517aa3ea4965e8aecff7 [email protected]::types
+4f1a02d21a22104c734f71cdbba19b6f7e93d4ee107ff79f0dbdd171a8430e0e [email protected]::types
+a2fbd9747fbb9ceb8c1090b5a24138312246502d5af0654a8c2b603a9bf521fc [email protected]::IGnssCallback
+889b59e3e7a59afa67bf19882a44f51a2f9e43b6556ec52baa9ec3efd1ef7fbe [email protected]::types
+db37a1c757e2e69b1ec9c75a981a6987bd87a131d92ab6acc00e04d19f374281 [email protected]::types
+997017f581406fca1675d2f612f7ccd73f0d04eadd54bf6212e6cf5971d0872d [email protected]::types
+06983ffe6d75e90a22503a6d9fd14417f983a36bb060a80ad5915240d69b8a40 [email protected]::types
# There will be no more HIDL HALs. Use AIDL instead.
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index 6273a38..fb04d84 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -23,7 +23,7 @@
sdk_version: "module_current",
},
ndk: {
- min_sdk_version: "current",
+ min_sdk_version: "UpsideDownCake",
},
},
double_loadable: true,
diff --git a/drm/aidl/OWNERS b/drm/aidl/OWNERS
index fa8fd20..fe69725 100644
--- a/drm/aidl/OWNERS
+++ b/drm/aidl/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 49079
[email protected]
[email protected]
[email protected]
diff --git a/drm/aidl/vts/OWNERS b/drm/aidl/vts/OWNERS
index e44b93e..fe69725 100644
--- a/drm/aidl/vts/OWNERS
+++ b/drm/aidl/vts/OWNERS
@@ -1,4 +1,3 @@
[email protected]
[email protected]
+# Bug component: 49079
[email protected]
[email protected]
diff --git a/gnss/1.0/IGnssCallback.hal b/gnss/1.0/IGnssCallback.hal
index 311ab21..512763e 100644
--- a/gnss/1.0/IGnssCallback.hal
+++ b/gnss/1.0/IGnssCallback.hal
@@ -37,7 +37,13 @@
MSA = 1 << 2,
/** GNSS supports single-shot fixes */
SINGLE_SHOT = 1 << 3,
- /** GNSS supports on demand time injection */
+ /**
+ * The platform periodically injects time to GNSS in addition to
+ * on-demand and occasional time updates.
+ *
+ * Note: The naming of "on demand" should be "periodic" instead. This
+ * is the result of a historic implementation bug, b/73893222.
+ */
ON_DEMAND_TIME = 1 << 4,
/** GNSS supports Geofencing */
GEOFENCING = 1 << 5,
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index a73182e..300e8de 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -27,7 +27,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.gnss-V2-ndk",
+ "android.hardware.gnss-V3-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp
index f8fad94..2414cbc 100644
--- a/gnss/1.1/vts/functional/Android.bp
+++ b/gnss/1.1/vts/functional/Android.bp
@@ -36,7 +36,7 @@
"[email protected]",
"[email protected]",
"android.hardware.gnss@common-vts-lib",
- "android.hardware.gnss-V2-cpp",
+ "android.hardware.gnss-V3-cpp",
],
shared_libs: [
"[email protected]",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 769e8ae..83bc2cc 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -50,7 +50,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.gnss-V2-ndk",
+ "android.hardware.gnss-V3-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 2042dd9..e8db886 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -39,7 +39,7 @@
"[email protected]",
"[email protected]",
"android.hardware.gnss@common-vts-lib",
- "android.hardware.gnss-V2-cpp",
+ "android.hardware.gnss-V3-cpp",
],
test_suites: [
"general-tests",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index 2979f5c..4a4ce54 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -44,7 +44,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.gnss-V2-ndk",
+ "android.hardware.gnss-V3-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
index d7b6eeb..76f9d07 100644
--- a/gnss/2.1/vts/functional/Android.bp
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -40,7 +40,7 @@
"[email protected]",
"[email protected]",
"android.hardware.gnss@common-vts-lib",
- "android.hardware.gnss-V2-cpp",
+ "android.hardware.gnss-V3-cpp",
],
shared_libs: [
"libvintf",
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
index 31426f0..54e3b21 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
@@ -39,6 +39,7 @@
android.hardware.gnss.GnssClock clock;
android.hardware.gnss.ElapsedRealtime elapsedRealtime;
android.hardware.gnss.GnssData.GnssAgc[] gnssAgcs = {};
+ boolean isFullTracking;
@VintfStability
parcelable GnssAgc {
double agcLevelDb;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl
index 8930752..c782b6f 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssRil.aidl
@@ -39,6 +39,7 @@
void setRefLocation(in android.hardware.gnss.IAGnssRil.AGnssRefLocation agnssReflocation);
void setSetId(in android.hardware.gnss.IAGnssRil.SetIdType type, in @utf8InCpp String setid);
void updateNetworkState(in android.hardware.gnss.IAGnssRil.NetworkAttributes attributes);
+ void injectNiSuplMessageData(in byte[] msgData, in int slotIndex);
const int NETWORK_CAPABILITY_NOT_METERED = 1;
const int NETWORK_CAPABILITY_NOT_ROAMING = 2;
@Backing(type="int") @VintfStability
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index 48c88f5..0247182 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -45,6 +45,7 @@
void gnssSetSystemInfoCb(in android.hardware.gnss.IGnssCallback.GnssSystemInfo info);
void gnssRequestTimeCb();
void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+ void gnssSetSignalTypeCapabilitiesCb(in android.hardware.gnss.GnssSignalType[] gnssSignalTypes);
const int CAPABILITY_SCHEDULING = 1;
const int CAPABILITY_MSB = 2;
const int CAPABILITY_MSA = 4;
@@ -60,6 +61,7 @@
const int CAPABILITY_CORRELATION_VECTOR = 4096;
const int CAPABILITY_SATELLITE_PVT = 8192;
const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
+ const int CAPABILITY_ACCUMULATED_DELTA_RANGE = 32768;
@Backing(type="int") @VintfStability
enum GnssStatusValue {
NONE = 0,
diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl
index 075a039..1bd8d48 100644
--- a/gnss/aidl/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/android/hardware/gnss/GnssData.aidl
@@ -99,4 +99,15 @@
* weak to be acquired, the AGC value must still be reported.
*/
GnssAgc[] gnssAgcs = {};
+
+ /**
+ * True indicates that the GNSS chipset switches off duty cycling. In such mode, no clock
+ * discontinuities are expected and, when supported, carrier phase should be continuous in good
+ * signal conditions. All non-blocklisted, healthy constellations, satellites and frequency
+ * bands that are meaningful to positioning accuracy must be tracked and reported in this mode.
+ *
+ * False indicates that the GNSS chipset optimizes power via duty cycling, constellations and
+ * frequency limits, etc.
+ */
+ boolean isFullTracking;
}
diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
index db724a4..925df1a 100644
--- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
+++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl
@@ -133,50 +133,50 @@
* zero to the value in the table. The state flag with the widest range indicates the range of
* the received GNSS satellite time value.
*
- * +---------------------------+--------------------+-----+-----------+--------------------+------+
- * | |GPS/QZSS |GLNS |BDS |GAL |SBAS |
- * +---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |State Flag |L1 |L5I |L5Q |L1OF |B1I |B1I |E1B |E1C |E5AQ |L1 |
- * | |C/A | | | |(D1) |(D2)| | | |C/A |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_UNKNOWN |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_CODE_LOCK |1ms |1 ms |1 ms |1 ms |1 ms |1 ms|- |- |1 ms |1 ms |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_SYMBOL_SYNC |20ms |10 ms |1 ms |10 ms|20 ms |2 ms|4 ms |4 ms |1 ms |2 ms |
- * | |(opt.)| |(opt.)| |(opt.)| |(opt.)|(opt.)|(opt.)| |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_BIT_SYNC |20 ms |20 ms |1 ms |20 ms|20 ms |- |8 ms |- |1 ms |4 ms |
- * | | | |(opt.)| | | | | |(opt.)| |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_SUBFRAME_SYNC |6s |6s |- |2 s |6 s |- |- |- |100 ms|- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_TOW_DECODED |1 week|- |- |1 day|1 week|- |1 week|- |- |1 week|
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_TOW_KNOWN |1 week|- |- |1 day|1 week|- |1 week|- |- |1 week|
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_GLO_STRING_SYNC |- |- |- |2 s |- |- |- |- |- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_GLO_TOD_DECODED |- |- |- |1 day|- |- |- |- |- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_GLO_TOD_KNOWN |- |- |- |1 day|- |- |- |- |- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_BDS_D2_BIT_SYNC |- |- |- |- |- |2 ms|- |- |- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_BDS_D2_SUBFRAME_SYNC |- |- |- |- |- |600 |- |- |- |- |
- * | | | | | | |ms | | | | |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_GAL_E1BC_CODE_LOCK |- |- |- |- |- |- |4 ms |4 ms |- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_GAL_E1C_2ND_CODE_LOCK|- |- |- |- |- |- |- |100 ms|- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_2ND_CODE_LOCK |- |10 ms |20 ms |- |- |- |- |100 ms|100 ms|- |
- * | | |(opt.)| | | | | |(opt.)| | |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_GAL_E1B_PAGE_SYNC |- |- |- |- |- |- |2 s |- |- |- |
- * |---------------------------+------+------+------+-----+------+----+------+------+------+------+
- * |STATE_SBAS_SYNC |- |- |- |- |- |- |- |- |- |1s |
- * +---------------------------+------+------+------+-----+------+----+------+------+------+------+
+ * +---------------------------+---------------------------+-----+---------------------------+--------------------+------+------+
+ * | |GPS/QZSS |GLNS |BDS |GAL |SBAS |IRNSS |
+ * +---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |State Flag |L1 |L1C |L5I |L5Q |L1OF |B1I |B1I |B1C |B2AQ |E1B |E1C |E5AQ |L1 |L5C |
+ * | |C/A |(P) | | | |(D1) |(D2) |(P) | | | | |C/A | |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_UNKNOWN |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_CODE_LOCK |1ms |10 ms |1 ms |1 ms |1 ms |1 ms |1 ms |10 ms |1 ms |- |- |1 ms |1 ms |1ms |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_SYMBOL_SYNC |- |- |10 ms |- |10 ms|- |2 ms |- |- |- |- |- |2 ms |- |
+ * | | | | | | | | | | | | | | | |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_BIT_SYNC |20 ms |- |20 ms |- |20 ms|20 ms |- |- |- |8 ms |- |- |4 ms |20 ms |
+ * | | | | | | | | | | | | | | | |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_SUBFRAME_SYNC |6s |- |6s |- |- |6 s |- |- |100 ms|- |- |100 ms|- |6s |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_TOW_DECODED |1 week|- |1 week|- |- |1 week|1 week|- |- |1 week|1 week|- |1 week|1 week|
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_TOW_KNOWN |1 week|1 week|1 week|1 week|- |1 week|1 week|1 week|1 week|1 week|1 week|1 week|1 week|1 week|
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_GLO_STRING_SYNC |- |- |- |- |2 s |- |- |- |- |- |- |- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_GLO_TOD_DECODED |- |- |- |- |1 day|- |- |- |- |- |- |- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_GLO_TOD_KNOWN |- |- |- |- |1 day|- |- |- |- |- |- |- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_BDS_D2_BIT_SYNC |- |- |- |- |- |- |2 ms |- |- |- |- |- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_BDS_D2_SUBFRAME_SYNC |- |- |- |- |- |- |600 |- |- |- |- |- |- |- |
+ * | | | | | | | |ms | | | | | | | |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_GAL_E1BC_CODE_LOCK |- |- |- |- |- |- |- |- |- |4 ms |4 ms |- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_GAL_E1C_2ND_CODE_LOCK|- |- |- |- |- |- |- |- |- |- |100 ms|- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_2ND_CODE_LOCK |- |18000 |10 ms |20 ms |- |- |- |18000 |100 ms|- |- |100 ms|- |- |
+ * | | |ms | | | | | |ms | | | | | | |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_GAL_E1B_PAGE_SYNC |- |- |- |- |- |- |- |- |- |2 s |- |- |- |- |
+ * |---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
+ * |STATE_SBAS_SYNC |- |- |- |- |- |- |- |- |- |- |- |- |1s |- |
+ * +---------------------------+------+------+------+------+-----+------+------+------+------+------+------+------+------+------+
*
* Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
* been determined from other sources. If TOW decoded is set then TOW Known must also be set.
diff --git a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl
index 44847f0..5f2e261 100644
--- a/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl
+++ b/gnss/aidl/android/hardware/gnss/IAGnssRil.aidl
@@ -164,4 +164,14 @@
*
*/
void updateNetworkState(in NetworkAttributes attributes);
+
+ /**
+ * Injects an SMS/WAP initiated SUPL message.
+ *
+ * @param msgData ASN.1 encoded SUPL INIT message. This is defined in
+ * UserPlane Location Protocol (Version 2.0.4).
+ * @param slotIndex Specifies the slot index (See
+ * android.telephony.SubscriptionManager#getSlotIndex()) of the SUPL connection.
+ */
+ void injectNiSuplMessageData(in byte[] msgData, in int slotIndex);
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index 8633bea..0200625 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -18,6 +18,7 @@
import android.hardware.gnss.GnssConstellationType;
import android.hardware.gnss.GnssLocation;
+import android.hardware.gnss.GnssSignalType;
import android.hardware.gnss.IGnssConfiguration;
import android.hardware.gnss.IGnssPsds;
@@ -48,7 +49,13 @@
/** Capability bit mask indicating that GNSS supports single-shot fixes */
const int CAPABILITY_SINGLE_SHOT = 1 << 3;
- /** Capability bit mask indicating that GNSS supports on demand time injection */
+ /**
+ * Capability bit indicating that the platform should periodically inject
+ * time to GNSS in addition to on-demand and occasional time updates.
+ *
+ * <p>Note:<em>The naming of "on demand" should be "periodic" instead. This
+ * is the result of a historic implementation bug, b/73893222.</em>
+ */
const int CAPABILITY_ON_DEMAND_TIME = 1 << 4;
/** Capability bit mask indicating that GNSS supports Geofencing */
@@ -81,6 +88,9 @@
/** Capability bit mask indicating that GNSS supports measurement corrections for driving */
const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 1 << 14;
+ /** Capability bit mask indicating that GNSS supports accumulated delta range */
+ const int CAPABILITY_ACCUMULATED_DELTA_RANGE = 1 << 15;
+
/**
* Callback to inform framework of the GNSS HAL implementation's capabilities.
*
@@ -204,9 +214,12 @@
/**
* Callback for the HAL to pass a vector of GnssSvInfo back to the client.
*
- * If GnssMeasurement is registered, the SvStatus report interval is the same as the measurement
- * interval, i.e., the interval the measurement engine runs at. If GnssMeasurement is not
- * registered, the SvStatus interval is the same as the location interval.
+ * If only GnssMeasurement is registered, the SvStatus reporting interval must be
+ * the same as the measurement interval, i.e., the interval the measurement
+ * engine runs at. If only location is registered, the SvStatus interval must
+ * be the same as the location interval. If both GnssMeasurement and location
+ * are registered, then the SvStatus interval is the same as the lesser interval
+ * between the two.
*
* @param svInfo SV status information from HAL.
*/
@@ -308,4 +321,18 @@
* during-call to E911, or up to 5 minutes after end-of-call or text to E911).
*/
void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+
+ /**
+ * Callback to inform the framework of the list of GnssSignalTypes the GNSS HAL implementation
+ * supports.
+ *
+ * These capabilities are static at runtime, i.e., they represent the signal types the
+ * GNSS implementation supports without considering the temporary disabled signal types such as
+ * the blocklisted satellites/constellations or the constellations disabled by regional
+ * restrictions.
+ *
+ * @param gnssSignalTypes a list of GnssSignalTypes specifying the constellations, carrier
+ * frequencies, and the code types the GNSS HAL implementation supports.
+ */
+ void gnssSetSignalTypeCapabilitiesCb(in GnssSignalType[] gnssSignalTypes);
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 8733754..33e9008 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -36,9 +36,9 @@
* If true, GNSS chipset must switch off duty cycling. In such mode no clock discontinuities
* are expected and, when supported, carrier phase should be continuous in good signal
* conditions. All non-blocklisted, healthy constellations, satellites and frequency bands
- * that the chipset supports must be reported in this mode. The GNSS chipset is allowed to
- * consume more power in this mode. If false, API must optimize power via duty cycling,
- * constellations and frequency limits, etc.
+ * that are meaningful to positioning accuracy must be tracked and reported in this mode.
+ * The GNSS chipset is allowed to consume more power in this mode. If false, API must
+ * optimize power via duty cycling, constellations and frequency limits, etc.
*/
boolean enableFullTracking;
@@ -78,6 +78,9 @@
* output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
* can be tolerated.)
*
+ * If setCallback() is invoked without a previous close(), the HAL must use the new callback
+ * and parameters to provide updates.
+ *
* @param callback Handle to GnssMeasurement callback interface.
* @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
* no clock discontinuities are expected and, when supported, carrier phase should be
@@ -104,6 +107,9 @@
/**
* Initializes the interface and registers the callback routines with the HAL.
*
+ * If setCallbackWithOptions() is invoked without a previous close(), the HAL must use the new
+ * callback and options to provide updates.
+ *
* @param options See Options definition.
*/
void setCallbackWithOptions(in IGnssMeasurementCallback callback, in Options options);
diff --git a/gnss/aidl/default/AGnssRil.cpp b/gnss/aidl/default/AGnssRil.cpp
index 2aa1abc..81b4f2a 100644
--- a/gnss/aidl/default/AGnssRil.cpp
+++ b/gnss/aidl/default/AGnssRil.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "AGnssRilAidl"
#include "AGnssRil.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
#include <inttypes.h>
#include <log/log.h>
@@ -55,4 +56,15 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus AGnssRil::injectNiSuplMessageData(const std::vector<uint8_t>& msgData,
+ int slotIndex) {
+ ALOGD("AGnssRil::injectNiSuplMessageData: msgData:%d bytes slotIndex:%d",
+ static_cast<int>(msgData.size()), slotIndex);
+ if (msgData.size() > 0) {
+ return ndk::ScopedAStatus::ok();
+ } else {
+ return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT);
+ }
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/AGnssRil.h b/gnss/aidl/default/AGnssRil.h
index e205b69..76583ac 100644
--- a/gnss/aidl/default/AGnssRil.h
+++ b/gnss/aidl/default/AGnssRil.h
@@ -26,6 +26,8 @@
ndk::ScopedAStatus setRefLocation(const AGnssRefLocation& agnssReflocation) override;
ndk::ScopedAStatus setSetId(SetIdType type, const std::string& setid) override;
ndk::ScopedAStatus updateNetworkState(const NetworkAttributes& attributes) override;
+ ndk::ScopedAStatus injectNiSuplMessageData(const std::vector<uint8_t>& msgData,
+ int slotIndex) override;
private:
// Synchronization lock for sCallback
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index c8ae6b2..ca5a41f 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -50,7 +50,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.gnss-V2-ndk",
+ "android.hardware.gnss-V3-ndk",
],
srcs: [
"AGnssRil.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 2d6490c..f1b9cbf 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -60,7 +60,8 @@
IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
IGnssCallback::CAPABILITY_SATELLITE_PVT |
IGnssCallback::CAPABILITY_CORRELATION_VECTOR |
- IGnssCallback::CAPABILITY_ANTENNA_INFO);
+ IGnssCallback::CAPABILITY_ANTENNA_INFO |
+ IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE);
auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
if (!status.isOk()) {
ALOGE("%s: Unable to invoke callback.gnssSetCapabilitiesCb", __func__);
@@ -68,13 +69,27 @@
IGnssCallback::GnssSystemInfo systemInfo = {
.yearOfHw = 2022,
- .name = "Google, Cuttlefish, AIDL v2",
+ .name = "Google, Cuttlefish, AIDL v3",
};
status = sGnssCallback->gnssSetSystemInfoCb(systemInfo);
if (!status.isOk()) {
ALOGE("%s: Unable to invoke callback.gnssSetSystemInfoCb", __func__);
}
-
+ GnssSignalType signalType1 = {
+ .constellation = GnssConstellationType::GPS,
+ .carrierFrequencyHz = 1.57542e+09,
+ .codeType = GnssSignalType::CODE_TYPE_C,
+ };
+ GnssSignalType signalType2 = {
+ .constellation = GnssConstellationType::GLONASS,
+ .carrierFrequencyHz = 1.5980625e+09,
+ .codeType = GnssSignalType::CODE_TYPE_C,
+ };
+ status = sGnssCallback->gnssSetSignalTypeCapabilitiesCb(
+ std::vector<GnssSignalType>({signalType1, signalType2}));
+ if (!status.isOk()) {
+ ALOGE("%s: Unable to invoke callback.gnssSetSignalTypeCapabilitiesCb", __func__);
+ }
return ScopedAStatus::ok();
}
@@ -310,6 +325,7 @@
ALOGD("getExtensionGnssMeasurement");
if (mGnssMeasurementInterface == nullptr) {
mGnssMeasurementInterface = SharedRefBase::make<GnssMeasurementInterface>();
+ mGnssMeasurementInterface->setGnssInterface(static_cast<std::shared_ptr<Gnss>>(this));
}
*iGnssMeasurement = mGnssMeasurementInterface;
return ScopedAStatus::ok();
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index df10fc8..00540cd 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -84,13 +84,13 @@
IMeasurementCorrectionsInterface>* iMeasurementCorrections)
override;
+ void reportSvStatus() const;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
std::shared_ptr<GnssMeasurementInterface> mGnssMeasurementInterface;
private:
void reportLocation(const GnssLocation&) const;
- void reportSvStatus() const;
void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList) const;
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index 606de07..aab9e03 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -20,6 +20,7 @@
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
#include "DeviceFileReader.h"
+#include "Gnss.h"
#include "GnssRawMeasurementParser.h"
#include "GnssReplayUtils.h"
#include "Utils.h"
@@ -54,7 +55,7 @@
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
stop();
}
- start(enableCorrVecOutputs);
+ start(enableCorrVecOutputs, enableFullTracking);
return ndk::ScopedAStatus::ok();
}
@@ -73,7 +74,7 @@
stop();
}
mIntervalMs = std::max(options.intervalMs, 1000);
- start(options.enableCorrVecOutputs);
+ start(options.enableCorrVecOutputs, options.enableFullTracking);
return ndk::ScopedAStatus::ok();
}
@@ -91,7 +92,8 @@
return ndk::ScopedAStatus::ok();
}
-void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
+void GnssMeasurementInterface::start(const bool enableCorrVecOutputs,
+ const bool enableFullTracking) {
ALOGD("start");
if (mIsActive) {
@@ -103,7 +105,7 @@
mIsActive = true;
mThreadBlocker.reset();
- mThread = std::thread([this, enableCorrVecOutputs]() {
+ mThread = std::thread([this, enableCorrVecOutputs, enableFullTracking]() {
int intervalMs;
do {
if (!mIsActive) {
@@ -122,8 +124,12 @@
this->reportMeasurement(*measurement);
}
} else {
- auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
+ auto measurement =
+ Utils::getMockMeasurement(enableCorrVecOutputs, enableFullTracking);
this->reportMeasurement(measurement);
+ if (!mLocationEnabled) {
+ mGnss->reportSvStatus();
+ }
}
intervalMs =
(mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
@@ -162,6 +168,10 @@
mLocationEnabled = enabled;
}
+void GnssMeasurementInterface::setGnssInterface(const std::shared_ptr<Gnss>& gnss) {
+ mGnss = gnss;
+}
+
void GnssMeasurementInterface::waitForStoppingThreads() {
for (auto& future : mFutures) {
ALOGD("Stopping previous thread.");
diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h
index bb08027..926a4e7 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.h
+++ b/gnss/aidl/default/GnssMeasurementInterface.h
@@ -25,6 +25,7 @@
#include "Utils.h"
namespace aidl::android::hardware::gnss {
+class Gnss;
struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
public:
@@ -39,9 +40,10 @@
const Options& options) override;
void setLocationInterval(const int intervalMs);
void setLocationEnabled(const bool enabled);
+ void setGnssInterface(const std::shared_ptr<Gnss>& gnss);
private:
- void start(const bool enableCorrVecOutputs);
+ void start(const bool enableCorrVecOutputs, const bool enableFullTracking);
void stop();
void reportMeasurement(const GnssData&);
void waitForStoppingThreads();
@@ -59,6 +61,8 @@
// Synchronization lock for sCallback
mutable std::mutex mMutex;
+
+ std::shared_ptr<Gnss> mGnss;
};
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
index 7449310..73b841e 100644
--- a/gnss/aidl/default/gnss-default.xml
+++ b/gnss/aidl/default/gnss-default.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.gnss</name>
- <version>2</version>
+ <version>3</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index f02a41e..2a09a56 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -51,7 +51,7 @@
"libbinder",
],
static_libs: [
- "android.hardware.gnss-V2-cpp",
+ "android.hardware.gnss-V3-cpp",
"android.hardware.gnss@common-vts-lib",
],
test_suites: [
diff --git a/gnss/aidl/vts/AndroidTest.xml b/gnss/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..d203402
--- /dev/null
+++ b/gnss/aidl/vts/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalGnssTargetTest.">
+ <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="VtsHalGnssTargetTest->/data/local/tmp/VtsHalGnssTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalGnssTargetTest" />
+ <option name="native-test-timeout" value="2m" />
+ </test>
+</configuration>
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
index 2f6128b..2e34921 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -18,11 +18,13 @@
#include "GnssCallbackAidl.h"
#include <log/log.h>
+#include <utils/SystemClock.h>
using android::binder::Status;
using android::hardware::gnss::GnssLocation;
using GnssSvInfo = android::hardware::gnss::IGnssCallback::GnssSvInfo;
using GnssSystemInfo = android::hardware::gnss::IGnssCallback::GnssSystemInfo;
+using GnssSignalType = android::hardware::gnss::GnssSignalType;
Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
ALOGI("Capabilities received %#08x", capabilities);
@@ -30,6 +32,20 @@
return Status::ok();
}
+Status GnssCallbackAidl::gnssSetSignalTypeCapabilitiesCb(
+ const std::vector<GnssSignalType>& signalTypes) {
+ ALOGI("SignalTypeCapabilities received");
+ std::ostringstream ss;
+ for (auto& signalType : signalTypes) {
+ ss << "[constellation=" << (int)signalType.constellation
+ << ", carrierFrequencyHz=" << signalType.carrierFrequencyHz
+ << ", codeType=" << signalType.codeType << "], ";
+ }
+ ALOGI("%s", ss.str().c_str());
+ signal_type_capabilities_cbq_.store(signalTypes);
+ return Status::ok();
+}
+
Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue /* status */) {
ALOGI("gnssStatusCb");
return Status::ok();
@@ -38,6 +54,7 @@
Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
ALOGI("gnssSvStatusCb. Size = %d", (int)svInfoList.size());
sv_info_list_cbq_.store(svInfoList);
+ sv_info_list_timestamps_millis_cbq_.store(::android::elapsedRealtime());
return Status::ok();
}
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
index a9495ba..82a0df4 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.h
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -25,13 +25,17 @@
public:
GnssCallbackAidl()
: capabilities_cbq_("capabilities"),
+ signal_type_capabilities_cbq_("signal_type_capabilities"),
info_cbq_("system_info"),
location_cbq_("location"),
sv_info_list_cbq_("sv_info"),
+ sv_info_list_timestamps_millis_cbq_("sv_info_timestamps"),
nmea_cbq_("nmea"){};
~GnssCallbackAidl(){};
android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+ android::binder::Status gnssSetSignalTypeCapabilitiesCb(
+ const std::vector<android::hardware::gnss::GnssSignalType>& signalTypes) override;
android::binder::Status gnssStatusCb(const GnssStatusValue status) override;
android::binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
android::binder::Status gnssLocationCb(
@@ -45,11 +49,15 @@
const bool isUserEmergency) override;
int last_capabilities_;
+ std::vector<android::hardware::gnss::GnssSignalType> last_signal_type_capabilities;
android::hardware::gnss::IGnssCallback::GnssSystemInfo last_info_;
android::hardware::gnss::GnssLocation last_location_;
android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
android::hardware::gnss::common::GnssCallbackEventQueue<
+ std::vector<android::hardware::gnss::GnssSignalType>>
+ signal_type_capabilities_cbq_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<
android::hardware::gnss::IGnssCallback::GnssSystemInfo>
info_cbq_;
android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssLocation>
@@ -57,6 +65,8 @@
android::hardware::gnss::common::GnssCallbackEventQueue<
std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
sv_info_list_cbq_;
+ android::hardware::gnss::common::GnssCallbackEventQueue<long>
+ sv_info_list_timestamps_millis_cbq_;
android::hardware::gnss::common::GnssCallbackEventQueue<std::pair<int64_t, std::string>>
nmea_cbq_;
};
\ No newline at end of file
diff --git a/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
index a553954..0d15b2a 100644
--- a/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp
@@ -24,9 +24,11 @@
android::binder::Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& gnssData) {
ALOGI("gnssMeasurementCb");
- ALOGV("elapsedRealtime: flags = 0x%X, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
+ ALOGV("elapsedRealtime: flags = 0x%X, timestampNs: %" PRId64
+ ", timeUncertaintyNs=%lf"
+ " isFullTracking=%s",
gnssData.elapsedRealtime.flags, gnssData.elapsedRealtime.timestampNs,
- gnssData.elapsedRealtime.timeUncertaintyNs);
+ gnssData.elapsedRealtime.timeUncertaintyNs, gnssData.isFullTracking ? "true" : "false");
gnss_data_cbq_.store(gnssData);
return android::binder::Status::ok();
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 64e51c7..4f5e6a0 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -105,6 +105,15 @@
EXPECT_TRUE(aidl_gnss_cb_->info_cbq_.retrieve(aidl_gnss_cb_->last_info_, TIMEOUT_SEC));
EXPECT_EQ(aidl_gnss_cb_->info_cbq_.calledCount(), 1);
}
+
+ /*
+ * SignalTypeCapabilities callback should trigger.
+ */
+ if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+ EXPECT_TRUE(aidl_gnss_cb_->signal_type_capabilities_cbq_.retrieve(
+ aidl_gnss_cb_->last_signal_type_capabilities, TIMEOUT_SEC));
+ EXPECT_EQ(aidl_gnss_cb_->signal_type_capabilities_cbq_.calledCount(), 1);
+ }
}
void GnssHalTest::TearDown() {
@@ -469,6 +478,52 @@
}
}
+void GnssHalTest::collectSvInfoListTimestamps(const int numMeasurementEvents,
+ const int timeoutSeconds,
+ std::vector<int>& deltasMs) {
+ aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.reset();
+ aidl_gnss_cb_->sv_info_list_cbq_.reset();
+
+ auto status = aidl_gnss_hal_->startSvStatus();
+ EXPECT_TRUE(status.isOk());
+ ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.size() ==
+ aidl_gnss_cb_->sv_info_list_cbq_.size());
+ long lastElapsedRealtimeMillis = 0;
+ for (int i = 0; i < numMeasurementEvents; i++) {
+ long timeStamp;
+ ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.retrieve(timeStamp,
+ timeoutSeconds));
+ if (lastElapsedRealtimeMillis != 0) {
+ deltasMs.push_back(timeStamp - lastElapsedRealtimeMillis);
+ }
+ lastElapsedRealtimeMillis = timeStamp;
+ }
+ status = aidl_gnss_hal_->stopSvStatus();
+ EXPECT_TRUE(status.isOk());
+}
+
+void GnssHalTest::checkGnssDataFields(const sp<GnssMeasurementCallbackAidl>& callback,
+ const int numMeasurementEvents, const int timeoutSeconds,
+ const bool isFullTracking) {
+ for (int i = 0; i < numMeasurementEvents; i++) {
+ GnssData lastGnssData;
+ ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, timeoutSeconds));
+ EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ ASSERT_TRUE(lastGnssData.measurements.size() > 0);
+
+ // Validity check GnssData fields
+ checkGnssMeasurementClockFields(lastGnssData);
+ if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+ if (isFullTracking) {
+ EXPECT_EQ(lastGnssData.isFullTracking, isFullTracking);
+ }
+ }
+ for (const auto& measurement : lastGnssData.measurements) {
+ checkGnssMeasurementFields(measurement, lastGnssData);
+ }
+ }
+}
+
void GnssHalTest::assertMeanAndStdev(int intervalMs, std::vector<int>& deltasMs) {
double mean = computeMean(deltasMs);
double stdev = computeStdev(mean, deltasMs);
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index c49c1b9..88d01c1 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -101,6 +101,11 @@
void collectMeasurementIntervals(const sp<GnssMeasurementCallbackAidl>& callback,
const int numMeasurementEvents, const int timeoutSeconds,
std::vector<int>& deltaMs);
+ void collectSvInfoListTimestamps(const int numMeasurementEvents, const int timeoutSeconds,
+ std::vector<int>& deltasMs);
+ void checkGnssDataFields(const sp<GnssMeasurementCallbackAidl>& callback,
+ const int numMeasurementEvents, const int timeoutSeconds,
+ const bool isFullTracking);
void assertMeanAndStdev(int intervalMillis, std::vector<int>& deltasMillis);
sp<IGnssAidl> aidl_gnss_hal_;
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index c7fc32a..aa8bdfd 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -173,6 +173,7 @@
* GnssCapabilities:
* 1. Verifies that GNSS hardware supports measurement capabilities.
* 2. Verifies that GNSS hardware supports Scheduling capabilities.
+ * 3. Verifies that GNSS hardware supports non-empty signal type capabilities.
*/
TEST_P(GnssHalTest, GnssCapabilites) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -182,6 +183,10 @@
EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_MEASUREMENTS);
}
EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_SCHEDULING);
+ if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+ return;
+ }
+ EXPECT_FALSE(aidl_gnss_cb_->last_signal_type_capabilities.empty());
}
/*
@@ -1082,6 +1087,7 @@
* 2. Sets AGnssRilCallback.
* 3. Update network state to connected and then disconnected.
* 4. Sets reference location.
+ * 5. Injects empty NI message data and verifies that it returns an error.
*/
TEST_P(GnssHalTest, TestAGnssRilExtension) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1125,6 +1131,11 @@
status = iAGnssRil->setRefLocation(agnssReflocation);
ASSERT_TRUE(status.isOk());
+
+ if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+ status = iAGnssRil->injectNiSuplMessageData(std::vector<uint8_t>(), 0);
+ ASSERT_FALSE(status.isOk());
+ }
}
/*
@@ -1396,8 +1407,9 @@
/*
* TestGnssMeasurementIntervals_WithoutLocation:
- * 1. start measurement with interval
- * 2. verify that the received measurement intervals have expected mean and stdev
+ * 1. Start measurement at intervals
+ * 2. Verify measurement are received at expected intervals
+ * 3. Verify status are reported at expected intervals
*/
TEST_P(GnssHalTest, TestGnssMeasurementIntervals_WithoutLocation) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1417,20 +1429,32 @@
auto callback = sp<GnssMeasurementCallbackAidl>::make();
startMeasurementWithInterval(intervals[i], iGnssMeasurement, callback);
- std::vector<int> deltas;
- collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10, deltas);
+ std::vector<int> measurementDeltas;
+ std::vector<int> svInfoListTimestampsDeltas;
+ collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10,
+ measurementDeltas);
+ if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+ collectSvInfoListTimestamps(numEvents[i], /* timeoutSeconds= */ 10,
+ svInfoListTimestampsDeltas);
+ }
status = iGnssMeasurement->close();
ASSERT_TRUE(status.isOk());
- assertMeanAndStdev(intervals[i], deltas);
+ assertMeanAndStdev(intervals[i], measurementDeltas);
+
+ if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+ assertMeanAndStdev(intervals[i], svInfoListTimestampsDeltas);
+ EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
+ }
}
}
/*
* TestGnssMeasurementIntervals_LocationOnBeforeMeasurement:
- * 1. start measurement with interval
- * 2. verify that the received measurement intervals have expected mean and stdev
+ * 1. Start location at 1s.
+ * 2. Start measurement at 2s. Verify measurements are received at 1s.
+ * 3. Stop measurement. Stop location.
*/
TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnBeforeMeasurement) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1465,15 +1489,17 @@
}
/*
- * TestGnssMeasurementIntervals:
- * 1. start measurement with interval
- * 2. verify that the received measurement intervals have expected mean and stdev
+ * TestGnssMeasurementIntervals_LocationOnAfterMeasurement:
+ * 1. Start measurement at 2s
+ * 2. Start location at 1s. Verify measurements are received at 1s
+ * 3. Stop location. Verify measurements are received at 2s
+ * 4. Stop measurement
*/
TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnAfterMeasurement) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
return;
}
-
+ const int kFirstMeasTimeoutSec = 10;
std::vector<int> intervals({2000});
sp<IGnssMeasurementInterface> iGnssMeasurement;
@@ -1482,20 +1508,171 @@
ASSERT_TRUE(iGnssMeasurement != nullptr);
int locationIntervalMs = 1000;
- // Start location first and then start measurement
+ // Start measurement first and then start location
ALOGD("TestGnssMeasurementIntervals_LocationOnAfterMeasurement");
for (auto& intervalMs : intervals) {
auto callback = sp<GnssMeasurementCallbackAidl>::make();
startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
+ // Start location and verify the measurements are received at 1Hz
StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
std::vector<int> deltas;
- collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10, deltas);
+ collectMeasurementIntervals(callback, /*numEvents=*/10, kFirstMeasTimeoutSec, deltas);
+ assertMeanAndStdev(locationIntervalMs, deltas);
+ // Stop location request and verify the measurements are received at 2s intervals
StopAndClearLocations();
+ callback->gnss_data_cbq_.reset();
+ deltas.clear();
+ collectMeasurementIntervals(callback, /*numEvents=*/5, kFirstMeasTimeoutSec, deltas);
+ assertMeanAndStdev(intervalMs, deltas);
+
status = iGnssMeasurement->close();
ASSERT_TRUE(status.isOk());
-
- assertMeanAndStdev(locationIntervalMs, deltas);
}
}
+
+/*
+ * TestGnssMeasurementIntervals_changeIntervals:
+ * This test ensures setCallback() can be called consecutively without close().
+ * 1. Start measurement with 20s interval and wait for 1 measurement.
+ * 2. Start measurement with 1s interval and wait for 5 measurements.
+ * Verify the measurements were received at 1Hz.
+ * 3. Start measurement with 2s interval and wait for 5 measurements.
+ * Verify the measurements were received at 2s intervals.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementIntervals_changeIntervals) {
+ if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+ return;
+ }
+ const int kFirstGnssMeasurementTimeoutSeconds = 10;
+ sp<IGnssMeasurementInterface> iGnssMeasurement;
+ auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+ auto callback = sp<GnssMeasurementCallbackAidl>::make();
+ std::vector<int> deltas;
+
+ // setCallback at 20s interval and wait for 1 measurement
+ startMeasurementWithInterval(20000, iGnssMeasurement, callback);
+ collectMeasurementIntervals(callback, /* numEvents= */ 1, kFirstGnssMeasurementTimeoutSeconds,
+ deltas);
+
+ // setCallback at 1s interval and wait for 5 measurements
+ callback->gnss_data_cbq_.reset();
+ deltas.clear();
+ startMeasurementWithInterval(1000, iGnssMeasurement, callback);
+ collectMeasurementIntervals(callback, /* numEvents= */ 5, kFirstGnssMeasurementTimeoutSeconds,
+ deltas);
+
+ // verify the measurements were received at 1Hz
+ assertMeanAndStdev(1000, deltas);
+
+ // setCallback at 2s interval and wait for 5 measurements
+ callback->gnss_data_cbq_.reset();
+ deltas.clear();
+ startMeasurementWithInterval(2000, iGnssMeasurement, callback);
+ collectMeasurementIntervals(callback, /* numEvents= */ 5, kFirstGnssMeasurementTimeoutSeconds,
+ deltas);
+
+ // verify the measurements were received at 2s intervals
+ assertMeanAndStdev(2000, deltas);
+
+ status = iGnssMeasurement->close();
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * TestGnssMeasurementIsFullTracking
+ * 1. Start measurement with enableFullTracking=true. Verify the received measurements have
+ * isFullTracking=true.
+ * 2. Start measurement with enableFullTracking = false. Verify the received measurements have
+ * isFullTracking=false.
+ * 3. Do step 1 again.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementIsFullTracking) {
+ // GnssData.isFullTracking is added in the interface version 3
+ if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+ return;
+ }
+ const int kFirstGnssMeasurementTimeoutSeconds = 10;
+ const int kNumMeasurementEvents = 5;
+ std::vector<bool> isFullTrackingList({true, false, true});
+
+ sp<IGnssMeasurementInterface> iGnssMeasurement;
+ auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+ ALOGD("TestGnssMeasurementIsFullTracking");
+ auto callback = sp<GnssMeasurementCallbackAidl>::make();
+ IGnssMeasurementInterface::Options options;
+ options.intervalMs = 1000;
+
+ for (auto isFullTracking : isFullTrackingList) {
+ options.enableFullTracking = isFullTracking;
+
+ callback->gnss_data_cbq_.reset();
+ auto status = iGnssMeasurement->setCallbackWithOptions(callback, options);
+ checkGnssDataFields(callback, kNumMeasurementEvents, kFirstGnssMeasurementTimeoutSeconds,
+ isFullTracking);
+ }
+
+ status = iGnssMeasurement->close();
+ ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * TestAccumulatedDeltaRange:
+ * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
+ * 2. Start measurement with 1s interval and wait for up to 15 measurements.
+ * 3. Verify at least one measurement has a valid AccumulatedDeltaRange state.
+ */
+TEST_P(GnssHalTest, TestAccumulatedDeltaRange) {
+ if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+ return;
+ }
+ if ((aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE) ==
+ 0) {
+ return;
+ }
+
+ ALOGD("TestAccumulatedDeltaRange");
+
+ auto callback = sp<GnssMeasurementCallbackAidl>::make();
+ sp<IGnssMeasurementInterface> iGnssMeasurement;
+ auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+ IGnssMeasurementInterface::Options options;
+ options.intervalMs = 1000;
+ options.enableFullTracking = true;
+ status = iGnssMeasurement->setCallbackWithOptions(callback, options);
+ ASSERT_TRUE(status.isOk());
+
+ bool accumulatedDeltaRangeFound = false;
+ const int kNumMeasurementEvents = 15;
+
+ // setCallback at 1s interval and wait for 15 measurements
+ for (int i = 0; i < kNumMeasurementEvents; i++) {
+ GnssData lastGnssData;
+ ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, 10));
+ EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ ASSERT_TRUE(lastGnssData.measurements.size() > 0);
+
+ // Validity check GnssData fields
+ checkGnssMeasurementClockFields(lastGnssData);
+ for (const auto& measurement : lastGnssData.measurements) {
+ if ((measurement.accumulatedDeltaRangeState & measurement.ADR_STATE_VALID) > 0) {
+ accumulatedDeltaRangeFound = true;
+ break;
+ }
+ }
+ if (accumulatedDeltaRangeFound) break;
+ }
+ ASSERT_TRUE(accumulatedDeltaRangeFound);
+ status = iGnssMeasurement->close();
+ ASSERT_TRUE(status.isOk());
+}
\ No newline at end of file
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index b896f04..4cf17a6 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -57,6 +57,6 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.gnss-V2-ndk",
+ "android.hardware.gnss-V3-ndk",
],
}
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 4de49f3..8303d93 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -102,7 +102,7 @@
.receivedSvTimeUncertaintyInNs = 15,
.cN0DbHz = 30.0,
.pseudorangeRateMps = -484.13739013671875,
- .pseudorangeRateUncertaintyMps = 1.0379999876022339,
+ .pseudorangeRateUncertaintyMps = 0.1037999987602233,
.accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
.accumulatedDeltaRangeM = 0.0,
@@ -147,7 +147,7 @@
return gnssData;
}
-GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
+GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs, const bool enableFullTracking) {
aidl::android::hardware::gnss::GnssSignalType signalType = {
.constellation = GnssConstellationType::GLONASS,
.carrierFrequencyHz = 1.59975e+09,
@@ -169,8 +169,8 @@
.basebandCN0DbHz = 26.5,
.agcLevelDb = 2.3,
.pseudorangeRateMps = -484.13739013671875,
- .pseudorangeRateUncertaintyMps = 1.0379999876022339,
- .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN,
+ .pseudorangeRateUncertaintyMps = 0.1037999987602233,
+ .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_VALID,
.accumulatedDeltaRangeM = 1.52,
.accumulatedDeltaRangeUncertaintyM = 2.43,
.multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN,
@@ -258,7 +258,8 @@
GnssData gnssData = {.measurements = {measurement},
.clock = clock,
.elapsedRealtime = timestamp,
- .gnssAgcs = std::vector({gnssAgc1, gnssAgc2})};
+ .gnssAgcs = std::vector({gnssAgc1, gnssAgc2}),
+ .isFullTracking = enableFullTracking};
return gnssData;
}
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index ad8f539..9be4a19 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -32,7 +32,7 @@
struct Utils {
static aidl::android::hardware::gnss::GnssData getMockMeasurement(
- const bool enableCorrVecOutputs);
+ const bool enableCorrVecOutputs, const bool enableFullTracking);
static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
index f92e609..b5325b2 100644
--- a/gnss/common/utils/vts/Android.bp
+++ b/gnss/common/utils/vts/Android.bp
@@ -44,7 +44,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.gnss-V2-cpp",
+ "android.hardware.gnss-V3-cpp",
],
static_libs: [
"libgtest",
diff --git a/graphics/Android.bp b/graphics/Android.bp
index 4ae7ec7..2fbcb41 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -53,13 +53,13 @@
cc_defaults {
name: "android.hardware.graphics.composer3-ndk_static",
static_libs: [
- "android.hardware.graphics.composer3-V1-ndk",
+ "android.hardware.graphics.composer3-V2-ndk",
],
}
cc_defaults {
name: "android.hardware.graphics.composer3-ndk_shared",
shared_libs: [
- "android.hardware.graphics.composer3-V1-ndk",
+ "android.hardware.graphics.composer3-V2-ndk",
],
}
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index 84bc1af..6c8ff4b 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -39,6 +39,9 @@
],
min_sdk_version: "29",
},
+ rust: {
+ enabled: true,
+ }
},
frozen: false,
versions_with_info: [
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
index 668b033..563b6c1 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
@@ -94,5 +94,6 @@
DYNAMIC_DEPTH = 4098,
JPEG_APP_SEGMENTS = 4099,
HEIF = 4100,
+ JPEG_R = 4101,
BT709_FULL_RANGE = 146866176,
}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl
index 128ef49..71927b6 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Hdr.aidl
@@ -35,6 +35,7 @@
/* @hide */
@Backing(type="int") @VintfStability
enum Hdr {
+ INVALID = 0,
DOLBY_VISION = 1,
HDR10 = 2,
HLG = 3,
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionCapability.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionCapability.aidl
new file mode 100644
index 0000000..b74f7d7
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionCapability.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+@VintfStability
+parcelable HdrConversionCapability {
+ android.hardware.graphics.common.Hdr sourceType;
+ android.hardware.graphics.common.Hdr outputType;
+ boolean addsLatency;
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionStrategy.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionStrategy.aidl
new file mode 100644
index 0000000..db785cf
--- /dev/null
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/HdrConversionStrategy.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.common;
+@VintfStability
+union HdrConversionStrategy {
+ boolean passthrough = true;
+ android.hardware.graphics.common.Hdr[] autoAllowedHdrTypes;
+ android.hardware.graphics.common.Hdr forceHdrConversion;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
index 5e9360f..4f2a087 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
@@ -87,7 +87,7 @@
* Use the unadjusted KR = 0.2126, KB = 0.0722 luminance interpretation
* for RGB conversion.
*/
- STANDARD_BT709 = 1 << 16, // 1 << STANDARD_SHIFT
+ STANDARD_BT709 = 1 << 16, // 1 << STANDARD_SHIFT
/**
* Primaries: x y
@@ -377,11 +377,19 @@
RANGE_LIMITED = 2 << 27, // 2 << RANGE_SHIFT = 0x10000000
/**
- * Extended range is used for scRGB. Intended for use with
- * floating point pixel formats. [0.0 - 1.0] is the standard
- * sRGB space. Values outside the range 0.0 - 1.0 can encode
- * color outside the sRGB gamut.
- * Used to blend / merge multiple dataspaces on a single display.
+ * Extended range can be used in combination with FP16 to communicate scRGB or with
+ * SurfaceControl's setExtendedRangeBrightness(SurfaceControl, float, float)
+ * to indicate an HDR range.
+ *
+ * When used with floating point pixel formats and #STANDARD_BT709 then [0.0 - 1.0] is the
+ * standard sRGB space and values outside the range [0.0 - 1.0] can encode
+ * color outside the sRGB gamut. [-0.5, 7.5] is the standard scRGB range.
+ * Used to blend/merge multiple dataspaces on a single display.
+ *
+ * As of Android U in combination with composer3's mixed SDR/HDR feature then this may
+ * be combined with SurfaceControl's setExtendedRangeBrightness(SurfaceControl, float, float)
+ * and other formats such as RGBA_8888 or RGBA_1010102 to communicate a variable HDR
+ * brightness range, which in turn will influence that layer's dimming ratio when composited
*/
RANGE_EXTENDED = 3 << 27, // 3 << RANGE_SHIFT = 0x18000000
@@ -397,7 +405,6 @@
*/
SRGB_LINEAR = 1 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
-
/**
* scRGB linear encoding:
*
@@ -412,7 +419,6 @@
*/
SCRGB_LINEAR = 1 << 16 | 1 << 22 | 3 << 27, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED
-
/**
* sRGB gamma encoding:
*
@@ -428,7 +434,6 @@
*/
SRGB = 1 << 16 | 2 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL
-
/**
* scRGB:
*
@@ -470,8 +475,8 @@
*
* Use limited range, SMPTE 170M transfer and BT.601_625 standard.
*/
- BT601_625 = 2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
-
+ BT601_625 =
+ 2 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
* ITU-R Recommendation 601 (BT.601) - 525-line
@@ -480,7 +485,8 @@
*
* Use limited range, SMPTE 170M transfer and BT.601_525 standard.
*/
- BT601_525 = 4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+ BT601_525 =
+ 4 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
* ITU-R Recommendation 709 (BT.709)
@@ -491,7 +497,6 @@
*/
BT709 = 1 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
-
/**
* SMPTE EG 432-1 and SMPTE RP 431-2.
*
@@ -501,7 +506,6 @@
*/
DCI_P3_LINEAR = 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
-
/**
* SMPTE EG 432-1 and SMPTE RP 431-2.
*
@@ -513,15 +517,14 @@
*/
DCI_P3 = 10 << 16 | 5 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL
-
/**
* Display P3
*
* Display P3 uses same primaries and white-point as DCI-P3
* linear transfer function makes this the same as DCI_P3_LINEAR.
*/
- DISPLAY_P3_LINEAR = 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
-
+ DISPLAY_P3_LINEAR =
+ 10 << 16 | 1 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_LINEAR | RANGE_FULL
/**
* Display P3
@@ -531,7 +534,6 @@
*/
DISPLAY_P3 = 10 << 16 | 2 << 22 | 1 << 27, // STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_FULL
-
/**
* Adobe RGB
*
@@ -541,7 +543,6 @@
*/
ADOBE_RGB = 11 << 16 | 4 << 22 | 1 << 27, // STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL
-
/**
* ITU-R Recommendation 2020 (BT.2020)
*
@@ -551,7 +552,6 @@
*/
BT2020_LINEAR = 6 << 16 | 1 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_LINEAR | RANGE_FULL
-
/**
* ITU-R Recommendation 2020 (BT.2020)
*
@@ -570,7 +570,6 @@
*/
BT2020_PQ = 6 << 16 | 7 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL
-
/**
* Data spaces for non-color formats
*/
@@ -611,7 +610,8 @@
*
* Use limited range, SMPTE 170M transfer and BT2020 standard
*/
- BT2020_ITU = 6 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+ BT2020_ITU =
+ 6 << 16 | 3 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
* ITU-R Recommendation 2100 (BT.2100)
@@ -621,7 +621,8 @@
* Use limited/full range, PQ/HLG transfer, and BT2020 standard
* limited range is the preferred / normative definition for BT.2100
*/
- BT2020_ITU_PQ = 6 << 16 | 7 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED
+ BT2020_ITU_PQ =
+ 6 << 16 | 7 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED
BT2020_ITU_HLG = 6 << 16 | 8 << 22 | 2 << 27, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED
BT2020_HLG = 6 << 16 | 8 << 22 | 1 << 27, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL
@@ -668,11 +669,25 @@
HEIF = 0x1004,
/**
+ * ISO/IEC TBD
+ *
+ * JPEG image with embedded 10-bit recovery map following the Jpeg/R specification.
+ *
+ * This value must always remain aligned with the public ImageFormat Jpeg/R definition and is
+ * valid with formats:
+ * HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Jpeg/R encoder according to ISO/IEC TBD.
+ * The image contains a standard SDR JPEG and a recovery map. Jpeg/R decoders can use the
+ * map to recover the 10-bit input image.
+ */
+ JPEG_R = 0x1005,
+
+ /**
* ITU-R Recommendation 709 (BT.709)
*
* High-definition television
*
* Use full range, SMPTE 170M transfer and BT.709 standard.
*/
- BT709_FULL_RANGE = 1 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_FULL
+ BT709_FULL_RANGE =
+ 1 << 16 | 3 << 22 | 1 << 27, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_FULL
}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl b/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
index 407b54f..c9ba16b 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Hdr.aidl
@@ -24,6 +24,10 @@
@Backing(type="int")
enum Hdr {
/**
+ * Invalid HDR type
+ */
+ INVALID = 0,
+ /**
* Device supports Dolby Vision HDR
*/
DOLBY_VISION = 1,
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HdrConversionCapability.aidl b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionCapability.aidl
new file mode 100644
index 0000000..d8524a5
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionCapability.aidl
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+import android.hardware.graphics.common.Hdr;
+
+/**
+ * Output parameter for IComposerClient.getHdrConversionCapabilities
+ */
+@VintfStability
+parcelable HdrConversionCapability {
+ /** sourceType is the HDR type that can be converted to outputType */
+ Hdr sourceType;
+
+ /**
+ * outputType is the HDR type/ SDR that the source type can be converted to. The value INVALID
+ * is used to depict SDR outputType.
+ */
+
+ Hdr outputType;
+
+ /**
+ * addsLatency is false if no latency added due to HDR conversion from sourceType to
+ * outputType, otherwise true.
+ */
+ boolean addsLatency;
+}
diff --git a/graphics/common/aidl/android/hardware/graphics/common/HdrConversionStrategy.aidl b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionStrategy.aidl
new file mode 100644
index 0000000..71beaa0
--- /dev/null
+++ b/graphics/common/aidl/android/hardware/graphics/common/HdrConversionStrategy.aidl
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.common;
+
+import android.hardware.graphics.common.Hdr;
+/**
+ * Input parameter for IComposerClient.setHdrConversionStrategy
+ */
+@VintfStability
+union HdrConversionStrategy {
+ /**
+ * When this parameter is set to true, HDR conversion is disabled by the
+ * implementation. The output HDR type will change dynamically to match the content. This value
+ * is never set to false, as other union values will be present in the false case.
+ */
+ boolean passthrough = true;
+
+ /**
+ * When this parameter is set, the output HDR type is selected by the
+ * implementation. The implementation is only allowed to set the output HDR type to the HDR
+ * types present in this list. If conversion to any of the autoHdrTypes types is not possible,
+ * the implementation should do no conversion.
+ */
+ Hdr[] autoAllowedHdrTypes;
+
+ /**
+ * When this parameter is set, the implementation should convert all
+ * content to this HDR type, when possible. If not possible, the functionality should be similar
+ * to passthrough=true.
+ */
+ Hdr forceHdrConversion;
+}
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 4822678..9444d89 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -666,11 +666,13 @@
ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
}
- NativeHandleWrapper allocate() {
+ NativeHandleWrapper allocate() { return allocate(mDisplayWidth, mDisplayHeight); }
+
+ NativeHandleWrapper allocate(uint32_t width, uint32_t height) {
uint64_t usage =
static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN |
BufferUsage::COMPOSER_OVERLAY);
- return mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888, usage);
+ return mGralloc->allocate(width, height, 1, PixelFormat::RGBA_8888, usage);
}
void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
@@ -884,6 +886,106 @@
}
/**
+ * Test IComposerClient::Command::SET_LAYER_BUFFER with the behavior used for clearing buffer slots.
+ */
+TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER_multipleTimes) {
+ // A placeholder buffer used to clear buffer slots
+ auto clearSlotBuffer = allocate(1u, 1u);
+
+ //
+ // Set the layer buffer to the first buffer
+ //
+ auto handle1 = allocate();
+ ASSERT_NE(nullptr, handle1.get());
+ IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+ Layer layer;
+ ASSERT_NO_FATAL_FAILURE(
+ layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+ mWriter->setLayerDisplayFrame(displayFrame);
+ mWriter->setLayerBuffer(0, handle1.get(), -1);
+ mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ GTEST_SUCCEED() << "Composition change requested, skipping test";
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ //
+ // Set the layer buffer to the second buffer
+ //
+ auto handle2 = allocate();
+ ASSERT_NE(nullptr, handle2.get());
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+ mWriter->setLayerDisplayFrame(displayFrame);
+ mWriter->setLayerBuffer(1, handle2.get(), -1);
+ mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ GTEST_SUCCEED() << "Composition change requested, skipping test";
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ //
+ // Set the layer buffer to the third buffer
+ //
+ auto handle3 = allocate();
+ ASSERT_NE(nullptr, handle3.get());
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
+ mWriter->setLayerDisplayFrame(displayFrame);
+ mWriter->setLayerBuffer(2, handle3.get(), -1);
+ mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ GTEST_SUCCEED() << "Composition change requested, skipping test";
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ // Ensure we can clear multiple buffer slots and then restore the active buffer at the end
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBuffer(0, clearSlotBuffer.get(), -1);
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBuffer(1, clearSlotBuffer.get(), -1);
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBuffer(2, nullptr, -1);
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+}
+
+/**
* Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE.
*/
TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SURFACE_DAMAGE) {
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index e383ce2..d11592f 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -29,6 +29,7 @@
"android.hardware.graphics.allocator-ndk_static",
"android.hardware.graphics.composer3-ndk_static",
"hidl_defaults",
+ "librenderengine_deps",
],
srcs: [
"ComposerVts.cpp",
@@ -41,7 +42,6 @@
static_libs: [
"[email protected]",
"[email protected]",
- "android.hardware.graphics.composer3-V1-ndk",
"[email protected]",
"libarect",
"libgtest",
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index b706596..d4f0281 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -129,12 +129,12 @@
void ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
Dataspace* outDataspace) {
mClient->getReadbackBufferAttributes(
- display,
- [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
- *outPixelFormat = tmpOutPixelFormat;
- *outDataspace = tmpOutDataspace;
- });
+ display,
+ [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
+ *outPixelFormat = tmpOutPixelFormat;
+ *outDataspace = tmpOutDataspace;
+ });
}
void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index 4a33fb5..1700b2a 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -71,14 +71,12 @@
});
auto texture = std::make_shared<renderengine::impl::ExternalTexture>(
mGraphicBuffer, *mRenderEngine, renderengine::impl::ExternalTexture::Usage::WRITEABLE);
- auto [status, readyFence] = mRenderEngine
- ->drawLayers(mDisplaySettings, compositionLayers, texture,
- true, std::move(bufferFence))
- .get();
- int fd = readyFence.release();
- if (fd != -1) {
- ASSERT_EQ(0, sync_wait(fd, -1));
- ASSERT_EQ(0, close(fd));
+ auto result = mRenderEngine
+ ->drawLayers(mDisplaySettings, compositionLayers, texture, true,
+ std::move(bufferFence))
+ .get();
+ if (result.ok()) {
+ result.value()->waitForever(LOG_TAG);
}
}
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index cdc7a93..3476376 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -29,8 +29,7 @@
"VtsHalTargetTestDefaults",
"android.hardware.graphics.allocator-ndk_static",
"android.hardware.graphics.composer3-ndk_static",
- // Needed for librenderengine
- "skia_deps",
+ "librenderengine_deps",
],
tidy_timeout_srcs: [
"VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
@@ -69,7 +68,6 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.graphics.composer3-V1-ndk",
"[email protected]",
"[email protected]",
"[email protected]",
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 7e25a2e..13ae089 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -66,16 +66,16 @@
mComposerCallback->setVsyncAllowed(false);
mComposerClient->getRaw()->getReadbackBufferAttributes(
- mPrimaryDisplay,
- [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
- mHasReadbackBuffer = tmpError == Error::NONE;
- if (mHasReadbackBuffer) {
- mReadbackPixelFormat = tmpPixelFormat;
- mReadbackDataspace = tmpDataspace;
- ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
- ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
- }
- });
+ mPrimaryDisplay,
+ [&](const auto& tmpError, const auto& tmpPixelFormat, const auto& tmpDataspace) {
+ mHasReadbackBuffer = tmpError == Error::NONE;
+ if (mHasReadbackBuffer) {
+ mReadbackPixelFormat = tmpPixelFormat;
+ mReadbackDataspace = tmpDataspace;
+ ASSERT_LT(static_cast<PixelFormat>(0), mReadbackPixelFormat);
+ ASSERT_NE(Dataspace::UNKNOWN, mReadbackDataspace);
+ }
+ });
mInvalidDisplayId = GetInvalidDisplayId();
}
@@ -711,4 +711,4 @@
}
return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index afc22d8..5e9a287 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -87,6 +87,10 @@
return;
}
+ if (metadata.size() == 0) {
+ return;
+ }
+
// space for numElements
commandLength += 1;
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index fa294ff..35225d9 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -737,6 +737,39 @@
}
}
+/*
+ * Test that no two display configs are exactly the same.
+ */
+TEST_P(GraphicsComposerHidlTest, GetDisplayConfigNoRepetitions) {
+ for (const auto& display : mDisplays) {
+ std::vector<Config> configs = mComposerClient->getDisplayConfigs(display.get());
+ for (int i = 0; i < configs.size(); i++) {
+ for (int j = i + 1; j < configs.size(); j++) {
+ const int32_t width1 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[i], IComposerClient::Attribute::WIDTH);
+ const int32_t height1 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[i], IComposerClient::Attribute::HEIGHT);
+ const int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[i], IComposerClient::Attribute::VSYNC_PERIOD);
+ const int32_t group1 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[i], IComposerClient::Attribute::CONFIG_GROUP);
+
+ const int32_t width2 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[j], IComposerClient::Attribute::WIDTH);
+ const int32_t height2 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[j], IComposerClient::Attribute::HEIGHT);
+ const int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[j], IComposerClient::Attribute::VSYNC_PERIOD);
+ const int32_t group2 = mComposerClient->getDisplayAttribute_2_4(
+ display.get(), configs[j], IComposerClient::Attribute::CONFIG_GROUP);
+
+ ASSERT_FALSE(width1 == width2 && height1 == height2 &&
+ vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
+ }
+ }
+ }
+}
+
} // namespace
} // namespace vts
} // namespace V2_4
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 3e2b79c..1e08221 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,7 +31,8 @@
enabled: true,
support_system_process: true,
},
- frozen: true,
+ frozen: false,
+ vndk_use_version: "1",
srcs: [
"android/hardware/graphics/composer3/*.aidl",
],
@@ -68,9 +69,9 @@
cc_library_headers {
name: "android.hardware.graphics.composer3-command-buffer",
+ defaults: ["android.hardware.graphics.composer3-ndk_shared"],
vendor_available: true,
shared_libs: [
- "android.hardware.graphics.composer3-V1-ndk",
"android.hardware.common-V2-ndk",
"libbase",
"libfmq",
@@ -88,12 +89,12 @@
cc_test {
name: "android.hardware.graphics.composer3-hidl2aidl-asserts",
+ defaults: ["android.hardware.graphics.composer3-ndk_shared"],
vendor_available: true,
srcs: ["android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp"],
shared_libs: [
"libbinder_ndk",
"libhidlbase",
- "android.hardware.graphics.composer3-V1-ndk",
"[email protected]",
"[email protected]",
],
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 b89f7d5..f02f8aa 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
@@ -38,6 +38,11 @@
SIDEBAND_STREAM = 1,
SKIP_CLIENT_COLOR_TRANSFORM = 2,
PRESENT_FENCE_IS_NOT_RELIABLE = 3,
+ /**
+ * @deprecated - enabled by default.
+ */
SKIP_VALIDATE = 4,
BOOT_DISPLAY_CONFIG = 5,
+ HDR_OUTPUT_CONVERSION_CONFIG = 6,
+ REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
index d2d8f04..34d6822 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
@@ -41,4 +41,5 @@
CURSOR = 4,
SIDEBAND = 5,
DISPLAY_DECORATION = 6,
+ REFRESH_RATE_INDICATOR = 7,
}
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 13462ce..00598eb 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;
- const int WRITE_CLIENT_TARGET_TO_OUTPUT = 2;
+ const int FLIP_CLIENT_TARGET = (1 << 0);
+ const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1);
@VintfStability
parcelable LayerRequest {
long layer;
int mask;
- const int CLEAR_CLIENT_TARGET = 1;
+ const int CLEAR_CLIENT_TARGET = (1 << 0);
}
}
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 4b737de..1990350 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,
- FORMAT_COMPONENT_1 = 2,
- FORMAT_COMPONENT_2 = 4,
- FORMAT_COMPONENT_3 = 8,
+ FORMAT_COMPONENT_0 = (1 << 0),
+ FORMAT_COMPONENT_1 = (1 << 1),
+ FORMAT_COMPONENT_2 = (1 << 2),
+ FORMAT_COMPONENT_3 = (1 << 3),
}
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 21620e7..2c08cbe 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
@@ -40,4 +40,5 @@
oneway void onVsync(long display, long timestamp, int vsyncPeriodNanos);
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);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index b49f239..cb85a88 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -75,6 +75,10 @@
void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence);
void setVsyncEnabled(long display, boolean enabled);
void setIdleTimerEnabled(long display, int timeoutMs);
+ android.hardware.graphics.composer3.OverlayProperties getOverlaySupport();
+ android.hardware.graphics.common.HdrConversionCapability[] getHdrConversionCapabilities();
+ android.hardware.graphics.common.Hdr setHdrConversionStrategy(in android.hardware.graphics.common.HdrConversionStrategy conversionStrategy);
+ void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
const int EX_BAD_CONFIG = 1;
const int EX_BAD_DISPLAY = 2;
const int EX_BAD_LAYER = 3;
@@ -85,5 +89,5 @@
const int EX_UNSUPPORTED = 8;
const int EX_SEAMLESS_NOT_ALLOWED = 9;
const int EX_SEAMLESS_NOT_POSSIBLE = 10;
- const int INVALID_CONFIGURATION = 2147483647;
+ const int INVALID_CONFIGURATION = 0x7fffffff;
}
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 0c5fac9..6d32218 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
@@ -54,4 +54,5 @@
@nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
@nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
@nullable android.hardware.graphics.common.Rect[] blockingRegion;
+ @nullable int[] bufferSlotsToClear;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
new file mode 100644
index 0000000..7d31ea3
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.graphics.composer3;
+@VintfStability
+parcelable OverlayProperties {
+ android.hardware.graphics.composer3.OverlayProperties.SupportedBufferCombinations[] combinations;
+ boolean supportMixedColorSpaces;
+ parcelable SupportedBufferCombinations {
+ android.hardware.graphics.common.PixelFormat[] pixelFormats;
+ android.hardware.graphics.common.Dataspace[] standards;
+ android.hardware.graphics.common.Dataspace[] transfers;
+ android.hardware.graphics.common.Dataspace[] ranges;
+ }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
index 8722f87..10a7dee 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -34,17 +34,17 @@
package android.hardware.graphics.composer3;
@Backing(type="int") @VintfStability
enum PerFrameMetadataKey {
- DISPLAY_RED_PRIMARY_X = 0,
- DISPLAY_RED_PRIMARY_Y = 1,
- DISPLAY_GREEN_PRIMARY_X = 2,
- DISPLAY_GREEN_PRIMARY_Y = 3,
- DISPLAY_BLUE_PRIMARY_X = 4,
- DISPLAY_BLUE_PRIMARY_Y = 5,
- WHITE_POINT_X = 6,
- WHITE_POINT_Y = 7,
- MAX_LUMINANCE = 8,
- MIN_LUMINANCE = 9,
- MAX_CONTENT_LIGHT_LEVEL = 10,
- MAX_FRAME_AVERAGE_LIGHT_LEVEL = 11,
- HDR10_PLUS_SEI = 12,
+ DISPLAY_RED_PRIMARY_X,
+ DISPLAY_RED_PRIMARY_Y,
+ DISPLAY_GREEN_PRIMARY_X,
+ DISPLAY_GREEN_PRIMARY_Y,
+ DISPLAY_BLUE_PRIMARY_X,
+ DISPLAY_BLUE_PRIMARY_Y,
+ WHITE_POINT_X,
+ WHITE_POINT_Y,
+ MAX_LUMINANCE,
+ MIN_LUMINANCE,
+ MAX_CONTENT_LIGHT_LEVEL,
+ MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+ HDR10_PLUS_SEI,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
index e6ddeba..dbfac22 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -38,7 +38,7 @@
android.hardware.graphics.composer3.PresentOrValidate.Result result;
@VintfStability
enum Result {
- Validated = 0,
- Presented = 1,
+ Validated,
+ Presented,
}
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
new file mode 100644
index 0000000..2b9801a
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/RefreshRateChangedDebugData.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.graphics.composer3;
+@VintfStability
+parcelable RefreshRateChangedDebugData {
+ long display;
+ int vsyncPeriodNanos;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
index 2f9eab9..4638610 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
@@ -55,6 +55,7 @@
* For this capability to be worthwhile the device implementation of
* presentDisplay should fail as fast as possible in the case a
* validateDisplay step is needed.
+ * @deprecated - enabled by default.
*/
SKIP_VALIDATE = 4,
@@ -66,4 +67,23 @@
* @see IComposerClient.getPreferredBootDisplayConfig
*/
BOOT_DISPLAY_CONFIG = 5,
+
+ /**
+ * Specifies that the device supports HDR output conversion.
+ *
+ * @see IComposerClient.getHdrConversionCapabilities
+ * @see IComposerClient.setHdrConversionStrategy
+ */
+ HDR_OUTPUT_CONVERSION_CONFIG = 6,
+
+ /**
+ * Specifies that the device supports the callback onRefreshRateChangedDebug
+ * to pass information about the refresh rate.
+ * The refresh rate from the callback is used to update the refresh rate
+ * overlay indicator.
+ *
+ * @see IComposerClient.setRefreshRateChangedCallbackDebugEnabled
+ * @see IComposerCallback.onRefreshRateChangedDebug
+ */
+ REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
index ddd45b7..9e8c768 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
@@ -23,7 +23,6 @@
parcelable ChangedCompositionTypes {
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
index ba6fe97..ea54a89 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
@@ -23,7 +23,6 @@
parcelable ClientTargetPropertyWithBrightness {
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
index 82b218b..37912b0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
@@ -86,4 +86,14 @@
* to either DEVICE or CLIENT.
*/
DISPLAY_DECORATION = 6,
+
+ /**
+ * This composition type is similar to DEVICE, with a single difference,
+ * that indicates to HWC that this layer update is not considered an activity
+ * of any sort. For example, If HWC maintains a timer for activity to switch
+ * the display mode from a power save mode, it should not reset that timer.
+ *
+ * Upon validateDisplay, the device may request a change from this type to CLIENT.
+ */
+ REFRESH_RATE_INDICATOR = 7,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index b6df147..4f69aee 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -26,7 +26,6 @@
parcelable DisplayCommand {
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
index 27fe1e6..3a50b6e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -34,7 +34,6 @@
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index 67954d4..f4384b7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.graphics.composer3;
+import android.hardware.graphics.composer3.RefreshRateChangedDebugData;
import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
@VintfStability
@@ -96,4 +97,25 @@
* @param display is the display whose vsync cadence changed due to panel idle mode.
*/
oneway void onVsyncIdle(long display);
+
+ /**
+ * Notifies the client the vsyncPeriod of the display changed.
+ * Whether or not to call this callback is managed by
+ * IComposerClient.setRefreshRateChangedCallbackDebugEnabled
+ *
+ * Immediate callback is required after the setRefreshRateChangedCallbackDebugEnabled
+ * called.
+ * When the panel refresh rate changes, as a result of a setActiveConfig or
+ * setActiveConfigWithConstraints, this callback should be called with the new panel
+ * refresh rate. In addition, when the panel refresh rate is changed by other means,
+ * such as idleness or DOZE power state, this callback should be called as well.
+ *
+ * This callback is used for debug purposes, and not for scheduling frames,
+ * therefore synchronization is not required.
+ *
+ * @see IComposerClient.setRefreshRateChangedCallbackDebugEnabled
+ *
+ * @param data is the data for the callback when refresh rate changed.
+ */
+ oneway void onRefreshRateChangedDebug(in RefreshRateChangedDebugData data);
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index a4ea64f..4e77f86 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -17,6 +17,9 @@
package android.hardware.graphics.composer3;
import android.hardware.graphics.common.DisplayDecorationSupport;
+import android.hardware.graphics.common.Hdr;
+import android.hardware.graphics.common.HdrConversionCapability;
+import android.hardware.graphics.common.HdrConversionStrategy;
import android.hardware.graphics.common.Transform;
import android.hardware.graphics.composer3.ClientTargetProperty;
import android.hardware.graphics.composer3.ColorMode;
@@ -32,6 +35,7 @@
import android.hardware.graphics.composer3.FormatColorComponent;
import android.hardware.graphics.composer3.HdrCapabilities;
import android.hardware.graphics.composer3.IComposerCallback;
+import android.hardware.graphics.composer3.OverlayProperties;
import android.hardware.graphics.composer3.PerFrameMetadataKey;
import android.hardware.graphics.composer3.PowerMode;
import android.hardware.graphics.composer3.ReadbackBufferAttributes;
@@ -814,4 +818,50 @@
*
*/
void setIdleTimerEnabled(long display, int timeoutMs);
+
+ /**
+ * Hardware overlays is a technique to composite different buffers directly to the screen
+ * while bypassing GPU composition.
+ *
+ * This function returns what the device's overlays support.
+ *
+ * @exception EX_UNSUPPORTED when not supported by the underlying HAL
+ *
+ * @return the overlay properties of the device.
+ */
+ OverlayProperties getOverlaySupport();
+
+ /**
+ * Returns the array of HDR conversion capability. Each HdrConversionCapability depicts that
+ * HDR conversion is possible from sourceType to outputType. This doesn't change after
+ * initialization.
+ *
+ * @exception EX_UNSUPPORTED when not supported by the underlying HAL
+ *
+ * @see setHdrConversionStrategy
+ */
+ HdrConversionCapability[] getHdrConversionCapabilities();
+
+ /**
+ * Sets the of HDR conversion strategy.
+ *
+ * @return the chosen HDR type in case HdrConversionStrategy has autoAllowedHdrTypes set. In
+ * other cases, return HDR type INVALID.
+ * @exception EX_UNSUPPORTED when not supported by the underlying HAL
+ *
+ * @see getHdrConversionCapabilities
+ */
+ Hdr setHdrConversionStrategy(in HdrConversionStrategy conversionStrategy);
+
+ /*
+ * Sets either the callback for the refresh rate change is enabled or disabled
+ * for the provided display.
+ *
+ * @see IComposerCallback.onRefreshRateChangedDebug
+ *
+ * @param display is the display on which the callback is enabled on.
+ * @param enabled true when refresh rate callback is enabled,
+ * false when refresh rate callback is disabled.
+ */
+ void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index f3b67a9..fd50be9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -258,4 +258,11 @@
* the screen.
*/
@nullable Rect[] blockingRegion;
+
+ /**
+ * Specifies which buffer slots should be cleared of buffer references
+ * because these buffers will no longer be used and the memory should
+ * be freed.
+ */
+ @nullable int[] bufferSlotsToClear;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
new file mode 100644
index 0000000..c25eea4
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+@VintfStability
+parcelable OverlayProperties {
+ parcelable SupportedBufferCombinations {
+ // List of pixelformats, standards, transfers and ranges dataspaces that can be used
+ // together.
+ // The pixelformats, standards, transfers and ranges stored inside are valid
+ // combinations.
+ // Dataspace identifies three components of colors - standard, transfer and
+ // range.
+ android.hardware.graphics.common.PixelFormat[] pixelFormats;
+ android.hardware.graphics.common.Dataspace[] standards;
+ android.hardware.graphics.common.Dataspace[] transfers;
+ android.hardware.graphics.common.Dataspace[] ranges;
+ }
+ // Array of all valid pixelformat, standard, transfer and range combinations.
+ // If all supported formats work with all standards, transfers and ranges,
+ // then this list may only have 1 entry.
+ // If some dataspaces, e.g. scRGB (STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED),
+ // only work with specific formats, then this list may contain more than 1 entry.
+ // If some ranges, e.g. RANGE_LIMITED, only work with specific
+ // formats/standards/transfers, then this list may contain more than 1 entry.
+ SupportedBufferCombinations[] combinations;
+
+ // True if the DPU is able to color manage at least two overlays
+ // with different input colorspaces, false otherwise.
+ boolean supportMixedColorSpaces;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
index 244b4e5..b757656 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
@@ -20,7 +20,6 @@
parcelable PresentFence {
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
index 5ae8940..e15dbf2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -20,7 +20,6 @@
parcelable PresentOrValidate {
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.aidl
new file mode 100644
index 0000000..c1f78d6
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/RefreshRateChangedDebugData.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.graphics.composer3;
+
+@VintfStability
+parcelable RefreshRateChangedDebugData {
+ /**
+ * The display for which the debug data is for.
+ */
+ long display;
+
+ /**
+ * The display vsync period in nanoseconds.
+ */
+ int vsyncPeriodNanos;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
index 459a042..58649d5 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
@@ -20,7 +20,6 @@
parcelable ReleaseFences {
/**
* The display which this commands refers to.
- * @see IComposer.createDisplay
*/
long display;
@VintfStability
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index 27dce76..76ba24b 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -19,8 +19,8 @@
#include <algorithm>
#include <limits>
#include <memory>
+#include <optional>
#include <unordered_map>
-#include <unordered_set>
#include <vector>
#include <inttypes.h>
@@ -41,8 +41,15 @@
class ComposerClientReader {
public:
+ explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
+
~ComposerClientReader() { resetData(); }
+ ComposerClientReader(ComposerClientReader&&) = default;
+
+ ComposerClientReader(const ComposerClientReader&) = delete;
+ ComposerClientReader& operator=(const ComposerClientReader&) = delete;
+
// Parse and execute commands from the command queue. The commands are
// actually return values from the server and will be saved in ReturnData.
void parse(std::vector<CommandResultPayload>&& results) {
@@ -85,6 +92,7 @@
void hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
uint32_t* outNumLayerRequestMasks) const {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
*outNumChangedCompositionTypes = 0;
@@ -100,6 +108,7 @@
// Get and clear saved changed composition types.
std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
@@ -111,6 +120,7 @@
// Get and clear saved display requests.
DisplayRequest takeDisplayRequests(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
@@ -122,6 +132,7 @@
// Get and clear saved release fences.
std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
@@ -133,6 +144,7 @@
// Get and clear saved present fence.
ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return {};
@@ -144,6 +156,7 @@
// Get what stage succeeded during PresentOrValidate: Present or Validate
std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
if (found == mReturnData.end()) {
return std::nullopt;
@@ -154,6 +167,7 @@
// Get the client target properties requested by hardware composer.
ClientTargetPropertyWithBrightness takeClientTargetProperty(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
auto found = mReturnData.find(display);
// If not found, return the default values.
@@ -177,32 +191,38 @@
void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && changedCompositionTypes.display != *mDisplay);
auto& data = mReturnData[changedCompositionTypes.display];
data.changedLayers = std::move(changedCompositionTypes.layers);
}
void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && displayRequest.display != *mDisplay);
auto& data = mReturnData[displayRequest.display];
data.displayRequests = std::move(displayRequest);
}
void parseSetPresentFence(PresentFence&& presentFence) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
auto& data = mReturnData[presentFence.display];
data.presentFence = std::move(presentFence.fence);
}
void parseSetReleaseFences(ReleaseFences&& releaseFences) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && releaseFences.display != *mDisplay);
auto& data = mReturnData[releaseFences.display];
data.releasedLayers = std::move(releaseFences.layers);
}
void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && presentOrValidate.display != *mDisplay);
auto& data = mReturnData[presentOrValidate.display];
data.presentOrValidateState = std::move(presentOrValidate.result);
}
void parseSetClientTargetProperty(
const ClientTargetPropertyWithBrightness&& clientTargetProperty) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && clientTargetProperty.display != *mDisplay);
auto& data = mReturnData[clientTargetProperty.display];
data.clientTargetProperty = std::move(clientTargetProperty);
}
@@ -222,6 +242,7 @@
std::vector<CommandError> mErrors;
std::unordered_map<int64_t, ReturnData> mReturnData;
+ const std::optional<int64_t> mDisplay;
};
} // namespace aidl::android::hardware::graphics::composer3
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 1d81f7b..4a5ac69 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -19,8 +19,6 @@
#include <algorithm>
#include <limits>
#include <memory>
-#include <unordered_map>
-#include <unordered_set>
#include <vector>
#include <inttypes.h>
@@ -59,13 +57,18 @@
namespace aidl::android::hardware::graphics::composer3 {
-class ComposerClientWriter {
+class ComposerClientWriter final {
public:
static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;
- ComposerClientWriter() { reset(); }
+ explicit ComposerClientWriter(int64_t display) : mDisplay(display) { reset(); }
- virtual ~ComposerClientWriter() { reset(); }
+ ~ComposerClientWriter() { reset(); }
+
+ ComposerClientWriter(ComposerClientWriter&&) = default;
+
+ ComposerClientWriter(const ComposerClientWriter&) = delete;
+ ComposerClientWriter& operator=(const ComposerClientWriter&) = delete;
void reset() {
mDisplayCommand.reset();
@@ -88,7 +91,7 @@
void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
ClientTarget clientTargetCommand;
- clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
+ clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
clientTargetCommand.dataspace = dataspace;
clientTargetCommand.damage.assign(damage.begin(), damage.end());
getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
@@ -97,7 +100,7 @@
void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
int releaseFence) {
getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
- getBuffer(slot, buffer, releaseFence));
+ getBufferCommand(slot, buffer, releaseFence));
}
void validateDisplay(int64_t display,
@@ -129,7 +132,20 @@
void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
const native_handle_t* buffer, int acquireFence) {
- getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
+ getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
+ }
+
+ void setLayerBufferWithNewCommand(int64_t display, int64_t layer, uint32_t slot,
+ const native_handle_t* buffer, int acquireFence) {
+ flushLayerCommand();
+ getLayerCommand(display, layer).buffer = getBufferCommand(slot, buffer, acquireFence);
+ flushLayerCommand();
+ }
+
+ void setLayerBufferSlotsToClear(int64_t display, int64_t layer,
+ const std::vector<uint32_t>& slotsToClear) {
+ getLayerCommand(display, layer)
+ .bufferSlotsToClear.emplace(slotsToClear.begin(), slotsToClear.end());
}
void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
@@ -229,8 +245,9 @@
std::optional<DisplayCommand> mDisplayCommand;
std::optional<LayerCommand> mLayerCommand;
std::vector<DisplayCommand> mCommands;
+ const int64_t mDisplay;
- Buffer getBuffer(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
+ Buffer getBufferCommand(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer bufferCommand;
bufferCommand.slot = static_cast<int32_t>(slot);
if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
@@ -254,6 +271,7 @@
DisplayCommand& getDisplayCommand(int64_t display) {
if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
+ LOG_ALWAYS_FATAL_IF(display != mDisplay);
flushLayerCommand();
flushDisplayCommand();
mDisplayCommand.emplace();
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index 84fd76a..88b5de4 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -28,8 +28,9 @@
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
- // Needed for librenderengine
- "skia_deps",
+ "librenderengine_deps",
+ "android.hardware.graphics.common-ndk_static",
+ "android.hardware.graphics.composer3-ndk_static",
],
srcs: [
"VtsHalGraphicsComposer3_TargetTest.cpp",
@@ -67,8 +68,6 @@
"android.hardware.graphics.composer3-command-buffer",
],
static_libs: [
- "android.hardware.graphics.composer3-V1-ndk",
- "android.hardware.graphics.common-V4-ndk",
"[email protected]",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
index d534943..7b3a2b4 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
@@ -29,6 +29,11 @@
mVsyncAllowed = allowed;
}
+void GraphicsComposerCallback::setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed) {
+ std::scoped_lock lock(mMutex);
+ mRefreshRateChangedDebugDataEnabledCallbackAllowed = allowed;
+}
+
std::vector<int64_t> GraphicsComposerCallback::getDisplays() const {
std::scoped_lock lock(mMutex);
return mDisplays;
@@ -79,6 +84,21 @@
return ret;
}
+std::vector<RefreshRateChangedDebugData>
+GraphicsComposerCallback::takeListOfRefreshRateChangedDebugData() {
+ std::scoped_lock lock(mMutex);
+
+ std::vector<RefreshRateChangedDebugData> ret;
+ ret.swap(mRefreshRateChangedDebugData);
+
+ return ret;
+}
+
+int32_t GraphicsComposerCallback::getInvalidRefreshRateDebugEnabledCallbackCount() const {
+ std::scoped_lock lock(mMutex);
+ return mInvalidRefreshRateDebugEnabledCallbackCount;
+}
+
::ndk::ScopedAStatus GraphicsComposerCallback::onHotplug(int64_t in_display, bool in_connected) {
std::scoped_lock lock(mMutex);
@@ -124,6 +144,19 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus GraphicsComposerCallback::onRefreshRateChangedDebug(
+ const RefreshRateChangedDebugData& data) {
+ std::scoped_lock lock(mMutex);
+
+ const auto it = std::find(mDisplays.begin(), mDisplays.end(), data.display);
+ if (mRefreshRateChangedDebugDataEnabledCallbackAllowed && it != mDisplays.end()) {
+ mRefreshRateChangedDebugData.push_back(data);
+ } else {
+ mInvalidRefreshRateDebugEnabledCallbackCount++;
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
::ndk::ScopedAStatus GraphicsComposerCallback::onVsyncPeriodTimingChanged(
int64_t in_display,
const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.h b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
index e54da34..13e992a 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
@@ -26,6 +26,8 @@
public:
void setVsyncAllowed(bool allowed);
+ void setRefreshRateChangedDebugDataEnabledCallbackAllowed(bool allowed);
+
std::vector<int64_t> getDisplays() const;
int32_t getInvalidHotplugCount() const;
@@ -44,6 +46,10 @@
std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline();
+ std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();
+
+ int32_t getInvalidRefreshRateDebugEnabledCallbackCount() const;
+
private:
virtual ::ndk::ScopedAStatus onHotplug(int64_t in_display, bool in_connected) override;
virtual ::ndk::ScopedAStatus onRefresh(int64_t in_display) override;
@@ -55,15 +61,21 @@
const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
in_updatedTimeline) override;
virtual ::ndk::ScopedAStatus onVsyncIdle(int64_t in_display) override;
+ virtual ::ndk::ScopedAStatus onRefreshRateChangedDebug(
+ const RefreshRateChangedDebugData&) override;
mutable std::mutex mMutex;
// the set of all currently connected displays
std::vector<int64_t> mDisplays GUARDED_BY(mMutex);
// true only when vsync is enabled
bool mVsyncAllowed GUARDED_BY(mMutex) = true;
+ // true only when RefreshRateChangedCallbackDebugEnabled is set to true.
+ bool mRefreshRateChangedDebugDataEnabledCallbackAllowed GUARDED_BY(mMutex) = false;
std::optional<VsyncPeriodChangeTimeline> mTimeline GUARDED_BY(mMutex);
+ std::vector<RefreshRateChangedDebugData> mRefreshRateChangedDebugData GUARDED_BY(mMutex);
+
int32_t mVsyncIdleCount GUARDED_BY(mMutex) = 0;
int64_t mVsyncIdleTime GUARDED_BY(mMutex) = 0;
@@ -73,6 +85,7 @@
int32_t mInvalidVsyncCount GUARDED_BY(mMutex) = 0;
int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0;
int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0;
+ int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0;
};
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/RenderEngineVts.cpp b/graphics/composer/aidl/vts/RenderEngineVts.cpp
index 71b011c..66779c8 100644
--- a/graphics/composer/aidl/vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/vts/RenderEngineVts.cpp
@@ -66,14 +66,12 @@
auto texture = std::make_shared<::android::renderengine::impl::ExternalTexture>(
mGraphicBuffer, *mRenderEngine,
::android::renderengine::impl::ExternalTexture::Usage::WRITEABLE);
- auto [status, readyFence] = mRenderEngine
- ->drawLayers(mDisplaySettings, compositionLayers, texture,
- true, std::move(bufferFence))
- .get();
- int fd = readyFence.release();
- if (fd != -1) {
- ASSERT_EQ(0, sync_wait(fd, -1));
- ASSERT_EQ(0, close(fd));
+ auto result = mRenderEngine
+ ->drawLayers(mDisplaySettings, compositionLayers, texture, true,
+ std::move(bufferFence))
+ .get();
+ if (result.ok()) {
+ result.value()->waitForever(LOG_TAG);
}
}
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index dd4161e..25b0ca0 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -58,6 +58,12 @@
return verifyComposerCallbackParams() && destroyAllLayers();
}
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() {
+ int32_t version = 1;
+ auto status = mComposerClient->getInterfaceVersion(&version);
+ return {std::move(status), version};
+}
+
std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
VirtualDisplay outVirtualDisplay;
@@ -113,6 +119,24 @@
return updateDisplayProperties(vtsDisplay, config);
}
+ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) {
+ const auto displayId = vtsDisplay->getDisplayId();
+ auto [activeStatus, activeConfig] = getActiveConfig(displayId);
+ EXPECT_TRUE(activeStatus.isOk());
+ auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig);
+ auto peakConfig = activeConfig;
+
+ const auto displayConfigs = vtsDisplay->getDisplayConfigs();
+ for (const auto [config, displayConfig] : displayConfigs) {
+ if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
+ displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
+ peakDisplayConfig = displayConfig;
+ peakConfig = config;
+ }
+ }
+ return setActiveConfig(vtsDisplay, peakConfig);
+}
+
std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
int64_t display, int32_t config, DisplayAttribute displayAttribute) {
int32_t outDisplayAttribute;
@@ -331,6 +355,20 @@
return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
}
+std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
+VtsComposerClient::getHdrConversionCapabilities() {
+ std::vector<common::HdrConversionCapability> hdrConversionCapability;
+ return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
+ hdrConversionCapability};
+}
+
+std::pair<ScopedAStatus, common::Hdr> VtsComposerClient::setHdrConversionStrategy(
+ const common::HdrConversionStrategy& conversionStrategy) {
+ common::Hdr preferredHdrOutputType;
+ return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
+ preferredHdrOutputType};
+}
+
std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
int64_t display) {
common::Transform outDisplayOrientation;
@@ -338,6 +376,11 @@
outDisplayOrientation};
}
+std::pair<ScopedAStatus, composer3::OverlayProperties> VtsComposerClient::getOverlaySupport() {
+ OverlayProperties properties;
+ return {mComposerClient->getOverlaySupport(&properties), properties};
+}
+
ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
}
@@ -350,6 +393,17 @@
return mComposerCallback->getVsyncIdleTime();
}
+ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
+ bool enabled) {
+ mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
+ return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
+}
+
+std::vector<RefreshRateChangedDebugData>
+VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
+ return mComposerCallback->takeListOfRefreshRateChangedDebugData();
+}
+
int64_t VtsComposerClient::getInvalidDisplayId() {
// returns an invalid display id (one that has not been registered to a
// display. Currently assuming that a device will never have close to
@@ -514,6 +568,10 @@
ALOGE("Invalid seamless possible count");
isValid = false;
}
+ if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
+ ALOGE("Invalid refresh rate debug enabled callback count");
+ isValid = false;
+ }
}
return isValid;
}
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index 74c5da5..ea3318c 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -35,6 +35,7 @@
#include <string>
#include <thread>
#include <unordered_map>
+#include <unordered_set>
#include "GraphicsComposerCallback.h"
using aidl::android::hardware::graphics::common::Dataspace;
@@ -60,6 +61,8 @@
bool tearDown();
+ std::pair<ScopedAStatus, int32_t> getInterfaceVersion();
+
std::pair<ScopedAStatus, VirtualDisplay> createVirtualDisplay(int32_t width, int32_t height,
PixelFormat pixelFormat,
int32_t bufferSlotCount);
@@ -74,6 +77,8 @@
ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config);
+ ScopedAStatus setPeakRefreshRateConfig(VtsDisplay* vtsDisplay);
+
std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config,
DisplayAttribute displayAttribute);
@@ -160,6 +165,12 @@
std::pair<ScopedAStatus, int32_t> getPreferredBootDisplayConfig(int64_t display);
+ std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
+ getHdrConversionCapabilities();
+
+ std::pair<ScopedAStatus, common::Hdr> setHdrConversionStrategy(
+ const common::HdrConversionStrategy& conversionStrategy);
+
std::pair<ScopedAStatus, common::Transform> getDisplayPhysicalOrientation(int64_t display);
ScopedAStatus setIdleTimerEnabled(int64_t display, int32_t timeoutMs);
@@ -172,6 +183,12 @@
std::pair<ScopedAStatus, std::vector<VtsDisplay>> getDisplays();
+ std::pair<ScopedAStatus, OverlayProperties> getOverlaySupport();
+
+ ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled);
+
+ std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();
+
private:
ScopedAStatus addDisplayConfig(VtsDisplay* vtsDisplay, int32_t config);
ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config);
@@ -231,15 +248,17 @@
};
void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
- displayConfigs.insert({config, displayConfig});
+ mDisplayConfigs.insert({config, displayConfig});
}
- DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; }
+ DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; }
+
+ std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; }
private:
int64_t mDisplayId;
int32_t mDisplayWidth;
int32_t mDisplayHeight;
- std::unordered_map<int32_t, DisplayConfig> displayConfigs;
+ std::unordered_map<int32_t, DisplayConfig> mDisplayConfigs;
};
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 46dde09..6fa3392 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -53,6 +53,7 @@
const auto& [status, displays] = mComposerClient->getDisplays();
ASSERT_TRUE(status.isOk());
mDisplays = displays;
+ mWriter.reset(new ComposerClientWriter(getPrimaryDisplayId()));
setTestColorModes();
@@ -200,15 +201,15 @@
void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
for (const auto& layer : layers) {
- layer->write(mWriter);
+ layer->write(*mWriter);
}
execute();
}
void execute() {
- const auto& commands = mWriter.getPendingCommands();
+ const auto& commands = mWriter->getPendingCommands();
if (commands.empty()) {
- mWriter.reset();
+ mWriter->reset();
return;
}
@@ -216,7 +217,7 @@
ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
mReader.parse(std::move(results));
- mWriter.reset();
+ mWriter->reset();
}
bool getHasReadbackBuffer() {
@@ -236,7 +237,7 @@
std::vector<VtsDisplay> mDisplays;
// use the slot count usually set by SF
std::vector<ColorMode> mTestColorModes;
- ComposerClientWriter mWriter;
+ std::unique_ptr<ComposerClientWriter> mWriter;
ComposerClientReader mReader;
std::unique_ptr<TestRenderEngine> mTestRenderEngine;
common::PixelFormat mPixelFormat;
@@ -297,7 +298,7 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
// if hwc cannot handle and asks for composition change,
// just succeed the test
@@ -306,7 +307,7 @@
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -349,14 +350,14 @@
getDisplayHeight(), common::PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
@@ -365,7 +366,7 @@
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -395,7 +396,7 @@
layer->setColor(BLUE);
layer->setDisplayFrame(coloredSquare);
layer->setZOrder(10);
- layer->write(mWriter);
+ layer->write(*mWriter);
// This following buffer call should have no effect
const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
@@ -403,8 +404,8 @@
const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
ASSERT_TRUE(graphicBufferStatus);
const auto& buffer = graphicBuffer->handle;
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
- /*acquireFence*/ -1);
+ mWriter->setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
+ /*acquireFence*/ -1);
// expected color for each pixel
std::vector<Color> expectedColors(
@@ -415,7 +416,7 @@
getDisplayHeight(), mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
@@ -423,7 +424,7 @@
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -533,7 +534,7 @@
getDisplayHeight(), PixelFormat::RGBA_FP16);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
@@ -542,7 +543,7 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
@@ -572,17 +573,17 @@
int32_t clientFence;
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));
- layer->setToClientComposition(mWriter);
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
+ clientDataspace, std::vector<common::Rect>(1, damage));
+ layer->setToClientComposition(*mWriter);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -631,9 +632,9 @@
deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
static_cast<int32_t>(deviceLayer->getHeight())});
deviceLayer->setZOrder(10);
- deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
- deviceLayer->write(mWriter);
+ deviceLayer->write(*mWriter);
PixelFormat clientFormat = PixelFormat::RGBA_8888;
auto clientUsage = static_cast<uint32_t>(
@@ -651,8 +652,8 @@
getDisplayHeight()};
clientLayer->setDisplayFrame(clientFrame);
clientLayer->setZOrder(0);
- clientLayer->write(mWriter);
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ clientLayer->write(*mWriter);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
@@ -678,16 +679,16 @@
int32_t clientFence;
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));
- clientLayer->setToClientComposition(mWriter);
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
+ clientDataspace, std::vector<common::Rect>(1, clientFrame));
+ clientLayer->setToClientComposition(*mWriter);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
ASSERT_TRUE(changedCompositionTypes.empty());
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -718,7 +719,7 @@
getDisplayHeight(), PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
@@ -729,14 +730,14 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -757,11 +758,11 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -798,7 +799,7 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
@@ -806,7 +807,7 @@
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -846,7 +847,7 @@
getDisplayHeight(), PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
layer->setSourceCrop({0, static_cast<float>(getDisplayHeight() / 2),
static_cast<float>(getDisplayWidth()),
static_cast<float>(getDisplayHeight())});
@@ -862,14 +863,14 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -920,13 +921,13 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -942,11 +943,11 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -980,7 +981,7 @@
// Preconditions to successfully run are knowing the max brightness and successfully applying
// the max brightness
ASSERT_GT(maxBrightnessNits, 0.f);
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.f, maxBrightnessNits);
+ mWriter->setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.f, maxBrightnessNits);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1030,7 +1031,7 @@
writeLayers(layers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED()
@@ -1038,7 +1039,7 @@
<< toString(mode);
continue;
}
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1088,7 +1089,7 @@
getDisplayHeight(), PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(Dataspace::UNKNOWN, mWriter);
+ layer->setDataspace(Dataspace::UNKNOWN, *mWriter);
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
layer->setBlendMode(blendMode);
@@ -1165,14 +1166,14 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(mLayers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1210,14 +1211,14 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(mLayers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -1250,14 +1251,14 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
writeLayers(mLayers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -1323,7 +1324,7 @@
getDisplayHeight(), mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
mLayer->setTransform(Transform::FLIP_H);
- mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
std::vector<Color> expectedColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1334,14 +1335,14 @@
writeLayers(mLayers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1369,7 +1370,7 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
mLayer->setTransform(Transform::FLIP_V);
- mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
std::vector<Color> expectedColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1380,14 +1381,14 @@
writeLayers(mLayers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
@@ -1414,7 +1415,7 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
mLayer->setTransform(Transform::ROT_180);
- mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
std::vector<Color> expectedColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1426,14 +1427,14 @@
writeLayers(mLayers);
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED();
return;
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ mWriter->presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 047109e..3ea5bf5 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -13,6 +13,7 @@
* 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/graphics/common/BlendMode.h>
@@ -32,9 +33,11 @@
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
#include <algorithm>
+#include <iterator>
#include <numeric>
#include <string>
#include <thread>
+#include <unordered_map>
#include "GraphicsComposerCallback.h"
#include "VtsComposerClient.h"
@@ -115,6 +118,12 @@
[&](const Capability& activeCapability) { return activeCapability == capability; });
}
+ int getInterfaceVersion() {
+ const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
+ EXPECT_TRUE(versionStatus.isOk());
+ return version;
+ }
+
const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
@@ -618,6 +627,68 @@
}
}
+TEST_P(GraphicsComposerAidlTest, GetHdrConversionCapabilities) {
+ if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+ GTEST_SUCCEED() << "HDR output conversion not supported";
+ return;
+ }
+ const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
+ EXPECT_TRUE(status.isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Passthrough) {
+ if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+ GTEST_SUCCEED() << "HDR output conversion not supported";
+ return;
+ }
+ common::HdrConversionStrategy hdrConversionStrategy;
+ hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::passthrough>(true);
+ const auto& [status, preferredHdrOutputType] =
+ mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
+}
+
+TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Force) {
+ if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+ GTEST_SUCCEED() << "HDR output conversion not supported";
+ return;
+ }
+ const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
+ for (auto conversionCapability : conversionCapabilities) {
+ if (conversionCapability.outputType != common::Hdr::INVALID) {
+ common::HdrConversionStrategy hdrConversionStrategy;
+ hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::forceHdrConversion>(
+ conversionCapability.outputType);
+ const auto& [statusSet, preferredHdrOutputType] =
+ mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
+ EXPECT_TRUE(statusSet.isOk());
+ EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
+ }
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Auto) {
+ if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
+ GTEST_SUCCEED() << "HDR output conversion not supported";
+ return;
+ }
+ const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
+ std::vector<aidl::android::hardware::graphics::common::Hdr> autoHdrTypes;
+ for (auto conversionCapability : conversionCapabilities) {
+ if (conversionCapability.outputType != common::Hdr::INVALID) {
+ autoHdrTypes.push_back(conversionCapability.outputType);
+ }
+ }
+ common::HdrConversionStrategy hdrConversionStrategy;
+ hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::autoAllowedHdrTypes>(
+ autoHdrTypes);
+ const auto& [statusSet, preferredHdrOutputType] =
+ mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
+ EXPECT_TRUE(statusSet.isOk());
+ EXPECT_NE(common::Hdr::INVALID, preferredHdrOutputType);
+}
+
TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode_BadDisplay) {
auto status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ true);
EXPECT_FALSE(status.isOk());
@@ -808,6 +879,39 @@
EXPECT_TRUE(status.isOk());
}
+TEST_P(GraphicsComposerAidlTest, GetOverlaySupport) {
+ if (getInterfaceVersion() <= 1) {
+ GTEST_SUCCEED() << "Device does not support the new API for overlay support";
+ return;
+ }
+
+ const auto& [status, properties] = mComposerClient->getOverlaySupport();
+ if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+ status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ GTEST_SUCCEED() << "getOverlaySupport is not supported";
+ return;
+ }
+
+ ASSERT_TRUE(status.isOk());
+ for (const auto& i : properties.combinations) {
+ for (const auto standard : i.standards) {
+ const auto val = static_cast<int32_t>(standard) &
+ static_cast<int32_t>(common::Dataspace::STANDARD_MASK);
+ ASSERT_TRUE(val == static_cast<int32_t>(standard));
+ }
+ for (const auto transfer : i.transfers) {
+ const auto val = static_cast<int32_t>(transfer) &
+ static_cast<int32_t>(common::Dataspace::TRANSFER_MASK);
+ ASSERT_TRUE(val == static_cast<int32_t>(transfer));
+ }
+ for (const auto range : i.ranges) {
+ const auto val = static_cast<int32_t>(range) &
+ static_cast<int32_t>(common::Dataspace::RANGE_MASK);
+ ASSERT_TRUE(val == static_cast<int32_t>(range));
+ }
+ }
+}
+
TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation_BadDisplay) {
const auto& [status, _] = mComposerClient->getDisplayPhysicalOrientation(getInvalidDisplayId());
@@ -1065,17 +1169,23 @@
}
void execute() {
- const auto& commands = mWriter.getPendingCommands();
- if (commands.empty()) {
- mWriter.reset();
- return;
+ std::vector<CommandResultPayload> payloads;
+ for (auto& [_, writer] : mWriters) {
+ const auto& commands = writer.getPendingCommands();
+ if (commands.empty()) {
+ writer.reset();
+ continue;
+ }
+
+ auto [status, results] = mComposerClient->executeCommands(commands);
+ ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
+ writer.reset();
+
+ payloads.reserve(payloads.size() + results.size());
+ payloads.insert(payloads.end(), std::make_move_iterator(results.begin()),
+ std::make_move_iterator(results.end()));
}
-
- auto [status, results] = mComposerClient->executeCommands(commands);
- ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
-
- mReader.parse(std::move(results));
- mWriter.reset();
+ mReader.parse(std::move(payloads));
}
static inline auto toTimePoint(nsecs_t time) {
@@ -1111,17 +1221,29 @@
}
}
- sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
+ bool checkIfCallbackRefreshRateChangedDebugEnabledReceived(
+ std::function<bool(RefreshRateChangedDebugData)> filter) {
+ const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData();
+ return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) {
+ return filter(refreshRateChangedDebugData);
+ });
+ }
+
+ sp<GraphicBuffer> allocate(uint32_t width, uint32_t height,
+ ::android::PixelFormat pixelFormat) {
return sp<GraphicBuffer>::make(
- static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
- static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat,
- /*layerCount*/ 1U,
- (static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
- static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
- static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY)),
+ width, height, pixelFormat, /*layerCount*/ 1U,
+ static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY),
"VtsHalGraphicsComposer3_TargetTest");
}
+ sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
+ return allocate(static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
+ static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat);
+ }
+
void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
if (timeline != nullptr) {
// Refresh time should be before newVsyncAppliedTimeNanos
@@ -1139,6 +1261,7 @@
const auto& [status, layer] =
mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
EXPECT_TRUE(status.isOk());
+ auto& writer = getWriter(display.getDisplayId());
{
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer);
@@ -1147,15 +1270,15 @@
configureLayer(display, layer, Composition::DEVICE, display.getFrameRect(),
display.getCrop());
- mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
- /*acquireFence*/ -1);
- mWriter.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
+ writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
+ writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
- mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(display.getDisplayId());
+ writer.presentDisplay(display.getDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1164,15 +1287,15 @@
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ASSERT_NE(nullptr, buffer->handle);
- mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
- /*acquireFence*/ -1);
- mWriter.setLayerSurfaceDamage(display.getDisplayId(), layer,
- std::vector<Rect>(1, {0, 0, 10, 10}));
- mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
+ writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
+ std::vector<Rect>(1, {0, 0, 10, 10}));
+ writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(display.getDisplayId());
+ writer.presentDisplay(display.getDisplayId());
execute();
}
@@ -1181,11 +1304,12 @@
sp<::android::Fence> presentAndGetFence(
std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
- mWriter.validateDisplay(getPrimaryDisplayId(), expectedPresentTime);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.validateDisplay(getPrimaryDisplayId(), expectedPresentTime);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ writer.presentDisplay(getPrimaryDisplayId());
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
@@ -1208,7 +1332,7 @@
return vsyncPeriod;
}
- int64_t createOnScreenLayer() {
+ int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) {
const auto& [status, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(status.isOk());
@@ -1216,11 +1340,25 @@
getPrimaryDisplay().getDisplayHeight()};
FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
(float)getPrimaryDisplay().getDisplayHeight()};
- configureLayer(getPrimaryDisplay(), layer, Composition::DEVICE, displayFrame, cropRect);
- mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
+ configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
return layer;
}
+ void sendBufferUpdate(int64_t layer) {
+ const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer->handle);
+
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
+
+ const sp<::android::Fence> presentFence =
+ presentAndGetFence(ComposerClientWriter::kNoTimestamp);
+ presentFence->waitForever(LOG_TAG);
+ }
+
bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display);
EXPECT_TRUE(status.isOk());
@@ -1317,8 +1455,9 @@
ASSERT_NE(nullptr, buffer2);
const auto layer = createOnScreenLayer();
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
- /*acquireFence*/ -1);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
+ /*acquireFence*/ -1);
const sp<::android::Fence> presentFence1 =
presentAndGetFence(ComposerClientWriter::kNoTimestamp);
presentFence1->waitForever(LOG_TAG);
@@ -1328,8 +1467,8 @@
expectedPresentTime += *framesDelay * vsyncPeriod;
}
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
- /*acquireFence*/ -1);
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
+ /*acquireFence*/ -1);
const auto setExpectedPresentTime = [&]() -> std::optional<ClockMonotonicTimestamp> {
if (!framesDelay.has_value()) {
return ComposerClientWriter::kNoTimestamp;
@@ -1350,17 +1489,18 @@
void configureLayer(const VtsDisplay& display, int64_t layer, Composition composition,
const Rect& displayFrame, const FRect& cropRect) {
- mWriter.setLayerCompositionType(display.getDisplayId(), layer, composition);
- mWriter.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
- mWriter.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
- mWriter.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
- mWriter.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
- mWriter.setLayerVisibleRegion(display.getDisplayId(), layer,
- std::vector<Rect>(1, displayFrame));
- mWriter.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
- mWriter.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
- mWriter.setLayerSurfaceDamage(display.getDisplayId(), layer,
- std::vector<Rect>(1, displayFrame));
+ auto& writer = getWriter(display.getDisplayId());
+ writer.setLayerCompositionType(display.getDisplayId(), layer, composition);
+ writer.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
+ writer.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
+ writer.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
+ writer.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
+ writer.setLayerVisibleRegion(display.getDisplayId(), layer,
+ std::vector<Rect>(1, displayFrame));
+ writer.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
+ writer.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
+ writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
+ std::vector<Rect>(1, displayFrame));
}
// clang-format off
const std::array<float, 16> kIdentity = {{
@@ -1371,12 +1511,20 @@
}};
// clang-format on
- ComposerClientWriter mWriter;
+ ComposerClientWriter& getWriter(int64_t display) {
+ auto [it, _] = mWriters.try_emplace(display, display);
+ return it->second;
+ }
+
ComposerClientReader mReader;
+
+ private:
+ std::unordered_map<int64_t, ComposerClientWriter> mWriters;
};
TEST_P(GraphicsComposerAidlCommandTest, SetColorTransform) {
- mWriter.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
execute();
}
@@ -1384,7 +1532,8 @@
const auto& [status, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(status.isOk());
- mWriter.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
execute();
const auto errors = mReader.takeErrors();
@@ -1400,8 +1549,9 @@
ASSERT_TRUE(status.isOk());
bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
DisplayCapability::BRIGHTNESS) != capabilities.end();
+ auto& writer = getWriter(getPrimaryDisplayId());
if (!brightnessSupport) {
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
execute();
const auto errors = mReader.takeErrors();
EXPECT_EQ(1, errors.size());
@@ -1410,23 +1560,23 @@
return;
}
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
execute();
EXPECT_TRUE(mReader.takeErrors().empty());
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
execute();
{
const auto errors = mReader.takeErrors();
@@ -1434,7 +1584,7 @@
EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
}
- mWriter.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
+ writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
execute();
{
const auto errors = mReader.takeErrors();
@@ -1447,8 +1597,9 @@
EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
.isOk());
- mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
- Dataspace::UNKNOWN, std::vector<Rect>());
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
+ Dataspace::UNKNOWN, std::vector<Rect>());
execute();
}
@@ -1468,24 +1619,28 @@
const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
const auto handle = buffer->handle;
- mWriter.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
+ auto& writer = getWriter(display.display);
+ writer.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, ValidDisplay) {
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, AcceptDisplayChanges) {
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
- mWriter.acceptDisplayChanges(getPrimaryDisplayId());
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.acceptDisplayChanges(getPrimaryDisplayId());
execute();
}
TEST_P(GraphicsComposerAidlCommandTest, PresentDisplay) {
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
- mWriter.presentDisplay(getPrimaryDisplayId());
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.presentDisplay(getPrimaryDisplayId());
execute();
}
@@ -1506,6 +1661,7 @@
const auto& [renderIntentsStatus, renderIntents] =
mComposerClient->getRenderIntents(getPrimaryDisplayId(), ColorMode::NATIVE);
EXPECT_TRUE(renderIntentsStatus.isOk());
+ auto& writer = getWriter(getPrimaryDisplayId());
for (auto intent : renderIntents) {
EXPECT_TRUE(mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE, intent)
.isOk());
@@ -1523,10 +1679,10 @@
FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
(float)getPrimaryDisplay().getDisplayHeight()};
configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
- /*acquireFence*/ -1);
- mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
+ /*acquireFence*/ -1);
+ writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
GTEST_SUCCEED() << "Composition change requested, skipping test";
@@ -1534,18 +1690,18 @@
}
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.presentDisplay(getPrimaryDisplayId());
+ writer.presentDisplay(getPrimaryDisplayId());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
const auto handle2 = buffer2->handle;
ASSERT_NE(nullptr, handle2);
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
- /*acquireFence*/ -1);
- mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
- std::vector<Rect>(1, {0, 0, 10, 10}));
- mWriter.presentDisplay(getPrimaryDisplayId());
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
+ /*acquireFence*/ -1);
+ writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
+ std::vector<Rect>(1, {0, 0, 10, 10}));
+ writer.presentDisplay(getPrimaryDisplayId());
execute();
}
}
@@ -1559,15 +1715,16 @@
const auto handle = buffer->handle;
ASSERT_NE(nullptr, handle);
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
getPrimaryDisplay().getDisplayHeight()};
FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
(float)getPrimaryDisplay().getDisplayHeight()};
configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
- mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
@@ -1575,15 +1732,15 @@
GTEST_SUCCEED() << "Composition change requested, skipping test";
return;
}
- mWriter.presentDisplay(getPrimaryDisplayId());
+ writer.presentDisplay(getPrimaryDisplayId());
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
+ writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
execute();
- mWriter.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
- mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
- mWriter.presentDisplay(getPrimaryDisplayId());
+ writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ writer.presentDisplay(getPrimaryDisplayId());
execute();
}
@@ -1595,10 +1752,109 @@
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
execute();
}
+TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferSlotsToClear) {
+ // Older HAL versions use a backwards compatible way of clearing buffer slots
+ const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
+ ASSERT_TRUE(versionStatus.isOk());
+ if (version <= 1) {
+ GTEST_SUCCEED() << "HAL at version 1 or lower does not have "
+ "LayerCommand::bufferSlotsToClear.";
+ return;
+ }
+
+ const auto& [layerStatus, layer] =
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ EXPECT_TRUE(layerStatus.isOk());
+ auto& writer = getWriter(getPrimaryDisplayId());
+
+ // setup 3 buffers in the buffer cache, with the last buffer being active
+ // then emulate the Android platform code that clears all 3 buffer slots
+
+ const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer1);
+ const auto handle1 = buffer1->handle;
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer2);
+ const auto handle2 = buffer2->handle;
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer3);
+ const auto handle3 = buffer3->handle;
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ // Ensure we can clear all 3 buffer slots, even the active buffer - it is assumed the
+ // current active buffer's slot will be cleared, but still remain the active buffer and no
+ // errors will occur.
+ writer.setLayerBufferSlotsToClear(getPrimaryDisplayId(), layer, {0, 1, 2});
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
+ const auto& [layerStatus, layer] =
+ mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+ EXPECT_TRUE(layerStatus.isOk());
+ auto& writer = getWriter(getPrimaryDisplayId());
+
+ // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
+ // Android platform code that clears all 3 buffer slots by setting all but the active buffer
+ // slot to a placeholder buffer, and then restoring the active buffer.
+
+ // This is used on HALs that don't support setLayerBufferSlotsToClear (version <= 3.1).
+
+ const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer1);
+ const auto handle1 = buffer1->handle;
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer2);
+ const auto handle2 = buffer2->handle;
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+ ASSERT_NE(nullptr, buffer3);
+ const auto handle3 = buffer3->handle;
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ // Older versions of the HAL clear all but the active buffer slot with a placeholder buffer,
+ // and then restoring the current active buffer at the end
+ auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
+ ASSERT_NE(nullptr, clearSlotBuffer);
+ auto clearSlotBufferHandle = clearSlotBuffer->handle;
+
+ // clear buffer slots 0 and 1 with new layer commands... and then...
+ writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
+ clearSlotBufferHandle, /*acquireFence*/ -1);
+ writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 1,
+ clearSlotBufferHandle, /*acquireFence*/ -1);
+ // ...reset the layer buffer to the current active buffer slot with a final new command
+ writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /*slot*/ 2, nullptr,
+ /*acquireFence*/ -1);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
@@ -1607,15 +1863,16 @@
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
+ writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
+ writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1628,15 +1885,16 @@
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- mWriter.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
+ writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
+ writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1646,15 +1904,16 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
+ writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
+ writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1664,11 +1923,12 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
+ writer.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1678,19 +1938,20 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
+ writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
+ writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
+ writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
execute();
}
@@ -1721,9 +1982,10 @@
configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
display.getCrop());
- mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
- /*acquireFence*/ -1);
- mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
+ auto& writer = getWriter(display.getDisplayId());
+ writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
+ /*acquireFence*/ -1);
+ writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (support) {
ASSERT_TRUE(mReader.takeErrors().empty());
@@ -1740,7 +2002,8 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
execute();
}
@@ -1749,7 +2012,8 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
execute();
}
@@ -1758,11 +2022,12 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
+ writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1781,7 +2046,8 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
execute();
}
@@ -1790,7 +2056,8 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
execute();
}
@@ -1799,39 +2066,40 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
+ writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
+ writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
+ writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
+ writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
+ writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer,
- static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
- static_cast<int>(Transform::ROT_90)));
+ writer.setLayerTransform(getPrimaryDisplayId(), layer,
+ static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+ static_cast<int>(Transform::ROT_90)));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerTransform(getPrimaryDisplayId(), layer,
- static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
- static_cast<int>(Transform::ROT_90)));
+ writer.setLayerTransform(getPrimaryDisplayId(), layer,
+ static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+ static_cast<int>(Transform::ROT_90)));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1844,15 +2112,16 @@
Rect empty{0, 0, 0, 0};
Rect unit{0, 0, 1, 1};
- mWriter.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
+ writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
+ writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1862,11 +2131,12 @@
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
EXPECT_TRUE(layerStatus.isOk());
- mWriter.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
+ writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
}
@@ -1888,6 +2158,7 @@
* white (D65) 0.3127 0.3290
*/
+ auto& writer = getWriter(getPrimaryDisplayId());
std::vector<PerFrameMetadata> aidlMetadata;
aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
@@ -1901,7 +2172,7 @@
aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
- mWriter.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
+ writer.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
execute();
const auto errors = mReader.takeErrors();
@@ -1918,19 +2189,20 @@
const auto& [layerStatus, layer] =
mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
- mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
+ writer.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
+ writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
execute();
ASSERT_TRUE(mReader.takeErrors().empty());
- mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
+ writer.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
execute();
{
const auto errors = mReader.takeErrors();
@@ -1938,7 +2210,7 @@
EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
}
- mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
+ writer.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
execute();
{
const auto errors = mReader.takeErrors();
@@ -2103,8 +2375,9 @@
ASSERT_NE(nullptr, buffer->handle);
const auto layer = createOnScreenLayer();
- mWriter.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
- /*acquireFence*/ -1);
+ auto& writer = getWriter(getPrimaryDisplayId());
+ writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
+ /*acquireFence*/ -1);
int32_t vsyncIdleCount = mComposerClient->getVsyncIdleCount();
auto earlyVsyncIdleTime = systemTime() + std::chrono::nanoseconds(2s).count();
EXPECT_TRUE(
@@ -2122,6 +2395,245 @@
EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
}
+TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Unsupported) {
+ if (getInterfaceVersion() <= 1) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+ "not supported on older version of the service";
+ return;
+ }
+ if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+ auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(
+ getPrimaryDisplayId(), /*enabled*/ true);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_NO_FATAL_FAILURE(
+ assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+
+ status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(),
+ /*enabled*/ false);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_NO_FATAL_FAILURE(
+ assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+ }
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SetRefreshRateChangedCallbackDebug_Enabled) {
+ if (getInterfaceVersion() <= 1) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+ "not supported on older version of the service";
+ return;
+ }
+ if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
+ return;
+ }
+
+ const auto displayId = getPrimaryDisplayId();
+ EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+ // Enable the callback
+ ASSERT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+ /*enabled*/ true)
+ .isOk());
+ std::this_thread::sleep_for(100ms);
+
+ const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
+ return displayId == refreshRateChangedDebugData.display;
+ };
+
+ // Check that we immediately got a callback
+ EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
+
+ ASSERT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+ /*enabled*/ false)
+ .isOk());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest,
+ SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) {
+ if (getInterfaceVersion() <= 1) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+ "not supported on older version of the service";
+ return;
+ }
+ if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
+ return;
+ }
+
+ auto display = getEditablePrimaryDisplay();
+ const auto displayId = display.getDisplayId();
+
+ if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) {
+ GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
+ return;
+ }
+
+ EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+ EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk());
+
+ ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk());
+ // Enable the callback
+ ASSERT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+ /*enabled*/ true)
+ .isOk());
+
+ const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
+ return displayId == refreshRateChangedDebugData.display;
+ };
+
+ int retryCount = 3;
+ do {
+ // Wait for 1s so that we enter the idle state
+ std::this_thread::sleep_for(1s);
+ if (!checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter)) {
+ // DID NOT receive a callback, we are in the idle state.
+ break;
+ }
+ } while (--retryCount > 0);
+
+ if (retryCount == 0) {
+ GTEST_SUCCEED() << "Unable to enter the idle mode";
+ return;
+ }
+
+ // Send the REFRESH_RATE_INDICATOR update
+ ASSERT_NO_FATAL_FAILURE(
+ sendBufferUpdate(createOnScreenLayer(Composition::REFRESH_RATE_INDICATOR)));
+ std::this_thread::sleep_for(1s);
+ EXPECT_FALSE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter))
+ << "A callback should not be received for REFRESH_RATE_INDICATOR";
+
+ EXPECT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId,
+ /*enabled*/ false)
+ .isOk());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest,
+ SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) {
+ if (getInterfaceVersion() <= 1) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is "
+ "not supported on older version of the service";
+ return;
+ }
+ if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
+ GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
+ return;
+ }
+
+ VsyncPeriodChangeConstraints constraints;
+ constraints.seamlessRequired = false;
+ constraints.desiredTimeNanos = systemTime();
+
+ for (VtsDisplay& display : mDisplays) {
+ const auto displayId = display.getDisplayId();
+ EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
+
+ // Enable the callback
+ ASSERT_TRUE(mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true)
+ .isOk());
+
+ forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
+ const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod;
+ const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
+
+ if (vsyncPeriod1 == vsyncPeriod2) {
+ return; // continue
+ }
+
+ EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
+ sendRefreshFrame(display, nullptr);
+
+ const auto& [status, timeline] =
+ mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints);
+ EXPECT_TRUE(status.isOk());
+
+ if (timeline.refreshRequired) {
+ sendRefreshFrame(display, &timeline);
+ }
+
+ const auto callbackFilter = [displayId,
+ vsyncPeriod2](auto refreshRateChangedDebugData) {
+ constexpr int kVsyncThreshold = 1000;
+ return displayId == refreshRateChangedDebugData.display &&
+ std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <=
+ kVsyncThreshold;
+ };
+
+ int retryCount = 3;
+ do {
+ std::this_thread::sleep_for(100ms);
+ if (checkIfCallbackRefreshRateChangedDebugEnabledReceived(callbackFilter)) {
+ GTEST_SUCCEED() << "Received a callback successfully";
+ break;
+ }
+ } while (--retryCount > 0);
+
+ if (retryCount == 0) {
+ GTEST_FAIL() << "failed to get a callback for the display " << displayId
+ << " with config " << config2;
+ }
+ });
+
+ EXPECT_TRUE(
+ mComposerClient
+ ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false)
+ .isOk());
+ }
+}
+
+/*
+ * Test that no two display configs are exactly the same.
+ */
+TEST_P(GraphicsComposerAidlTest, GetDisplayConfigNoRepetitions) {
+ for (const auto& display : mDisplays) {
+ const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
+ for (std::vector<int>::size_type i = 0; i < configs.size(); i++) {
+ for (std::vector<int>::size_type j = i + 1; j < configs.size(); j++) {
+ const auto& [widthStatus1, width1] = mComposerClient->getDisplayAttribute(
+ display.getDisplayId(), configs[i], DisplayAttribute::WIDTH);
+ const auto& [heightStatus1, height1] = mComposerClient->getDisplayAttribute(
+ display.getDisplayId(), configs[i], DisplayAttribute::HEIGHT);
+ const auto& [vsyncPeriodStatus1, vsyncPeriod1] =
+ mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[i],
+ DisplayAttribute::VSYNC_PERIOD);
+ const auto& [groupStatus1, group1] = mComposerClient->getDisplayAttribute(
+ display.getDisplayId(), configs[i], DisplayAttribute::CONFIG_GROUP);
+
+ const auto& [widthStatus2, width2] = mComposerClient->getDisplayAttribute(
+ display.getDisplayId(), configs[j], DisplayAttribute::WIDTH);
+ const auto& [heightStatus2, height2] = mComposerClient->getDisplayAttribute(
+ display.getDisplayId(), configs[j], DisplayAttribute::HEIGHT);
+ const auto& [vsyncPeriodStatus2, vsyncPeriod2] =
+ mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[j],
+ DisplayAttribute::VSYNC_PERIOD);
+ const auto& [groupStatus2, group2] = mComposerClient->getDisplayAttribute(
+ display.getDisplayId(), configs[j], DisplayAttribute::CONFIG_GROUP);
+
+ ASSERT_FALSE(width1 == width2 && height1 == height2 &&
+ vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
+ }
+ }
+ }
+}
+
+/**
+ * Test Capability::SKIP_VALIDATE
+ *
+ * Capability::SKIP_VALIDATE has been deprecated and should not be enabled.
+ */
+TEST_P(GraphicsComposerAidlCommandTest, SkipValidateDeprecatedTest) {
+ if (getInterfaceVersion() <= 1) {
+ GTEST_SUCCEED() << "HAL at version 1 or lower can contain Capability::SKIP_VALIDATE.";
+ return;
+ }
+ ASSERT_FALSE(hasCapability(Capability::SKIP_VALIDATE))
+ << "Found Capability::SKIP_VALIDATE capability.";
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsComposerAidlCommandTest,
diff --git a/graphics/mapper/4.0/utils/vts/Android.bp b/graphics/mapper/4.0/utils/vts/Android.bp
index d808559..51e871b 100644
--- a/graphics/mapper/4.0/utils/vts/Android.bp
+++ b/graphics/mapper/4.0/utils/vts/Android.bp
@@ -37,7 +37,6 @@
],
static_libs: [
"[email protected]",
- "android.hardware.graphics.common-V4-ndk",
"[email protected]",
"libaidlcommonsupport",
],
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index ebdc4ec..6208ae9 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -33,7 +33,6 @@
],
srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
static_libs: [
- "android.hardware.graphics.common-V4-ndk",
"[email protected]",
"libaidlcommonsupport",
"libgralloctypes",
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 2ec98d4..e4a84e1 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -954,7 +954,6 @@
EXPECT_EQ(PlaneLayoutComponentType::RAW,
static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
- EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
}
@@ -996,7 +995,6 @@
EXPECT_EQ(PlaneLayoutComponentType::RAW,
static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
- EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
ASSERT_NO_FATAL_FAILURE(fence.reset(mGralloc->unlock(bufferHandle)));
}
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
index d40e160..1d01a02 100644
--- a/graphics/mapper/stable-c/Android.bp
+++ b/graphics/mapper/stable-c/Android.bp
@@ -33,6 +33,32 @@
export_header_lib_headers: [
"libarect_headers",
],
+ // TODO(b/214400477) Remove apex_available
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ "test_com.android.media.swcodec",
+ ],
+ min_sdk_version: "29",
+}
+
+cc_library_shared {
+ name: "libimapper_stablec_abicheck",
+ visibility: ["//visibility:private"],
+ defaults: [
+ "android.hardware.graphics.allocator-ndk_shared",
+ "android.hardware.graphics.common-ndk_shared",
+ ],
+ header_libs: [
+ "libimapper_stablec",
+ ],
+ srcs: [
+ "imapper5_abicheck.cpp",
+ ],
+ header_abi_checker: {
+ enabled: true,
+ symbol_file: "imapper.map.txt",
+ },
}
cc_library_headers {
@@ -47,6 +73,13 @@
"libbase_headers",
"libimapper_stablec",
],
+ // TODO(b/214400477) Remove apex_available
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ "test_com.android.media.swcodec",
+ ],
+ min_sdk_version: "29",
}
cc_test {
diff --git a/graphics/mapper/stable-c/imapper.map.txt b/graphics/mapper/stable-c/imapper.map.txt
new file mode 100644
index 0000000..43abd33
--- /dev/null
+++ b/graphics/mapper/stable-c/imapper.map.txt
@@ -0,0 +1,4 @@
+LIBIMAPPER { # introduced=UpsideDownCake
+ global:
+ AIMapper_loadIMapper;
+}
diff --git a/graphics/mapper/stable-c/imapper5_abicheck.cpp b/graphics/mapper/stable-c/imapper5_abicheck.cpp
new file mode 100644
index 0000000..92f7198
--- /dev/null
+++ b/graphics/mapper/stable-c/imapper5_abicheck.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/graphics/mapper/IMapper.h>
+
+AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
+ static AIMapper mapper = {AIMAPPER_VERSION_5, {}};
+ *outImplementation = &mapper;
+ return AIMAPPER_ERROR_NONE;
+}
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
index 3dba86d..0e6d3dc 100644
--- a/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
+++ b/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h
@@ -567,6 +567,8 @@
#undef DEFINE_TYPE
+#if defined(__cplusplus) && __cplusplus >= 202002L
+
template <typename F, std::size_t... I>
void invokeWithStandardMetadata(F&& f, StandardMetadataType type, std::index_sequence<I...>) {
// Setup the jump table, mapping from each type to a springboard that invokes the template
@@ -621,4 +623,6 @@
return retVal;
}
+#endif
+
} // namespace android::hardware::graphics::mapper
\ No newline at end of file
diff --git a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
index 0de88cd..75e436d 100644
--- a/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
+++ b/graphics/mapper/stable-c/include/android/hardware/graphics/mapper/IMapper.h
@@ -26,10 +26,8 @@
#pragma once
+#include <stdint.h>
#include <sys/cdefs.h>
-#include <cinttypes>
-#include <cstddef>
-#include <type_traits>
#include <android/rect.h>
#include <cutils/native_handle.h>
diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp
index 5aa820c..95a14b2 100644
--- a/input/common/aidl/Android.bp
+++ b/input/common/aidl/Android.bp
@@ -12,7 +12,6 @@
host_supported: true,
vendor_available: true,
srcs: ["android/hardware/input/common/*.aidl"],
- frozen: true,
stability: "vintf",
backend: {
cpp: {
diff --git a/media/bufferpool/aidl/Android.bp b/media/bufferpool/aidl/Android.bp
index 68ac489..b01cdbe 100644
--- a/media/bufferpool/aidl/Android.bp
+++ b/media/bufferpool/aidl/Android.bp
@@ -24,6 +24,7 @@
aidl_interface {
name: "android.hardware.media.bufferpool2",
vendor_available: true,
+ double_loadable: true,
srcs: ["android/hardware/media/bufferpool2/*.aidl"],
imports: [
"android.hardware.common-V2",
@@ -39,6 +40,11 @@
},
ndk: {
enabled: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ ],
+ min_sdk_version: "29",
},
},
}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
index 54896d4..5899a40 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -34,5 +34,10 @@
package android.hardware.media.bufferpool2;
@VintfStability
interface IClientManager {
- long registerSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
+ android.hardware.media.bufferpool2.IClientManager.Registration registerSender(in android.hardware.media.bufferpool2.IAccessor bufferPool);
+ @VintfStability
+ parcelable Registration {
+ long connectionId;
+ boolean isNew = true;
+ }
}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl
index 300fcba..844e920 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/IConnection.aidl
@@ -35,12 +35,13 @@
@VintfStability
interface IConnection {
android.hardware.media.bufferpool2.IConnection.FetchResult[] fetch(in android.hardware.media.bufferpool2.IConnection.FetchInfo[] fetchInfos);
+ void sync();
parcelable FetchInfo {
long transactionId;
int bufferId;
}
union FetchResult {
android.hardware.media.bufferpool2.Buffer buffer;
- android.hardware.media.bufferpool2.ResultStatus failure;
+ int failure;
}
}
diff --git a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl
index 7370998..4bc3889 100644
--- a/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl
+++ b/media/bufferpool/aidl/aidl_api/android.hardware.media.bufferpool2/current/android/hardware/media/bufferpool2/ResultStatus.aidl
@@ -34,7 +34,6 @@
package android.hardware.media.bufferpool2;
@VintfStability
parcelable ResultStatus {
- int resultStatus;
const int OK = 0;
const int NO_MEMORY = 1;
const int ALREADY_EXISTS = 2;
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
index bf36e25..a3054cb 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IClientManager.aidl
@@ -28,6 +28,16 @@
@VintfStability
interface IClientManager {
/**
+ * Result of registerSender.
+ */
+ @VintfStability
+ parcelable Registration {
+ /** registered connection id */
+ long connectionId;
+ /** true when the connection is new */
+ boolean isNew = true;
+ }
+ /**
* Sets up a buffer receiving communication node for the specified
* buffer pool. A manager must create a IConnection to the buffer
* pool if it does not already have a connection.
@@ -39,8 +49,7 @@
* sent to that connection during transfers.
* @throws ServiceSpecificException with one of the following values:
* ResultStatus::NO_MEMORY - Memory allocation failure occurred.
- * ResultStatus::ALREADY_EXISTS - A sender was registered already.
* ResultStatus::CRITICAL_ERROR - Other errors.
*/
- long registerSender(in IAccessor bufferPool);
+ Registration registerSender(in IAccessor bufferPool);
}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl
index d869f47..68367c7 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/IConnection.aidl
@@ -49,7 +49,7 @@
* ResultStatus::NOT_FOUND - A buffer was not found due to invalidation.
* ResultStatus::CRITICAL_ERROR - Other errors.
*/
- ResultStatus failure;
+ int failure;
}
/**
@@ -70,4 +70,12 @@
* ResultStatus::CRITICAL_ERROR - Other errors.
*/
FetchResult[] fetch(in FetchInfo[] fetchInfos);
+
+ /**
+ * Enforce processing of unprocessed bufferpool messages.
+ *
+ * BufferPool implementation optimizes message processing by piggy-backing approach.
+ * This method can ensure pending bufferpool messages being processed timely.
+ */
+ void sync();
}
diff --git a/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl b/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl
index 162f9a7..003d147 100644
--- a/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl
+++ b/media/bufferpool/aidl/android/hardware/media/bufferpool2/ResultStatus.aidl
@@ -23,6 +23,4 @@
const int ALREADY_EXISTS = 2;
const int NOT_FOUND = 3;
const int CRITICAL_ERROR = 4;
-
- int resultStatus;
}
diff --git a/media/bufferpool/aidl/default/Accessor.cpp b/media/bufferpool/aidl/default/Accessor.cpp
new file mode 100644
index 0000000..3d206ac
--- /dev/null
+++ b/media/bufferpool/aidl/default/Accessor.cpp
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "AidlBufferPoolAcc"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
+
+#include "Accessor.h"
+#include "Connection.h"
+#include "DataHelper.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+namespace {
+ static constexpr nsecs_t kEvictGranularityNs = 1000000000; // 1 sec
+ static constexpr nsecs_t kEvictDurationNs = 5000000000; // 5 secs
+}
+
+#ifdef __ANDROID_VNDK__
+static constexpr uint32_t kSeqIdVndkBit = 1U << 31;
+#else
+static constexpr uint32_t kSeqIdVndkBit = 0;
+#endif
+
+static constexpr uint32_t kSeqIdMax = 0x7fffffff;
+uint32_t Accessor::sSeqId = time(nullptr) & kSeqIdMax;
+
+namespace {
+// anonymous namespace
+static std::shared_ptr<ConnectionDeathRecipient> sConnectionDeathRecipient =
+ std::make_shared<ConnectionDeathRecipient>();
+
+void serviceDied(void *cookie) {
+ if (sConnectionDeathRecipient) {
+ sConnectionDeathRecipient->onDead(cookie);
+ }
+}
+}
+
+std::shared_ptr<ConnectionDeathRecipient> Accessor::getConnectionDeathRecipient() {
+ return sConnectionDeathRecipient;
+}
+
+ConnectionDeathRecipient::ConnectionDeathRecipient() {
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
+ AIBinder_DeathRecipient_new(serviceDied));
+}
+
+void ConnectionDeathRecipient::add(
+ int64_t connectionId,
+ const std::shared_ptr<Accessor> &accessor) {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mAccessors.find(connectionId) == mAccessors.end()) {
+ mAccessors.insert(std::make_pair(connectionId, accessor));
+ }
+}
+
+void ConnectionDeathRecipient::remove(int64_t connectionId) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mAccessors.erase(connectionId);
+ auto it = mConnectionToCookie.find(connectionId);
+ if (it != mConnectionToCookie.end()) {
+ void * cookie = it->second;
+ mConnectionToCookie.erase(it);
+ auto cit = mCookieToConnections.find(cookie);
+ if (cit != mCookieToConnections.end()) {
+ cit->second.erase(connectionId);
+ if (cit->second.size() == 0) {
+ mCookieToConnections.erase(cit);
+ }
+ }
+ }
+}
+
+void ConnectionDeathRecipient::addCookieToConnection(
+ void *cookie,
+ int64_t connectionId) {
+ std::lock_guard<std::mutex> lock(mLock);
+ if (mAccessors.find(connectionId) == mAccessors.end()) {
+ return;
+ }
+ mConnectionToCookie.insert(std::make_pair(connectionId, cookie));
+ auto it = mCookieToConnections.find(cookie);
+ if (it != mCookieToConnections.end()) {
+ it->second.insert(connectionId);
+ } else {
+ mCookieToConnections.insert(std::make_pair(
+ cookie, std::set<int64_t>{connectionId}));
+ }
+}
+
+void ConnectionDeathRecipient::onDead(void *cookie) {
+ std::map<int64_t, const std::weak_ptr<Accessor>> connectionsToClose;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+
+ auto it = mCookieToConnections.find(cookie);
+ if (it != mCookieToConnections.end()) {
+ for (auto conIt = it->second.begin(); conIt != it->second.end(); ++conIt) {
+ auto accessorIt = mAccessors.find(*conIt);
+ if (accessorIt != mAccessors.end()) {
+ connectionsToClose.insert(std::make_pair(*conIt, accessorIt->second));
+ mAccessors.erase(accessorIt);
+ }
+ mConnectionToCookie.erase(*conIt);
+ }
+ mCookieToConnections.erase(it);
+ }
+ }
+
+ if (connectionsToClose.size() > 0) {
+ std::shared_ptr<Accessor> accessor;
+ for (auto it = connectionsToClose.begin(); it != connectionsToClose.end(); ++it) {
+ accessor = it->second.lock();
+
+ if (accessor) {
+ accessor->close(it->first);
+ ALOGD("connection %lld closed on death", (long long)it->first);
+ }
+ }
+ }
+}
+
+AIBinder_DeathRecipient *ConnectionDeathRecipient::getRecipient() {
+ return mDeathRecipient.get();
+}
+
+::ndk::ScopedAStatus Accessor::connect(const std::shared_ptr<::aidl::android::hardware::media::bufferpool2::IObserver>& in_observer, ::aidl::android::hardware::media::bufferpool2::IAccessor::ConnectionInfo* _aidl_return) {
+ std::shared_ptr<Connection> connection;
+ ConnectionId connectionId;
+ uint32_t msgId;
+ StatusDescriptor statusDesc;
+ InvalidationDescriptor invDesc;
+ BufferPoolStatus status = connect(
+ in_observer, false, &connection, &connectionId, &msgId, &statusDesc, &invDesc);
+ if (status == ResultStatus::OK) {
+ _aidl_return->connection = connection;
+ _aidl_return->connectionId = connectionId;
+ _aidl_return->msgId = msgId;
+ _aidl_return->toFmqDesc = std::move(statusDesc);
+ _aidl_return->fromFmqDesc = std::move(invDesc);
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
+}
+
+Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
+ : mAllocator(allocator), mScheduleEvictTs(0) {}
+
+Accessor::~Accessor() {
+}
+
+bool Accessor::isValid() {
+ return mBufferPool.isValid();
+}
+
+BufferPoolStatus Accessor::flush() {
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ mBufferPool.processStatusMessages();
+ mBufferPool.flush(ref<Accessor>());
+ return ResultStatus::OK;
+}
+
+BufferPoolStatus Accessor::allocate(
+ ConnectionId connectionId,
+ const std::vector<uint8_t> ¶ms,
+ BufferId *bufferId, const native_handle_t** handle) {
+ std::unique_lock<std::mutex> lock(mBufferPool.mMutex);
+ mBufferPool.processStatusMessages();
+ BufferPoolStatus status = ResultStatus::OK;
+ if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
+ lock.unlock();
+ std::shared_ptr<BufferPoolAllocation> alloc;
+ size_t allocSize;
+ status = mAllocator->allocate(params, &alloc, &allocSize);
+ lock.lock();
+ if (status == ResultStatus::OK) {
+ status = mBufferPool.addNewBuffer(alloc, allocSize, params, bufferId, handle);
+ }
+ ALOGV("create a buffer %d : %u %p",
+ status == ResultStatus::OK, *bufferId, *handle);
+ }
+ if (status == ResultStatus::OK) {
+ // TODO: handle ownBuffer failure
+ mBufferPool.handleOwnBuffer(connectionId, *bufferId);
+ }
+ mBufferPool.cleanUp();
+ scheduleEvictIfNeeded();
+ return status;
+}
+
+BufferPoolStatus Accessor::fetch(
+ ConnectionId connectionId, TransactionId transactionId,
+ BufferId bufferId, const native_handle_t** handle) {
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ mBufferPool.processStatusMessages();
+ auto found = mBufferPool.mTransactions.find(transactionId);
+ if (found != mBufferPool.mTransactions.end() &&
+ contains(&mBufferPool.mPendingTransactions,
+ connectionId, transactionId)) {
+ if (found->second->mSenderValidated &&
+ found->second->mStatus == BufferStatus::TRANSFER_FROM &&
+ found->second->mBufferId == bufferId) {
+ found->second->mStatus = BufferStatus::TRANSFER_FETCH;
+ auto bufferIt = mBufferPool.mBuffers.find(bufferId);
+ if (bufferIt != mBufferPool.mBuffers.end()) {
+ mBufferPool.mStats.onBufferFetched();
+ *handle = bufferIt->second->handle();
+ return ResultStatus::OK;
+ }
+ }
+ }
+ mBufferPool.cleanUp();
+ scheduleEvictIfNeeded();
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus Accessor::connect(
+ const std::shared_ptr<IObserver> &observer, bool local,
+ std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
+ uint32_t *pMsgId,
+ StatusDescriptor* statusDescPtr,
+ InvalidationDescriptor* invDescPtr) {
+ std::shared_ptr<Connection> newConnection = ::ndk::SharedRefBase::make<Connection>();
+ BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+ {
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ if (newConnection) {
+ int32_t pid = getpid();
+ ConnectionId id = (int64_t)pid << 32 | sSeqId | kSeqIdVndkBit;
+ status = mBufferPool.mObserver.open(id, statusDescPtr);
+ if (status == ResultStatus::OK) {
+ newConnection->initialize(ref<Accessor>(), id);
+ *connection = newConnection;
+ *pConnectionId = id;
+ *pMsgId = mBufferPool.mInvalidation.mInvalidationId;
+ mBufferPool.mConnectionIds.insert(id);
+ mBufferPool.mInvalidationChannel.getDesc(invDescPtr);
+ mBufferPool.mInvalidation.onConnect(id, observer);
+ if (sSeqId == kSeqIdMax) {
+ sSeqId = 0;
+ } else {
+ ++sSeqId;
+ }
+ }
+
+ }
+ mBufferPool.processStatusMessages();
+ mBufferPool.cleanUp();
+ scheduleEvictIfNeeded();
+ }
+ if (!local && status == ResultStatus::OK) {
+ std::shared_ptr<Accessor> accessor(ref<Accessor>());
+ sConnectionDeathRecipient->add(*pConnectionId, accessor);
+ }
+ return status;
+}
+
+BufferPoolStatus Accessor::close(ConnectionId connectionId) {
+ {
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ ALOGV("connection close %lld: %u", (long long)connectionId, mBufferPool.mInvalidation.mId);
+ mBufferPool.processStatusMessages();
+ mBufferPool.handleClose(connectionId);
+ mBufferPool.mObserver.close(connectionId);
+ mBufferPool.mInvalidation.onClose(connectionId);
+ // Since close# will be called after all works are finished, it is OK to
+ // evict unused buffers.
+ mBufferPool.cleanUp(true);
+ scheduleEvictIfNeeded();
+ }
+ sConnectionDeathRecipient->remove(connectionId);
+ return ResultStatus::OK;
+}
+
+void Accessor::cleanUp(bool clearCache) {
+ // transaction timeout, buffer caching TTL handling
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ mBufferPool.processStatusMessages();
+ mBufferPool.cleanUp(clearCache);
+}
+
+void Accessor::handleInvalidateAck() {
+ std::map<ConnectionId, const std::shared_ptr<IObserver>> observers;
+ uint32_t invalidationId;
+ {
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ mBufferPool.processStatusMessages();
+ mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
+ }
+ // Do not hold lock for send invalidations
+ size_t deadClients = 0;
+ for (auto it = observers.begin(); it != observers.end(); ++it) {
+ const std::shared_ptr<IObserver> observer = it->second;
+ if (observer) {
+ ::ndk::ScopedAStatus status = observer->onMessage(it->first, invalidationId);
+ if (!status.isOk()) {
+ ++deadClients;
+ }
+ }
+ }
+ if (deadClients > 0) {
+ ALOGD("During invalidation found %zu dead clients", deadClients);
+ }
+}
+
+void Accessor::invalidatorThread(
+ std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
+ std::mutex &mutex,
+ std::condition_variable &cv,
+ bool &ready) {
+ constexpr uint32_t NUM_SPIN_TO_INCREASE_SLEEP = 1024;
+ constexpr uint32_t NUM_SPIN_TO_LOG = 1024*8;
+ constexpr useconds_t MAX_SLEEP_US = 10000;
+ uint32_t numSpin = 0;
+ useconds_t sleepUs = 1;
+
+ while(true) {
+ std::map<uint32_t, const std::weak_ptr<Accessor>> copied;
+ {
+ std::unique_lock<std::mutex> lock(mutex);
+ while (!ready) {
+ numSpin = 0;
+ sleepUs = 1;
+ cv.wait(lock);
+ }
+ copied.insert(accessors.begin(), accessors.end());
+ }
+ std::list<ConnectionId> erased;
+ for (auto it = copied.begin(); it != copied.end(); ++it) {
+ const std::shared_ptr<Accessor> acc = it->second.lock();
+ if (!acc) {
+ erased.push_back(it->first);
+ } else {
+ acc->handleInvalidateAck();
+ }
+ }
+ {
+ std::unique_lock<std::mutex> lock(mutex);
+ for (auto it = erased.begin(); it != erased.end(); ++it) {
+ accessors.erase(*it);
+ }
+ if (accessors.size() == 0) {
+ ready = false;
+ } else {
+ // N.B. Since there is not a efficient way to wait over FMQ,
+ // polling over the FMQ is the current way to prevent draining
+ // CPU.
+ lock.unlock();
+ ++numSpin;
+ if (numSpin % NUM_SPIN_TO_INCREASE_SLEEP == 0 &&
+ sleepUs < MAX_SLEEP_US) {
+ sleepUs *= 10;
+ }
+ if (numSpin % NUM_SPIN_TO_LOG == 0) {
+ ALOGW("invalidator thread spinning");
+ }
+ ::usleep(sleepUs);
+ }
+ }
+ }
+}
+
+Accessor::AccessorInvalidator::AccessorInvalidator() : mReady(false) {
+ std::thread invalidator(
+ invalidatorThread,
+ std::ref(mAccessors),
+ std::ref(mMutex),
+ std::ref(mCv),
+ std::ref(mReady));
+ invalidator.detach();
+}
+
+void Accessor::AccessorInvalidator::addAccessor(
+ uint32_t accessorId, const std::weak_ptr<Accessor> &accessor) {
+ bool notify = false;
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (mAccessors.find(accessorId) == mAccessors.end()) {
+ if (!mReady) {
+ mReady = true;
+ notify = true;
+ }
+ mAccessors.emplace(accessorId, accessor);
+ ALOGV("buffer invalidation added bp:%u %d", accessorId, notify);
+ }
+ lock.unlock();
+ if (notify) {
+ mCv.notify_one();
+ }
+}
+
+void Accessor::AccessorInvalidator::delAccessor(uint32_t accessorId) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mAccessors.erase(accessorId);
+ ALOGV("buffer invalidation deleted bp:%u", accessorId);
+ if (mAccessors.size() == 0) {
+ mReady = false;
+ }
+}
+
+std::unique_ptr<Accessor::AccessorInvalidator> Accessor::sInvalidator;
+
+void Accessor::createInvalidator() {
+ if (!sInvalidator) {
+ sInvalidator = std::make_unique<Accessor::AccessorInvalidator>();
+ }
+}
+
+void Accessor::evictorThread(
+ std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
+ std::mutex &mutex,
+ std::condition_variable &cv) {
+ std::list<const std::weak_ptr<Accessor>> evictList;
+ while (true) {
+ int expired = 0;
+ int evicted = 0;
+ {
+ nsecs_t now = systemTime();
+ std::unique_lock<std::mutex> lock(mutex);
+ while (accessors.size() == 0) {
+ cv.wait(lock);
+ }
+ auto it = accessors.begin();
+ while (it != accessors.end()) {
+ if (now > (it->second + kEvictDurationNs)) {
+ ++expired;
+ evictList.push_back(it->first);
+ it = accessors.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+ // evict idle accessors;
+ for (auto it = evictList.begin(); it != evictList.end(); ++it) {
+ const std::shared_ptr<Accessor> accessor = it->lock();
+ if (accessor) {
+ accessor->cleanUp(true);
+ ++evicted;
+ }
+ }
+ if (expired > 0) {
+ ALOGD("evictor expired: %d, evicted: %d", expired, evicted);
+ }
+ evictList.clear();
+ ::usleep(kEvictGranularityNs / 1000);
+ }
+}
+
+Accessor::AccessorEvictor::AccessorEvictor() {
+ std::thread evictor(
+ evictorThread,
+ std::ref(mAccessors),
+ std::ref(mMutex),
+ std::ref(mCv));
+ evictor.detach();
+}
+
+void Accessor::AccessorEvictor::addAccessor(
+ const std::weak_ptr<Accessor> &accessor, nsecs_t ts) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ bool notify = mAccessors.empty();
+ auto it = mAccessors.find(accessor);
+ if (it == mAccessors.end()) {
+ mAccessors.emplace(accessor, ts);
+ } else {
+ it->second = ts;
+ }
+ if (notify) {
+ mCv.notify_one();
+ }
+}
+
+std::unique_ptr<Accessor::AccessorEvictor> Accessor::sEvictor;
+
+void Accessor::createEvictor() {
+ if (!sEvictor) {
+ sEvictor = std::make_unique<Accessor::AccessorEvictor>();
+ }
+}
+
+void Accessor::scheduleEvictIfNeeded() {
+ nsecs_t now = systemTime();
+
+ if (now > (mScheduleEvictTs + kEvictGranularityNs)) {
+ mScheduleEvictTs = now;
+ sEvictor->addAccessor(ref<Accessor>(), now);
+ }
+}
+
+} // namespace aidl::android::hardware::media::bufferpool2::implemntation {
diff --git a/media/bufferpool/aidl/default/Accessor.h b/media/bufferpool/aidl/default/Accessor.h
new file mode 100644
index 0000000..85e2fa7
--- /dev/null
+++ b/media/bufferpool/aidl/default/Accessor.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/BnAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+#include <memory>
+#include <map>
+#include <set>
+#include <condition_variable>
+
+#include "BufferPool.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+struct Connection;
+using ::aidl::android::hardware::media::bufferpool2::IObserver;
+using ::aidl::android::hardware::media::bufferpool2::IAccessor;
+
+/**
+ * Receives death notifications from remote connections.
+ * On death notifications, the connections are closed and used resources
+ * are released.
+ */
+struct ConnectionDeathRecipient {
+ ConnectionDeathRecipient();
+ /**
+ * Registers a newly connected connection from remote processes.
+ */
+ void add(int64_t connectionId, const std::shared_ptr<Accessor> &accessor);
+
+ /**
+ * Removes a connection.
+ */
+ void remove(int64_t connectionId);
+
+ void addCookieToConnection(void *cookie, int64_t connectionId);
+
+ void onDead(void *cookie);
+
+ AIBinder_DeathRecipient *getRecipient();
+
+private:
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+ std::mutex mLock;
+ std::map<void *, std::set<int64_t>> mCookieToConnections;
+ std::map<int64_t, void *> mConnectionToCookie;
+ std::map<int64_t, const std::weak_ptr<Accessor>> mAccessors;
+};
+
+/**
+ * A buffer pool accessor which enables a buffer pool to communicate with buffer
+ * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
+ */
+struct Accessor : public BnAccessor {
+ // Methods from ::aidl::android::hardware::media::bufferpool2::IAccessor.
+ ::ndk::ScopedAStatus connect(const std::shared_ptr<IObserver>& in_observer,
+ IAccessor::ConnectionInfo* _aidl_return) override;
+
+ /**
+ * Creates a buffer pool accessor which uses the specified allocator.
+ *
+ * @param allocator buffer allocator.
+ */
+ explicit Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator);
+
+ /** Destructs a buffer pool accessor. */
+ ~Accessor();
+
+ /** Returns whether the accessor is valid. */
+ bool isValid();
+
+ /** Invalidates all buffers which are owned by bufferpool */
+ BufferPoolStatus flush();
+
+ /** Allocates a buffer from a buffer pool.
+ *
+ * @param connectionId the connection id of the client.
+ * @param params the allocation parameters.
+ * @param bufferId the id of the allocated buffer.
+ * @param handle the native handle of the allocated buffer.
+ *
+ * @return OK when a buffer is successfully allocated.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus allocate(
+ ConnectionId connectionId,
+ const std::vector<uint8_t>& params,
+ BufferId *bufferId,
+ const native_handle_t** handle);
+
+ /**
+ * Fetches a buffer for the specified transaction.
+ *
+ * @param connectionId the id of receiving connection(client).
+ * @param transactionId the id of the transfer transaction.
+ * @param bufferId the id of the buffer to be fetched.
+ * @param handle the native handle of the fetched buffer.
+ *
+ * @return OK when a buffer is successfully fetched.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus fetch(
+ ConnectionId connectionId,
+ TransactionId transactionId,
+ BufferId bufferId,
+ const native_handle_t** handle);
+
+ /**
+ * Makes a connection to the buffer pool. The buffer pool client uses the
+ * created connection in order to communicate with the buffer pool. An
+ * FMQ for buffer status message is also created for the client.
+ *
+ * @param observer client observer for buffer invalidation
+ * @param local true when a connection request comes from local process,
+ * false otherwise.
+ * @param connection created connection
+ * @param pConnectionId the id of the created connection
+ * @param pMsgId the id of the recent buffer pool message
+ * @param statusDescPtr FMQ descriptor for shared buffer status message
+ * queue between a buffer pool and the client.
+ * @param invDescPtr FMQ descriptor for buffer invalidation message
+ * queue from a buffer pool to the client.
+ *
+ * @return OK when a connection is successfully made.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus connect(
+ const std::shared_ptr<IObserver>& observer,
+ bool local,
+ std::shared_ptr<Connection> *connection, ConnectionId *pConnectionId,
+ uint32_t *pMsgId,
+ StatusDescriptor* statusDescPtr,
+ InvalidationDescriptor* invDescPtr);
+
+ /**
+ * Closes the specified connection to the client.
+ *
+ * @param connectionId the id of the connection.
+ *
+ * @return OK when the connection is closed.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus close(ConnectionId connectionId);
+
+ /**
+ * Processes pending buffer status messages and performs periodic cache
+ * cleaning.
+ *
+ * @param clearCache if clearCache is true, it frees all buffers waiting
+ * to be recycled.
+ */
+ void cleanUp(bool clearCache);
+
+ /**
+ * ACK on buffer invalidation messages
+ */
+ void handleInvalidateAck();
+
+ /**
+ * Gets a death_recipient for remote connection death.
+ */
+ static std::shared_ptr<ConnectionDeathRecipient> getConnectionDeathRecipient();
+
+ static void createInvalidator();
+
+ static void createEvictor();
+
+private:
+ // ConnectionId = pid : (timestamp_created + seqId)
+ // in order to guarantee uniqueness for each connection
+ static uint32_t sSeqId;
+
+ const std::shared_ptr<BufferPoolAllocator> mAllocator;
+ nsecs_t mScheduleEvictTs;
+ BufferPool mBufferPool;
+
+ struct AccessorInvalidator {
+ std::map<uint32_t, const std::weak_ptr<Accessor>> mAccessors;
+ std::mutex mMutex;
+ std::condition_variable mCv;
+ bool mReady;
+
+ AccessorInvalidator();
+ void addAccessor(uint32_t accessorId, const std::weak_ptr<Accessor> &accessor);
+ void delAccessor(uint32_t accessorId);
+ };
+
+ static std::unique_ptr<AccessorInvalidator> sInvalidator;
+
+ static void invalidatorThread(
+ std::map<uint32_t, const std::weak_ptr<Accessor>> &accessors,
+ std::mutex &mutex,
+ std::condition_variable &cv,
+ bool &ready);
+
+ struct AccessorEvictor {
+ std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> mAccessors;
+ std::mutex mMutex;
+ std::condition_variable mCv;
+
+ AccessorEvictor();
+ void addAccessor(const std::weak_ptr<Accessor> &accessor, nsecs_t ts);
+ };
+
+ static std::unique_ptr<AccessorEvictor> sEvictor;
+
+ static void evictorThread(
+ std::map<const std::weak_ptr<Accessor>, nsecs_t, std::owner_less<>> &accessors,
+ std::mutex &mutex,
+ std::condition_variable &cv);
+
+ void scheduleEvictIfNeeded();
+
+ friend struct BufferPool;
+};
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Android.bp b/media/bufferpool/aidl/default/Android.bp
new file mode 100644
index 0000000..11a6163
--- /dev/null
+++ b/media/bufferpool/aidl/default/Android.bp
@@ -0,0 +1,50 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+ name: "libstagefright_aidl_bufferpool2",
+ vendor_available: true,
+ min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media.swcodec",
+ "test_com.android.media.swcodec",
+ ],
+ srcs: [
+ "Accessor.cpp",
+ "BufferPool.cpp",
+ "BufferPoolClient.cpp",
+ "BufferStatus.cpp",
+ "ClientManager.cpp",
+ "Connection.cpp",
+ "Observer.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libcutils",
+ "libfmq",
+ "liblog",
+ "libutils",
+ "android.hardware.media.bufferpool2-V1-ndk",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ ],
+ export_shared_lib_headers: [
+ "libfmq",
+ "android.hardware.media.bufferpool2-V1-ndk",
+ ],
+ double_loadable: true,
+ cflags: [
+ "-DBUFFERPOOL_CLONE_HANDLES",
+ ],
+}
diff --git a/media/bufferpool/aidl/default/BufferPool.cpp b/media/bufferpool/aidl/default/BufferPool.cpp
new file mode 100644
index 0000000..ed4574f
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPool.cpp
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlBufferPool"
+//#define LOG_NDEBUG 0
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Log.h>
+#include <thread>
+#include "Accessor.h"
+#include "BufferPool.h"
+#include "Connection.h"
+#include "DataHelper.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+namespace {
+ static constexpr int64_t kCleanUpDurationMs = 500; // 0.5 sec
+ static constexpr int64_t kLogDurationMs = 5000; // 5 secs
+
+ static constexpr size_t kMinAllocBytesForEviction = 1024*1024*15;
+ static constexpr size_t kMinBufferCountForEviction = 25;
+ static constexpr size_t kMaxUnusedBufferCount = 64;
+ static constexpr size_t kUnusedBufferCountTarget = kMaxUnusedBufferCount - 16;
+}
+
+BufferPool::BufferPool()
+ : mTimestampMs(::android::elapsedRealtime()),
+ mLastCleanUpMs(mTimestampMs),
+ mLastLogMs(mTimestampMs),
+ mSeq(0),
+ mStartSeq(0) {
+ mValid = mInvalidationChannel.isValid();
+}
+
+
+// Statistics helper
+template<typename T, typename S>
+int percentage(T base, S total) {
+ return int(total ? 0.5 + 100. * static_cast<S>(base) / total : 0);
+}
+
+std::atomic<std::uint32_t> BufferPool::Invalidation::sInvSeqId(0);
+
+BufferPool::~BufferPool() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ ALOGD("Destruction - bufferpool2 %p "
+ "cached: %zu/%zuM, %zu/%d%% in use; "
+ "allocs: %zu, %d%% recycled; "
+ "transfers: %zu, %d%% unfetched",
+ this, mStats.mBuffersCached, mStats.mSizeCached >> 20,
+ mStats.mBuffersInUse, percentage(mStats.mBuffersInUse, mStats.mBuffersCached),
+ mStats.mTotalAllocations, percentage(mStats.mTotalRecycles, mStats.mTotalAllocations),
+ mStats.mTotalTransfers,
+ percentage(mStats.mTotalTransfers - mStats.mTotalFetches, mStats.mTotalTransfers));
+}
+
+void BufferPool::Invalidation::onConnect(
+ ConnectionId conId, const std::shared_ptr<IObserver>& observer) {
+ mAcks[conId] = mInvalidationId; // starts from current invalidationId
+ mObservers.insert(std::make_pair(conId, observer));
+}
+
+void BufferPool::Invalidation::onClose(ConnectionId conId) {
+ mAcks.erase(conId);
+ mObservers.erase(conId);
+}
+
+void BufferPool::Invalidation::onAck(
+ ConnectionId conId,
+ uint32_t msgId) {
+ auto it = mAcks.find(conId);
+ if (it == mAcks.end()) {
+ ALOGW("ACK from inconsistent connection! %lld", (long long)conId);
+ return;
+ }
+ if (isMessageLater(msgId, it->second)) {
+ mAcks[conId] = msgId;
+ }
+}
+
+void BufferPool::Invalidation::onBufferInvalidated(
+ BufferId bufferId,
+ BufferInvalidationChannel &channel) {
+ for (auto it = mPendings.begin(); it != mPendings.end();) {
+ if (it->isInvalidated(bufferId)) {
+ uint32_t msgId = 0;
+ if (it->mNeedsAck) {
+ msgId = ++mInvalidationId;
+ if (msgId == 0) {
+ // wrap happens
+ msgId = ++mInvalidationId;
+ }
+ }
+ channel.postInvalidation(msgId, it->mFrom, it->mTo);
+ it = mPendings.erase(it);
+ continue;
+ }
+ ++it;
+ }
+}
+
+void BufferPool::Invalidation::onInvalidationRequest(
+ bool needsAck,
+ uint32_t from,
+ uint32_t to,
+ size_t left,
+ BufferInvalidationChannel &channel,
+ const std::shared_ptr<Accessor> &impl) {
+ uint32_t msgId = 0;
+ if (needsAck) {
+ msgId = ++mInvalidationId;
+ if (msgId == 0) {
+ // wrap happens
+ msgId = ++mInvalidationId;
+ }
+ }
+ ALOGV("bufferpool2 invalidation requested and queued");
+ if (left == 0) {
+ channel.postInvalidation(msgId, from, to);
+ } else {
+ ALOGV("bufferpoo2 invalidation requested and pending");
+ Pending pending(needsAck, from, to, left, impl);
+ mPendings.push_back(pending);
+ }
+ Accessor::sInvalidator->addAccessor(mId, impl);
+}
+
+void BufferPool::Invalidation::onHandleAck(
+ std::map<ConnectionId, const std::shared_ptr<IObserver>> *observers,
+ uint32_t *invalidationId) {
+ if (mInvalidationId != 0) {
+ *invalidationId = mInvalidationId;
+ std::set<int> deads;
+ for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
+ if (it->second != mInvalidationId) {
+ const std::shared_ptr<IObserver> observer = mObservers[it->first];
+ if (observer) {
+ observers->emplace(it->first, observer);
+ ALOGV("connection %lld will call observer (%u: %u)",
+ (long long)it->first, it->second, mInvalidationId);
+ // N.B: onMessage will be called later. ignore possibility of
+ // onMessage# oneway call being lost.
+ it->second = mInvalidationId;
+ } else {
+ ALOGV("bufferpool2 observer died %lld", (long long)it->first);
+ deads.insert(it->first);
+ }
+ }
+ }
+ if (deads.size() > 0) {
+ for (auto it = deads.begin(); it != deads.end(); ++it) {
+ onClose(*it);
+ }
+ }
+ }
+ if (mPendings.size() == 0) {
+ // All invalidation Ids are synced and no more pending invalidations.
+ Accessor::sInvalidator->delAccessor(mId);
+ }
+}
+
+bool BufferPool::handleOwnBuffer(
+ ConnectionId connectionId, BufferId bufferId) {
+
+ bool added = insert(&mUsingBuffers, connectionId, bufferId);
+ if (added) {
+ auto iter = mBuffers.find(bufferId);
+ iter->second->mOwnerCount++;
+ }
+ insert(&mUsingConnections, bufferId, connectionId);
+ return added;
+}
+
+bool BufferPool::handleReleaseBuffer(
+ ConnectionId connectionId, BufferId bufferId) {
+ bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
+ if (deleted) {
+ auto iter = mBuffers.find(bufferId);
+ iter->second->mOwnerCount--;
+ if (iter->second->mOwnerCount == 0 &&
+ iter->second->mTransactionCount == 0) {
+ if (!iter->second->mInvalidated) {
+ mStats.onBufferUnused(iter->second->mAllocSize);
+ mFreeBuffers.insert(bufferId);
+ } else {
+ mStats.onBufferUnused(iter->second->mAllocSize);
+ mStats.onBufferEvicted(iter->second->mAllocSize);
+ mBuffers.erase(iter);
+ mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+ }
+ }
+ }
+ erase(&mUsingConnections, bufferId, connectionId);
+ ALOGV("release buffer %u : %d", bufferId, deleted);
+ return deleted;
+}
+
+bool BufferPool::handleTransferTo(const BufferStatusMessage &message) {
+ auto completed = mCompletedTransactions.find(
+ message.transactionId);
+ if (completed != mCompletedTransactions.end()) {
+ // already completed
+ mCompletedTransactions.erase(completed);
+ return true;
+ }
+ // the buffer should exist and be owned.
+ auto bufferIter = mBuffers.find(message.bufferId);
+ if (bufferIter == mBuffers.end() ||
+ !contains(&mUsingBuffers, message.connectionId, FromAidl(message.bufferId))) {
+ return false;
+ }
+ auto found = mTransactions.find(message.transactionId);
+ if (found != mTransactions.end()) {
+ // transfer_from was received earlier.
+ found->second->mSender = message.connectionId;
+ found->second->mSenderValidated = true;
+ return true;
+ }
+ if (mConnectionIds.find(message.targetConnectionId) == mConnectionIds.end()) {
+ // N.B: it could be fake or receive connection already closed.
+ ALOGD("bufferpool2 %p receiver connection %lld is no longer valid",
+ this, (long long)message.targetConnectionId);
+ return false;
+ }
+ mStats.onBufferSent();
+ mTransactions.insert(std::make_pair(
+ message.transactionId,
+ std::make_unique<TransactionStatus>(message, mTimestampMs)));
+ insert(&mPendingTransactions, message.targetConnectionId,
+ FromAidl(message.transactionId));
+ bufferIter->second->mTransactionCount++;
+ return true;
+}
+
+bool BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
+ auto found = mTransactions.find(message.transactionId);
+ if (found == mTransactions.end()) {
+ // TODO: is it feasible to check ownership here?
+ mStats.onBufferSent();
+ mTransactions.insert(std::make_pair(
+ message.transactionId,
+ std::make_unique<TransactionStatus>(message, mTimestampMs)));
+ insert(&mPendingTransactions, message.connectionId,
+ FromAidl(message.transactionId));
+ auto bufferIter = mBuffers.find(message.bufferId);
+ bufferIter->second->mTransactionCount++;
+ } else {
+ if (message.connectionId == found->second->mReceiver) {
+ found->second->mStatus = BufferStatus::TRANSFER_FROM;
+ }
+ }
+ return true;
+}
+
+bool BufferPool::handleTransferResult(const BufferStatusMessage &message) {
+ auto found = mTransactions.find(message.transactionId);
+ if (found != mTransactions.end()) {
+ bool deleted = erase(&mPendingTransactions, message.connectionId,
+ FromAidl(message.transactionId));
+ if (deleted) {
+ if (!found->second->mSenderValidated) {
+ mCompletedTransactions.insert(message.transactionId);
+ }
+ auto bufferIter = mBuffers.find(message.bufferId);
+ if (message.status == BufferStatus::TRANSFER_OK) {
+ handleOwnBuffer(message.connectionId, message.bufferId);
+ }
+ bufferIter->second->mTransactionCount--;
+ if (bufferIter->second->mOwnerCount == 0
+ && bufferIter->second->mTransactionCount == 0) {
+ if (!bufferIter->second->mInvalidated) {
+ mStats.onBufferUnused(bufferIter->second->mAllocSize);
+ mFreeBuffers.insert(message.bufferId);
+ } else {
+ mStats.onBufferUnused(bufferIter->second->mAllocSize);
+ mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+ mBuffers.erase(bufferIter);
+ mInvalidation.onBufferInvalidated(message.bufferId, mInvalidationChannel);
+ }
+ }
+ mTransactions.erase(found);
+ }
+ ALOGV("transfer finished %llu %u - %d", (unsigned long long)message.transactionId,
+ message.bufferId, deleted);
+ return deleted;
+ }
+ ALOGV("transfer not found %llu %u", (unsigned long long)message.transactionId,
+ message.bufferId);
+ return false;
+}
+
+void BufferPool::processStatusMessages() {
+ std::vector<BufferStatusMessage> messages;
+ mObserver.getBufferStatusChanges(messages);
+ mTimestampMs = ::android::elapsedRealtime();
+ for (BufferStatusMessage& message: messages) {
+ bool ret = false;
+ switch (message.status) {
+ case BufferStatus::NOT_USED:
+ ret = handleReleaseBuffer(
+ message.connectionId, message.bufferId);
+ break;
+ case BufferStatus::USED:
+ // not happening
+ break;
+ case BufferStatus::TRANSFER_TO:
+ ret = handleTransferTo(message);
+ break;
+ case BufferStatus::TRANSFER_FROM:
+ ret = handleTransferFrom(message);
+ break;
+ case BufferStatus::TRANSFER_TIMEOUT:
+ // TODO
+ break;
+ case BufferStatus::TRANSFER_LOST:
+ // TODO
+ break;
+ case BufferStatus::TRANSFER_FETCH:
+ // not happening
+ break;
+ case BufferStatus::TRANSFER_OK:
+ case BufferStatus::TRANSFER_ERROR:
+ ret = handleTransferResult(message);
+ break;
+ case BufferStatus::INVALIDATION_ACK:
+ mInvalidation.onAck(message.connectionId, message.bufferId);
+ ret = true;
+ break;
+ }
+ if (ret == false) {
+ ALOGW("buffer status message processing failure - message : %d connection : %lld",
+ message.status, (long long)message.connectionId);
+ }
+ }
+ messages.clear();
+}
+
+bool BufferPool::handleClose(ConnectionId connectionId) {
+ // Cleaning buffers
+ auto buffers = mUsingBuffers.find(connectionId);
+ if (buffers != mUsingBuffers.end()) {
+ for (const BufferId& bufferId : buffers->second) {
+ bool deleted = erase(&mUsingConnections, bufferId, connectionId);
+ if (deleted) {
+ auto bufferIter = mBuffers.find(bufferId);
+ bufferIter->second->mOwnerCount--;
+ if (bufferIter->second->mOwnerCount == 0 &&
+ bufferIter->second->mTransactionCount == 0) {
+ // TODO: handle freebuffer insert fail
+ if (!bufferIter->second->mInvalidated) {
+ mStats.onBufferUnused(bufferIter->second->mAllocSize);
+ mFreeBuffers.insert(bufferId);
+ } else {
+ mStats.onBufferUnused(bufferIter->second->mAllocSize);
+ mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+ mBuffers.erase(bufferIter);
+ mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+ }
+ }
+ }
+ }
+ mUsingBuffers.erase(buffers);
+ }
+
+ // Cleaning transactions
+ auto pending = mPendingTransactions.find(connectionId);
+ if (pending != mPendingTransactions.end()) {
+ for (const TransactionId& transactionId : pending->second) {
+ auto iter = mTransactions.find(transactionId);
+ if (iter != mTransactions.end()) {
+ if (!iter->second->mSenderValidated) {
+ mCompletedTransactions.insert(transactionId);
+ }
+ BufferId bufferId = iter->second->mBufferId;
+ auto bufferIter = mBuffers.find(bufferId);
+ bufferIter->second->mTransactionCount--;
+ if (bufferIter->second->mOwnerCount == 0 &&
+ bufferIter->second->mTransactionCount == 0) {
+ // TODO: handle freebuffer insert fail
+ if (!bufferIter->second->mInvalidated) {
+ mStats.onBufferUnused(bufferIter->second->mAllocSize);
+ mFreeBuffers.insert(bufferId);
+ } else {
+ mStats.onBufferUnused(bufferIter->second->mAllocSize);
+ mStats.onBufferEvicted(bufferIter->second->mAllocSize);
+ mBuffers.erase(bufferIter);
+ mInvalidation.onBufferInvalidated(bufferId, mInvalidationChannel);
+ }
+ }
+ mTransactions.erase(iter);
+ }
+ }
+ }
+ mConnectionIds.erase(connectionId);
+ return true;
+}
+
+bool BufferPool::getFreeBuffer(
+ const std::shared_ptr<BufferPoolAllocator> &allocator,
+ const std::vector<uint8_t> ¶ms, BufferId *pId,
+ const native_handle_t** handle) {
+ auto bufferIt = mFreeBuffers.begin();
+ for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
+ BufferId bufferId = *bufferIt;
+ if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
+ break;
+ }
+ }
+ if (bufferIt != mFreeBuffers.end()) {
+ BufferId id = *bufferIt;
+ mFreeBuffers.erase(bufferIt);
+ mStats.onBufferRecycled(mBuffers[id]->mAllocSize);
+ *handle = mBuffers[id]->handle();
+ *pId = id;
+ ALOGV("recycle a buffer %u %p", id, *handle);
+ return true;
+ }
+ return false;
+}
+
+BufferPoolStatus BufferPool::addNewBuffer(
+ const std::shared_ptr<BufferPoolAllocation> &alloc,
+ const size_t allocSize,
+ const std::vector<uint8_t> ¶ms,
+ BufferId *pId,
+ const native_handle_t** handle) {
+
+ BufferId bufferId = mSeq++;
+ if (mSeq == Connection::SYNC_BUFFERID) {
+ mSeq = 0;
+ }
+ std::unique_ptr<InternalBuffer> buffer =
+ std::make_unique<InternalBuffer>(
+ bufferId, alloc, allocSize, params);
+ if (buffer) {
+ auto res = mBuffers.insert(std::make_pair(
+ bufferId, std::move(buffer)));
+ if (res.second) {
+ mStats.onBufferAllocated(allocSize);
+ *handle = alloc->handle();
+ *pId = bufferId;
+ return ResultStatus::OK;
+ }
+ }
+ return ResultStatus::NO_MEMORY;
+}
+
+void BufferPool::cleanUp(bool clearCache) {
+ if (clearCache || mTimestampMs > mLastCleanUpMs + kCleanUpDurationMs ||
+ mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
+ mLastCleanUpMs = mTimestampMs;
+ if (mTimestampMs > mLastLogMs + kLogDurationMs ||
+ mStats.buffersNotInUse() > kMaxUnusedBufferCount) {
+ mLastLogMs = mTimestampMs;
+ ALOGD("bufferpool2 %p : %zu(%zu size) total buffers - "
+ "%zu(%zu size) used buffers - %zu/%zu (recycle/alloc) - "
+ "%zu/%zu (fetch/transfer)",
+ this, mStats.mBuffersCached, mStats.mSizeCached,
+ mStats.mBuffersInUse, mStats.mSizeInUse,
+ mStats.mTotalRecycles, mStats.mTotalAllocations,
+ mStats.mTotalFetches, mStats.mTotalTransfers);
+ }
+ for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+ if (!clearCache && mStats.buffersNotInUse() <= kUnusedBufferCountTarget &&
+ (mStats.mSizeCached < kMinAllocBytesForEviction ||
+ mBuffers.size() < kMinBufferCountForEviction)) {
+ break;
+ }
+ auto it = mBuffers.find(*freeIt);
+ if (it != mBuffers.end() &&
+ it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+ mStats.onBufferEvicted(it->second->mAllocSize);
+ mBuffers.erase(it);
+ freeIt = mFreeBuffers.erase(freeIt);
+ } else {
+ ++freeIt;
+ ALOGW("bufferpool2 inconsistent!");
+ }
+ }
+ }
+}
+
+void BufferPool::invalidate(
+ bool needsAck, BufferId from, BufferId to,
+ const std::shared_ptr<Accessor> &impl) {
+ for (auto freeIt = mFreeBuffers.begin(); freeIt != mFreeBuffers.end();) {
+ if (isBufferInRange(from, to, *freeIt)) {
+ auto it = mBuffers.find(*freeIt);
+ if (it != mBuffers.end() &&
+ it->second->mOwnerCount == 0 && it->second->mTransactionCount == 0) {
+ mStats.onBufferEvicted(it->second->mAllocSize);
+ mBuffers.erase(it);
+ freeIt = mFreeBuffers.erase(freeIt);
+ continue;
+ } else {
+ ALOGW("bufferpool2 inconsistent!");
+ }
+ }
+ ++freeIt;
+ }
+
+ size_t left = 0;
+ for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
+ if (isBufferInRange(from, to, it->first)) {
+ it->second->invalidate();
+ ++left;
+ }
+ }
+ mInvalidation.onInvalidationRequest(needsAck, from, to, left, mInvalidationChannel, impl);
+}
+
+void BufferPool::flush(const std::shared_ptr<Accessor> &impl) {
+ BufferId from = mStartSeq;
+ BufferId to = mSeq;
+ mStartSeq = mSeq;
+ // TODO: needsAck params
+ ALOGV("buffer invalidation request bp:%u %u %u", mInvalidation.mId, from, to);
+ if (from != to) {
+ invalidate(true, from, to, impl);
+ }
+}
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPool.h b/media/bufferpool/aidl/default/BufferPool.h
new file mode 100644
index 0000000..1529a53
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPool.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <set>
+#include <vector>
+#include <mutex>
+#include <condition_variable>
+#include <utils/Timers.h>
+
+#include "BufferStatus.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using BufferStatus = aidl::android::hardware::media::bufferpool2::BufferStatus;
+using BufferStatusMessage = aidl::android::hardware::media::bufferpool2::BufferStatusMessage;
+
+struct Accessor;
+struct InternalBuffer;
+struct TransactionStatus;
+
+/**
+ * Buffer pool implementation.
+ *
+ * Handles buffer status messages. Handles buffer allocation/recycling.
+ * Handles buffer transfer between buffer pool clients.
+ */
+struct BufferPool {
+private:
+ std::mutex mMutex;
+ int64_t mTimestampMs;
+ int64_t mLastCleanUpMs;
+ int64_t mLastLogMs;
+ BufferId mSeq;
+ BufferId mStartSeq;
+ bool mValid;
+ BufferStatusObserver mObserver;
+ BufferInvalidationChannel mInvalidationChannel;
+
+ std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
+ std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
+
+ std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
+ // Transactions completed before TRANSFER_TO message arrival.
+ // Fetch does not occur for the transactions.
+ // Only transaction id is kept for the transactions in short duration.
+ std::set<TransactionId> mCompletedTransactions;
+ // Currently active(pending) transations' status & information.
+ std::map<TransactionId, std::unique_ptr<TransactionStatus>>
+ mTransactions;
+
+ std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
+ std::set<BufferId> mFreeBuffers;
+ std::set<ConnectionId> mConnectionIds;
+
+ struct Invalidation {
+ static std::atomic<std::uint32_t> sInvSeqId;
+
+ struct Pending {
+ bool mNeedsAck;
+ uint32_t mFrom;
+ uint32_t mTo;
+ size_t mLeft;
+ const std::weak_ptr<Accessor> mImpl;
+ Pending(bool needsAck, uint32_t from, uint32_t to, size_t left,
+ const std::shared_ptr<Accessor> &impl)
+ : mNeedsAck(needsAck),
+ mFrom(from),
+ mTo(to),
+ mLeft(left),
+ mImpl(impl)
+ {}
+
+ bool isInvalidated(uint32_t bufferId) {
+ return isBufferInRange(mFrom, mTo, bufferId) && --mLeft == 0;
+ }
+ };
+
+ std::list<Pending> mPendings;
+ std::map<ConnectionId, uint32_t> mAcks;
+ std::map<ConnectionId, const std::shared_ptr<IObserver>> mObservers;
+ uint32_t mInvalidationId;
+ uint32_t mId;
+
+ Invalidation() : mInvalidationId(0), mId(sInvSeqId.fetch_add(1)) {}
+
+ void onConnect(ConnectionId conId, const std::shared_ptr<IObserver> &observer);
+
+ void onClose(ConnectionId conId);
+
+ void onAck(ConnectionId conId, uint32_t msgId);
+
+ void onBufferInvalidated(
+ BufferId bufferId,
+ BufferInvalidationChannel &channel);
+
+ void onInvalidationRequest(
+ bool needsAck, uint32_t from, uint32_t to, size_t left,
+ BufferInvalidationChannel &channel,
+ const std::shared_ptr<Accessor> &impl);
+
+ void onHandleAck(
+ std::map<ConnectionId, const std::shared_ptr<IObserver>> *observers,
+ uint32_t *invalidationId);
+ } mInvalidation;
+ /// Buffer pool statistics which tracks allocation and transfer statistics.
+ struct Stats {
+ /// Total size of allocations which are used or available to use.
+ /// (bytes or pixels)
+ size_t mSizeCached;
+ /// # of cached buffers which are used or available to use.
+ size_t mBuffersCached;
+ /// Total size of allocations which are currently used. (bytes or pixels)
+ size_t mSizeInUse;
+ /// # of currently used buffers
+ size_t mBuffersInUse;
+
+ /// # of allocations called on bufferpool. (# of fetched from BlockPool)
+ size_t mTotalAllocations;
+ /// # of allocations that were served from the cache.
+ /// (# of allocator alloc prevented)
+ size_t mTotalRecycles;
+ /// # of buffer transfers initiated.
+ size_t mTotalTransfers;
+ /// # of transfers that had to be fetched.
+ size_t mTotalFetches;
+
+ Stats()
+ : mSizeCached(0), mBuffersCached(0), mSizeInUse(0), mBuffersInUse(0),
+ mTotalAllocations(0), mTotalRecycles(0), mTotalTransfers(0), mTotalFetches(0) {}
+
+ /// # of currently unused buffers
+ size_t buffersNotInUse() const {
+ ALOG_ASSERT(mBuffersCached >= mBuffersInUse);
+ return mBuffersCached - mBuffersInUse;
+ }
+
+ /// A new buffer is allocated on an allocation request.
+ void onBufferAllocated(size_t allocSize) {
+ mSizeCached += allocSize;
+ mBuffersCached++;
+
+ mSizeInUse += allocSize;
+ mBuffersInUse++;
+
+ mTotalAllocations++;
+ }
+
+ /// A buffer is evicted and destroyed.
+ void onBufferEvicted(size_t allocSize) {
+ mSizeCached -= allocSize;
+ mBuffersCached--;
+ }
+
+ /// A buffer is recycled on an allocation request.
+ void onBufferRecycled(size_t allocSize) {
+ mSizeInUse += allocSize;
+ mBuffersInUse++;
+
+ mTotalAllocations++;
+ mTotalRecycles++;
+ }
+
+ /// A buffer is available to be recycled.
+ void onBufferUnused(size_t allocSize) {
+ mSizeInUse -= allocSize;
+ mBuffersInUse--;
+ }
+
+ /// A buffer transfer is initiated.
+ void onBufferSent() {
+ mTotalTransfers++;
+ }
+
+ /// A buffer fetch is invoked by a buffer transfer.
+ void onBufferFetched() {
+ mTotalFetches++;
+ }
+ } mStats;
+
+ bool isValid() {
+ return mValid;
+ }
+
+ void invalidate(bool needsAck, BufferId from, BufferId to,
+ const std::shared_ptr<Accessor> &impl);
+
+ static void createInvalidator();
+
+public:
+ /** Creates a buffer pool. */
+ BufferPool();
+
+ /** Destroys a buffer pool. */
+ ~BufferPool();
+
+ /**
+ * Processes all pending buffer status messages, and returns the result.
+ * Each status message is handled by methods with 'handle' prefix.
+ */
+ void processStatusMessages();
+
+ /**
+ * Handles a buffer being owned by a connection.
+ *
+ * @param connectionId the id of the buffer owning connection.
+ * @param bufferId the id of the buffer.
+ *
+ * @return {@code true} when the buffer is owned,
+ * {@code false} otherwise.
+ */
+ bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
+
+ /**
+ * Handles a buffer being released by a connection.
+ *
+ * @param connectionId the id of the buffer owning connection.
+ * @param bufferId the id of the buffer.
+ *
+ * @return {@code true} when the buffer ownership is released,
+ * {@code false} otherwise.
+ */
+ bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
+
+ /**
+ * Handles a transfer transaction start message from the sender.
+ *
+ * @param message a buffer status message for the transaction.
+ *
+ * @result {@code true} when transfer_to message is acknowledged,
+ * {@code false} otherwise.
+ */
+ bool handleTransferTo(const BufferStatusMessage &message);
+
+ /**
+ * Handles a transfer transaction being acked by the receiver.
+ *
+ * @param message a buffer status message for the transaction.
+ *
+ * @result {@code true} when transfer_from message is acknowledged,
+ * {@code false} otherwise.
+ */
+ bool handleTransferFrom(const BufferStatusMessage &message);
+
+ /**
+ * Handles a transfer transaction result message from the receiver.
+ *
+ * @param message a buffer status message for the transaction.
+ *
+ * @result {@code true} when the existing transaction is finished,
+ * {@code false} otherwise.
+ */
+ bool handleTransferResult(const BufferStatusMessage &message);
+
+ /**
+ * Handles a connection being closed, and returns the result. All the
+ * buffers and transactions owned by the connection will be cleaned up.
+ * The related FMQ will be cleaned up too.
+ *
+ * @param connectionId the id of the connection.
+ *
+ * @result {@code true} when the connection existed,
+ * {@code false} otherwise.
+ */
+ bool handleClose(ConnectionId connectionId);
+
+ /**
+ * Recycles a existing free buffer if it is possible.
+ *
+ * @param allocator the buffer allocator
+ * @param params the allocation parameters.
+ * @param pId the id of the recycled buffer.
+ * @param handle the native handle of the recycled buffer.
+ *
+ * @return {@code true} when a buffer is recycled, {@code false}
+ * otherwise.
+ */
+ bool getFreeBuffer(
+ const std::shared_ptr<BufferPoolAllocator> &allocator,
+ const std::vector<uint8_t> ¶ms,
+ BufferId *pId, const native_handle_t **handle);
+
+ /**
+ * Adds a newly allocated buffer to bufferpool.
+ *
+ * @param alloc the newly allocated buffer.
+ * @param allocSize the size of the newly allocated buffer.
+ * @param params the allocation parameters.
+ * @param pId the buffer id for the newly allocated buffer.
+ * @param handle the native handle for the newly allocated buffer.
+ *
+ * @return OK when an allocation is successfully allocated.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus addNewBuffer(
+ const std::shared_ptr<BufferPoolAllocation> &alloc,
+ const size_t allocSize,
+ const std::vector<uint8_t> ¶ms,
+ BufferId *pId,
+ const native_handle_t **handle);
+
+ /**
+ * Processes pending buffer status messages and performs periodic cache
+ * cleaning.
+ *
+ * @param clearCache if clearCache is true, it frees all buffers
+ * waiting to be recycled.
+ */
+ void cleanUp(bool clearCache = false);
+
+ /**
+ * Processes pending buffer status messages and invalidate all current
+ * free buffers. Active buffers are invalidated after being inactive.
+ */
+ void flush(const std::shared_ptr<Accessor> &impl);
+
+ friend struct Accessor;
+};
+
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
new file mode 100644
index 0000000..e9777d8
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -0,0 +1,858 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlBufferPoolCli"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <utils/Log.h>
+#include "BufferPoolClient.h"
+#include "Accessor.h"
+#include "Connection.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::IConnection;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
+using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
+
+static constexpr int64_t kReceiveTimeoutMs = 2000; // 2s
+static constexpr int kPostMaxRetry = 3;
+static constexpr int kCacheTtlMs = 1000;
+static constexpr size_t kMaxCachedBufferCount = 64;
+static constexpr size_t kCachedBufferCountTarget = kMaxCachedBufferCount - 16;
+
+class BufferPoolClient::Impl
+ : public std::enable_shared_from_this<BufferPoolClient::Impl> {
+public:
+ explicit Impl(const std::shared_ptr<Accessor> &accessor,
+ const std::shared_ptr<IObserver> &observer);
+
+ explicit Impl(const std::shared_ptr<IAccessor> &accessor,
+ const std::shared_ptr<IObserver> &observer);
+
+ bool isValid() {
+ return mValid;
+ }
+
+ bool isLocal() {
+ return mValid && mLocal;
+ }
+
+ ConnectionId getConnectionId() {
+ return mConnectionId;
+ }
+
+ std::shared_ptr<IAccessor> &getAccessor() {
+ return mAccessor;
+ }
+
+ bool isActive(int64_t *lastTransactionMs, bool clearCache);
+
+ void receiveInvalidation(uint32_t msgID);
+
+ BufferPoolStatus flush();
+
+ BufferPoolStatus allocate(const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ BufferPoolStatus receive(
+ TransactionId transactionId, BufferId bufferId,
+ int64_t timestampMs,
+ native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer);
+
+ void postBufferRelease(BufferId bufferId);
+
+ bool postSend(
+ BufferId bufferId, ConnectionId receiver,
+ TransactionId *transactionId, int64_t *timestampMs);
+private:
+
+ bool postReceive(
+ BufferId bufferId, TransactionId transactionId,
+ int64_t timestampMs);
+
+ bool postReceiveResult(
+ BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync);
+
+ void trySyncFromRemote();
+
+ bool syncReleased(uint32_t msgId = 0);
+
+ void evictCaches(bool clearCache = false);
+
+ void invalidateBuffer(BufferId id);
+
+ void invalidateRange(BufferId from, BufferId to);
+
+ BufferPoolStatus allocateBufferHandle(
+ const std::vector<uint8_t>& params, BufferId *bufferId,
+ native_handle_t **handle);
+
+ BufferPoolStatus fetchBufferHandle(
+ TransactionId transactionId, BufferId bufferId,
+ native_handle_t **handle);
+
+ struct BlockPoolDataDtor;
+ struct ClientBuffer;
+
+ bool mLocal;
+ bool mValid;
+ std::shared_ptr<IAccessor> mAccessor;
+ std::shared_ptr<Connection> mLocalConnection;
+ std::shared_ptr<IConnection> mRemoteConnection;
+ uint32_t mSeqId;
+ ConnectionId mConnectionId;
+ int64_t mLastEvictCacheMs;
+ std::unique_ptr<BufferInvalidationListener> mInvalidationListener;
+
+ // CachedBuffers
+ struct BufferCache {
+ std::mutex mLock;
+ bool mCreating;
+ std::condition_variable mCreateCv;
+ std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
+ int mActive;
+ int64_t mLastChangeMs;
+
+ BufferCache() : mCreating(false), mActive(0),
+ mLastChangeMs(::android::elapsedRealtime()) {}
+
+ void incActive_l() {
+ ++mActive;
+ mLastChangeMs = ::android::elapsedRealtime();
+ }
+
+ void decActive_l() {
+ --mActive;
+ mLastChangeMs = ::android::elapsedRealtime();
+ }
+
+ int cachedBufferCount() const {
+ return mBuffers.size() - mActive;
+ }
+ } mCache;
+
+ // FMQ - release notifier
+ struct ReleaseCache {
+ std::mutex mLock;
+ std::list<BufferId> mReleasingIds;
+ std::list<BufferId> mReleasedIds;
+ uint32_t mInvalidateId; // TODO: invalidation ACK to bufferpool
+ bool mInvalidateAck;
+ std::unique_ptr<BufferStatusChannel> mStatusChannel;
+
+ ReleaseCache() : mInvalidateId(0), mInvalidateAck(true) {}
+ } mReleasing;
+
+ // This lock is held during synchronization from remote side.
+ // In order to minimize remote calls and locking duration, this lock is held
+ // by best effort approach using try_lock().
+ std::mutex mRemoteSyncLock;
+};
+
+struct BufferPoolClient::Impl::BlockPoolDataDtor {
+ BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
+ : mImpl(impl) {}
+
+ void operator()(BufferPoolData *buffer) {
+ BufferId id = buffer->mId;
+ delete buffer;
+
+ auto impl = mImpl.lock();
+ if (impl && impl->isValid()) {
+ impl->postBufferRelease(id);
+ }
+ }
+ const std::weak_ptr<BufferPoolClient::Impl> mImpl;
+};
+
+struct BufferPoolClient::Impl::ClientBuffer {
+private:
+ int64_t mExpireMs;
+ bool mHasCache;
+ ConnectionId mConnectionId;
+ BufferId mId;
+ native_handle_t *mHandle;
+ std::weak_ptr<BufferPoolData> mCache;
+
+ void updateExpire() {
+ mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
+ }
+
+public:
+ ClientBuffer(
+ ConnectionId connectionId, BufferId id, native_handle_t *handle)
+ : mHasCache(false), mConnectionId(connectionId),
+ mId(id), mHandle(handle) {
+ mExpireMs = ::android::elapsedRealtime() + kCacheTtlMs;
+ }
+
+ ~ClientBuffer() {
+ if (mHandle) {
+ native_handle_close(mHandle);
+ native_handle_delete(mHandle);
+ }
+ }
+
+ BufferId id() const {
+ return mId;
+ }
+
+ bool expire() const {
+ int64_t now = ::android::elapsedRealtime();
+ return now >= mExpireMs;
+ }
+
+ bool hasCache() const {
+ return mHasCache;
+ }
+
+ std::shared_ptr<BufferPoolData> fetchCache(native_handle_t **pHandle) {
+ if (mHasCache) {
+ std::shared_ptr<BufferPoolData> cache = mCache.lock();
+ if (cache) {
+ *pHandle = mHandle;
+ }
+ return cache;
+ }
+ return nullptr;
+ }
+
+ std::shared_ptr<BufferPoolData> createCache(
+ const std::shared_ptr<BufferPoolClient::Impl> &impl,
+ native_handle_t **pHandle) {
+ if (!mHasCache) {
+ // Allocates a raw ptr in order to avoid sending #postBufferRelease
+ // from deleter, in case of native_handle_clone failure.
+ BufferPoolData *ptr = new BufferPoolData(mConnectionId, mId);
+ if (ptr) {
+ std::shared_ptr<BufferPoolData> cache(ptr, BlockPoolDataDtor(impl));
+ if (cache) {
+ mCache = cache;
+ mHasCache = true;
+ *pHandle = mHandle;
+ return cache;
+ }
+ }
+ if (ptr) {
+ delete ptr;
+ }
+ }
+ return nullptr;
+ }
+
+ bool onCacheRelease() {
+ if (mHasCache) {
+ // TODO: verify mCache is not valid;
+ updateExpire();
+ mHasCache = false;
+ return true;
+ }
+ return false;
+ }
+};
+
+BufferPoolClient::Impl::Impl(const std::shared_ptr<Accessor> &accessor,
+ const std::shared_ptr<IObserver> &observer)
+ : mLocal(true), mValid(false), mAccessor(accessor), mSeqId(0),
+ mLastEvictCacheMs(::android::elapsedRealtime()) {
+ StatusDescriptor statusDesc;
+ InvalidationDescriptor invDesc;
+ BufferPoolStatus status = accessor->connect(
+ observer, true,
+ &mLocalConnection, &mConnectionId, &mReleasing.mInvalidateId,
+ &statusDesc, &invDesc);
+ if (status == ResultStatus::OK) {
+ mReleasing.mStatusChannel =
+ std::make_unique<BufferStatusChannel>(statusDesc);
+ mInvalidationListener =
+ std::make_unique<BufferInvalidationListener>(invDesc);
+ mValid = mReleasing.mStatusChannel &&
+ mReleasing.mStatusChannel->isValid() &&
+ mInvalidationListener &&
+ mInvalidationListener->isValid();
+ }
+}
+
+BufferPoolClient::Impl::Impl(const std::shared_ptr<IAccessor> &accessor,
+ const std::shared_ptr<IObserver> &observer)
+ : mLocal(false), mValid(false), mAccessor(accessor), mSeqId(0),
+ mLastEvictCacheMs(::android::elapsedRealtime()) {
+ IAccessor::ConnectionInfo conInfo;
+ bool valid = false;
+ if(accessor->connect(observer, &conInfo).isOk()) {
+ auto channel = std::make_unique<BufferStatusChannel>(conInfo.toFmqDesc);
+ auto observer = std::make_unique<BufferInvalidationListener>(conInfo.fromFmqDesc);
+
+ if (channel && channel->isValid()
+ && observer && observer->isValid()) {
+ mRemoteConnection = conInfo.connection;
+ mConnectionId = conInfo.connectionId;
+ mReleasing.mInvalidateId = conInfo.msgId;
+ mReleasing.mStatusChannel = std::move(channel);
+ mInvalidationListener = std::move(observer);
+ valid = true;
+ }
+ }
+ mValid = valid;
+}
+
+bool BufferPoolClient::Impl::isActive(int64_t *lastTransactionMs, bool clearCache) {
+ bool active = false;
+ {
+ std::lock_guard<std::mutex> lock(mCache.mLock);
+ syncReleased();
+ evictCaches(clearCache);
+ *lastTransactionMs = mCache.mLastChangeMs;
+ active = mCache.mActive > 0;
+ }
+ if (mValid && mLocal && mLocalConnection) {
+ mLocalConnection->cleanUp(clearCache);
+ return true;
+ }
+ return active;
+}
+
+void BufferPoolClient::Impl::receiveInvalidation(uint32_t messageId) {
+ std::lock_guard<std::mutex> lock(mCache.mLock);
+ syncReleased(messageId);
+ // TODO: evict cache required?
+}
+
+BufferPoolStatus BufferPoolClient::Impl::flush() {
+ if (!mLocal || !mLocalConnection || !mValid) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ {
+ std::unique_lock<std::mutex> lock(mCache.mLock);
+ syncReleased();
+ evictCaches();
+ return mLocalConnection->flush();
+ }
+}
+
+BufferPoolStatus BufferPoolClient::Impl::allocate(
+ const std::vector<uint8_t> ¶ms,
+ native_handle_t **pHandle,
+ std::shared_ptr<BufferPoolData> *buffer) {
+ if (!mLocal || !mLocalConnection || !mValid) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ BufferId bufferId;
+ native_handle_t *handle = nullptr;
+ buffer->reset();
+ BufferPoolStatus status = allocateBufferHandle(params, &bufferId, &handle);
+ if (status == ResultStatus::OK) {
+ if (handle) {
+ std::unique_lock<std::mutex> lock(mCache.mLock);
+ syncReleased();
+ evictCaches();
+ auto cacheIt = mCache.mBuffers.find(bufferId);
+ if (cacheIt != mCache.mBuffers.end()) {
+ // TODO: verify it is recycled. (not having active ref)
+ mCache.mBuffers.erase(cacheIt);
+ }
+ auto clientBuffer = std::make_unique<ClientBuffer>(
+ mConnectionId, bufferId, handle);
+ if (clientBuffer) {
+ auto result = mCache.mBuffers.insert(std::make_pair(
+ bufferId, std::move(clientBuffer)));
+ if (result.second) {
+ *buffer = result.first->second->createCache(
+ shared_from_this(), pHandle);
+ if (*buffer) {
+ mCache.incActive_l();
+ }
+ }
+ }
+ }
+ if (!*buffer) {
+ ALOGV("client cache creation failure %d: %lld",
+ handle != nullptr, (long long)mConnectionId);
+ status = ResultStatus::NO_MEMORY;
+ postBufferRelease(bufferId);
+ }
+ }
+ return status;
+}
+
+BufferPoolStatus BufferPoolClient::Impl::receive(
+ TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
+ native_handle_t **pHandle,
+ std::shared_ptr<BufferPoolData> *buffer) {
+ if (!mValid) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ if (timestampMs != 0) {
+ timestampMs += kReceiveTimeoutMs;
+ }
+ if (!postReceive(bufferId, transactionId, timestampMs)) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+ buffer->reset();
+ while(1) {
+ std::unique_lock<std::mutex> lock(mCache.mLock);
+ syncReleased();
+ evictCaches();
+ auto cacheIt = mCache.mBuffers.find(bufferId);
+ if (cacheIt != mCache.mBuffers.end()) {
+ if (cacheIt->second->hasCache()) {
+ *buffer = cacheIt->second->fetchCache(pHandle);
+ if (!*buffer) {
+ // check transfer time_out
+ lock.unlock();
+ std::this_thread::yield();
+ continue;
+ }
+ ALOGV("client receive from reference %lld", (long long)mConnectionId);
+ break;
+ } else {
+ *buffer = cacheIt->second->createCache(shared_from_this(), pHandle);
+ if (*buffer) {
+ mCache.incActive_l();
+ }
+ ALOGV("client receive from cache %lld", (long long)mConnectionId);
+ break;
+ }
+ } else {
+ if (!mCache.mCreating) {
+ mCache.mCreating = true;
+ lock.unlock();
+ native_handle_t* handle = nullptr;
+ status = fetchBufferHandle(transactionId, bufferId, &handle);
+ lock.lock();
+ if (status == ResultStatus::OK) {
+ if (handle) {
+ auto clientBuffer = std::make_unique<ClientBuffer>(
+ mConnectionId, bufferId, handle);
+ if (clientBuffer) {
+ auto result = mCache.mBuffers.insert(
+ std::make_pair(bufferId, std::move(
+ clientBuffer)));
+ if (result.second) {
+ *buffer = result.first->second->createCache(
+ shared_from_this(), pHandle);
+ if (*buffer) {
+ mCache.incActive_l();
+ }
+ }
+ }
+ }
+ if (!*buffer) {
+ status = ResultStatus::NO_MEMORY;
+ }
+ }
+ mCache.mCreating = false;
+ lock.unlock();
+ mCache.mCreateCv.notify_all();
+ break;
+ }
+ mCache.mCreateCv.wait(lock);
+ }
+ }
+ bool needsSync = false;
+ bool posted = postReceiveResult(bufferId, transactionId,
+ *buffer ? true : false, &needsSync);
+ ALOGV("client receive %lld - %u : %s (%d)", (long long)mConnectionId, bufferId,
+ *buffer ? "ok" : "fail", posted);
+ if (mValid && mLocal && mLocalConnection) {
+ mLocalConnection->cleanUp(false);
+ }
+ if (needsSync && mRemoteConnection) {
+ trySyncFromRemote();
+ }
+ if (*buffer) {
+ if (!posted) {
+ buffer->reset();
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ return ResultStatus::OK;
+ }
+ return status;
+}
+
+
+void BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
+ std::lock_guard<std::mutex> lock(mReleasing.mLock);
+ mReleasing.mReleasingIds.push_back(bufferId);
+ mReleasing.mStatusChannel->postBufferRelease(
+ mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+}
+
+// TODO: revise ad-hoc posting data structure
+bool BufferPoolClient::Impl::postSend(
+ BufferId bufferId, ConnectionId receiver,
+ TransactionId *transactionId, int64_t *timestampMs) {
+ {
+ // TODO: don't need to call syncReleased every time
+ std::lock_guard<std::mutex> lock(mCache.mLock);
+ syncReleased();
+ }
+ bool ret = false;
+ bool needsSync = false;
+ {
+ std::lock_guard<std::mutex> lock(mReleasing.mLock);
+ *timestampMs = ::android::elapsedRealtime();
+ *transactionId = (mConnectionId << 32) | mSeqId++;
+ // TODO: retry, add timeout, target?
+ ret = mReleasing.mStatusChannel->postBufferStatusMessage(
+ *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
+ receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
+ needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+ }
+ if (mValid && mLocal && mLocalConnection) {
+ mLocalConnection->cleanUp(false);
+ }
+ if (needsSync && mRemoteConnection) {
+ trySyncFromRemote();
+ }
+ return ret;
+}
+
+bool BufferPoolClient::Impl::postReceive(
+ BufferId bufferId, TransactionId transactionId, int64_t timestampMs) {
+ for (int i = 0; i < kPostMaxRetry; ++i) {
+ std::unique_lock<std::mutex> lock(mReleasing.mLock);
+ int64_t now = ::android::elapsedRealtime();
+ if (timestampMs == 0 || now < timestampMs) {
+ bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
+ transactionId, bufferId, BufferStatus::TRANSFER_FROM,
+ mConnectionId, -1, mReleasing.mReleasingIds,
+ mReleasing.mReleasedIds);
+ if (result) {
+ return true;
+ }
+ lock.unlock();
+ std::this_thread::yield();
+ } else {
+ mReleasing.mStatusChannel->postBufferStatusMessage(
+ transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
+ mConnectionId, -1, mReleasing.mReleasingIds,
+ mReleasing.mReleasedIds);
+ return false;
+ }
+ }
+ return false;
+}
+
+bool BufferPoolClient::Impl::postReceiveResult(
+ BufferId bufferId, TransactionId transactionId, bool result, bool *needsSync) {
+ std::lock_guard<std::mutex> lock(mReleasing.mLock);
+ // TODO: retry, add timeout
+ bool ret = mReleasing.mStatusChannel->postBufferStatusMessage(
+ transactionId, bufferId,
+ result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
+ mConnectionId, -1, mReleasing.mReleasingIds,
+ mReleasing.mReleasedIds);
+ *needsSync = !mLocal && mReleasing.mStatusChannel->needsSync();
+ return ret;
+}
+
+void BufferPoolClient::Impl::trySyncFromRemote() {
+ if (mRemoteSyncLock.try_lock()) {
+ bool needsSync = false;
+ {
+ std::lock_guard<std::mutex> lock(mReleasing.mLock);
+ needsSync = mReleasing.mStatusChannel->needsSync();
+ }
+ if (needsSync) {
+ if (!mRemoteConnection->sync().isOk()) {
+ ALOGD("sync from client %lld failed: bufferpool process died.",
+ (long long)mConnectionId);
+ }
+ }
+ mRemoteSyncLock.unlock();
+ }
+}
+
+// should have mCache.mLock
+bool BufferPoolClient::Impl::syncReleased(uint32_t messageId) {
+ bool cleared = false;
+ {
+ std::lock_guard<std::mutex> lock(mReleasing.mLock);
+ if (mReleasing.mReleasingIds.size() > 0) {
+ mReleasing.mStatusChannel->postBufferRelease(
+ mConnectionId, mReleasing.mReleasingIds,
+ mReleasing.mReleasedIds);
+ }
+ if (mReleasing.mReleasedIds.size() > 0) {
+ for (BufferId& id: mReleasing.mReleasedIds) {
+ ALOGV("client release buffer %lld - %u", (long long)mConnectionId, id);
+ auto found = mCache.mBuffers.find(id);
+ if (found != mCache.mBuffers.end()) {
+ if (found->second->onCacheRelease()) {
+ mCache.decActive_l();
+ } else {
+ // should not happen!
+ ALOGW("client %lld cache release status inconsistent!",
+ (long long)mConnectionId);
+ }
+ } else {
+ // should not happen!
+ ALOGW("client %lld cache status inconsistent!", (long long)mConnectionId);
+ }
+ }
+ mReleasing.mReleasedIds.clear();
+ cleared = true;
+ }
+ }
+ std::vector<BufferInvalidationMessage> invalidations;
+ mInvalidationListener->getInvalidations(invalidations);
+ uint32_t lastMsgId = 0;
+ if (invalidations.size() > 0) {
+ for (auto it = invalidations.begin(); it != invalidations.end(); ++it) {
+ if (it->messageId != 0) {
+ lastMsgId = it->messageId;
+ }
+ if (it->fromBufferId == it->toBufferId) {
+ // TODO: handle fromBufferId = UINT32_MAX
+ invalidateBuffer(it->fromBufferId);
+ } else {
+ invalidateRange(it->fromBufferId, it->toBufferId);
+ }
+ }
+ }
+ {
+ std::lock_guard<std::mutex> lock(mReleasing.mLock);
+ if (lastMsgId != 0) {
+ if (isMessageLater(lastMsgId, mReleasing.mInvalidateId)) {
+ mReleasing.mInvalidateId = lastMsgId;
+ mReleasing.mInvalidateAck = false;
+ }
+ } else if (messageId != 0) {
+ // messages are drained.
+ if (isMessageLater(messageId, mReleasing.mInvalidateId)) {
+ mReleasing.mInvalidateId = messageId;
+ mReleasing.mInvalidateAck = true;
+ }
+ }
+ if (!mReleasing.mInvalidateAck) {
+ // post ACK
+ mReleasing.mStatusChannel->postBufferInvalidateAck(
+ mConnectionId,
+ mReleasing.mInvalidateId, &mReleasing.mInvalidateAck);
+ ALOGV("client %lld invalidateion ack (%d) %u",
+ (long long)mConnectionId,
+ mReleasing.mInvalidateAck, mReleasing.mInvalidateId);
+ }
+ }
+ return cleared;
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::evictCaches(bool clearCache) {
+ int64_t now = ::android::elapsedRealtime();
+ if (now >= mLastEvictCacheMs + kCacheTtlMs ||
+ clearCache || mCache.cachedBufferCount() > kMaxCachedBufferCount) {
+ size_t evicted = 0;
+ for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+ if (!it->second->hasCache() && (it->second->expire() ||
+ clearCache || mCache.cachedBufferCount() > kCachedBufferCountTarget)) {
+ it = mCache.mBuffers.erase(it);
+ ++evicted;
+ } else {
+ ++it;
+ }
+ }
+ ALOGV("cache count %lld : total %zu, active %d, evicted %zu",
+ (long long)mConnectionId, mCache.mBuffers.size(), mCache.mActive, evicted);
+ mLastEvictCacheMs = now;
+ }
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::invalidateBuffer(BufferId id) {
+ for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end(); ++it) {
+ if (id == it->second->id()) {
+ if (!it->second->hasCache()) {
+ mCache.mBuffers.erase(it);
+ ALOGV("cache invalidated %lld : buffer %u",
+ (long long)mConnectionId, id);
+ } else {
+ ALOGW("Inconsistent invalidation %lld : activer buffer!! %u",
+ (long long)mConnectionId, (unsigned int)id);
+ }
+ break;
+ }
+ }
+}
+
+// should have mCache.mLock
+void BufferPoolClient::Impl::invalidateRange(BufferId from, BufferId to) {
+ size_t invalidated = 0;
+ for (auto it = mCache.mBuffers.begin(); it != mCache.mBuffers.end();) {
+ if (!it->second->hasCache()) {
+ BufferId bid = it->second->id();
+ if (from < to) {
+ if (from <= bid && bid < to) {
+ ++invalidated;
+ it = mCache.mBuffers.erase(it);
+ continue;
+ }
+ } else {
+ if (from <= bid || bid < to) {
+ ++invalidated;
+ it = mCache.mBuffers.erase(it);
+ continue;
+ }
+ }
+ }
+ ++it;
+ }
+ ALOGV("cache invalidated %lld : # of invalidated %zu",
+ (long long)mConnectionId, invalidated);
+}
+
+BufferPoolStatus BufferPoolClient::Impl::allocateBufferHandle(
+ const std::vector<uint8_t>& params, BufferId *bufferId,
+ native_handle_t** handle) {
+ if (mLocalConnection) {
+ const native_handle_t* allocHandle = nullptr;
+ BufferPoolStatus status = mLocalConnection->allocate(
+ params, bufferId, &allocHandle);
+ if (status == ResultStatus::OK) {
+ *handle = native_handle_clone(allocHandle);
+ }
+ ALOGV("client allocate result %lld %d : %u clone %p",
+ (long long)mConnectionId, status == ResultStatus::OK,
+ *handle ? *bufferId : 0 , *handle);
+ return status;
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::Impl::fetchBufferHandle(
+ TransactionId transactionId, BufferId bufferId,
+ native_handle_t **handle) {
+ std::shared_ptr<IConnection> connection;
+ if (mLocal) {
+ connection = mLocalConnection;
+ } else {
+ connection = mRemoteConnection;
+ }
+ std::vector<FetchInfo> infos;
+ std::vector<FetchResult> results;
+ infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
+ ndk::ScopedAStatus status = connection->fetch(infos, &results);
+ if (!status.isOk()) {
+ BufferPoolStatus svcSpecific = status.getServiceSpecificError();
+ return svcSpecific ? svcSpecific : ResultStatus::CRITICAL_ERROR;
+ }
+ if (results[0].getTag() == FetchResult::buffer) {
+ *handle = ::android::dupFromAidl(results[0].get<FetchResult::buffer>().buffer);
+ return ResultStatus::OK;
+ }
+ return results[0].get<FetchResult::failure>();
+}
+
+
+BufferPoolClient::BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
+ const std::shared_ptr<IObserver> &observer) {
+ mImpl = std::make_shared<Impl>(accessor, observer);
+}
+
+BufferPoolClient::BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
+ const std::shared_ptr<IObserver> &observer) {
+ mImpl = std::make_shared<Impl>(accessor, observer);
+}
+
+BufferPoolClient::~BufferPoolClient() {
+ // TODO: how to handle orphaned buffers?
+}
+
+bool BufferPoolClient::isValid() {
+ return mImpl && mImpl->isValid();
+}
+
+bool BufferPoolClient::isLocal() {
+ return mImpl && mImpl->isLocal();
+}
+
+bool BufferPoolClient::isActive(int64_t *lastTransactionMs, bool clearCache) {
+ if (!isValid()) {
+ *lastTransactionMs = 0;
+ return false;
+ }
+ return mImpl->isActive(lastTransactionMs, clearCache);
+}
+
+ConnectionId BufferPoolClient::getConnectionId() {
+ if (isValid()) {
+ return mImpl->getConnectionId();
+ }
+ return -1;
+}
+
+BufferPoolStatus BufferPoolClient::getAccessor(std::shared_ptr<IAccessor> *accessor) {
+ if (isValid()) {
+ *accessor = mImpl->getAccessor();
+ return ResultStatus::OK;
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+void BufferPoolClient::receiveInvalidation(uint32_t msgId) {
+ ALOGV("bufferpool2 client recv inv %u", msgId);
+ if (isValid()) {
+ mImpl->receiveInvalidation(msgId);
+ }
+}
+
+BufferPoolStatus BufferPoolClient::flush() {
+ if (isValid()) {
+ return mImpl->flush();
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::allocate(
+ const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer) {
+ if (isValid()) {
+ return mImpl->allocate(params, handle, buffer);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::receive(
+ TransactionId transactionId, BufferId bufferId, int64_t timestampMs,
+ native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+ if (isValid()) {
+ return mImpl->receive(transactionId, bufferId, timestampMs, handle, buffer);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus BufferPoolClient::postSend(
+ ConnectionId receiverId,
+ const std::shared_ptr<BufferPoolData> &buffer,
+ TransactionId *transactionId,
+ int64_t *timestampMs) {
+ if (isValid()) {
+ bool result = mImpl->postSend(
+ buffer->mId, receiverId, transactionId, timestampMs);
+ return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.h b/media/bufferpool/aidl/default/BufferPoolClient.h
new file mode 100644
index 0000000..80fd43e
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferPoolClient.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <aidl/android/hardware/media/bufferpool2/IAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/IObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::IAccessor;
+using aidl::android::hardware::media::bufferpool2::IObserver;
+
+struct Accessor;
+
+/**
+ * A buffer pool client for a buffer pool. For a specific buffer pool, at most
+ * one buffer pool client exists per process. This class will not be exposed
+ * outside. A buffer pool client will be used via ClientManager.
+ */
+class BufferPoolClient {
+public:
+ /**
+ * Creates a buffer pool client from a local buffer pool
+ * (via ClientManager#create).
+ */
+ explicit BufferPoolClient(const std::shared_ptr<Accessor> &accessor,
+ const std::shared_ptr<IObserver> &observer);
+
+ /**
+ * Creates a buffer pool client from a remote buffer pool
+ * (via ClientManager#registerSender).
+ * Note: A buffer pool client created with remote buffer pool cannot
+ * allocate a buffer.
+ */
+ explicit BufferPoolClient(const std::shared_ptr<IAccessor> &accessor,
+ const std::shared_ptr<IObserver> &observer);
+
+ /** Destructs a buffer pool client. */
+ ~BufferPoolClient();
+
+private:
+ bool isValid();
+
+ bool isLocal();
+
+ bool isActive(int64_t *lastTransactionMs, bool clearCache);
+
+ ConnectionId getConnectionId();
+
+ BufferPoolStatus getAccessor(std::shared_ptr<IAccessor> *accessor);
+
+ void receiveInvalidation(uint32_t msgId);
+
+ BufferPoolStatus flush();
+
+ BufferPoolStatus allocate(const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ BufferPoolStatus receive(TransactionId transactionId,
+ BufferId bufferId,
+ int64_t timestampMs,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ BufferPoolStatus postSend(ConnectionId receiver,
+ const std::shared_ptr<BufferPoolData> &buffer,
+ TransactionId *transactionId,
+ int64_t *timestampMs);
+
+ class Impl;
+ std::shared_ptr<Impl> mImpl;
+
+ friend struct ClientManager;
+ friend struct Observer;
+};
+
+} // namespace aidl::android::hardware::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/BufferStatus.cpp b/media/bufferpool/aidl/default/BufferStatus.cpp
new file mode 100644
index 0000000..19caa1e
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferStatus.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AidlBufferPoolStatus"
+//#define LOG_NDEBUG 0
+
+#include <thread>
+#include <time.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferStatus.h>
+#include "BufferStatus.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::BufferStatus;
+
+bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId) {
+ return curMsgId != prevMsgId && curMsgId - prevMsgId < prevMsgId - curMsgId;
+}
+
+bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId) {
+ if (from < to) {
+ return from <= bufferId && bufferId < to;
+ } else { // wrap happens
+ return from <= bufferId || bufferId < to;
+ }
+}
+
+static constexpr int kNumElementsInQueue = 1024*16;
+static constexpr int kMinElementsToSyncInQueue = 128;
+
+BufferPoolStatus BufferStatusObserver::open(
+ ConnectionId id, StatusDescriptor* fmqDescPtr) {
+ if (mBufferStatusQueues.find(id) != mBufferStatusQueues.end()) {
+ ALOGE("connection id collision %lld", (unsigned long long)id);
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ auto queue = std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
+ if (!queue || queue->isValid() == false) {
+ return ResultStatus::NO_MEMORY;
+ }
+ *fmqDescPtr = queue->dupeDesc();
+ auto result = mBufferStatusQueues.insert(
+ std::make_pair(id, std::move(queue)));
+ if (!result.second) {
+ return ResultStatus::NO_MEMORY;
+ }
+ return ResultStatus::OK;
+}
+
+BufferPoolStatus BufferStatusObserver::close(ConnectionId id) {
+ if (mBufferStatusQueues.find(id) == mBufferStatusQueues.end()) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ mBufferStatusQueues.erase(id);
+ return ResultStatus::OK;
+}
+
+void BufferStatusObserver::getBufferStatusChanges(std::vector<BufferStatusMessage> &messages) {
+ for (auto it = mBufferStatusQueues.begin(); it != mBufferStatusQueues.end(); ++it) {
+ BufferStatusMessage message;
+ size_t avail = it->second->availableToRead();
+ while (avail > 0) {
+ if (!it->second->read(&message, 1)) {
+ // Since available # of reads are already confirmed,
+ // this should not happen.
+ // TODO: error handling (spurious client?)
+ ALOGW("FMQ message cannot be read from %lld", (long long)it->first);
+ return;
+ }
+ message.connectionId = it->first;
+ messages.push_back(message);
+ --avail;
+ }
+ }
+}
+
+BufferStatusChannel::BufferStatusChannel(
+ const StatusDescriptor &fmqDesc) {
+ auto queue = std::make_unique<BufferStatusQueue>(fmqDesc);
+ if (!queue || queue->isValid() == false) {
+ mValid = false;
+ return;
+ }
+ mValid = true;
+ mBufferStatusQueue = std::move(queue);
+}
+
+bool BufferStatusChannel::isValid() {
+ return mValid;
+}
+
+bool BufferStatusChannel::needsSync() {
+ if (mValid) {
+ size_t avail = mBufferStatusQueue->availableToWrite();
+ return avail + kMinElementsToSyncInQueue < kNumElementsInQueue;
+ }
+ return false;
+}
+
+void BufferStatusChannel::postBufferRelease(
+ ConnectionId connectionId,
+ std::list<BufferId> &pending, std::list<BufferId> &posted) {
+ if (mValid && pending.size() > 0) {
+ size_t avail = mBufferStatusQueue->availableToWrite();
+ avail = std::min(avail, pending.size());
+ BufferStatusMessage message;
+ for (size_t i = 0 ; i < avail; ++i) {
+ BufferId id = pending.front();
+ message.status = BufferStatus::NOT_USED;
+ message.bufferId = id;
+ message.connectionId = connectionId;
+ if (!mBufferStatusQueue->write(&message, 1)) {
+ // Since available # of writes are already confirmed,
+ // this should not happen.
+ // TODO: error handing?
+ ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+ return;
+ }
+ pending.pop_front();
+ posted.push_back(id);
+ }
+ }
+}
+
+void BufferStatusChannel::postBufferInvalidateAck(
+ ConnectionId connectionId,
+ uint32_t invalidateId,
+ bool *invalidated) {
+ if (mValid && !*invalidated) {
+ size_t avail = mBufferStatusQueue->availableToWrite();
+ if (avail > 0) {
+ BufferStatusMessage message;
+ message.status = BufferStatus::INVALIDATION_ACK;
+ message.bufferId = invalidateId;
+ message.connectionId = connectionId;
+ if (!mBufferStatusQueue->write(&message, 1)) {
+ // Since available # of writes are already confirmed,
+ // this should not happen.
+ // TODO: error handing?
+ ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+ return;
+ }
+ *invalidated = true;
+ }
+ }
+}
+
+bool BufferStatusChannel::postBufferStatusMessage(
+ TransactionId transactionId, BufferId bufferId,
+ BufferStatus status, ConnectionId connectionId, ConnectionId targetId,
+ std::list<BufferId> &pending, std::list<BufferId> &posted) {
+ if (mValid) {
+ size_t avail = mBufferStatusQueue->availableToWrite();
+ size_t numPending = pending.size();
+ if (avail >= numPending + 1) {
+ BufferStatusMessage release, message;
+ for (size_t i = 0; i < numPending; ++i) {
+ BufferId id = pending.front();
+ release.status = BufferStatus::NOT_USED;
+ release.bufferId = id;
+ release.connectionId = connectionId;
+ if (!mBufferStatusQueue->write(&release, 1)) {
+ // Since available # of writes are already confirmed,
+ // this should not happen.
+ // TODO: error handling?
+ ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+ return false;
+ }
+ pending.pop_front();
+ posted.push_back(id);
+ }
+ message.transactionId = transactionId;
+ message.bufferId = bufferId;
+ message.status = status;
+ message.connectionId = connectionId;
+ message.targetConnectionId = targetId;
+ // TODO : timesatamp
+ message.timestampUs = 0;
+ if (!mBufferStatusQueue->write(&message, 1)) {
+ // Since available # of writes are already confirmed,
+ // this should not happen.
+ ALOGW("FMQ message cannot be sent from %lld", (long long)connectionId);
+ return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+BufferInvalidationListener::BufferInvalidationListener(
+ const InvalidationDescriptor &fmqDesc) {
+ std::unique_ptr<BufferInvalidationQueue> queue =
+ std::make_unique<BufferInvalidationQueue>(fmqDesc);
+ if (!queue || queue->isValid() == false) {
+ mValid = false;
+ return;
+ }
+ mValid = true;
+ mBufferInvalidationQueue = std::move(queue);
+ // drain previous messages
+ size_t avail = std::min(
+ mBufferInvalidationQueue->availableToRead(), (size_t) kNumElementsInQueue);
+ std::vector<BufferInvalidationMessage> temp(avail);
+ if (avail > 0) {
+ mBufferInvalidationQueue->read(temp.data(), avail);
+ }
+}
+
+void BufferInvalidationListener::getInvalidations(
+ std::vector<BufferInvalidationMessage> &messages) {
+ // Try twice in case of overflow.
+ // TODO: handling overflow though it may not happen.
+ for (int i = 0; i < 2; ++i) {
+ size_t avail = std::min(
+ mBufferInvalidationQueue->availableToRead(), (size_t) kNumElementsInQueue);
+ if (avail > 0) {
+ std::vector<BufferInvalidationMessage> temp(avail);
+ if (mBufferInvalidationQueue->read(temp.data(), avail)) {
+ messages.reserve(messages.size() + avail);
+ for (auto it = temp.begin(); it != temp.end(); ++it) {
+ messages.push_back(*it);
+ }
+ break;
+ }
+ } else {
+ return;
+ }
+ }
+}
+
+bool BufferInvalidationListener::isValid() {
+ return mValid;
+}
+
+BufferInvalidationChannel::BufferInvalidationChannel()
+ : mValid(true),
+ mBufferInvalidationQueue(
+ std::make_unique<BufferInvalidationQueue>(kNumElementsInQueue, true)) {
+ if (!mBufferInvalidationQueue || mBufferInvalidationQueue->isValid() == false) {
+ mValid = false;
+ }
+}
+
+bool BufferInvalidationChannel::isValid() {
+ return mValid;
+}
+
+void BufferInvalidationChannel::getDesc(InvalidationDescriptor *fmqDescPtr) {
+ if (mValid) {
+ *fmqDescPtr = mBufferInvalidationQueue->dupeDesc();
+ }
+ // TODO: writing invalid descriptor?
+}
+
+void BufferInvalidationChannel::postInvalidation(
+ uint32_t msgId, BufferId fromId, BufferId toId) {
+ BufferInvalidationMessage message;
+
+ message.messageId = msgId;
+ message.fromBufferId = fromId;
+ message.toBufferId = toId;
+ // TODO: handle failure (it does not happen normally.)
+ mBufferInvalidationQueue->write(&message);
+}
+
+} // namespace ::aidl::android::hardware::media::bufferpool2::implementation
+
diff --git a/media/bufferpool/aidl/default/BufferStatus.h b/media/bufferpool/aidl/default/BufferStatus.h
new file mode 100644
index 0000000..3dd92f4
--- /dev/null
+++ b/media/bufferpool/aidl/default/BufferStatus.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <bufferpool2/BufferPoolTypes.h>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <vector>
+#include <list>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId);
+
+bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId);
+
+/**
+ * A collection of buffer status message FMQ for a buffer pool. buffer
+ * ownership/status change messages are sent via the FMQs from the clients.
+ */
+class BufferStatusObserver {
+private:
+ std::map<ConnectionId, std::unique_ptr<BufferStatusQueue>>
+ mBufferStatusQueues;
+
+public:
+ /** Creates a buffer status message FMQ for the specified
+ * connection(client).
+ *
+ * @param connectionId connection Id of the specified client.
+ * @param fmqDescPtr ptr of created FMQ's descriptor.
+ *
+ * @return OK if FMQ is created successfully.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus open(ConnectionId id, StatusDescriptor* _Nonnull fmqDescPtr);
+
+ /** Closes a buffer status message FMQ for the specified
+ * connection(client).
+ *
+ * @param connectionId connection Id of the specified client.
+ *
+ * @return OK if the specified connection is closed successfully.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus close(ConnectionId id);
+
+ /** Retrieves all pending FMQ buffer status messages from clients.
+ *
+ * @param messages retrieved pending messages.
+ */
+ void getBufferStatusChanges(std::vector<BufferStatusMessage> &messages);
+};
+
+/**
+ * A buffer status message FMQ for a buffer pool client. Buffer ownership/status
+ * change messages are sent via the fmq to the buffer pool.
+ */
+class BufferStatusChannel {
+private:
+ bool mValid;
+ std::unique_ptr<BufferStatusQueue> mBufferStatusQueue;
+
+public:
+ /**
+ * Connects to a buffer status message FMQ from a descriptor of
+ * the created FMQ.
+ *
+ * @param fmqDesc Descriptor of the created FMQ.
+ */
+ BufferStatusChannel(const StatusDescriptor &fmqDesc);
+
+ /** Returns whether the FMQ is connected successfully. */
+ bool isValid();
+
+ /** Returns whether the FMQ needs to be synced from the buffer pool */
+ bool needsSync();
+
+ /**
+ * Posts a buffer release message to the buffer pool.
+ *
+ * @param connectionId connection Id of the client.
+ * @param pending currently pending buffer release messages.
+ * @param posted posted buffer release messages.
+ */
+ void postBufferRelease(
+ ConnectionId connectionId,
+ std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+ /**
+ * Posts a buffer status message regarding the specified buffer
+ * transfer transaction.
+ *
+ * @param transactionId Id of the specified transaction.
+ * @param bufferId buffer Id of the specified transaction.
+ * @param status new status of the buffer.
+ * @param connectionId connection Id of the client.
+ * @param targetId connection Id of the receiver(only when the sender
+ * posts a status message).
+ * @param pending currently pending buffer release messages.
+ * @param posted posted buffer release messages.
+ *
+ * @return {@code true} when the specified message is posted,
+ * {@code false} otherwise.
+ */
+ bool postBufferStatusMessage(
+ TransactionId transactionId,
+ BufferId bufferId,
+ BufferStatus status,
+ ConnectionId connectionId,
+ ConnectionId targetId,
+ std::list<BufferId> &pending, std::list<BufferId> &posted);
+
+ /**
+ * Posts a buffer invaliadation message to the buffer pool.
+ *
+ * @param connectionId connection Id of the client.
+ * @param invalidateId invalidation ack to the buffer pool.
+ * if invalidation id is zero, the ack will not be
+ * posted.
+ * @param invalidated sets {@code true} only when the invalidation ack is
+ * posted.
+ */
+ void postBufferInvalidateAck(
+ ConnectionId connectionId,
+ uint32_t invalidateId,
+ bool* _Nonnull invalidated);
+};
+
+/**
+ * A buffer invalidation FMQ for a buffer pool client. Buffer invalidation
+ * messages are received via the fmq from the buffer pool. Buffer invalidation
+ * messages are handled as soon as possible.
+ */
+class BufferInvalidationListener {
+private:
+ bool mValid;
+ std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
+
+public:
+ /**
+ * Connects to a buffer invalidation FMQ from a descriptor of the created FMQ.
+ *
+ * @param fmqDesc Descriptor of the created FMQ.
+ */
+ BufferInvalidationListener(const InvalidationDescriptor &fmqDesc);
+
+ /** Retrieves all pending buffer invalidation messages from the buffer pool.
+ *
+ * @param messages retrieved pending messages.
+ */
+ void getInvalidations(std::vector<BufferInvalidationMessage> &messages);
+
+ /** Returns whether the FMQ is connected successfully. */
+ bool isValid();
+};
+
+/**
+ * A buffer invalidation FMQ for a buffer pool. A buffer pool will send buffer
+ * invalidation messages to the clients via the FMQ. The FMQ is shared among
+ * buffer pool clients.
+ */
+class BufferInvalidationChannel {
+private:
+ bool mValid;
+ std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
+
+public:
+ /**
+ * Creates a buffer invalidation FMQ for a buffer pool.
+ */
+ BufferInvalidationChannel();
+
+ /** Returns whether the FMQ is connected successfully. */
+ bool isValid();
+
+ /**
+ * Retrieves the descriptor of a buffer invalidation FMQ. the descriptor may
+ * be passed to the client for buffer invalidation handling.
+ *
+ * @param fmqDescPtr ptr of created FMQ's descriptor.
+ */
+ void getDesc(InvalidationDescriptor* _Nonnull fmqDescPtr);
+
+ /** Posts a buffer invalidation for invalidated buffers.
+ *
+ * @param msgId Invalidation message id which is used when clients send
+ * acks back via BufferStatusMessage
+ * @param fromId The start bufferid of the invalidated buffers(inclusive)
+ * @param toId The end bufferId of the invalidated buffers(inclusive)
+ */
+ void postInvalidation(uint32_t msgId, BufferId fromId, BufferId toId);
+};
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/ClientManager.cpp b/media/bufferpool/aidl/default/ClientManager.cpp
new file mode 100644
index 0000000..de1db50
--- /dev/null
+++ b/media/bufferpool/aidl/default/ClientManager.cpp
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "AidlBufferPoolMgr"
+//#define LOG_NDEBUG 0
+
+#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
+#include <bufferpool2/ClientManager.h>
+
+#include <sys/types.h>
+#include <utils/SystemClock.h>
+#include <unistd.h>
+#include <utils/Log.h>
+
+#include <chrono>
+
+#include "BufferPoolClient.h"
+#include "Observer.h"
+#include "Accessor.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using namespace std::chrono_literals;
+
+using Registration = aidl::android::hardware::media::bufferpool2::IClientManager::Registration;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+
+static constexpr int64_t kRegisterTimeoutMs = 500; // 0.5 sec
+static constexpr int64_t kCleanUpDurationMs = 1000; // TODO: 1 sec tune
+static constexpr int64_t kClientTimeoutMs = 5000; // TODO: 5 secs tune
+
+class ClientManager::Impl {
+public:
+ Impl();
+
+ // BnRegisterSender
+ BufferPoolStatus registerSender(const std::shared_ptr<IAccessor> &accessor,
+ Registration *pRegistration);
+
+ // BpRegisterSender
+ BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
+ ConnectionId senderId,
+ ConnectionId *receiverId,
+ bool *isNew);
+
+ BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+ ConnectionId *pConnectionId);
+
+ BufferPoolStatus close(ConnectionId connectionId);
+
+ BufferPoolStatus flush(ConnectionId connectionId);
+
+ BufferPoolStatus allocate(ConnectionId connectionId,
+ const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ BufferPoolStatus receive(ConnectionId connectionId,
+ TransactionId transactionId,
+ BufferId bufferId,
+ int64_t timestampMs,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ BufferPoolStatus postSend(ConnectionId receiverId,
+ const std::shared_ptr<BufferPoolData> &buffer,
+ TransactionId *transactionId,
+ int64_t *timestampMs);
+
+ BufferPoolStatus getAccessor(ConnectionId connectionId,
+ std::shared_ptr<IAccessor> *accessor);
+
+ void cleanUp(bool clearCache = false);
+
+private:
+ // In order to prevent deadlock between multiple locks,
+ // always lock ClientCache.lock before locking ActiveClients.lock.
+ struct ClientCache {
+ // This lock is held for brief duration.
+ // Blocking operation is not performed while holding the lock.
+ std::mutex mMutex;
+ std::list<std::pair<const std::weak_ptr<IAccessor>, const std::weak_ptr<BufferPoolClient>>>
+ mClients;
+ std::condition_variable mConnectCv;
+ bool mConnecting;
+ int64_t mLastCleanUpMs;
+
+ ClientCache() : mConnecting(false), mLastCleanUpMs(::android::elapsedRealtime()) {}
+ } mCache;
+
+ // Active clients which can be retrieved via ConnectionId
+ struct ActiveClients {
+ // This lock is held for brief duration.
+ // Blocking operation is not performed holding the lock.
+ std::mutex mMutex;
+ std::map<ConnectionId, const std::shared_ptr<BufferPoolClient>>
+ mClients;
+ } mActive;
+
+ std::shared_ptr<Observer> mObserver;
+};
+
+ClientManager::Impl::Impl()
+ : mObserver(::ndk::SharedRefBase::make<Observer>()) {}
+
+BufferPoolStatus ClientManager::Impl::registerSender(
+ const std::shared_ptr<IAccessor> &accessor, Registration *pRegistration) {
+ cleanUp();
+ int64_t timeoutMs = ::android::elapsedRealtime() + kRegisterTimeoutMs;
+ do {
+ std::unique_lock<std::mutex> lock(mCache.mMutex);
+ for (auto it = mCache.mClients.begin(); it != mCache.mClients.end(); ++it) {
+ std::shared_ptr<IAccessor> sAccessor = it->first.lock();
+ if (sAccessor && sAccessor.get() == accessor.get()) {
+ const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+ if (client) {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ pRegistration->connectionId = client->getConnectionId();
+ if (mActive.mClients.find(pRegistration->connectionId)
+ != mActive.mClients.end()) {
+ ALOGV("register existing connection %lld",
+ (long long)pRegistration->connectionId);
+ pRegistration->isNew = false;
+ return ResultStatus::OK;
+ }
+ }
+ mCache.mClients.erase(it);
+ break;
+ }
+ }
+ if (!mCache.mConnecting) {
+ mCache.mConnecting = true;
+ lock.unlock();
+ BufferPoolStatus result = ResultStatus::OK;
+ const std::shared_ptr<BufferPoolClient> client =
+ std::make_shared<BufferPoolClient>(accessor, mObserver);
+ lock.lock();
+ if (!client) {
+ result = ResultStatus::NO_MEMORY;
+ } else if (!client->isValid()) {
+ result = ResultStatus::CRITICAL_ERROR;
+ }
+ if (result == ResultStatus::OK) {
+ // TODO: handle insert fail. (malloc fail)
+ const std::weak_ptr<BufferPoolClient> wclient = client;
+ mCache.mClients.push_back(std::make_pair(accessor, wclient));
+ ConnectionId conId = client->getConnectionId();
+ mObserver->addClient(conId, wclient);
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ mActive.mClients.insert(std::make_pair(conId, client));
+ }
+ pRegistration->connectionId = conId;
+ pRegistration->isNew = true;
+ ALOGV("register new connection %lld", (long long)conId);
+ }
+ mCache.mConnecting = false;
+ lock.unlock();
+ mCache.mConnectCv.notify_all();
+ return result;
+ }
+ mCache.mConnectCv.wait_for(lock, kRegisterTimeoutMs*1ms);
+ } while (::android::elapsedRealtime() < timeoutMs);
+ // TODO: return timeout error
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::Impl::registerSender(
+ const std::shared_ptr<IClientManager> &receiver,
+ ConnectionId senderId,
+ ConnectionId *receiverId,
+ bool *isNew) {
+ std::shared_ptr<IAccessor> accessor;
+ bool local = false;
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ auto it = mActive.mClients.find(senderId);
+ if (it == mActive.mClients.end()) {
+ return ResultStatus::NOT_FOUND;
+ }
+ it->second->getAccessor(&accessor);
+ local = it->second->isLocal();
+ }
+ if (accessor) {
+ Registration registration;
+ ::ndk::ScopedAStatus status = receiver->registerSender(accessor, ®istration);
+ if (!status.isOk()) {
+ return ResultStatus::CRITICAL_ERROR;
+ } else if (local) {
+ std::shared_ptr<ConnectionDeathRecipient> recipient =
+ Accessor::getConnectionDeathRecipient();
+ if (recipient) {
+ ALOGV("client death recipient registered %lld", (long long)*receiverId);
+ recipient->addCookieToConnection(receiver->asBinder().get(), *receiverId);
+ AIBinder_linkToDeath(receiver->asBinder().get(), recipient->getRecipient(),
+ receiver->asBinder().get());
+ }
+ }
+ *receiverId = registration.connectionId;
+ *isNew = registration.isNew;
+ return ResultStatus::OK;
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::Impl::create(
+ const std::shared_ptr<BufferPoolAllocator> &allocator,
+ ConnectionId *pConnectionId) {
+ std::shared_ptr<Accessor> accessor = ::ndk::SharedRefBase::make<Accessor>(allocator);
+ if (!accessor || !accessor->isValid()) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ // TODO: observer is local. use direct call instead of hidl call.
+ std::shared_ptr<BufferPoolClient> client =
+ std::make_shared<BufferPoolClient>(accessor, mObserver);
+ if (!client || !client->isValid()) {
+ return ResultStatus::CRITICAL_ERROR;
+ }
+ // Since a new bufferpool is created, evict memories which are used by
+ // existing bufferpools and clients.
+ cleanUp(true);
+ {
+ // TODO: handle insert fail. (malloc fail)
+ std::lock_guard<std::mutex> lock(mCache.mMutex);
+ const std::weak_ptr<BufferPoolClient> wclient = client;
+ mCache.mClients.push_back(std::make_pair(accessor, wclient));
+ ConnectionId conId = client->getConnectionId();
+ mObserver->addClient(conId, wclient);
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ mActive.mClients.insert(std::make_pair(conId, client));
+ }
+ *pConnectionId = conId;
+ ALOGV("create new connection %lld", (long long)*pConnectionId);
+ }
+ return ResultStatus::OK;
+}
+
+BufferPoolStatus ClientManager::Impl::close(ConnectionId connectionId) {
+ std::unique_lock<std::mutex> lock1(mCache.mMutex);
+ std::unique_lock<std::mutex> lock2(mActive.mMutex);
+ auto it = mActive.mClients.find(connectionId);
+ if (it != mActive.mClients.end()) {
+ std::shared_ptr<IAccessor> accessor;
+ it->second->getAccessor(&accessor);
+ std::shared_ptr<BufferPoolClient> closing = it->second;
+ mActive.mClients.erase(connectionId);
+ for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+ // clean up dead client caches
+ std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
+ if (!cAccessor || (accessor && cAccessor.get() == accessor.get())) {
+ cit = mCache.mClients.erase(cit);
+ } else {
+ cit++;
+ }
+ }
+ lock2.unlock();
+ lock1.unlock();
+ closing->flush();
+ return ResultStatus::OK;
+ }
+ return ResultStatus::NOT_FOUND;
+}
+
+BufferPoolStatus ClientManager::Impl::flush(ConnectionId connectionId) {
+ std::shared_ptr<BufferPoolClient> client;
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ auto it = mActive.mClients.find(connectionId);
+ if (it == mActive.mClients.end()) {
+ return ResultStatus::NOT_FOUND;
+ }
+ client = it->second;
+ }
+ return client->flush();
+}
+
+BufferPoolStatus ClientManager::Impl::allocate(
+ ConnectionId connectionId, const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+ std::shared_ptr<BufferPoolClient> client;
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ auto it = mActive.mClients.find(connectionId);
+ if (it == mActive.mClients.end()) {
+ return ResultStatus::NOT_FOUND;
+ }
+ client = it->second;
+ }
+#ifdef BUFFERPOOL_CLONE_HANDLES
+ native_handle_t *origHandle;
+ BufferPoolStatus res = client->allocate(params, &origHandle, buffer);
+ if (res != ResultStatus::OK) {
+ return res;
+ }
+ *handle = native_handle_clone(origHandle);
+ if (handle == NULL) {
+ buffer->reset();
+ return ResultStatus::NO_MEMORY;
+ }
+ return ResultStatus::OK;
+#else
+ return client->allocate(params, handle, buffer);
+#endif
+}
+
+BufferPoolStatus ClientManager::Impl::receive(
+ ConnectionId connectionId, TransactionId transactionId,
+ BufferId bufferId, int64_t timestampMs,
+ native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+ std::shared_ptr<BufferPoolClient> client;
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ auto it = mActive.mClients.find(connectionId);
+ if (it == mActive.mClients.end()) {
+ return ResultStatus::NOT_FOUND;
+ }
+ client = it->second;
+ }
+#ifdef BUFFERPOOL_CLONE_HANDLES
+ native_handle_t *origHandle;
+ BufferPoolStatus res = client->receive(
+ transactionId, bufferId, timestampMs, &origHandle, buffer);
+ if (res != ResultStatus::OK) {
+ return res;
+ }
+ *handle = native_handle_clone(origHandle);
+ if (handle == NULL) {
+ buffer->reset();
+ return ResultStatus::NO_MEMORY;
+ }
+ return ResultStatus::OK;
+#else
+ return client->receive(transactionId, bufferId, timestampMs, handle, buffer);
+#endif
+}
+
+BufferPoolStatus ClientManager::Impl::postSend(
+ ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+ TransactionId *transactionId, int64_t *timestampMs) {
+ ConnectionId connectionId = buffer->mConnectionId;
+ std::shared_ptr<BufferPoolClient> client;
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ auto it = mActive.mClients.find(connectionId);
+ if (it == mActive.mClients.end()) {
+ return ResultStatus::NOT_FOUND;
+ }
+ client = it->second;
+ }
+ return client->postSend(receiverId, buffer, transactionId, timestampMs);
+}
+
+BufferPoolStatus ClientManager::Impl::getAccessor(
+ ConnectionId connectionId, std::shared_ptr<IAccessor> *accessor) {
+ std::shared_ptr<BufferPoolClient> client;
+ {
+ std::lock_guard<std::mutex> lock(mActive.mMutex);
+ auto it = mActive.mClients.find(connectionId);
+ if (it == mActive.mClients.end()) {
+ return ResultStatus::NOT_FOUND;
+ }
+ client = it->second;
+ }
+ return client->getAccessor(accessor);
+}
+
+void ClientManager::Impl::cleanUp(bool clearCache) {
+ int64_t now = ::android::elapsedRealtime();
+ int64_t lastTransactionMs;
+ std::lock_guard<std::mutex> lock1(mCache.mMutex);
+ if (clearCache || mCache.mLastCleanUpMs + kCleanUpDurationMs < now) {
+ std::lock_guard<std::mutex> lock2(mActive.mMutex);
+ int cleaned = 0;
+ for (auto it = mActive.mClients.begin(); it != mActive.mClients.end();) {
+ if (!it->second->isActive(&lastTransactionMs, clearCache)) {
+ if (lastTransactionMs + kClientTimeoutMs < now) {
+ std::shared_ptr<IAccessor> accessor;
+ it->second->getAccessor(&accessor);
+ it = mActive.mClients.erase(it);
+ ++cleaned;
+ continue;
+ }
+ }
+ ++it;
+ }
+ for (auto cit = mCache.mClients.begin(); cit != mCache.mClients.end();) {
+ // clean up dead client caches
+ std::shared_ptr<IAccessor> cAccessor = cit->first.lock();
+ if (!cAccessor) {
+ cit = mCache.mClients.erase(cit);
+ } else {
+ ++cit;
+ }
+ }
+ ALOGV("# of cleaned connections: %d", cleaned);
+ mCache.mLastCleanUpMs = now;
+ }
+}
+
+::ndk::ScopedAStatus ClientManager::registerSender(
+ const std::shared_ptr<IAccessor>& in_bufferPool, Registration* _aidl_return) {
+ BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+ if (mImpl) {
+ status = mImpl->registerSender(in_bufferPool, _aidl_return);
+ }
+ if (status != ResultStatus::OK) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(status);
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+// Methods for local use.
+std::shared_ptr<ClientManager> ClientManager::sInstance;
+std::mutex ClientManager::sInstanceLock;
+
+std::shared_ptr<ClientManager> ClientManager::getInstance() {
+ std::lock_guard<std::mutex> lock(sInstanceLock);
+ if (!sInstance) {
+ sInstance = ::ndk::SharedRefBase::make<ClientManager>();
+ // TODO: configure thread count for threadpool properly
+ // after b/261652496 is resolved.
+ }
+ Accessor::createInvalidator();
+ Accessor::createEvictor();
+ return sInstance;
+}
+
+ClientManager::ClientManager() : mImpl(new Impl()) {}
+
+ClientManager::~ClientManager() {
+}
+
+BufferPoolStatus ClientManager::create(
+ const std::shared_ptr<BufferPoolAllocator> &allocator,
+ ConnectionId *pConnectionId) {
+ if (mImpl) {
+ return mImpl->create(allocator, pConnectionId);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::registerSender(
+ const std::shared_ptr<IClientManager> &receiver,
+ ConnectionId senderId,
+ ConnectionId *receiverId,
+ bool *isNew) {
+ if (mImpl) {
+ return mImpl->registerSender(receiver, senderId, receiverId, isNew);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::close(ConnectionId connectionId) {
+ if (mImpl) {
+ return mImpl->close(connectionId);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::flush(ConnectionId connectionId) {
+ if (mImpl) {
+ return mImpl->flush(connectionId);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::allocate(
+ ConnectionId connectionId, const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+ if (mImpl) {
+ return mImpl->allocate(connectionId, params, handle, buffer);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::receive(
+ ConnectionId connectionId, TransactionId transactionId,
+ BufferId bufferId, int64_t timestampMs,
+ native_handle_t **handle, std::shared_ptr<BufferPoolData> *buffer) {
+ if (mImpl) {
+ return mImpl->receive(connectionId, transactionId, bufferId,
+ timestampMs, handle, buffer);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus ClientManager::postSend(
+ ConnectionId receiverId, const std::shared_ptr<BufferPoolData> &buffer,
+ TransactionId *transactionId, int64_t* timestampMs) {
+ if (mImpl && buffer) {
+ return mImpl->postSend(receiverId, buffer, transactionId, timestampMs);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+void ClientManager::cleanUp() {
+ if (mImpl) {
+ mImpl->cleanUp(true);
+ }
+}
+
+} // namespace ::aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Connection.cpp b/media/bufferpool/aidl/default/Connection.cpp
new file mode 100644
index 0000000..53d350d
--- /dev/null
+++ b/media/bufferpool/aidl/default/Connection.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "AidlBufferPoolCon"
+//#define LOG_NDEBUG 0
+
+#include <aidlcommonsupport/NativeHandle.h>
+
+#include "Connection.h"
+#include "Accessor.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using Buffer = aidl::android::hardware::media::bufferpool2::Buffer;
+using FetchInfo = aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo;
+using FetchResult = aidl::android::hardware::media::bufferpool2::IConnection::FetchResult;
+
+::ndk::ScopedAStatus Connection::fetch(const std::vector<FetchInfo>& in_fetchInfos,
+ std::vector<FetchResult>* _aidl_return) {
+ int success = 0;
+ int failure = 0;
+ if (mInitialized && mAccessor) {
+ for (auto it = in_fetchInfos.begin(); it != in_fetchInfos.end(); ++it) {
+ if (fetch(it->transactionId, it->bufferId, _aidl_return)) {
+ success++;
+ } else {
+ failure++;
+ }
+ }
+ if (failure > 0) {
+ ALOGD("total fetch %d, failure %d", success + failure, failure);
+ }
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(ResultStatus::CRITICAL_ERROR);
+}
+
+::ndk::ScopedAStatus Connection::sync() {
+ if (mInitialized && mAccessor) {
+ mAccessor->cleanUp(false);
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+
+bool Connection::fetch(TransactionId transactionId, BufferId bufferId,
+ std::vector<FetchResult> *result) {
+ BufferPoolStatus status = ResultStatus::CRITICAL_ERROR;
+ const native_handle_t *handle = nullptr;
+ status = mAccessor->fetch(
+ mConnectionId, transactionId, bufferId, &handle);
+ if (status == ResultStatus::OK) {
+ result->emplace_back(FetchResult::make<FetchResult::buffer>());
+ result->back().get<FetchResult::buffer>().id = bufferId;
+ result->back().get<FetchResult::buffer>().buffer = ::android::dupToAidl(handle);
+ return true;
+ }
+ result->emplace_back(FetchResult::make<FetchResult::failure>(status));
+ return false;
+}
+
+Connection::Connection() : mInitialized(false), mConnectionId(-1LL) {}
+
+Connection::~Connection() {
+ if (mInitialized && mAccessor) {
+ mAccessor->close(mConnectionId);
+ }
+}
+
+void Connection::initialize(
+ const std::shared_ptr<Accessor>& accessor, ConnectionId connectionId) {
+ if (!mInitialized) {
+ mAccessor = accessor;
+ mConnectionId = connectionId;
+ mInitialized = true;
+ }
+}
+
+BufferPoolStatus Connection::flush() {
+ if (mInitialized && mAccessor) {
+ return mAccessor->flush();
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+BufferPoolStatus Connection::allocate(
+ const std::vector<uint8_t> ¶ms, BufferId *bufferId,
+ const native_handle_t **handle) {
+ if (mInitialized && mAccessor) {
+ return mAccessor->allocate(mConnectionId, params, bufferId, handle);
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+void Connection::cleanUp(bool clearCache) {
+ if (mInitialized && mAccessor) {
+ mAccessor->cleanUp(clearCache);
+ }
+}
+
+} // namespace ::aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Connection.h b/media/bufferpool/aidl/default/Connection.h
new file mode 100644
index 0000000..d8298af
--- /dev/null
+++ b/media/bufferpool/aidl/default/Connection.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <aidl/android/hardware/media/bufferpool2/BnConnection.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+struct Accessor;
+
+struct Connection : public BnConnection {
+ // Methods from ::aidl::android::hardware::media::bufferpool2::IConnection.
+ ::ndk::ScopedAStatus fetch(const std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchInfo>& in_fetchInfos, std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchResult>* _aidl_return) override;
+
+ // Methods from ::aidl::android::hardware::media::bufferpool2::IConnection.
+ ::ndk::ScopedAStatus sync() override;
+
+ /**
+ * Invalidates all buffers which are active and/or are ready to be recycled.
+ */
+ BufferPoolStatus flush();
+
+ /**
+ * Allocates a buffer using the specified parameters. Recycles a buffer if
+ * it is possible. The returned buffer can be transferred to other remote
+ * clients(Connection).
+ *
+ * @param params allocation parameters.
+ * @param bufferId Id of the allocated buffer.
+ * @param handle native handle of the allocated buffer.
+ *
+ * @return OK if a buffer is successfully allocated.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus allocate(const std::vector<uint8_t> ¶ms,
+ BufferId *bufferId, const native_handle_t **handle);
+
+ /**
+ * Processes pending buffer status messages and performs periodic cache cleaning
+ * from bufferpool.
+ *
+ * @param clearCache if clearCache is true, bufferpool frees all buffers
+ * waiting to be recycled.
+ */
+ void cleanUp(bool clearCache);
+
+ /** Destructs a connection. */
+ ~Connection();
+
+ /** Creates a connection. */
+ Connection();
+
+ /**
+ * Initializes with the specified buffer pool and the connection id.
+ * The connection id should be unique in the whole system.
+ *
+ * @param accessor the specified buffer pool.
+ * @param connectionId Id.
+ */
+ void initialize(const std::shared_ptr<Accessor> &accessor, ConnectionId connectionId);
+
+ enum : uint32_t {
+ SYNC_BUFFERID = UINT32_MAX,
+ };
+
+private:
+ bool mInitialized;
+ std::shared_ptr<Accessor> mAccessor;
+ ConnectionId mConnectionId;
+
+ bool fetch(
+ uint64_t transactionId,
+ uint32_t bufferId,
+ std::vector<::aidl::android::hardware::media::bufferpool2::IConnection::FetchResult>
+ *result);
+};
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/DataHelper.h b/media/bufferpool/aidl/default/DataHelper.h
new file mode 100644
index 0000000..a90b3c7
--- /dev/null
+++ b/media/bufferpool/aidl/default/DataHelper.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/BufferStatusMessage.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+#include <map>
+#include <set>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+ auto iter = mapOfSet->find(key);
+ if (iter == mapOfSet->end()) {
+ std::set<U> valueSet{value};
+ mapOfSet->insert(std::make_pair(key, valueSet));
+ return true;
+ } else if (iter->second.find(value) == iter->second.end()) {
+ iter->second.insert(value);
+ return true;
+ }
+ return false;
+}
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+ bool ret = false;
+ auto iter = mapOfSet->find(key);
+ if (iter != mapOfSet->end()) {
+ if (iter->second.erase(value) > 0) {
+ ret = true;
+ }
+ if (iter->second.size() == 0) {
+ mapOfSet->erase(iter);
+ }
+ }
+ return ret;
+}
+
+// Helper template methods for handling map of set.
+template<class T, class U>
+bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
+ auto iter = mapOfSet->find(key);
+ if (iter != mapOfSet->end()) {
+ auto setIter = iter->second.find(value);
+ return setIter != iter->second.end();
+ }
+ return false;
+}
+
+// Buffer data structure for internal BufferPool use.(storage/fetching)
+struct InternalBuffer {
+ BufferId mId;
+ size_t mOwnerCount;
+ size_t mTransactionCount;
+ const std::shared_ptr<BufferPoolAllocation> mAllocation;
+ const size_t mAllocSize;
+ const std::vector<uint8_t> mConfig;
+ bool mInvalidated;
+
+ InternalBuffer(
+ BufferId id,
+ const std::shared_ptr<BufferPoolAllocation> &alloc,
+ const size_t allocSize,
+ const std::vector<uint8_t> &allocConfig)
+ : mId(id), mOwnerCount(0), mTransactionCount(0),
+ mAllocation(alloc), mAllocSize(allocSize), mConfig(allocConfig),
+ mInvalidated(false) {}
+
+ const native_handle_t *handle() {
+ return mAllocation->handle();
+ }
+
+ void invalidate() {
+ mInvalidated = true;
+ }
+};
+
+// Buffer transacion status/message data structure for internal BufferPool use.
+struct TransactionStatus {
+ TransactionId mId;
+ BufferId mBufferId;
+ ConnectionId mSender;
+ ConnectionId mReceiver;
+ BufferStatus mStatus;
+ int64_t mTimestampMs;
+ bool mSenderValidated;
+
+ TransactionStatus(const BufferStatusMessage &message, int64_t timestampMs) {
+ mId = message.transactionId;
+ mBufferId = message.bufferId;
+ mStatus = message.status;
+ mTimestampMs = timestampMs;
+ if (mStatus == BufferStatus::TRANSFER_TO) {
+ mSender = message.connectionId;
+ mReceiver = message.targetConnectionId;
+ mSenderValidated = true;
+ } else {
+ mSender = -1LL;
+ mReceiver = message.connectionId;
+ mSenderValidated = false;
+ }
+ }
+};
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Observer.cpp b/media/bufferpool/aidl/default/Observer.cpp
new file mode 100644
index 0000000..a22e825
--- /dev/null
+++ b/media/bufferpool/aidl/default/Observer.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Observer.h"
+#include "BufferPoolClient.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+Observer::Observer() {
+}
+
+Observer::~Observer() {
+}
+
+::ndk::ScopedAStatus Observer::onMessage(int64_t in_connectionId, int32_t in_msgId) {
+ std::unique_lock<std::mutex> lock(mLock);
+ auto it = mClients.find(in_connectionId);
+ if (it != mClients.end()) {
+ const std::shared_ptr<BufferPoolClient> client = it->second.lock();
+ if (!client) {
+ mClients.erase(it);
+ } else {
+ lock.unlock();
+ client->receiveInvalidation(in_msgId);
+ }
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+void Observer::addClient(ConnectionId connectionId,
+ const std::weak_ptr<BufferPoolClient> &wclient) {
+ std::lock_guard<std::mutex> lock(mLock);
+ for (auto it = mClients.begin(); it != mClients.end();) {
+ if (!it->second.lock() || it->first == connectionId) {
+ it = mClients.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ mClients.insert(std::make_pair(connectionId, wclient));
+
+}
+
+void Observer::delClient(ConnectionId connectionId) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mClients.erase(connectionId);
+}
+
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
diff --git a/media/bufferpool/aidl/default/Observer.h b/media/bufferpool/aidl/default/Observer.h
new file mode 100644
index 0000000..febb21b
--- /dev/null
+++ b/media/bufferpool/aidl/default/Observer.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <aidl/android/hardware/media/bufferpool2/BnObserver.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+class BufferPoolClient;
+
+struct Observer : public BnObserver {
+ ::ndk::ScopedAStatus onMessage(int64_t in_connectionId, int32_t in_msgId) override;
+
+ ~Observer();
+
+ void addClient(ConnectionId connectionId,
+ const std::weak_ptr<BufferPoolClient> &wclient);
+
+ void delClient(ConnectionId connectionId);
+
+private:
+ Observer();
+
+ friend class ::ndk::SharedRefBase;
+
+ std::mutex mLock;
+ std::map<ConnectionId, const std::weak_ptr<BufferPoolClient>> mClients;
+};
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
+
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h b/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h
new file mode 100644
index 0000000..b833362
--- /dev/null
+++ b/media/bufferpool/aidl/default/include/bufferpool2/BufferPoolTypes.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cutils/native_handle.h>
+#include <fmq/AidlMessageQueue.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferStatusMessage.h>
+#include <aidl/android/hardware/media/bufferpool2/BufferInvalidationMessage.h>
+#include <aidl/android/hardware/media/bufferpool2/ResultStatus.h>
+
+namespace aidl::android::hardware::media::bufferpool2 {
+
+struct BufferPoolData {
+ // For local use, to specify a bufferpool (client connection) for buffers.
+ // Retrieved from returned info of IAccessor#connect([email protected]).
+ int64_t mConnectionId;
+ // BufferId
+ uint32_t mId;
+
+ BufferPoolData() : mConnectionId(0), mId(0) {}
+
+ BufferPoolData(
+ int64_t connectionId, uint32_t id)
+ : mConnectionId(connectionId), mId(id) {}
+
+ ~BufferPoolData() {}
+};
+
+namespace implementation {
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::common::fmq::UnsynchronizedWrite;
+
+using aidl::android::hardware::media::bufferpool2::BufferStatusMessage;
+using aidl::android::hardware::media::bufferpool2::BufferInvalidationMessage;
+
+typedef uint32_t BufferId;
+typedef uint64_t TransactionId;
+typedef int64_t ConnectionId;
+typedef int32_t BufferPoolStatus;
+
+// AIDL hal description language does not support unsigned.
+int32_t static inline ToAidl(BufferId id) {return static_cast<int32_t>(id);}
+int64_t static inline ToAidl(TransactionId id) {return static_cast<int64_t>(id);}
+
+BufferId static inline FromAidl(int32_t id) {return static_cast<BufferId>(id);}
+TransactionId static inline FromAidl(int64_t id) {return static_cast<TransactionId>(id);}
+
+enum : ConnectionId {
+ INVALID_CONNECTIONID = 0,
+};
+
+typedef ::android::AidlMessageQueue<BufferStatusMessage, SynchronizedReadWrite> BufferStatusQueue;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<BufferStatusMessage, SynchronizedReadWrite>
+ StatusDescriptor;
+
+typedef ::android::AidlMessageQueue<BufferInvalidationMessage, UnsynchronizedWrite>
+ BufferInvalidationQueue;
+typedef aidl::android::hardware::common::fmq::MQDescriptor<BufferInvalidationMessage, UnsynchronizedWrite>
+ InvalidationDescriptor;
+
+/**
+ * Allocation wrapper class for buffer pool.
+ */
+struct BufferPoolAllocation {
+ const native_handle_t *mHandle;
+
+ const native_handle_t *handle() {
+ return mHandle;
+ }
+
+ BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
+
+ ~BufferPoolAllocation() {};
+};
+
+/**
+ * Allocator wrapper class for buffer pool.
+ */
+class BufferPoolAllocator {
+public:
+
+ /**
+ * Allocate an allocation(buffer) for buffer pool.
+ *
+ * @param params allocation parameters
+ * @param alloc created allocation
+ * @param allocSize size of created allocation
+ *
+ * @return OK when an allocation is created successfully.
+ */
+ virtual BufferPoolStatus allocate(
+ const std::vector<uint8_t> ¶ms,
+ std::shared_ptr<BufferPoolAllocation> *alloc,
+ size_t *allocSize) = 0;
+
+ /**
+ * Returns whether allocation parameters of an old allocation are
+ * compatible with new allocation parameters.
+ */
+ virtual bool compatible(const std::vector<uint8_t> &newParams,
+ const std::vector<uint8_t> &oldParams) = 0;
+
+protected:
+ BufferPoolAllocator() = default;
+
+ virtual ~BufferPoolAllocator() = default;
+};
+
+} // namespace implementation
+} // namespace aidl::android::hareware::media::bufferpool2
+
diff --git a/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
new file mode 100644
index 0000000..bff75ba
--- /dev/null
+++ b/media/bufferpool/aidl/default/include/bufferpool2/ClientManager.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/media/bufferpool2/IAccessor.h>
+#include <aidl/android/hardware/media/bufferpool2/BnClientManager.h>
+#include <memory>
+#include "BufferPoolTypes.h"
+
+namespace aidl::android::hardware::media::bufferpool2::implementation {
+
+using aidl::android::hardware::media::bufferpool2::BnClientManager;
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::IAccessor;
+
+struct ClientManager : public BnClientManager {
+ // Methods from ::aidl::android::hardware::media::bufferpool2::IClientManager follow.
+ ::ndk::ScopedAStatus registerSender(
+ const std::shared_ptr<IAccessor>& in_bufferPool,
+ ::aidl::android::hardware::media::bufferpool2::IClientManager::Registration* _aidl_return)
+ override;
+
+ /** Gets an instance. */
+ static std::shared_ptr<ClientManager> getInstance();
+
+ /**
+ * Creates a local connection with a newly created buffer pool.
+ *
+ * @param allocator for new buffer allocation.
+ * @param pConnectionId Id of the created connection. This is
+ * system-wide unique.
+ *
+ * @return OK when a buffer pool and a local connection is successfully
+ * created.
+ * ResultStatus::NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
+ ConnectionId *pConnectionId);
+
+ /**
+ * Register a created connection as sender for remote process.
+ *
+ * @param receiver The remote receiving process.
+ * @param senderId A local connection which will send buffers to.
+ * @param receiverId Id of the created receiving connection on the receiver
+ * process.
+ * @param isNew @true when the receiving connection is newly created.
+ *
+ * @return OK when the receiving connection is successfully created on the
+ * receiver process.
+ * NOT_FOUND when the sender connection was not found.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus registerSender(const std::shared_ptr<IClientManager> &receiver,
+ ConnectionId senderId,
+ ConnectionId *receiverId,
+ bool *isNew);
+
+ /**
+ * Closes the specified connection.
+ *
+ * @param connectionId The id of the connection.
+ *
+ * @return OK when the connection is closed.
+ * NOT_FOUND when the specified connection was not found.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus close(ConnectionId connectionId);
+
+ /**
+ * Evicts cached allocations. If it's local connection, release the
+ * previous allocations and do not recycle current active allocations.
+ *
+ * @param connectionId The id of the connection.
+ *
+ * @return OK when the connection is resetted.
+ * NOT_FOUND when the specified connection was not found.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus flush(ConnectionId connectionId);
+
+ /**
+ * Allocates a buffer from the specified connection. The output parameter
+ * handle is cloned from the internal handle. So it is safe to use directly,
+ * and it should be deleted and destroyed after use.
+ *
+ * @param connectionId The id of the connection.
+ * @param params The allocation parameters.
+ * @param handle The native handle to the allocated buffer. handle
+ * should be cloned before use.
+ * @param buffer The allocated buffer.
+ *
+ * @return OK when a buffer was allocated successfully.
+ * NOT_FOUND when the specified connection was not found.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus allocate(ConnectionId connectionId,
+ const std::vector<uint8_t> ¶ms,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ /**
+ * Receives a buffer for the transaction. The output parameter handle is
+ * cloned from the internal handle. So it is safe to use directly, and it
+ * should be deleted and destoyed after use.
+ *
+ * @param connectionId The id of the receiving connection.
+ * @param transactionId The id for the transaction.
+ * @param bufferId The id for the buffer.
+ * @param timestampMs The timestamp of the buffer is being sent.
+ * @param handle The native handle to the allocated buffer. handle
+ * should be cloned before use.
+ * @param buffer The received buffer.
+ *
+ * @return OK when a buffer was received successfully.
+ * NOT_FOUND when the specified connection was not found.
+ * NO_MEMORY when there is no memory.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus receive(ConnectionId connectionId,
+ TransactionId transactionId,
+ BufferId bufferId,
+ int64_t timestampMs,
+ native_handle_t **handle,
+ std::shared_ptr<BufferPoolData> *buffer);
+
+ /**
+ * Posts a buffer transfer transaction to the buffer pool. Sends a buffer
+ * to other remote clients(connection) after this call has been succeeded.
+ *
+ * @param receiverId The id of the receiving connection.
+ * @param buffer to transfer
+ * @param transactionId Id of the transfer transaction.
+ * @param timestampMs The timestamp of the buffer transaction is being
+ * posted.
+ *
+ * @return OK when a buffer transaction was posted successfully.
+ * NOT_FOUND when the sending connection was not found.
+ * CRITICAL_ERROR otherwise.
+ */
+ BufferPoolStatus postSend(ConnectionId receiverId,
+ const std::shared_ptr<BufferPoolData> &buffer,
+ TransactionId *transactionId,
+ int64_t *timestampMs);
+
+ /**
+ * Time out inactive lingering connections and close.
+ */
+ void cleanUp();
+
+ /** Destructs the manager of buffer pool clients. */
+ ~ClientManager();
+private:
+ static std::shared_ptr<ClientManager> sInstance;
+ static std::mutex sInstanceLock;
+
+ class Impl;
+ const std::unique_ptr<Impl> mImpl;
+
+ friend class ::ndk::SharedRefBase;
+
+ ClientManager();
+};
+
+} // namespace aidl::android::hardware::media::bufferpool2::implementation
+
diff --git a/media/bufferpool/aidl/default/tests/Android.bp b/media/bufferpool/aidl/default/tests/Android.bp
new file mode 100644
index 0000000..549af57
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/Android.bp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_av_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsVndkAidlBufferpool2V1_0TargetSingleTest",
+ test_suites: ["device-tests"],
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "allocator.cpp",
+ "single.cpp",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libcutils",
+ "libfmq",
+ "liblog",
+ "libutils",
+ "android.hardware.media.bufferpool2-V1-ndk",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ "libstagefright_aidl_bufferpool2"
+ ],
+ compile_multilib: "both",
+}
+
+cc_test {
+ name: "VtsVndkAidlBufferpool2V1_0TargetMultiTest",
+ test_suites: ["device-tests"],
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "allocator.cpp",
+ "multi.cpp",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libcutils",
+ "libfmq",
+ "liblog",
+ "libutils",
+ "android.hardware.media.bufferpool2-V1-ndk",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ "libstagefright_aidl_bufferpool2"
+ ],
+ compile_multilib: "both",
+}
+
+cc_test {
+ name: "VtsVndkAidlBufferpool2V1_0TargetCondTest",
+ test_suites: ["device-tests"],
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "allocator.cpp",
+ "cond.cpp",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libcutils",
+ "libfmq",
+ "liblog",
+ "libutils",
+ "android.hardware.media.bufferpool2-V1-ndk",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ "libstagefright_aidl_bufferpool2"
+ ],
+ compile_multilib: "both",
+}
diff --git a/media/bufferpool/aidl/default/tests/allocator.cpp b/media/bufferpool/aidl/default/tests/allocator.cpp
new file mode 100644
index 0000000..16b33a6
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/allocator.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+#include "allocator.h"
+
+union Params {
+ struct {
+ uint32_t capacity;
+ } data;
+ uint8_t array[0];
+ Params() : data{0} {}
+ Params(uint32_t size)
+ : data{size} {}
+};
+
+
+namespace {
+
+struct HandleAshmem : public native_handle_t {
+ HandleAshmem(int ashmemFd, size_t size)
+ : native_handle_t(cHeader),
+ mFds{ ashmemFd },
+ mInts{ int (size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } {}
+
+ int ashmemFd() const { return mFds.mAshmem; }
+ size_t size() const {
+ return size_t(unsigned(mInts.mSizeLo))
+ | size_t(uint64_t(unsigned(mInts.mSizeHi)) << 32);
+ }
+
+ static bool isValid(const native_handle_t * const o);
+
+protected:
+ struct {
+ int mAshmem;
+ } mFds;
+ struct {
+ int mSizeLo;
+ int mSizeHi;
+ int mMagic;
+ } mInts;
+
+private:
+ enum {
+ kMagic = 'ahm\x00',
+ numFds = sizeof(mFds) / sizeof(int),
+ numInts = sizeof(mInts) / sizeof(int),
+ version = sizeof(native_handle_t)
+ };
+ const static native_handle_t cHeader;
+};
+
+const native_handle_t HandleAshmem::cHeader = {
+ HandleAshmem::version,
+ HandleAshmem::numFds,
+ HandleAshmem::numInts,
+ {}
+};
+
+bool HandleAshmem::isValid(const native_handle_t * const o) {
+ if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
+ return false;
+ }
+ const HandleAshmem *other = static_cast<const HandleAshmem*>(o);
+ return other->mInts.mMagic == kMagic;
+}
+
+class AllocationAshmem {
+private:
+ AllocationAshmem(int ashmemFd, size_t capacity, bool res)
+ : mHandle(ashmemFd, capacity),
+ mInit(res) {}
+
+public:
+ static AllocationAshmem *Alloc(size_t size) {
+ constexpr static const char *kAllocationTag = "bufferpool_test";
+ int ashmemFd = ashmem_create_region(kAllocationTag, size);
+ return new AllocationAshmem(ashmemFd, size, ashmemFd >= 0);
+ }
+
+ ~AllocationAshmem() {
+ if (mInit) {
+ native_handle_close(&mHandle);
+ }
+ }
+
+ const HandleAshmem *handle() {
+ return &mHandle;
+ }
+
+private:
+ HandleAshmem mHandle;
+ bool mInit;
+ // TODO: mapping and map fd
+};
+
+struct AllocationDtor {
+ AllocationDtor(const std::shared_ptr<AllocationAshmem> &alloc)
+ : mAlloc(alloc) {}
+
+ void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
+
+ const std::shared_ptr<AllocationAshmem> mAlloc;
+};
+
+}
+
+void IpcMutex::init() {
+ pthread_mutexattr_t mattr;
+ pthread_mutexattr_init(&mattr);
+ pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
+ pthread_mutex_init(&lock, &mattr);
+ pthread_mutexattr_destroy(&mattr);
+
+ pthread_condattr_t cattr;
+ pthread_condattr_init(&cattr);
+ pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
+ pthread_cond_init(&cond, &cattr);
+ pthread_condattr_destroy(&cattr);
+}
+
+IpcMutex *IpcMutex::Import(void *pMutex) {
+ return reinterpret_cast<IpcMutex *>(pMutex);
+}
+
+
+BufferPoolStatus TestBufferPoolAllocator::allocate(
+ const std::vector<uint8_t> ¶ms,
+ std::shared_ptr<BufferPoolAllocation> *alloc,
+ size_t *allocSize) {
+ Params ashmemParams;
+ memcpy(&ashmemParams, params.data(), std::min(sizeof(Params), params.size()));
+
+ std::shared_ptr<AllocationAshmem> ashmemAlloc =
+ std::shared_ptr<AllocationAshmem>(
+ AllocationAshmem::Alloc(ashmemParams.data.capacity));
+ if (ashmemAlloc) {
+ BufferPoolAllocation *ptr = new BufferPoolAllocation(ashmemAlloc->handle());
+ if (ptr) {
+ *alloc = std::shared_ptr<BufferPoolAllocation>(ptr, AllocationDtor(ashmemAlloc));
+ if (*alloc) {
+ *allocSize = ashmemParams.data.capacity;
+ return ResultStatus::OK;
+ }
+ delete ptr;
+ return ResultStatus::NO_MEMORY;
+ }
+ }
+ return ResultStatus::CRITICAL_ERROR;
+}
+
+bool TestBufferPoolAllocator::compatible(const std::vector<uint8_t> &newParams,
+ const std::vector<uint8_t> &oldParams) {
+ size_t newSize = newParams.size();
+ size_t oldSize = oldParams.size();
+ if (newSize == oldSize) {
+ for (size_t i = 0; i < newSize; ++i) {
+ if (newParams[i] != oldParams[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+bool TestBufferPoolAllocator::Fill(const native_handle_t *handle, const unsigned char val) {
+ if (!HandleAshmem::isValid(handle)) {
+ return false;
+ }
+ const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+ unsigned char *ptr = (unsigned char *)mmap(
+ NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+
+ if (ptr != MAP_FAILED) {
+ for (size_t i = 0; i < o->size(); ++i) {
+ ptr[i] = val;
+ }
+ munmap(ptr, o->size());
+ return true;
+ }
+ return false;
+}
+
+bool TestBufferPoolAllocator::Verify(const native_handle_t *handle, const unsigned char val) {
+ if (!HandleAshmem::isValid(handle)) {
+ return false;
+ }
+ const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+ unsigned char *ptr = (unsigned char *)mmap(
+ NULL, o->size(), PROT_READ, MAP_SHARED, o->ashmemFd(), 0);
+
+ if (ptr != MAP_FAILED) {
+ bool res = true;
+ for (size_t i = 0; i < o->size(); ++i) {
+ if (ptr[i] != val) {
+ res = false;
+ break;
+ }
+ }
+ munmap(ptr, o->size());
+ return res;
+ }
+ return false;
+}
+
+bool TestBufferPoolAllocator::MapMemoryForMutex(const native_handle_t *handle, void **mem) {
+ if (!HandleAshmem::isValid(handle)) {
+ return false;
+ }
+ const HandleAshmem *o = static_cast<const HandleAshmem*>(handle);
+ *mem = mmap(
+ NULL, o->size(), PROT_READ|PROT_WRITE, MAP_SHARED, o->ashmemFd(), 0);
+ if (*mem == MAP_FAILED || *mem == nullptr) {
+ return false;
+ }
+ return true;
+}
+
+bool TestBufferPoolAllocator::UnmapMemoryForMutex(void *mem) {
+ munmap(mem, sizeof(IpcMutex));
+ return true;
+}
+
+void getTestAllocatorParams(std::vector<uint8_t> *params) {
+ constexpr static int kAllocationSize = 1024 * 10;
+ Params ashmemParams(kAllocationSize);
+
+ params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
+
+void getIpcMutexParams(std::vector<uint8_t> *params) {
+ Params ashmemParams(sizeof(IpcMutex));
+
+ params->assign(ashmemParams.array, ashmemParams.array + sizeof(ashmemParams));
+}
diff --git a/media/bufferpool/aidl/default/tests/allocator.h b/media/bufferpool/aidl/default/tests/allocator.h
new file mode 100644
index 0000000..7e7203f
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/allocator.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <pthread.h>
+#include <bufferpool2/BufferPoolTypes.h>
+
+using aidl::android::hardware::media::bufferpool2::implementation::
+ BufferPoolStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::
+ BufferPoolAllocation;
+using aidl::android::hardware::media::bufferpool2::implementation::
+ BufferPoolAllocator;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+
+struct IpcMutex {
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ int counter = 0;
+ bool signalled = false;
+
+ void init();
+
+ static IpcMutex *Import(void *mem);
+};
+
+// buffer allocator for the tests
+class TestBufferPoolAllocator : public BufferPoolAllocator {
+ public:
+ TestBufferPoolAllocator() {}
+
+ ~TestBufferPoolAllocator() override {}
+
+ BufferPoolStatus allocate(const std::vector<uint8_t> ¶ms,
+ std::shared_ptr<BufferPoolAllocation> *alloc,
+ size_t *allocSize) override;
+
+ bool compatible(const std::vector<uint8_t> &newParams,
+ const std::vector<uint8_t> &oldParams) override;
+
+ static bool Fill(const native_handle_t *handle, const unsigned char val);
+
+ static bool Verify(const native_handle_t *handle, const unsigned char val);
+
+ static bool MapMemoryForMutex(const native_handle_t *handle, void **mem);
+
+ static bool UnmapMemoryForMutex(void *mem);
+};
+
+// retrieve buffer allocator parameters
+void getTestAllocatorParams(std::vector<uint8_t> *params);
+
+void getIpcMutexParams(std::vector<uint8_t> *params);
diff --git a/media/bufferpool/aidl/default/tests/cond.cpp b/media/bufferpool/aidl/default/tests/cond.cpp
new file mode 100644
index 0000000..6d469ce
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/cond.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_stability.h>
+#include <android-base/logging.h>
+#include <bufferpool2/ClientManager.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include "allocator.h"
+
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
+
+namespace {
+
+const std::string testInstance = std::string() + ClientManager::descriptor + "/condtest";
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+ INIT_OK = 0,
+ INIT_ERROR,
+ SEND,
+ RECEIVE_OK,
+ RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+ struct {
+ int32_t command;
+ BufferId bufferId;
+ ConnectionId connectionId;
+ TransactionId transactionId;
+ int64_t timestampUs;
+ } data;
+ char array[0];
+};
+
+constexpr int kSignalInt = 200;
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ BufferPoolStatus status;
+ mReceiverPid = -1;
+ mConnectionValid = false;
+
+ ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+ ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+ mReceiverPid = fork();
+ ASSERT_TRUE(mReceiverPid >= 0);
+
+ if (mReceiverPid == 0) {
+ doReceiver();
+ // In order to ignore gtest behaviour, wait for being killed from
+ // tearDown
+ pause();
+ }
+
+ mManager = ClientManager::getInstance();
+ ASSERT_NE(mManager, nullptr);
+
+ mAllocator = std::make_shared<TestBufferPoolAllocator>();
+ ASSERT_TRUE((bool)mAllocator);
+
+ status = mManager->create(mAllocator, &mConnectionId);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ mConnectionValid = true;
+ }
+
+ virtual void TearDown() override {
+ if (mReceiverPid > 0) {
+ kill(mReceiverPid, SIGKILL);
+ int wstatus;
+ wait(&wstatus);
+ }
+
+ if (mConnectionValid) {
+ mManager->close(mConnectionId);
+ }
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ std::shared_ptr<ClientManager> mManager;
+ std::shared_ptr<BufferPoolAllocator> mAllocator;
+ bool mConnectionValid;
+ ConnectionId mConnectionId;
+ pid_t mReceiverPid;
+ int mCommandPipeFds[2];
+ int mResultPipeFds[2];
+
+ bool sendMessage(int *pipes, const PipeMessage &message) {
+ int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+ return ret == sizeof(PipeMessage);
+ }
+
+ bool receiveMessage(int *pipes, PipeMessage *message) {
+ int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+ return ret == sizeof(PipeMessage);
+ }
+
+ void doReceiver() {
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ PipeMessage message;
+ mManager = ClientManager::getInstance();
+ if (!mManager) {
+ message.data.command = PipeCommand::INIT_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ auto binder = mManager->asBinder();
+ AIBinder_forceDowngradeToSystemStability(binder.get());
+ binder_status_t status =
+ AServiceManager_addService(binder.get(), testInstance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+ if (status != android::OK) {
+ message.data.command = PipeCommand::INIT_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ message.data.command = PipeCommand::INIT_OK;
+ sendMessage(mResultPipeFds, message);
+
+ int val = 0;
+ receiveMessage(mCommandPipeFds, &message);
+ {
+ native_handle_t *rhandle = nullptr;
+ std::shared_ptr<BufferPoolData> rbuffer;
+ void *mem = nullptr;
+ IpcMutex *mutex = nullptr;
+ BufferPoolStatus status = mManager->receive(
+ message.data.connectionId, message.data.transactionId,
+ message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+ mManager->close(message.data.connectionId);
+ if (status != ResultStatus::OK) {
+ message.data.command = PipeCommand::RECEIVE_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ if (!TestBufferPoolAllocator::MapMemoryForMutex(rhandle, &mem)) {
+ message.data.command = PipeCommand::RECEIVE_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ mutex = IpcMutex::Import(mem);
+ pthread_mutex_lock(&(mutex->lock));
+ while (mutex->signalled != true) {
+ pthread_cond_wait(&(mutex->cond), &(mutex->lock));
+ }
+ val = mutex->counter;
+ pthread_mutex_unlock(&(mutex->lock));
+
+ (void)TestBufferPoolAllocator::UnmapMemoryForMutex(mem);
+ if (rhandle) {
+ native_handle_close(rhandle);
+ native_handle_delete(rhandle);
+ }
+ }
+ if (val == kSignalInt) {
+ message.data.command = PipeCommand::RECEIVE_OK;
+ } else {
+ message.data.command = PipeCommand::RECEIVE_ERROR;
+ }
+ sendMessage(mResultPipeFds, message);
+ }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+ BufferPoolStatus status;
+ PipeMessage message;
+
+ ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+
+
+ std::shared_ptr<IClientManager> receiver =
+ IClientManager::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(testInstance.c_str())));
+ ASSERT_NE(receiver, nullptr);
+ ConnectionId receiverId;
+
+ bool isNew = true;
+ status = mManager->registerSender(receiver, mConnectionId, &receiverId, &isNew);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ {
+ native_handle_t *shandle = nullptr;
+ std::shared_ptr<BufferPoolData> sbuffer;
+ TransactionId transactionId;
+ int64_t postUs;
+ std::vector<uint8_t> vecParams;
+ void *mem = nullptr;
+ IpcMutex *mutex = nullptr;
+
+ getIpcMutexParams(&vecParams);
+ status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+ ASSERT_TRUE(status == ResultStatus::OK);
+
+ ASSERT_TRUE(TestBufferPoolAllocator::MapMemoryForMutex(shandle, &mem));
+
+ mutex = new(mem) IpcMutex();
+ mutex->init();
+
+ status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+ ASSERT_TRUE(status == ResultStatus::OK);
+
+ message.data.command = PipeCommand::SEND;
+ message.data.bufferId = sbuffer->mId;
+ message.data.connectionId = receiverId;
+ message.data.transactionId = transactionId;
+ message.data.timestampUs = postUs;
+ sendMessage(mCommandPipeFds, message);
+ for (int i=0; i < 200000000; ++i) {
+ // no-op in order to ensure
+ // pthread_cond_wait is called before pthread_cond_signal
+ }
+ pthread_mutex_lock(&(mutex->lock));
+ mutex->counter = kSignalInt;
+ mutex->signalled = true;
+ pthread_cond_signal(&(mutex->cond));
+ pthread_mutex_unlock(&(mutex->lock));
+ (void)TestBufferPoolAllocator::UnmapMemoryForMutex(mem);
+ if (shandle) {
+ native_handle_close(shandle);
+ native_handle_delete(shandle);
+ }
+ }
+ EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+ EXPECT_TRUE(message.data.command == PipeCommand::RECEIVE_OK);
+}
+
+} // anonymous namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/media/bufferpool/aidl/default/tests/multi.cpp b/media/bufferpool/aidl/default/tests/multi.cpp
new file mode 100644
index 0000000..8806eb0
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/multi.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_stability.h>
+#include <android-base/logging.h>
+#include <bufferpool2/ClientManager.h>
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include "allocator.h"
+
+using aidl::android::hardware::media::bufferpool2::IClientManager;
+using aidl::android::hardware::media::bufferpool2::ResultStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
+
+namespace {
+
+const std::string testInstance = std::string() + ClientManager::descriptor + "/multitest";
+
+// communication message types between processes.
+enum PipeCommand : int32_t {
+ INIT_OK = 0,
+ INIT_ERROR,
+ SEND,
+ RECEIVE_OK,
+ RECEIVE_ERROR,
+};
+
+// communication message between processes.
+union PipeMessage {
+ struct {
+ int32_t command;
+ BufferId bufferId;
+ ConnectionId connectionId;
+ TransactionId transactionId;
+ int64_t timestampUs;
+ } data;
+ char array[0];
+};
+
+// media.bufferpool test setup
+class BufferpoolMultiTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ BufferPoolStatus status;
+ mReceiverPid = -1;
+ mConnectionValid = false;
+
+ ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
+ ASSERT_TRUE(pipe(mResultPipeFds) == 0);
+
+ mReceiverPid = fork();
+ ASSERT_TRUE(mReceiverPid >= 0);
+
+ if (mReceiverPid == 0) {
+ doReceiver();
+ // In order to ignore gtest behaviour, wait for being killed from
+ // tearDown
+ pause();
+ }
+ mManager = ClientManager::getInstance();
+ ASSERT_NE(mManager, nullptr);
+
+ mAllocator = std::make_shared<TestBufferPoolAllocator>();
+ ASSERT_TRUE((bool)mAllocator);
+
+ status = mManager->create(mAllocator, &mConnectionId);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ mConnectionValid = true;
+ }
+
+ virtual void TearDown() override {
+ if (mReceiverPid > 0) {
+ kill(mReceiverPid, SIGKILL);
+ int wstatus;
+ wait(&wstatus);
+ }
+
+ if (mConnectionValid) {
+ mManager->close(mConnectionId);
+ }
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ std::shared_ptr<ClientManager> mManager;
+ std::shared_ptr<BufferPoolAllocator> mAllocator;
+ bool mConnectionValid;
+ ConnectionId mConnectionId;
+ pid_t mReceiverPid;
+ int mCommandPipeFds[2];
+ int mResultPipeFds[2];
+
+ bool sendMessage(int *pipes, const PipeMessage &message) {
+ int ret = write(pipes[1], message.array, sizeof(PipeMessage));
+ return ret == sizeof(PipeMessage);
+ }
+
+ bool receiveMessage(int *pipes, PipeMessage *message) {
+ int ret = read(pipes[0], message->array, sizeof(PipeMessage));
+ return ret == sizeof(PipeMessage);
+ }
+
+ void doReceiver() {
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ PipeMessage message;
+ mManager = ClientManager::getInstance();
+ if (!mManager) {
+ message.data.command = PipeCommand::INIT_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ auto binder = mManager->asBinder();
+ AIBinder_forceDowngradeToSystemStability(binder.get());
+ binder_status_t status =
+ AServiceManager_addService(binder.get(), testInstance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+ if (status != android::OK) {
+ message.data.command = PipeCommand::INIT_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ message.data.command = PipeCommand::INIT_OK;
+ sendMessage(mResultPipeFds, message);
+
+ receiveMessage(mCommandPipeFds, &message);
+ {
+ native_handle_t *rhandle = nullptr;
+ std::shared_ptr<BufferPoolData> rbuffer;
+ BufferPoolStatus status = mManager->receive(
+ message.data.connectionId, message.data.transactionId,
+ message.data.bufferId, message.data.timestampUs, &rhandle, &rbuffer);
+ mManager->close(message.data.connectionId);
+ if (status != ResultStatus::OK) {
+ message.data.command = PipeCommand::RECEIVE_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ if (!TestBufferPoolAllocator::Verify(rhandle, 0x77)) {
+ message.data.command = PipeCommand::RECEIVE_ERROR;
+ sendMessage(mResultPipeFds, message);
+ return;
+ }
+ if (rhandle) {
+ native_handle_close(rhandle);
+ native_handle_delete(rhandle);
+ }
+ }
+ message.data.command = PipeCommand::RECEIVE_OK;
+ sendMessage(mResultPipeFds, message);
+ }
+};
+
+// Buffer transfer test between processes.
+TEST_F(BufferpoolMultiTest, TransferBuffer) {
+ BufferPoolStatus status;
+ PipeMessage message;
+
+ ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+
+ std::shared_ptr<IClientManager> receiver = IClientManager::fromBinder(ndk::SpAIBinder(
+ AServiceManager_waitForService(testInstance.c_str())));
+ ASSERT_NE(receiver, nullptr);
+ ConnectionId receiverId;
+
+ bool isNew = true;
+ status = mManager->registerSender(receiver, mConnectionId, &receiverId, &isNew);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ {
+ native_handle_t *shandle = nullptr;
+ std::shared_ptr<BufferPoolData> sbuffer;
+ TransactionId transactionId;
+ int64_t postUs;
+ std::vector<uint8_t> vecParams;
+
+ getTestAllocatorParams(&vecParams);
+ status = mManager->allocate(mConnectionId, vecParams, &shandle, &sbuffer);
+ ASSERT_TRUE(status == ResultStatus::OK);
+
+ ASSERT_TRUE(TestBufferPoolAllocator::Fill(shandle, 0x77));
+ if (shandle) {
+ native_handle_close(shandle);
+ native_handle_delete(shandle);
+ }
+
+ status = mManager->postSend(receiverId, sbuffer, &transactionId, &postUs);
+ ASSERT_TRUE(status == ResultStatus::OK);
+
+ message.data.command = PipeCommand::SEND;
+ message.data.bufferId = sbuffer->mId;
+ message.data.connectionId = receiverId;
+ message.data.transactionId = transactionId;
+ message.data.timestampUs = postUs;
+ sendMessage(mCommandPipeFds, message);
+ }
+ EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
+ EXPECT_TRUE(message.data.command == PipeCommand::RECEIVE_OK);
+}
+
+} // anonymous namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/media/bufferpool/aidl/default/tests/single.cpp b/media/bufferpool/aidl/default/tests/single.cpp
new file mode 100644
index 0000000..66aa5e9
--- /dev/null
+++ b/media/bufferpool/aidl/default/tests/single.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "buffferpool_unit_test"
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+#include <binder/ProcessState.h>
+#include <bufferpool2/ClientManager.h>
+#include <unistd.h>
+#include <iostream>
+#include <memory>
+#include <vector>
+#include "allocator.h"
+
+using aidl::android::hardware::media::bufferpool2::implementation::BufferId;
+using aidl::android::hardware::media::bufferpool2::implementation::BufferPoolStatus;
+using aidl::android::hardware::media::bufferpool2::implementation::ClientManager;
+using aidl::android::hardware::media::bufferpool2::implementation::ConnectionId;
+using aidl::android::hardware::media::bufferpool2::implementation::TransactionId;
+using aidl::android::hardware::media::bufferpool2::BufferPoolData;
+
+namespace {
+
+// Number of iteration for buffer allocation test.
+constexpr static int kNumAllocationTest = 3;
+
+// Number of iteration for buffer recycling test.
+constexpr static int kNumRecycleTest = 3;
+
+// media.bufferpool test setup
+class BufferpoolSingleTest : public ::testing::Test {
+ public:
+ virtual void SetUp() override {
+ BufferPoolStatus status;
+ mConnectionValid = false;
+
+ mManager = ClientManager::getInstance();
+ ASSERT_NE(mManager, nullptr);
+
+ mAllocator = std::make_shared<TestBufferPoolAllocator>();
+ ASSERT_TRUE((bool)mAllocator);
+
+ status = mManager->create(mAllocator, &mConnectionId);
+ ASSERT_TRUE(status == ResultStatus::OK);
+
+ mConnectionValid = true;
+
+ bool isNew = true;
+ status = mManager->registerSender(mManager, mConnectionId, &mReceiverId, &isNew);
+ ASSERT_TRUE(status == ResultStatus::OK && isNew == false &&
+ mReceiverId == mConnectionId);
+ }
+
+ virtual void TearDown() override {
+ if (mConnectionValid) {
+ mManager->close(mConnectionId);
+ }
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ std::shared_ptr<ClientManager> mManager;
+ std::shared_ptr<BufferPoolAllocator> mAllocator;
+ bool mConnectionValid;
+ ConnectionId mConnectionId;
+ ConnectionId mReceiverId;
+
+};
+
+// Buffer allocation test.
+// Check whether each buffer allocation is done successfully with
+// unique buffer id.
+TEST_F(BufferpoolSingleTest, AllocateBuffer) {
+ BufferPoolStatus status;
+ std::vector<uint8_t> vecParams;
+ getTestAllocatorParams(&vecParams);
+
+ std::shared_ptr<BufferPoolData> buffer[kNumAllocationTest];
+ native_handle_t *allocHandle = nullptr;
+ for (int i = 0; i < kNumAllocationTest; ++i) {
+ status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer[i]);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ if (allocHandle) {
+ native_handle_close(allocHandle);
+ native_handle_delete(allocHandle);
+ }
+ }
+ for (int i = 0; i < kNumAllocationTest; ++i) {
+ for (int j = i + 1; j < kNumAllocationTest; ++j) {
+ ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId);
+ }
+ }
+ EXPECT_TRUE(kNumAllocationTest > 1);
+}
+
+// Buffer recycle test.
+// Check whether de-allocated buffers are recycled.
+TEST_F(BufferpoolSingleTest, RecycleBuffer) {
+ BufferPoolStatus status;
+ std::vector<uint8_t> vecParams;
+ getTestAllocatorParams(&vecParams);
+
+ BufferId bid[kNumRecycleTest];
+ for (int i = 0; i < kNumRecycleTest; ++i) {
+ std::shared_ptr<BufferPoolData> buffer;
+ native_handle_t *allocHandle = nullptr;
+ status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &buffer);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ bid[i] = buffer->mId;
+ if (allocHandle) {
+ native_handle_close(allocHandle);
+ native_handle_delete(allocHandle);
+ }
+ }
+ for (int i = 1; i < kNumRecycleTest; ++i) {
+ ASSERT_TRUE(bid[i - 1] == bid[i]);
+ }
+ EXPECT_TRUE(kNumRecycleTest > 1);
+}
+
+// Buffer transfer test.
+// Check whether buffer is transferred to another client successfully.
+TEST_F(BufferpoolSingleTest, TransferBuffer) {
+ BufferPoolStatus status;
+ std::vector<uint8_t> vecParams;
+ getTestAllocatorParams(&vecParams);
+ std::shared_ptr<BufferPoolData> sbuffer, rbuffer;
+ native_handle_t *allocHandle = nullptr;
+ native_handle_t *recvHandle = nullptr;
+
+ TransactionId transactionId;
+ int64_t postMs;
+
+ status = mManager->allocate(mConnectionId, vecParams, &allocHandle, &sbuffer);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ ASSERT_TRUE(TestBufferPoolAllocator::Fill(allocHandle, 0x77));
+ status = mManager->postSend(mReceiverId, sbuffer, &transactionId, &postMs);
+ ASSERT_TRUE(status == ResultStatus::OK);
+ status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postMs,
+ &recvHandle, &rbuffer);
+ EXPECT_TRUE(status == ResultStatus::OK);
+ ASSERT_TRUE(TestBufferPoolAllocator::Verify(recvHandle, 0x77));
+
+ if (allocHandle) {
+ native_handle_close(allocHandle);
+ native_handle_delete(allocHandle);
+ }
+ if (recvHandle) {
+ native_handle_close(recvHandle);
+ native_handle_delete(recvHandle);
+ }
+}
+
+} // anonymous namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
deleted file mode 100644
index 3393ede..0000000
--- a/media/c2/aidl/Android.bp
+++ /dev/null
@@ -1,38 +0,0 @@
-// This is the expected build file, but it may not be right in all cases
-
-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.media.c2",
- vendor_available: true,
- srcs: ["android/hardware/media/c2/*.aidl"],
- include_dirs: [
- "frameworks/native/aidl/gui",
- ],
- imports: [
- "android.hardware.common-V2",
- "android.hardware.media.bufferpool2-V1",
- ],
- stability: "vintf",
- backend: {
- cpp: {
- enabled: false,
- },
- java: {
- enabled: false,
- },
- ndk: {
- enabled: true,
- additional_shared_libraries: [
- "libnativewindow",
- ],
- },
- },
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/BaseBlock.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/BaseBlock.aidl
deleted file mode 100644
index 460ff97..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/BaseBlock.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-union BaseBlock {
- android.hardware.common.NativeHandle nativeBlock;
- android.hardware.media.bufferpool2.BufferStatusMessage pooledBlock;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Block.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Block.aidl
deleted file mode 100644
index 7b3005e..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Block.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable Block {
- int index;
- android.hardware.media.c2.Params meta;
- android.hardware.common.NativeHandle fence;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Buffer.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Buffer.aidl
deleted file mode 100644
index b632932..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Buffer.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable Buffer {
- android.hardware.media.c2.Params info;
- android.hardware.media.c2.Block[] blocks;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
deleted file mode 100644
index d0e4cbf..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldDescriptor.aidl
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable FieldDescriptor {
- android.hardware.media.c2.FieldId fieldId;
- android.hardware.media.c2.FieldDescriptor.Type type;
- int structIndex;
- int extent;
- String name;
- android.hardware.media.c2.FieldDescriptor.NamedValue[] namedValues;
- @Backing(type="int") @VintfStability
- enum Type {
- NO_INIT = 0,
- INT32 = 1,
- UINT32 = 2,
- CNTR32 = 3,
- INT64 = 4,
- UINT64 = 5,
- CNTR64 = 6,
- FLOAT = 7,
- STRING = 256,
- BLOB = 257,
- STRUCT = 131072,
- }
- @VintfStability
- parcelable NamedValue {
- String name;
- long value;
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldId.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldId.aidl
deleted file mode 100644
index 935b85d..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldId.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable FieldId {
- int offset;
- int sizeBytes;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValues.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValues.aidl
deleted file mode 100644
index 69060be..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValues.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-union FieldSupportedValues {
- boolean empty;
- android.hardware.media.c2.ValueRange range;
- long[] values;
- long[] flags;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
deleted file mode 100644
index 22f7c84..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable FieldSupportedValuesQuery {
- android.hardware.media.c2.ParamField field;
- android.hardware.media.c2.FieldSupportedValuesQuery.Type type;
- @Backing(type="int") @VintfStability
- enum Type {
- POSSIBLE = 0,
- CURRENT = 1,
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
deleted file mode 100644
index 187e3eb..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable FieldSupportedValuesQueryResult {
- android.hardware.media.c2.Status status;
- android.hardware.media.c2.FieldSupportedValues values;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
deleted file mode 100644
index e73b05e..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/FrameData.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable FrameData {
- int flags;
- android.hardware.media.c2.WorkOrdinal ordinal;
- android.hardware.media.c2.Buffer[] buffers;
- android.hardware.media.c2.Params configUpdate;
- android.hardware.media.c2.InfoBuffer[] infoBuffers;
- const int DROP_FRAME = 1;
- const int END_OF_STREAM = 2;
- const int DISCARD_FRAME = 4;
- const int FLAG_INCOMPLETE = 8;
- const int CODEC_CONFIG = -2147483648;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
deleted file mode 100644
index 7ed09af..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponent.aidl
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-interface IComponent {
- android.hardware.common.NativeHandle configureVideoTunnel(in int avSyncHwId);
- android.hardware.media.c2.IComponent.BlockPool createBlockPool(in int allocatorId);
- void destroyBlockPool(in long blockPoolId);
- void drain(in boolean withEos);
- android.hardware.media.c2.WorkBundle flush();
- android.hardware.media.c2.IComponentInterface getInterface();
- void queue(in android.hardware.media.c2.WorkBundle workBundle);
- void release();
- void reset();
- void setOutputSurface(in long blockPoolId, in android.view.Surface surface, in android.hardware.media.c2.SurfaceSyncObj syncObject);
- void start();
- void stop();
- parcelable BlockPool {
- long blockPoolId;
- android.hardware.media.c2.IConfigurable configurable;
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentInterface.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentInterface.aidl
deleted file mode 100644
index 2350dae..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentInterface.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-interface IComponentInterface {
- android.hardware.media.c2.IConfigurable getConfigurable();
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentListener.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentListener.aidl
deleted file mode 100644
index f6f2a63..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentListener.aidl
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-interface IComponentListener {
- oneway void onError(in android.hardware.media.c2.Status status, in int errorCode);
- oneway void onFramesRendered(in android.hardware.media.c2.IComponentListener.RenderedFrame[] renderedFrames);
- oneway void onInputBuffersReleased(in android.hardware.media.c2.IComponentListener.InputBuffer[] inputBuffers);
- oneway void onTripped(in android.hardware.media.c2.SettingResult[] settingResults);
- oneway void onWorkDone(in android.hardware.media.c2.WorkBundle workBundle);
- @VintfStability
- parcelable InputBuffer {
- long frameIndex;
- int arrayIndex;
- }
- @VintfStability
- parcelable RenderedFrame {
- long bufferQueueId;
- int slotId;
- long timestampNs;
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
deleted file mode 100644
index 35532be..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IComponentStore.aidl
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-interface IComponentStore {
- void copyBuffer(in android.hardware.media.c2.Buffer src, in android.hardware.media.c2.Buffer dst);
- android.hardware.media.c2.IComponent createComponent(in String name, in android.hardware.media.c2.IComponentListener listener, in android.hardware.media.bufferpool2.IClientManager pool);
- android.hardware.media.c2.IComponentInterface createInterface(in String name);
- android.hardware.media.c2.IConfigurable getConfigurable();
- android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
- android.hardware.media.c2.StructDescriptor[] getStructDescriptors(in int[] indices);
- android.hardware.media.c2.IComponentStore.ComponentTraits[] listComponents();
- @VintfStability
- parcelable ComponentTraits {
- String name;
- android.hardware.media.c2.IComponentStore.ComponentTraits.Domain domain;
- android.hardware.media.c2.IComponentStore.ComponentTraits.Kind kind;
- int rank;
- String mediaType;
- String[] aliases;
- @Backing(type="int") @VintfStability
- enum Kind {
- OTHER = 0,
- DECODER = 1,
- ENCODER = 2,
- }
- @Backing(type="int") @VintfStability
- enum Domain {
- OTHER = 0,
- VIDEO = 1,
- AUDIO = 2,
- IMAGE = 3,
- }
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
deleted file mode 100644
index 32f5abd..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.media.c2;
-@VintfStability
-interface IConfigurable {
- android.hardware.media.c2.IConfigurable.ConfigResult config(in android.hardware.media.c2.Params inParams, in boolean mayBlock);
- int getId();
- String getName();
- android.hardware.media.c2.Params query(in int[] indices, in boolean mayBlock);
- android.hardware.media.c2.ParamDescriptor[] querySupportedParams(in int start, in int count);
- android.hardware.media.c2.FieldSupportedValuesQueryResult[] querySupportedValues(in android.hardware.media.c2.FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
- @VintfStability
- parcelable ConfigResult {
- android.hardware.media.c2.Params params;
- android.hardware.media.c2.SettingResult[] failures;
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/InfoBuffer.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/InfoBuffer.aidl
deleted file mode 100644
index 94cd77d..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/InfoBuffer.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable InfoBuffer {
- int index;
- android.hardware.media.c2.Buffer buffer;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
deleted file mode 100644
index 04c869c..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamDescriptor.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.media.c2;
-@VintfStability
-parcelable ParamDescriptor {
- int index;
- int attrib;
- String name;
- int[] dependencies;
- const int ATTRIBUTE_REQUIRED = 1;
- const int ATTRIBUTE_PERSISTENT = 2;
- const int ATTRIBUTE_STRICT = 4;
- const int ATTRIBUTE_READ_ONLY = 8;
- const int ATTRIBUTE_HIDDEN = 16;
- const int ATTRIBUTE_INTERNAL = 32;
- const int ATTRIBUTE_CONST = 64;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamField.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamField.aidl
deleted file mode 100644
index 13d2522..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamField.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable ParamField {
- int index;
- android.hardware.media.c2.FieldId fieldId;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamFieldValues.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamFieldValues.aidl
deleted file mode 100644
index 5a2821c..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ParamFieldValues.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable ParamFieldValues {
- android.hardware.media.c2.ParamField paramOrField;
- android.hardware.media.c2.FieldSupportedValues[] values;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Params.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Params.aidl
deleted file mode 100644
index 7d363c0..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Params.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable Params {
- byte[] params;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
deleted file mode 100644
index f9e6a93..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SettingResult.aidl
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable SettingResult {
- android.hardware.media.c2.SettingResult.Failure failure;
- android.hardware.media.c2.ParamFieldValues field;
- android.hardware.media.c2.ParamFieldValues[] conflicts;
- @Backing(type="int") @VintfStability
- enum Failure {
- BAD_TYPE = 0,
- BAD_PORT = 1,
- BAD_INDEX = 2,
- READ_ONLY = 3,
- MISMATCH = 4,
- BAD_VALUE = 5,
- CONFLICT = 6,
- UNSUPPORTED = 7,
- INFO_BAD_VALUE = 8,
- INFO_CONFLICT = 9,
- }
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
deleted file mode 100644
index ad07677..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Status.aidl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable Status {
- int status;
- const int OK = 0;
- const int BAD_VALUE = -22;
- const int BAD_INDEX = -75;
- const int CANNOT_DO = -2147483646;
- const int DUPLICATE = -17;
- const int NOT_FOUND = -2;
- const int BAD_STATE = -38;
- const int BLOCKING = -9930;
- const int NO_MEMORY = -12;
- const int REFUSED = -1;
- const int TIMED_OUT = -110;
- const int OMITTED = -74;
- const int CORRUPTED = -2147483648;
- const int NO_INIT = -19;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/StructDescriptor.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/StructDescriptor.aidl
deleted file mode 100644
index 58268e0..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/StructDescriptor.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable StructDescriptor {
- int type;
- android.hardware.media.c2.FieldDescriptor[] fields;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
deleted file mode 100644
index 1c9bf8d..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable SurfaceSyncObj {
- android.hardware.common.NativeHandle syncMemory;
- long bqId;
- int generationId;
- long consumerUsage;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ValueRange.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ValueRange.aidl
deleted file mode 100644
index db71ce0..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/ValueRange.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable ValueRange {
- long min;
- long max;
- long step;
- long num;
- long denom;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Work.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Work.aidl
deleted file mode 100644
index a534348..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Work.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable Work {
- byte[] chainInfo;
- android.hardware.media.c2.FrameData input;
- android.hardware.media.c2.Worklet[] worklets;
- int workletsProcessed;
- android.hardware.media.c2.Status result;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkBundle.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkBundle.aidl
deleted file mode 100644
index 84708a8..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkBundle.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable WorkBundle {
- android.hardware.media.c2.Work[] works;
- android.hardware.media.c2.BaseBlock[] baseBlocks;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkOrdinal.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkOrdinal.aidl
deleted file mode 100644
index 2833df3..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/WorkOrdinal.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable WorkOrdinal {
- long timestampUs;
- long frameIndex;
- long customOrdinal;
-}
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Worklet.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Worklet.aidl
deleted file mode 100644
index a79abf2..0000000
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/Worklet.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.media.c2;
-@VintfStability
-parcelable Worklet {
- int componentId;
- byte[] tunings;
- android.hardware.media.c2.SettingResult[] failures;
- android.hardware.media.c2.FrameData output;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/BaseBlock.aidl b/media/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
deleted file mode 100644
index 8b8b8e0..0000000
--- a/media/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.common.NativeHandle;
-
-/**
- * Storage type for `BaseBlock`.
- *
- * A `BaseBlock` is a representation of a codec memory block. Coded data,
- * decoded data, codec-specific data, and other codec-related data are all sent
- * in the form of BaseBlocks.
- */
-@VintfStability
-union BaseBlock {
- /**
- * #nativeBlock is the opaque representation of a buffer.
- */
- NativeHandle nativeBlock;
- /**
- * #pooledBlock is a reference to a buffer handled by a BufferPool.
- */
- android.hardware.media.bufferpool2.BufferStatusMessage pooledBlock;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/Block.aidl b/media/c2/aidl/android/hardware/media/c2/Block.aidl
deleted file mode 100644
index 34aa7b1..0000000
--- a/media/c2/aidl/android/hardware/media/c2/Block.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.common.NativeHandle;
-import android.hardware.media.c2.Params;
-
-/**
- * Reference to a @ref BaseBlock within a @ref WorkBundle.
- *
- * `Block` contains additional attributes that `BaseBlock` does not. These
- * attributes may differ among `Block` objects that refer to the same
- * `BaseBlock` in the same `WorkBundle`.
- */
-@VintfStability
-parcelable Block {
- /**
- * Identity of a `BaseBlock` within a `WorkBundle`. This is an index into
- * #WorkBundle.baseBlocks.
- */
- int index;
- /**
- * Metadata associated with this `Block`.
- */
- Params meta;
- /**
- * Fence for synchronizing `Block` access.
- */
- NativeHandle fence;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/Buffer.aidl b/media/c2/aidl/android/hardware/media/c2/Buffer.aidl
deleted file mode 100644
index d2dcf2d..0000000
--- a/media/c2/aidl/android/hardware/media/c2/Buffer.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.Block;
-import android.hardware.media.c2.Params;
-
-/**
- * A codec buffer, which is a collection of @ref Block objects and metadata.
- *
- * This is a part of @ref FrameData.
- */
-@VintfStability
-parcelable Buffer {
- /**
- * Metadata associated with the buffer.
- */
- Params info;
- /**
- * Blocks contained in the buffer.
- */
- Block[] blocks;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl b/media/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
deleted file mode 100644
index a2774ec..0000000
--- a/media/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FieldId;
-
-/**
- * Description of a field inside a C2Param structure.
- */
-@VintfStability
-parcelable FieldDescriptor {
- /**
- * Possible types of the field.
- */
- @VintfStability
- @Backing(type="int")
- enum Type {
- NO_INIT = 0,
- INT32,
- UINT32,
- CNTR32,
- INT64,
- UINT64,
- CNTR64,
- FLOAT,
- /**
- * Fixed-size string (POD).
- */
- STRING = 0x100,
- /**
- * A blob has no sub-elements and can be thought of as an array of
- * bytes. However, bytes cannot be individually addressed by clients.
- */
- BLOB,
- /**
- * The field is a structure that may contain other fields.
- */
- STRUCT = 0x20000,
- }
- /**
- * Named value type. This is used for defining an enum value for a numeric
- * type.
- */
- @VintfStability
- parcelable NamedValue {
- /**
- * Name of the enum value. This must be unique for each enum value in
- * the same field.
- */
- String name;
- /**
- * Underlying value of the enum value. Multiple enum names may have the
- * same underlying value.
- */
- long value;
- }
- /**
- * Location of the field in the C2Param structure
- */
- FieldId fieldId;
- /**
- * Type of the field.
- */
- Type type;
- /**
- * If #type is #Type.STRUCT, #structIndex is the C2Param structure index;
- * otherwise, #structIndex is not used.
- */
- int structIndex;
- /**
- * Extent of the field.
- * - For a non-array field, #extent is 1.
- * - For a fixed-length array field, #extent is the length. An array field
- * of length 1 is indistinguishable from a non-array field.
- * - For a variable-length array field, #extent is 0. This can only occur as
- * the last member of a C2Param structure.
- */
- int extent;
- /**
- * Name of the field. This must be unique for each field in the same
- * structure.
- */
- String name;
- /**
- * List of enum values. This is not used when #type is not one of the
- * numeric types.
- */
- NamedValue[] namedValues;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldId.aidl b/media/c2/aidl/android/hardware/media/c2/FieldId.aidl
deleted file mode 100644
index 68bf058..0000000
--- a/media/c2/aidl/android/hardware/media/c2/FieldId.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-/**
- * Identifying information of a field relative to a known C2Param structure.
- *
- * Within a given C2Param structure, each field is uniquely identified by @ref
- * FieldId.
- */
-@VintfStability
-parcelable FieldId {
- /**
- * Offset of the field in bytes.
- */
- int offset;
- /**
- * Size of the field in bytes.
- */
- int sizeBytes;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
deleted file mode 100644
index 6c2033b..0000000
--- a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.ValueRange;
-
-/*
- * Description of supported values for a field of C2Param.
- *
- * This can be a continuous range or a discrete set of values.
- *
- * The intended type of values must be made clear in the context where
- * `FieldSupportedValues` is used.
- */
-@VintfStability
-union FieldSupportedValues {
- /**
- * No supported values
- */
- boolean empty;
- /**
- * Numeric range, described in a #ValueRange structure
- */
- ValueRange range;
- /**
- * List of values
- */
- long[] values;
- /**
- * List of flags that can be OR-ed.
- *
- * The list contains { min-mask, flag1, flag2... }. Basically, the first
- * value is the required set of flags to be set, and the rest of the values are flags that can
- * be set independently. FLAGS is only supported for integral types. Supported flags should
- * not overlap, as it can make validation non-deterministic. The standard validation method
- * is that starting from the original value, if each flag is removed when fully present (the
- * min-mask must be fully present), we shall arrive at 0.
- */
- long[] flags;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
deleted file mode 100644
index bdaaef6..0000000
--- a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.ParamField;
-
-/**
- * Query information for supported values of a field. This is used as input to
- * IConfigurable::querySupportedValues().
- */
-@VintfStability
-parcelable FieldSupportedValuesQuery {
- @VintfStability
- @Backing(type="int")
- enum Type {
- /**
- * Query all possible values regardless of other settings.
- */
- POSSIBLE = 0,
- /**
- * Query currently possible values given dependent settings.
- */
- CURRENT,
- }
- /**
- * Identity of the field to query.
- */
- ParamField field;
- /**
- * Type of the query. See #Type for more information.
- */
- Type type;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl b/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
deleted file mode 100644
index b5c28c6..0000000
--- a/media/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FieldSupportedValues;
-import android.hardware.media.c2.Status;
-
-/**
- * This structure is used to hold the result from
- * IConfigurable::querySupportedValues().
- */
-@VintfStability
-parcelable FieldSupportedValuesQueryResult {
- /**
- * Result of the query. Possible values are
- * - `Status::OK`: The query was successful.
- * - `Status::BAD_STATE`: The query was requested when the `IConfigurable` instance
- * was in a bad state.
- * - `Status::BAD_INDEX`: The requested field was not recognized.
- * - `Status::TIMED_OUT`: The query could not be completed in a timely manner.
- * - `Status::BLOCKING`: The query must block, but the parameter `mayBlock` in the
- * call to `querySupportedValues()` was `false`.
- * - `Status::CORRUPTED`: Some unknown error occurred.
- */
- Status status;
- /**
- * Supported values. This is meaningful only when #status is `OK`.
- */
- FieldSupportedValues values;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/FrameData.aidl b/media/c2/aidl/android/hardware/media/c2/FrameData.aidl
deleted file mode 100644
index 15c1b6d..0000000
--- a/media/c2/aidl/android/hardware/media/c2/FrameData.aidl
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.Buffer;
-import android.hardware.media.c2.InfoBuffer;
-import android.hardware.media.c2.Params;
-import android.hardware.media.c2.WorkOrdinal;
-
-/**
- * Data for an input frame or an output frame.
- *
- * This structure represents a @e frame with its metadata. A @e frame consists
- * of an ordered set of buffers, configuration changes, and info buffers along
- * with some non-configuration metadata.
- *
- * @note `FrameData` is the HIDL counterpart of `C2FrameData` in the Codec 2.0
- * standard.
- */
-@VintfStability
-parcelable FrameData {
- /** List of frame flags */
- /**
- * For input frames: no output frame shall be generated when processing
- * this frame, but metadata must still be processed.
- *
- * For output frames: this frame must be discarded but metadata is still
- * valid.
- */
- const int DROP_FRAME = (1 << 0);
- /**
- * This frame is the last frame of the current stream. Further frames
- * are part of a new stream.
- */
- const int END_OF_STREAM = (1 << 1);
- /**
- * This frame must be discarded with its metadata.
- *
- * This flag is only set by components, e.g. as a response to the flush
- * command.
- */
- const int DISCARD_FRAME = (1 << 2);
- /**
- * This frame is not the last frame produced for the input.
- *
- * This flag is normally set by the component - e.g. when an input frame
- * results in multiple output frames, this flag is set on all but the
- * last output frame.
- *
- * Also, when components are chained, this flag should be propagated
- * down the work chain. That is, if set on an earlier frame of a
- * work-chain, it should be propagated to all later frames in that
- * chain. Additionally, components down the chain could set this flag
- * even if not set earlier, e.g. if multiple output frames are generated
- * at that component for the input frame.
- */
- const int FLAG_INCOMPLETE = (1 << 3);
- /**
- * This frame contains only codec-specific configuration data, and no
- * actual access unit.
- */
- const int CODEC_CONFIG = (1 << 31);
- /**
- * Frame flags, as described above.
- */
- int flags;
- /**
- * @ref WorkOrdinal of the frame.
- */
- WorkOrdinal ordinal;
- /**
- * List of frame buffers.
- */
- Buffer[] buffers;
- /**
- * List of configuration updates.
- */
- Params configUpdate;
- /**
- * List of info buffers.
- */
- InfoBuffer[] infoBuffers;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl b/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
deleted file mode 100644
index b3390c3..0000000
--- a/media/c2/aidl/android/hardware/media/c2/IComponent.aidl
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.common.NativeHandle;
-import android.view.Surface;
-
-import android.hardware.media.c2.IComponentInterface;
-import android.hardware.media.c2.IConfigurable;
-import android.hardware.media.c2.WorkBundle;
-import android.hardware.media.c2.SurfaceSyncObj;
-
-/**
- * Interface for an AIDL Codec2 component.
- * Components have two states: stopped and running. The running state has three
- * sub-states: executing, tripped and error.
- *
- * All methods in `IComponent` must not block. If a method call cannot be
- * completed in a timely manner, it must throw `Status::TIMED_OUT`.
- */
-@VintfStability
-interface IComponent {
- /**
- * The reference object from framwork to HAL C2BlockPool.
- *
- * The object will be returned when C2BlockPool is created by a framework
- * request. The object also can be destroyed using blockPoolId.
- * Using configurable framework can query/config the object in HAL(IComponent).
- */
- parcelable BlockPool {
- long blockPoolId;
- IConfigurable configurable;
- }
- /**
- * Configures a component for a tunneled playback mode.
- *
- * A successful call to this method puts the component in the *tunneled*
- * mode. In this mode, the output `Worklet`s returned in
- * IComponentListener::onWorkDone() may not contain any buffers. The output
- * buffers are passed directly to the consumer end of a buffer queue whose
- * producer side is configured with the returned @p sidebandStream passed
- * to IGraphicBufferProducer::setSidebandStream().
- *
- * The component is initially in the non-tunneled mode by default. The
- * tunneled mode can be toggled on only before the component starts
- * processing. Once the component is put into the tunneled mode, it shall
- * stay in the tunneled mode until and only until reset() is called.
- *
- * @param avSyncHwId A resource ID for hardware sync. The generator of sync
- * IDs must ensure that this number is unique among all services at any
- * given time. For example, if both the audio HAL and the tuner HAL
- * support this feature, sync IDs from the audio HAL must not clash
- * with sync IDs from the tuner HAL.
- * @return Codec-allocated sideband stream NativeHandle. This can
- * be passed to IGraphicBufferProducer::setSidebandStream() to
- * establish a direct channel to the consumer.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::OMITTED` - The component does not support video tunneling.
- * - `Status::BAD_STATE` - The component is already running.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- NativeHandle configureVideoTunnel(in int avSyncHwId);
-
- /**
- * Creates a local `C2BlockPool` backed by the given allocator and returns
- * its id.
- *
- * The returned @p blockPoolId is the only way the client can refer to a
- * `C2BlockPool` object in the component. The id can be passed to
- * setOutputSurface() or used in some C2Param objects later.
- *
- * The created `C2BlockPool` object can be destroyed by calling
- * destroyBlockPool(), reset() or release(). reset() and release() must
- * destroy all `C2BlockPool` objects that have been created.
- *
- * @param allocatorId Id of a `C2Allocator`.
- * @param out configurable Configuration interface for the created pool. This
- * must not be null.
- * @return Created block pool information. This could be used to config/query and
- * also be used in setOutputSurface() if the allocator
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NO_MEMORY` - Not enough memory to create the pool.
- * - `Status::BAD_VALUE` - @p allocatorId is not recognized.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- BlockPool createBlockPool(in int allocatorId);
-
- /**
- * Destroys a local block pool previously created by createBlockPool().
- *
- * @param blockPoolId Id of a `C2BlockPool` that was previously returned by
- * createBlockPool().
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NOT_FOUND` - The supplied blockPoolId is not valid.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void destroyBlockPool(in long blockPoolId);
-
- /**
- * Drains the component, and optionally downstream components. This is a
- * signalling method; as such it does not wait for any work completion.
- *
- * The last `Work` item is marked as "drain-till-here", so the component is
- * notified not to wait for further `Work` before it processes what is
- * already queued. This method can also be used to set the end-of-stream
- * flag after `Work` has been queued. Client can continue to queue further
- * `Work` immediately after this method returns.
- *
- * This method must be supported in running (including tripped) states.
- *
- * `Work` that is completed must be returned via
- * IComponentListener::onWorkDone().
- *
- * @param withEos Whether to drain the component with marking end-of-stream.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void drain(in boolean withEos);
-
- /**
- * Discards and abandons any pending `Work` items for the component.
- *
- * This method must be supported in running (including tripped) states.
- *
- * `Work` that could be immediately abandoned/discarded must be returned in
- * @p flushedWorkBundle. The order in which queued `Work` items are
- * discarded can be arbitrary.
- *
- * `Work` that could not be abandoned or discarded immediately must be
- * marked to be discarded at the earliest opportunity, and must be returned
- * via IComponentListener::onWorkDone(). This must be completed within
- * 500ms.
- *
- * @return `WorkBundle` object containing flushed `Work` items.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- WorkBundle flush();
-
- /**
- * Returns the @ref IComponentInterface instance associated to this
- * component.
- *
- * An @ref IConfigurable instance for the component can be obtained by calling
- * IComponentInterface::getConfigurable() on the returned @p intf.
- *
- * @return `IComponentInterface` instance. This must not be null.
- */
- IComponentInterface getInterface();
-
- /**
- * Queues up work for the component.
- *
- * This method must be supported in running (including tripped) states.
- *
- * It is acceptable for this method to return `OK` and return an error value
- * using the IComponentListener::onWorkDone() callback.
- *
- * @param workBundle `WorkBundle` object containing a list of `Work` objects
- * to queue to the component.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::BAD_INDEX` - Some component id in some `Worklet` is not valid.
- * - `Status::CANNOT_DO` - The components are not tunneled but some `Work` object
- * contains tunneling information.
- * - `Status::NO_MEMORY` - Not enough memory to queue @p workBundle.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void queue(in WorkBundle workBundle);
-
- /**
- * Releases the component.
- *
- * This method must be supported in stopped state.
- *
- * This method destroys the component. Upon return, if @p status is `OK` or
- * `DUPLICATE`, all resources must have been released.
- *
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::BAD_STATE` - The component is running.
- * - `Status::DUPLICATE` - The component is already released.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void release();
-
- /**
- * Resets the component.
- *
- * This method must be supported in all (including tripped) states other
- * than released.
- *
- * This method must be supported during any other blocking call.
- *
- * This method must return within 500ms.
- *
- * When this call returns, if @p status is `OK`, all `Work` items must
- * have been abandoned, and all resources (including `C2BlockPool` objects
- * previously created by createBlockPool()) must have been released.
- *
- * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
- * expected as a response to this call. For all other return values, the
- * component must be in the stopped state.
- *
- * This brings settings back to their default, "guaranteeing" no tripped
- * state.
- *
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::BAD_STATE` - Component is in released state.
- * - `Status::DUPLICATE` - When called during another reset call from another
- * thread.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void reset();
-
- /**
- * Starts using a surface for output with a synchronization object
- *
- * This method must not block.
- *
- * @param blockPoolId Id of the `C2BlockPool` to be associated with the
- * output surface.
- * @param surface Output surface.
- * @param syncObject synchronization object for buffer allocation between
- * Framework and Component.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::CANNOT_DO` - The component does not support an output surface.
- * - `Status::REFUSED` - The output surface cannot be accessed.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void setOutputSurface(in long blockPoolId, in Surface surface,
- in SurfaceSyncObj syncObject);
-
- /**
- * Starts the component.
- *
- * This method must be supported in stopped state as well as tripped state.
- *
- * If the return value is `OK`, the component must be in the running state.
- * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
- * expected as a response to this call. Otherwise, the component must be in
- * the stopped state.
- *
- * If a component is in the tripped state and start() is called while the
- * component configuration still results in a trip, start() must succeed and
- * a new onTripped() callback must be used to communicate the configuration
- * conflict that results in the new trip.
- *
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::BAD_STATE` - Component is not in stopped or tripped state.
- * - `Status::DUPLICATE` - When called during another start call from another
- * thread.
- * - `Status::NO_MEMORY` - Not enough memory to start the component.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void start();
-
- /**
- * Stops the component.
- *
- * This method must be supported in running (including tripped) state.
- *
- * This method must return within 500ms.
- *
- * Upon this call, all pending `Work` must be abandoned.
- *
- * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
- * expected as a response to this call. For all other return values, the
- * component must be in the stopped state.
- *
- * This does not alter any settings and tunings that may have resulted in a
- * tripped state.
- *
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::BAD_STATE` - Component is not in running state.
- * - `Status::DUPLICATE` - When called during another stop call from another
- * thread.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void stop();
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
deleted file mode 100644
index 9db81e6..0000000
--- a/media/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.IConfigurable;
-
-/**
- * Component interface object. This object contains all of the configurations of
- * a potential or actual component. It can be created and used independently of
- * an actual Codec2 component to query supported parameters for various
- * component settings, and configurations for a potential component.
- *
- * An actual component exposes this interface via IComponent::getInterface().
- */
-@VintfStability
-interface IComponentInterface {
- /**
- * Returns the @ref IConfigurable instance associated to this component
- * interface.
- *
- * @return `IConfigurable` instance. This must not be null.
- */
- IConfigurable getConfigurable();
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentListener.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
deleted file mode 100644
index 75500b7..0000000
--- a/media/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.SettingResult;
-import android.hardware.media.c2.Status;
-import android.hardware.media.c2.WorkBundle;
-
-/**
- * Callback interface for handling notifications from @ref IComponent.
- */
-@VintfStability
-oneway interface IComponentListener {
- /**
- * Identifying information for an input buffer previously queued to the
- * component via IComponent::queue().
- */
- @VintfStability
- parcelable InputBuffer {
- /**
- * This value comes from `Work::input.ordinal.frameIndex` in a `Work`
- * object that was previously queued.
- */
- long frameIndex;
- /**
- * This value is an index into `Work::input.buffers` (which is an array)
- * in a `Work` object that was previously queued.
- */
- int arrayIndex;
- }
- /**
- * Information about rendering of a frame to a `Surface`.
- */
- @VintfStability
- parcelable RenderedFrame {
- /**
- * Id of the `BufferQueue` containing the rendered buffer.
- *
- * This value must have been obtained by an earlier call to
- * IGraphicBufferProducer::getUniqueId().
- */
- long bufferQueueId;
- /**
- * Id of the slot of the rendered buffer.
- *
- * This value must have been obtained by an earlier call to
- * IGraphicBufferProducer::dequeueBuffer() or
- * IGraphicBufferProducer::attachBuffer().
- */
- int slotId;
- /**
- * Timestamp the rendering happened.
- *
- * The reference point for the timestamp is determined by the
- * `BufferQueue` that performed the rendering.
- */
- long timestampNs;
- }
- /**
- * Notify the listener of an error.
- *
- * @param status Error type. @p status may be `OK`, which means that an
- * error has occurred, but the error type does not fit into the type
- * `Status`. In this case, additional information is provided by
- * @p errorCode.
- * @param errorCode Additional error information. The framework may not
- * recognize the meaning of this value.
- */
- void onError(in Status status, in int errorCode);
-
- /**
- * Notify the listener that frames have been rendered.
- *
- * @param renderedFrames List of @ref RenderedFrame objects.
- */
- void onFramesRendered(in RenderedFrame[] renderedFrames);
-
- /**
- * Notify the listener that some input buffers are no longer needed by the
- * component, and hence can be released or reused by the client.
- *
- * Input buffers that are contained in a `Work` object returned by an
- * earlier onWorkDone() call are assumed released, so they must not appear
- * in any onInputBuffersReleased() calls. That means
- * onInputBuffersReleased() must only report input buffers that are released
- * before the output in the same `Work` item is produced. However, it is
- * possible for an input buffer to be returned by onWorkDone() after it has
- * been reported by onInputBuffersReleased().
- *
- * @note onWorkDone() and onInputBuffersReleased() both notify the client
- * that input buffers are no longer needed. However, in order to minimize
- * IPC calls, onInputBuffersReleased() should be called only when
- * onWorkDone() cannot be called, e.g., the component needs more input
- * before an output can be produced.
- *
- * @param inputBuffers List of `InputBuffer` objects, identifying input
- * buffers that are no longer needed by the component.
- */
- void onInputBuffersReleased(in InputBuffer[] inputBuffers);
-
- /**
- * Notify the listener that the component is tripped.
- *
- * @param settingResults List of failures.
- */
- void onTripped(in SettingResult[] settingResults);
-
- /**
- * Notify the listener that some `Work` items have been completed.
- *
- * All the input buffers in the returned `Work` objects must not be used by
- * the component after onWorkDone() is called.
- *
- * @param workBundle List of completed `Work` objects.
- */
- void onWorkDone(in WorkBundle workBundle);
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl b/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
deleted file mode 100644
index 1435a7e..0000000
--- a/media/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.Buffer;
-import android.hardware.media.c2.IComponent;
-import android.hardware.media.c2.IComponentInterface;
-import android.hardware.media.c2.IComponentListener;
-import android.hardware.media.c2.IConfigurable;
-import android.hardware.media.c2.StructDescriptor;
-
-/**
- * Entry point for Codec2 HAL.
- *
- * All methods in `IComponentStore` must not block. If a method call cannot be
- * completed in a timely manner, it must throw `Status::TIMED_OUT`. The only
- * exceptions are getPoolClientManager() and getConfigurable(), which must
- * always return immediately.
- *
- * @note This is an extension of version 1.1 of `IComponentStore`. The purpose
- * of the extension is to add support for blocking output buffer allocator.
- */
-@VintfStability
-interface IComponentStore {
- /**
- * Component traits.
- */
- @VintfStability
- parcelable ComponentTraits {
- @VintfStability
- @Backing(type="int")
- enum Kind {
- OTHER = 0,
- DECODER,
- ENCODER,
- }
- @VintfStability
- @Backing(type="int")
- enum Domain {
- OTHER = 0,
- VIDEO,
- AUDIO,
- IMAGE,
- }
- /**
- * Name of the component. This must be unique for each component.
- *
- * This name is use to identify the component to create in
- * createComponent() and createComponentInterface().
- */
- String name;
- /**
- * Component domain.
- */
- Domain domain;
- /**
- * Component kind.
- */
- Kind kind;
- /**
- * Rank used by `MediaCodecList` to determine component ordering. Lower
- * value means higher priority.
- */
- int rank;
- /**
- * MIME type.
- */
- String mediaType;
- /**
- * Aliases for component name for backward compatibility.
- *
- * Multiple components can have the same alias (but not the same
- * component name) as long as their media types differ.
- */
- String[] aliases;
- }
-
- /**
- * Copies the contents of @p src into @p dst without changing the format of
- * @p dst.
- *
- * @param src Source buffer.
- * @param dst Destination buffer.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::CANNOT_DO` - @p src and @p dst are not compatible.
- * - `Status::REFUSED` - No permission to copy.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- void copyBuffer(in Buffer src, in Buffer dst);
-
- /**
- * Creates a component by name.
- *
- * @param name Name of the component to create. This must match one of the
- * names returned by listComponents().
- * @param listener Callback receiver.
- * @param pool `IClientManager` object of the BufferPool in the client
- * process. This may be null if the client does not own a BufferPool.
- * @return The created component.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NOT_FOUND` - There is no component with the given name.
- * - `Status::NO_MEMORY` - Not enough memory to create the component.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- *
- * @sa IComponentListener.
- */
- IComponent createComponent(in String name, in IComponentListener listener,
- in android.hardware.media.bufferpool2.IClientManager pool);
-
- /**
- * Creates a component interface by name.
- *
- * @param name Name of the component interface to create. This should match
- * one of the names returned by listComponents().
- * @return The created component interface.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NOT_FOUND` - There is no component interface with the given name.
- * - `Status::NO_MEMORY` - Not enough memory to create the component interface.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- IComponentInterface createInterface(in String name);
-
- /**
- * Returns the @ref IConfigurable instance associated to this component
- * store.
- *
- * @return `IConfigurable` instance. This must not be null.
- */
- IConfigurable getConfigurable();
-
- /**
- * Returns the `IClientManager` object for the component's BufferPool.
- *
- * @return If the component store supports receiving buffers via
- * BufferPool API, @p pool must be a valid `IClientManager` instance.
- * Otherwise, @p pool must be null.
- */
- android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
-
- /**
- * Returns a list of `StructDescriptor` objects for a set of requested
- * C2Param structure indices that this store is aware of.
- *
- * This operation must be performed at best effort, e.g. the component
- * store must simply ignore all struct indices that it is not aware of.
- *
- * @param indices Indices of C2Param structures to describe.
- * @return List of `StructDescriptor` objects.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NOT_FOUND` - Some indices were not known.
- * - `Status::NO_MEMORY` - Not enough memory to complete this method.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- StructDescriptor[] getStructDescriptors(in int[] indices);
-
- /**
- * Returns the list of components supported by this component store.
- *
- * @return traits List of component traits for all components supported by
- * this store (in no particular order).
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NO_MEMORY` - Not enough memory to complete this method.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- ComponentTraits[] listComponents();
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
deleted file mode 100644
index 7fdb825..0000000
--- a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FieldSupportedValuesQuery;
-import android.hardware.media.c2.FieldSupportedValuesQueryResult;
-import android.hardware.media.c2.ParamDescriptor;
-import android.hardware.media.c2.Params;
-import android.hardware.media.c2.SettingResult;
-
-/**
- * Generic configuration interface presented by all configurable Codec2 objects.
- *
- * This interface must be supported in all states of the owning object, and must
- * not change the state of the owning object.
- */
-@VintfStability
-interface IConfigurable {
- /**
- * Return parcelable for config() interface.
- *
- * This includes the successful config settings along with the failure reasons of
- * the specified setting.
- */
- @VintfStability
- parcelable ConfigResult {
- Params params;
- SettingResult[] failures;
- }
-
- /**
- * Sets a set of parameters for the object.
- *
- * Tuning is performed at best effort: the object must update all supported
- * configurations at best effort and skip unsupported parameters. Any errors
- * are communicated in the return value along with the failures.
- *
- * A non-strict parameter update with an unsupported value shall cause an
- * update to the closest supported value. A strict parameter update with an
- * unsupported value shall be skipped and a failure shall be returned.
- *
- * If @p mayBlock is false, this method must not block. An update that
- * requires blocking shall be skipped and a failure shall be returned.
- *
- * If @p mayBlock is true, an update may block, but the whole method call
- * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
- *
- * The final values for all parameters set are propagated back to the caller
- * in @p params.
- *
- * \par For IComponent
- *
- * When the object type is @ref IComponent, this method must be supported in
- * any state except released.
- *
- * The blocking behavior of this method differs among states:
- * - In the stopped state, this must be non-blocking. @p mayBlock is
- * ignored. (The method operates as if @p mayBlock was false.)
- * - In any of the running states, this method may block momentarily if
- * @p mayBlock is true. However, if the call cannot be completed in a
- * timely manner, `Status::TIMED_OUT` is thrown.
- *
- * @note Parameter tuning @e does depend on the order of the tuning
- * parameters, e.g., some parameter update may enable some subsequent
- * parameter update.
- *
- * @param inParams Requested parameter updates.
- * @param mayBlock Whether this call may block or not.
- * @return result of config. Params in the result should be in same order
- * with @p inParams.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NO_MEMORY` - Some supported parameters could not be updated
- * successfully because they contained unsupported values.
- * These are returned in @p failures.
- * - `Status::BLOCKING` - Setting some parameters requires blocking, but
- * @p mayBlock is false.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- ConfigResult config(in Params inParams, in boolean mayBlock);
-
- /**
- * Returns the id of the object. This must be unique among all objects of
- * the same type hosted by the same store.
- *
- * @return Id of the object.
- */
- int getId();
-
- /**
- * Returns the name of the object.
- *
- * This must match the name that was supplied during the creation of the
- * object.
- *
- * @return Name of the object.
- */
- String getName();
-
- /**
- * Queries a set of parameters from the object.
- *
- * Querying is performed at best effort: the object must query all supported
- * parameters and skip unsupported ones (which may include parameters that
- * could not be allocated).
- *
- * If @p mayBlock is true, a query may block, but the whole method call
- * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
- *
- * If @p mayBlock is false, this method must not block(All parameter queries
- * that require blocking must be skipped). Otherwise, this
- * method is allowed to block for a certain period of time before completing
- * the operation. If the operation is not completed in a timely manner,
- * `Status::TIMED_OUT` is thrown.
- *
- * @note Since unsupported parameters will be skipped, the returned results
- * does not have every settings from @p indices, but the result will preserve
- * the original order from @p indices though unsupported settings are skipped.
- *
- * \par For IComponent
- *
- * When the object type is @ref IComponent, this method must be supported in
- * any state except released. This call must not change the state nor the
- * internal configuration of the component.
- *
- * The blocking behavior of this method differs among states:
- * - In the stopped state, this must be non-blocking. @p mayBlock is
- * ignored. (The method operates as if @p mayBlock was false.)
- * - In any of the running states, this method may block momentarily if
- * @p mayBlock is true. However, if the call cannot be completed in a
- * timely manner, `Status::status` is thrown.
- *
- * @param indices List of C2Param structure indices to query.
- * @param mayBlock Whether this call may block or not.
- * @return Flattened representation of std::vector<C2Param> object.
- * Unsupported settings are skipped in the results. The order in @p indices
- * still be preserved except skipped settings.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NO_MEMORY` - Could not allocate memory for a supported parameter.
- * - `Status::BLOCKING` - Querying some parameters requires blocking, but
- * @p mayBlock is false.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- Params query(in int[] indices, in boolean mayBlock);
-
- /**
- * Returns a list of supported parameters within a selected range of C2Param
- * structure indices.
- *
- * @param start The first index of the selected range.
- * @param count The length of the selected range.
- * @return List of supported parameters in the selected range. This
- * list may have fewer than @p count elements if some indices in the
- * range are not supported.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::NO_MEMORY` - Not enough memory to complete this method.
- *
- */
- ParamDescriptor[] querySupportedParams(in int start, in int count);
-
- /**
- * Retrieves the supported values for the queried fields.
- *
- * The object must process all fields queried even if some queries fail.
- *
- * If @p mayBlock is false, this method must not block. Otherwise, this
- * method is allowed to block for a certain period of time before completing
- * the operation. If the operation cannot be completed in a timely manner,
- * `Status::TIMED_OUT` is thrown.
- *
- * \par For IComponent
- *
- * When the object type is @ref IComponent, this method must be supported in
- * any state except released.
- *
- * The blocking behavior of this method differs among states:
- * - In the stopped state, this must be non-blocking. @p mayBlock is
- * ignored. (The method operates as if @p mayBlock was false.)
- * - In any of the running states, this method may block momentarily if
- * @p mayBlock is true. However, if the call cannot be completed in a
- * timely manner, `Status::TIMED_OUT` is thrown.
- *
- * @param inFields List of field queries.
- * @param mayBlock Whether this call may block or not.
- * @return List of supported values and results for the
- * supplied queries.
- * @throws ServiceSpecificException with one of the following values:
- * - `Status::BLOCKING` - Querying some parameters requires blocking, but
- * @p mayBlock is false.
- * - `Status::NO_MEMORY` - Not enough memory to complete this method.
- * - `Status::BLOCKING` - Querying some fields requires blocking, but @p mayblock
- * is false.
- * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
- * - `Status::CORRUPTED` - Some unknown error occurred.
- */
- FieldSupportedValuesQueryResult[] querySupportedValues(
- in FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl b/media/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
deleted file mode 100644
index 207c4d0..0000000
--- a/media/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.Buffer;
-
-/**
- * An extension of @ref Buffer that also contains a C2Param structure index.
- *
- * This is a part of @ref FrameData.
- */
-@VintfStability
-parcelable InfoBuffer {
- /**
- * A C2Param structure index.
- */
- int index;
- /**
- * Associated @ref Buffer object.
- */
- Buffer buffer;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl b/media/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
deleted file mode 100644
index 84c6acc..0000000
--- a/media/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-/**
- * Usage description of a C2Param structure.
- *
- * @ref ParamDescriptor is returned by IConfigurable::querySupportedParams().
- */
-@VintfStability
-parcelable ParamDescriptor {
- /** The list of bit flags for attrib */
- /**
- * The parameter is required to be specified.
- */
- const int ATTRIBUTE_REQUIRED = 1 << 0;
- /**
- * The parameter retains its value.
- */
- const int ATTRIBUTE_PERSISTENT = 1 << 1;
- /**
- * The parameter is strict.
- */
- const int ATTRIBUTE_STRICT = 1 << 2;
- /**
- * The parameter is publicly read-only.
- */
- const int ATTRIBUTE_READ_ONLY = 1 << 3;
- /**
- * The parameter must not be visible to clients.
- */
- const int ATTRIBUTE_HIDDEN = 1 << 4;
- /**
- * The parameter must not be used by framework (other than testing).
- */
- const int ATTRIBUTE_INTERNAL = 1 << 5;
- /**
- * The parameter is publicly constant (hence read-only).
- */
- const int ATTRIBUTE_CONST = 1 << 6;
-
- /**
- * Index of the C2Param structure being described.
- */
- int index;
- /**
- * bit flag for attribute defined in the above.
- */
- int attrib;
- /**
- * Name of the structure. This must be unique for each structure.
- */
- String name;
- /**
- * Indices of other C2Param structures that this C2Param structure depends
- * on.
- */
- int[] dependencies;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/ParamField.aidl b/media/c2/aidl/android/hardware/media/c2/ParamField.aidl
deleted file mode 100644
index 64a46bb..0000000
--- a/media/c2/aidl/android/hardware/media/c2/ParamField.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FieldId;
-
-/**
- * Reference to a field in a C2Param structure.
- */
-@VintfStability
-parcelable ParamField {
- /**
- * Index of the C2Param structure.
- */
- int index;
- /**
- * Identifier of the field inside the C2Param structure.
- */
- FieldId fieldId;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl b/media/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
deleted file mode 100644
index 7b74c0e..0000000
--- a/media/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FieldSupportedValues;
-import android.hardware.media.c2.ParamField;
-
-/**
- * Supported values for a field.
- *
- * This is a pair of the field specifier together with an optional supported
- * values object. This structure is used when reporting parameter configuration
- * failures and conflicts.
- */
-@VintfStability
-parcelable ParamFieldValues {
- /**
- * Reference to a field or a C2Param structure.
- */
- ParamField paramOrField;
- /**
- * Optional supported values for the field if #paramOrField specifies an
- * actual field that is numeric (non struct, blob or string). Supported
- * values for arrays (including string and blobs) describe the supported
- * values for each element (character for string, and bytes for blobs). It
- * is optional for read-only strings and blobs.
- */
- FieldSupportedValues[] values;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/Params.aidl b/media/c2/aidl/android/hardware/media/c2/Params.aidl
deleted file mode 100644
index 53b512c..0000000
--- a/media/c2/aidl/android/hardware/media/c2/Params.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-/**
- * Flattened representation of std::vector<C2Param> object.
- *
- * The `Params` type is an array of bytes made up by concatenating a list of
- * C2Param objects. The start index (offset into @ref Params) of each C2Param
- * object in the list is divisible by 8. Up to 7 padding bytes may be added
- * after each C2Param object to achieve this 64-bit alignment.
- *
- * Each C2Param object has the following layout:
- * - 4 bytes: C2Param structure index (of type @ref ParamIndex) identifying the
- * type of the C2Param object.
- * - 4 bytes: size of the C2Param object (unsigned 4-byte integer).
- * - (size - 8) bytes: data of the C2Param object.
- */
-@VintfStability
-parcelable Params {
- byte[] params;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/SettingResult.aidl b/media/c2/aidl/android/hardware/media/c2/SettingResult.aidl
deleted file mode 100644
index c2b9574..0000000
--- a/media/c2/aidl/android/hardware/media/c2/SettingResult.aidl
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.ParamFieldValues;
-
-/**
- * Information describing the reason the parameter settings may fail, or may be
- * overridden.
- */
-@VintfStability
-parcelable SettingResult {
- /**
- * Failure code
- */
- @VintfStability
- @Backing(type="int")
- enum Failure {
- /**
- * Parameter is not supported.
- */
- BAD_TYPE,
- /**
- * Parameter is not supported on the specific port.
- */
- BAD_PORT,
- /**
- * Parameter is not supported on the specific stream.
- */
- BAD_INDEX,
- /**
- * Parameter is read-only and cannot be set.
- */
- READ_ONLY,
- /**
- * Parameter mismatches input data.
- */
- MISMATCH,
- /**
- * Strict parameter does not accept value for the field at all.
- */
- BAD_VALUE,
- /**
- * Strict parameter field value is in conflict with an/other
- * setting(s).
- */
- CONFLICT,
- /**
- * Parameter field is out of range due to other settings. (This failure
- * mode can only be used for strict calculated parameters.)
- */
- UNSUPPORTED,
- /**
- * Field does not access the requested parameter value at all. It has
- * been corrected to the closest supported value. This failure mode is
- * provided to give guidance as to what are the currently supported
- * values for this field (which may be a subset of the at-all-potential
- * values).
- */
- INFO_BAD_VALUE,
- /**
- * Requested parameter value is in conflict with an/other setting(s)
- * and has been corrected to the closest supported value. This failure
- * mode is given to provide guidance as to what are the currently
- * supported values as well as to optionally provide suggestion to the
- * client as to how to enable the requested parameter value.
- */
- INFO_CONFLICT,
- }
- Failure failure;
- /**
- * Failing (or corrected) field or parameter and optionally, currently
- * supported values for the field. Values must only be set for field
- * failures other than `BAD_VALUE`, and only if they are different from the
- * globally supported values (e.g. due to restrictions by another parameter
- * or input data).
- */
- ParamFieldValues field;
- /**
- * Conflicting parameters or fields with (optional) suggested values for any
- * conflicting fields to avoid the conflict. Values must only be set for
- * `CONFLICT`, `UNSUPPORTED` or `INFO_CONFLICT` failure code.
- */
- ParamFieldValues[] conflicts;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/Status.aidl b/media/c2/aidl/android/hardware/media/c2/Status.aidl
deleted file mode 100644
index 58a2404..0000000
--- a/media/c2/aidl/android/hardware/media/c2/Status.aidl
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-/**
- * Common return values for Codec2 operations.
- */
-@VintfStability
-parcelable Status {
- /**
- * Operation completed successfully.
- */
- const int OK = 0;
- /**
- * Argument has invalid value (user error).
- */
- const int BAD_VALUE = -22;
- /**
- * Argument uses invalid index (user error).
- */
- const int BAD_INDEX = -75;
- /**
- * Argument/Index is valid but not possible.
- */
- const int CANNOT_DO = -2147483646;
- /**
- * Object already exists.
- */
- const int DUPLICATE = -17;
- /**
- * Object not found.
- */
- const int NOT_FOUND = -2;
- /**
- * Operation is not permitted in the current state.
- */
- const int BAD_STATE = -38;
- /**
- * Operation would block but blocking is not permitted.
- */
- const int BLOCKING = -9930;
- /**
- * Not enough memory to complete operation.
- */
- const int NO_MEMORY = -12;
- /**
- * Missing permission to complete operation.
- */
- const int REFUSED = -1;
- /**
- * Operation did not complete within timeout.
- */
- const int TIMED_OUT = -110;
- /**
- * Operation is not implemented/supported (optional only).
- */
- const int OMITTED = -74;
- /**
- * Some unexpected error prevented the operation.
- */
- const int CORRUPTED = -2147483648;
- /**
- * Status has not been initialized.
- */
- const int NO_INIT = -19;
-
- int status;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl b/media/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
deleted file mode 100644
index 00359041..0000000
--- a/media/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FieldDescriptor;
-
-/**
- * Description of a C2Param structure. It consists of an index and a list of
- * `FieldDescriptor`s.
- */
-@VintfStability
-parcelable StructDescriptor {
- /**
- * Index of the structure.
- *
- * Actually C2Param::CoreIndex
- * Core index is the underlying parameter type for a parameter. It is used to describe the
- * layout of the parameter structure regardless of the component or parameter kind/scope.
- *
- * It is used to identify and distinguish global parameters, and also parameters on a given
- * port or stream. They must be unique for the set of global parameters, as well as for the
- * set of parameters on each port or each stream, but the same core index can be used for
- * parameters on different streams or ports, as well as for global parameters and port/stream
- * parameters.
- */
- int type;
- /**
- * List of fields in the structure.
- *
- * Fields are ordered by their offsets. A field that is a structure is
- * ordered before its members.
- */
- FieldDescriptor[] fields;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl b/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
deleted file mode 100644
index d20e102..0000000
--- a/media/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.common.NativeHandle;
-/**
- * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued
- * output buffers. This keeps # of dequeued buffers from Surface less than
- * configured max # of dequeued buffers all the time.
- */
-@VintfStability
-parcelable SurfaceSyncObj {
- /**
- * ASharedMemory for synchronization data. Layout is below
- *
- * |lock(futex) 4bytes|
- * |conditional_variable(futex) 4bytes|
- * |# of max dequeable buffer 4bytes|
- * |# of dequeued buffer 4bytes|
- * |Status of the surface 4bytes|
- * INIT = 0, Configuring surface is not finished.
- * ACTIVE = 1, Surface is ready to allocate(dequeue).
- * SWITCHING = 2, Switching to the new surface. It is blocked
- * to allocate(dequeue) a buffer until switching
- * completes.
- */
- NativeHandle syncMemory;
- /**
- * BufferQueue id.
- */
- long bqId;
- /**
- * Generation id.
- */
- int generationId;
- /**
- * Consumer usage flags. See +ndk
- * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
- */
- long consumerUsage;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/ValueRange.aidl b/media/c2/aidl/android/hardware/media/c2/ValueRange.aidl
deleted file mode 100644
index 9abcb7d..0000000
--- a/media/c2/aidl/android/hardware/media/c2/ValueRange.aidl
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-/**
- * Description of a set of values.
- *
- * If the `step` member is 0, and `num` and `denom` are both 1, the `Range`
- * structure represents a closed interval bounded by `min` and `max`.
- *
- * Otherwise, the #ValueRange structure represents a finite sequence of numbers
- * produced from the following recurrence relation:
- *
- * @code
- * v[0] = min
- * v[i] = v[i - 1] * num / denom + step ; i >= 1
- * @endcode
- *
- * Both the ratio `num / denom` and the value `step` must be positive. The
- * last number in the sequence described by this #Range structure is the
- * largest number in the sequence that is smaller than or equal to `max`.
- *
- * @note
- * The division in the formula may truncate the result if the data type of
- * these values is an integral type.
- */
-@VintfStability
-parcelable ValueRange {
- /**
- * Lower end of the range (inclusive).
- */
- long min;
- /**
- * Upper end of the range (inclusive).
- */
- long max;
- /**
- * The non-homogeneous term in the recurrence relation.
- */
- long step;
- /**
- * The numerator of the scale coefficient in the recurrence relation.
- */
- long num;
- /**
- * The denominator of the scale coefficient in the recurrence relation.
- */
- long denom;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/Work.aidl b/media/c2/aidl/android/hardware/media/c2/Work.aidl
deleted file mode 100644
index 4b8d696..0000000
--- a/media/c2/aidl/android/hardware/media/c2/Work.aidl
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FrameData;
-import android.hardware.media.c2.Status;
-import android.hardware.media.c2.Worklet;
-
-/**
- * A collection of input data to and output data from the component.
- *
- * A `Work` object holds information about a single work item. It is created by
- * the client and passed to the component via IComponent::queue(). The component
- * has two ways of returning a `Work` object to the client:
- * 1. If the queued `Work` object has been successfully processed,
- * IComponentListener::onWorkDone() shall be called to notify the listener,
- * and the output shall be included in the returned `Work` object.
- * 2. If the client calls IComponent::flush(), a `Work` object that has not
- * been processed shall be returned.
- *
- * `Work` is a part of @ref WorkBundle.
- */
-@VintfStability
-parcelable Work {
- /**
- * Additional work chain info not part of this work.
- */
- byte[] chainInfo;
- /**
- * @ref FrameData for the input.
- */
- FrameData input;
- /**
- * The chain of `Worklet`s.
- *
- * The length of #worklets is 1 when tunneling is not enabled.
- *
- * If #worklets has more than a single element, the tunnels between
- * successive components of the work chain must have been successfully
- * pre-registered at the time that the `Work` is submitted. Allocating the
- * output buffers in the `Worklet`s is the responsibility of each component
- * in the chain.
- *
- * Upon `Work` submission, #worklets must be an appropriately sized vector
- * containing `Worklet`s with @ref Worklet.hasOutput set to `false`. After a
- * successful processing, all but the final `Worklet` in the returned
- * #worklets must have @ref Worklet.hasOutput set to `false`.
- */
- Worklet[] worklets;
- /**
- * The number of `Worklet`s successfully processed in this chain.
- *
- * This must be initialized to 0 by the client when the `Work` is submitted,
- * and it must contain the number of `Worklet`s that were successfully
- * processed when the `Work` is returned to the client.
- *
- * #workletsProcessed cannot exceed the length of #worklets. If
- * #workletsProcessed is smaller than the length of #worklets, #result
- * cannot be `OK`.
- */
- int workletsProcessed;
- /**
- * The final outcome of the `Work` (corresponding to #workletsProcessed).
- *
- * The value of @ref Status.OK implies that all `Worklet`s have been
- * successfully processed.
- */
- Status result;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/WorkBundle.aidl b/media/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
deleted file mode 100644
index 2125fda..0000000
--- a/media/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.BaseBlock;
-import android.hardware.media.c2.Work;
-
-/**
- * List of `Work` objects.
- *
- * `WorkBundle` is used in IComponent::queue(), IComponent::flush() and
- * IComponentListener::onWorkDone(). A `WorkBundle` object consists of a list of
- * `Work` objects and a list of `BaseBlock` objects. Bundling multiple `Work`
- * objects together provides two benefits:
- * 1. Batching of `Work` objects can reduce the number of IPC calls.
- * 2. If multiple `Work` objects contain `Block`s that refer to the same
- * `BaseBlock`, the number of `BaseBlock`s that is sent between processes
- * is also reduced.
- *
- * @note `WorkBundle` is the AIDL counterpart of the vector of `C2Work` in the
- * Codec 2.0 standard. The presence of #baseBlocks helps with minimizing the
- * data transferred over an IPC.
- */
-@VintfStability
-parcelable WorkBundle {
- /**
- * A list of Work items.
- */
- Work[] works;
- /**
- * A list of blocks indexed by elements of #works.
- */
- BaseBlock[] baseBlocks;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl b/media/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
deleted file mode 100644
index 5708a90..0000000
--- a/media/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-/**
- * Ordering information of @ref FrameData objects. Each member is used for
- * comparing urgency: a smaller difference from a reference value indicates that
- * the associated Work object is more urgent. The reference value for each
- * member is initialized the first time it is communicated between the client
- * and the codec, and it may be updated to later values that are communicated.
- *
- * Each member of `WorkOrdinal` is stored as an unsigned integer, but the actual
- * order it represents is derived by subtracting the reference value, then
- * interpreting the result as a signed number with the same storage size (using
- * two's complement).
- *
- * @note `WorkOrdinal` is the HIDL counterpart of `C2WorkOrdinalStruct` in the
- * Codec 2.0 standard.
- */
-@VintfStability
-parcelable WorkOrdinal {
- /**
- * Timestamp in microseconds.
- */
- long timestampUs;
- /**
- * Frame index.
- */
- long frameIndex;
- /**
- * Component specific frame ordinal.
- */
- long customOrdinal;
-}
diff --git a/media/c2/aidl/android/hardware/media/c2/Worklet.aidl b/media/c2/aidl/android/hardware/media/c2/Worklet.aidl
deleted file mode 100644
index 6b3ceac..0000000
--- a/media/c2/aidl/android/hardware/media/c2/Worklet.aidl
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.media.c2;
-
-import android.hardware.media.c2.FrameData;
-import android.hardware.media.c2.SettingResult;
-
-/**
- * In/out structure containing some instructions for and results from output
- * processing.
- *
- * This is a part of @ref Work. One `Worklet` corresponds to one output
- * @ref FrameData. The client must construct an original `Worklet` object inside
- * a @ref Work object for each expected output before calling
- * IComponent::queue().
- */
-@VintfStability
-parcelable Worklet {
- /**
- * Component id. (Input)
- *
- * This is used only when tunneling is enabled.
- *
- * When used, this must match the return value from IConfigurable::getId().
- */
- int componentId;
- /**
- * List of C2Param objects describing tunings to be applied before
- * processing this `Worklet`. (Input)
- */
- byte[] tunings;
- /**
- * List of failures. (Output)
- */
- SettingResult[] failures;
- /**
- * Output frame data. (Output)
- */
- FrameData output;
-}
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 1347f60..f0b458a 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -25,7 +25,10 @@
cc_defaults {
name: "neuralnetworks_utils_hal_aidl_defaults",
- defaults: ["neuralnetworks_utils_defaults"],
+ defaults: [
+ "android.hardware.graphics.common-ndk_static",
+ "neuralnetworks_utils_defaults",
+ ],
srcs: [
// AIDL utils that a driver may depend on.
"src/BufferTracker.cpp",
@@ -38,7 +41,6 @@
export_include_dirs: ["include"],
cflags: ["-Wthread-safety"],
static_libs: [
- "android.hardware.graphics.common-V4-ndk",
"libaidlcommonsupport",
"libarect",
"neuralnetworks_types",
@@ -90,9 +92,9 @@
// AIDL features can include this cc_defaults to avoid managing dependency versions explicitly.
cc_defaults {
name: "neuralnetworks_use_latest_utils_hal_aidl",
+ defaults: ["android.hardware.graphics.common-ndk_static"],
static_libs: [
"android.hardware.common-V2-ndk",
- "android.hardware.graphics.common-V4-ndk",
"android.hardware.neuralnetworks-V4-ndk",
"neuralnetworks_utils_hal_aidl",
],
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
index 1d3ecb7..e6809da 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
@@ -39,4 +39,6 @@
oneway void pause();
oneway void resume();
oneway void close();
+ oneway void sendHint(android.hardware.power.SessionHint hint);
+ void setThreads(in int[] threadIds);
}
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
new file mode 100644
index 0000000..9c1f381
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@Backing(type="int") @VintfStability
+enum SessionHint {
+ CPU_LOAD_UP = 0,
+ CPU_LOAD_DOWN = 1,
+ CPU_LOAD_RESET = 2,
+ CPU_LOAD_RESUME = 3,
+ POWER_EFFICIENCY = 4,
+}
diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl
index c289448..7db0ea1 100644
--- a/power/aidl/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl
@@ -16,10 +16,11 @@
package android.hardware.power;
+import android.hardware.power.SessionHint;
import android.hardware.power.WorkDuration;
@VintfStability
-oneway interface IPowerHintSession {
+interface IPowerHintSession {
/**
* Updates the desired duration of a previously-created thread group.
*
@@ -28,7 +29,7 @@
*
* @param targetDurationNanos the new desired duration in nanoseconds
*/
- void updateTargetWorkDuration(long targetDurationNanos);
+ oneway void updateTargetWorkDuration(long targetDurationNanos);
/**
* Reports the actual duration of a thread group.
@@ -40,20 +41,44 @@
* @param actualDurationMicros how long the thread group took to complete its
* last task in nanoseconds
*/
- void reportActualWorkDuration(in WorkDuration[] durations);
+ oneway void reportActualWorkDuration(in WorkDuration[] durations);
/**
* Pause the session when the application is not allowed to send hint in framework.
*/
- void pause();
+ oneway void pause();
/**
* Resume the session when the application is allowed to send hint in framework.
*/
- void resume();
+ oneway void resume();
/**
* Close the session to release resources.
*/
- void close();
+ oneway void close();
+
+ /**
+ * Gives information to the PowerHintSession about upcoming or unexpected
+ * changes in load to supplement the normal updateTarget/reportActual cycle.
+ *
+ * @param hint The hint to provide to the PowerHintSession
+ */
+ oneway void sendHint(SessionHint hint);
+
+ /**
+ * Sets a list of threads to the power hint session. This operation will replace
+ * the current list of threads with the given list of threads. If there's already
+ * boost for the replaced threads, a reset must be performed for the replaced
+ * threads. Note that this is not an oneway method.
+ *
+ * @param threadIds The list of threads to be associated
+ * with this session.
+ *
+ * @throws ScopedAStatus Status of the operation. If status code is not
+ * STATUS_OK, getMessage() must be populated with the human-readable
+ * error message. If the list of thread ids is empty, EX_ILLEGAL_ARGUMENT
+ * must be thrown.
+ */
+ void setThreads(in int[] threadIds);
}
diff --git a/power/aidl/android/hardware/power/SessionHint.aidl b/power/aidl/android/hardware/power/SessionHint.aidl
new file mode 100644
index 0000000..a172e12
--- /dev/null
+++ b/power/aidl/android/hardware/power/SessionHint.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@Backing(type="int")
+enum SessionHint {
+ /**
+ * This hint indicates an increase in CPU workload intensity. It means that
+ * this hint session needs extra CPU resources to meet the target duration.
+ * This hint must be sent before reporting the actual duration to the session.
+ */
+ CPU_LOAD_UP = 0,
+
+ /**
+ * This hint indicates a decrease in CPU workload intensity. It means that
+ * this hint session can reduce CPU resources and still meet the target duration.
+ */
+ CPU_LOAD_DOWN = 1,
+
+ /**
+ * This hint indicates an upcoming CPU workload that is completely changed and
+ * unknown. It means that the hint session should reset CPU resources to a known
+ * baseline to prepare for an arbitrary load, and must wake up if inactive.
+ */
+ CPU_LOAD_RESET = 2,
+
+ /**
+ * This hint indicates that the most recent CPU workload is resuming after a
+ * period of inactivity. It means that the hint session should allocate similar
+ * CPU resources to what was used previously, and must wake up if inactive.
+ */
+ CPU_LOAD_RESUME = 3,
+
+ /**
+ * This hint indicates that this power hint session should be applied with a
+ * power-efficient-first scheduling strategy. This means the work of this
+ * power hint session is noncritical despite its CPU intensity.
+ */
+ POWER_EFFICIENCY = 4,
+}
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index b321394..da91ee6 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -30,7 +30,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.power-V3-ndk",
+ "android.hardware.power-V4-ndk",
],
srcs: [
"main.cpp",
diff --git a/power/aidl/default/PowerHintSession.cpp b/power/aidl/default/PowerHintSession.cpp
index 17fd26a..f395800 100644
--- a/power/aidl/default/PowerHintSession.cpp
+++ b/power/aidl/default/PowerHintSession.cpp
@@ -47,4 +47,16 @@
return ScopedAStatus::ok();
}
+ScopedAStatus PowerHintSession::sendHint(SessionHint /* hint */) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus PowerHintSession::setThreads(const std::vector<int32_t>& threadIds) {
+ if (threadIds.size() == 0) {
+ LOG(ERROR) << "Error: threadIds.size() shouldn't be " << threadIds.size();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ return ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/PowerHintSession.h b/power/aidl/default/PowerHintSession.h
index b7bf54c..1d74716 100644
--- a/power/aidl/default/PowerHintSession.h
+++ b/power/aidl/default/PowerHintSession.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/power/BnPowerHintSession.h>
+#include <aidl/android/hardware/power/SessionHint.h>
#include <aidl/android/hardware/power/WorkDuration.h>
namespace aidl::android::hardware::power::impl::example {
@@ -30,6 +31,8 @@
ndk::ScopedAStatus pause() override;
ndk::ScopedAStatus resume() override;
ndk::ScopedAStatus close() override;
+ ndk::ScopedAStatus sendHint(SessionHint hint) override;
+ ndk::ScopedAStatus setThreads(const std::vector<int32_t>& threadIds) override;
};
} // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/power-default.xml b/power/aidl/default/power-default.xml
index 927ba22..f5dd6b9 100644
--- a/power/aidl/default/power-default.xml
+++ b/power/aidl/default/power-default.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.power</name>
- <version>3</version>
+ <version>4</version>
<fqname>IPower/default</fqname>
</hal>
</manifest>
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index 4e8f517..56c98bd 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.power-V3-ndk",
+ "android.hardware.power-V4-ndk",
],
test_suites: [
"general-tests",
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index b81dd8f..d14e7b6 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -34,12 +34,16 @@
using android::hardware::power::IPower;
using android::hardware::power::IPowerHintSession;
using android::hardware::power::Mode;
+using android::hardware::power::SessionHint;
using android::hardware::power::WorkDuration;
const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};
const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
+const std::vector<SessionHint> kSessionHints{ndk::enum_range<SessionHint>().begin(),
+ ndk::enum_range<SessionHint>().end()};
+
const std::vector<Boost> kInvalidBoosts = {
static_cast<Boost>(static_cast<int32_t>(kBoosts.front()) - 1),
static_cast<Boost>(static_cast<int32_t>(kBoosts.back()) + 1),
@@ -50,6 +54,11 @@
static_cast<Mode>(static_cast<int32_t>(kModes.back()) + 1),
};
+const std::vector<SessionHint> kInvalidSessionHints = {
+ static_cast<SessionHint>(static_cast<int32_t>(kSessionHints.front()) - 1),
+ static_cast<SessionHint>(static_cast<int32_t>(kSessionHints.back()) + 1),
+};
+
class DurationWrapper : public WorkDuration {
public:
DurationWrapper(int64_t dur, int64_t time) {
@@ -91,6 +100,10 @@
// target-level=7 compatibility_matrix file.
const uint64_t kCompatibilityMatrix7ApiLevel = 33;
+// DEVICEs launching with Android 14 MUST meet the requirements for the
+// target-level=8 compatibility_matrix file.
+const uint64_t kCompatibilityMatrix8ApiLevel = 34;
+
inline bool isUnknownOrUnsupported(const ndk::ScopedAStatus& status) {
return status.getStatus() == STATUS_UNKNOWN_TRANSACTION ||
status.getExceptionCode() == EX_UNSUPPORTED_OPERATION;
@@ -218,6 +231,42 @@
ASSERT_TRUE(session->reportActualWorkDuration(kDurations).isOk());
}
+TEST_P(PowerAidl, sendSessionHint) {
+ std::shared_ptr<IPowerHintSession> session;
+ auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
+ if (!status.isOk()) {
+ EXPECT_TRUE(isUnknownOrUnsupported(status));
+ return;
+ }
+ for (const auto& sessionHint : kSessionHints) {
+ ASSERT_TRUE(session->sendHint(sessionHint).isOk());
+ }
+ for (const auto& sessionHint : kInvalidSessionHints) {
+ ASSERT_TRUE(session->sendHint(sessionHint).isOk());
+ }
+}
+
+TEST_P(PowerAidl, setThreads) {
+ std::shared_ptr<IPowerHintSession> session;
+ auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session);
+ if (mApiLevel < kCompatibilityMatrix7ApiLevel && !status.isOk()) {
+ EXPECT_TRUE(isUnknownOrUnsupported(status));
+ GTEST_SKIP() << "DEVICE not launching with Android 13 and beyond.";
+ }
+ ASSERT_TRUE(status.isOk());
+
+ if (mApiLevel < kCompatibilityMatrix8ApiLevel) {
+ GTEST_SKIP() << "DEVICE not launching with Android 14 and beyond.";
+ }
+
+ status = session->setThreads(kEmptyTids);
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+
+ status = session->setThreads(kSelfTids);
+ ASSERT_TRUE(status.isOk());
+}
+
// FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
// or later
TEST_P(PowerAidl, hasFixedPerformance) {
@@ -236,6 +285,7 @@
::android::PrintInstanceNameToString);
} // namespace
+} // namespace aidl::android::hardware::power
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
@@ -243,5 +293,3 @@
ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}
-
-} // namespace aidl::android::hardware::power
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index 08bcc28..e8cebd7 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -12,11 +12,11 @@
vendor_available: true,
host_supported: true,
srcs: ["android/hardware/radio/*.aidl"],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -36,12 +36,12 @@
vendor_available: true,
host_supported: true,
srcs: ["android/hardware/radio/config/*.aidl"],
- frozen: true,
+ frozen: false,
stability: "vintf",
- imports: ["android.hardware.radio-V1"],
+ imports: ["android.hardware.radio-V2"],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -62,10 +62,10 @@
host_supported: true,
srcs: ["android/hardware/radio/data/*.aidl"],
stability: "vintf",
- imports: ["android.hardware.radio-V1"],
+ imports: ["android.hardware.radio-V2"],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -86,10 +86,10 @@
host_supported: true,
srcs: ["android/hardware/radio/messaging/*.aidl"],
stability: "vintf",
- imports: ["android.hardware.radio-V1"],
+ imports: ["android.hardware.radio-V2"],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -110,10 +110,10 @@
host_supported: true,
srcs: ["android/hardware/radio/modem/*.aidl"],
stability: "vintf",
- imports: ["android.hardware.radio-V1"],
+ imports: ["android.hardware.radio-V2"],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -134,10 +134,10 @@
host_supported: true,
srcs: ["android/hardware/radio/network/*.aidl"],
stability: "vintf",
- imports: ["android.hardware.radio-V1"],
+ imports: ["android.hardware.radio-V2"],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -181,12 +181,12 @@
srcs: ["android/hardware/radio/sim/*.aidl"],
stability: "vintf",
imports: [
- "android.hardware.radio-V1",
- "android.hardware.radio.config-V1",
+ "android.hardware.radio-V2",
+ "android.hardware.radio.config-V2",
],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -210,10 +210,10 @@
host_supported: true,
srcs: ["android/hardware/radio/voice/*.aidl"],
stability: "vintf",
- imports: ["android.hardware.radio-V1"],
+ imports: ["android.hardware.radio-V2"],
backend: {
cpp: {
- enabled: false,
+ enabled: true,
},
java: {
sdk_version: "module_current",
@@ -227,3 +227,38 @@
],
}
+
+aidl_interface {
+ name: "android.hardware.radio.ims.media",
+ vendor_available: true,
+ srcs: ["android/hardware/radio/ims/media/*.aidl"],
+ stability: "vintf",
+ imports: [
+ "android.hardware.radio-V2",
+ "android.hardware.radio.data-V2",
+ ],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ },
+}
+
+aidl_interface {
+ name: "android.hardware.radio.ims",
+ vendor_available: true,
+ srcs: ["android/hardware/radio/ims/*.aidl"],
+ stability: "vintf",
+ imports: ["android.hardware.radio-V2"],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ },
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..74017e4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.config;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum MultipleEnabledProfilesMode {
+ NONE,
+ MEP_A1,
+ MEP_A2,
+ MEP_B,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
index be4c080..c264dfd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
@@ -38,4 +38,5 @@
String atr;
String eid;
android.hardware.radio.config.SimPortInfo[] portInfo;
+ android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
index 86272c2..a33ad6e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl
@@ -34,8 +34,8 @@
package android.hardware.radio.data;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ApnAuthType {
- NO_PAP_NO_CHAP = 0,
- PAP_NO_CHAP = 1,
- NO_PAP_CHAP = 2,
- PAP_CHAP = 3,
+ NO_PAP_NO_CHAP,
+ PAP_NO_CHAP,
+ NO_PAP_CHAP,
+ PAP_CHAP,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
index 1518a57..45d22c8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
@@ -35,19 +35,19 @@
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ApnTypes {
NONE = 0,
- DEFAULT = 1,
- MMS = 2,
- SUPL = 4,
- DUN = 8,
- HIPRI = 16,
- FOTA = 32,
- IMS = 64,
- CBS = 128,
- IA = 256,
- EMERGENCY = 512,
- MCX = 1024,
- XCAP = 2048,
- VSIM = 4096,
- BIP = 8192,
- ENTERPRISE = 16384,
+ DEFAULT = (1 << 0),
+ MMS = (1 << 1),
+ SUPL = (1 << 2),
+ DUN = (1 << 3),
+ HIPRI = (1 << 4),
+ FOTA = (1 << 5),
+ IMS = (1 << 6),
+ CBS = (1 << 7),
+ IA = (1 << 8),
+ EMERGENCY = (1 << 9),
+ MCX = (1 << 10),
+ XCAP = (1 << 11),
+ VSIM = (1 << 12),
+ BIP = (1 << 13),
+ ENTERPRISE = (1 << 14),
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
index d7d6983..8a3fd4f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
@@ -35,343 +35,347 @@
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum DataCallFailCause {
NONE = 0,
- OPERATOR_BARRED = 8,
- NAS_SIGNALLING = 14,
- INSUFFICIENT_RESOURCES = 26,
- MISSING_UNKNOWN_APN = 27,
- UNKNOWN_PDP_ADDRESS_TYPE = 28,
- USER_AUTHENTICATION = 29,
- ACTIVATION_REJECT_GGSN = 30,
- ACTIVATION_REJECT_UNSPECIFIED = 31,
- SERVICE_OPTION_NOT_SUPPORTED = 32,
- SERVICE_OPTION_NOT_SUBSCRIBED = 33,
- SERVICE_OPTION_OUT_OF_ORDER = 34,
- NSAPI_IN_USE = 35,
- REGULAR_DEACTIVATION = 36,
- QOS_NOT_ACCEPTED = 37,
- NETWORK_FAILURE = 38,
- UMTS_REACTIVATION_REQ = 39,
- FEATURE_NOT_SUPP = 40,
- TFT_SEMANTIC_ERROR = 41,
- TFT_SYTAX_ERROR = 42,
- UNKNOWN_PDP_CONTEXT = 43,
- FILTER_SEMANTIC_ERROR = 44,
- FILTER_SYTAX_ERROR = 45,
- PDP_WITHOUT_ACTIVE_TFT = 46,
- ONLY_IPV4_ALLOWED = 50,
- ONLY_IPV6_ALLOWED = 51,
- ONLY_SINGLE_BEARER_ALLOWED = 52,
- ESM_INFO_NOT_RECEIVED = 53,
- PDN_CONN_DOES_NOT_EXIST = 54,
- MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 55,
- MAX_ACTIVE_PDP_CONTEXT_REACHED = 65,
- UNSUPPORTED_APN_IN_CURRENT_PLMN = 66,
- INVALID_TRANSACTION_ID = 81,
- MESSAGE_INCORRECT_SEMANTIC = 95,
- INVALID_MANDATORY_INFO = 96,
- MESSAGE_TYPE_UNSUPPORTED = 97,
- MSG_TYPE_NONCOMPATIBLE_STATE = 98,
- UNKNOWN_INFO_ELEMENT = 99,
- CONDITIONAL_IE_ERROR = 100,
- MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101,
- PROTOCOL_ERRORS = 111,
- APN_TYPE_CONFLICT = 112,
- INVALID_PCSCF_ADDR = 113,
- INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 114,
- EMM_ACCESS_BARRED = 115,
- EMERGENCY_IFACE_ONLY = 116,
- IFACE_MISMATCH = 117,
- COMPANION_IFACE_IN_USE = 118,
- IP_ADDRESS_MISMATCH = 119,
- IFACE_AND_POL_FAMILY_MISMATCH = 120,
- EMM_ACCESS_BARRED_INFINITE_RETRY = 121,
- AUTH_FAILURE_ON_EMERGENCY_CALL = 122,
- OEM_DCFAILCAUSE_1 = 4097,
- OEM_DCFAILCAUSE_2 = 4098,
- OEM_DCFAILCAUSE_3 = 4099,
- OEM_DCFAILCAUSE_4 = 4100,
- OEM_DCFAILCAUSE_5 = 4101,
- OEM_DCFAILCAUSE_6 = 4102,
- OEM_DCFAILCAUSE_7 = 4103,
- OEM_DCFAILCAUSE_8 = 4104,
- OEM_DCFAILCAUSE_9 = 4105,
- OEM_DCFAILCAUSE_10 = 4106,
- OEM_DCFAILCAUSE_11 = 4107,
- OEM_DCFAILCAUSE_12 = 4108,
- OEM_DCFAILCAUSE_13 = 4109,
- OEM_DCFAILCAUSE_14 = 4110,
- OEM_DCFAILCAUSE_15 = 4111,
- VOICE_REGISTRATION_FAIL = -1,
- DATA_REGISTRATION_FAIL = -2,
- SIGNAL_LOST = -3,
- PREF_RADIO_TECH_CHANGED = -4,
- RADIO_POWER_OFF = -5,
- TETHERED_CALL_ACTIVE = -6,
- ERROR_UNSPECIFIED = 65535,
- LLC_SNDCP = 25,
- ACTIVATION_REJECTED_BCM_VIOLATION = 48,
- COLLISION_WITH_NETWORK_INITIATED_REQUEST = 56,
- ONLY_IPV4V6_ALLOWED = 57,
- ONLY_NON_IP_ALLOWED = 58,
- UNSUPPORTED_QCI_VALUE = 59,
- BEARER_HANDLING_NOT_SUPPORTED = 60,
- INVALID_DNS_ADDR = 123,
- INVALID_PCSCF_OR_DNS_ADDRESS = 124,
- CALL_PREEMPT_BY_EMERGENCY_APN = 127,
- UE_INITIATED_DETACH_OR_DISCONNECT = 128,
- MIP_FA_REASON_UNSPECIFIED = 2000,
- MIP_FA_ADMIN_PROHIBITED = 2001,
- MIP_FA_INSUFFICIENT_RESOURCES = 2002,
- MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2003,
- MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 2004,
- MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 2005,
- MIP_FA_MALFORMED_REQUEST = 2006,
- MIP_FA_MALFORMED_REPLY = 2007,
- MIP_FA_ENCAPSULATION_UNAVAILABLE = 2008,
- MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 2009,
- MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 2010,
- MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 2011,
- MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 2012,
- MIP_FA_MISSING_NAI = 2013,
- MIP_FA_MISSING_HOME_AGENT = 2014,
- MIP_FA_MISSING_HOME_ADDRESS = 2015,
- MIP_FA_UNKNOWN_CHALLENGE = 2016,
- MIP_FA_MISSING_CHALLENGE = 2017,
- MIP_FA_STALE_CHALLENGE = 2018,
- MIP_HA_REASON_UNSPECIFIED = 2019,
- MIP_HA_ADMIN_PROHIBITED = 2020,
- MIP_HA_INSUFFICIENT_RESOURCES = 2021,
- MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2022,
- MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 2023,
- MIP_HA_REGISTRATION_ID_MISMATCH = 2024,
- MIP_HA_MALFORMED_REQUEST = 2025,
- MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 2026,
- MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 2027,
- MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 2028,
- MIP_HA_ENCAPSULATION_UNAVAILABLE = 2029,
- CLOSE_IN_PROGRESS = 2030,
- NETWORK_INITIATED_TERMINATION = 2031,
- MODEM_APP_PREEMPTED = 2032,
- PDN_IPV4_CALL_DISALLOWED = 2033,
- PDN_IPV4_CALL_THROTTLED = 2034,
- PDN_IPV6_CALL_DISALLOWED = 2035,
- PDN_IPV6_CALL_THROTTLED = 2036,
- MODEM_RESTART = 2037,
- PDP_PPP_NOT_SUPPORTED = 2038,
- UNPREFERRED_RAT = 2039,
- PHYSICAL_LINK_CLOSE_IN_PROGRESS = 2040,
- APN_PENDING_HANDOVER = 2041,
- PROFILE_BEARER_INCOMPATIBLE = 2042,
- SIM_CARD_CHANGED = 2043,
- LOW_POWER_MODE_OR_POWERING_DOWN = 2044,
- APN_DISABLED = 2045,
- MAX_PPP_INACTIVITY_TIMER_EXPIRED = 2046,
- IPV6_ADDRESS_TRANSFER_FAILED = 2047,
- TRAT_SWAP_FAILED = 2048,
- EHRPD_TO_HRPD_FALLBACK = 2049,
- MIP_CONFIG_FAILURE = 2050,
- PDN_INACTIVITY_TIMER_EXPIRED = 2051,
- MAX_IPV4_CONNECTIONS = 2052,
- MAX_IPV6_CONNECTIONS = 2053,
- APN_MISMATCH = 2054,
- IP_VERSION_MISMATCH = 2055,
- DUN_CALL_DISALLOWED = 2056,
- INTERNAL_EPC_NONEPC_TRANSITION = 2057,
- INTERFACE_IN_USE = 2058,
- APN_DISALLOWED_ON_ROAMING = 2059,
- APN_PARAMETERS_CHANGED = 2060,
- NULL_APN_DISALLOWED = 2061,
- THERMAL_MITIGATION = 2062,
- DATA_SETTINGS_DISABLED = 2063,
- DATA_ROAMING_SETTINGS_DISABLED = 2064,
- DDS_SWITCHED = 2065,
- FORBIDDEN_APN_NAME = 2066,
- DDS_SWITCH_IN_PROGRESS = 2067,
- CALL_DISALLOWED_IN_ROAMING = 2068,
- NON_IP_NOT_SUPPORTED = 2069,
- PDN_NON_IP_CALL_THROTTLED = 2070,
- PDN_NON_IP_CALL_DISALLOWED = 2071,
- CDMA_LOCK = 2072,
- CDMA_INTERCEPT = 2073,
- CDMA_REORDER = 2074,
- CDMA_RELEASE_DUE_TO_SO_REJECTION = 2075,
- CDMA_INCOMING_CALL = 2076,
- CDMA_ALERT_STOP = 2077,
- CHANNEL_ACQUISITION_FAILURE = 2078,
- MAX_ACCESS_PROBE = 2079,
- CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 2080,
- NO_RESPONSE_FROM_BASE_STATION = 2081,
- REJECTED_BY_BASE_STATION = 2082,
- CONCURRENT_SERVICES_INCOMPATIBLE = 2083,
- NO_CDMA_SERVICE = 2084,
- RUIM_NOT_PRESENT = 2085,
- CDMA_RETRY_ORDER = 2086,
- ACCESS_BLOCK = 2087,
- ACCESS_BLOCK_ALL = 2088,
- IS707B_MAX_ACCESS_PROBES = 2089,
- THERMAL_EMERGENCY = 2090,
- CONCURRENT_SERVICES_NOT_ALLOWED = 2091,
- INCOMING_CALL_REJECTED = 2092,
- NO_SERVICE_ON_GATEWAY = 2093,
- NO_GPRS_CONTEXT = 2094,
- ILLEGAL_MS = 2095,
- ILLEGAL_ME = 2096,
- GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 2097,
- GPRS_SERVICES_NOT_ALLOWED = 2098,
- MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 2099,
- IMPLICITLY_DETACHED = 2100,
- PLMN_NOT_ALLOWED = 2101,
- LOCATION_AREA_NOT_ALLOWED = 2102,
- GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 2103,
- PDP_DUPLICATE = 2104,
- UE_RAT_CHANGE = 2105,
- CONGESTION = 2106,
- NO_PDP_CONTEXT_ACTIVATED = 2107,
- ACCESS_CLASS_DSAC_REJECTION = 2108,
- PDP_ACTIVATE_MAX_RETRY_FAILED = 2109,
- RADIO_ACCESS_BEARER_FAILURE = 2110,
- ESM_UNKNOWN_EPS_BEARER_CONTEXT = 2111,
- DRB_RELEASED_BY_RRC = 2112,
- CONNECTION_RELEASED = 2113,
- EMM_DETACHED = 2114,
- EMM_ATTACH_FAILED = 2115,
- EMM_ATTACH_STARTED = 2116,
- LTE_NAS_SERVICE_REQUEST_FAILED = 2117,
- DUPLICATE_BEARER_ID = 2118,
- ESM_COLLISION_SCENARIOS = 2119,
- ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 2120,
- ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 2121,
- ESM_BAD_OTA_MESSAGE = 2122,
- ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 2123,
- ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 2124,
- DS_EXPLICIT_DEACTIVATION = 2125,
- ESM_LOCAL_CAUSE_NONE = 2126,
- LTE_THROTTLING_NOT_REQUIRED = 2127,
- ACCESS_CONTROL_LIST_CHECK_FAILURE = 2128,
- SERVICE_NOT_ALLOWED_ON_PLMN = 2129,
- EMM_T3417_EXPIRED = 2130,
- EMM_T3417_EXT_EXPIRED = 2131,
- RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 2132,
- RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 2133,
- RRC_UPLINK_CONNECTION_RELEASE = 2134,
- RRC_UPLINK_RADIO_LINK_FAILURE = 2135,
- RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 2136,
- RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 2137,
- RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 2138,
- RRC_CONNECTION_ACCESS_BARRED = 2139,
- RRC_CONNECTION_CELL_RESELECTION = 2140,
- RRC_CONNECTION_CONFIG_FAILURE = 2141,
- RRC_CONNECTION_TIMER_EXPIRED = 2142,
- RRC_CONNECTION_LINK_FAILURE = 2143,
- RRC_CONNECTION_CELL_NOT_CAMPED = 2144,
- RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 2145,
- RRC_CONNECTION_REJECT_BY_NETWORK = 2146,
- RRC_CONNECTION_NORMAL_RELEASE = 2147,
- RRC_CONNECTION_RADIO_LINK_FAILURE = 2148,
- RRC_CONNECTION_REESTABLISHMENT_FAILURE = 2149,
- RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 2150,
- RRC_CONNECTION_ABORT_REQUEST = 2151,
- RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 2152,
- NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 2153,
- NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 2154,
- ESM_PROCEDURE_TIME_OUT = 2155,
- INVALID_CONNECTION_ID = 2156,
- MAXIMIUM_NSAPIS_EXCEEDED = 2157,
- INVALID_PRIMARY_NSAPI = 2158,
- CANNOT_ENCODE_OTA_MESSAGE = 2159,
- RADIO_ACCESS_BEARER_SETUP_FAILURE = 2160,
- PDP_ESTABLISH_TIMEOUT_EXPIRED = 2161,
- PDP_MODIFY_TIMEOUT_EXPIRED = 2162,
- PDP_INACTIVE_TIMEOUT_EXPIRED = 2163,
- PDP_LOWERLAYER_ERROR = 2164,
- PDP_MODIFY_COLLISION = 2165,
- MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 2166,
- NAS_REQUEST_REJECTED_BY_NETWORK = 2167,
- RRC_CONNECTION_INVALID_REQUEST = 2168,
- RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 2169,
- RRC_CONNECTION_RF_UNAVAILABLE = 2170,
- RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 2171,
- RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 2172,
- RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 2173,
- RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 2174,
- RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 2175,
- IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 2176,
- IMEI_NOT_ACCEPTED = 2177,
- EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 2178,
- EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 2179,
- MSC_TEMPORARILY_NOT_REACHABLE = 2180,
- CS_DOMAIN_NOT_AVAILABLE = 2181,
- ESM_FAILURE = 2182,
- MAC_FAILURE = 2183,
- SYNCHRONIZATION_FAILURE = 2184,
- UE_SECURITY_CAPABILITIES_MISMATCH = 2185,
- SECURITY_MODE_REJECTED = 2186,
- UNACCEPTABLE_NON_EPS_AUTHENTICATION = 2187,
- CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 2188,
- NO_EPS_BEARER_CONTEXT_ACTIVATED = 2189,
- INVALID_EMM_STATE = 2190,
- NAS_LAYER_FAILURE = 2191,
- MULTIPLE_PDP_CALL_NOT_ALLOWED = 2192,
- EMBMS_NOT_ENABLED = 2193,
- IRAT_HANDOVER_FAILED = 2194,
- EMBMS_REGULAR_DEACTIVATION = 2195,
- TEST_LOOPBACK_REGULAR_DEACTIVATION = 2196,
- LOWER_LAYER_REGISTRATION_FAILURE = 2197,
- DATA_PLAN_EXPIRED = 2198,
- UMTS_HANDOVER_TO_IWLAN = 2199,
- EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 2200,
- EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 2201,
- EVDO_HDR_CHANGED = 2202,
- EVDO_HDR_EXITED = 2203,
- EVDO_HDR_NO_SESSION = 2204,
- EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 2205,
- EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 2206,
- FAILED_TO_ACQUIRE_COLOCATED_HDR = 2207,
- OTASP_COMMIT_IN_PROGRESS = 2208,
- NO_HYBRID_HDR_SERVICE = 2209,
- HDR_NO_LOCK_GRANTED = 2210,
- DBM_OR_SMS_IN_PROGRESS = 2211,
- HDR_FADE = 2212,
- HDR_ACCESS_FAILURE = 2213,
- UNSUPPORTED_1X_PREV = 2214,
- LOCAL_END = 2215,
- NO_SERVICE = 2216,
- FADE = 2217,
- NORMAL_RELEASE = 2218,
- ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219,
- REDIRECTION_OR_HANDOFF_IN_PROGRESS = 2220,
- EMERGENCY_MODE = 2221,
- PHONE_IN_USE = 2222,
- INVALID_MODE = 2223,
- INVALID_SIM_STATE = 2224,
- NO_COLLOCATED_HDR = 2225,
- UE_IS_ENTERING_POWERSAVE_MODE = 2226,
- DUAL_SWITCH = 2227,
- PPP_TIMEOUT = 2228,
- PPP_AUTH_FAILURE = 2229,
- PPP_OPTION_MISMATCH = 2230,
- PPP_PAP_FAILURE = 2231,
- PPP_CHAP_FAILURE = 2232,
- PPP_CLOSE_IN_PROGRESS = 2233,
- LIMITED_TO_IPV4 = 2234,
- LIMITED_TO_IPV6 = 2235,
- VSNCP_TIMEOUT = 2236,
- VSNCP_GEN_ERROR = 2237,
- VSNCP_APN_UNAUTHORIZED = 2238,
- VSNCP_PDN_LIMIT_EXCEEDED = 2239,
- VSNCP_NO_PDN_GATEWAY_ADDRESS = 2240,
- VSNCP_PDN_GATEWAY_UNREACHABLE = 2241,
- VSNCP_PDN_GATEWAY_REJECT = 2242,
- VSNCP_INSUFFICIENT_PARAMETERS = 2243,
- VSNCP_RESOURCE_UNAVAILABLE = 2244,
- VSNCP_ADMINISTRATIVELY_PROHIBITED = 2245,
- VSNCP_PDN_ID_IN_USE = 2246,
- VSNCP_SUBSCRIBER_LIMITATION = 2247,
- VSNCP_PDN_EXISTS_FOR_THIS_APN = 2248,
- VSNCP_RECONNECT_NOT_ALLOWED = 2249,
- IPV6_PREFIX_UNAVAILABLE = 2250,
- HANDOFF_PREFERENCE_CHANGED = 2251,
- SLICE_REJECTED = 2252,
- MATCH_ALL_RULE_NOT_ALLOWED = 2253,
- ALL_MATCHING_RULES_FAILED = 2254,
+ OPERATOR_BARRED = 0x08,
+ NAS_SIGNALLING = 0x0E,
+ INSUFFICIENT_RESOURCES = 0x1A,
+ MISSING_UNKNOWN_APN = 0x1B,
+ UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,
+ USER_AUTHENTICATION = 0x1D,
+ ACTIVATION_REJECT_GGSN = 0x1E,
+ ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
+ SERVICE_OPTION_NOT_SUPPORTED = 0x20,
+ SERVICE_OPTION_NOT_SUBSCRIBED = 0x21,
+ SERVICE_OPTION_OUT_OF_ORDER = 0x22,
+ NSAPI_IN_USE = 0x23,
+ REGULAR_DEACTIVATION = 0x24,
+ QOS_NOT_ACCEPTED = 0x25,
+ NETWORK_FAILURE = 0x26,
+ UMTS_REACTIVATION_REQ = 0x27,
+ FEATURE_NOT_SUPP = 0x28,
+ TFT_SEMANTIC_ERROR = 0x29,
+ TFT_SYTAX_ERROR = 0x2A,
+ UNKNOWN_PDP_CONTEXT = 0x2B,
+ FILTER_SEMANTIC_ERROR = 0x2C,
+ FILTER_SYTAX_ERROR = 0x2D,
+ PDP_WITHOUT_ACTIVE_TFT = 0x2E,
+ ONLY_IPV4_ALLOWED = 0x32,
+ ONLY_IPV6_ALLOWED = 0x33,
+ ONLY_SINGLE_BEARER_ALLOWED = 0x34,
+ ESM_INFO_NOT_RECEIVED = 0x35,
+ PDN_CONN_DOES_NOT_EXIST = 0x36,
+ MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
+ MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
+ UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
+ INVALID_TRANSACTION_ID = 0x51,
+ MESSAGE_INCORRECT_SEMANTIC = 0x5F,
+ INVALID_MANDATORY_INFO = 0x60,
+ MESSAGE_TYPE_UNSUPPORTED = 0x61,
+ MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
+ UNKNOWN_INFO_ELEMENT = 0x63,
+ CONDITIONAL_IE_ERROR = 0x64,
+ MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
+ PROTOCOL_ERRORS = 0x6F,
+ APN_TYPE_CONFLICT = 0x70,
+ INVALID_PCSCF_ADDR = 0x71,
+ INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
+ EMM_ACCESS_BARRED = 0x73,
+ EMERGENCY_IFACE_ONLY = 0x74,
+ IFACE_MISMATCH = 0x75,
+ COMPANION_IFACE_IN_USE = 0x76,
+ IP_ADDRESS_MISMATCH = 0x77,
+ IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
+ EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
+ AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
+ OEM_DCFAILCAUSE_1 = 0x1001,
+ OEM_DCFAILCAUSE_2 = 0x1002,
+ OEM_DCFAILCAUSE_3 = 0x1003,
+ OEM_DCFAILCAUSE_4 = 0x1004,
+ OEM_DCFAILCAUSE_5 = 0x1005,
+ OEM_DCFAILCAUSE_6 = 0x1006,
+ OEM_DCFAILCAUSE_7 = 0x1007,
+ OEM_DCFAILCAUSE_8 = 0x1008,
+ OEM_DCFAILCAUSE_9 = 0x1009,
+ OEM_DCFAILCAUSE_10 = 0x100A,
+ OEM_DCFAILCAUSE_11 = 0x100B,
+ OEM_DCFAILCAUSE_12 = 0x100C,
+ OEM_DCFAILCAUSE_13 = 0x100D,
+ OEM_DCFAILCAUSE_14 = 0x100E,
+ OEM_DCFAILCAUSE_15 = 0x100F,
+ VOICE_REGISTRATION_FAIL = (-1),
+ DATA_REGISTRATION_FAIL = (-2),
+ SIGNAL_LOST = (-3),
+ PREF_RADIO_TECH_CHANGED = (-4),
+ RADIO_POWER_OFF = (-5),
+ TETHERED_CALL_ACTIVE = (-6),
+ ERROR_UNSPECIFIED = 0xffff,
+ LLC_SNDCP = 0x19,
+ ACTIVATION_REJECTED_BCM_VIOLATION = 0x30,
+ COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38,
+ ONLY_IPV4V6_ALLOWED = 0x39,
+ ONLY_NON_IP_ALLOWED = 0x3A,
+ UNSUPPORTED_QCI_VALUE = 0x3B,
+ BEARER_HANDLING_NOT_SUPPORTED = 0x3C,
+ INVALID_DNS_ADDR = 0x7B,
+ INVALID_PCSCF_OR_DNS_ADDRESS = 0x7C,
+ CALL_PREEMPT_BY_EMERGENCY_APN = 0x7F,
+ UE_INITIATED_DETACH_OR_DISCONNECT = 0x80,
+ MIP_FA_REASON_UNSPECIFIED = 0x7D0,
+ MIP_FA_ADMIN_PROHIBITED = 0x7D1,
+ MIP_FA_INSUFFICIENT_RESOURCES = 0x7D2,
+ MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7D3,
+ MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 0x7D4,
+ MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 0x7D5,
+ MIP_FA_MALFORMED_REQUEST = 0x7D6,
+ MIP_FA_MALFORMED_REPLY = 0x7D7,
+ MIP_FA_ENCAPSULATION_UNAVAILABLE = 0x7D8,
+ MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 0x7D9,
+ MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 0x7DA,
+ MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 0x7DB,
+ MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 0x7DC,
+ MIP_FA_MISSING_NAI = 0x7DD,
+ MIP_FA_MISSING_HOME_AGENT = 0x7DE,
+ MIP_FA_MISSING_HOME_ADDRESS = 0x7DF,
+ MIP_FA_UNKNOWN_CHALLENGE = 0x7E0,
+ MIP_FA_MISSING_CHALLENGE = 0x7E1,
+ MIP_FA_STALE_CHALLENGE = 0x7E2,
+ MIP_HA_REASON_UNSPECIFIED = 0x7E3,
+ MIP_HA_ADMIN_PROHIBITED = 0x7E4,
+ MIP_HA_INSUFFICIENT_RESOURCES = 0x7E5,
+ MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7E6,
+ MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 0x7E7,
+ MIP_HA_REGISTRATION_ID_MISMATCH = 0x7E8,
+ MIP_HA_MALFORMED_REQUEST = 0x7E9,
+ MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 0x7EA,
+ MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 0x7EB,
+ MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 0x7EC,
+ MIP_HA_ENCAPSULATION_UNAVAILABLE = 0x7ED,
+ CLOSE_IN_PROGRESS = 0x7EE,
+ NETWORK_INITIATED_TERMINATION = 0x7EF,
+ MODEM_APP_PREEMPTED = 0x7F0,
+ PDN_IPV4_CALL_DISALLOWED = 0x7F1,
+ PDN_IPV4_CALL_THROTTLED = 0x7F2,
+ PDN_IPV6_CALL_DISALLOWED = 0x7F3,
+ PDN_IPV6_CALL_THROTTLED = 0x7F4,
+ MODEM_RESTART = 0x7F5,
+ PDP_PPP_NOT_SUPPORTED = 0x7F6,
+ UNPREFERRED_RAT = 0x7F7,
+ PHYSICAL_LINK_CLOSE_IN_PROGRESS = 0x7F8,
+ APN_PENDING_HANDOVER = 0x7F9,
+ PROFILE_BEARER_INCOMPATIBLE = 0x7FA,
+ SIM_CARD_CHANGED = 0x7FB,
+ LOW_POWER_MODE_OR_POWERING_DOWN = 0x7FC,
+ APN_DISABLED = 0x7FD,
+ MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE,
+ IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF,
+ TRAT_SWAP_FAILED = 0x800,
+ EHRPD_TO_HRPD_FALLBACK = 0x801,
+ MIP_CONFIG_FAILURE = 0x802,
+ PDN_INACTIVITY_TIMER_EXPIRED = 0x803,
+ MAX_IPV4_CONNECTIONS = 0x804,
+ MAX_IPV6_CONNECTIONS = 0x805,
+ APN_MISMATCH = 0x806,
+ IP_VERSION_MISMATCH = 0x807,
+ DUN_CALL_DISALLOWED = 0x808,
+ INTERNAL_EPC_NONEPC_TRANSITION = 0x809,
+ INTERFACE_IN_USE = 0x80A,
+ APN_DISALLOWED_ON_ROAMING = 0x80B,
+ APN_PARAMETERS_CHANGED = 0x80C,
+ NULL_APN_DISALLOWED = 0x80D,
+ THERMAL_MITIGATION = 0x80E,
+ DATA_SETTINGS_DISABLED = 0x80F,
+ DATA_ROAMING_SETTINGS_DISABLED = 0x810,
+ DDS_SWITCHED = 0x811,
+ FORBIDDEN_APN_NAME = 0x812,
+ DDS_SWITCH_IN_PROGRESS = 0x813,
+ CALL_DISALLOWED_IN_ROAMING = 0x814,
+ NON_IP_NOT_SUPPORTED = 0x815,
+ PDN_NON_IP_CALL_THROTTLED = 0x816,
+ PDN_NON_IP_CALL_DISALLOWED = 0x817,
+ CDMA_LOCK = 0x818,
+ CDMA_INTERCEPT = 0x819,
+ CDMA_REORDER = 0x81A,
+ CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B,
+ CDMA_INCOMING_CALL = 0x81C,
+ CDMA_ALERT_STOP = 0x81D,
+ CHANNEL_ACQUISITION_FAILURE = 0x81E,
+ MAX_ACCESS_PROBE = 0x81F,
+ CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 0x820,
+ NO_RESPONSE_FROM_BASE_STATION = 0x821,
+ REJECTED_BY_BASE_STATION = 0x822,
+ CONCURRENT_SERVICES_INCOMPATIBLE = 0x823,
+ NO_CDMA_SERVICE = 0x824,
+ RUIM_NOT_PRESENT = 0x825,
+ CDMA_RETRY_ORDER = 0x826,
+ ACCESS_BLOCK = 0x827,
+ ACCESS_BLOCK_ALL = 0x828,
+ IS707B_MAX_ACCESS_PROBES = 0x829,
+ THERMAL_EMERGENCY = 0x82A,
+ CONCURRENT_SERVICES_NOT_ALLOWED = 0x82B,
+ INCOMING_CALL_REJECTED = 0x82C,
+ NO_SERVICE_ON_GATEWAY = 0x82D,
+ NO_GPRS_CONTEXT = 0x82E,
+ ILLEGAL_MS = 0x82F,
+ ILLEGAL_ME = 0x830,
+ GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 0x831,
+ GPRS_SERVICES_NOT_ALLOWED = 0x832,
+ MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 0x833,
+ IMPLICITLY_DETACHED = 0x834,
+ PLMN_NOT_ALLOWED = 0x835,
+ LOCATION_AREA_NOT_ALLOWED = 0x836,
+ GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 0x837,
+ PDP_DUPLICATE = 0x838,
+ UE_RAT_CHANGE = 0x839,
+ CONGESTION = 0x83A,
+ NO_PDP_CONTEXT_ACTIVATED = 0x83B,
+ ACCESS_CLASS_DSAC_REJECTION = 0x83C,
+ PDP_ACTIVATE_MAX_RETRY_FAILED = 0x83D,
+ RADIO_ACCESS_BEARER_FAILURE = 0x83E,
+ ESM_UNKNOWN_EPS_BEARER_CONTEXT = 0x83F,
+ DRB_RELEASED_BY_RRC = 0x840,
+ CONNECTION_RELEASED = 0x841,
+ EMM_DETACHED = 0x842,
+ EMM_ATTACH_FAILED = 0x843,
+ EMM_ATTACH_STARTED = 0x844,
+ LTE_NAS_SERVICE_REQUEST_FAILED = 0x845,
+ DUPLICATE_BEARER_ID = 0x846,
+ ESM_COLLISION_SCENARIOS = 0x847,
+ ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 0x848,
+ ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 0x849,
+ ESM_BAD_OTA_MESSAGE = 0x84A,
+ ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 0x84B,
+ ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 0x84C,
+ DS_EXPLICIT_DEACTIVATION = 0x84D,
+ ESM_LOCAL_CAUSE_NONE = 0x84E,
+ LTE_THROTTLING_NOT_REQUIRED = 0x84F,
+ ACCESS_CONTROL_LIST_CHECK_FAILURE = 0x850,
+ SERVICE_NOT_ALLOWED_ON_PLMN = 0x851,
+ EMM_T3417_EXPIRED = 0x852,
+ EMM_T3417_EXT_EXPIRED = 0x853,
+ RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 0x854,
+ RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 0x855,
+ RRC_UPLINK_CONNECTION_RELEASE = 0x856,
+ RRC_UPLINK_RADIO_LINK_FAILURE = 0x857,
+ RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 0x858,
+ RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 0x859,
+ RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 0x85A,
+ RRC_CONNECTION_ACCESS_BARRED = 0x85B,
+ RRC_CONNECTION_CELL_RESELECTION = 0x85C,
+ RRC_CONNECTION_CONFIG_FAILURE = 0x85D,
+ RRC_CONNECTION_TIMER_EXPIRED = 0x85E,
+ RRC_CONNECTION_LINK_FAILURE = 0x85F,
+ RRC_CONNECTION_CELL_NOT_CAMPED = 0x860,
+ RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 0x861,
+ RRC_CONNECTION_REJECT_BY_NETWORK = 0x862,
+ RRC_CONNECTION_NORMAL_RELEASE = 0x863,
+ RRC_CONNECTION_RADIO_LINK_FAILURE = 0x864,
+ RRC_CONNECTION_REESTABLISHMENT_FAILURE = 0x865,
+ RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 0x866,
+ RRC_CONNECTION_ABORT_REQUEST = 0x867,
+ RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 0x868,
+ NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 0x869,
+ NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 0x86A,
+ ESM_PROCEDURE_TIME_OUT = 0x86B,
+ INVALID_CONNECTION_ID = 0x86C,
+ MAXIMIUM_NSAPIS_EXCEEDED = 0x86D,
+ INVALID_PRIMARY_NSAPI = 0x86E,
+ CANNOT_ENCODE_OTA_MESSAGE = 0x86F,
+ RADIO_ACCESS_BEARER_SETUP_FAILURE = 0x870,
+ PDP_ESTABLISH_TIMEOUT_EXPIRED = 0x871,
+ PDP_MODIFY_TIMEOUT_EXPIRED = 0x872,
+ PDP_INACTIVE_TIMEOUT_EXPIRED = 0x873,
+ PDP_LOWERLAYER_ERROR = 0x874,
+ PDP_MODIFY_COLLISION = 0x875,
+ /**
+ * @deprecated use MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED instead.
+ */
+ MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+ MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+ NAS_REQUEST_REJECTED_BY_NETWORK = 0x877,
+ RRC_CONNECTION_INVALID_REQUEST = 0x878,
+ RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 0x879,
+ RRC_CONNECTION_RF_UNAVAILABLE = 0x87A,
+ RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 0x87B,
+ RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 0x87C,
+ RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 0x87D,
+ RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 0x87E,
+ RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 0x87F,
+ IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 0x880,
+ IMEI_NOT_ACCEPTED = 0x881,
+ EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 0x882,
+ EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 0x883,
+ MSC_TEMPORARILY_NOT_REACHABLE = 0x884,
+ CS_DOMAIN_NOT_AVAILABLE = 0x885,
+ ESM_FAILURE = 0x886,
+ MAC_FAILURE = 0x887,
+ SYNCHRONIZATION_FAILURE = 0x888,
+ UE_SECURITY_CAPABILITIES_MISMATCH = 0x889,
+ SECURITY_MODE_REJECTED = 0x88A,
+ UNACCEPTABLE_NON_EPS_AUTHENTICATION = 0x88B,
+ CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 0x88C,
+ NO_EPS_BEARER_CONTEXT_ACTIVATED = 0x88D,
+ INVALID_EMM_STATE = 0x88E,
+ NAS_LAYER_FAILURE = 0x88F,
+ MULTIPLE_PDP_CALL_NOT_ALLOWED = 0x890,
+ EMBMS_NOT_ENABLED = 0x891,
+ IRAT_HANDOVER_FAILED = 0x892,
+ EMBMS_REGULAR_DEACTIVATION = 0x893,
+ TEST_LOOPBACK_REGULAR_DEACTIVATION = 0x894,
+ LOWER_LAYER_REGISTRATION_FAILURE = 0x895,
+ DATA_PLAN_EXPIRED = 0x896,
+ UMTS_HANDOVER_TO_IWLAN = 0x897,
+ EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898,
+ EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899,
+ EVDO_HDR_CHANGED = 0x89A,
+ EVDO_HDR_EXITED = 0x89B,
+ EVDO_HDR_NO_SESSION = 0x89C,
+ EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D,
+ EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E,
+ FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F,
+ OTASP_COMMIT_IN_PROGRESS = 0x8A0,
+ NO_HYBRID_HDR_SERVICE = 0x8A1,
+ HDR_NO_LOCK_GRANTED = 0x8A2,
+ DBM_OR_SMS_IN_PROGRESS = 0x8A3,
+ HDR_FADE = 0x8A4,
+ HDR_ACCESS_FAILURE = 0x8A5,
+ UNSUPPORTED_1X_PREV = 0x8A6,
+ LOCAL_END = 0x8A7,
+ NO_SERVICE = 0x8A8,
+ FADE = 0x8A9,
+ NORMAL_RELEASE = 0x8AA,
+ ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 0x8AB,
+ REDIRECTION_OR_HANDOFF_IN_PROGRESS = 0x8AC,
+ EMERGENCY_MODE = 0x8AD,
+ PHONE_IN_USE = 0x8AE,
+ INVALID_MODE = 0x8AF,
+ INVALID_SIM_STATE = 0x8B0,
+ NO_COLLOCATED_HDR = 0x8B1,
+ UE_IS_ENTERING_POWERSAVE_MODE = 0x8B2,
+ DUAL_SWITCH = 0x8B3,
+ PPP_TIMEOUT = 0x8B4,
+ PPP_AUTH_FAILURE = 0x8B5,
+ PPP_OPTION_MISMATCH = 0x8B6,
+ PPP_PAP_FAILURE = 0x8B7,
+ PPP_CHAP_FAILURE = 0x8B8,
+ PPP_CLOSE_IN_PROGRESS = 0x8B9,
+ LIMITED_TO_IPV4 = 0x8BA,
+ LIMITED_TO_IPV6 = 0x8BB,
+ VSNCP_TIMEOUT = 0x8BC,
+ VSNCP_GEN_ERROR = 0x8BD,
+ VSNCP_APN_UNAUTHORIZED = 0x8BE,
+ VSNCP_PDN_LIMIT_EXCEEDED = 0x8BF,
+ VSNCP_NO_PDN_GATEWAY_ADDRESS = 0x8C0,
+ VSNCP_PDN_GATEWAY_UNREACHABLE = 0x8C1,
+ VSNCP_PDN_GATEWAY_REJECT = 0x8C2,
+ VSNCP_INSUFFICIENT_PARAMETERS = 0x8C3,
+ VSNCP_RESOURCE_UNAVAILABLE = 0x8C4,
+ VSNCP_ADMINISTRATIVELY_PROHIBITED = 0x8C5,
+ VSNCP_PDN_ID_IN_USE = 0x8C6,
+ VSNCP_SUBSCRIBER_LIMITATION = 0x8C7,
+ VSNCP_PDN_EXISTS_FOR_THIS_APN = 0x8C8,
+ VSNCP_RECONNECT_NOT_ALLOWED = 0x8C9,
+ IPV6_PREFIX_UNAVAILABLE = 0x8CA,
+ HANDOFF_PREFERENCE_CHANGED = 0x8CB,
+ SLICE_REJECTED = 0x8CC,
+ MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD,
+ ALL_MATCHING_RULES_FAILED = 0x8CE,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index 16fada1..0136fa4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -60,7 +60,7 @@
const int ID_FOTA = 3;
const int ID_CBS = 4;
const int ID_OEM_BASE = 1000;
- const int ID_INVALID = -1;
+ const int ID_INVALID = 0xFFFFFFFF;
const int TYPE_COMMON = 0;
const int TYPE_3GPP = 1;
const int TYPE_3GPP2 = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
index 4f976cd..e80a764 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl
@@ -34,8 +34,8 @@
package android.hardware.radio.data;
@Backing(type="byte") @JavaDerive(toString=true) @VintfStability
enum DataThrottlingAction {
- NO_DATA_THROTTLING = 0,
- THROTTLE_SECONDARY_CARRIER = 1,
- THROTTLE_ANCHOR_CARRIER = 2,
- HOLD = 3,
+ NO_DATA_THROTTLING,
+ THROTTLE_SECONDARY_CARRIER,
+ THROTTLE_ANCHOR_CARRIER,
+ HOLD,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
index 48e646e..77d637b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
@@ -39,5 +39,5 @@
long deprecationTime;
long expirationTime;
const int ADDRESS_PROPERTY_NONE = 0;
- const int ADDRESS_PROPERTY_DEPRECATED = 32;
+ const int ADDRESS_PROPERTY_DEPRECATED = 0x20;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
index 62f6204..be859b7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
@@ -38,7 +38,12 @@
android.hardware.radio.data.QosBandwidth downlink;
android.hardware.radio.data.QosBandwidth uplink;
byte qfi;
+ /**
+ * @deprecated use averagingWindowMillis;
+ */
char averagingWindowMs;
+ int averagingWindowMillis = AVERAGING_WINDOW_UNKNOWN;
const byte FLOW_ID_RANGE_MIN = 1;
const byte FLOW_ID_RANGE_MAX = 63;
+ const int AVERAGING_WINDOW_UNKNOWN = (-1);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
index 9771e5c..d1c4a62 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.data;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum PdpProtocolType {
- UNKNOWN = -1,
+ UNKNOWN = (-1),
IP = 0,
IPV6 = 1,
IPV4V6 = 2,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
index e22b359..de45cc5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
@@ -47,7 +47,7 @@
const byte DIRECTION_DOWNLINK = 0;
const byte DIRECTION_UPLINK = 1;
const byte DIRECTION_BIDIRECTIONAL = 2;
- const byte PROTOCOL_UNSPECIFIED = -1;
+ const byte PROTOCOL_UNSPECIFIED = (-1);
const byte PROTOCOL_TCP = 6;
const byte PROTOCOL_UDP = 17;
const byte PROTOCOL_ESP = 50;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
index 434ee7d..d83df81 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -39,7 +39,7 @@
byte sscMode;
android.hardware.radio.data.SliceInfo[] sliceInfo;
String[] dnn;
- const byte SSC_MODE_UNKNOWN = -1;
+ const byte SSC_MODE_UNKNOWN = (-1);
const byte SSC_MODE_1 = 1;
const byte SSC_MODE_2 = 2;
const byte SSC_MODE_3 = 3;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrMode.aidl
new file mode 100644
index 0000000..37e3b25
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrMode.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum AmrMode {
+ AMR_MODE_0 = (1 << 0) /* 1 */,
+ AMR_MODE_1 = (1 << 1) /* 2 */,
+ AMR_MODE_2 = (1 << 2) /* 4 */,
+ AMR_MODE_3 = (1 << 3) /* 8 */,
+ AMR_MODE_4 = (1 << 4) /* 16 */,
+ AMR_MODE_5 = (1 << 5) /* 32 */,
+ AMR_MODE_6 = (1 << 6) /* 64 */,
+ AMR_MODE_7 = (1 << 7) /* 128 */,
+ AMR_MODE_8 = (1 << 8) /* 256 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl
new file mode 100644
index 0000000..36edb7f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.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.radio.ims.media;
+@VintfStability
+parcelable AmrParams {
+ android.hardware.radio.ims.media.AmrMode amrMode;
+ boolean octetAligned;
+ int maxRedundancyMillis;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
new file mode 100644
index 0000000..c108c07
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@JavaDerive(toString=true) @VintfStability
+parcelable AnbrMode {
+ android.hardware.radio.ims.media.CodecMode anbrUplinkMode;
+ android.hardware.radio.ims.media.CodecMode anbrDownlinkMode;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
new file mode 100644
index 0000000..fff6e1c
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@VintfStability
+parcelable CallQuality {
+ int downlinkCallQualityLevel;
+ int uplinkCallQualityLevel;
+ int callDuration;
+ int numRtpPacketsTransmitted;
+ int numRtpPacketsReceived;
+ int numRtpPacketsTransmittedLost;
+ int numRtpPacketsNotReceived;
+ int averageRelativeJitter;
+ int maxRelativeJitter;
+ int averageRoundTripTime;
+ int codecType;
+ boolean rtpInactivityDetected;
+ boolean rxSilenceDetected;
+ boolean txSilenceDetected;
+ int numVoiceFrames;
+ int numNoDataFrames;
+ int numDroppedRtpPackets;
+ long minPlayoutDelayMillis;
+ long maxPlayoutDelayMillis;
+ int numRtpSidPacketsReceived;
+ int numRtpDuplicatePackets;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
new file mode 100644
index 0000000..0e9140f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims.media;
+@JavaDerive(toString=true) @VintfStability
+union CodecMode {
+ boolean noinit;
+ android.hardware.radio.ims.media.AmrMode amr;
+ android.hardware.radio.ims.media.EvsMode evs;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
new file mode 100644
index 0000000..3da2dbd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.radio.ims.media;
+@VintfStability
+parcelable CodecParams {
+ android.hardware.radio.ims.media.CodecType codecType;
+ byte rxPayloadTypeNumber;
+ byte txPayloadTypeNumber;
+ byte samplingRateKHz;
+ boolean dtxEnabled;
+ android.hardware.radio.ims.media.CodecSpecificParams codecSpecificParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl
new file mode 100644
index 0000000..08e3f0f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.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.radio.ims.media;
+@VintfStability
+union CodecSpecificParams {
+ android.hardware.radio.ims.media.AmrParams amr;
+ android.hardware.radio.ims.media.EvsParams evs;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecType.aidl
new file mode 100644
index 0000000..e4193cd
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecType.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum CodecType {
+ AMR = (1 << 0) /* 1 */,
+ AMR_WB = (1 << 1) /* 2 */,
+ EVS = (1 << 2) /* 4 */,
+ PCMA = (1 << 3) /* 8 */,
+ PCMU = (1 << 4) /* 16 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
new file mode 100644
index 0000000..5523fd8
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.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.radio.ims.media;
+@VintfStability
+parcelable DtmfParams {
+ byte rxPayloadTypeNumber;
+ byte txPayloadTypeNumber;
+ byte samplingRateKHz;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsBandwidth.aidl
new file mode 100644
index 0000000..db3eb29
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsBandwidth.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum EvsBandwidth {
+ NONE = 0,
+ NARROW_BAND = (1 << 0) /* 1 */,
+ WIDE_BAND = (1 << 1) /* 2 */,
+ SUPER_WIDE_BAND = (1 << 2) /* 4 */,
+ FULL_BAND = (1 << 3) /* 8 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsMode.aidl
new file mode 100644
index 0000000..fb1f14d
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsMode.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum EvsMode {
+ EVS_MODE_0 = (1 << 0) /* 1 */,
+ EVS_MODE_1 = (1 << 1) /* 2 */,
+ EVS_MODE_2 = (1 << 2) /* 4 */,
+ EVS_MODE_3 = (1 << 3) /* 8 */,
+ EVS_MODE_4 = (1 << 4) /* 16 */,
+ EVS_MODE_5 = (1 << 5) /* 32 */,
+ EVS_MODE_6 = (1 << 6) /* 64 */,
+ EVS_MODE_7 = (1 << 7) /* 128 */,
+ EVS_MODE_8 = (1 << 8) /* 256 */,
+ EVS_MODE_9 = (1 << 9) /* 512 */,
+ EVS_MODE_10 = (1 << 10) /* 1024 */,
+ EVS_MODE_11 = (1 << 11) /* 2048 */,
+ EVS_MODE_12 = (1 << 12) /* 4096 */,
+ EVS_MODE_13 = (1 << 13) /* 8192 */,
+ EVS_MODE_14 = (1 << 14) /* 16384 */,
+ EVS_MODE_15 = (1 << 15) /* 32768 */,
+ EVS_MODE_16 = (1 << 16) /* 65536 */,
+ EVS_MODE_17 = (1 << 17) /* 131072 */,
+ EVS_MODE_18 = (1 << 18) /* 262144 */,
+ EVS_MODE_19 = (1 << 19) /* 524288 */,
+ EVS_MODE_20 = (1 << 20) /* 1048576 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
new file mode 100644
index 0000000..735eb08
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.radio.ims.media;
+@VintfStability
+parcelable EvsParams {
+ android.hardware.radio.ims.media.EvsBandwidth bandwidth;
+ android.hardware.radio.ims.media.EvsMode evsMode;
+ byte channelAwareMode;
+ boolean useHeaderFullOnly;
+ boolean useEvsModeSwitch;
+ byte codecModeRequest;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMedia.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMedia.aidl
new file mode 100644
index 0000000..30793e5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMedia.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.radio.ims.media;
+@VintfStability
+interface IImsMedia {
+ oneway void setListener(in android.hardware.radio.ims.media.IImsMediaListener mediaListener);
+ oneway void openSession(int sessionId, in android.hardware.radio.ims.media.LocalEndPoint localEndPoint, in android.hardware.radio.ims.media.RtpConfig config);
+ oneway void closeSession(int sessionId);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaListener.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaListener.aidl
new file mode 100644
index 0000000..40f7107
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaListener.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.radio.ims.media;
+@VintfStability
+interface IImsMediaListener {
+ oneway void onOpenSessionSuccess(int sessionId, android.hardware.radio.ims.media.IImsMediaSession session);
+ oneway void onOpenSessionFailure(int sessionId, android.hardware.radio.ims.media.RtpError error);
+ oneway void onSessionClosed(int sessionId);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSession.aidl
new file mode 100644
index 0000000..ea9f3a4
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSession.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.radio.ims.media;
+@VintfStability
+interface IImsMediaSession {
+ oneway void setListener(in android.hardware.radio.ims.media.IImsMediaSessionListener sessionListener);
+ oneway void modifySession(in android.hardware.radio.ims.media.RtpConfig config);
+ oneway void sendDtmf(char dtmfDigit, int duration);
+ oneway void startDtmf(char dtmfDigit);
+ oneway void stopDtmf();
+ oneway void sendHeaderExtension(in List<android.hardware.radio.ims.media.RtpHeaderExtension> extensions);
+ oneway void setMediaQualityThreshold(in android.hardware.radio.ims.media.MediaQualityThreshold threshold);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
new file mode 100644
index 0000000..cb221df
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/IImsMediaSessionListener.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.radio.ims.media;
+@VintfStability
+interface IImsMediaSessionListener {
+ oneway void onModifySessionResponse(in android.hardware.radio.ims.media.RtpConfig config, android.hardware.radio.ims.media.RtpError error);
+ oneway void onFirstMediaPacketReceived(in android.hardware.radio.ims.media.RtpConfig config);
+ oneway void onHeaderExtensionReceived(in List<android.hardware.radio.ims.media.RtpHeaderExtension> extensions);
+ oneway void notifyMediaQualityStatus(in android.hardware.radio.ims.media.MediaQualityStatus quality);
+ oneway void triggerAnbrQuery(in android.hardware.radio.ims.media.RtpConfig config);
+ oneway void onDtmfReceived(char dtmfDigit, int durationMs);
+ oneway void onCallQualityChanged(in android.hardware.radio.ims.media.CallQuality callQuality);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/LocalEndPoint.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/LocalEndPoint.aidl
new file mode 100644
index 0000000..6ec5156
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/LocalEndPoint.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.radio.ims.media;
+@VintfStability
+parcelable LocalEndPoint {
+ ParcelFileDescriptor rtpFd;
+ ParcelFileDescriptor rtcpFd;
+ int modemId;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaDirection.aidl
new file mode 100644
index 0000000..0e9eaee
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaDirection.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum MediaDirection {
+ NO_FLOW = 0,
+ RTP_TX = (1 << 0) /* 1 */,
+ RTP_RX = (1 << 1) /* 2 */,
+ RTCP_TX = (1 << 2) /* 4 */,
+ RTCP_RX = (1 << 3) /* 8 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl
new file mode 100644
index 0000000..4accf53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.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.radio.ims.media;
+@VintfStability
+parcelable MediaQualityStatus {
+ int rtpInactivityTimeMillis;
+ int rtcpInactivityTimeMillis;
+ int rtpPacketLossRate;
+ int rtpJitterMillis;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
new file mode 100644
index 0000000..31cf373
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.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.radio.ims.media;
+@VintfStability
+parcelable MediaQualityThreshold {
+ int[] rtpInactivityTimerMillis;
+ int rtcpInactivityTimerMillis;
+ int rtpPacketLossDurationMillis;
+ int rtpHysteresisTimeInMillis;
+ int[] rtpPacketLossRate;
+ int[] rtpJitterMillis;
+ boolean notifyCurrentStatus;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl
new file mode 100644
index 0000000..6a76d85
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.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.radio.ims.media;
+@VintfStability
+parcelable RtcpConfig {
+ String canonicalName;
+ int transmitPort;
+ int transmitIntervalSec;
+ int rtcpXrBlocks;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
new file mode 100644
index 0000000..289c810
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpXrReportBlockType.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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum RtcpXrReportBlockType {
+ RTCPXR_NONE = 0,
+ RTCPXR_LOSS_RLE_REPORT_BLOCK = (1 << 0) /* 1 */,
+ RTCPXR_DUPLICATE_RLE_REPORT_BLOCK = (1 << 1) /* 2 */,
+ RTCPXR_PACKET_RECEIPT_TIMES_REPORT_BLOCK = (1 << 2) /* 4 */,
+ RTCPXR_RECEIVER_REFERENCE_TIME_REPORT_BLOCK = (1 << 3) /* 8 */,
+ RTCPXR_DLRR_REPORT_BLOCK = (1 << 4) /* 16 */,
+ RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK = (1 << 5) /* 32 */,
+ RTCPXR_VOIP_METRICS_REPORT_BLOCK = (1 << 6) /* 64 */,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl
new file mode 100644
index 0000000..35357d1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.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.radio.ims.media;
+@VintfStability
+parcelable RtpAddress {
+ String ipAddress;
+ int portNumber;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
new file mode 100644
index 0000000..8a826f6
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.radio.ims.media;
+@VintfStability
+parcelable RtpConfig {
+ int direction;
+ android.hardware.radio.AccessNetwork accessNetwork;
+ android.hardware.radio.ims.media.RtpAddress remoteAddress;
+ android.hardware.radio.ims.media.RtpSessionParams sessionParams;
+ android.hardware.radio.ims.media.RtcpConfig rtcpConfig;
+ android.hardware.radio.ims.media.AnbrMode anbrModeParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpError.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpError.aidl
new file mode 100644
index 0000000..41b0aeb
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpError.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.radio.ims.media;
+@Backing(type="int") @VintfStability
+enum RtpError {
+ NONE = 0,
+ INVALID_PARAM = 1,
+ NOT_READY = 2,
+ NO_MEMORY = 3,
+ NO_RESOURCES = 4,
+ PORT_UNAVAILABLE = 5,
+ NOT_SUPPORTED = 6,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..83b8a31
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.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.radio.ims.media;
+@VintfStability
+parcelable RtpHeaderExtension {
+ int localId;
+ byte[] data;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
new file mode 100644
index 0000000..13a7487
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.radio.ims.media;
+@VintfStability
+parcelable RtpSessionParams {
+ byte pTimeMillis;
+ int maxPtimeMillis;
+ byte dscp;
+ android.hardware.radio.ims.media.DtmfParams dtmfParams;
+ android.hardware.radio.ims.media.CodecParams codecParams;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
new file mode 100644
index 0000000..90e75f9
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ConnectionFailureInfo {
+ android.hardware.radio.ims.ConnectionFailureInfo.ConnectionFailureReason failureReason;
+ int causeCode;
+ int waitTimeMillis;
+ @Backing(type="int") @VintfStability
+ enum ConnectionFailureReason {
+ REASON_ACCESS_DENIED = 1,
+ REASON_NAS_FAILURE = 2,
+ REASON_RACH_FAILURE = 3,
+ REASON_RLC_FAILURE = 4,
+ REASON_RRC_REJECT = 5,
+ REASON_RRC_TIMEOUT = 6,
+ REASON_NO_SERVICE = 7,
+ REASON_PDN_NOT_AVAILABLE = 8,
+ REASON_RF_BUSY = 9,
+ REASON_UNSPECIFIED = 0xFFFF,
+ }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/EpsFallbackReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/EpsFallbackReason.aidl
new file mode 100644
index 0000000..ebea903
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/EpsFallbackReason.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EpsFallbackReason {
+ NO_NETWORK_TRIGGER = 1,
+ NO_NETWORK_RESPONSE = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioIms.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioIms.aidl
new file mode 100644
index 0000000..4df8709
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioIms.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioIms {
+ oneway void setSrvccCallInfo(int serial, in android.hardware.radio.ims.SrvccCall[] srvccCalls);
+ oneway void updateImsRegistrationInfo(int serial, in android.hardware.radio.ims.ImsRegistration imsRegistration);
+ oneway void startImsTraffic(int serial, int token, android.hardware.radio.ims.ImsTrafficType imsTrafficType, android.hardware.radio.AccessNetwork accessNetworkType, android.hardware.radio.ims.ImsCall.Direction trafficDirection);
+ oneway void stopImsTraffic(int serial, int token);
+ oneway void triggerEpsFallback(int serial, in android.hardware.radio.ims.EpsFallbackReason reason);
+ oneway void setResponseFunctions(in android.hardware.radio.ims.IRadioImsResponse radioImsResponse, in android.hardware.radio.ims.IRadioImsIndication radioImsIndication);
+ oneway void sendAnbrQuery(int serial, android.hardware.radio.ims.ImsStreamType mediaType, android.hardware.radio.ims.ImsStreamDirection direction, int bitsPerSecond);
+ oneway void updateImsCallStatus(int serial, in android.hardware.radio.ims.ImsCall[] imsCalls);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsIndication.aidl
new file mode 100644
index 0000000..ef6b4cc
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioImsIndication {
+ oneway void onConnectionSetupFailure(in android.hardware.radio.RadioIndicationType type, int token, in android.hardware.radio.ims.ConnectionFailureInfo info);
+ oneway void notifyAnbr(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.ims.ImsStreamType mediaType, in android.hardware.radio.ims.ImsStreamDirection direction, int bitsPerSecond);
+ oneway void triggerImsDeregistration(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.ims.ImsDeregistrationReason reason);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsResponse.aidl
new file mode 100644
index 0000000..053ba46
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/IRadioImsResponse.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@VintfStability
+interface IRadioImsResponse {
+ oneway void setSrvccCallInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void updateImsRegistrationInfoResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void startImsTrafficResponse(in android.hardware.radio.RadioResponseInfo info, in @nullable android.hardware.radio.ims.ConnectionFailureInfo failureInfo);
+ oneway void stopImsTrafficResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void triggerEpsFallbackResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void sendAnbrQueryResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void updateImsCallStatusResponse(in android.hardware.radio.RadioResponseInfo info);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
new file mode 100644
index 0000000..6e14830
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsCall {
+ int index;
+ android.hardware.radio.ims.ImsCall.CallType callType;
+ android.hardware.radio.AccessNetwork accessNetwork;
+ android.hardware.radio.ims.ImsCall.CallState callState;
+ android.hardware.radio.ims.ImsCall.Direction direction;
+ boolean isHeldByRemote;
+ @Backing(type="int")
+ enum CallType {
+ NORMAL,
+ EMERGENCY,
+ }
+ @Backing(type="int")
+ enum CallState {
+ ACTIVE,
+ HOLDING,
+ DIALING,
+ ALERTING,
+ INCOMING,
+ WAITING,
+ DISCONNECTING,
+ DISCONNECTED,
+ }
+ @Backing(type="int")
+ enum Direction {
+ INCOMING,
+ OUTGOING,
+ }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
new file mode 100644
index 0000000..b04e559
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsDeregistrationReason {
+ REASON_SIM_REMOVED = 1,
+ REASON_SIM_REFRESH = 2,
+ REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
new file mode 100644
index 0000000..be5e004
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImsRegistration {
+ android.hardware.radio.ims.ImsRegistrationState regState;
+ android.hardware.radio.AccessNetwork accessNetworkType;
+ android.hardware.radio.ims.SuggestedAction suggestedAction;
+ int capabilities;
+ const int IMS_MMTEL_CAPABILITY_NONE = 0;
+ const int IMS_MMTEL_CAPABILITY_VOICE = (1 << 0);
+ const int IMS_MMTEL_CAPABILITY_VIDEO = (1 << 1);
+ const int IMS_MMTEL_CAPABILITY_SMS = (1 << 2);
+ const int IMS_RCS_CAPABILITIES = (1 << 3);
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistrationState.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistrationState.aidl
new file mode 100644
index 0000000..6302b47
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistrationState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsRegistrationState {
+ NOT_REGISTERED,
+ REGISTERED,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamDirection.aidl
new file mode 100644
index 0000000..cf2e4f1
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamDirection.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsStreamDirection {
+ UPLINK = 1,
+ DOWNLINK = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamType.aidl
new file mode 100644
index 0000000..10c477f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsStreamType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @VintfStability
+enum ImsStreamType {
+ AUDIO = 1,
+ VIDEO = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsTrafficType.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsTrafficType.aidl
new file mode 100644
index 0000000..b1a0b77
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsTrafficType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum ImsTrafficType {
+ EMERGENCY,
+ EMERGENCY_SMS,
+ VOICE,
+ VIDEO,
+ SMS,
+ REGISTRATION,
+ UT_XCAP,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
new file mode 100644
index 0000000..5119b0f
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@JavaDerive(toString=true) @VintfStability
+parcelable SrvccCall {
+ int index;
+ android.hardware.radio.ims.SrvccCall.CallType callType;
+ int callState;
+ android.hardware.radio.ims.SrvccCall.CallSubState callSubstate;
+ android.hardware.radio.ims.SrvccCall.ToneType ringbackToneType;
+ boolean isMpty;
+ boolean isMT;
+ String number;
+ int numPresentation;
+ String name;
+ int namePresentation;
+ @Backing(type="int") @VintfStability
+ enum CallType {
+ NORMAL,
+ EMERGENCY,
+ }
+ @Backing(type="int") @VintfStability
+ enum CallSubState {
+ NONE,
+ PREALERTING,
+ }
+ @Backing(type="int") @VintfStability
+ enum ToneType {
+ NONE,
+ LOCAL,
+ NETWORK,
+ }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
new file mode 100644
index 0000000..bbe170e
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SuggestedAction.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.ims;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SuggestedAction {
+ NONE,
+ TRIGGER_PLMN_BLOCK,
+ TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
index 019b185..d061c9e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio.messaging;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum SmsAcknowledgeFailCause {
- MEMORY_CAPACITY_EXCEEDED = 211,
- UNSPECIFIED_ERROR = 255,
+ MEMORY_CAPACITY_EXCEEDED = 0xD3,
+ UNSPECIFIED_ERROR = 0XFF,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
index 4e8c6d7..acc0b22 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.modem;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum DeviceStateType {
- POWER_SAVE_MODE = 0,
- CHARGING_STATE = 1,
- LOW_DATA_EXPECTED = 2,
+ POWER_SAVE_MODE,
+ CHARGING_STATE,
+ LOW_DATA_EXPECTED,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl
index 41eff51..8546be7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl
@@ -36,14 +36,26 @@
interface IRadioModem {
oneway void enableModem(in int serial, in boolean on);
oneway void getBasebandVersion(in int serial);
+ /**
+ * @deprecated use getImei(int serial)
+ */
oneway void getDeviceIdentity(in int serial);
oneway void getHardwareConfig(in int serial);
oneway void getModemActivityInfo(in int serial);
oneway void getModemStackStatus(in int serial);
oneway void getRadioCapability(in int serial);
+ /**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
oneway void nvReadItem(in int serial, in android.hardware.radio.modem.NvItem itemId);
oneway void nvResetConfig(in int serial, in android.hardware.radio.modem.ResetNvType resetType);
+ /**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
oneway void nvWriteCdmaPrl(in int serial, in byte[] prl);
+ /**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
oneway void nvWriteItem(in int serial, in android.hardware.radio.modem.NvWriteItem item);
oneway void requestShutdown(in int serial);
oneway void responseAcknowledgement();
@@ -51,4 +63,5 @@
oneway void setRadioCapability(in int serial, in android.hardware.radio.modem.RadioCapability rc);
oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, in boolean preferredForEmergencyCall);
oneway void setResponseFunctions(in android.hardware.radio.modem.IRadioModemResponse radioModemResponse, in android.hardware.radio.modem.IRadioModemIndication radioModemIndication);
+ oneway void getImei(in int serial);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl
index dcaff45..5955439 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -37,17 +37,30 @@
oneway void acknowledgeRequest(in int serial);
oneway void enableModemResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void getBasebandVersionResponse(in android.hardware.radio.RadioResponseInfo info, in String version);
+ /**
+ * @deprecated use getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo)
+ */
oneway void getDeviceIdentityResponse(in android.hardware.radio.RadioResponseInfo info, in String imei, in String imeisv, in String esn, in String meid);
oneway void getHardwareConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.HardwareConfig[] config);
oneway void getModemActivityInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.ActivityStatsInfo activityInfo);
oneway void getModemStackStatusResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
oneway void getRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc);
+ /**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
oneway void nvReadItemResponse(in android.hardware.radio.RadioResponseInfo info, in String result);
oneway void nvResetConfigResponse(in android.hardware.radio.RadioResponseInfo info);
+ /**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
oneway void nvWriteCdmaPrlResponse(in android.hardware.radio.RadioResponseInfo info);
+ /**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
oneway void nvWriteItemResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void requestShutdownResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void sendDeviceStateResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc);
oneway void setRadioPowerResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void getImeiResponse(in android.hardware.radio.RadioResponseInfo responseInfo, in @nullable android.hardware.radio.modem.ImeiInfo imeiInfo);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
new file mode 100644
index 0000000..f8776ec
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.modem;
+@JavaDerive(toString=true) @VintfStability
+parcelable ImeiInfo {
+ android.hardware.radio.modem.ImeiInfo.ImeiType type;
+ String imei;
+ String svn;
+ @Backing(type="int") @VintfStability
+ enum ImeiType {
+ PRIMARY = 1,
+ SECONDARY = 2,
+ }
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
index 3e27643..b80d7ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl
@@ -32,6 +32,9 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.radio.modem;
+/**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum NvItem {
CDMA_MEID = 1,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
index 17b7de0..6a786bc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
@@ -32,6 +32,9 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.radio.modem;
+/**
+ * @deprecated NV APIs are deprecated starting from Android U.
+ */
@JavaDerive(toString=true) @VintfStability
parcelable NvWriteItem {
android.hardware.radio.modem.NvItem itemId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
index e3b5796..37622b1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.modem;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ResetNvType {
- RELOAD = 0,
- ERASE = 1,
- FACTORY_RESET = 2,
+ RELOAD,
+ ERASE,
+ FACTORY_RESET,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 74c4e29..927f9ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -38,7 +38,7 @@
int roamingIndicator;
int systemIsInPrl;
int defaultRoamingIndicator;
- const int PRL_INDICATOR_NOT_REGISTERED = -1;
+ const int PRL_INDICATOR_NOT_REGISTERED = (-1);
const int PRL_INDICATOR_NOT_IN_PRL = 0;
const int PRL_INDICATOR_IN_PRL = 1;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
index 24ec26b..2a4db70 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.network;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum CdmaRoamingType {
- HOME_NETWORK = 0,
- AFFILIATED_ROAM = 1,
- ANY_ROAM = 2,
+ HOME_NETWORK,
+ AFFILIATED_ROAM,
+ ANY_ROAM,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
index 8986d71..5ce3b3e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.network;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum CellConnectionStatus {
- NONE = 0,
- PRIMARY_SERVING = 1,
- SECONDARY_SERVING = 2,
+ NONE,
+ PRIMARY_SERVING,
+ SECONDARY_SERVING,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
index 209cf5e..6b022b6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio.network;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum Domain {
- CS = 1,
- PS = 2,
+ CS = (1 << 0),
+ PS = (1 << 1),
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyMode.aidl
new file mode 100644
index 0000000..071e6b5
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyMode {
+ EMERGENCY_WWAN = 1,
+ EMERGENCY_WLAN = 2,
+ EMERGENCY_CALLBACK = 3,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
new file mode 100644
index 0000000..2797aff
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyNetworkScanTrigger {
+ android.hardware.radio.AccessNetwork[] accessNetwork;
+ android.hardware.radio.network.EmergencyScanType scanType;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
new file mode 100644
index 0000000..7d99a53
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@JavaDerive(toString=true) @VintfStability
+parcelable EmergencyRegResult {
+ android.hardware.radio.AccessNetwork accessNetwork;
+ android.hardware.radio.network.RegState regState;
+ android.hardware.radio.network.Domain emcDomain;
+ boolean isVopsSupported;
+ boolean isEmcBearerSupported;
+ byte nwProvidedEmc;
+ byte nwProvidedEmf;
+ String mcc = "";
+ String mnc = "";
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyScanType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyScanType.aidl
new file mode 100644
index 0000000..5e86c76
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.radio.network;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum EmergencyScanType {
+ NO_PREFERENCE = 0,
+ LIMITED_SERVICE = 1,
+ FULL_SERVICE = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
index dfbf881..90e342a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -36,4 +36,13 @@
parcelable EutranRegistrationInfo {
android.hardware.radio.network.LteVopsInfo lteVopsInfo;
android.hardware.radio.network.NrIndicators nrIndicators;
+ android.hardware.radio.network.EutranRegistrationInfo.AttachResultType lteAttachResultType;
+ int extraInfo;
+ const int EXTRA_CSFB_NOT_PREFERRED = (1 << 0);
+ const int EXTRA_SMS_ONLY = (1 << 1);
+ enum AttachResultType {
+ NONE,
+ EPS_ONLY,
+ COMBINED,
+ }
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index 2b70e45..382ddd8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -41,6 +41,9 @@
oneway void getCdmaRoamingPreference(in int serial);
oneway void getCellInfoList(in int serial);
oneway void getDataRegistrationState(in int serial);
+ /**
+ * @deprecated Deprecated starting from Android U.
+ */
oneway void getImsRegistrationState(in int serial);
oneway void getNetworkSelectionMode(in int serial);
oneway void getOperator(in int serial);
@@ -70,4 +73,12 @@
oneway void supplyNetworkDepersonalization(in int serial, in String netPin);
oneway void setUsageSetting(in int serial, in android.hardware.radio.network.UsageSetting usageSetting);
oneway void getUsageSetting(in int serial);
+ oneway void setEmergencyMode(int serial, in android.hardware.radio.network.EmergencyMode emcModeType);
+ oneway void triggerEmergencyNetworkScan(int serial, in android.hardware.radio.network.EmergencyNetworkScanTrigger request);
+ oneway void cancelEmergencyNetworkScan(int serial, boolean resetScan);
+ oneway void exitEmergencyMode(in int serial);
+ oneway void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+ oneway void isNullCipherAndIntegrityEnabled(in int serial);
+ oneway void isN1ModeEnabled(in int serial);
+ oneway void setN1ModeEnabled(in int serial, boolean enable);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
index bd03c51..0f017ea 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -48,4 +48,5 @@
oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhoneRestrictedState state);
oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SuppSvcNotification suppSvc);
oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat);
+ oneway void emergencyNetworkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.EmergencyRegResult result);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 5f6c736..bfe8fa3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -42,6 +42,9 @@
oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CdmaRoamingType type);
oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellInfo[] cellInfo);
oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult dataRegResponse);
+ /**
+ * @deprecated Deprecated starting from Android U.
+ */
oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily);
oneway void getNetworkSelectionModeResponse(in android.hardware.radio.RadioResponseInfo info, in boolean manual);
oneway void getOperatorResponse(in android.hardware.radio.RadioResponseInfo info, in String longName, in String shortName, in String numeric);
@@ -69,4 +72,12 @@
oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
oneway void setUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void getUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.UsageSetting usageSetting);
+ oneway void setEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.EmergencyRegResult regState);
+ oneway void triggerEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void exitEmergencyModeResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void cancelEmergencyNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void setNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void isNullCipherAndIntegrityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
+ oneway void isN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info, boolean isEnabled);
+ oneway void setN1ModeEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
index d9ed68e..00ba346 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl
@@ -35,12 +35,12 @@
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum IndicationFilter {
NONE = 0,
- ALL = -1,
- SIGNAL_STRENGTH = 1,
- FULL_NETWORK_STATE = 2,
- DATA_CALL_DORMANCY_CHANGED = 4,
- LINK_CAPACITY_ESTIMATE = 8,
- PHYSICAL_CHANNEL_CONFIG = 16,
- REGISTRATION_FAILURE = 32,
- BARRING_INFO = 64,
+ ALL = (~0),
+ SIGNAL_STRENGTH = (1 << 0),
+ FULL_NETWORK_STATE = (1 << 1),
+ DATA_CALL_DORMANCY_CHANGED = (1 << 2),
+ LINK_CAPACITY_ESTIMATE = (1 << 3),
+ PHYSICAL_CHANNEL_CONFIG = (1 << 4),
+ REGISTRATION_FAILURE = (1 << 5),
+ BARRING_INFO = (1 << 6),
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
index 98bbe6b..7d6ab82 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
@@ -42,4 +42,5 @@
int csiSinr;
int csiCqiTableIndex;
byte[] csiCqiReport;
+ int timingAdvance = 0x7FFFFFFF;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
index 41555f9..4e3e39e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl
@@ -34,9 +34,9 @@
package android.hardware.radio.network;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum PhoneRestrictedState {
- NONE = 0,
- CS_EMERGENCY = 1,
- CS_NORMAL = 2,
- CS_ALL = 4,
- PS_ALL = 16,
+ NONE = 0x00,
+ CS_EMERGENCY = 0x01,
+ CS_NORMAL = 0x02,
+ CS_ALL = 0x04,
+ PS_ALL = 0x10,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
index e9a9f60..74696fb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl
@@ -34,23 +34,23 @@
package android.hardware.radio.network;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum RadioBandMode {
- BAND_MODE_UNSPECIFIED = 0,
- BAND_MODE_EURO = 1,
- BAND_MODE_USA = 2,
- BAND_MODE_JPN = 3,
- BAND_MODE_AUS = 4,
- BAND_MODE_AUS_2 = 5,
- BAND_MODE_CELL_800 = 6,
- BAND_MODE_PCS = 7,
- BAND_MODE_JTACS = 8,
- BAND_MODE_KOREA_PCS = 9,
- BAND_MODE_5_450M = 10,
- BAND_MODE_IMT2000 = 11,
- BAND_MODE_7_700M_2 = 12,
- BAND_MODE_8_1800M = 13,
- BAND_MODE_9_900M = 14,
- BAND_MODE_10_800M_2 = 15,
- BAND_MODE_EURO_PAMR_400M = 16,
- BAND_MODE_AWS = 17,
- BAND_MODE_USA_2500M = 18,
+ BAND_MODE_UNSPECIFIED,
+ BAND_MODE_EURO,
+ BAND_MODE_USA,
+ BAND_MODE_JPN,
+ BAND_MODE_AUS,
+ BAND_MODE_AUS_2,
+ BAND_MODE_CELL_800,
+ BAND_MODE_PCS,
+ BAND_MODE_JTACS,
+ BAND_MODE_KOREA_PCS,
+ BAND_MODE_5_450M,
+ BAND_MODE_IMT2000,
+ BAND_MODE_7_700M_2,
+ BAND_MODE_8_1800M,
+ BAND_MODE_9_900M,
+ BAND_MODE_10_800M_2,
+ BAND_MODE_EURO_PAMR_400M,
+ BAND_MODE_AWS,
+ BAND_MODE_USA_2500M,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
index e6e7999..711c9ac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl
@@ -44,4 +44,5 @@
NOT_REG_MT_SEARCHING_OP_EM = 12,
REG_DENIED_EM = 13,
UNKNOWN_EM = 14,
+ REG_EM = 20,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
index e2cd44c..8acf8ab 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl
@@ -56,7 +56,7 @@
CONGESTION = 22,
GSM_AUTHENTICATION_UNACCEPTABLE = 23,
NOT_AUTHORIZED_FOR_THIS_CSG = 25,
- SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA = 26,
+ SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA,
SERVICE_OPTION_NOT_SUPPORTED = 32,
SERVICE_OPTION_NOT_SUBSCRIBED = 33,
SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
index 040932c..744eed7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -48,4 +48,5 @@
const int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6;
const int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7;
const int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
+ const int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl
index e0e2a03..6cef92b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapApduType.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio.sap;
@Backing(type="int") @VintfStability
enum SapApduType {
- APDU = 0,
- APDU7816 = 1,
+ APDU,
+ APDU7816,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl
index aceac37..841dfe3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapConnectRsp.aidl
@@ -34,9 +34,9 @@
package android.hardware.radio.sap;
@Backing(type="int") @VintfStability
enum SapConnectRsp {
- SUCCESS = 0,
- CONNECT_FAILURE = 1,
- MSG_SIZE_TOO_LARGE = 2,
- MSG_SIZE_TOO_SMALL = 3,
- CONNECT_OK_CALL_ONGOING = 4,
+ SUCCESS,
+ CONNECT_FAILURE,
+ MSG_SIZE_TOO_LARGE,
+ MSG_SIZE_TOO_SMALL,
+ CONNECT_OK_CALL_ONGOING,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl
index 0447f9b..dace1e1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapDisconnectType.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio.sap;
@Backing(type="int") @VintfStability
enum SapDisconnectType {
- GRACEFUL = 0,
- IMMEDIATE = 1,
+ GRACEFUL,
+ IMMEDIATE,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl
index 1db226b..a2a6df0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapResultCode.aidl
@@ -34,12 +34,12 @@
package android.hardware.radio.sap;
@Backing(type="int") @VintfStability
enum SapResultCode {
- SUCCESS = 0,
- GENERIC_FAILURE = 1,
- CARD_NOT_ACCESSSIBLE = 2,
- CARD_ALREADY_POWERED_OFF = 3,
- CARD_REMOVED = 4,
- CARD_ALREADY_POWERED_ON = 5,
- DATA_NOT_AVAILABLE = 6,
- NOT_SUPPORTED = 7,
+ SUCCESS,
+ GENERIC_FAILURE,
+ CARD_NOT_ACCESSSIBLE,
+ CARD_ALREADY_POWERED_OFF,
+ CARD_REMOVED,
+ CARD_ALREADY_POWERED_ON,
+ DATA_NOT_AVAILABLE,
+ NOT_SUPPORTED,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl
index 32f71c2..6988c99 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapStatus.aidl
@@ -34,10 +34,10 @@
package android.hardware.radio.sap;
@Backing(type="int") @VintfStability
enum SapStatus {
- UNKNOWN_ERROR = 0,
- CARD_RESET = 1,
- CARD_NOT_ACCESSIBLE = 2,
- CARD_REMOVED = 3,
- CARD_INSERTED = 4,
- RECOVERED = 5,
+ UNKNOWN_ERROR,
+ CARD_RESET,
+ CARD_NOT_ACCESSIBLE,
+ CARD_REMOVED,
+ CARD_INSERTED,
+ RECOVERED,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl
index e3ffdb0..3c6852e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sap/current/android/hardware/radio/sap/SapTransferProtocol.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio.sap;
@Backing(type="int") @VintfStability
enum SapTransferProtocol {
- T0 = 0,
- T1 = 1,
+ T0,
+ T1,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
index 05bc13a..6bc3919 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.sim;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum CardPowerState {
- POWER_DOWN = 0,
- POWER_UP = 1,
- POWER_UP_PASS_THROUGH = 2,
+ POWER_DOWN,
+ POWER_UP,
+ POWER_UP_PASS_THROUGH,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
index 9000d43..46cb7be 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
@@ -44,6 +44,7 @@
String iccid;
String eid;
android.hardware.radio.config.SlotPortMapping slotMap;
+ android.hardware.radio.config.MultipleEnabledProfilesMode supportedMepMode = android.hardware.radio.config.MultipleEnabledProfilesMode.NONE;
const int STATE_ABSENT = 0;
const int STATE_PRESENT = 1;
const int STATE_ERROR = 2;
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 944f1ca..3700de3 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
@@ -37,4 +37,11 @@
android.hardware.radio.sim.Carrier[] allowedCarriers;
android.hardware.radio.sim.Carrier[] excludedCarriers;
boolean allowedCarriersPrioritized;
+ android.hardware.radio.sim.CarrierRestrictions.CarrierRestrictionStatus status;
+ @Backing(type="int") @VintfStability
+ enum CarrierRestrictionStatus {
+ UNKNOWN = 0,
+ NOT_RESTRICTED = 1,
+ RESTRICTED = 2,
+ }
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
index 13469f3..080aa5e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio.sim;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum CdmaSubscriptionSource {
- RUIM_SIM = 0,
- NV = 1,
+ RUIM_SIM,
+ NV,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
index 85a0c71..901b251 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
@@ -46,6 +46,9 @@
oneway void getImsiForApp(in int serial, in String aid);
oneway void getSimPhonebookCapacity(in int serial);
oneway void getSimPhonebookRecords(in int serial);
+ /**
+ * @deprecated use iccCloseLogicalChannelWithSessionInfo instead.
+ */
oneway void iccCloseLogicalChannel(in int serial, in int channelId);
oneway void iccIoForApp(in int serial, in android.hardware.radio.sim.IccIo iccIo);
oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2);
@@ -70,4 +73,5 @@
oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid);
oneway void supplySimDepersonalization(in int serial, in android.hardware.radio.sim.PersoSubstate persoType, in String controlKey);
oneway void updateSimPhonebookRecords(in int serial, in android.hardware.radio.sim.PhonebookRecordInfo recordInfo);
+ oneway void iccCloseLogicalChannelWithSessionInfo(in int serial, in android.hardware.radio.sim.SessionInfo sessionInfo);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
index 8e68e30..d7c2100 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -47,6 +47,9 @@
oneway void getImsiForAppResponse(in android.hardware.radio.RadioResponseInfo info, in String imsi);
oneway void getSimPhonebookCapacityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PhonebookCapacity capacity);
oneway void getSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info);
+ /**
+ * @deprecated use iccCloseLogicalChannelWithSessionInfoResponse instead.
+ */
oneway void iccCloseLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void iccIoForAppResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo);
oneway void iccOpenLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in int channelId, in byte[] selectResponse);
@@ -69,4 +72,5 @@
oneway void supplyIccPukForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
oneway void supplySimDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PersoSubstate persoType, in int remainingRetries);
oneway void updateSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info, in int updatedRecordIndex);
+ oneway void iccCloseLogicalChannelWithSessionInfoResponse(in android.hardware.radio.RadioResponseInfo info);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
index e33769e..dc1d960 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl
@@ -34,39 +34,39 @@
package android.hardware.radio.sim;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum PersoSubstate {
- UNKNOWN = 0,
- IN_PROGRESS = 1,
- READY = 2,
- SIM_NETWORK = 3,
- SIM_NETWORK_SUBSET = 4,
- SIM_CORPORATE = 5,
- SIM_SERVICE_PROVIDER = 6,
- SIM_SIM = 7,
- SIM_NETWORK_PUK = 8,
- SIM_NETWORK_SUBSET_PUK = 9,
- SIM_CORPORATE_PUK = 10,
- SIM_SERVICE_PROVIDER_PUK = 11,
- SIM_SIM_PUK = 12,
- RUIM_NETWORK1 = 13,
- RUIM_NETWORK2 = 14,
- RUIM_HRPD = 15,
- RUIM_CORPORATE = 16,
- RUIM_SERVICE_PROVIDER = 17,
- RUIM_RUIM = 18,
- RUIM_NETWORK1_PUK = 19,
- RUIM_NETWORK2_PUK = 20,
- RUIM_HRPD_PUK = 21,
- RUIM_CORPORATE_PUK = 22,
- RUIM_SERVICE_PROVIDER_PUK = 23,
- RUIM_RUIM_PUK = 24,
- SIM_SPN = 25,
- SIM_SPN_PUK = 26,
- SIM_SP_EHPLMN = 27,
- SIM_SP_EHPLMN_PUK = 28,
- SIM_ICCID = 29,
- SIM_ICCID_PUK = 30,
- SIM_IMPI = 31,
- SIM_IMPI_PUK = 32,
- SIM_NS_SP = 33,
- SIM_NS_SP_PUK = 34,
+ UNKNOWN,
+ IN_PROGRESS,
+ READY,
+ SIM_NETWORK,
+ SIM_NETWORK_SUBSET,
+ SIM_CORPORATE,
+ SIM_SERVICE_PROVIDER,
+ SIM_SIM,
+ SIM_NETWORK_PUK,
+ SIM_NETWORK_SUBSET_PUK,
+ SIM_CORPORATE_PUK,
+ SIM_SERVICE_PROVIDER_PUK,
+ SIM_SIM_PUK,
+ RUIM_NETWORK1,
+ RUIM_NETWORK2,
+ RUIM_HRPD,
+ RUIM_CORPORATE,
+ RUIM_SERVICE_PROVIDER,
+ RUIM_RUIM,
+ RUIM_NETWORK1_PUK,
+ RUIM_NETWORK2_PUK,
+ RUIM_HRPD_PUK,
+ RUIM_CORPORATE_PUK,
+ RUIM_SERVICE_PROVIDER_PUK,
+ RUIM_RUIM_PUK,
+ SIM_SPN,
+ SIM_SPN_PUK,
+ SIM_SP_EHPLMN,
+ SIM_SP_EHPLMN_PUK,
+ SIM_ICCID,
+ SIM_ICCID_PUK,
+ SIM_IMPI,
+ SIM_IMPI_PUK,
+ SIM_NS_SP,
+ SIM_NS_SP_PUK,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
index 5cdc6d1..663ea73 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl
@@ -34,10 +34,10 @@
package android.hardware.radio.sim;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum PinState {
- UNKNOWN = 0,
- ENABLED_NOT_VERIFIED = 1,
- ENABLED_VERIFIED = 2,
- DISABLED = 3,
- ENABLED_BLOCKED = 4,
- ENABLED_PERM_BLOCKED = 5,
+ UNKNOWN,
+ ENABLED_NOT_VERIFIED,
+ ENABLED_VERIFIED,
+ DISABLED,
+ ENABLED_BLOCKED,
+ ENABLED_PERM_BLOCKED,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl
new file mode 100644
index 0000000..1329141
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.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.radio.sim;
+@JavaDerive(toString=true) @VintfStability
+parcelable SessionInfo {
+ int sessionId;
+ boolean isEs10 = false;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
index 2201345..c391e5a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
@@ -41,4 +41,5 @@
int p2;
int p3;
String data;
+ boolean isEs10 = false;
}
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 4ded3e9..d59fcab 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
@@ -34,6 +34,6 @@
package android.hardware.radio.sim;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum SimLockMultiSimPolicy {
- NO_MULTISIM_POLICY = 0,
- ONE_VALID_SIM_MUST_BE_PRESENT = 1,
+ NO_MULTISIM_POLICY,
+ ONE_VALID_SIM_MUST_BE_PRESENT,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
index 15669ac..1ab2902 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl
@@ -34,14 +34,14 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum AudioQuality {
- UNSPECIFIED = 0,
- AMR = 1,
- AMR_WB = 2,
- GSM_EFR = 3,
- GSM_FR = 4,
- GSM_HR = 5,
- EVRC = 6,
- EVRC_B = 7,
- EVRC_WB = 8,
- EVRC_NW = 9,
+ UNSPECIFIED,
+ AMR,
+ AMR_WB,
+ GSM_EFR,
+ GSM_FR,
+ GSM_HR,
+ EVRC,
+ EVRC_B,
+ EVRC_WB,
+ EVRC_NW,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
index 7877fda..fad3841 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -34,16 +34,16 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum CdmaOtaProvisionStatus {
- SPL_UNLOCKED = 0,
- SPC_RETRIES_EXCEEDED = 1,
- A_KEY_EXCHANGED = 2,
- SSD_UPDATED = 3,
- NAM_DOWNLOADED = 4,
- MDN_DOWNLOADED = 5,
- IMSI_DOWNLOADED = 6,
- PRL_DOWNLOADED = 7,
- COMMITTED = 8,
- OTAPA_STARTED = 9,
- OTAPA_STOPPED = 10,
- OTAPA_ABORTED = 11,
+ SPL_UNLOCKED,
+ SPC_RETRIES_EXCEEDED,
+ A_KEY_EXCHANGED,
+ SSD_UPDATED,
+ NAM_DOWNLOADED,
+ MDN_DOWNLOADED,
+ IMSI_DOWNLOADED,
+ PRL_DOWNLOADED,
+ COMMITTED,
+ OTAPA_STARTED,
+ OTAPA_STOPPED,
+ OTAPA_ABORTED,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
index 3fbb0d8..a34149a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ClipStatus {
- CLIP_PROVISIONED = 0,
- CLIP_UNPROVISIONED = 1,
- UNKNOWN = 2,
+ CLIP_PROVISIONED,
+ CLIP_UNPROVISIONED,
+ UNKNOWN,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
index 07f011d..4e1dfc0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum EmergencyCallRouting {
- UNKNOWN = 0,
- EMERGENCY = 1,
- NORMAL = 2,
+ UNKNOWN,
+ EMERGENCY,
+ NORMAL,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
index 98df8cd..ac3867e 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -40,8 +40,8 @@
int categories;
String[] urns;
int sources;
- const int SOURCE_NETWORK_SIGNALING = 1;
- const int SOURCE_SIM = 2;
- const int SOURCE_MODEM_CONFIG = 4;
- const int SOURCE_DEFAULT = 8;
+ const int SOURCE_NETWORK_SIGNALING = (1 << 0);
+ const int SOURCE_SIM = (1 << 1);
+ const int SOURCE_MODEM_CONFIG = (1 << 2);
+ const int SOURCE_DEFAULT = (1 << 3);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
index 042dd61..0a70d2d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl
@@ -35,11 +35,11 @@
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum EmergencyServiceCategory {
UNSPECIFIED = 0,
- POLICE = 1,
- AMBULANCE = 2,
- FIRE_BRIGADE = 4,
- MARINE_GUARD = 8,
- MOUNTAIN_RESCUE = 16,
- MIEC = 32,
- AIEC = 64,
+ POLICE = (1 << 0),
+ AMBULANCE = (1 << 1),
+ FIRE_BRIGADE = (1 << 2),
+ MARINE_GUARD = (1 << 3),
+ MOUNTAIN_RESCUE = (1 << 4),
+ MIEC = (1 << 5),
+ AIEC = (1 << 6),
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
index 1740134..7d54623 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -114,20 +114,20 @@
CDMA_PREEMPTED = 1007,
CDMA_NOT_EMERGENCY = 1008,
CDMA_ACCESS_BLOCKED = 1009,
- OEM_CAUSE_1 = 61441,
- OEM_CAUSE_2 = 61442,
- OEM_CAUSE_3 = 61443,
- OEM_CAUSE_4 = 61444,
- OEM_CAUSE_5 = 61445,
- OEM_CAUSE_6 = 61446,
- OEM_CAUSE_7 = 61447,
- OEM_CAUSE_8 = 61448,
- OEM_CAUSE_9 = 61449,
- OEM_CAUSE_10 = 61450,
- OEM_CAUSE_11 = 61451,
- OEM_CAUSE_12 = 61452,
- OEM_CAUSE_13 = 61453,
- OEM_CAUSE_14 = 61454,
- OEM_CAUSE_15 = 61455,
- ERROR_UNSPECIFIED = 65535,
+ OEM_CAUSE_1 = 0xf001,
+ OEM_CAUSE_2 = 0xf002,
+ OEM_CAUSE_3 = 0xf003,
+ OEM_CAUSE_4 = 0xf004,
+ OEM_CAUSE_5 = 0xf005,
+ OEM_CAUSE_6 = 0xf006,
+ OEM_CAUSE_7 = 0xf007,
+ OEM_CAUSE_8 = 0xf008,
+ OEM_CAUSE_9 = 0xf009,
+ OEM_CAUSE_10 = 0xf00a,
+ OEM_CAUSE_11 = 0xf00b,
+ OEM_CAUSE_12 = 0xf00c,
+ OEM_CAUSE_13 = 0xf00d,
+ OEM_CAUSE_14 = 0xf00e,
+ OEM_CAUSE_15 = 0xf00f,
+ ERROR_UNSPECIFIED = 0xffff,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
index 864374b..4b5c216 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl
@@ -34,8 +34,8 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum SrvccState {
- HANDOVER_STARTED = 0,
- HANDOVER_COMPLETED = 1,
- HANDOVER_FAILED = 2,
- HANDOVER_CANCELED = 3,
+ HANDOVER_STARTED,
+ HANDOVER_COMPLETED,
+ HANDOVER_FAILED,
+ HANDOVER_CANCELED,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
index 50bb1fd..75f3de5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -72,13 +72,13 @@
const int TELESERVICE_TYPE_SMS_SERVICES = 4;
const int TELESERVICE_TYPE_ALL_TELESERVICES_EXCEPT_SMS = 5;
const int SUPP_SERVICE_CLASS_NONE = 0;
- const int SUPP_SERVICE_CLASS_VOICE = 1;
- const int SUPP_SERVICE_CLASS_DATA = 2;
- const int SUPP_SERVICE_CLASS_FAX = 4;
- const int SUPP_SERVICE_CLASS_SMS = 8;
- const int SUPP_SERVICE_CLASS_DATA_SYNC = 16;
- const int SUPP_SERVICE_CLASS_DATA_ASYNC = 32;
- const int SUPP_SERVICE_CLASS_PACKET = 64;
- const int SUPP_SERVICE_CLASS_PAD = 128;
- const int SUPP_SERVICE_CLASS_MAX = 128;
+ const int SUPP_SERVICE_CLASS_VOICE = (1 << 0);
+ const int SUPP_SERVICE_CLASS_DATA = (1 << 1);
+ const int SUPP_SERVICE_CLASS_FAX = (1 << 2);
+ const int SUPP_SERVICE_CLASS_SMS = (1 << 3);
+ const int SUPP_SERVICE_CLASS_DATA_SYNC = (1 << 4);
+ const int SUPP_SERVICE_CLASS_DATA_ASYNC = (1 << 5);
+ const int SUPP_SERVICE_CLASS_PACKET = (1 << 6);
+ const int SUPP_SERVICE_CLASS_PAD = (1 << 7);
+ const int SUPP_SERVICE_CLASS_MAX = (1 << 7);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
index 77417e8..e432e65 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum TtyMode {
- OFF = 0,
- FULL = 1,
- HCO = 2,
- VCO = 3,
+ OFF,
+ FULL,
+ HCO,
+ VCO,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
index ad243d2..424e73f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UssdModeType.aidl
@@ -34,10 +34,10 @@
package android.hardware.radio.voice;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum UssdModeType {
- NOTIFY = 0,
- REQUEST = 1,
- NW_RELEASE = 2,
- LOCAL_CLIENT = 3,
- NOT_SUPPORTED = 4,
- NW_TIMEOUT = 5,
+ NOTIFY,
+ REQUEST,
+ NW_RELEASE,
+ LOCAL_CLIENT,
+ NOT_SUPPORTED,
+ NW_TIMEOUT,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
index 8ce689f..9641651 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
@@ -34,11 +34,11 @@
package android.hardware.radio;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum AccessNetwork {
- UNKNOWN = 0,
- GERAN = 1,
- UTRAN = 2,
- EUTRAN = 3,
- CDMA2000 = 4,
- IWLAN = 5,
- NGRAN = 6,
+ UNKNOWN,
+ GERAN,
+ UTRAN,
+ EUTRAN,
+ CDMA2000,
+ IWLAN,
+ NGRAN,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
index ecc2a9b..b7b074b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
@@ -34,25 +34,28 @@
package android.hardware.radio;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum RadioAccessFamily {
- UNKNOWN = 1,
- GPRS = 2,
- EDGE = 4,
- UMTS = 8,
- IS95A = 16,
- IS95B = 32,
- ONE_X_RTT = 64,
- EVDO_0 = 128,
- EVDO_A = 256,
- HSDPA = 512,
- HSUPA = 1024,
- HSPA = 2048,
- EVDO_B = 4096,
- EHRPD = 8192,
- LTE = 16384,
- HSPAP = 32768,
- GSM = 65536,
- TD_SCDMA = 131072,
- IWLAN = 262144,
- LTE_CA = 524288,
- NR = 1048576,
+ UNKNOWN = (1 << android.hardware.radio.RadioTechnology.UNKNOWN) /* 1 */,
+ GPRS = (1 << android.hardware.radio.RadioTechnology.GPRS) /* 2 */,
+ EDGE = (1 << android.hardware.radio.RadioTechnology.EDGE) /* 4 */,
+ UMTS = (1 << android.hardware.radio.RadioTechnology.UMTS) /* 8 */,
+ IS95A = (1 << android.hardware.radio.RadioTechnology.IS95A) /* 16 */,
+ IS95B = (1 << android.hardware.radio.RadioTechnology.IS95B) /* 32 */,
+ ONE_X_RTT = (1 << android.hardware.radio.RadioTechnology.ONE_X_RTT) /* 64 */,
+ EVDO_0 = (1 << android.hardware.radio.RadioTechnology.EVDO_0) /* 128 */,
+ EVDO_A = (1 << android.hardware.radio.RadioTechnology.EVDO_A) /* 256 */,
+ HSDPA = (1 << android.hardware.radio.RadioTechnology.HSDPA) /* 512 */,
+ HSUPA = (1 << android.hardware.radio.RadioTechnology.HSUPA) /* 1024 */,
+ HSPA = (1 << android.hardware.radio.RadioTechnology.HSPA) /* 2048 */,
+ EVDO_B = (1 << android.hardware.radio.RadioTechnology.EVDO_B) /* 4096 */,
+ EHRPD = (1 << android.hardware.radio.RadioTechnology.EHRPD) /* 8192 */,
+ LTE = (1 << android.hardware.radio.RadioTechnology.LTE) /* 16384 */,
+ HSPAP = (1 << android.hardware.radio.RadioTechnology.HSPAP) /* 32768 */,
+ GSM = (1 << android.hardware.radio.RadioTechnology.GSM) /* 65536 */,
+ TD_SCDMA = (1 << android.hardware.radio.RadioTechnology.TD_SCDMA) /* 131072 */,
+ IWLAN = (1 << android.hardware.radio.RadioTechnology.IWLAN) /* 262144 */,
+ /**
+ * @deprecated use LTE instead.
+ */
+ LTE_CA = (1 << android.hardware.radio.RadioTechnology.LTE_CA) /* 524288 */,
+ NR = (1 << android.hardware.radio.RadioTechnology.NR) /* 1048576 */,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
index b91bf03..9785825 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
@@ -37,5 +37,5 @@
const int MAX_RILDS = 3;
const int MAX_UUID_LENGTH = 64;
const int CARD_MAX_APPS = 8;
- const int P2_CONSTANT_NO_P2 = -1;
+ const int P2_CONSTANT_NO_P2 = (-1) /* -1 */;
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
index 54ea3a4..58b35a57 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum RadioIndicationType {
- UNSOLICITED = 0,
- UNSOLICITED_ACK_EXP = 1,
+ UNSOLICITED,
+ UNSOLICITED_ACK_EXP,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
index 5cd99c4..1ee62bd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl
@@ -34,7 +34,7 @@
package android.hardware.radio;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum RadioResponseType {
- SOLICITED = 0,
- SOLICITED_ACK = 1,
- SOLICITED_ACK_EXP = 2,
+ SOLICITED,
+ SOLICITED_ACK,
+ SOLICITED_ACK_EXP,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
index 9dad0a4..b6af5aa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
@@ -34,25 +34,28 @@
package android.hardware.radio;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum RadioTechnology {
- UNKNOWN = 0,
- GPRS = 1,
- EDGE = 2,
- UMTS = 3,
- IS95A = 4,
- IS95B = 5,
- ONE_X_RTT = 6,
- EVDO_0 = 7,
- EVDO_A = 8,
- HSDPA = 9,
- HSUPA = 10,
- HSPA = 11,
- EVDO_B = 12,
- EHRPD = 13,
- LTE = 14,
- HSPAP = 15,
- GSM = 16,
- TD_SCDMA = 17,
- IWLAN = 18,
- LTE_CA = 19,
- NR = 20,
+ UNKNOWN,
+ GPRS,
+ EDGE,
+ UMTS,
+ IS95A,
+ IS95B,
+ ONE_X_RTT,
+ EVDO_0,
+ EVDO_A,
+ HSDPA,
+ HSUPA,
+ HSPA,
+ EVDO_B,
+ EHRPD,
+ LTE,
+ HSPAP,
+ GSM,
+ TD_SCDMA,
+ IWLAN,
+ /**
+ * @deprecated use LTE instead and indicate carrier aggregation through multiple physical channel configurations in IRadioNetwork::currentPhysicalChannelConfigs.
+ */
+ LTE_CA,
+ NR,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
index e6fdce2..2af7e53 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -34,6 +34,6 @@
package android.hardware.radio;
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum RadioTechnologyFamily {
- THREE_GPP = 0,
- THREE_GPP2 = 1,
+ THREE_GPP,
+ THREE_GPP2,
}
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index 6cd0a95..edf33ba 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -41,6 +41,7 @@
GSM = 1 << RadioTechnology.GSM,
TD_SCDMA = 1 << RadioTechnology.TD_SCDMA,
IWLAN = 1 << RadioTechnology.IWLAN,
+ /** @deprecated use LTE instead. */
LTE_CA = 1 << RadioTechnology.LTE_CA,
/**
* 5G NR. This is only use in 5G Standalone mode.
diff --git a/radio/aidl/android/hardware/radio/RadioError.aidl b/radio/aidl/android/hardware/radio/RadioError.aidl
index ae58a0e..2031399 100644
--- a/radio/aidl/android/hardware/radio/RadioError.aidl
+++ b/radio/aidl/android/hardware/radio/RadioError.aidl
@@ -41,6 +41,9 @@
* Operation requires SIM PUK2 to be entered
*/
SIM_PUK2 = 5,
+ /**
+ * Optional API
+ */
REQUEST_NOT_SUPPORTED = 6,
CANCELLED = 7,
/**
@@ -177,7 +180,8 @@
*/
NO_SMS_TO_ACK = 48,
/**
- * Received error from network
+ * Received error from network. This generic error code should be used only when the error
+ * cannot be mapped to other specific network error codes.
*/
NETWORK_ERR = 49,
/**
diff --git a/radio/aidl/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
index 917cb16..4b51152 100644
--- a/radio/aidl/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
@@ -45,6 +45,10 @@
GSM,
TD_SCDMA,
IWLAN,
+ /**
+ * @deprecated use LTE instead and indicate carrier aggregation through multiple
+ * physical channel configurations in IRadioNetwork::currentPhysicalChannelConfigs.
+ */
LTE_CA,
/**
* 5G NR. This is only used in 5G Standalone mode.
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
index 929f02d..0d36bbd 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -54,7 +54,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getNumOfLiveModemsResponse(
in android.hardware.radio.RadioResponseInfo info, in byte numOfLiveModems);
@@ -93,7 +92,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
*/
void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl b/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
new file mode 100644
index 0000000..b18ea0e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/MultipleEnabledProfilesMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.config;
+
+/**
+ * Multiple Enabled Profiles(MEP) mode is the jointly supported MEP mode. As per section 3.4.1.1 of
+ * GSMA spec SGP.22 v3.0,there are 3 supported MEP modes: MEP-A1, MEP-A2 and MEP-B.
+ * If there is no jointly supported MEP mode, supported MEP mode is set to NONE.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum MultipleEnabledProfilesMode {
+ /**
+ * If there is no jointly supported MEP mode, set supported MEP mode to NONE.
+ */
+ NONE,
+ /**
+ * In case of MEP-A1, the ISD-R is selected on eSIM port 0 only and profiles are selected on
+ * eSIM ports 1 and higher, with the eSIM port being assigned by the LPA or platform.
+ */
+ MEP_A1,
+ /**
+ * In case of MEP-A2, the ISD-R is selected on eSIM port 0 only and profiles are selected on
+ * eSIM ports 1 and higher, with the eSIM port being assigned by the eUICC.
+ */
+ MEP_A2,
+ /**
+ * In case of MEP-B, profiles are selected on eSIM ports 0 and higher, with the ISD-R being
+ * selectable on any of these eSIM ports.
+ */
+ MEP_B,
+}
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 748660f..6a36d5e 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -16,6 +16,7 @@
package android.hardware.radio.config;
+import android.hardware.radio.config.MultipleEnabledProfilesMode;
import android.hardware.radio.config.SimPortInfo;
@VintfStability
@@ -52,4 +53,9 @@
* active port in the slot mapping.
*/
SimPortInfo[] portInfo;
+ /**
+ * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0. Should always
+ * report proper MEP mode irrespective of whether the slot is active or inactive.
+ */
+ MultipleEnabledProfilesMode supportedMepMode = MultipleEnabledProfilesMode.NONE;
}
diff --git a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
index 29ece76..071ce55 100644
--- a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
@@ -911,10 +911,14 @@
*/
PDP_MODIFY_COLLISION = 0x875,
/**
- * Maximum size of the L2 message was exceeded.
+ * @deprecated use MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED instead.
*/
MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
/**
+ * Maximum size of the L2 message was exceeded.
+ */
+ MAXIMUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
+ /**
* Non-access stratum (NAS) request was rejected by the network.
*/
NAS_REQUEST_REJECTED_BY_NETWORK = 0x877,
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
index 88b6c1b..06c83c1 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
@@ -44,7 +44,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
* RadioError:NO_RESOURCES- Indicates that no pdu session ids are available
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void allocatePduSessionIdResponse(in RadioResponseInfo info, in int id);
@@ -57,7 +56,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
* RadioError:NO_RESOURCES
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_CALL_ID
*/
void cancelHandoverResponse(in RadioResponseInfo info);
@@ -66,7 +64,6 @@
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
- * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE indicates success. Any other error will remove the network from the list.
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_CALL_ID
@@ -112,7 +109,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
* RadioError:NO_RESOURCES
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void releasePduSessionIdResponse(in RadioResponseInfo info);
@@ -131,7 +127,6 @@
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void setDataAllowedResponse(in RadioResponseInfo info);
@@ -146,7 +141,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void setDataProfileResponse(in RadioResponseInfo info);
@@ -159,7 +153,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:MODEM_ERR
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void setDataThrottlingResponse(in RadioResponseInfo info);
@@ -176,7 +169,6 @@
* RadioError:MODEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:NOT_PROVISIONED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -208,7 +200,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
* RadioError:NO_RESOURCES
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_CALL_ID
*/
void startHandoverResponse(in RadioResponseInfo info);
diff --git a/radio/aidl/android/hardware/radio/data/NrQos.aidl b/radio/aidl/android/hardware/radio/data/NrQos.aidl
index af8ab83..4078fdc 100644
--- a/radio/aidl/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/NrQos.aidl
@@ -27,6 +27,8 @@
const byte FLOW_ID_RANGE_MIN = 1;
const byte FLOW_ID_RANGE_MAX = 63;
+ const int AVERAGING_WINDOW_UNKNOWN = -1;
+
/**
* 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501. The allowed values are standard
* values (1-9, 65-68, 69-70, 75, 79-80, 82-85) defined in the spec and operator specific values
@@ -37,8 +39,15 @@
QosBandwidth uplink;
/**
* QOS flow identifier of the QOS flow description in the range
- * (FLOW_ID_RANGE_MIN, FLOW_ID_RANGE_MAX)
+ * (FLOW_ID_RANGE_MIN, FLOW_ID_RANGE_MAX).
*/
byte qfi;
+ /**
+ * @deprecated use averagingWindowMillis;
+ */
char averagingWindowMs;
+ /**
+ * The duration over which flow rates are calculated.
+ */
+ int averagingWindowMillis = AVERAGING_WINDOW_UNKNOWN;
}
diff --git a/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
new file mode 100644
index 0000000..70faa1e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ConnectionFailureInfo {
+
+ @VintfStability
+ @Backing(type="int")
+ enum ConnectionFailureReason {
+ /** Access class check failed */
+ REASON_ACCESS_DENIED = 1,
+ /** 3GPP Non-access stratum failure */
+ REASON_NAS_FAILURE = 2,
+ /** Random access failure */
+ REASON_RACH_FAILURE = 3,
+ /** Radio link failure */
+ REASON_RLC_FAILURE = 4,
+ /** Radio connection establishment rejected by network */
+ REASON_RRC_REJECT = 5,
+ /** Radio connection establishment timed out */
+ REASON_RRC_TIMEOUT = 6,
+ /** Device currently not in service */
+ REASON_NO_SERVICE = 7,
+ /** The PDN is no more active */
+ REASON_PDN_NOT_AVAILABLE = 8,
+ /** Radio resource is busy with another subscription */
+ REASON_RF_BUSY = 9,
+ REASON_UNSPECIFIED = 0xFFFF,
+ }
+
+ /**
+ * Values are REASON_* constants
+ */
+ ConnectionFailureReason failureReason;
+
+ /**
+ * Failure cause code from network or modem specific to the failure
+ */
+ int causeCode;
+
+ /**
+ * Retry wait time provided by network in milliseconds
+ */
+ int waitTimeMillis;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/EpsFallbackReason.aidl b/radio/aidl/android/hardware/radio/ims/EpsFallbackReason.aidl
new file mode 100644
index 0000000..670638b
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/EpsFallbackReason.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum EpsFallbackReason {
+ /**
+ * If VoNR is not supported and EPS fallback is not triggered by network then UE initiated EPS
+ * fallback would be triggered by IMS stack with this reason. The modem shall locally release
+ * the 5G NR SA RRC connection and acquire the LTE network and perform a tracking area update
+ * procedure. After the EPS fallback procedure is completed, the call setup for voice will
+ * be established.
+ */
+ NO_NETWORK_TRIGGER = 1,
+
+ /**
+ * If the UE doesn't receive any response for SIP INVITE within a certain time in 5G NR SA,
+ * UE initiated EPS fallback will be triggered with this reason. The modem shall reset its data
+ * buffer of IMS PDUs to prevent the ghost call. After the EPS fallback procedure is completed,
+ * the VoLTE call will be established.
+ */
+ NO_NETWORK_RESPONSE = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioIms.aidl b/radio/aidl/android/hardware/radio/ims/IRadioIms.aidl
new file mode 100644
index 0000000..bd661a7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/IRadioIms.aidl
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.ims.EpsFallbackReason;
+import android.hardware.radio.ims.IRadioImsIndication;
+import android.hardware.radio.ims.IRadioImsResponse;
+import android.hardware.radio.ims.ImsCall;
+import android.hardware.radio.ims.ImsRegistration;
+import android.hardware.radio.ims.ImsStreamDirection;
+import android.hardware.radio.ims.ImsStreamType;
+import android.hardware.radio.ims.ImsTrafficType;
+import android.hardware.radio.ims.SrvccCall;
+
+/**
+ * This interface is used by IMS telephony layer to talk to cellular radio.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ * setResponseFunctions must work with IRadioImsResponse and IRadioImsIndication.
+ */
+@VintfStability
+oneway interface IRadioIms {
+ /**
+ * Provides a list of SRVCC call information to radio.
+ *
+ * @param serial Serial number of request
+ * @param srvccCalls the list of calls
+ *
+ * Response function is IRadioImsResponse.setSrvccCallInfoResponse()
+ */
+ void setSrvccCallInfo(int serial, in SrvccCall[] srvccCalls);
+
+ /**
+ * Update the IMS registration information to the radio.
+ *
+ * This information shall be used by radio to implement following carrier requirements:
+ * 1) Graceful IMS PDN disconnection on cellular when NAS is about to perform detach
+ * eg. SIM removal or SIM refresh
+ * 2) Block PLMN or RAT based on the IMS registration failure reason
+ *
+ * @param serial Serial number of request
+ * @param imsRegistration IMS registration information
+ *
+ * Response function is IRadioImsResponse.updateImsRegistrationInfoResponse()
+ */
+ void updateImsRegistrationInfo(int serial, in ImsRegistration imsRegistration);
+
+ /**
+ * IMS stack notifies the NAS and RRC layers of the radio that the upcoming IMS traffic is
+ * for the service mentioned in the ImsTrafficType. If this API is not
+ * explicitly invoked and IMS module sends traffic on IMS PDN then the radio
+ * shall treat type as background data traffic type.
+ * This API shall be used by modem
+ * 1. To set the appropriate establishment cause in RRC connection request.
+ * 2. To prioritize RF resources in case of DSDS. The service priority is
+ * EMERGENCY > EMERGENCY SMS > VOICE > VIDEO > SMS > REGISTRATION > Ut/XCAP. The RF
+ * shall be prioritized to the subscription which handles higher priority service.
+ * When both subscriptions are handling the same type of service then RF shall be
+ * prioritized to the voice preferred sub.
+ * 3. To evaluate the overall access barring in the case of ACB, ACB-Skp/SCM and UAC.
+ * The response {@link IRadioImsResponse#startImsTrafficResponse()} with success shall
+ * be sent by modem upon access class is allowed and RF resource is allotted. Otherwise
+ * the same API shall be invoked with appropriate {@link ConnectionFailureInfo}. Further
+ * if RRC connection setup fails then {@link IRadioImsIndication#onConnectionSetupFailure()}
+ * shall be invoked by modem with appropriate {@link ConnectionFailureInfo}.
+ *
+ * @param serial Serial number of request
+ * @param token A nonce to identify the request
+ * @param imsTrafficType IMS traffic type like registration, voice, and video
+ * @param accessNetworkType The type of the radio access network used
+ * @param trafficDirection Indicates whether traffic is originated by mobile originated or
+ * mobile terminated use case eg. MO/MT call/SMS etc
+ *
+ * Response function is IRadioImsResponse.startImsTrafficResponse()
+ */
+ void startImsTraffic(int serial, int token,
+ ImsTrafficType imsTrafficType, AccessNetwork accessNetworkType,
+ ImsCall.Direction trafficDirection);
+
+ /**
+ * Indicates IMS traffic has been stopped.
+ * For all IMS traffic, notified with startImsTraffic, IMS service shall notify
+ * stopImsTraffic when it completes the traffic specified by the token.
+ *
+ * @param serial Serial number of request
+ * @param token The token assigned by startImsTraffic()
+ *
+ * Response function is IRadioImsResponse.stopImsTrafficResponse()
+ */
+ void stopImsTraffic(int serial, int token);
+
+ /**
+ * Triggers the UE initiated EPS fallback when a MO voice call failed to establish on 5G NR
+ * network and network didn't initiate a fallback.
+ *
+ * @param serial Serial number of request
+ * @param reason Specifies the reason that causes EPS fallback
+ *
+ * Response function is IRadioImsResponse.triggerEpsFallbackResponse()
+ */
+ void triggerEpsFallback(int serial, in EpsFallbackReason reason);
+
+ /**
+ * Set response functions for IMS radio requests and indications.
+ *
+ * @param radioImsResponse Object containing response functions
+ * @param radioImsIndication Object containing radio indications
+ */
+ void setResponseFunctions(in IRadioImsResponse radioImsResponse,
+ in IRadioImsIndication radioImsIndication);
+
+ /**
+ * Access Network Bitrate Recommendation Query (ANBRQ), see 3GPP TS 26.114.
+ * This API triggers radio to send ANBRQ message
+ * to the access network to query the desired bitrate.
+ *
+ * @param serial Serial number of request
+ * @param mediaType Media type is used to identify media stream such as audio or video
+ * @param direction Direction of this packet stream (e.g. uplink or downlink)
+ * @param bitsPerSecond The bit rate requested by the opponent UE
+ *
+ * Response function is IRadioImsResponse.sendAnbrQueryResponse()
+ */
+ void sendAnbrQuery(int serial, ImsStreamType mediaType, ImsStreamDirection direction, int bitsPerSecond);
+
+ /**
+ * Provides a list of IMS call information to radio.
+ *
+ * @param serial Serial number of request
+ * @param imsCalls The list of IMS calls
+ *
+ * Response function is IRadioImsResponse.updateImsCallStatusResponse()
+ */
+ void updateImsCallStatus(int serial, in ImsCall[] imsCalls);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
new file mode 100644
index 0000000..d123d07
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/IRadioImsIndication.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.RadioIndicationType;
+import android.hardware.radio.ims.ConnectionFailureInfo;
+import android.hardware.radio.ims.ImsDeregistrationReason;
+import android.hardware.radio.ims.ImsStreamDirection;
+import android.hardware.radio.ims.ImsStreamType;
+
+/**
+ * Interface declaring unsolicited radio indications for ims APIs.
+ */
+@VintfStability
+oneway interface IRadioImsIndication {
+ /**
+ * Fired by radio when any IMS traffic is not sent to network due to any failure
+ * on cellular networks. IMS service shall call stopImsTraffic when receiving
+ * this indication.
+ *
+ * @param type Type of radio indication
+ * @param token The token of startImsTraffic() associated with this indication
+ * @param info Connection failure information
+ */
+ void onConnectionSetupFailure(
+ in RadioIndicationType type, int token, in ConnectionFailureInfo info);
+
+ /**
+ * Access Network Bitrate Recommendation (ANBR), see 3GPP TS 26.114.
+ * Notifies the bit rate received from the network via ANBR message
+ *
+ * @param type Type of radio indication
+ * @param mediaType Media type is used to identify media stream such as audio or video
+ * @param direction Direction of this packet stream (e.g. uplink or downlink)
+ * @param bitsPerSecond The recommended bit rate for the UE
+ * for a specific logical channel and a specific direction by NW
+ */
+ void notifyAnbr(in RadioIndicationType type, in ImsStreamType mediaType,
+ in ImsStreamDirection direction, int bitsPerSecond);
+
+ /**
+ * Requests IMS stack to perform graceful IMS deregistration before radio performing
+ * network detach in the events of SIM remove, refresh or and so on. The radio waits for
+ * the IMS deregistration, which will be notified by telephony via
+ * {@link IRadioIms#updateImsRegistrationInfo()}, or a certain timeout interval to start
+ * the network detach procedure.
+ *
+ * @param type Type of radio indication
+ * @param reason the reason why the deregistration is triggered
+ */
+ void triggerImsDeregistration(in RadioIndicationType type, in ImsDeregistrationReason reason);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/IRadioImsResponse.aidl b/radio/aidl/android/hardware/radio/ims/IRadioImsResponse.aidl
new file mode 100644
index 0000000..ff516cc
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/IRadioImsResponse.aidl
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.RadioResponseInfo;
+import android.hardware.radio.ims.ConnectionFailureInfo;
+
+/**
+ * Interface declaring response functions to solicited radio requests for ims APIs.
+ */
+@VintfStability
+oneway interface IRadioImsResponse {
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void setSrvccCallInfoResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void updateImsRegistrationInfoResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error.
+ * @param failureInfo Information about failure in detail. If there is no error,
+ * it should be {@code null}.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void startImsTrafficResponse(in RadioResponseInfo info,
+ in @nullable ConnectionFailureInfo failureInfo);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void stopImsTrafficResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void triggerEpsFallbackResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void sendAnbrQueryResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INVALID_STATE
+ * RadioError:NO_MEMORY
+ * RadioError:SYSTEM_ERR
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:NO_RESOURCES
+ */
+ void updateImsCallStatusResponse(in RadioResponseInfo info);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
new file mode 100644
index 0000000..b71682f
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.AccessNetwork;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ImsCall {
+
+ @Backing(type="int")
+ enum CallType {
+ NORMAL,
+ EMERGENCY,
+ }
+
+ @Backing(type="int")
+ enum CallState {
+ ACTIVE,
+ HOLDING,
+ DIALING, /* Outgoing only */
+ ALERTING, /* Outgoing only */
+ INCOMING, /* Incoming only */
+ WAITING, /* Incoming only */
+ DISCONNECTING,
+ DISCONNECTED,
+ }
+
+ @Backing(type="int")
+ enum Direction {
+ INCOMING,
+ OUTGOING,
+ }
+
+ /** Call index */
+ int index;
+
+ /** The type of the call */
+ CallType callType;
+
+ /** The access network where the call is in progress */
+ AccessNetwork accessNetwork;
+
+ /** The state of the call */
+ CallState callState;
+
+ /** The direction of the call */
+ Direction direction;
+
+ /** True if the call is put on HOLD by the other party */
+ boolean isHeldByRemote;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
new file mode 100644
index 0000000..eac8db4
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsDeregistrationReason.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsDeregistrationReason {
+ /**
+ * Radio shall send this reason to IMS stack to perform graceful de-registration
+ * due to SIM card is removed.
+ */
+ REASON_SIM_REMOVED = 1,
+ /**
+ * Radio shall send this reason to IMS stack to perform graceful de-registration
+ * due to SIM refresh that needs a NAS detach and re-attach.
+ */
+ REASON_SIM_REFRESH = 2,
+ /**
+ * Radio shall send this reason to IMS stack to perform graceful de-registration
+ * due to allowed network types bitmask changed that results in NAS detach.
+ */
+ REASON_ALLOWED_NETWORK_TYPES_CHANGED = 3,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
new file mode 100644
index 0000000..662f9e9
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.ims.ImsRegistrationState;
+import android.hardware.radio.ims.SuggestedAction;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ImsRegistration {
+ /** Default value */
+ const int IMS_MMTEL_CAPABILITY_NONE = 0;
+ /** IMS voice */
+ const int IMS_MMTEL_CAPABILITY_VOICE = 1 << 0;
+ /** IMS video */
+ const int IMS_MMTEL_CAPABILITY_VIDEO = 1 << 1;
+ /** IMS SMS */
+ const int IMS_MMTEL_CAPABILITY_SMS = 1 << 2;
+ /** IMS RCS */
+ const int IMS_RCS_CAPABILITIES = 1 << 3;
+
+ /** Indicates the current IMS registration state. */
+ ImsRegistrationState regState;
+
+ /**
+ * Indicates the type of the radio access network where IMS is registered.
+ */
+ AccessNetwork accessNetworkType;
+
+ /** Indicates the expected action for the radio to do. */
+ SuggestedAction suggestedAction;
+
+ /**
+ * Values are bitwise ORs of IMS_MMTEL_CAPABILITY_* constants and IMS_RCS_CAPABILITIES.
+ * IMS capability such as VOICE, VIDEO, SMS and RCS.
+ */
+ int capabilities;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsRegistrationState.aidl b/radio/aidl/android/hardware/radio/ims/ImsRegistrationState.aidl
new file mode 100644
index 0000000..fd5c0fa
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsRegistrationState.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsRegistrationState {
+ /** IMS is not registered */
+ NOT_REGISTERED,
+
+ /** IMS is successfully registered */
+ REGISTERED,
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/ims/ImsStreamDirection.aidl b/radio/aidl/android/hardware/radio/ims/ImsStreamDirection.aidl
new file mode 100644
index 0000000..c0cea32
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsStreamDirection.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsStreamDirection {
+ /** DIRECTION_UPLINK - From UE to Network **/
+ UPLINK = 1,
+ /** DIRECTION_DOWNLINK - From Network to UE **/
+ DOWNLINK = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsStreamType.aidl b/radio/aidl/android/hardware/radio/ims/ImsStreamType.aidl
new file mode 100644
index 0000000..c12a0c1
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsStreamType.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@Backing(type="int")
+enum ImsStreamType {
+ /** Media Stream Type - Audio **/
+ AUDIO = 1,
+ /** Media Stream Type - Video **/
+ VIDEO = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/ImsTrafficType.aidl b/radio/aidl/android/hardware/radio/ims/ImsTrafficType.aidl
new file mode 100644
index 0000000..5a824c0
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/ImsTrafficType.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.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum ImsTrafficType {
+ /** Emergency call */
+ EMERGENCY,
+
+ /** Emergency SMS */
+ EMERGENCY_SMS,
+
+ /** Voice call */
+ VOICE,
+
+ /** Video call */
+ VIDEO,
+
+ /** SMS over IMS */
+ SMS,
+
+ /** IMS registration and subscription for reg event package (signaling) */
+ REGISTRATION,
+
+ /** Ut/XCAP (XML Configuration Access Protocol) */
+ UT_XCAP
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
new file mode 100644
index 0000000..38e6cdb
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable SrvccCall {
+
+ @VintfStability
+ @Backing(type="int")
+ enum CallType {
+ NORMAL,
+ EMERGENCY,
+ }
+
+ @VintfStability
+ @Backing(type="int")
+ enum CallSubState {
+ NONE,
+ /** Pre-alerting state. Applicable for MT calls only */
+ PREALERTING,
+ }
+
+ @VintfStability
+ @Backing(type="int")
+ enum ToneType {
+ NONE,
+ LOCAL,
+ NETWORK,
+ }
+
+ /** Connection index */
+ int index;
+
+ /** The type of the call */
+ CallType callType;
+
+ /** Values are android.hardware.radio.voice.Call.STATE_* constants */
+ int callState;
+
+ /** The substate of the call */
+ CallSubState callSubstate;
+
+ /** The type of the ringback tone */
+ ToneType ringbackToneType;
+
+ /** true if is mpty call */
+ boolean isMpty;
+
+ /** true if call is mobile terminated */
+ boolean isMT;
+
+ /** Remote party nummber */
+ String number;
+
+ /** Values are android.hardware.radio.voice.Call.PRESENTATION_* constants */
+ int numPresentation;
+
+ /** Remote party name */
+ String name;
+
+ /** Values are android.hardware.radio.voice.Call.PRESENTATION_* constants */
+ int namePresentation;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
new file mode 100644
index 0000000..2d12ed6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/SuggestedAction.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"),
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims;
+
+@VintfStability
+@JavaDerive(toString=true)
+@Backing(type="int")
+enum SuggestedAction {
+ /** Default value */
+ NONE,
+ /**
+ * Indicates that the IMS registration is failed with fatal error such as 403 or 404
+ * on all P-CSCF addresses. The radio shall block the current PLMN or disable
+ * the RAT as per the carrier requirements.
+ */
+ TRIGGER_PLMN_BLOCK,
+ /**
+ * Indicates that the IMS registration on current PLMN failed multiple times.
+ * The radio shall block the current PLMN or disable the RAT during EPS or 5GS mobility
+ * management timer value as per the carrier requirements.
+ */
+ TRIGGER_PLMN_BLOCK_WITH_TIMEOUT,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/AmrMode.aidl b/radio/aidl/android/hardware/radio/ims/media/AmrMode.aidl
new file mode 100644
index 0000000..66d8ef0
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/AmrMode.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+/** AMR codec mode to represent the bit rate. See 3ggp Specs 26.976 & 26.071 */
+@VintfStability
+@Backing(type="int")
+enum AmrMode {
+ /** 4.75 kbps for AMR / 6.6 kbps for AMR-WB */
+ AMR_MODE_0 = 1 << 0,
+ /** 5.15 kbps for AMR / 8.855 kbps for AMR-WB */
+ AMR_MODE_1 = 1 << 1,
+ /** 5.9 kbps for AMR / 12.65 kbps for AMR-WB */
+ AMR_MODE_2 = 1 << 2,
+ /** 6.7 kbps for AMR / 14.25 kbps for AMR-WB */
+ AMR_MODE_3 = 1 << 3,
+ /** 7.4 kbps for AMR / 15.85 kbps for AMR-WB */
+ AMR_MODE_4 = 1 << 4,
+ /** 7.95 kbps for AMR / 18.25 kbps for AMR-WB */
+ AMR_MODE_5 = 1 << 5,
+ /** 10.2 kbps for AMR / 19.85 kbps for AMR-WB */
+ AMR_MODE_6 = 1 << 6,
+ /** 12.2 kbps for AMR / 23.05 kbps for AMR-WB */
+ AMR_MODE_7 = 1 << 7,
+ /** Silence frame for AMR / 23.85 kbps for AMR-WB */
+ AMR_MODE_8 = 1 << 8,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl
new file mode 100644
index 0000000..4ed3a24
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/AmrParams.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.AmrMode;
+
+@VintfStability
+parcelable AmrParams {
+ /** mode-set: AMR codec mode to represent the bit rate */
+ AmrMode amrMode;
+ /**
+ * octet-align: If it's set to true then all fields in the AMR/AMR-WB header
+ * shall be aligned to octet boundaries by adding padding bits.
+ */
+ boolean octetAligned;
+ /**
+ * max-red: It’s the maximum duration in milliseconds that elapses between the
+ * primary (first) transmission of a frame and any redundant transmission that
+ * the sender will use. This parameter allows a receiver to have a bounded delay
+ * when redundancy is used. Allowed values are between 0 (no redundancy will be
+ * used) and 65535. If the parameter is omitted, no limitation on the use of
+ * redundancy is present. See RFC 4867
+ */
+ int maxRedundancyMillis;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
new file mode 100644
index 0000000..f758cd4
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.CodecMode;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable AnbrMode {
+ /**
+ * Codec mode converted from bitrate received for uplink
+ * from network or peer UE for ANBR
+ */
+ CodecMode anbrUplinkMode;
+ /**
+ * Codec mode converted from bitrate received for downlink
+ * from network or peer UE for ANBR
+ */
+ CodecMode anbrDownlinkMode;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
new file mode 100644
index 0000000..a8f7b16
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable CallQuality {
+ /**
+ * downlink CallQualityLevel for a given ongoing call
+ * this value corresponds to the CALL_QUALITY_* constants in {@link CallQuality}
+ */
+ int downlinkCallQualityLevel;
+ /**
+ * uplink CallQualityLevel for a given ongoing call
+ * this value corresponds to the CALL_QUALITY_* constants in {@link CallQuality}
+ */
+ int uplinkCallQualityLevel;
+ /** the call duration in milliseconds */
+ int callDuration;
+ /** RTP packets sent to network */
+ int numRtpPacketsTransmitted;
+ /** RTP packets received from network */
+ int numRtpPacketsReceived;
+ /** RTP packets which were lost in network and never transmitted */
+ int numRtpPacketsTransmittedLost;
+ /** RTP packets which were lost in network and never received */
+ int numRtpPacketsNotReceived;
+ /** average relative jitter in milliseconds */
+ int averageRelativeJitter;
+ /** maximum relative jitter in milliseconds */
+ int maxRelativeJitter;
+ /** average round trip delay in milliseconds */
+ int averageRoundTripTime;
+ /**
+ * the codec type. This value corresponds to the AUDIO_QUALITY_* constants in
+ * {@link ImsStreamMediaProfile}
+ */
+ int codecType;
+ /** True if no incoming RTP is received for a continuous duration of 4 seconds */
+ boolean rtpInactivityDetected;
+ /**
+ * True if only silence RTP packets are received for 20 seconds
+ * immediately after call is connected
+ */
+ boolean rxSilenceDetected;
+ /**
+ * True if only silence RTP packets are sent for 20 seconds
+ * immediately after call is connected
+ */
+ boolean txSilenceDetected;
+ /** the number of Voice frames sent by jitter buffer to audio */
+ int numVoiceFrames;
+ /** the number of no-data frames sent by jitter buffer to audio */
+ int numNoDataFrames;
+ /** the number of RTP voice packets dropped by jitter buffer */
+ int numDroppedRtpPackets;
+ /** the minimum playout delay in the reporting interval in milliseconds */
+ long minPlayoutDelayMillis;
+ /** the maximum playout delay in the reporting interval in milliseconds */
+ long maxPlayoutDelayMillis;
+ /**
+ * the total number of RTP SID (Silence Insertion Descriptor) packets
+ * received by this device for an ongoing call
+ */
+ int numRtpSidPacketsReceived;
+ /**
+ * the total number of RTP duplicate packets received by this device
+ * for an ongoing call
+ */
+ int numRtpDuplicatePackets;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
new file mode 100644
index 0000000..aa1b3a4
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.AmrMode;
+import android.hardware.radio.ims.media.EvsMode;
+
+@VintfStability
+@JavaDerive(toString=true)
+union CodecMode {
+ /** Default value */
+ boolean noinit;
+ /** AMR codec mode to represent the bit rate. See 3ggp Specs 26.976 & 26.071 */
+ AmrMode amr;
+ /** EVS codec mode to represent the bit rate. See 3ggp Spec 26.952 Table 5.1 */
+ EvsMode evs;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl
new file mode 100644
index 0000000..0aa5505
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecParams.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.CodecSpecificParams;
+import android.hardware.radio.ims.media.CodecType;
+
+@VintfStability
+parcelable CodecParams {
+ /** Negotiated codec type */
+ CodecType codecType;
+ /**
+ * Static or dynamic payload type number negotiated through the SDP for
+ * the incoming RTP packets. This value shall be matched with the PT value
+ * of the incoming RTP header. Values 0 to 127, see RFC 3551 section 6
+ */
+ byte rxPayloadTypeNumber;
+ /**
+ * Static or dynamic payload type number negotiated through the SDP for
+ * the outgoing RTP packets. This value shall be set to the PT value
+ * of the outgoing RTP header. Values 0 to 127, see RFC 3551 section 6
+ */
+ byte txPayloadTypeNumber;
+ /** Sampling rate in kHz*/
+ byte samplingRateKHz;
+ /** dtx: Whether discontinuous transmission is enabled or not */
+ boolean dtxEnabled;
+ /** Codec specific parameters */
+ CodecSpecificParams codecSpecificParams;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
new file mode 100644
index 0000000..4410c81
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.AmrParams;
+import android.hardware.radio.ims.media.EvsParams;
+
+@VintfStability
+union CodecSpecificParams {
+ AmrParams amr;
+ EvsParams evs;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecType.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecType.aidl
new file mode 100644
index 0000000..31218e3
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecType.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+@Backing(type="int")
+enum CodecType {
+ /** Adaptive Multi-Rate */
+ AMR = 1 << 0,
+ /** Adaptive Multi-Rate Wide Band */
+ AMR_WB = 1 << 1,
+ /** Enhanced Voice Services */
+ EVS = 1 << 2,
+ /** G.711 A-law i.e. Pulse Code Modulation using A-law */
+ PCMA = 1 << 3,
+ /** G.711 μ-law i.e. Pulse Code Modulation using μ-law */
+ PCMU = 1 << 4,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
new file mode 100644
index 0000000..a7dcb0d
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable DtmfParams {
+ /**
+ * Dynamic payload type number to be used for DTMF RTP packets received.
+ * The values is in the range from 96 to 127 chosen during the session
+ * establishment. The PT value of the RTP header of all DTMF packets shall be
+ * set with this value.
+ */
+ byte rxPayloadTypeNumber;
+
+ /**
+ * Dynamic payload type number to be used for DTMF RTP packets sent.
+ * The values is in the range from 96 to 127 chosen during the session
+ * establishment. The PT value of the RTP header of all DTMF packets shall be set
+ * with this value.
+ */
+ byte txPayloadTypeNumber;
+
+ /** Sampling rate in kHz */
+ byte samplingRateKHz;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsBandwidth.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsBandwidth.aidl
new file mode 100644
index 0000000..8278514
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsBandwidth.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+/** EVS Speech codec bandwidths, See 3gpp spec 26.441 Table 1 */
+@VintfStability
+@Backing(type="int")
+enum EvsBandwidth {
+ NONE = 0,
+ NARROW_BAND = 1 << 0,
+ WIDE_BAND = 1 << 1,
+ SUPER_WIDE_BAND = 1 << 2,
+ FULL_BAND = 1 << 3,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsMode.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsMode.aidl
new file mode 100644
index 0000000..95bd6c7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsMode.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+/** EVS codec mode to represent the bit rate. See 3ggp Spec 26.952 Table 5.1 */
+@VintfStability
+@Backing(type="int")
+enum EvsMode {
+ /** 6.6 kbps for EVS AMR-WB IO */
+ EVS_MODE_0 = 1 << 0,
+ /** 8.855 kbps for AMR-WB IO */
+ EVS_MODE_1 = 1 << 1,
+ /** 12.65 kbps for AMR-WB IO */
+ EVS_MODE_2 = 1 << 2,
+ /** 14.25 kbps for AMR-WB IO */
+ EVS_MODE_3 = 1 << 3,
+ /** 15.85 kbps for AMR-WB IO */
+ EVS_MODE_4 = 1 << 4,
+ /** 18.25 kbps for AMR-WB IO */
+ EVS_MODE_5 = 1 << 5,
+ /** 19.85 kbps for AMR-WB IO */
+ EVS_MODE_6 = 1 << 6,
+ /** 23.05 kbps for AMR-WB IO */
+ EVS_MODE_7 = 1 << 7,
+ /** 23.85 kbps for AMR-WB IO */
+ EVS_MODE_8 = 1 << 8,
+ /** 5.9 kbps for EVS primary */
+ EVS_MODE_9 = 1 << 9,
+ /** 7.2 kbps for EVS primary */
+ EVS_MODE_10 = 1 << 10,
+ /** 8.0 kbps for EVS primary */
+ EVS_MODE_11 = 1 << 11,
+ /** 9.6 kbps for EVS primary */
+ EVS_MODE_12 = 1 << 12,
+ /** 13.2 kbps for EVS primary */
+ EVS_MODE_13 = 1 << 13,
+ /** 16.4 kbps for EVS primary */
+ EVS_MODE_14 = 1 << 14,
+ /** 24.4 kbps for EVS primary */
+ EVS_MODE_15 = 1 << 15,
+ /** 32.0 kbps for EVS primary */
+ EVS_MODE_16 = 1 << 16,
+ /** 48.0 kbps for EVS primary */
+ EVS_MODE_17 = 1 << 17,
+ /** 64.0 kbps for EVS primary */
+ EVS_MODE_18 = 1 << 18,
+ /** 96.0 kbps for EVS primary */
+ EVS_MODE_19 = 1 << 19,
+ /** 128.0 kbps for EVS primary */
+ EVS_MODE_20 = 1 << 20,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
new file mode 100644
index 0000000..d138c83
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.EvsBandwidth;
+import android.hardware.radio.ims.media.EvsMode;
+
+@VintfStability
+parcelable EvsParams {
+ /** EVS codec bandwidth */
+ EvsBandwidth bandwidth;
+
+ /** mode-set: EVS codec mode to represent the bit rate */
+ EvsMode evsMode;
+ /**
+ * ch-aw-recv: Channel aware mode for the receive direction. Permissible values
+ * are -1, 0, 2, 3, 5, and 7. If -1, channel-aware mode is disabled in the
+ * session for the receive direction. If 0 or not present, partial redundancy
+ * (channel-aware mode) is not used at the start of the session for the receive
+ * direction. If positive (2, 3, 5, or 7), partial redundancy (channel-aware
+ * mode) is used at the start of the session for the receive direction using the
+ * value as the offset, See 3GPP TS 26.445 section 4.4.5
+ */
+ byte channelAwareMode;
+ /**
+ * hf-only: Header full only is used for the outgoing and incoming packets.
+ * If it's true then the session shall support header full format only else the
+ * session could support both header full format and compact format.
+ */
+ boolean useHeaderFullOnly;
+ /**
+ * evs-mode-switch: Used for switching between EVS Primary mode and EVS AMR-WB IO mode,
+ * If this value is true, the codec operates in AMR-WB IO mode
+ */
+ boolean useEvsModeSwitch;
+ /**
+ * cmr: Codec mode request is used to request the speech codec encoder of the
+ * other party to set the frame type index of speech mode via RTP header, See
+ * 3GPP TS 26.445 section A.3. Allowed values are -1, 0 and 1.
+ */
+ byte codecModeRequest;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMedia.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMedia.aidl
new file mode 100644
index 0000000..ecf1370
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMedia.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.IImsMediaListener;
+import android.hardware.radio.ims.media.LocalEndPoint;
+import android.hardware.radio.ims.media.RtpConfig;
+import android.hardware.radio.ims.media.RtpError;
+
+/**
+ * This interface is used by IMS media framework to talk to RTP stack located in another processor.
+ */
+@VintfStability
+oneway interface IImsMedia {
+
+ /**
+ * Set the listener functions for receiving notifications from the RTP stack.
+ *
+ * @param mediaListener Object containing listener methods
+ */
+ void setListener(in IImsMediaListener mediaListener);
+
+ /**
+ * Opens a RTP session for the local end point with the associated initial remote configuration
+ * if there is a valid RtpConfig passed. It starts the media flow if the media direction in the
+ * RtpConfig is set to any value other than NO_MEDIA_FLOW. If the open session is successful
+ * then the implementation shall return a new IImsMediaSession binder connection for this
+ * session using IImsMediaListener#onOpenSessionSuccess() API. If the open session is failed
+ * then the implementation shall return the error using IImsMediaListener#onOpenSessionFailure()
+ *
+ * @param sessionId unique identifier of the session
+ * @param localEndPoint provides IP address, port and logical modem id for local RTP endpoint
+ * @param config provides remote end point info and codec details. This could be null initially
+ * and the application may update this later using modifySession() API.
+ */
+ void openSession(int sessionId, in LocalEndPoint localEndPoint, in RtpConfig config);
+
+ /**
+ * Close the RTP session including cleanup of all the resources associated with the session.
+ * This shall also close the session specific binder connection opened as part of openSession().
+ *
+ * @param sessionId identifier for the rtp session that needs to be closed
+ */
+ void closeSession(int sessionId);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaListener.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaListener.aidl
new file mode 100644
index 0000000..228acb7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaListener.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.IImsMediaSession;
+import android.hardware.radio.ims.media.RtpError;
+
+/**
+ * Interface declaring listener functions for unsolicited IMS media notifications.
+ */
+@VintfStability
+oneway interface IImsMediaListener {
+ /**
+ * Fired when a IImsMedia#openSession() API is successful.
+ *
+ * @param sessionId identifier of the session
+ * @param session new IImsMediaSession binder connection to be used for the session
+ * specific operations
+ */
+ void onOpenSessionSuccess(int sessionId, IImsMediaSession session);
+
+ /**
+ * Fired when IImsMedia#openSession() API failed to create a new session.
+ *
+ * @param sessionId identifier of the session
+ * @param error one of the following RTP error code
+ * RtpError :INVALID_PARAM
+ * RtpError :INTERNAL_ERR
+ * RtpError :NO_MEMORY
+ * RtpError :NO_RESOURCES
+ * RtpError :PORT_UNAVAILABLE
+ */
+ void onOpenSessionFailure(int sessionId, RtpError error);
+
+ /**
+ * Fired when IImsMedia#closeSession() API handled.
+ *
+ * @param sessionId identifier of the session
+ */
+ void onSessionClosed(int sessionId);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
new file mode 100644
index 0000000..ec2fa2b
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSession.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.IImsMediaSessionListener;
+import android.hardware.radio.ims.media.MediaQualityThreshold;
+import android.hardware.radio.ims.media.RtpConfig;
+import android.hardware.radio.ims.media.RtpError;
+import android.hardware.radio.ims.media.RtpHeaderExtension;
+
+/**
+ * Session specific interface used by IMS media framework to talk to the vendor RTP stack.
+ */
+@VintfStability
+oneway interface IImsMediaSession {
+ /**
+ * Set the listener functions to receive IMS media session specific notifications.
+ *
+ * @param sessionListener Object containing notification methods
+ */
+ void setListener(in IImsMediaSessionListener sessionListener);
+
+ /**
+ * Modifies the configuration of the RTP session. It can be used to pause/resume
+ * the media stream by changing the value of the MediaDirection.
+ *
+ * @param config provides remote end point info and codec details
+ */
+ void modifySession(in RtpConfig config);
+
+ /**
+ * Send DTMF digit until the duration expires.
+ *
+ * @param dtmfDigit single char having one of 12 values: 0-9, *, #
+ * @param duration of the key press in milliseconds.
+ */
+ void sendDtmf(char dtmfDigit, int duration);
+
+ /**
+ * Start sending DTMF digit until the stopDtmf() API is received.
+ * If the implementation is currently sending a DTMF tone for which
+ * stopDtmf() is not received yet, then that digit must be stopped first
+ *
+ * @param dtmfDigit single char having one of 12 values: 0-9, *, #
+ */
+ void startDtmf(char dtmfDigit);
+
+ /**
+ * Stop sending the last DTMF digit started by startDtmf().
+ * stopDtmf() without preceding startDtmf() must be ignored.
+ */
+ void stopDtmf();
+
+ /**
+ * Send RTP header extension to the other party in the next RTP packet.
+ *
+ * @param extensions data to be transmitted via RTP header extension
+ */
+ void sendHeaderExtension(in List<RtpHeaderExtension> extensions);
+
+ /**
+ * Sets the media quality threshold parameters of the session to get
+ * media quality notifications.
+ *
+ * @param threshold media quality thresholds for various quality parameters
+ */
+ void setMediaQualityThreshold(in MediaQualityThreshold threshold);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
new file mode 100644
index 0000000..8341da2
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/IImsMediaSessionListener.aidl
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.CallQuality;
+import android.hardware.radio.ims.media.MediaQualityStatus;
+import android.hardware.radio.ims.media.RtpConfig;
+import android.hardware.radio.ims.media.RtpError;
+import android.hardware.radio.ims.media.RtpHeaderExtension;
+
+/**
+ * Interface declaring listener functions for unsolicited IMS media notifications per session.
+ */
+@VintfStability
+oneway interface IImsMediaSessionListener {
+ /**
+ * Notifies the result of IImsMediaSession#modifySession() API.
+ *
+ * @param config The RTP config passed in IImsMediaSession#modifySession() API
+ * @param error RtpError.NONE in case of success else one of the following
+ * RtpError :INVALID_PARAM
+ * RtpError :INTERNAL_ERR
+ * RtpError :NO_MEMORY
+ * RtpError :NO_RESOURCES
+ */
+ void onModifySessionResponse(in RtpConfig config, RtpError error);
+
+ /**
+ * Indicates when the first Rtp media packet is received by the UE during ring
+ * back, call hold or early media scenarios. This is sent only if the packet is
+ * received on the active remote configuration.
+ *
+ * In case of early media scenarios, the implementation shall play the RTP
+ * packets from the most recently added config.
+ *
+ * @param config The remote config where the media is received
+ */
+ void onFirstMediaPacketReceived(in RtpConfig config);
+
+ /**
+ * RTP header extension received from the other party
+ *
+ * @param extensions content of the received RTP header extension
+ */
+ void onHeaderExtensionReceived(in List<RtpHeaderExtension> extensions);
+
+ /**
+ * Notifies when the measured media quality crosses at least one of
+ * {@link MediaQualityThreshold} set by {@link IImsMediaSession#setMediaQualityThreshold()}.
+ *
+ * @param quality The object of MediaQualityStatus with the rtp and the rtcp statistics.
+ */
+ void notifyMediaQualityStatus(in MediaQualityStatus quality);
+
+ /**
+ * The modem RTP stack fires this API to query whether the desired bitrate mentioned
+ * in the RtpConfig is currently available on the NW or not using ANBRQ message.
+ * See 3GPP TS 26.114.
+ *
+ * @param config containing desired bitrate and direction
+ */
+ void triggerAnbrQuery(in RtpConfig config);
+
+ /**
+ * Notifies the received DTMF digit from the other party
+ *
+ * @param dtmfDigit single char having one of 12 values: 0-9, *, #
+ * @param durationMs The duration to play the tone in milliseconds unit
+ */
+ void onDtmfReceived(char dtmfDigit, int durationMs);
+
+ /**
+ * Notifies when a change to call quality has occurred
+ *
+ * @param CallQuality The call quality statistics of ongoing call since last report
+ */
+ void onCallQualityChanged(in CallQuality callQuality);
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/LocalEndPoint.aidl b/radio/aidl/android/hardware/radio/ims/media/LocalEndPoint.aidl
new file mode 100644
index 0000000..2bd48c6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/LocalEndPoint.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.os.ParcelFileDescriptor;
+
+@VintfStability
+parcelable LocalEndPoint {
+ /** Socket file descriptor for RTP traffic */
+ ParcelFileDescriptor rtpFd;
+ /** Socket file descriptor for RTCP traffic */
+ ParcelFileDescriptor rtcpFd;
+ /** The logical modem ID, returned by IRadioConfig.getPhoneCapability() */
+ int modemId;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaDirection.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaDirection.aidl
new file mode 100644
index 0000000..e5c34c7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaDirection.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+/**
+ * Directions can be combined to meet various media direction
+ * requirements depending on the scenario.
+ *
+ * Examples:
+ * No Flow : NO_FLOW - eg. SRVCC.
+ * RTCP-only : RTCP_TX | RTCP_RX - eg. Local Hold or Dual Hold.
+ * Receive-Only : RTP_RX | RTCP_TX | RTCP_RX - eg. Remote Hold.
+ * Send-Receive : RTP_TX | RTP_RX | RTCP_TX | RTCP_RX - eg. Active call.
+ * Send-Only : RTP_TX | RTCP_TX | RTCP_RX - eg. Simplex call, voice mail, etc
+ */
+@VintfStability
+@Backing(type="int")
+enum MediaDirection {
+ /**
+ * No RTP/RTCP flow in either direction. The implementation
+ * may release the audio resource. Eg. SRVCC.
+ */
+ NO_FLOW = 0,
+
+ /** Send RTP packets */
+ RTP_TX = 1 << 0,
+
+ /** Receive and processes RTP packets */
+ RTP_RX = 1 << 1,
+
+ /** Send RTCP packets */
+ RTCP_TX = 1 << 2,
+
+ /** Receive RTCP packets */
+ RTCP_RX = 1 << 3,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl
new file mode 100644
index 0000000..b99e501
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable MediaQualityStatus {
+ /**
+ * Rtp inactivity observed as per threshold set by
+ * {@link IImsMediaSession#setMediaQualityThreshold()}
+ */
+ int rtpInactivityTimeMillis;
+ /**
+ * Rtcp inactivity observed as per threshold set by
+ * {@link IImsMediaSession#setMediaQualityThreshold()}
+ */
+ int rtcpInactivityTimeMillis;
+ /**
+ * Rtp packet loss rate observed as per threshold set by
+ * {@link IImsMediaSession#setMediaQualityThreshold()}
+ */
+ int rtpPacketLossRate;
+ /**
+ * Rtp jitter observed as per threshold set by
+ * {@link IImsMediaSession#setMediaQualityThreshold()}
+ */
+ int rtpJitterMillis;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
new file mode 100644
index 0000000..bf98928
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable MediaQualityThreshold {
+ /** Array including threshold values in milliseconds for monitoring RTP inactivity */
+ int[] rtpInactivityTimerMillis;
+ /** Timer in milliseconds for monitoring RTCP inactivity */
+ int rtcpInactivityTimerMillis;
+ /**
+ * This value determines the size of the time window (in milliseconds)
+ * required to calculate the packet loss rate per second for the manner of
+ * smoothly monitoring changes in the packet loss rate value.
+ */
+ int rtpPacketLossDurationMillis;
+ /**
+ * The threshold hysteresis time for packet loss and jitter. This has a goal to prevent
+ * frequent ping-pong notification. So whenever a notifier needs to report the cross of
+ * threshold in opposite direction, this hysteresis timer should be respected.
+ */
+ int rtpHysteresisTimeInMillis;
+ /**
+ * Array including threshold values of Packet loss rate in percentage of
+ * (total number of packets lost) / (total number of packets expected) calculated
+ * every one sec with the packet received in rtpPacketLossDurationMillis.
+ */
+ int[] rtpPacketLossRate;
+
+ /** Array including threshold values in milliseconds for RTP jitter */
+ int[] rtpJitterMillis;
+
+ /**
+ * A flag indicating whether the client needs to be notified the current media quality status
+ * right after the threshold is being set. True means the media stack should notify the client
+ * of the current status.
+ */
+ boolean notifyCurrentStatus;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
new file mode 100644
index 0000000..98bbfc6
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable RtcpConfig {
+ /** Canonical name that will be sent to all session participants */
+ String canonicalName;
+ /** Port for sending outgoing RTCP packets */
+ int transmitPort;
+ /** Transmit interval in seconds. Value 0 indicates that RTCP reports should not be reported */
+ int transmitIntervalSec;
+ /** Bitmask of RTCP-XR blocks to enable as in RtcpXrReportBlockType */
+ int rtcpXrBlocks;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl b/radio/aidl/android/hardware/radio/ims/media/RtcpXrReportBlockType.aidl
new file mode 100644
index 0000000..7f6839a
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtcpXrReportBlockType.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+/** RTP Control Protocol Extended Reports (RTCP XR) Blocks, See RFC 3611 section 4 */
+
+@VintfStability
+@Backing(type="int")
+enum RtcpXrReportBlockType {
+ /** Disable RTCP XR */
+ RTCPXR_NONE = 0,
+ /** Loss RLE Report Block */
+ RTCPXR_LOSS_RLE_REPORT_BLOCK = 1 << 0,
+ /** Duplicate RLE Report Block */
+ RTCPXR_DUPLICATE_RLE_REPORT_BLOCK = 1 << 1,
+ /** Packet Receipt Times Report Block */
+ RTCPXR_PACKET_RECEIPT_TIMES_REPORT_BLOCK = 1 << 2,
+ /** Receiver Reference Time Report Block */
+ RTCPXR_RECEIVER_REFERENCE_TIME_REPORT_BLOCK = 1 << 3,
+ /** DLRR Report Block */
+ RTCPXR_DLRR_REPORT_BLOCK = 1 << 4,
+ /** Statistics Summary Report Block */
+ RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK = 1 << 5,
+ /** VoIP Metrics Report Block */
+ RTCPXR_VOIP_METRICS_REPORT_BLOCK = 1 << 6,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
new file mode 100644
index 0000000..2db73a3
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+parcelable RtpAddress {
+ /** Point to point IP address */
+ String ipAddress;
+ /** UDP port number used for the RTP traffic */
+ int portNumber;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
new file mode 100644
index 0000000..f93b112
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.ims.media.AnbrMode;
+import android.hardware.radio.ims.media.RtcpConfig;
+import android.hardware.radio.ims.media.RtpAddress;
+import android.hardware.radio.ims.media.RtpSessionParams;
+
+@VintfStability
+parcelable RtpConfig {
+ /** Media flow direction. The bitfield of MediaDirection(s) */
+ int direction;
+ /** Radio Access Network */
+ AccessNetwork accessNetwork;
+ /** IP address and port number of the other party for RTP media */
+ RtpAddress remoteAddress;
+ /** Negotiated session parameters */
+ RtpSessionParams sessionParams;
+ /** RTCP configuration */
+ RtcpConfig rtcpConfig;
+ /**
+ * ANBR Mode parameters. This is set to valid only when its triggered,
+ * otherwise it shall be set to NULL.
+ *
+ * This would be used in the following two cases
+ * - IImsMediaSession#modifySession(RtpConfig) - When RAN wants to change the bit
+ * rate via ANBR MAC layer signaling, ImsStack converts the received bitrate
+ * to the codec mode appropriately and passes the codec mode and direction
+ * using modifySession(). The underlying RTP stack shall adapt to
+ * the changed bitrate.
+ *
+ * - IImsMediaSessionListener#triggerAnbrQuery(RtpConfig) - When the vendor RTP
+ * stack receives a request for bitrate increase from the peer terminal via CMR,
+ * RTCP-APP or TMMBR, it triggers ANBRQ by setting the desired bitrate and the
+ * direction of the stream.
+ */
+ AnbrMode anbrModeParams;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpError.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpError.aidl
new file mode 100644
index 0000000..11a3468
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpError.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+@VintfStability
+@Backing(type="int")
+enum RtpError {
+ /** Success */
+ NONE = 0,
+ /** Invalid parameters passed in the request */
+ INVALID_PARAM = 1,
+ /** The RTP stack is not ready to handle the request */
+ NOT_READY = 2,
+ /** Unable to handle the request due to memory allocation failure */
+ NO_MEMORY = 3,
+ /** Unable to handle the request due to no sufficient resources such as audio, codec */
+ NO_RESOURCES = 4,
+ /** The requested port number is not available */
+ PORT_UNAVAILABLE = 5,
+ /** The request is not supported by the implementation */
+ NOT_SUPPORTED = 6,
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
new file mode 100644
index 0000000..76b13dc
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package android.hardware.radio.ims.media;
+
+/** RTP Header Extensions, see RFC 8285 */
+@VintfStability
+parcelable RtpHeaderExtension {
+ /** Local identifier */
+ int localId;
+ /** Extension data bytes */
+ byte[] data;
+}
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl
new file mode 100644
index 0000000..f93c52c
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.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.
+ */
+
+package android.hardware.radio.ims.media;
+
+import android.hardware.radio.ims.media.CodecParams;
+import android.hardware.radio.ims.media.DtmfParams;
+
+@VintfStability
+parcelable RtpSessionParams {
+ /**
+ * ptime: Recommended length of time in milliseconds represented by the media
+ * in each packet, see RFC 4566
+ */
+ byte pTimeMillis;
+ /**
+ * maxptime: Maximum amount of media that can be encapsulated in each packet
+ * represented in milliseconds, see RFC 4566
+ */
+ int maxPtimeMillis;
+ /** dscp: Differentiated Services Field Code Point value, see RFC 2474 */
+ byte dscp;
+ /** DTMF payload and clock rate */
+ DtmfParams dtmfParams;
+ /** Negotiated codec parameters */
+ CodecParams codecParams;
+}
diff --git a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
index ee62d95..b256c9a 100644
--- a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -27,6 +27,7 @@
/**
* SMS in PDU format as an ASCII hex string less the SMSC address.
* TP-Layer-Length is be "strlen(pdu)/2
+ * TP - MessageRef field of pdu must not be modified by modem
*/
String pdu;
}
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 492755f..8cbc869 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -36,7 +36,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void acknowledgeIncomingGsmSmsWithPduResponse(in RadioResponseInfo info);
@@ -56,7 +55,6 @@
* RadioError:NETWORK_NOT_READY
* RadioError:INVALID_MODEM_STATE
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -73,7 +71,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void acknowledgeLastIncomingGsmSmsResponse(in RadioResponseInfo info);
@@ -98,7 +95,6 @@
* RadioError:MODEM_ERR
* RadioError:NO_SUCH_ENTRY
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -122,7 +118,6 @@
* RadioError:NO_SUCH_ENTRY
* RadioError:INTERNAL_ERR
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
@@ -145,7 +140,6 @@
* RadioError:MODEM_ERR
* RadioError:NO_RESOURCES
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
@@ -168,7 +162,6 @@
* RadioError:MODEM_ERR
* RadioError:NO_RESOURCES
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
@@ -191,7 +184,6 @@
* RadioError:MODEM_ERR
* RadioError:INVALID_MODEM_STATE
* RadioError:NOT_PROVISIONED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -212,7 +204,6 @@
* RadioError:MODEM_ERR
* RadioError:INVALID_STATE
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:SIM_ABSENT
@@ -240,7 +231,6 @@
* RadioError:MODEM_ERR
* RadioError:NETWORK_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NETWORK_NOT_READY
* RadioError:OPERATION_NOT_ALLOWED
@@ -275,7 +265,6 @@
* RadioError:INVALID_SMSC_ADDRESS
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:ENCODING_ERR
* RadioError:NO_RESOURCES
@@ -308,7 +297,6 @@
* RadioError:ENCODING_ERR
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NETWORK_NOT_READY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -336,7 +324,6 @@
* RadioError:MODEM_ERR
* RadioError:NETWORK_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NETWORK_NOT_READY
* RadioError:OPERATION_NOT_ALLOWED
@@ -368,7 +355,6 @@
* RadioError:MODEM_ERR
* RadioError:NETWORK_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NETWORK_NOT_READY
* RadioError:OPERATION_NOT_ALLOWED
@@ -393,7 +379,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -414,7 +399,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
@@ -434,7 +418,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -455,7 +438,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
@@ -476,7 +458,6 @@
* RadioError:MODEM_ERR
* RadioError:NO_RESOURCES
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -502,7 +483,6 @@
* RadioError:INVALID_MODEM_STATE
* RadioError:INVALID_SMSC_ADDRESS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -531,7 +511,6 @@
* RadioError:INVALID_SMSC_ADDRESS
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
* RadioError:SIM_ABSENT
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
index ba0ddb9..2011c53 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
@@ -67,6 +67,7 @@
* @param serial Serial number of request.
*
* Response function is IRadioModemResponse.getDeviceIdentityResponse()
+ * @deprecated use getImei(int serial)
*/
void getDeviceIdentity(in int serial);
@@ -117,6 +118,8 @@
* @param itemId NvItem
*
* Response function is IRadioModemResponse.nvReadItemResponse()
+ *
+ * @deprecated NV APIs are deprecated starting from Android U.
*/
void nvReadItem(in int serial, in NvItem itemId);
@@ -128,6 +131,8 @@
* @param resetType ResetNvType
*
* Response function is IRadioModemResponse.nvResetConfigResponse()
+ *
+ * Note: This will be deprecated in favor of a rebootModem API in Android U.
*/
void nvResetConfig(in int serial, in ResetNvType resetType);
@@ -139,6 +144,8 @@
* @param prl PRL as a byte array
*
* Response function is IRadioModemResponse.nvWriteCdmaPrlResponse()
+ *
+ * @deprecated NV APIs are deprecated starting from Android U.
*/
void nvWriteCdmaPrl(in int serial, in byte[] prl);
@@ -150,6 +157,8 @@
* @param item NvWriteItem
*
* Response function is IRadioModemResponse.nvWriteItemResponse()
+ *
+ * @deprecated NV APIs are deprecated starting from Android U.
*/
void nvWriteItem(in int serial, in NvWriteItem item);
@@ -227,4 +236,13 @@
*/
void setResponseFunctions(in IRadioModemResponse radioModemResponse,
in IRadioModemIndication radioModemIndication);
+
+ /**
+ * Request the IMEI associated with the radio.
+ *
+ * @param serial : Serial number of request.
+ *
+ * Response function is IRadioModemResponse.getImeiResponse()
+ */
+ void getImei(in int serial);
}
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
index b17cac4..fd4bffb 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -20,6 +20,7 @@
import android.hardware.radio.modem.ActivityStatsInfo;
import android.hardware.radio.modem.HardwareConfig;
import android.hardware.radio.modem.RadioCapability;
+import android.hardware.radio.modem.ImeiInfo;
/**
* Interface declaring response functions to solicited radio requests for modem APIs.
@@ -61,7 +62,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:NOT_PROVISIONED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -89,6 +89,7 @@
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:REQUEST_NOT_SUPPORTED
+ * @deprecated use getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo)
*/
void getDeviceIdentityResponse(in RadioResponseInfo info, in String imei, in String imeisv,
in String esn, in String meid);
@@ -100,7 +101,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getHardwareConfigResponse(in RadioResponseInfo info, in HardwareConfig[] config);
@@ -118,7 +118,6 @@
* RadioError:NOT_PROVISIONED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getModemActivityInfoResponse(in RadioResponseInfo info, in ActivityStatsInfo activityInfo);
@@ -141,7 +140,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INVALID_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
@@ -156,7 +154,8 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
+ *
+ * @deprecated NV APIs are deprecated starting from Android U.
*/
void nvReadItemResponse(in RadioResponseInfo info, in String result);
@@ -166,7 +165,8 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
+ *
+ * Note: This will be deprecated in favor of a rebootModemResponse API in Android U.
*/
void nvResetConfigResponse(in RadioResponseInfo info);
@@ -176,7 +176,8 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
+ *
+ * @deprecated NV APIs are deprecated starting from Android U.
*/
void nvWriteCdmaPrlResponse(in RadioResponseInfo info);
@@ -186,7 +187,8 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
+ *
+ * @deprecated NV APIs are deprecated starting from Android U.
*/
void nvWriteItemResponse(in RadioResponseInfo info);
@@ -200,7 +202,6 @@
* RadioError:NO_MEMORY
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -216,7 +217,6 @@
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -237,7 +237,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
* RadioError:INVALID_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -254,4 +253,20 @@
* RadioError:NO_RF_CALIBRATION_INFO
*/
void setRadioPowerResponse(in RadioResponseInfo info);
+
+ /**
+ * ImeiInfo to encapsulate the IMEI information from modem. When the return error code
+ * is {@code RadioError:NONE}, {@code imeiInfo} must be non-null, and a valid IMEITYPE,
+ * IMEI and SVN must be filled in {@code imeiInfo}. When the error code is not
+ * {@code RadioError:NONE}, {@code imeiInfo} must be {@code null}.
+ *
+ * @param responseInfo Response info struct containing response type, serial no. and error
+ * @param imeiInfo IMEI information
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ */
+ void getImeiResponse(in RadioResponseInfo responseInfo, in @nullable ImeiInfo imeiInfo);
}
diff --git a/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
new file mode 100644
index 0000000..2d25bb7
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.modem;
+
+/**
+ * ImeiInfo to encapsulate the IMEI information from modem
+ */
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable ImeiInfo {
+
+ @VintfStability
+ @Backing(type="int")
+ /**
+ * ImeiType enum is used identify the IMEI as primary or secondary as mentioned in GSMA TS.37
+ */
+ enum ImeiType {
+ /**
+ * This is the primary IMEI of the device as mentioned in the GSMA TS.37. In a multi-SIM
+ * device the modem must set one IMEI with this type as mentioned in GSMA TS37_2.2_REQ_8.
+ * A single SIM with one IMEI must by default set that IMEI with this type.
+ */
+ PRIMARY = 1,
+ /** This is not the primary IMEI of the device */
+ SECONDARY = 2,
+ }
+
+ /** Primary or secondary IMEI as mentioned in GSMA spec TS.37 */
+ ImeiType type;
+ /**
+ * IMEI value, see 3gpp spec 23.003 section 6. Note: This primary IMEI mapping must be
+ * permanent throughout the lifetime of the device irrespective of the factory data reset,
+ * SIM activations or swaps.
+ */
+ String imei;
+ /**
+ * IMEI software version, see 3gpp spec 23.003 section 6.
+ */
+ String svn;
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/modem/NvItem.aidl b/radio/aidl/android/hardware/radio/modem/NvItem.aidl
index 649b0d2..310b1ad 100644
--- a/radio/aidl/android/hardware/radio/modem/NvItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvItem.aidl
@@ -16,6 +16,7 @@
package android.hardware.radio.modem;
+/** @deprecated NV APIs are deprecated starting from Android U. */
@VintfStability
@Backing(type="int")
@JavaDerive(toString=true)
diff --git a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
index 47fb490..6472f23 100644
--- a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
@@ -18,6 +18,7 @@
import android.hardware.radio.modem.NvItem;
+/** @deprecated NV APIs are deprecated starting from Android U. */
@VintfStability
@JavaDerive(toString=true)
parcelable NvWriteItem {
diff --git a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
index 16487f8..6476fe8 100644
--- a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
@@ -16,6 +16,7 @@
package android.hardware.radio.modem;
+/** Note: This will be deprecated along with nvResetConfig in Android U. */
@VintfStability
@Backing(type="int")
@JavaDerive(toString=true)
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyMode.aidl b/radio/aidl/android/hardware/radio/network/EmergencyMode.aidl
new file mode 100644
index 0000000..25031a9
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum EmergencyMode {
+ /**
+ * Mode Type Emergency WWAN, indicates that the current domain selected for the Emergency call
+ * is cellular.
+ */
+ EMERGENCY_WWAN = 1,
+
+ /**
+ * Mode Type Emergency WLAN, indicates that the current domain selected for the Emergency call
+ * is WLAN/WIFI.
+ */
+ EMERGENCY_WLAN = 2,
+
+ /**
+ * Mode Type Emergency Callback, indicates that the current mode set request is for Emergency
+ * callback.
+ */
+ EMERGENCY_CALLBACK = 3,
+}
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
new file mode 100644
index 0000000..0a22e4c
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.network.EmergencyScanType;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable EmergencyNetworkScanTrigger{
+ /**
+ * Access network to be prioritized during emergency scan. The 1st entry has the highest
+ * priority.
+ */
+ AccessNetwork[] accessNetwork;
+
+ /**
+ * Scan type indicates the type of scans to be performed i.e. limited scan, full service scan or
+ * any scan.
+ */
+ EmergencyScanType scanType;
+}
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
new file mode 100644
index 0000000..2215149
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+import android.hardware.radio.AccessNetwork;
+import android.hardware.radio.network.Domain;
+import android.hardware.radio.network.RegState;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable EmergencyRegResult {
+ /**
+ * Indicates the cellular access network of the current emergency capable system.
+ */
+ AccessNetwork accessNetwork;
+
+ /**
+ * Registration state of the current emergency capable system.
+ */
+ RegState regState;
+
+ /**
+ * EMC domain indicates the current domain of the acquired system.
+ */
+ Domain emcDomain;
+
+ /**
+ * This indicates whether the network supports voice over PS network.
+ */
+ boolean isVopsSupported;
+
+ /**
+ * This indicates if camped network support VoLTE emergency bearers.
+ * This should only be set if the UE is in LTE mode.
+ */
+ boolean isEmcBearerSupported;
+
+ /**
+ * The value of the network provided EMC 5G Registration ACCEPT.
+ * This should be set only if the UE is in 5G mode.
+ */
+ byte nwProvidedEmc;
+
+ /**
+ * The value of the network provided EMF ( EPS Fallback) in 5G Registration ACCEPT.
+ * This should not be set if UE is not in 5G mode.
+ */
+ byte nwProvidedEmf;
+
+ /** 3-digit Mobile Country Code, 000..999, empty string if unknown. */
+ String mcc = "";
+
+ /** 2 or 3-digit Mobile Network Code, 00..999, empty string if unknown. */
+ String mnc = "";
+}
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyScanType.aidl b/radio/aidl/android/hardware/radio/network/EmergencyScanType.aidl
new file mode 100644
index 0000000..72c5490
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/EmergencyScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.network;
+
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum EmergencyScanType {
+ /**
+ * Scan Type No Preference, indicates that the modem can scan for emergency
+ * service as per modem’s implementation.
+ */
+ NO_PREFERENCE = 0,
+
+ /**
+ * Scan Type limited, indicates that the modem will scan for
+ * emergency service in limited service mode.
+ */
+ LIMITED_SERVICE = 1,
+
+ /**
+ * Scan Type Full Service, indicates that the modem will scan for
+ * emergency service in Full service mode.
+ */
+ FULL_SERVICE = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
index c9563ac..b986944 100644
--- a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -22,6 +22,21 @@
@VintfStability
@JavaDerive(toString=true)
parcelable EutranRegistrationInfo {
+ enum AttachResultType {
+ /** Default value. */
+ NONE,
+ /** LTE is attached with eps only. */
+ EPS_ONLY,
+ /** LTE combined EPS and IMSI attach. */
+ COMBINED,
+ }
+
+ /** LTE combined attach with CSFB not preferred */
+ const int EXTRA_CSFB_NOT_PREFERRED = 1 << 0;
+
+ /** LTE combined attach for SMS only */
+ const int EXTRA_SMS_ONLY = 1 << 1;
+
/**
* Network capabilities for voice over PS services. This info is valid only on LTE network and
* must be present when device is camped on LTE. VopsInfo must be empty when device is camped
@@ -33,4 +48,13 @@
* be empty.
*/
NrIndicators nrIndicators;
+
+ /**
+ * The type of network attachment. This info is valid only on LTE network and must be present
+ * when device has attached to the network.
+ */
+ AttachResultType lteAttachResultType;
+
+ /** Values are bitwise ORs of EXTRA_* constants */
+ int extraInfo;
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index cce52ff..f22cdb0 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -18,6 +18,8 @@
import android.hardware.radio.AccessNetwork;
import android.hardware.radio.network.CdmaRoamingType;
+import android.hardware.radio.network.EmergencyMode;
+import android.hardware.radio.network.EmergencyNetworkScanTrigger;
import android.hardware.radio.network.IRadioNetworkIndication;
import android.hardware.radio.network.IRadioNetworkResponse;
import android.hardware.radio.network.IndicationFilter;
@@ -110,6 +112,8 @@
* @param serial Serial number of request.
*
* Response function is IRadioNetworkResponse.getImsRegistrationStateResponse()
+ *
+ * @deprecated Deprecated starting from Android U.
*/
void getImsRegistrationState(in int serial);
@@ -437,4 +441,118 @@
* @param serial Serial number of request.
*/
oneway void getUsageSetting(in int serial);
+
+ /**
+ * Set the Emergency Mode
+ *
+ * @param serial Serial number of the request.
+ * @param emcModeType Defines the radio emergency mode type/radio network required/
+ * type of service to be scanned.
+ *
+ * Response function is IRadioEmergencyResponse.setEmergencyModeResponse()
+ */
+ void setEmergencyMode(int serial, in EmergencyMode emcModeType);
+
+ /**
+ * Triggers an Emergency network scan.
+ *
+ * @param serial Serial number of the request.
+ * @param request Contains the preferred networks and type of service to be scanned.
+ * See {@link EmergencyNetworkScanTrigger}.
+ *
+ * Response function is IRadioEmergencyResponse.triggerEmergencyNetworkScanResponse()
+ */
+ void triggerEmergencyNetworkScan(int serial, in EmergencyNetworkScanTrigger request);
+
+ /**
+ * Cancels ongoing Emergency network scan
+ *
+ * @param serial Serial number of the request.
+ * @param resetScan Indicates how the next {@link #triggerEmergencyNetworkScan} should work.
+ * If {@code true}, then the modem shall start the new scan from the beginning,
+ * otherwise the modem shall resume from the last search.
+ *
+ * Response function is IRadioEmergencyResponse.cancelEmergencyNetworkScan()
+ */
+ void cancelEmergencyNetworkScan(int serial, boolean resetScan);
+
+ /**
+ * Exits ongoing Emergency Mode
+ *
+ * @param serial Serial number of the request.
+ *
+ * Response function is IRadioEmergencyResponse.exitEmergencyModeResponse()
+ */
+ void exitEmergencyMode(in int serial);
+
+ /**
+ * Set if null encryption and integrity modes are enabled. If the value of enabled is false
+ * the modem must not allow any network communications with null ciphering (for both signalling
+ * and user data) or null integrity (for signalling) modes for 3G and above, even if the
+ * network only uses null algorithms. This setting must be respected even if
+ * "cipheringDisabled" (as defined in TS 38.331) is in use by the network.
+ *
+ * For 2G, which does not use integrity protection, the modem must only disallow any network
+ * communications with null ciphering.
+ *
+ * In the case when enabled is false, integrity protection for user data is optional, but
+ * ciphering for user data is required.
+ *
+ * In case of an emergency call, the modem must bypass this setting.
+ *
+ * Null ciphering and integrity modes include (but are not limited to):
+ * 2G: A5/0 and GEA0
+ * 3G: UEA0 and UIA0
+ * 4G: EEA0 and EIA0
+ * 5G: NEA0 and NIA0
+ *
+ *
+ * @param serial Serial number of the request.
+ * @param enabled To allow null encryption/integrity, set to true.
+ * Otherwise, false.
+ *
+ * Response callback is IRadioResponse.setNullCipherAndIntegrityEnabledResponse()
+ */
+ void setNullCipherAndIntegrityEnabled(in int serial, in boolean enabled);
+
+ /**
+ * Get whether null encryption and integrity modes are enabled.
+ *
+ * Null ciphering and integrity modes include, (but are not limited to):
+ * 2G: A5/0, GAE0 (no integrity algorithm supported)
+ * 3G: UEA0 and UIA0
+ * 4G: EEA0 and EIA
+ * 5G: NEA0 and NIA0
+ *
+ * @param serial Serial number of the request.
+ *
+ * Response callback is IRadioNetworkResponse.isNullCipherAndIntegrityEnabledResponse()
+ */
+ void isNullCipherAndIntegrityEnabled(in int serial);
+
+ /**
+ * Checks whether N1 mode (access to 5G core network) is enabled or not.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioNetworkResponse.isN1ModeEnabledResponse()
+ */
+ void isN1ModeEnabled(in int serial);
+
+ /**
+ * Enables or disables N1 mode (access to 5G core network) in accordance with
+ * 3GPP TS 24.501 4.9.
+ *
+ * Note: The default value of N1 mode shall be based on the modem's internal configuration
+ * as per device or carrier. This API may be invoked on demand first to disable N1 mode and
+ * later to re-enable for certain use case. This setting shall not be persisted by modem.
+ * This setting shall not interfere with the allowed network type bitmap set using
+ * {@link IRadioNetwork#setAllowedNetworkTypesBitmap()} API.
+ *
+ * @param serial Serial number of request.
+ * @param enable {@code true} to enable N1 mode, {@code false} to disable N1 mode.
+ *
+ * Response function is IRadioNetworkResponse.setN1ModeEnabledResponse()
+ */
+ void setN1ModeEnabled(in int serial, boolean enable);
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index f471433..47d932d 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -27,6 +27,7 @@
import android.hardware.radio.network.PhysicalChannelConfig;
import android.hardware.radio.network.SignalStrength;
import android.hardware.radio.network.SuppSvcNotification;
+import android.hardware.radio.network.EmergencyRegResult;
/**
* Interface declaring unsolicited radio indications for network APIs.
@@ -190,4 +191,12 @@
* @param rat Current new voice rat
*/
void voiceRadioTechChanged(in RadioIndicationType type, in RadioTechnology rat);
+
+ /**
+ * Emergency Scan Results.
+ *
+ * @param type Type of radio indication
+ * @param result the result of the Emergency Network Scan
+ */
+ void emergencyNetworkScanResult(in RadioIndicationType type, in EmergencyRegResult result);
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index dcf0004..457b5b9 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -23,6 +23,7 @@
import android.hardware.radio.network.CdmaRoamingType;
import android.hardware.radio.network.CellIdentity;
import android.hardware.radio.network.CellInfo;
+import android.hardware.radio.network.EmergencyRegResult;
import android.hardware.radio.network.OperatorInfo;
import android.hardware.radio.network.RadioAccessSpecifier;
import android.hardware.radio.network.RadioBandMode;
@@ -56,7 +57,6 @@
* RadioError:INTERNAL_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
*/
void getAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info, in int networkTypeBitmap);
@@ -73,7 +73,6 @@
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -92,7 +91,6 @@
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:CANCELLED
* RadioError:NO_RESOURCES
* RadioError:INTERNAL_ERR
@@ -125,7 +123,6 @@
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:SIM_ABSENT
@@ -169,7 +166,8 @@
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
+ *
+ * @deprecated Deprecated starting from Android U.
*/
void getImsRegistrationStateResponse(
in RadioResponseInfo info, in boolean isRegistered, in RadioTechnologyFamily ratFamily);
@@ -186,7 +184,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -204,7 +201,6 @@
* RadioError:NO_MEMORY
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -246,7 +242,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getVoiceRadioTechnologyResponse(in RadioResponseInfo info, in RadioTechnology rat);
@@ -271,7 +266,6 @@
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void isNrDualConnectivityEnabledResponse(in RadioResponseInfo info, in boolean isEnabled);
@@ -286,7 +280,6 @@
* RadioError:INTERNAL_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
*/
void setAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info);
@@ -303,7 +296,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -324,7 +316,6 @@
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
* RadioError:FDN_CHECK_FAILURE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -341,7 +332,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -361,7 +351,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void setCellInfoListRateResponse(in RadioResponseInfo info);
@@ -399,7 +388,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:SIM_ABSENT
@@ -419,7 +407,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*
@@ -442,7 +429,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*
@@ -458,7 +444,6 @@
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_STATE
*/
void setNrDualConnectivityStateResponse(in RadioResponseInfo info);
@@ -485,7 +470,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:SIM_ABSENT
@@ -542,7 +526,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void supplyNetworkDepersonalizationResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -572,4 +555,116 @@
* RadioError:SIM_ABSENT
*/
oneway void getUsageSettingResponse(in RadioResponseInfo info, in UsageSetting usageSetting);
+
+ /**
+ * Response of setEmergencyMode.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ * @param regState the current registration state of the modem.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ void setEmergencyModeResponse(in RadioResponseInfo info, in EmergencyRegResult regState);
+
+ /**
+ * Response of triggerEmergencyNetworkScan.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ * RadioError:INVALID_ARGUMENTS
+ */
+ void triggerEmergencyNetworkScanResponse(in RadioResponseInfo info);
+
+ /**
+ * Response of exitEmergencyMode.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ */
+ void exitEmergencyModeResponse(in RadioResponseInfo info);
+
+ /**
+ * Response of cancelEmergencyNetworkScan.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ */
+ void cancelEmergencyNetworkScanResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ void setNullCipherAndIntegrityEnabledResponse(in RadioResponseInfo info);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param enabled the last known state of null ciphering and integrity algorithms
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ void isNullCipherAndIntegrityEnabledResponse(in RadioResponseInfo info, in boolean isEnabled);
+
+ /**
+ * Response of isN1ModeEnabled.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ * @param isEnabled Indicates whether N1 mode is enabled or not.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ void isN1ModeEnabledResponse(in RadioResponseInfo info, boolean isEnabled);
+
+ /**
+ * Response of setN1ModeEnabled.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_STATE
+ */
+ void setN1ModeEnabledResponse(in RadioResponseInfo info);
}
diff --git a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
index 1bb569a..30ae067 100644
--- a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
@@ -71,4 +71,11 @@
* Range [0, 15], 0xFF means invalid/unreported.
*/
byte[] csiCqiReport;
+ /**
+ * Timing advance in micro seconds for a one way trip from cell to device. Approximate distance
+ * is calculated using 300m/us * timingAdvance. Range: 0 to 1282 inclusive.
+ * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value.
+ * Reference: 3GPP 36.213 section 4.2.3
+ */
+ int timingAdvance = 0x7FFFFFFF;
}
diff --git a/radio/aidl/android/hardware/radio/network/RegState.aidl b/radio/aidl/android/hardware/radio/network/RegState.aidl
index 3f13783..bdba4c4 100644
--- a/radio/aidl/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegState.aidl
@@ -65,4 +65,10 @@
* Same as UNKNOWN but indicates that emergency calls are enabled
*/
UNKNOWN_EM = 14,
+ /**
+ * Emergency attached in EPS or in 5GS.
+ * Reference: 3GPP TS 24.301 9.9.3.11 EPS attach type.
+ * Reference: 3GPP TS 24.501 9.11.3.6 5GS registration result.
+ */
+ REG_EM = 20,
}
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index 3d96b8c..f1d2972 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -33,9 +33,9 @@
*/
RegState regState;
/**
- * Indicates the radio technology (except LTE_CA, which is no longer a valid value), which
- * must not be UNKNOWN if regState is REG_HOME, REG_ROAMING, NOT_REG_MT_NOT_SEARCHING_OP_EM,
- * NOT_REG_MT_SEARCHING_OP_EM, REG_DENIED_EM, or UNKNOWN_EM.
+ * Indicates the radio technology, which must not be UNKNOWN if regState is REG_HOME,
+ * REG_ROAMING, NOT_REG_MT_NOT_SEARCHING_OP_EM, NOT_REG_MT_SEARCHING_OP_EM, REG_DENIED_EM,
+ * or UNKNOWN_EM.
* When the device is on carrier aggregation, vendor RIL service must properly report multiple
* PhysicalChannelConfig elements through IRadioNetwork::currentPhysicalChannelConfigs.
*/
diff --git a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
index 2f90180..0a8e9ce 100644
--- a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -82,7 +82,13 @@
* Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
*/
const int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
-
+ /**
+ * EcNo value
+ * Range: -24 dBm to 1 dBm.
+ * Used RAN: UTRAN
+ * Reference: 3GPP TS 25.215 5.1.5
+ */
+ const int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
/**
* Signal Measurement Type
* Values are SIGNAL_MEASUREMENT_TYPE_
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index a14cf7d..1419c51 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -16,6 +16,7 @@
package android.hardware.radio.sim;
+import android.hardware.radio.config.MultipleEnabledProfilesMode;
import android.hardware.radio.config.SlotPortMapping;
import android.hardware.radio.sim.AppStatus;
import android.hardware.radio.sim.PinState;
@@ -93,4 +94,8 @@
* PortId is the id (enumerated value) for the associated port available on the SIM.
*/
SlotPortMapping slotMap;
+ /**
+ * Jointly supported Multiple Enabled Profiles(MEP) mode as per SGP.22 V3.0
+ */
+ MultipleEnabledProfilesMode supportedMepMode = MultipleEnabledProfilesMode.NONE;
}
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index 3dce907..edbec2c 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -21,6 +21,22 @@
@VintfStability
@JavaDerive(toString=true)
parcelable CarrierRestrictions {
+ @VintfStability
+ @Backing(type="int")
+ /** This enum defines the carrier restriction status values */
+ enum CarrierRestrictionStatus {
+ /**
+ * Carrier restriction status value is unknown, used in cases where modem is dependent on
+ * external module to know about the lock status and the module hasn’t yet provided the lock
+ * status. For example, when the lock status is maintained on a cloud server and device has
+ * just booted after out of box and not yet connected to the internet.
+ */
+ UNKNOWN = 0,
+ /** There is no carrier restriction on the device */
+ NOT_RESTRICTED = 1,
+ /** The device is restricted to a carrier */
+ RESTRICTED = 2,
+ }
/**
* Allowed carriers
*/
@@ -40,4 +56,6 @@
* and not in the allowed list.
*/
boolean allowedCarriersPrioritized;
+ /** Current restriction status as defined in CarrierRestrictionStatus enum */
+ CarrierRestrictionStatus status;
}
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 7923b14..3823a71 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -26,6 +26,7 @@
import android.hardware.radio.sim.PersoSubstate;
import android.hardware.radio.sim.PhonebookRecordInfo;
import android.hardware.radio.sim.SelectUiccSub;
+import android.hardware.radio.sim.SessionInfo;
import android.hardware.radio.sim.SimApdu;
import android.hardware.radio.sim.SimLockMultiSimPolicy;
@@ -184,6 +185,8 @@
* @param channelId session id of the logical channel (+CCHC).
*
* Response function is IRadioSimResponse.iccCloseLogicalChannelResponse()
+ *
+ * @deprecated use iccCloseLogicalChannelWithSessionInfo instead.
*/
void iccCloseLogicalChannel(in int serial, in int channelId);
@@ -494,4 +497,19 @@
* Response function is IRadioSimResponse.updateSimPhonebookRecordsResponse()
*/
void updateSimPhonebookRecords(in int serial, in PhonebookRecordInfo recordInfo);
+
+ /**
+ * Close a previously opened logical channel. This command reflects TS 27.007
+ * "close logical channel" operation (+CCHC).
+ *
+ * Per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A. In order
+ * to close proper logical channel, should pass information about whether the logical channel
+ * was opened for sending ES10 commands or not.
+ *
+ * @param serial Serial number of request.
+ * @param sessionInfo Details of the opened logical channel info like sessionId and isEs10.
+ *
+ * Response function is IRadioSimResponse.iccCloseLogicalChannelWithSessionInfoResponse()
+ */
+ void iccCloseLogicalChannelWithSessionInfo(in int serial, in SessionInfo sessionInfo);
}
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index 750a29a..90f172f 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -65,7 +65,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_PUK2
*/
void changeIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -84,7 +83,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void changeIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -108,7 +106,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getAllowedCarriersResponse(in RadioResponseInfo info, in CarrierRestrictions carriers,
in SimLockMultiSimPolicy multiSimPolicy);
@@ -133,7 +130,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
* RadioError:NOT_PROVISIONED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:SIM_ABSENT
@@ -153,7 +149,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void getCdmaSubscriptionSourceResponse(
@@ -176,7 +171,6 @@
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
* RadioError:FDN_CHECK_FAILURE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -191,7 +185,6 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
* RadioError:NO_RESOURCES
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getIccCardStatusResponse(in RadioResponseInfo info, in CardStatus cardStatus);
@@ -208,7 +201,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_SIM_STATE
* RadioError:SIM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void getImsiForAppResponse(in RadioResponseInfo info, in String imsi);
@@ -219,13 +211,10 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API,
- * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM.
*/
void getSimPhonebookCapacityResponse(in RadioResponseInfo info, in PhonebookCapacity capacity);
@@ -235,13 +224,10 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
- * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API,
- * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM.
*/
void getSimPhonebookRecordsResponse(in RadioResponseInfo info);
@@ -255,7 +241,8 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
+ *
+ * @deprecated use iccCloseLogicalChannelWithSessionInfoResponse instead.
*/
void iccCloseLogicalChannelResponse(in RadioResponseInfo info);
@@ -274,7 +261,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_SIM_STATE
* RadioError:SIM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void iccIoForAppResponse(in RadioResponseInfo info, in IccIoResult iccIo);
@@ -296,7 +282,6 @@
* RadioError:SIM_ERR
* RadioError:INVALID_SIM_STATE
* RadioError:MISSING_RESOURCE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void iccOpenLogicalChannelResponse(
in RadioResponseInfo info, in int channelId, in byte[] selectResponse);
@@ -312,7 +297,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void iccTransmitApduBasicChannelResponse(in RadioResponseInfo info, in IccIoResult result);
@@ -327,7 +311,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void iccTransmitApduLogicalChannelResponse(in RadioResponseInfo info, in IccIoResult result);
@@ -341,7 +324,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void reportStkServiceIsRunningResponse(in RadioResponseInfo info);
@@ -359,7 +341,6 @@
* RadioError:INVALID_MODEM_STATE
* RadioError:SIM_ERR
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void requestIccSimAuthenticationResponse(in RadioResponseInfo info, in IccIoResult result);
@@ -379,7 +360,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void sendEnvelopeResponse(in RadioResponseInfo info, in String commandResponse);
@@ -397,7 +377,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void sendEnvelopeWithStatusResponse(in RadioResponseInfo info, in IccIoResult iccIo);
@@ -415,7 +394,6 @@
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void sendTerminalResponseToSimResponse(in RadioResponseInfo info);
@@ -427,7 +405,6 @@
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void setAllowedCarriersResponse(in RadioResponseInfo info);
@@ -435,12 +412,11 @@
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
- * RadioError:RIL_E_SUCCESS
- * RadioError:RIL_E_RADIO_NOT_AVAILABLE
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
* RadioError:SIM_ABSENT
- * RadioError:RIL_E_REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
- * RadioError:MODEM_INTERNAL_FAILURE
+ * RadioError:INTERNAL_FAILURE
*/
void setCarrierInfoForImsiEncryptionResponse(in RadioResponseInfo info);
@@ -456,7 +432,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void setCdmaSubscriptionSourceResponse(in RadioResponseInfo info);
@@ -477,7 +452,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_STATE
* RadioError:FDN_CHECK_FAILURE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -507,7 +481,6 @@
* RadioError:SYSTEM_ERR
* RadioError:MODEM_ERR
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -527,7 +500,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_PUK2
*/
void supplyIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -546,7 +518,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void supplyIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -564,7 +535,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void supplyIccPuk2ForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -582,7 +552,6 @@
* RadioError:CANCELLED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void supplyIccPukForAppResponse(in RadioResponseInfo info, in int remainingRetries);
@@ -603,7 +572,6 @@
* RadioError:MODEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:NO_RESOURCES
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void supplySimDepersonalizationResponse(
in RadioResponseInfo info, in PersoSubstate persoType, in int remainingRetries);
@@ -616,7 +584,6 @@
* Valid errors returned:
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:INVALID_SIM_STATE
* RadioError:MODEM_ERR
@@ -624,8 +591,19 @@
* RadioError:SIM_ERR
* RadioError:NO_SUCH_ENTRY
* RadioError:NO_RESOURCES
- * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API,
- * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM.
*/
void updateSimPhonebookRecordsResponse(in RadioResponseInfo info, in int updatedRecordIndex);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:NO_RESOURCES
+ * RadioError:CANCELLED
+ */
+ void iccCloseLogicalChannelWithSessionInfoResponse(in RadioResponseInfo info);
}
diff --git a/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
new file mode 100644
index 0000000..9e3e8ed
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+@VintfStability
+@JavaDerive(toString=true)
+parcelable SessionInfo {
+ /**
+ * Session id of the logical channel from TS 27.007 (+CCHC).
+ */
+ int sessionId;
+ /**
+ * Whether the logical channel was opened for sending ES10 commands.
+ */
+ boolean isEs10 = false;
+}
diff --git a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
index 43adbbc..9799f2b 100644
--- a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
@@ -49,4 +49,9 @@
* In hex string format ([a-fA-F0-9]*)
*/
String data;
+ /**
+ * isEs10 indicates that the current streaming APDU contains an ES10 command or it is a regular
+ * APDU. (As per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A1)
+ */
+ boolean isEs10 = false;
}
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index cf1b953..39e3ace 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -42,7 +42,6 @@
* RadioError:INVALID_CALL_ID
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -71,7 +70,6 @@
* RadioError:INVALID_STATE
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -92,7 +90,6 @@
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -122,7 +119,6 @@
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:ABORTED
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:CANCELLED
*/
@@ -163,7 +159,6 @@
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:SIM_ABSENT
@@ -185,7 +180,6 @@
* RadioError:INTERNAL_ERR
* RadioError:INVALID_CALL_ID
* RadioError:OPERATION_NOT_ALLOWED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -212,7 +206,6 @@
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
* RadioError:FDN_CHECK_FAILURE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SYSTEM_ERR
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -241,7 +234,6 @@
* RadioError:FDN_CHECK_FAILURE
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -260,7 +252,6 @@
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
* RadioError:FDN_CHECK_FAILURE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -282,7 +273,6 @@
* RadioError:INTERNAL_ERR
* RadioError:FDN_CHECK_FAILURE
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -298,7 +288,6 @@
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -344,7 +333,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:INTERNAL_ERR
* RadioError:MODEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -367,7 +355,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -386,7 +373,6 @@
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -404,7 +390,6 @@
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -423,7 +408,6 @@
* RadioError:INVALID_ARGUMENTS
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
void handleStkCallSetupRequestFromSimResponse(in RadioResponseInfo info);
@@ -442,7 +426,6 @@
* RadioError:INVALID_CALL_ID
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void hangupConnectionResponse(in RadioResponseInfo info);
@@ -461,7 +444,6 @@
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -482,7 +464,6 @@
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:CANCELLED
*/
void hangupWaitingOrBackgroundResponse(in RadioResponseInfo info);
@@ -497,7 +478,6 @@
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void isVoNrEnabledResponse(in RadioResponseInfo info, in boolean enable);
@@ -516,7 +496,6 @@
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -536,7 +515,6 @@
* RadioError:MODEM_ERR
* RadioError:INVALID_CALL_ID
* RadioError:INVALID_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
@@ -557,7 +535,6 @@
* RadioError:MODEM_ERR
* RadioError:INVALID_CALL_ID
* RadioError:INVALID_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -578,7 +555,6 @@
* RadioError:INVALID_CALL_ID
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
*/
@@ -603,7 +579,6 @@
* RadioError:ABORTED
* RadioError:SYSTEM_ERR
* RadioError:INVALID_STATE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -625,7 +600,6 @@
* RadioError:INTERNAL_ERR
* RadioError:INVALID_CALL_ID
* RadioError:OPERATION_NOT_ALLOWED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:CANCELLED
*/
@@ -647,7 +621,6 @@
* RadioError:INTERNAL_ERR
* RadioError:INVALID_STATE
* RadioError:FDN_CHECK_FAILURE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -670,7 +643,6 @@
* RadioError:INVALID_STATE
* RadioError:FDN_CHECK_FAILURE
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -690,7 +662,6 @@
* RadioError:NO_MEMORY
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -707,7 +678,6 @@
* RadioError:REQUEST_RATE_LIMITED
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -724,7 +694,6 @@
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_CALL_ID
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -742,7 +711,6 @@
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -758,7 +726,6 @@
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
- * RadioError:REQUEST_NOT_SUPPORTED
*/
void setVoNrEnabledResponse(in RadioResponseInfo info);
@@ -776,7 +743,6 @@
* RadioError:INTERNAL_ERR
* RadioError:INVALID_CALL_ID
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
*/
@@ -796,7 +762,6 @@
* RadioError:MODEM_ERR
* RadioError:INTERNAL_ERR
* RadioError:INVALID_CALL_ID
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:CANCELLED
* RadioError:INVALID_MODEM_STATE
*/
@@ -817,7 +782,6 @@
* RadioError:OPERATION_NOT_ALLOWED
* RadioError:INVALID_ARGUMENTS
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_MODEM_STATE
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index aa20fc3..5cf1378 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -31,18 +31,20 @@
"-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
shared_libs: [
- "android.hardware.radio.config-V1-ndk",
+ "android.hardware.radio.config-V2-ndk",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.radio.data-V1-ndk",
- "android.hardware.radio.messaging-V1-ndk",
- "android.hardware.radio.modem-V1-ndk",
- "android.hardware.radio.network-V1-ndk",
+ "android.hardware.radio.data-V2-ndk",
+ "android.hardware.radio.ims-V1-ndk",
+ "android.hardware.radio.ims.media-V1-ndk",
+ "android.hardware.radio.messaging-V2-ndk",
+ "android.hardware.radio.modem-V2-ndk",
+ "android.hardware.radio.network-V2-ndk",
"android.hardware.radio.sap-V1-ndk",
- "android.hardware.radio.sim-V1-ndk",
- "android.hardware.radio.voice-V1-ndk",
+ "android.hardware.radio.sim-V2-ndk",
+ "android.hardware.radio.voice-V2-ndk",
"[email protected]",
"[email protected]",
"[email protected]",
@@ -70,6 +72,11 @@
"data/RadioResponse-data.cpp",
"data/RadioData.cpp",
"data/structs.cpp",
+ "ims/RadioIndication-ims.cpp",
+ "ims/RadioResponse-ims.cpp",
+ "ims/RadioIms.cpp",
+ "ims/media/RadioImsMediaSession.cpp",
+ "ims/media/RadioImsMedia.cpp",
"messaging/RadioIndication-messaging.cpp",
"messaging/RadioMessaging.cpp",
"messaging/RadioResponse-messaging.cpp",
diff --git a/radio/aidl/compat/libradiocompat/data/structs.cpp b/radio/aidl/compat/libradiocompat/data/structs.cpp
index cc6dcbc..47f1f86 100644
--- a/radio/aidl/compat/libradiocompat/data/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/data/structs.cpp
@@ -137,7 +137,7 @@
.downlink = toAidl(qos.downlink),
.uplink = toAidl(qos.uplink),
.qfi = static_cast<int8_t>(qos.qfi),
- .averagingWindowMs = qos.averagingWindowMs,
+ .averagingWindowMillis = qos.averagingWindowMs,
};
}
diff --git a/radio/aidl/compat/libradiocompat/ims/RadioIms.cpp b/radio/aidl/compat/libradiocompat/ims/RadioIms.cpp
new file mode 100644
index 0000000..d2bdfff
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/RadioIms.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIms.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Ims"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::ims;
+constexpr auto ok = &ScopedAStatus::ok;
+
+std::shared_ptr<aidl::IRadioImsResponse> RadioIms::respond() {
+ return mCallbackManager->response().imsCb();
+}
+
+ScopedAStatus RadioIms::setSrvccCallInfo(
+ int32_t serial, const std::vector<aidl::SrvccCall>& /*srvccCalls*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " setSrvccCallInfo is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioIms::updateImsRegistrationInfo(
+ int32_t serial, const aidl::ImsRegistration& /*imsRegistration*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " updateImsRegistrationInfo is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioIms::startImsTraffic(
+ int32_t serial, int32_t /*token*/, aidl::ImsTrafficType /*imsTrafficType*/,
+ ::aidl::android::hardware::radio::AccessNetwork /*accessNetworkType*/,
+ ::aidl::android::hardware::radio::ims::ImsCall::Direction /*trafficDirection*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " startImsTraffic is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioIms::stopImsTraffic(int32_t serial, int32_t /*token*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " stopImsTraffic is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioIms::triggerEpsFallback(int32_t serial, aidl::EpsFallbackReason /*reason*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " triggerEpsFallback is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioIms::sendAnbrQuery(
+ int32_t serial, aidl::ImsStreamType /*mediaType*/, aidl::ImsStreamDirection /*direction*/,
+ int32_t /*bitsPerSecond*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " sendAnbrQuery is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioIms::updateImsCallStatus(
+ int32_t serial, const std::vector<aidl::ImsCall>& /*imsCalls*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " updateImsCallStatus is unsupported by HIDL HALs";
+ return ok();
+}
+
+ScopedAStatus RadioIms::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioImsResponse>& response,
+ const std::shared_ptr<aidl::IRadioImsIndication>& indication) {
+ LOG_CALL << response << ' ' << indication;
+ mCallbackManager->setResponseFunctions(response, indication);
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/RadioIndication-ims.cpp b/radio/aidl/compat/libradiocompat/ims/RadioIndication-ims.cpp
new file mode 100644
index 0000000..10109b8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/RadioIndication-ims.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsIndication"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::ims;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioImsIndication> imsCb) {
+ mImsCb = imsCb;
+}
+
+std::shared_ptr<aidl::IRadioImsIndication> RadioIndication::imsCb() {
+ return mImsCb.get();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/RadioResponse-ims.cpp b/radio/aidl/compat/libradiocompat/ims/RadioResponse-ims.cpp
new file mode 100644
index 0000000..831a0ae
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/RadioResponse-ims.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::ims;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioImsResponse> imsCb) {
+ mImsCb = imsCb;
+}
+
+std::shared_ptr<aidl::IRadioImsResponse> RadioResponse::imsCb() {
+ return mImsCb.get();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp
new file mode 100644
index 0000000..464a410
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMedia.cpp
@@ -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.
+ */
+
+#include <libradiocompat/RadioImsMedia.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsMedia"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioImsMedia::setListener(
+ const std::shared_ptr<::aidl::android::hardware::radio::ims::media::
+ IImsMediaListener>& /*in_mediaListener*/) {
+ LOG(ERROR) << " setListener is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMedia::openSession(
+ int32_t /*in_sessionId*/,
+ const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& /*in_localEndPoint*/,
+ const ::aidl::android::hardware::radio::ims::media::RtpConfig& /*in_config*/) {
+ LOG(ERROR) << " openSession is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMedia::closeSession(int32_t /*in_sessionId*/) {
+ LOG(ERROR) << " closeSession is unsupported by HIDL HALs";
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp
new file mode 100644
index 0000000..ae86914
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/ims/media/RadioImsMediaSession.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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 <libradiocompat/RadioImsMediaSession.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ImsMediaSession"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::ims::media;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioImsMediaSession::setListener(
+ const std::shared_ptr<aidl::IImsMediaSessionListener>& /*in_sessionListener*/) {
+ LOG(ERROR) << " setListener is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMediaSession::modifySession(const aidl::RtpConfig& /*in_config*/) {
+ LOG(ERROR) << " modifySession is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMediaSession::sendDtmf(char16_t /*in_dtmfDigit*/, int32_t /*in_duration*/) {
+ LOG(ERROR) << " sendDtmf is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMediaSession::startDtmf(char16_t /*in_dtmfDigit*/) {
+ LOG(ERROR) << " startDtmf is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMediaSession::stopDtmf() {
+ LOG(ERROR) << " stopDtmf is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMediaSession::sendHeaderExtension(
+ const std::vector<aidl::RtpHeaderExtension>& /*in_extensions*/) {
+ LOG(ERROR) << " sendHeaderExtension is unsupported by HIDL HALs";
+ return ok();
+}
+ScopedAStatus RadioImsMediaSession::setMediaQualityThreshold(
+ const aidl::MediaQualityThreshold& /*in_threshold*/) {
+ LOG(ERROR) << " setMediaQualityThreshold is unsupported by HIDL HALs";
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIms.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIms.h
new file mode 100644
index 0000000..0dbc565
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIms.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/ims/BnRadioIms.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioIms : public RadioCompatBase, public aidl::android::hardware::radio::ims::BnRadioIms {
+ ::ndk::ScopedAStatus setSrvccCallInfo(
+ int32_t serial,
+ const std::vector<::aidl::android::hardware::radio::ims::SrvccCall>& srvccCalls)
+ override;
+ ::ndk::ScopedAStatus updateImsRegistrationInfo(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::ims::ImsRegistration& imsRegistration) override;
+ ::ndk::ScopedAStatus startImsTraffic(
+ int32_t serial, int32_t token,
+ ::aidl::android::hardware::radio::ims::ImsTrafficType imsTrafficType,
+ ::aidl::android::hardware::radio::AccessNetwork accessNetworkType,
+ ::aidl::android::hardware::radio::ims::ImsCall::Direction trafficDirection) override;
+ ::ndk::ScopedAStatus stopImsTraffic(int32_t serial, int32_t token) override;
+ ::ndk::ScopedAStatus triggerEpsFallback(
+ int32_t serial,
+ ::aidl::android::hardware::radio::ims::EpsFallbackReason reason) override;
+ ::ndk::ScopedAStatus sendAnbrQuery(
+ int32_t serial, ::aidl::android::hardware::radio::ims::ImsStreamType mediaType,
+ ::aidl::android::hardware::radio::ims::ImsStreamDirection direction,
+ int32_t bitsPerSecond) override;
+ ::ndk::ScopedAStatus updateImsCallStatus(
+ int32_t serial,
+ const std::vector<::aidl::android::hardware::radio::ims::ImsCall>& imsCalls) override;
+
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse>&
+ radioImsResponse,
+ const std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsIndication>&
+ radioImsIndication) override;
+
+ protected:
+ std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse> respond();
+
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h
new file mode 100644
index 0000000..2ee6bf1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMedia.h
@@ -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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/ims/media/BnImsMedia.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioImsMedia : public RadioCompatBase,
+ public aidl::android::hardware::radio::ims::media::BnImsMedia {
+ ::ndk::ScopedAStatus setListener(
+ const std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaListener>&
+ in_mediaListener) override;
+ ::ndk::ScopedAStatus openSession(
+ int32_t in_sessionId,
+ const ::aidl::android::hardware::radio::ims::media::LocalEndPoint& in_localEndPoint,
+ const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override;
+ ::ndk::ScopedAStatus closeSession(int32_t in_sessionId) override;
+
+ protected:
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.h
new file mode 100644
index 0000000..00f21fc
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioImsMediaSession.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 "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/ims/media/BnImsMediaSession.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioImsMediaSession : public RadioCompatBase,
+ public aidl::android::hardware::radio::ims::media::BnImsMediaSession {
+ ::ndk::ScopedAStatus setListener(
+ const std::shared_ptr<
+ ::aidl::android::hardware::radio::ims::media::IImsMediaSessionListener>&
+ in_sessionListener) override;
+ ::ndk::ScopedAStatus modifySession(
+ const ::aidl::android::hardware::radio::ims::media::RtpConfig& in_config) override;
+ ::ndk::ScopedAStatus sendDtmf(char16_t in_dtmfDigit, int32_t in_duration) override;
+ ::ndk::ScopedAStatus startDtmf(char16_t in_dtmfDigit) override;
+ ::ndk::ScopedAStatus stopDtmf() override;
+ ::ndk::ScopedAStatus sendHeaderExtension(
+ const std::vector<::aidl::android::hardware::radio::ims::media::RtpHeaderExtension>&
+ in_extensions) override;
+ ::ndk::ScopedAStatus setMediaQualityThreshold(
+ const ::aidl::android::hardware::radio::ims::media::MediaQualityThreshold& in_threshold)
+ override;
+
+ protected:
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
index 6cfd59c..f042456 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -19,6 +19,7 @@
#include "GuaranteedCallback.h"
#include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
+#include <aidl/android/hardware/radio/ims/IRadioImsIndication.h>
#include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
#include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
#include <aidl/android/hardware/radio/network/IRadioNetworkIndication.h>
@@ -55,6 +56,10 @@
::aidl::android::hardware::radio::voice::IRadioVoiceIndication,
::aidl::android::hardware::radio::voice::IRadioVoiceIndicationDefault, true>
mVoiceCb;
+ GuaranteedCallback< //
+ ::aidl::android::hardware::radio::ims::IRadioImsIndication,
+ ::aidl::android::hardware::radio::ims::IRadioImsIndicationDefault, true>
+ mImsCb;
// IRadioIndication @ 1.0
Return<void> radioStateChanged(V1_0::RadioIndicationType type,
@@ -220,6 +225,8 @@
std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
void setResponseFunction(
std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsIndication> imsCb);
std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb();
std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
@@ -228,6 +235,7 @@
std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> networkCb();
std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb();
std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voiceCb();
+ std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsIndication> imsCb();
};
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
index beb1fb0..54bedd8 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -26,6 +26,7 @@
::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
+ ::ndk::ScopedAStatus getImei(int32_t serial) override;
::ndk::ScopedAStatus getHardwareConfig(int32_t serial) override;
::ndk::ScopedAStatus getModemActivityInfo(int32_t serial) override;
::ndk::ScopedAStatus getModemStackStatus(int32_t serial) override;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index 9784665..d57c83d 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -18,6 +18,9 @@
#include "RadioCompatBase.h"
#include <aidl/android/hardware/radio/network/BnRadioNetwork.h>
+#include <aidl/android/hardware/radio/network/IRadioNetwork.h>
+
+// using namespace aidl::android::hardware::radio::network;
namespace android::hardware::radio::compat {
@@ -90,6 +93,21 @@
::aidl::android::hardware::radio::network::UsageSetting usageSetting) override;
::ndk::ScopedAStatus getUsageSetting(int32_t serial) override;
+ ::ndk::ScopedAStatus setEmergencyMode(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::network::EmergencyMode emergencyMode) override;
+ ::ndk::ScopedAStatus triggerEmergencyNetworkScan(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::network::EmergencyNetworkScanTrigger&
+ scanTrigger) override;
+ ::ndk::ScopedAStatus cancelEmergencyNetworkScan(int32_t serial, bool resetScan) override;
+ ::ndk::ScopedAStatus exitEmergencyMode(int32_t serial) override;
+ ::ndk::ScopedAStatus isN1ModeEnabled(int32_t serial) override;
+ ::ndk::ScopedAStatus setN1ModeEnabled(int32_t serial, bool enable) override;
+
+ ::ndk::ScopedAStatus setNullCipherAndIntegrityEnabled(int32_t serial, bool enabled) override;
+ ::ndk::ScopedAStatus isNullCipherAndIntegrityEnabled(int32_t serial) override;
+
protected:
std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> respond();
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
index 1f82dd1..e20eed9 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -19,6 +19,8 @@
#include "GuaranteedCallback.h"
#include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
+#include <aidl/android/hardware/radio/ims/IRadioImsResponse.h>
+#include <aidl/android/hardware/radio/ims/media/IImsMediaListener.h>
#include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
#include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
#include <aidl/android/hardware/radio/network/IRadioNetworkResponse.h>
@@ -49,6 +51,9 @@
GuaranteedCallback<::aidl::android::hardware::radio::voice::IRadioVoiceResponse,
::aidl::android::hardware::radio::voice::IRadioVoiceResponseDefault>
mVoiceCb;
+ GuaranteedCallback<::aidl::android::hardware::radio::ims::IRadioImsResponse,
+ ::aidl::android::hardware::radio::ims::IRadioImsResponseDefault>
+ mImsCb;
// IRadioResponse @ 1.0
Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
@@ -440,6 +445,8 @@
std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
void setResponseFunction(
std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse> imsCb);
std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb();
std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
@@ -448,6 +455,7 @@
std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> networkCb();
std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb();
std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb();
+ std::shared_ptr<::aidl::android::hardware::radio::ims::IRadioImsResponse> imsCb();
};
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
index ff91aef..f12e532 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -41,6 +41,8 @@
::ndk::ScopedAStatus getSimPhonebookCapacity(int32_t serial) override;
::ndk::ScopedAStatus getSimPhonebookRecords(int32_t serial) override;
::ndk::ScopedAStatus iccCloseLogicalChannel(int32_t serial, int32_t channelId) override;
+ ::ndk::ScopedAStatus iccCloseLogicalChannelWithSessionInfo(int32_t serial,
+ const ::aidl::android::hardware::radio::sim::SessionInfo& recordInfo) override;
::ndk::ScopedAStatus iccIoForApp(
int32_t serial, const ::aidl::android::hardware::radio::sim::IccIo& iccIo) override;
::ndk::ScopedAStatus iccOpenLogicalChannel(int32_t serial, const std::string& aid,
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
index d28b940..f088b10 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -15,7 +15,7 @@
*/
#include <libradiocompat/RadioModem.h>
-
+#include "commonStructs.h"
#include "debug.h"
#include "structs.h"
@@ -49,6 +49,13 @@
return ok();
}
+ScopedAStatus RadioModem::getImei(int32_t serial) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " getImei is unsupported by HIDL HALs";
+ respond()->getImeiResponse(notSupported(serial), {});
+ return ok();
+}
+
ScopedAStatus RadioModem::getHardwareConfig(int32_t serial) {
LOG_CALL << serial;
mHal1_5->getHardwareConfig(serial);
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index d5e2a8d..a379eec 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -261,6 +261,11 @@
if (infos.size() > 1) {
LOG(WARNING) << "Multi-element reporting criteria are not supported with HIDL HAL";
}
+ if (infos[0].signalMeasurement == aidl::SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_ECNO) {
+ LOG(WARNING) << "SIGNAL_MEASUREMENT_TYPE_ECNO are not supported with HIDL HAL";
+ respond()->setSignalStrengthReportingCriteriaResponse(notSupported(serial));
+ return ok();
+ }
mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
V1_5::AccessNetwork(infos[0].ran));
return ok();
@@ -311,4 +316,60 @@
return ok();
}
+ScopedAStatus RadioNetwork::setEmergencyMode(int32_t serial, aidl::EmergencyMode) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " setEmergencyMode is unsupported by HIDL HALs";
+ respond()->setEmergencyModeResponse(notSupported(serial), {});
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::triggerEmergencyNetworkScan(int32_t serial,
+ const aidl::EmergencyNetworkScanTrigger&) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " triggerEmergencyNetworkScan is unsupported by HIDL HALs";
+ respond()->triggerEmergencyNetworkScanResponse(notSupported(serial));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::cancelEmergencyNetworkScan(int32_t serial, bool) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " cancelEmergencyNetworkScan is unsupported by HIDL HALs";
+ respond()->cancelEmergencyNetworkScanResponse(notSupported(serial));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::exitEmergencyMode(int32_t serial) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " exitEmergencyMode is unsupported by HIDL HALs";
+ respond()->exitEmergencyModeResponse(notSupported(serial));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setNullCipherAndIntegrityEnabled(int32_t serial, bool) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " setNullCipherAndIntegrityEnabled is unsupported by HIDL HALs";
+ respond()->setNullCipherAndIntegrityEnabledResponse(notSupported(serial));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::isNullCipherAndIntegrityEnabled(int32_t serial) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " isNullCipherAndIntegrityEnabled is unsupported by HIDL HALs";
+ respond()->isNullCipherAndIntegrityEnabledResponse(notSupported(serial), true);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::isN1ModeEnabled(int32_t serial) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " isN1ModeEnabled is unsupported by HIDL HALs";
+ respond()->isN1ModeEnabledResponse(notSupported(serial), false);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setN1ModeEnabled(int32_t serial, bool /*enable*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " setN1ModeEnabled is unsupported by HIDL HALs";
+ respond()->setN1ModeEnabledResponse(notSupported(serial));
+ return ok();
+}
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
index b43f64f..490b07b 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -124,6 +124,14 @@
return ok();
}
+ScopedAStatus RadioSim::iccCloseLogicalChannelWithSessionInfo(int32_t serial,
+ const aidl::SessionInfo& /*SessionInfo*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " iccCloseLogicalChannelWithSessionInfo is unsupported by HIDL HALs";
+ respond()->iccCloseLogicalChannelWithSessionInfoResponse(notSupported(serial));
+ return ok();
+}
+
ScopedAStatus RadioSim::iccIoForApp(int32_t serial, const aidl::IccIo& iccIo) {
LOG_CALL << serial;
mHal1_5->iccIOForApp(serial, toHidl(iccIo));
@@ -289,5 +297,4 @@
}
return ok();
}
-
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp
index 933e3e1..dff0182 100644
--- a/radio/aidl/compat/service/Android.bp
+++ b/radio/aidl/compat/service/Android.bp
@@ -34,18 +34,20 @@
],
shared_libs: [
"android.hardware.radio-library.compat",
- "android.hardware.radio.config-V1-ndk",
+ "android.hardware.radio.config-V2-ndk",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.radio.data-V1-ndk",
- "android.hardware.radio.messaging-V1-ndk",
- "android.hardware.radio.modem-V1-ndk",
- "android.hardware.radio.network-V1-ndk",
+ "android.hardware.radio.data-V2-ndk",
+ "android.hardware.radio.ims-V1-ndk",
+ "android.hardware.radio.ims.media-V1-ndk",
+ "android.hardware.radio.messaging-V2-ndk",
+ "android.hardware.radio.modem-V2-ndk",
+ "android.hardware.radio.network-V2-ndk",
"android.hardware.radio.sap-V1-ndk",
- "android.hardware.radio.sim-V1-ndk",
- "android.hardware.radio.voice-V1-ndk",
+ "android.hardware.radio.sim-V2-ndk",
+ "android.hardware.radio.voice-V2-ndk",
"[email protected]",
"[email protected]",
"[email protected]",
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index 97964b4..e79d3c0 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -41,6 +41,12 @@
"radio_data_indication.cpp",
"radio_data_response.cpp",
"radio_data_test.cpp",
+ "radio_ims_indication.cpp",
+ "radio_ims_response.cpp",
+ "radio_ims_test.cpp",
+ "radio_imsmedia_listener.cpp",
+ "radio_imsmedia_session_listener.cpp",
+ "radio_imsmedia_test.cpp",
"radio_messaging_indication.cpp",
"radio_messaging_response.cpp",
"radio_messaging_test.cpp",
@@ -65,15 +71,17 @@
"libvintf",
],
static_libs: [
- "android.hardware.radio-V1-ndk",
- "android.hardware.radio.config-V1-ndk",
- "android.hardware.radio.data-V1-ndk",
- "android.hardware.radio.messaging-V1-ndk",
- "android.hardware.radio.modem-V1-ndk",
- "android.hardware.radio.network-V1-ndk",
+ "android.hardware.radio-V2-ndk",
+ "android.hardware.radio.config-V2-ndk",
+ "android.hardware.radio.data-V2-ndk",
+ "android.hardware.radio.ims-V1-ndk",
+ "android.hardware.radio.ims.media-V1-ndk",
+ "android.hardware.radio.messaging-V2-ndk",
+ "android.hardware.radio.modem-V2-ndk",
+ "android.hardware.radio.network-V2-ndk",
"android.hardware.radio.sap-V1-ndk",
- "android.hardware.radio.sim-V1-ndk",
- "android.hardware.radio.voice-V1-ndk",
+ "android.hardware.radio.sim-V2-ndk",
+ "android.hardware.radio.voice-V2-ndk",
],
test_suites: [
"general-tests",
diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
index ccd4427..c04173b 100644
--- a/radio/aidl/vts/VtsHalRadioTargetTest.cpp
+++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
@@ -18,6 +18,8 @@
#include "radio_config_utils.h"
#include "radio_data_utils.h"
+#include "radio_ims_utils.h"
+#include "radio_imsmedia_utils.h"
#include "radio_messaging_utils.h"
#include "radio_modem_utils.h"
#include "radio_network_utils.h"
@@ -71,6 +73,17 @@
testing::ValuesIn(android::getAidlHalInstanceNames(IRadioVoice::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioImsTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, RadioImsTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IRadioIms::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioImsMediaTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioImsMediaTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IImsMedia::descriptor)),
+ android::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
index 8170a01..d515e1a 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.h
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -67,6 +67,8 @@
static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+static constexpr const char* FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";
+
#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
#define MODEM_SET_SIM_POWER_DELAY_IN_SECONDS 2
diff --git a/radio/aidl/vts/radio_ims_indication.cpp b/radio/aidl/vts/radio_ims_indication.cpp
new file mode 100644
index 0000000..988038b
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_indication.cpp
@@ -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.
+ */
+
+#include "radio_ims_utils.h"
+
+RadioImsIndication::RadioImsIndication(RadioServiceTest& parent) : parent_ims(parent) {}
+
+ndk::ScopedAStatus RadioImsIndication::onConnectionSetupFailure(RadioIndicationType /*type*/,
+ int32_t /*token*/, const ConnectionFailureInfo& /*info*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsIndication::notifyAnbr(RadioIndicationType /*type*/,
+ ImsStreamType /*mediaType*/, ImsStreamDirection /*direction*/, int /*bitsPerSecond*/) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsIndication::triggerImsDeregistration(RadioIndicationType /*type*/,
+ ImsDeregistrationReason /*reason*/) {
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_ims_response.cpp b/radio/aidl/vts/radio_ims_response.cpp
new file mode 100644
index 0000000..c6d62dc
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_response.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_ims_utils.h"
+
+RadioImsResponse::RadioImsResponse(RadioServiceTest& parent) : parent_ims(parent) {}
+
+ndk::ScopedAStatus RadioImsResponse::setSrvccCallInfoResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::updateImsRegistrationInfoResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::startImsTrafficResponse(const RadioResponseInfo& info,
+ const std::optional<ConnectionFailureInfo>& response) {
+ rspInfo = info;
+ startImsTrafficResp = response;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::stopImsTrafficResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::triggerEpsFallbackResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::sendAnbrQueryResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioImsResponse::updateImsCallStatusResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_ims.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_ims_test.cpp b/radio/aidl/vts/radio_ims_test.cpp
new file mode 100644
index 0000000..289d3ed
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_test.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_ims_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioImsTest::SetUp() {
+ std::string serviceName = GetParam();
+
+ if (!isServiceValidForDeviceConfiguration(serviceName)) {
+ ALOGI("Skipped the test due to device configuration.");
+ GTEST_SKIP();
+ }
+
+ radio_ims = IRadioIms::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(nullptr, radio_ims.get());
+
+ radioRsp_ims = ndk::SharedRefBase::make<RadioImsResponse>(*this);
+ ASSERT_NE(nullptr, radioRsp_ims.get());
+
+ count_ = 0;
+
+ radioInd_ims = ndk::SharedRefBase::make<RadioImsIndication>(*this);
+ ASSERT_NE(nullptr, radioInd_ims.get());
+
+ radio_ims->setResponseFunctions(radioRsp_ims, radioInd_ims);
+
+ // Assert IRadioConfig exists before testing
+ radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+ AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+ ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioIms.setSrvccCallInfo() for the response returned.
+ */
+TEST_P(RadioImsTest, setSrvccCallInfo) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping setSrvccCallInfo because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running setSrvccCallInfo because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ SrvccCall srvccCall;
+
+ ndk::ScopedAStatus res =
+ radio_ims->setSrvccCallInfo(serial, { srvccCall });
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("setSrvccCallInfo, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.updateImsRegistrationInfo() for the response returned.
+ */
+TEST_P(RadioImsTest, updateImsRegistrationInfo) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping updateImsRegistrationInfo because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running updateImsRegistrationInfo because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ImsRegistration regInfo;
+ regInfo.regState = ImsRegistrationState::NOT_REGISTERED;
+ regInfo.accessNetworkType = AccessNetwork::EUTRAN;
+ regInfo.suggestedAction = SuggestedAction::NONE;
+ regInfo.capabilities = ImsRegistration::IMS_MMTEL_CAPABILITY_NONE;
+
+ ndk::ScopedAStatus res =
+ radio_ims->updateImsRegistrationInfo(serial, regInfo);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("updateImsRegistrationInfo, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.startImsTraffic() for the response returned.
+ */
+TEST_P(RadioImsTest, startImsTraffic) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping startImsTraffic because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running startImsTraffic because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res =
+ radio_ims->startImsTraffic(serial, 1,
+ ImsTrafficType::REGISTRATION, AccessNetwork::EUTRAN, ImsCall::Direction::OUTGOING);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("startImsTraffic, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.stopImsTraffic() for the response returned.
+ */
+TEST_P(RadioImsTest, stopImsTraffic) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping stopImsTraffic because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running stopImsTraffic because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_ims->stopImsTraffic(serial, 2);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("stopImsTraffic, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.triggerEpsFallback() for the response returned.
+ */
+TEST_P(RadioImsTest, triggerEpsFallback) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping triggerEpsFallback because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running triggerEpsFallback because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res =
+ radio_ims->triggerEpsFallback(serial, EpsFallbackReason::NO_NETWORK_TRIGGER);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("triggerEpsFallback, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.sendAnbrQuery() for the response returned.
+ */
+TEST_P(RadioImsTest, sendAnbrQuery) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping sendAnbrQuery because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running sendAnbrQuery because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res =
+ radio_ims->sendAnbrQuery(serial, ImsStreamType::AUDIO, ImsStreamDirection::UPLINK, 13200);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("sendAnbrQuery, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+/*
+ * Test IRadioIms.updateImsCallStatus() for the response returned.
+ */
+TEST_P(RadioImsTest, updateImsCallStatus) {
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping updateImsCallStatus because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running updateImsCallStatus because ims is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ImsCall imsCall;
+
+ ndk::ScopedAStatus res =
+ radio_ims->updateImsCallStatus(serial, { imsCall });
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_ims->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_ims->rspInfo.serial);
+
+ ALOGI("updateImsCallStatus, rspInfo.error = %s\n",
+ toString(radioRsp_ims->rspInfo.error).c_str());
+
+ verifyError(radioRsp_ims->rspInfo.error);
+}
+
+void RadioImsTest::verifyError(RadioError resp) {
+ switch (resp) {
+ case RadioError::NONE:
+ case RadioError::RADIO_NOT_AVAILABLE:
+ case RadioError::INVALID_STATE:
+ case RadioError::NO_MEMORY:
+ case RadioError::SYSTEM_ERR:
+ case RadioError::MODEM_ERR:
+ case RadioError::INTERNAL_ERR:
+ case RadioError::INVALID_ARGUMENTS:
+ case RadioError::NO_RESOURCES:
+ SUCCEED();
+ break;
+ default:
+ FAIL();
+ break;
+ }
+}
diff --git a/radio/aidl/vts/radio_ims_utils.h b/radio/aidl/vts/radio_ims_utils.h
new file mode 100644
index 0000000..2bf80dc
--- /dev/null
+++ b/radio/aidl/vts/radio_ims_utils.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/ims/BnRadioImsIndication.h>
+#include <aidl/android/hardware/radio/ims/BnRadioImsResponse.h>
+#include <aidl/android/hardware/radio/ims/IRadioIms.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::ims;
+
+class RadioImsTest;
+
+/* Callback class for radio ims response */
+class RadioImsResponse : public BnRadioImsResponse {
+ protected:
+ RadioServiceTest& parent_ims;
+
+ public:
+ RadioImsResponse(RadioServiceTest& parent_ims);
+ virtual ~RadioImsResponse() = default;
+
+ RadioResponseInfo rspInfo;
+ std::optional<ConnectionFailureInfo> startImsTrafficResp;
+
+ virtual ndk::ScopedAStatus setSrvccCallInfoResponse(const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus updateImsRegistrationInfoResponse(
+ const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus startImsTrafficResponse(
+ const RadioResponseInfo& info,
+ const std::optional<ConnectionFailureInfo>& response) override;
+
+ virtual ndk::ScopedAStatus stopImsTrafficResponse(const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus triggerEpsFallbackResponse(const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus sendAnbrQueryResponse(const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus updateImsCallStatusResponse(const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio ims indication */
+class RadioImsIndication : public BnRadioImsIndication {
+ protected:
+ RadioServiceTest& parent_ims;
+
+ public:
+ RadioImsIndication(RadioServiceTest& parent_ims);
+ virtual ~RadioImsIndication() = default;
+
+ virtual ndk::ScopedAStatus onConnectionSetupFailure(RadioIndicationType type,
+ int32_t token, const ConnectionFailureInfo& info) override;
+
+ virtual ndk::ScopedAStatus notifyAnbr(RadioIndicationType type, ImsStreamType mediaType,
+ ImsStreamDirection direction, int bitsPerSecond) override;
+
+ virtual ndk::ScopedAStatus triggerImsDeregistration(RadioIndicationType type,
+ ImsDeregistrationReason reason) override;
+};
+
+// The main test class for Radio AIDL Ims.
+class RadioImsTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+ protected:
+ virtual void verifyError(RadioError resp);
+
+ public:
+ virtual void SetUp() override;
+
+ /* radio ims service handle */
+ std::shared_ptr<IRadioIms> radio_ims;
+ /* radio ims response handle */
+ std::shared_ptr<RadioImsResponse> radioRsp_ims;
+ /* radio ims indication handle */
+ std::shared_ptr<RadioImsIndication> radioInd_ims;
+};
diff --git a/radio/aidl/vts/radio_imsmedia_listener.cpp b/radio/aidl/vts/radio_imsmedia_listener.cpp
new file mode 100644
index 0000000..78f66a9
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_listener.cpp
@@ -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.
+ */
+
+#include "radio_imsmedia_utils.h"
+
+ImsMediaListener::ImsMediaListener(RadioServiceTest& parent) : parent_imsmedia(parent) {}
+
+ndk::ScopedAStatus ImsMediaListener::onOpenSessionSuccess(
+ int32_t in_sessionId, const std::shared_ptr<IImsMediaSession>& in_session) {
+ mSessionId = in_sessionId;
+ mSession = in_session;
+ parent_imsmedia.notify(SERIAL_OPEN_SESSION);
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaListener::onOpenSessionFailure(int32_t in_sessionId, RtpError in_error) {
+ mSessionId = in_sessionId;
+ mError = in_error;
+ parent_imsmedia.notify(SERIAL_OPEN_SESSION);
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaListener::onSessionClosed(int32_t in_sessionId) {
+ mSessionId = in_sessionId;
+ parent_imsmedia.notify(SERIAL_CLOSE_SESSION);
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_imsmedia_session_listener.cpp b/radio/aidl/vts/radio_imsmedia_session_listener.cpp
new file mode 100644
index 0000000..986cab2
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_session_listener.cpp
@@ -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.
+ */
+
+#include "radio_imsmedia_utils.h"
+
+ImsMediaSessionListener::ImsMediaSessionListener(RadioServiceTest& parent)
+ : parent_imsmedia(parent) {}
+
+ndk::ScopedAStatus ImsMediaSessionListener::onModifySessionResponse(const RtpConfig& in_config,
+ RtpError in_error) {
+ mConfig = in_config;
+ mError = in_error;
+ parent_imsmedia.notify(SERIAL_MODIFY_SESSION);
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onFirstMediaPacketReceived(
+ const RtpConfig& /*in_config*/) {
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onHeaderExtensionReceived(
+ const std::vector<RtpHeaderExtension>& /*in_extensions*/) {
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::notifyMediaQualityStatus(
+ const MediaQualityStatus& /*in_quality*/) {
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::triggerAnbrQuery(const RtpConfig& /*in_config*/) {
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onDtmfReceived(char16_t /*in_dtmfDigit*/,
+ int32_t /*in_durationMs*/) {
+ return ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus ImsMediaSessionListener::onCallQualityChanged(
+ const CallQuality& /*in_callQuality*/) {
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_imsmedia_test.cpp b/radio/aidl/vts/radio_imsmedia_test.cpp
new file mode 100644
index 0000000..2b6f5ef
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_test.cpp
@@ -0,0 +1,281 @@
+/*
+ * 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/radio/ims/media/MediaDirection.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <sys/socket.h>
+
+#include "radio_imsmedia_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioImsMediaTest::SetUp() {
+ std::string serviceName = GetParam();
+
+ ALOGD("Enter RadioImsMediaTest.");
+
+ radio_imsmedia = IImsMedia::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(nullptr, radio_imsmedia.get());
+
+ radio_imsmedialistener = ndk::SharedRefBase::make<ImsMediaListener>(*this);
+ ASSERT_NE(nullptr, radio_imsmedialistener.get());
+
+ radio_imsmediasessionlistener = ndk::SharedRefBase::make<ImsMediaSessionListener>(*this);
+ ASSERT_NE(nullptr, radio_imsmediasessionlistener.get());
+ count_ = 0;
+}
+
+TEST_P(RadioImsMediaTest, MOCallSuccess) {
+ int32_t sessionId = 1;
+ RtpConfig modifyRtpConfig;
+
+ modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+ static_cast<int32_t>(MediaDirection::RTP_RX) |
+ static_cast<int32_t>(MediaDirection::RTCP_TX) |
+ static_cast<int32_t>(MediaDirection::RTCP_RX);
+ modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+ modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping setListener because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running setListener because ims is supported in device");
+ }
+
+ ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_OPEN_SESSION;
+ res = triggerOpenSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+ ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+ radio_imsmediasession = radio_imsmedialistener->mSession;
+ radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_MODIFY_SESSION;
+ res = radio_imsmediasession->modifySession(modifyRtpConfig);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+ verifyError(radio_imsmediasessionlistener->mError);
+
+ serial = SERIAL_CLOSE_SESSION;
+ res = radio_imsmedia->closeSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+}
+
+TEST_P(RadioImsMediaTest, testDtmfOperation) {
+ int32_t sessionId = 1;
+ char16_t dtmfDight = 'a';
+ int32_t duration = 200;
+ RtpConfig modifyRtpConfig;
+
+ modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+ static_cast<int32_t>(MediaDirection::RTP_RX) |
+ static_cast<int32_t>(MediaDirection::RTCP_TX) |
+ static_cast<int32_t>(MediaDirection::RTCP_RX);
+ modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+ modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping setListener because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running setListener because ims is supported in device");
+ }
+
+ ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_OPEN_SESSION;
+ res = triggerOpenSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+ ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+ radio_imsmediasession = radio_imsmedialistener->mSession;
+ radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_MODIFY_SESSION;
+ res = radio_imsmediasession->modifySession(modifyRtpConfig);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+ verifyError(radio_imsmediasessionlistener->mError);
+
+ res = radio_imsmediasession->sendDtmf(dtmfDight, duration);
+ ASSERT_OK(res);
+
+ res = radio_imsmediasession->startDtmf(dtmfDight);
+ ASSERT_OK(res);
+
+ res = radio_imsmediasession->stopDtmf();
+ ASSERT_OK(res);
+
+ serial = SERIAL_CLOSE_SESSION;
+ res = radio_imsmedia->closeSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
+TEST_P(RadioImsMediaTest, sendHeaderExtension) {
+ int32_t sessionId = 1;
+ std::vector<RtpHeaderExtension> extensions;
+ RtpConfig modifyRtpConfig;
+
+ modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+ static_cast<int32_t>(MediaDirection::RTP_RX) |
+ static_cast<int32_t>(MediaDirection::RTCP_TX) |
+ static_cast<int32_t>(MediaDirection::RTCP_RX);
+ modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+ modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping setListener because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running setListener because ims is supported in device");
+ }
+
+ ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_OPEN_SESSION;
+ res = triggerOpenSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+ ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+ radio_imsmediasession = radio_imsmedialistener->mSession;
+ radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_MODIFY_SESSION;
+ res = radio_imsmediasession->modifySession(modifyRtpConfig);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+ verifyError(radio_imsmediasessionlistener->mError);
+
+ res = radio_imsmediasession->sendHeaderExtension(extensions);
+ ASSERT_OK(res);
+
+ serial = SERIAL_CLOSE_SESSION;
+ res = radio_imsmedia->closeSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
+TEST_P(RadioImsMediaTest, setMediaQualityThreshold) {
+ int32_t sessionId = 1;
+ MediaQualityThreshold threshold;
+ RtpConfig modifyRtpConfig;
+
+ modifyRtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+ static_cast<int32_t>(MediaDirection::RTP_RX) |
+ static_cast<int32_t>(MediaDirection::RTCP_TX) |
+ static_cast<int32_t>(MediaDirection::RTCP_RX);
+ modifyRtpConfig.remoteAddress.ipAddress = "122.22.22.33";
+ modifyRtpConfig.remoteAddress.portNumber = 1234;
+
+ if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+ ALOGI("Skipping setListener because ims is not supported in device");
+ return;
+ } else {
+ ALOGI("Running setListener because ims is supported in device");
+ }
+
+ ndk::ScopedAStatus res = radio_imsmedia->setListener(radio_imsmedialistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_OPEN_SESSION;
+ res = triggerOpenSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(sessionId, radio_imsmedialistener->mSessionId);
+ ASSERT_NE(nullptr, radio_imsmedialistener->mSession);
+
+ radio_imsmediasession = radio_imsmedialistener->mSession;
+ radio_imsmediasession->setListener(radio_imsmediasessionlistener);
+ ASSERT_OK(res);
+
+ serial = SERIAL_MODIFY_SESSION;
+ res = radio_imsmediasession->modifySession(modifyRtpConfig);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(modifyRtpConfig, radio_imsmediasessionlistener->mConfig);
+ verifyError(radio_imsmediasessionlistener->mError);
+
+ res = radio_imsmediasession->setMediaQualityThreshold(threshold);
+ ASSERT_OK(res);
+
+ serial = SERIAL_CLOSE_SESSION;
+ res = radio_imsmedia->closeSession(sessionId);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
+
+ndk::ScopedAStatus RadioImsMediaTest::triggerOpenSession(int32_t sessionId) {
+ LocalEndPoint localEndPoint;
+ RtpConfig rtpConfig;
+ ndk::ScopedAStatus result;
+
+ int mSocketFd = ::socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ int mRtcpSocketFd = ::socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ localEndPoint.rtpFd = ndk::ScopedFileDescriptor(mSocketFd);
+ localEndPoint.rtcpFd = ndk::ScopedFileDescriptor(mRtcpSocketFd);
+ localEndPoint.modemId = 1;
+
+ rtpConfig.direction = static_cast<int32_t>(MediaDirection::RTP_TX) |
+ static_cast<int32_t>(MediaDirection::RTP_RX) |
+ static_cast<int32_t>(MediaDirection::RTCP_TX) |
+ static_cast<int32_t>(MediaDirection::RTCP_RX);
+ rtpConfig.remoteAddress.ipAddress = "122.22.22.22";
+ rtpConfig.remoteAddress.portNumber = 2222;
+
+ result = radio_imsmedia->openSession(sessionId, localEndPoint, rtpConfig);
+ return result;
+}
+
+void RadioImsMediaTest::verifyError(RtpError error) {
+ switch (error) {
+ case RtpError::NONE:
+ case RtpError::INVALID_PARAM:
+ case RtpError::NOT_READY:
+ case RtpError::NO_MEMORY:
+ case RtpError::NO_RESOURCES:
+ case RtpError::PORT_UNAVAILABLE:
+ case RtpError::NOT_SUPPORTED:
+ SUCCEED();
+ break;
+ default:
+ FAIL();
+ break;
+ }
+}
diff --git a/radio/aidl/vts/radio_imsmedia_utils.h b/radio/aidl/vts/radio_imsmedia_utils.h
new file mode 100644
index 0000000..6143add
--- /dev/null
+++ b/radio/aidl/vts/radio_imsmedia_utils.h
@@ -0,0 +1,98 @@
+
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/ims/media/BnImsMediaListener.h>
+#include <aidl/android/hardware/radio/ims/media/BnImsMediaSessionListener.h>
+#include <aidl/android/hardware/radio/ims/media/IImsMedia.h>
+#include <aidl/android/hardware/radio/ims/media/IImsMediaSession.h>
+
+#include "radio_aidl_hal_utils.h"
+
+#define SERIAL_SET_LISTENER 1
+#define SERIAL_OPEN_SESSION 2
+#define SERIAL_CLOSE_SESSION 3
+#define SERIAL_MODIFY_SESSION 4
+
+using namespace aidl::android::hardware::radio::ims::media;
+
+class RadioImsMediaTest;
+
+/* Listener class for ImsMedia. */
+class ImsMediaListener : public BnImsMediaListener {
+ protected:
+ RadioServiceTest& parent_imsmedia;
+
+ public:
+ ImsMediaListener(RadioServiceTest& parent_imsmedialistener);
+ virtual ~ImsMediaListener() = default;
+
+ int32_t mSessionId;
+ std::shared_ptr<::aidl::android::hardware::radio::ims::media::IImsMediaSession> mSession;
+ RtpError mError;
+
+ virtual ndk::ScopedAStatus onOpenSessionSuccess(
+ int32_t in_sessionId, const std::shared_ptr<IImsMediaSession>& in_session) override;
+ virtual ndk::ScopedAStatus onOpenSessionFailure(int32_t in_sessionId,
+ RtpError in_error) override;
+ virtual ndk::ScopedAStatus onSessionClosed(int32_t in_sessionId) override;
+};
+
+/* Listener class for ImsMediaSession. */
+class ImsMediaSessionListener : public BnImsMediaSessionListener {
+ protected:
+ RadioServiceTest& parent_imsmedia;
+
+ public:
+ ImsMediaSessionListener(RadioServiceTest& parent_imsmediasessionlistener);
+ virtual ~ImsMediaSessionListener() = default;
+
+ RtpConfig mConfig;
+ RtpError mError;
+
+ virtual ndk::ScopedAStatus onModifySessionResponse(const RtpConfig& in_config,
+ RtpError in_error) override;
+ virtual ndk::ScopedAStatus onFirstMediaPacketReceived(const RtpConfig& in_config) override;
+ virtual ndk::ScopedAStatus onHeaderExtensionReceived(
+ const std::vector<RtpHeaderExtension>& in_extensions) override;
+ virtual ndk::ScopedAStatus notifyMediaQualityStatus(
+ const MediaQualityStatus& in_quality) override;
+ virtual ndk::ScopedAStatus triggerAnbrQuery(const RtpConfig& in_config) override;
+ virtual ndk::ScopedAStatus onDtmfReceived(char16_t in_dtmfDigit,
+ int32_t in_durationMs) override;
+ virtual ndk::ScopedAStatus onCallQualityChanged(const CallQuality& in_callQuality) override;
+};
+
+/* The main test class for Radio AIDL ImsMedia. */
+class RadioImsMediaTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+ protected:
+ virtual void verifyError(RtpError inError);
+ virtual ndk::ScopedAStatus triggerOpenSession(int32_t sessionId);
+
+ public:
+ virtual void SetUp() override;
+
+ /* radio imsmedia service handle */
+ std::shared_ptr<IImsMedia> radio_imsmedia;
+ /* radio imsmediasession service handle */
+ std::shared_ptr<IImsMediaSession> radio_imsmediasession;
+ /* radio imsmedia listener handle */
+ std::shared_ptr<ImsMediaListener> radio_imsmedialistener;
+ /* radio imsmediasession listener handle */
+ std::shared_ptr<ImsMediaSessionListener> radio_imsmediasessionlistener;
+};
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
index 20b44c5..050b2c8 100644
--- a/radio/aidl/vts/radio_modem_response.cpp
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -46,6 +46,13 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus RadioModemResponse::getImeiResponse(const RadioResponseInfo& info,
+ const std::optional<ImeiInfo>& /*imeiInfo*/) {
+ rspInfo = info;
+ parent_modem.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus RadioModemResponse::getHardwareConfigResponse(
const RadioResponseInfo& info, const std::vector<HardwareConfig>& /*config*/) {
rspInfo = info;
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index f88da13..c00b238 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -188,6 +188,25 @@
}
/*
+ * Test IRadioModem.getImei() for the response returned.
+ */
+TEST_P(RadioModemTest, getImei) {
+ LOG(DEBUG) << "getImei";
+ serial = GetRandomSerialNumber();
+
+ radio_modem->getImei(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+
+ if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error,
+ {RadioError::NONE, RadioError::EMPTY_RECORD}));
+ }
+ LOG(DEBUG) << "getImei finished";
+}
+
+/*
* Test IRadioModem.nvReadItem() for the response returned.
*/
TEST_P(RadioModemTest, nvReadItem) {
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
index 49e1891..d2f5a10 100644
--- a/radio/aidl/vts/radio_modem_utils.h
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -19,6 +19,7 @@
#include <aidl/android/hardware/radio/modem/BnRadioModemIndication.h>
#include <aidl/android/hardware/radio/modem/BnRadioModemResponse.h>
#include <aidl/android/hardware/radio/modem/IRadioModem.h>
+#include <aidl/android/hardware/radio/modem/ImeiInfo.h>
#include "radio_aidl_hal_utils.h"
@@ -52,6 +53,9 @@
const std::string& esn,
const std::string& meid) override;
+ virtual ndk::ScopedAStatus getImeiResponse(const RadioResponseInfo& info,
+ const std::optional<ImeiInfo>& config) override;
+
virtual ndk::ScopedAStatus getHardwareConfigResponse(
const RadioResponseInfo& info, const std::vector<HardwareConfig>& config) override;
diff --git a/radio/aidl/vts/radio_network_indication.cpp b/radio/aidl/vts/radio_network_indication.cpp
index 7acbff4..ae3bd4b 100644
--- a/radio/aidl/vts/radio_network_indication.cpp
+++ b/radio/aidl/vts/radio_network_indication.cpp
@@ -92,3 +92,8 @@
RadioTechnology /*rat*/) {
return ndk::ScopedAStatus::ok();
}
+
+ndk::ScopedAStatus RadioNetworkIndication::emergencyNetworkScanResult(
+ RadioIndicationType /*type*/, const EmergencyRegResult& /*result*/) {
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 2292c54..25d45a5 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -266,3 +266,57 @@
parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
+
+ndk::ScopedAStatus RadioNetworkResponse::setEmergencyModeResponse(
+ const RadioResponseInfo& info, const EmergencyRegResult& /*regState*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::triggerEmergencyNetworkScanResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::exitEmergencyModeResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::cancelEmergencyNetworkScanResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNullCipherAndIntegrityEnabledResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isNullCipherAndIntegrityEnabledResponse(
+ const RadioResponseInfo& info, bool /*isEnabled*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isN1ModeEnabledResponse(
+ const RadioResponseInfo& info, bool /*isEnabled*/) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setN1ModeEnabledResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 61b34d7..7d9986b 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -356,7 +356,7 @@
/*
* Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
*/
-TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran) {
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran_Rscp) {
serial = GetRandomSerialNumber();
SignalThresholdInfo signalThresholdInfo;
@@ -380,6 +380,33 @@
}
/*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran_Ecno) {
+ serial = GetRandomSerialNumber();
+
+ SignalThresholdInfo signalThresholdInfo;
+ signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_ECNO;
+ signalThresholdInfo.hysteresisMs = 5000;
+ signalThresholdInfo.hysteresisDb = 2;
+ signalThresholdInfo.thresholds = {-22, -18, 0};
+ signalThresholdInfo.isEnabled = true;
+ signalThresholdInfo.ran = AccessNetwork::UTRAN;
+
+ ndk::ScopedAStatus res =
+ radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ALOGI("setSignalStrengthReportingCriteria_Utran, rspInfo.error = %s\n",
+ toString(radioRsp_network->rspInfo.error).c_str());
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
* Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
*/
TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRP) {
@@ -1504,11 +1531,12 @@
// Check for access technology specific info
AccessTechnologySpecificInfo info = radioRsp_network->dataRegResp.accessTechnologySpecificInfo;
RadioTechnology rat = radioRsp_network->dataRegResp.rat;
+
// TODO: add logic for cdmaInfo
- if (rat == RadioTechnology::LTE || rat == RadioTechnology::LTE_CA) {
+ if (rat == RadioTechnology::LTE) {
ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::eutranInfo);
} else if (rat == RadioTechnology::NR) {
- ASSERT_EQ(info.getTag(), AccessTechnologySpecificInfo::ngranNrVopsInfo);
+ ASSERT_TRUE(info.getTag() == AccessTechnologySpecificInfo::ngranNrVopsInfo);
}
}
@@ -1838,3 +1866,168 @@
}
LOG(DEBUG) << "supplyNetworkDepersonalization finished";
}
+
+/*
+ * Test IRadioNetwork.setEmergencyMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setEmergencyMode) {
+ LOG(DEBUG) << "setEmergencyMode";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setEmergencyMode(serial, EmergencyMode::EMERGENCY_WWAN);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ 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::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS}));
+ LOG(DEBUG) << "setEmergencyMode finished";
+}
+
+/*
+ * Test IRadioNetwork.triggerEmergencyNetworkScan() for the response returned.
+ */
+TEST_P(RadioNetworkTest, triggerEmergencyNetworkScan) {
+ LOG(DEBUG) << "triggerEmergencyNetworkScan";
+ serial = GetRandomSerialNumber();
+
+ EmergencyNetworkScanTrigger scanRequest;
+ scanRequest.accessNetwork = {AccessNetwork::EUTRAN};
+ scanRequest.scanType = EmergencyScanType::NO_PREFERENCE;
+
+ radio_network->triggerEmergencyNetworkScan(serial, scanRequest);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ 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::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS}));
+ LOG(DEBUG) << "triggerEmergencyNetworkScan finished";
+}
+
+/*
+ * Test IRadioNetwork.cancelEmergencyNetworkScan() for the response returned.
+ */
+TEST_P(RadioNetworkTest, cancelEmergencyNetworkScan) {
+ LOG(DEBUG) << "cancelEmergencyNetworkScan";
+ serial = GetRandomSerialNumber();
+
+ radio_network->cancelEmergencyNetworkScan(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ 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::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR}));
+ LOG(DEBUG) << "cancelEmergencyNetworkScan finished";
+}
+
+/*
+ * Test IRadioNetwork.exitEmergencyMode() for the response returned.
+ */
+TEST_P(RadioNetworkTest, exitEmergencyMode) {
+ LOG(DEBUG) << "exitEmergencyMode";
+ serial = GetRandomSerialNumber();
+
+ radio_network->exitEmergencyMode(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ 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::REQUEST_NOT_SUPPORTED, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR}));
+ LOG(DEBUG) << "exitEmergencyMode finished";
+}
+
+/*
+ * Test IRadioNetwork.setN1ModeEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setN1ModeEnabled) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res =
+ radio_network->setN1ModeEnabled(serial, false);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ if (getRadioHalCapabilities()) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::REQUEST_NOT_SUPPORTED}));
+ } else {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+ RadioError::INVALID_STATE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.isN1ModeEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isN1ModeEnabled) {
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->isN1ModeEnabled(serial);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ if (getRadioHalCapabilities()) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::REQUEST_NOT_SUPPORTED}));
+ } else {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+ RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+ }
+}
+
+/*
+ * Test IRadioNetwork.setNullCipherAndIntegrityEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNullCipherAndIntegrityEnabled) {
+ LOG(DEBUG) << "setNullCipherAndIntegrityEnabled";
+ serial = GetRandomSerialNumber();
+
+ radio_network->setNullCipherAndIntegrityEnabled(serial, false);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ 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::REQUEST_NOT_SUPPORTED,
+ RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ LOG(DEBUG) << "setNullCipherAndIntegrityEnabled finished";
+}
+
+/**
+ * Test IRadioNetwork.isNullCipherAndIntegrityEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isNullCipherAndIntegrityEnabled) {
+ LOG(DEBUG) << "isNullCipherAndIntegrityEnabled";
+ serial = GetRandomSerialNumber();
+
+ ndk::ScopedAStatus res = radio_network->isNullCipherAndIntegrityEnabled(serial);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ 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, RadioError::REQUEST_NOT_SUPPORTED}));
+ LOG(DEBUG) << "isNullCipherAndIntegrityEnabled finished";
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 29f20e8..601f044 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -147,6 +147,28 @@
virtual ndk::ScopedAStatus supplyNetworkDepersonalizationResponse(
const RadioResponseInfo& info, int32_t remainingRetries) override;
+
+ virtual ndk::ScopedAStatus setEmergencyModeResponse(
+ const RadioResponseInfo& info, const EmergencyRegResult& regState) override;
+
+ virtual ndk::ScopedAStatus triggerEmergencyNetworkScanResponse(
+ const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus exitEmergencyModeResponse(const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus cancelEmergencyNetworkScanResponse(
+ const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus setNullCipherAndIntegrityEnabledResponse(
+ const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus isNullCipherAndIntegrityEnabledResponse(
+ const RadioResponseInfo& info, const bool isEnabled) override;
+
+ virtual ndk::ScopedAStatus isN1ModeEnabledResponse(
+ const RadioResponseInfo& info, bool isEnabled) override;
+
+ virtual ndk::ScopedAStatus setN1ModeEnabledResponse(const RadioResponseInfo& info) override;
};
/* Callback class for radio network indication */
@@ -201,6 +223,9 @@
virtual ndk::ScopedAStatus voiceRadioTechChanged(RadioIndicationType type,
RadioTechnology rat) override;
+
+ virtual ndk::ScopedAStatus emergencyNetworkScanResult(
+ RadioIndicationType type, const EmergencyRegResult& result) override;
};
// The main test class for Radio AIDL Network.
diff --git a/radio/aidl/vts/radio_sim_response.cpp b/radio/aidl/vts/radio_sim_response.cpp
index 391c9cb..296c65c 100644
--- a/radio/aidl/vts/radio_sim_response.cpp
+++ b/radio/aidl/vts/radio_sim_response.cpp
@@ -118,6 +118,13 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelWithSessionInfoResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_sim.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& info,
const IccIoResult& /*iccIo*/) {
rspInfo = info;
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index e69247d..44be258 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -762,6 +762,27 @@
}
/*
+ * Test IRadioSim.iccCloseLogicalChannelWithSessionInfo() for the response returned.
+ */
+TEST_P(RadioSimTest, iccCloseLogicalChannelWithSessionInfo) {
+ LOG(DEBUG) << "iccCloseLogicalChannelWithSessionInfo";
+ serial = GetRandomSerialNumber();
+ SessionInfo info;
+ memset(&info, 0, sizeof(info));
+ info.sessionId = 0;
+ info.isEs10 = false;
+
+ // Try closing invalid channel and check INVALID_ARGUMENTS returned as error
+ radio_sim->iccCloseLogicalChannelWithSessionInfo(serial, info);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+ EXPECT_EQ(RadioError::INVALID_ARGUMENTS, radioRsp_sim->rspInfo.error);
+ LOG(DEBUG) << "iccCloseLogicalChannelWithSessionInfo finished";
+}
+
+/*
* Test IRadioSim.iccTransmitApduLogicalChannel() for the response returned.
*/
TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) {
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
index 83f1cbc..71c7eb8 100644
--- a/radio/aidl/vts/radio_sim_utils.h
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -87,6 +87,9 @@
virtual ndk::ScopedAStatus iccCloseLogicalChannelResponse(
const RadioResponseInfo& info) override;
+ virtual ndk::ScopedAStatus iccCloseLogicalChannelWithSessionInfoResponse(
+ const RadioResponseInfo& info) override;
+
virtual ndk::ScopedAStatus iccIoForAppResponse(const RadioResponseInfo& info,
const IccIoResult& iccIo) override;
diff --git a/security/rkp/aidl/lint-baseline.xml b/security/rkp/aidl/lint-baseline.xml
new file mode 100644
index 0000000..d25d383
--- /dev/null
+++ b/security/rkp/aidl/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V1-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="50"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V2-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="50"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 34 (current min is 33): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/security/rkp/aidl/android.hardware.security.rkp-V3-java-source/gen/android/hardware/security/keymint/IRemotelyProvisionedComponent.java"
+ line="495"
+ column="12"/>
+ </issue>
+
+</issues>
\ No newline at end of file
diff --git a/sensors/2.1/default/apex/Android.bp b/sensors/2.1/default/apex/Android.bp
deleted file mode 100644
index 3345b92..0000000
--- a/sensors/2.1/default/apex/Android.bp
+++ /dev/null
@@ -1,46 +0,0 @@
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-apex_key {
- name: "com.android.hardware.sensors.key",
- public_key: "com.android.hardware.sensors.avbpubkey",
- private_key: "com.android.hardware.sensors.pem",
-}
-
-android_app_certificate {
- name: "com.android.hardware.sensors.certificate",
- certificate: "com.android.hardware.sensors",
-}
-
-prebuilt_etc {
- name: "com.android.hardware.sensors.rc",
- src: "com.android.hardware.sensors.rc",
- 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.sensors.key",
- certificate: ":com.android.hardware.sensors.certificate",
- file_contexts: "file_contexts",
- use_vndk_as_stable: true,
- updatable: false,
- // Install the apex in /vendor/apex
- soc_specific: true,
- binaries: ["[email protected]"],
- prebuilts: [
- "com.android.hardware.sensors.rc",
- "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",
- ],
- vintf_fragments: [":[email protected]"],
-}
diff --git a/sensors/2.1/default/apex/apex_manifest.json b/sensors/2.1/default/apex/apex_manifest.json
deleted file mode 100644
index 47e45ee..0000000
--- a/sensors/2.1/default/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.hardware.sensors",
- "version": 1
-}
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.rc b/sensors/2.1/default/apex/com.android.hardware.sensors.rc
deleted file mode 100644
index bd245b4..0000000
--- a/sensors/2.1/default/apex/com.android.hardware.sensors.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor.sensors-hal-2-1-mock /apex/com.android.hardware.sensors/bin/hw/[email protected]
- interface [email protected]::ISensors default
- interface [email protected]::ISensors default
- class hal
- user system
- group system
- rlimit rtprio 10 10
diff --git a/sensors/2.1/default/apex/file_contexts b/sensors/2.1/default/apex/file_contexts
deleted file mode 100644
index d0095c0..0000000
--- a/sensors/2.1/default/apex/file_contexts
+++ /dev/null
@@ -1,5 +0,0 @@
-(/.*)? u:object_r:vendor_file:s0
-# Permission XMLs
-/etc/permissions(/.*)? u:object_r:vendor_configs_file:s0
-# Service binary
-/bin/hw/android\.hardware\.sensors@2\.1-service\.mock u:object_r:hal_sensors_default_exec:s0
diff --git a/sensors/2.1/multihal/[email protected] b/sensors/2.1/multihal/[email protected]
index e149058..deea16e 100644
--- a/sensors/2.1/multihal/[email protected]
+++ b/sensors/2.1/multihal/[email protected]
@@ -1,7 +1,7 @@
service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/[email protected]
class hal
user system
- group system wakelock context_hub input uhid
+ group system wakelock context_hub input
task_profiles ServiceCapacityLow
capabilities BLOCK_SUSPEND
rlimit rtprio 10 10
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
index f60f5bb..b26040b 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
@@ -58,6 +58,8 @@
const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 24;
const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 88;
const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+ const int RUNTIME_SENSORS_HANDLE_BASE = 1593835520;
+ const int RUNTIME_SENSORS_HANDLE_END = 1610612735;
@Backing(type="int") @VintfStability
enum RateLevel {
STOP = 0,
diff --git a/sensors/aidl/android/hardware/sensors/ISensors.aidl b/sensors/aidl/android/hardware/sensors/ISensors.aidl
index 2c68489..5e276dd 100644
--- a/sensors/aidl/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/android/hardware/sensors/ISensors.aidl
@@ -371,4 +371,13 @@
const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 0x18;
const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 0x58;
const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+
+ /**
+ * Constants related to reserved sensor handle ranges.
+ *
+ * The following range (inclusive) is reserved for usage by the system for
+ * runtime sensors.
+ */
+ const int RUNTIME_SENSORS_HANDLE_BASE = 0x5F000000;
+ const int RUNTIME_SENSORS_HANDLE_END = 0x5FFFFFFF;
}
diff --git a/sensors/aidl/convert/Android.bp b/sensors/aidl/convert/Android.bp
index 0b31597..53060b9 100644
--- a/sensors/aidl/convert/Android.bp
+++ b/sensors/aidl/convert/Android.bp
@@ -35,7 +35,7 @@
"libhardware",
"libbase",
"libutils",
- "android.hardware.sensors-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
],
whole_static_libs: [
"sensors_common_convert",
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 49841a4..16b4d35 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -23,6 +23,16 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+filegroup {
+ name: "sensors-default.rc",
+ srcs: ["sensors-default.rc"],
+}
+
+filegroup {
+ name: "sensors-default.xml",
+ srcs: ["sensors-default.xml"],
+}
+
cc_library_static {
name: "libsensorsexampleimpl",
vendor: true,
@@ -31,7 +41,7 @@
"libfmq",
"libpower",
"libbinder_ndk",
- "android.hardware.sensors-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
],
export_include_dirs: ["include"],
srcs: [
@@ -47,8 +57,8 @@
cc_binary {
name: "android.hardware.sensors-service.example",
relative_install_path: "hw",
- init_rc: ["sensors-default.rc"],
- vintf_fragments: ["sensors-default.xml"],
+ init_rc: [":sensors-default.rc"],
+ vintf_fragments: [":sensors-default.xml"],
vendor: true,
shared_libs: [
"libbase",
@@ -58,7 +68,7 @@
"libcutils",
"liblog",
"libutils",
- "android.hardware.sensors-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
],
static_libs: [
"libsensorsexampleimpl",
diff --git a/sensors/aidl/default/apex/Android.bp b/sensors/aidl/default/apex/Android.bp
new file mode 100644
index 0000000..ceb428b
--- /dev/null
+++ b/sensors/aidl/default/apex/Android.bp
@@ -0,0 +1,53 @@
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+ name: "com.android.hardware.sensors.key",
+ public_key: "com.android.hardware.sensors.avbpubkey",
+ private_key: "com.android.hardware.sensors.pem",
+}
+
+android_app_certificate {
+ name: "com.android.hardware.sensors.certificate",
+ certificate: "com.android.hardware.sensors",
+}
+
+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.sensors.key",
+ certificate: ":com.android.hardware.sensors.certificate",
+ file_contexts: "file_contexts",
+ use_vndk_as_stable: true,
+ updatable: false,
+ // Install the apex in /vendor/apex
+ soc_specific: true,
+ binaries: ["android.hardware.sensors-service.example"],
+ prebuilts: [
+ "com.android.hardware.sensors.rc",
+ "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",
+ ],
+ vintf_fragments: [":sensors-default.xml"],
+}
diff --git a/sensors/aidl/default/apex/apex_manifest.json b/sensors/aidl/default/apex/apex_manifest.json
new file mode 100644
index 0000000..659e739
--- /dev/null
+++ b/sensors/aidl/default/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.sensors",
+ "version": 1
+}
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.avbpubkey b/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.avbpubkey
rename to sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
Binary files differ
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.pem
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.pem
rename to sensors/aidl/default/apex/com.android.hardware.sensors.pem
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.pk8 b/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.pk8
rename to sensors/aidl/default/apex/com.android.hardware.sensors.pk8
Binary files differ
diff --git a/sensors/2.1/default/apex/com.android.hardware.sensors.x509.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
similarity index 100%
rename from sensors/2.1/default/apex/com.android.hardware.sensors.x509.pem
rename to sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
diff --git a/sensors/aidl/default/apex/file_contexts b/sensors/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..27be16b
--- /dev/null
+++ b/sensors/aidl/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)? u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)? u:object_r:vendor_configs_file:s0
+# Service binary
+/bin/hw/android\.hardware\.sensors-service\.example u:object_r:hal_sensors_default_exec:s0
\ No newline at end of file
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
index eee1062..a20d6d7 100644
--- a/sensors/aidl/default/multihal/Android.bp
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -38,7 +38,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.sensors-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
],
export_include_dirs: ["include"],
srcs: [
diff --git a/sensors/aidl/default/multihal/HalProxyAidl.cpp b/sensors/aidl/default/multihal/HalProxyAidl.cpp
index e6bcdad..dbef030 100644
--- a/sensors/aidl/default/multihal/HalProxyAidl.cpp
+++ b/sensors/aidl/default/multihal/HalProxyAidl.cpp
@@ -17,6 +17,7 @@
#include "HalProxyAidl.h"
#include <aidlcommonsupport/NativeHandle.h>
#include <fmq/AidlMessageQueue.h>
+#include <hidl/HidlSupport.h>
#include <hidl/Status.h>
#include "ConvertUtils.h"
#include "EventMessageQueueWrapperAidl.h"
@@ -28,6 +29,8 @@
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using ::aidl::android::hardware::sensors::ISensors;
using ::aidl::android::hardware::sensors::ISensorsCallback;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent;
using ::ndk::ScopedAStatus;
@@ -225,13 +228,18 @@
return resultToAStatus(HalProxy::unregisterDirectChannel(in_channelHandle));
}
-binder_status_t HalProxyAidl::dump(int fd, const char ** /* args */,
- uint32_t /* numArgs */) {
+binder_status_t HalProxyAidl::dump(int fd, const char ** args,
+ uint32_t numArgs) {
native_handle_t *nativeHandle =
native_handle_create(1 /* numFds */, 0 /* numInts */);
nativeHandle->data[0] = fd;
- HalProxy::debug(nativeHandle, {} /* args */);
+ hidl_vec<hidl_string> hidl_args;
+ hidl_args.resize(numArgs);
+ for (size_t i = 0; i < numArgs; ++i) {
+ hidl_args[i] = args[i];
+ }
+ HalProxy::debug(nativeHandle, hidl_args);
native_handle_delete(nativeHandle);
return STATUS_OK;
@@ -241,4 +249,4 @@
} // namespace sensors
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/sensors/aidl/default/sensors-default.xml b/sensors/aidl/default/sensors-default.xml
index 7898a6b..36b28ed 100644
--- a/sensors/aidl/default/sensors-default.xml
+++ b/sensors/aidl/default/sensors-default.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.sensors</name>
- <version>1</version>
+ <version>2</version>
<fqname>ISensors/default</fqname>
</hal>
</manifest>
diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp
index 6d35daf..522d305 100644
--- a/sensors/aidl/multihal/Android.bp
+++ b/sensors/aidl/multihal/Android.bp
@@ -40,7 +40,7 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.sensors-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
"libbase",
"libcutils",
"libfmq",
diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
index d78edff..5da4fbd 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
+++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
@@ -17,7 +17,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.sensors</name>
- <version>1</version>
+ <version>2</version>
<fqname>ISensors/default</fqname>
</hal>
</manifest>
diff --git a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
index 3f91a0a..5aecc54 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
+++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
@@ -1,7 +1,7 @@
service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal
class hal
user system
- group system wakelock context_hub
+ group system wakelock context_hub input uhid
task_profiles ServiceCapacityLow
capabilities BLOCK_SUSPEND
- rlimit rtprio 10 10
\ No newline at end of file
+ rlimit rtprio 10 10
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index f3972ec..c17a558 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -41,7 +41,7 @@
"android.hardware.common.fmq-V1-ndk",
],
static_libs: [
- "android.hardware.sensors-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
"VtsHalSensorsTargetTestUtils",
"libaidlcommonsupport",
],
diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
index 35220a2..618acbb 100644
--- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
+++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
@@ -561,10 +561,15 @@
EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(info.type, info.typeAsString));
}
- // Test if all sensor has name and vendor
+ // Test if all sensors have name and vendor
EXPECT_FALSE(info.name.empty());
EXPECT_FALSE(info.vendor.empty());
+ // Make sure that the sensor handle is not within the reserved range for runtime
+ // sensors.
+ EXPECT_FALSE(ISensors::RUNTIME_SENSORS_HANDLE_BASE <= info.sensorHandle &&
+ info.sensorHandle <= ISensors::RUNTIME_SENSORS_HANDLE_END);
+
// Make sure that sensors of the same type have a unique name.
std::vector<std::string>& v = sensorTypeNameMap[static_cast<int32_t>(info.type)];
bool isUniqueName = std::find(v.begin(), v.end(), info.name) == v.end();
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index 31a17db..305383e 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -351,7 +351,7 @@
return Return<void>();
}
-Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /*args*/) {
+Return<void> HalProxy::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
ALOGE("%s: missing fd for writing", __FUNCTION__);
return Void();
@@ -385,7 +385,7 @@
stream << " Name: " << subHal->getName() << std::endl;
stream << " Debug dump: " << std::endl;
android::base::WriteStringToFd(stream.str(), writeFd);
- subHal->debug(fd, {});
+ subHal->debug(fd, args);
stream.str("");
stream << std::endl;
}
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
index f2c92ae..ec7c906 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h
@@ -225,7 +225,9 @@
ASSERT_EQ(batch(handle, samplingPeriodInNs, batchingPeriodInNs), Result::OK);
ASSERT_EQ(activate(handle, 1), Result::OK);
- events = getEnvironment()->collectEvents(minTimeUs, minNEvent, true /*clearBeforeStart*/);
+ events = getEnvironment()->collectEvents(
+ minTimeUs, minNEvent, true /* clearBeforeStart */, true /* changeCollection */,
+ [&type](const EventType& event) { return event.sensorType == type; });
ASSERT_EQ(activate(handle, 0), Result::OK);
ALOGI("Collected %zu samples", events.size());
@@ -233,24 +235,14 @@
ASSERT_GT(events.size(), 0u);
bool handleMismatchReported = false;
- bool metaSensorTypeErrorReported = false;
for (auto& e : events) {
- if (e.sensorType == type) {
- // avoid generating hundreds of error
- if (!handleMismatchReported) {
- EXPECT_EQ(e.sensorHandle, handle)
- << (handleMismatchReported = true,
- "Event of the same type must come from the sensor registered");
- }
- sensorEvents.push_back(e);
- } else {
- // avoid generating hundreds of error
- if (!metaSensorTypeErrorReported) {
- EXPECT_TRUE(isMetaSensorType(e.sensorType))
- << (metaSensorTypeErrorReported = true,
- "Only meta types are allowed besides the type registered");
- }
+ // avoid generating hundreds of error
+ if (!handleMismatchReported) {
+ EXPECT_EQ(e.sensorHandle, handle)
+ << (handleMismatchReported = true,
+ "Event of the same type must come from the sensor registered");
}
+ sensorEvents.push_back(e);
}
std::string s;
diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
index e851d40..c061a75 100644
--- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
+++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsVtsEnvironmentBase.h
@@ -20,6 +20,7 @@
#include <gtest/gtest.h>
#include <atomic>
+#include <functional>
#include <memory>
#include <mutex>
#include <thread>
@@ -61,9 +62,16 @@
}
// set sensor event collection status
- void setCollection(bool enable) {
+ void setCollection(bool enable, const std::optional<std::function<bool(const Event&)>>& filter =
+ std::nullopt) {
std::lock_guard<std::mutex> lock(mEventsMutex);
mCollectionEnabled = enable;
+
+ if (enable && filter.has_value()) {
+ mEventFilter = *filter;
+ } else {
+ mEventFilter.reset();
+ }
}
void registerCallback(IEventCallback<Event>* callback) {
@@ -76,8 +84,10 @@
mCallback = nullptr;
}
- std::vector<Event> collectEvents(useconds_t timeLimitUs, size_t nEventLimit,
- bool clearBeforeStart = true, bool changeCollection = true) {
+ std::vector<Event> collectEvents(
+ useconds_t timeLimitUs, size_t nEventLimit, bool clearBeforeStart = true,
+ bool changeCollection = true,
+ const std::optional<std::function<bool(const Event&)>>& filter = std::nullopt) {
std::vector<Event> events;
constexpr useconds_t SLEEP_GRANULARITY = 100 * 1000; // granularity 100 ms
@@ -85,7 +95,7 @@
clearBeforeStart);
if (changeCollection) {
- setCollection(true);
+ setCollection(true, filter);
}
if (clearBeforeStart) {
catEvents(nullptr);
@@ -121,7 +131,7 @@
void addEvent(const Event& ev) {
std::lock_guard<std::mutex> lock(mEventsMutex);
- if (mCollectionEnabled) {
+ if (mCollectionEnabled && (!mEventFilter.has_value() || (*mEventFilter)(ev))) {
mEvents.push_back(ev);
}
@@ -138,6 +148,7 @@
std::atomic_bool mStopThread;
std::thread mPollThread;
std::vector<Event> mEvents;
+ std::optional<std::function<bool(const Event&)>> mEventFilter;
std::mutex mEventsMutex;
IEventCallback<Event>* mCallback;
diff --git a/staging/c2/aidl/Android.bp b/staging/c2/aidl/Android.bp
new file mode 100644
index 0000000..b9da7ad
--- /dev/null
+++ b/staging/c2/aidl/Android.bp
@@ -0,0 +1,39 @@
+// This is the expected build file, but it may not be right in all cases
+
+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.media.c2",
+ vendor_available: true,
+ double_loadable: true,
+ unstable: true,
+ srcs: ["android/hardware/media/c2/*.aidl"],
+ include_dirs: [
+ "frameworks/native/aidl/gui",
+ ],
+ imports: [
+ "android.hardware.common-V2",
+ "android.hardware.media.bufferpool2-V1",
+ ],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: true,
+ additional_shared_libraries: [
+ "libnativewindow",
+ ],
+ },
+ },
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/BaseBlock.aidl b/staging/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
new file mode 100644
index 0000000..16e7653
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/BaseBlock.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Storage type for `BaseBlock`.
+ *
+ * A `BaseBlock` is a representation of a codec memory block. Coded data,
+ * decoded data, codec-specific data, and other codec-related data are all sent
+ * in the form of BaseBlocks.
+ */
+union BaseBlock {
+ /**
+ * #nativeBlock is the opaque representation of a buffer.
+ */
+ NativeHandle nativeBlock;
+ /**
+ * #pooledBlock is a reference to a buffer handled by a BufferPool.
+ */
+ android.hardware.media.bufferpool2.BufferStatusMessage pooledBlock;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Block.aidl b/staging/c2/aidl/android/hardware/media/c2/Block.aidl
new file mode 100644
index 0000000..4da8490
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Block.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.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.media.c2.Params;
+
+/**
+ * Reference to a @ref BaseBlock within a @ref WorkBundle.
+ *
+ * `Block` contains additional attributes that `BaseBlock` does not. These
+ * attributes may differ among `Block` objects that refer to the same
+ * `BaseBlock` in the same `WorkBundle`.
+ */
+parcelable Block {
+ /**
+ * Identity of a `BaseBlock` within a `WorkBundle`. This is an index into
+ * #WorkBundle.baseBlocks.
+ */
+ int index;
+ /**
+ * Metadata associated with this `Block`.
+ */
+ Params meta;
+ /**
+ * Fence for synchronizing `Block` access.
+ */
+ NativeHandle fence;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Buffer.aidl b/staging/c2/aidl/android/hardware/media/c2/Buffer.aidl
new file mode 100644
index 0000000..fe01b64
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Buffer.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Block;
+import android.hardware.media.c2.Params;
+
+/**
+ * A codec buffer, which is a collection of @ref Block objects and metadata.
+ *
+ * This is a part of @ref FrameData.
+ */
+parcelable Buffer {
+ /**
+ * Metadata associated with the buffer.
+ */
+ Params info;
+ /**
+ * Blocks contained in the buffer.
+ */
+ Block[] blocks;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
new file mode 100644
index 0000000..3dd14cd
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldDescriptor.aidl
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldId;
+
+/**
+ * Description of a field inside a C2Param structure.
+ */
+parcelable FieldDescriptor {
+ /**
+ * Possible types of the field.
+ */
+ @Backing(type="int")
+ enum Type {
+ NO_INIT = 0,
+ INT32,
+ UINT32,
+ CNTR32,
+ INT64,
+ UINT64,
+ CNTR64,
+ FLOAT,
+ /**
+ * Fixed-size string (POD).
+ */
+ STRING = 0x100,
+ /**
+ * A blob has no sub-elements and can be thought of as an array of
+ * bytes. However, bytes cannot be individually addressed by clients.
+ */
+ BLOB,
+ /**
+ * The field is a structure that may contain other fields.
+ */
+ STRUCT = 0x20000,
+ }
+ /**
+ * Named value type. This is used for defining an enum value for a numeric
+ * type.
+ */
+ parcelable NamedValue {
+ /**
+ * Name of the enum value. This must be unique for each enum value in
+ * the same field.
+ */
+ String name;
+ /**
+ * Underlying value of the enum value. Multiple enum names may have the
+ * same underlying value.
+ */
+ long value;
+ }
+ /**
+ * Location of the field in the C2Param structure
+ */
+ FieldId fieldId;
+ /**
+ * Type of the field.
+ */
+ Type type;
+ /**
+ * If #type is #Type.STRUCT, #structIndex is the C2Param structure index;
+ * otherwise, #structIndex is not used.
+ */
+ int structIndex;
+ /**
+ * Extent of the field.
+ * - For a non-array field, #extent is 1.
+ * - For a fixed-length array field, #extent is the length. An array field
+ * of length 1 is indistinguishable from a non-array field.
+ * - For a variable-length array field, #extent is 0. This can only occur as
+ * the last member of a C2Param structure.
+ */
+ int extent;
+ /**
+ * Name of the field. This must be unique for each field in the same
+ * structure.
+ */
+ String name;
+ /**
+ * List of enum values. This is not used when #type is not one of the
+ * numeric types.
+ */
+ NamedValue[] namedValues;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldId.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldId.aidl
new file mode 100644
index 0000000..c53f7a5
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldId.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Identifying information of a field relative to a known C2Param structure.
+ *
+ * Within a given C2Param structure, each field is uniquely identified by @ref
+ * FieldId.
+ */
+parcelable FieldId {
+ /**
+ * Offset of the field in bytes.
+ */
+ int offset;
+ /**
+ * Size of the field in bytes.
+ */
+ int sizeBytes;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
new file mode 100644
index 0000000..5f4ad2a
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValues.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.ValueRange;
+
+/*
+ * Description of supported values for a field of C2Param.
+ *
+ * This can be a continuous range or a discrete set of values.
+ *
+ * The intended type of values must be made clear in the context where
+ * `FieldSupportedValues` is used.
+ */
+union FieldSupportedValues {
+ /**
+ * No supported values
+ */
+ boolean empty;
+ /**
+ * Numeric range, described in a #ValueRange structure
+ */
+ ValueRange range;
+ /**
+ * List of values
+ */
+ long[] values;
+ /**
+ * List of flags that can be OR-ed.
+ *
+ * The list contains { min-mask, flag1, flag2... }. Basically, the first
+ * value is the required set of flags to be set, and the rest of the values are flags that can
+ * be set independently. FLAGS is only supported for integral types. Supported flags should
+ * not overlap, as it can make validation non-deterministic. The standard validation method
+ * is that starting from the original value, if each flag is removed when fully present (the
+ * min-mask must be fully present), we shall arrive at 0.
+ */
+ long[] flags;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
new file mode 100644
index 0000000..33a8170
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQuery.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.ParamField;
+
+/**
+ * Query information for supported values of a field. This is used as input to
+ * IConfigurable::querySupportedValues().
+ */
+parcelable FieldSupportedValuesQuery {
+ @Backing(type="int")
+ enum Type {
+ /**
+ * Query all possible values regardless of other settings.
+ */
+ POSSIBLE = 0,
+ /**
+ * Query currently possible values given dependent settings.
+ */
+ CURRENT,
+ }
+ /**
+ * Identity of the field to query.
+ */
+ ParamField field;
+ /**
+ * Type of the query. See #Type for more information.
+ */
+ Type type;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.aidl
new file mode 100644
index 0000000..133712a
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FieldSupportedValuesQueryResult.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.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValues;
+import android.hardware.media.c2.Status;
+
+/**
+ * This structure is used to hold the result from
+ * IConfigurable::querySupportedValues().
+ */
+parcelable FieldSupportedValuesQueryResult {
+ /**
+ * Result of the query. Possible values are
+ * - `Status::OK`: The query was successful.
+ * - `Status::BAD_STATE`: The query was requested when the `IConfigurable` instance
+ * was in a bad state.
+ * - `Status::BAD_INDEX`: The requested field was not recognized.
+ * - `Status::TIMED_OUT`: The query could not be completed in a timely manner.
+ * - `Status::BLOCKING`: The query must block, but the parameter `mayBlock` in the
+ * call to `querySupportedValues()` was `false`.
+ * - `Status::CORRUPTED`: Some unknown error occurred.
+ */
+ Status status;
+ /**
+ * Supported values. This is meaningful only when #status is `OK`.
+ */
+ FieldSupportedValues values;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/FrameData.aidl b/staging/c2/aidl/android/hardware/media/c2/FrameData.aidl
new file mode 100644
index 0000000..81c76be
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/FrameData.aidl
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+import android.hardware.media.c2.InfoBuffer;
+import android.hardware.media.c2.Params;
+import android.hardware.media.c2.WorkOrdinal;
+
+/**
+ * Data for an input frame or an output frame.
+ *
+ * This structure represents a @e frame with its metadata. A @e frame consists
+ * of an ordered set of buffers, configuration changes, and info buffers along
+ * with some non-configuration metadata.
+ *
+ * @note `FrameData` is the HIDL counterpart of `C2FrameData` in the Codec 2.0
+ * standard.
+ */
+parcelable FrameData {
+ /** List of frame flags */
+ /**
+ * For input frames: no output frame shall be generated when processing
+ * this frame, but metadata must still be processed.
+ *
+ * For output frames: this frame must be discarded but metadata is still
+ * valid.
+ */
+ const int DROP_FRAME = (1 << 0);
+ /**
+ * This frame is the last frame of the current stream. Further frames
+ * are part of a new stream.
+ */
+ const int END_OF_STREAM = (1 << 1);
+ /**
+ * This frame must be discarded with its metadata.
+ *
+ * This flag is only set by components, e.g. as a response to the flush
+ * command.
+ */
+ const int DISCARD_FRAME = (1 << 2);
+ /**
+ * This frame is not the last frame produced for the input.
+ *
+ * This flag is normally set by the component - e.g. when an input frame
+ * results in multiple output frames, this flag is set on all but the
+ * last output frame.
+ *
+ * Also, when components are chained, this flag should be propagated
+ * down the work chain. That is, if set on an earlier frame of a
+ * work-chain, it should be propagated to all later frames in that
+ * chain. Additionally, components down the chain could set this flag
+ * even if not set earlier, e.g. if multiple output frames are generated
+ * at that component for the input frame.
+ */
+ const int FLAG_INCOMPLETE = (1 << 3);
+ /**
+ * This frame contains only codec-specific configuration data, and no
+ * actual access unit.
+ */
+ const int CODEC_CONFIG = (1 << 31);
+ /**
+ * Frame flags, as described above.
+ */
+ int flags;
+ /**
+ * @ref WorkOrdinal of the frame.
+ */
+ WorkOrdinal ordinal;
+ /**
+ * List of frame buffers.
+ */
+ Buffer[] buffers;
+ /**
+ * List of configuration updates.
+ */
+ Params configUpdate;
+ /**
+ * List of info buffers.
+ */
+ InfoBuffer[] infoBuffers;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponent.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponent.aidl
new file mode 100644
index 0000000..bea4b70
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponent.aidl
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+import android.view.Surface;
+
+import android.hardware.media.c2.IComponentInterface;
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.WorkBundle;
+import android.hardware.media.c2.SurfaceSyncObj;
+
+/**
+ * Interface for an AIDL Codec2 component.
+ * Components have two states: stopped and running. The running state has three
+ * sub-states: executing, tripped and error.
+ *
+ * All methods in `IComponent` must not block. If a method call cannot be
+ * completed in a timely manner, it must throw `Status::TIMED_OUT`.
+ */
+interface IComponent {
+ /**
+ * The reference object from framwork to HAL C2BlockPool.
+ *
+ * The object will be returned when C2BlockPool is created by a framework
+ * request. The object also can be destroyed using blockPoolId.
+ * Using configurable framework can query/config the object in HAL(IComponent).
+ */
+ parcelable BlockPool {
+ long blockPoolId;
+ IConfigurable configurable;
+ }
+ /**
+ * Configures a component for a tunneled playback mode.
+ *
+ * A successful call to this method puts the component in the *tunneled*
+ * mode. In this mode, the output `Worklet`s returned in
+ * IComponentListener::onWorkDone() may not contain any buffers. The output
+ * buffers are passed directly to the consumer end of a buffer queue whose
+ * producer side is configured with the returned @p sidebandStream passed
+ * to IGraphicBufferProducer::setSidebandStream().
+ *
+ * The component is initially in the non-tunneled mode by default. The
+ * tunneled mode can be toggled on only before the component starts
+ * processing. Once the component is put into the tunneled mode, it shall
+ * stay in the tunneled mode until and only until reset() is called.
+ *
+ * @param avSyncHwId A resource ID for hardware sync. The generator of sync
+ * IDs must ensure that this number is unique among all services at any
+ * given time. For example, if both the audio HAL and the tuner HAL
+ * support this feature, sync IDs from the audio HAL must not clash
+ * with sync IDs from the tuner HAL.
+ * @return Codec-allocated sideband stream NativeHandle. This can
+ * be passed to IGraphicBufferProducer::setSidebandStream() to
+ * establish a direct channel to the consumer.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::OMITTED` - The component does not support video tunneling.
+ * - `Status::BAD_STATE` - The component is already running.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ NativeHandle configureVideoTunnel(in int avSyncHwId);
+
+ /**
+ * Creates a local `C2BlockPool` backed by the given allocator and returns
+ * its id.
+ *
+ * The returned @p blockPoolId is the only way the client can refer to a
+ * `C2BlockPool` object in the component. The id can be passed to
+ * setOutputSurface() or used in some C2Param objects later.
+ *
+ * The created `C2BlockPool` object can be destroyed by calling
+ * destroyBlockPool(), reset() or release(). reset() and release() must
+ * destroy all `C2BlockPool` objects that have been created.
+ *
+ * @param allocatorId Id of a `C2Allocator`.
+ * @param out configurable Configuration interface for the created pool. This
+ * must not be null.
+ * @return Created block pool information. This could be used to config/query and
+ * also be used in setOutputSurface() if the allocator
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Not enough memory to create the pool.
+ * - `Status::BAD_VALUE` - @p allocatorId is not recognized.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ BlockPool createBlockPool(in int allocatorId);
+
+ /**
+ * Destroys a local block pool previously created by createBlockPool().
+ *
+ * @param blockPoolId Id of a `C2BlockPool` that was previously returned by
+ * createBlockPool().
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - The supplied blockPoolId is not valid.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void destroyBlockPool(in long blockPoolId);
+
+ /**
+ * Drains the component, and optionally downstream components. This is a
+ * signalling method; as such it does not wait for any work completion.
+ *
+ * The last `Work` item is marked as "drain-till-here", so the component is
+ * notified not to wait for further `Work` before it processes what is
+ * already queued. This method can also be used to set the end-of-stream
+ * flag after `Work` has been queued. Client can continue to queue further
+ * `Work` immediately after this method returns.
+ *
+ * This method must be supported in running (including tripped) states.
+ *
+ * `Work` that is completed must be returned via
+ * IComponentListener::onWorkDone().
+ *
+ * @param withEos Whether to drain the component with marking end-of-stream.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void drain(in boolean withEos);
+
+ /**
+ * Discards and abandons any pending `Work` items for the component.
+ *
+ * This method must be supported in running (including tripped) states.
+ *
+ * `Work` that could be immediately abandoned/discarded must be returned in
+ * @p flushedWorkBundle. The order in which queued `Work` items are
+ * discarded can be arbitrary.
+ *
+ * `Work` that could not be abandoned or discarded immediately must be
+ * marked to be discarded at the earliest opportunity, and must be returned
+ * via IComponentListener::onWorkDone(). This must be completed within
+ * 500ms.
+ *
+ * @return `WorkBundle` object containing flushed `Work` items.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ WorkBundle flush();
+
+ /**
+ * Returns the @ref IComponentInterface instance associated to this
+ * component.
+ *
+ * An @ref IConfigurable instance for the component can be obtained by calling
+ * IComponentInterface::getConfigurable() on the returned @p intf.
+ *
+ * @return `IComponentInterface` instance. This must not be null.
+ */
+ IComponentInterface getInterface();
+
+ /**
+ * Queues up work for the component.
+ *
+ * This method must be supported in running (including tripped) states.
+ *
+ * It is acceptable for this method to return `OK` and return an error value
+ * using the IComponentListener::onWorkDone() callback.
+ *
+ * @param workBundle `WorkBundle` object containing a list of `Work` objects
+ * to queue to the component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_INDEX` - Some component id in some `Worklet` is not valid.
+ * - `Status::CANNOT_DO` - The components are not tunneled but some `Work` object
+ * contains tunneling information.
+ * - `Status::NO_MEMORY` - Not enough memory to queue @p workBundle.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void queue(in WorkBundle workBundle);
+
+ /**
+ * Releases the component.
+ *
+ * This method must be supported in stopped state.
+ *
+ * This method destroys the component. Upon return, if @p status is `OK` or
+ * `DUPLICATE`, all resources must have been released.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - The component is running.
+ * - `Status::DUPLICATE` - The component is already released.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void release();
+
+ /**
+ * Resets the component.
+ *
+ * This method must be supported in all (including tripped) states other
+ * than released.
+ *
+ * This method must be supported during any other blocking call.
+ *
+ * This method must return within 500ms.
+ *
+ * When this call returns, if @p status is `OK`, all `Work` items must
+ * have been abandoned, and all resources (including `C2BlockPool` objects
+ * previously created by createBlockPool()) must have been released.
+ *
+ * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+ * expected as a response to this call. For all other return values, the
+ * component must be in the stopped state.
+ *
+ * This brings settings back to their default, "guaranteeing" no tripped
+ * state.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - Component is in released state.
+ * - `Status::DUPLICATE` - When called during another reset call from another
+ * thread.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void reset();
+
+ /**
+ * Starts using a surface for output with a synchronization object
+ *
+ * This method must not block.
+ *
+ * @param blockPoolId Id of the `C2BlockPool` to be associated with the
+ * output surface.
+ * @param surface Output surface.
+ * @param syncObject synchronization object for buffer allocation between
+ * Framework and Component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::CANNOT_DO` - The component does not support an output surface.
+ * - `Status::REFUSED` - The output surface cannot be accessed.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void setOutputSurface(in long blockPoolId, in Surface surface,
+ in SurfaceSyncObj syncObject);
+
+ /**
+ * Starts the component.
+ *
+ * This method must be supported in stopped state as well as tripped state.
+ *
+ * If the return value is `OK`, the component must be in the running state.
+ * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+ * expected as a response to this call. Otherwise, the component must be in
+ * the stopped state.
+ *
+ * If a component is in the tripped state and start() is called while the
+ * component configuration still results in a trip, start() must succeed and
+ * a new onTripped() callback must be used to communicate the configuration
+ * conflict that results in the new trip.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - Component is not in stopped or tripped state.
+ * - `Status::DUPLICATE` - When called during another start call from another
+ * thread.
+ * - `Status::NO_MEMORY` - Not enough memory to start the component.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void start();
+
+ /**
+ * Stops the component.
+ *
+ * This method must be supported in running (including tripped) state.
+ *
+ * This method must return within 500ms.
+ *
+ * Upon this call, all pending `Work` must be abandoned.
+ *
+ * If the return value is `BAD_STATE` or `DUPLICATE`, no state change is
+ * expected as a response to this call. For all other return values, the
+ * component must be in the stopped state.
+ *
+ * This does not alter any settings and tunings that may have resulted in a
+ * tripped state.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BAD_STATE` - Component is not in running state.
+ * - `Status::DUPLICATE` - When called during another stop call from another
+ * thread.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void stop();
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
new file mode 100644
index 0000000..4589115
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponentInterface.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.IConfigurable;
+
+/**
+ * Component interface object. This object contains all of the configurations of
+ * a potential or actual component. It can be created and used independently of
+ * an actual Codec2 component to query supported parameters for various
+ * component settings, and configurations for a potential component.
+ *
+ * An actual component exposes this interface via IComponent::getInterface().
+ */
+interface IComponentInterface {
+ /**
+ * Returns the @ref IConfigurable instance associated to this component
+ * interface.
+ *
+ * @return `IConfigurable` instance. This must not be null.
+ */
+ IConfigurable getConfigurable();
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponentListener.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
new file mode 100644
index 0000000..786c8f1
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponentListener.aidl
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.SettingResult;
+import android.hardware.media.c2.Status;
+import android.hardware.media.c2.WorkBundle;
+
+/**
+ * Callback interface for handling notifications from @ref IComponent.
+ */
+oneway interface IComponentListener {
+ /**
+ * Identifying information for an input buffer previously queued to the
+ * component via IComponent::queue().
+ */
+ parcelable InputBuffer {
+ /**
+ * This value comes from `Work::input.ordinal.frameIndex` in a `Work`
+ * object that was previously queued.
+ */
+ long frameIndex;
+ /**
+ * This value is an index into `Work::input.buffers` (which is an array)
+ * in a `Work` object that was previously queued.
+ */
+ int arrayIndex;
+ }
+ /**
+ * Information about rendering of a frame to a `Surface`.
+ */
+ parcelable RenderedFrame {
+ /**
+ * Id of the `BufferQueue` containing the rendered buffer.
+ *
+ * This value must have been obtained by an earlier call to
+ * IGraphicBufferProducer::getUniqueId().
+ */
+ long bufferQueueId;
+ /**
+ * Id of the slot of the rendered buffer.
+ *
+ * This value must have been obtained by an earlier call to
+ * IGraphicBufferProducer::dequeueBuffer() or
+ * IGraphicBufferProducer::attachBuffer().
+ */
+ int slotId;
+ /**
+ * Timestamp the rendering happened.
+ *
+ * The reference point for the timestamp is determined by the
+ * `BufferQueue` that performed the rendering.
+ */
+ long timestampNs;
+ }
+ /**
+ * Notify the listener of an error.
+ *
+ * @param status Error type. @p status may be `OK`, which means that an
+ * error has occurred, but the error type does not fit into the type
+ * `Status`. In this case, additional information is provided by
+ * @p errorCode.
+ * @param errorCode Additional error information. The framework may not
+ * recognize the meaning of this value.
+ */
+ void onError(in Status status, in int errorCode);
+
+ /**
+ * Notify the listener that frames have been rendered.
+ *
+ * @param renderedFrames List of @ref RenderedFrame objects.
+ */
+ void onFramesRendered(in RenderedFrame[] renderedFrames);
+
+ /**
+ * Notify the listener that some input buffers are no longer needed by the
+ * component, and hence can be released or reused by the client.
+ *
+ * Input buffers that are contained in a `Work` object returned by an
+ * earlier onWorkDone() call are assumed released, so they must not appear
+ * in any onInputBuffersReleased() calls. That means
+ * onInputBuffersReleased() must only report input buffers that are released
+ * before the output in the same `Work` item is produced. However, it is
+ * possible for an input buffer to be returned by onWorkDone() after it has
+ * been reported by onInputBuffersReleased().
+ *
+ * @note onWorkDone() and onInputBuffersReleased() both notify the client
+ * that input buffers are no longer needed. However, in order to minimize
+ * IPC calls, onInputBuffersReleased() should be called only when
+ * onWorkDone() cannot be called, e.g., the component needs more input
+ * before an output can be produced.
+ *
+ * @param inputBuffers List of `InputBuffer` objects, identifying input
+ * buffers that are no longer needed by the component.
+ */
+ void onInputBuffersReleased(in InputBuffer[] inputBuffers);
+
+ /**
+ * Notify the listener that the component is tripped.
+ *
+ * @param settingResults List of failures.
+ */
+ void onTripped(in SettingResult[] settingResults);
+
+ /**
+ * Notify the listener that some `Work` items have been completed.
+ *
+ * All the input buffers in the returned `Work` objects must not be used by
+ * the component after onWorkDone() is called.
+ *
+ * @param workBundle List of completed `Work` objects.
+ */
+ void onWorkDone(in WorkBundle workBundle);
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IComponentStore.aidl b/staging/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
new file mode 100644
index 0000000..d332bd3
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IComponentStore.aidl
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+import android.hardware.media.c2.IComponent;
+import android.hardware.media.c2.IComponentInterface;
+import android.hardware.media.c2.IComponentListener;
+import android.hardware.media.c2.IConfigurable;
+import android.hardware.media.c2.StructDescriptor;
+
+/**
+ * Entry point for Codec2 HAL.
+ *
+ * All methods in `IComponentStore` must not block. If a method call cannot be
+ * completed in a timely manner, it must throw `Status::TIMED_OUT`. The only
+ * exceptions are getPoolClientManager() and getConfigurable(), which must
+ * always return immediately.
+ *
+ * @note This is an extension of version 1.1 of `IComponentStore`. The purpose
+ * of the extension is to add support for blocking output buffer allocator.
+ */
+interface IComponentStore {
+ /**
+ * Component traits.
+ */
+ parcelable ComponentTraits {
+ @Backing(type="int")
+ enum Kind {
+ OTHER = 0,
+ DECODER,
+ ENCODER,
+ }
+ @Backing(type="int")
+ enum Domain {
+ OTHER = 0,
+ VIDEO,
+ AUDIO,
+ IMAGE,
+ }
+ /**
+ * Name of the component. This must be unique for each component.
+ *
+ * This name is use to identify the component to create in
+ * createComponent() and createComponentInterface().
+ */
+ String name;
+ /**
+ * Component domain.
+ */
+ Domain domain;
+ /**
+ * Component kind.
+ */
+ Kind kind;
+ /**
+ * Rank used by `MediaCodecList` to determine component ordering. Lower
+ * value means higher priority.
+ */
+ int rank;
+ /**
+ * MIME type.
+ */
+ String mediaType;
+ /**
+ * Aliases for component name for backward compatibility.
+ *
+ * Multiple components can have the same alias (but not the same
+ * component name) as long as their media types differ.
+ */
+ String[] aliases;
+ }
+
+ /**
+ * Copies the contents of @p src into @p dst without changing the format of
+ * @p dst.
+ *
+ * @param src Source buffer.
+ * @param dst Destination buffer.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::CANNOT_DO` - @p src and @p dst are not compatible.
+ * - `Status::REFUSED` - No permission to copy.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ void copyBuffer(in Buffer src, in Buffer dst);
+
+ /**
+ * Creates a component by name.
+ *
+ * @param name Name of the component to create. This must match one of the
+ * names returned by listComponents().
+ * @param listener Callback receiver.
+ * @param pool `IClientManager` object of the BufferPool in the client
+ * process. This may be null if the client does not own a BufferPool.
+ * @return The created component.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - There is no component with the given name.
+ * - `Status::NO_MEMORY` - Not enough memory to create the component.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ *
+ * @sa IComponentListener.
+ */
+ IComponent createComponent(in String name, in IComponentListener listener,
+ in android.hardware.media.bufferpool2.IClientManager pool);
+
+ /**
+ * Creates a component interface by name.
+ *
+ * @param name Name of the component interface to create. This should match
+ * one of the names returned by listComponents().
+ * @return The created component interface.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - There is no component interface with the given name.
+ * - `Status::NO_MEMORY` - Not enough memory to create the component interface.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ IComponentInterface createInterface(in String name);
+
+ /**
+ * Returns the @ref IConfigurable instance associated to this component
+ * store.
+ *
+ * @return `IConfigurable` instance. This must not be null.
+ */
+ IConfigurable getConfigurable();
+
+ /**
+ * Returns the `IClientManager` object for the component's BufferPool.
+ *
+ * @return If the component store supports receiving buffers via
+ * BufferPool API, @p pool must be a valid `IClientManager` instance.
+ * Otherwise, @p pool must be null.
+ */
+ android.hardware.media.bufferpool2.IClientManager getPoolClientManager();
+
+ /**
+ * Returns a list of `StructDescriptor` objects for a set of requested
+ * C2Param structure indices that this store is aware of.
+ *
+ * This operation must be performed at best effort, e.g. the component
+ * store must simply ignore all struct indices that it is not aware of.
+ *
+ * @param indices Indices of C2Param structures to describe.
+ * @return List of `StructDescriptor` objects.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NOT_FOUND` - Some indices were not known.
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ StructDescriptor[] getStructDescriptors(in int[] indices);
+
+ /**
+ * Returns the list of components supported by this component store.
+ *
+ * @return traits List of component traits for all components supported by
+ * this store (in no particular order).
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ ComponentTraits[] listComponents();
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/IConfigurable.aidl b/staging/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
new file mode 100644
index 0000000..9f79576
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValuesQuery;
+import android.hardware.media.c2.FieldSupportedValuesQueryResult;
+import android.hardware.media.c2.ParamDescriptor;
+import android.hardware.media.c2.Params;
+import android.hardware.media.c2.SettingResult;
+
+/**
+ * Generic configuration interface presented by all configurable Codec2 objects.
+ *
+ * This interface must be supported in all states of the owning object, and must
+ * not change the state of the owning object.
+ */
+interface IConfigurable {
+ /**
+ * Return parcelable for config() interface.
+ *
+ * This includes the successful config settings along with the failure reasons of
+ * the specified setting.
+ */
+ parcelable ConfigResult {
+ Params params;
+ SettingResult[] failures;
+ }
+
+ /**
+ * Sets a set of parameters for the object.
+ *
+ * Tuning is performed at best effort: the object must update all supported
+ * configurations at best effort and skip unsupported parameters. Any errors
+ * are communicated in the return value along with the failures.
+ *
+ * A non-strict parameter update with an unsupported value shall cause an
+ * update to the closest supported value. A strict parameter update with an
+ * unsupported value shall be skipped and a failure shall be returned.
+ *
+ * If @p mayBlock is false, this method must not block. An update that
+ * requires blocking shall be skipped and a failure shall be returned.
+ *
+ * If @p mayBlock is true, an update may block, but the whole method call
+ * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
+ *
+ * The final values for all parameters set are propagated back to the caller
+ * in @p params.
+ *
+ * \par For IComponent
+ *
+ * When the object type is @ref IComponent, this method must be supported in
+ * any state except released.
+ *
+ * The blocking behavior of this method differs among states:
+ * - In the stopped state, this must be non-blocking. @p mayBlock is
+ * ignored. (The method operates as if @p mayBlock was false.)
+ * - In any of the running states, this method may block momentarily if
+ * @p mayBlock is true. However, if the call cannot be completed in a
+ * timely manner, `Status::TIMED_OUT` is thrown.
+ *
+ * @note Parameter tuning @e does depend on the order of the tuning
+ * parameters, e.g., some parameter update may enable some subsequent
+ * parameter update.
+ *
+ * @param inParams Requested parameter updates.
+ * @param mayBlock Whether this call may block or not.
+ * @return result of config. Params in the result should be in same order
+ * with @p inParams.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Some supported parameters could not be updated
+ * successfully because they contained unsupported values.
+ * These are returned in @p failures.
+ * - `Status::BLOCKING` - Setting some parameters requires blocking, but
+ * @p mayBlock is false.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ ConfigResult config(in Params inParams, in boolean mayBlock);
+
+ /**
+ * Returns the id of the object. This must be unique among all objects of
+ * the same type hosted by the same store.
+ *
+ * @return Id of the object.
+ */
+ int getId();
+
+ /**
+ * Returns the name of the object.
+ *
+ * This must match the name that was supplied during the creation of the
+ * object.
+ *
+ * @return Name of the object.
+ */
+ String getName();
+
+ /**
+ * Queries a set of parameters from the object.
+ *
+ * Querying is performed at best effort: the object must query all supported
+ * parameters and skip unsupported ones (which may include parameters that
+ * could not be allocated).
+ *
+ * If @p mayBlock is true, a query may block, but the whole method call
+ * has to complete in a timely manner, or `Status::TIMED_OUT` is thrown.
+ *
+ * If @p mayBlock is false, this method must not block(All parameter queries
+ * that require blocking must be skipped). Otherwise, this
+ * method is allowed to block for a certain period of time before completing
+ * the operation. If the operation is not completed in a timely manner,
+ * `Status::TIMED_OUT` is thrown.
+ *
+ * @note Since unsupported parameters will be skipped, the returned results
+ * does not have every settings from @p indices, but the result will preserve
+ * the original order from @p indices though unsupported settings are skipped.
+ *
+ * \par For IComponent
+ *
+ * When the object type is @ref IComponent, this method must be supported in
+ * any state except released. This call must not change the state nor the
+ * internal configuration of the component.
+ *
+ * The blocking behavior of this method differs among states:
+ * - In the stopped state, this must be non-blocking. @p mayBlock is
+ * ignored. (The method operates as if @p mayBlock was false.)
+ * - In any of the running states, this method may block momentarily if
+ * @p mayBlock is true. However, if the call cannot be completed in a
+ * timely manner, `Status::status` is thrown.
+ *
+ * @param indices List of C2Param structure indices to query.
+ * @param mayBlock Whether this call may block or not.
+ * @return Flattened representation of std::vector<C2Param> object.
+ * Unsupported settings are skipped in the results. The order in @p indices
+ * still be preserved except skipped settings.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Could not allocate memory for a supported parameter.
+ * - `Status::BLOCKING` - Querying some parameters requires blocking, but
+ * @p mayBlock is false.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ Params query(in int[] indices, in boolean mayBlock);
+
+ /**
+ * Returns a list of supported parameters within a selected range of C2Param
+ * structure indices.
+ *
+ * @param start The first index of the selected range.
+ * @param count The length of the selected range.
+ * @return List of supported parameters in the selected range. This
+ * list may have fewer than @p count elements if some indices in the
+ * range are not supported.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ *
+ */
+ ParamDescriptor[] querySupportedParams(in int start, in int count);
+
+ /**
+ * Retrieves the supported values for the queried fields.
+ *
+ * The object must process all fields queried even if some queries fail.
+ *
+ * If @p mayBlock is false, this method must not block. Otherwise, this
+ * method is allowed to block for a certain period of time before completing
+ * the operation. If the operation cannot be completed in a timely manner,
+ * `Status::TIMED_OUT` is thrown.
+ *
+ * \par For IComponent
+ *
+ * When the object type is @ref IComponent, this method must be supported in
+ * any state except released.
+ *
+ * The blocking behavior of this method differs among states:
+ * - In the stopped state, this must be non-blocking. @p mayBlock is
+ * ignored. (The method operates as if @p mayBlock was false.)
+ * - In any of the running states, this method may block momentarily if
+ * @p mayBlock is true. However, if the call cannot be completed in a
+ * timely manner, `Status::TIMED_OUT` is thrown.
+ *
+ * @param inFields List of field queries.
+ * @param mayBlock Whether this call may block or not.
+ * @return List of supported values and results for the
+ * supplied queries.
+ * @throws ServiceSpecificException with one of the following values:
+ * - `Status::BLOCKING` - Querying some parameters requires blocking, but
+ * @p mayBlock is false.
+ * - `Status::NO_MEMORY` - Not enough memory to complete this method.
+ * - `Status::BLOCKING` - Querying some fields requires blocking, but @p mayblock
+ * is false.
+ * - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
+ * - `Status::CORRUPTED` - Some unknown error occurred.
+ */
+ FieldSupportedValuesQueryResult[] querySupportedValues(
+ in FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl b/staging/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
new file mode 100644
index 0000000..7cfabcb
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/InfoBuffer.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.Buffer;
+
+/**
+ * An extension of @ref Buffer that also contains a C2Param structure index.
+ *
+ * This is a part of @ref FrameData.
+ */
+parcelable InfoBuffer {
+ /**
+ * A C2Param structure index.
+ */
+ int index;
+ /**
+ * Associated @ref Buffer object.
+ */
+ Buffer buffer;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl b/staging/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
new file mode 100644
index 0000000..716c07e
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ParamDescriptor.aidl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Usage description of a C2Param structure.
+ *
+ * @ref ParamDescriptor is returned by IConfigurable::querySupportedParams().
+ */
+parcelable ParamDescriptor {
+ /** The list of bit flags for attrib */
+ /**
+ * The parameter is required to be specified.
+ */
+ const int ATTRIBUTE_REQUIRED = 1 << 0;
+ /**
+ * The parameter retains its value.
+ */
+ const int ATTRIBUTE_PERSISTENT = 1 << 1;
+ /**
+ * The parameter is strict.
+ */
+ const int ATTRIBUTE_STRICT = 1 << 2;
+ /**
+ * The parameter is publicly read-only.
+ */
+ const int ATTRIBUTE_READ_ONLY = 1 << 3;
+ /**
+ * The parameter must not be visible to clients.
+ */
+ const int ATTRIBUTE_HIDDEN = 1 << 4;
+ /**
+ * The parameter must not be used by framework (other than testing).
+ */
+ const int ATTRIBUTE_INTERNAL = 1 << 5;
+ /**
+ * The parameter is publicly constant (hence read-only).
+ */
+ const int ATTRIBUTE_CONST = 1 << 6;
+
+ /**
+ * Index of the C2Param structure being described.
+ */
+ int index;
+ /**
+ * bit flag for attribute defined in the above.
+ */
+ int attrib;
+ /**
+ * Name of the structure. This must be unique for each structure.
+ */
+ String name;
+ /**
+ * Indices of other C2Param structures that this C2Param structure depends
+ * on.
+ */
+ int[] dependencies;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ParamField.aidl b/staging/c2/aidl/android/hardware/media/c2/ParamField.aidl
new file mode 100644
index 0000000..94f737d
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ParamField.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldId;
+
+/**
+ * Reference to a field in a C2Param structure.
+ */
+parcelable ParamField {
+ /**
+ * Index of the C2Param structure.
+ */
+ int index;
+ /**
+ * Identifier of the field inside the C2Param structure.
+ */
+ FieldId fieldId;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl b/staging/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
new file mode 100644
index 0000000..4bb9a91
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ParamFieldValues.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldSupportedValues;
+import android.hardware.media.c2.ParamField;
+
+/**
+ * Supported values for a field.
+ *
+ * This is a pair of the field specifier together with an optional supported
+ * values object. This structure is used when reporting parameter configuration
+ * failures and conflicts.
+ */
+parcelable ParamFieldValues {
+ /**
+ * Reference to a field or a C2Param structure.
+ */
+ ParamField paramOrField;
+ /**
+ * Optional supported values for the field if #paramOrField specifies an
+ * actual field that is numeric (non struct, blob or string). Supported
+ * values for arrays (including string and blobs) describe the supported
+ * values for each element (character for string, and bytes for blobs). It
+ * is optional for read-only strings and blobs.
+ */
+ FieldSupportedValues[] values;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Params.aidl b/staging/c2/aidl/android/hardware/media/c2/Params.aidl
new file mode 100644
index 0000000..3c1a321
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Params.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Flattened representation of std::vector<C2Param> object.
+ *
+ * The `Params` type is an array of bytes made up by concatenating a list of
+ * C2Param objects. The start index (offset into @ref Params) of each C2Param
+ * object in the list is divisible by 8. Up to 7 padding bytes may be added
+ * after each C2Param object to achieve this 64-bit alignment.
+ *
+ * Each C2Param object has the following layout:
+ * - 4 bytes: C2Param structure index (of type @ref ParamIndex) identifying the
+ * type of the C2Param object.
+ * - 4 bytes: size of the C2Param object (unsigned 4-byte integer).
+ * - (size - 8) bytes: data of the C2Param object.
+ */
+parcelable Params {
+ byte[] params;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/SettingResult.aidl b/staging/c2/aidl/android/hardware/media/c2/SettingResult.aidl
new file mode 100644
index 0000000..a270146
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/SettingResult.aidl
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.ParamFieldValues;
+
+/**
+ * Information describing the reason the parameter settings may fail, or may be
+ * overridden.
+ */
+parcelable SettingResult {
+ /**
+ * Failure code
+ */
+ @Backing(type="int")
+ enum Failure {
+ /**
+ * Parameter is not supported.
+ */
+ BAD_TYPE,
+ /**
+ * Parameter is not supported on the specific port.
+ */
+ BAD_PORT,
+ /**
+ * Parameter is not supported on the specific stream.
+ */
+ BAD_INDEX,
+ /**
+ * Parameter is read-only and cannot be set.
+ */
+ READ_ONLY,
+ /**
+ * Parameter mismatches input data.
+ */
+ MISMATCH,
+ /**
+ * Strict parameter does not accept value for the field at all.
+ */
+ BAD_VALUE,
+ /**
+ * Strict parameter field value is in conflict with an/other
+ * setting(s).
+ */
+ CONFLICT,
+ /**
+ * Parameter field is out of range due to other settings. (This failure
+ * mode can only be used for strict calculated parameters.)
+ */
+ UNSUPPORTED,
+ /**
+ * Field does not access the requested parameter value at all. It has
+ * been corrected to the closest supported value. This failure mode is
+ * provided to give guidance as to what are the currently supported
+ * values for this field (which may be a subset of the at-all-potential
+ * values).
+ */
+ INFO_BAD_VALUE,
+ /**
+ * Requested parameter value is in conflict with an/other setting(s)
+ * and has been corrected to the closest supported value. This failure
+ * mode is given to provide guidance as to what are the currently
+ * supported values as well as to optionally provide suggestion to the
+ * client as to how to enable the requested parameter value.
+ */
+ INFO_CONFLICT,
+ }
+ Failure failure;
+ /**
+ * Failing (or corrected) field or parameter and optionally, currently
+ * supported values for the field. Values must only be set for field
+ * failures other than `BAD_VALUE`, and only if they are different from the
+ * globally supported values (e.g. due to restrictions by another parameter
+ * or input data).
+ */
+ ParamFieldValues field;
+ /**
+ * Conflicting parameters or fields with (optional) suggested values for any
+ * conflicting fields to avoid the conflict. Values must only be set for
+ * `CONFLICT`, `UNSUPPORTED` or `INFO_CONFLICT` failure code.
+ */
+ ParamFieldValues[] conflicts;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Status.aidl b/staging/c2/aidl/android/hardware/media/c2/Status.aidl
new file mode 100644
index 0000000..660db57
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Status.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Common return values for Codec2 operations.
+ */
+parcelable Status {
+ /**
+ * Operation completed successfully.
+ */
+ const int OK = 0;
+ /**
+ * Argument has invalid value (user error).
+ */
+ const int BAD_VALUE = -22;
+ /**
+ * Argument uses invalid index (user error).
+ */
+ const int BAD_INDEX = -75;
+ /**
+ * Argument/Index is valid but not possible.
+ */
+ const int CANNOT_DO = -2147483646;
+ /**
+ * Object already exists.
+ */
+ const int DUPLICATE = -17;
+ /**
+ * Object not found.
+ */
+ const int NOT_FOUND = -2;
+ /**
+ * Operation is not permitted in the current state.
+ */
+ const int BAD_STATE = -38;
+ /**
+ * Operation would block but blocking is not permitted.
+ */
+ const int BLOCKING = -9930;
+ /**
+ * Not enough memory to complete operation.
+ */
+ const int NO_MEMORY = -12;
+ /**
+ * Missing permission to complete operation.
+ */
+ const int REFUSED = -1;
+ /**
+ * Operation did not complete within timeout.
+ */
+ const int TIMED_OUT = -110;
+ /**
+ * Operation is not implemented/supported (optional only).
+ */
+ const int OMITTED = -74;
+ /**
+ * Some unexpected error prevented the operation.
+ */
+ const int CORRUPTED = -2147483648;
+ /**
+ * Status has not been initialized.
+ */
+ const int NO_INIT = -19;
+
+ int status;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl b/staging/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
new file mode 100644
index 0000000..5d6d2eb
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/StructDescriptor.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FieldDescriptor;
+
+/**
+ * Description of a C2Param structure. It consists of an index and a list of
+ * `FieldDescriptor`s.
+ */
+parcelable StructDescriptor {
+ /**
+ * Index of the structure.
+ *
+ * Actually C2Param::CoreIndex
+ * Core index is the underlying parameter type for a parameter. It is used to describe the
+ * layout of the parameter structure regardless of the component or parameter kind/scope.
+ *
+ * It is used to identify and distinguish global parameters, and also parameters on a given
+ * port or stream. They must be unique for the set of global parameters, as well as for the
+ * set of parameters on each port or each stream, but the same core index can be used for
+ * parameters on different streams or ports, as well as for global parameters and port/stream
+ * parameters.
+ */
+ int type;
+ /**
+ * List of fields in the structure.
+ *
+ * Fields are ordered by their offsets. A field that is a structure is
+ * ordered before its members.
+ */
+ FieldDescriptor[] fields;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl b/staging/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
new file mode 100644
index 0000000..2e7330e
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/SurfaceSyncObj.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.common.NativeHandle;
+/**
+ * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued
+ * output buffers. This keeps # of dequeued buffers from Surface less than
+ * configured max # of dequeued buffers all the time.
+ */
+parcelable SurfaceSyncObj {
+ /**
+ * ASharedMemory for synchronization data. Layout is below
+ *
+ * |lock(futex) 4bytes|
+ * |conditional_variable(futex) 4bytes|
+ * |# of max dequeable buffer 4bytes|
+ * |# of dequeued buffer 4bytes|
+ * |Status of the surface 4bytes|
+ * INIT = 0, Configuring surface is not finished.
+ * ACTIVE = 1, Surface is ready to allocate(dequeue).
+ * SWITCHING = 2, Switching to the new surface. It is blocked
+ * to allocate(dequeue) a buffer until switching
+ * completes.
+ */
+ NativeHandle syncMemory;
+ /**
+ * BufferQueue id.
+ */
+ long bqId;
+ /**
+ * Generation id.
+ */
+ int generationId;
+ /**
+ * Consumer usage flags. See +ndk
+ * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
+ */
+ long consumerUsage;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/ValueRange.aidl b/staging/c2/aidl/android/hardware/media/c2/ValueRange.aidl
new file mode 100644
index 0000000..6707a25
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/ValueRange.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Description of a set of values.
+ *
+ * If the `step` member is 0, and `num` and `denom` are both 1, the `Range`
+ * structure represents a closed interval bounded by `min` and `max`.
+ *
+ * Otherwise, the #ValueRange structure represents a finite sequence of numbers
+ * produced from the following recurrence relation:
+ *
+ * @code
+ * v[0] = min
+ * v[i] = v[i - 1] * num / denom + step ; i >= 1
+ * @endcode
+ *
+ * Both the ratio `num / denom` and the value `step` must be positive. The
+ * last number in the sequence described by this #Range structure is the
+ * largest number in the sequence that is smaller than or equal to `max`.
+ *
+ * @note
+ * The division in the formula may truncate the result if the data type of
+ * these values is an integral type.
+ */
+parcelable ValueRange {
+ /**
+ * Lower end of the range (inclusive).
+ */
+ long min;
+ /**
+ * Upper end of the range (inclusive).
+ */
+ long max;
+ /**
+ * The non-homogeneous term in the recurrence relation.
+ */
+ long step;
+ /**
+ * The numerator of the scale coefficient in the recurrence relation.
+ */
+ long num;
+ /**
+ * The denominator of the scale coefficient in the recurrence relation.
+ */
+ long denom;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Work.aidl b/staging/c2/aidl/android/hardware/media/c2/Work.aidl
new file mode 100644
index 0000000..0732479
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Work.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FrameData;
+import android.hardware.media.c2.Status;
+import android.hardware.media.c2.Worklet;
+
+/**
+ * A collection of input data to and output data from the component.
+ *
+ * A `Work` object holds information about a single work item. It is created by
+ * the client and passed to the component via IComponent::queue(). The component
+ * has two ways of returning a `Work` object to the client:
+ * 1. If the queued `Work` object has been successfully processed,
+ * IComponentListener::onWorkDone() shall be called to notify the listener,
+ * and the output shall be included in the returned `Work` object.
+ * 2. If the client calls IComponent::flush(), a `Work` object that has not
+ * been processed shall be returned.
+ *
+ * `Work` is a part of @ref WorkBundle.
+ */
+parcelable Work {
+ /**
+ * Additional work chain info not part of this work.
+ */
+ byte[] chainInfo;
+ /**
+ * @ref FrameData for the input.
+ */
+ FrameData input;
+ /**
+ * The chain of `Worklet`s.
+ *
+ * The length of #worklets is 1 when tunneling is not enabled.
+ *
+ * If #worklets has more than a single element, the tunnels between
+ * successive components of the work chain must have been successfully
+ * pre-registered at the time that the `Work` is submitted. Allocating the
+ * output buffers in the `Worklet`s is the responsibility of each component
+ * in the chain.
+ *
+ * Upon `Work` submission, #worklets must be an appropriately sized vector
+ * containing `Worklet`s with @ref Worklet.hasOutput set to `false`. After a
+ * successful processing, all but the final `Worklet` in the returned
+ * #worklets must have @ref Worklet.hasOutput set to `false`.
+ */
+ Worklet[] worklets;
+ /**
+ * The number of `Worklet`s successfully processed in this chain.
+ *
+ * This must be initialized to 0 by the client when the `Work` is submitted,
+ * and it must contain the number of `Worklet`s that were successfully
+ * processed when the `Work` is returned to the client.
+ *
+ * #workletsProcessed cannot exceed the length of #worklets. If
+ * #workletsProcessed is smaller than the length of #worklets, #result
+ * cannot be `OK`.
+ */
+ int workletsProcessed;
+ /**
+ * The final outcome of the `Work` (corresponding to #workletsProcessed).
+ *
+ * The value of @ref Status.OK implies that all `Worklet`s have been
+ * successfully processed.
+ */
+ Status result;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/WorkBundle.aidl b/staging/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
new file mode 100644
index 0000000..79b4cdb
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/WorkBundle.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.BaseBlock;
+import android.hardware.media.c2.Work;
+
+/**
+ * List of `Work` objects.
+ *
+ * `WorkBundle` is used in IComponent::queue(), IComponent::flush() and
+ * IComponentListener::onWorkDone(). A `WorkBundle` object consists of a list of
+ * `Work` objects and a list of `BaseBlock` objects. Bundling multiple `Work`
+ * objects together provides two benefits:
+ * 1. Batching of `Work` objects can reduce the number of IPC calls.
+ * 2. If multiple `Work` objects contain `Block`s that refer to the same
+ * `BaseBlock`, the number of `BaseBlock`s that is sent between processes
+ * is also reduced.
+ *
+ * @note `WorkBundle` is the AIDL counterpart of the vector of `C2Work` in the
+ * Codec 2.0 standard. The presence of #baseBlocks helps with minimizing the
+ * data transferred over an IPC.
+ */
+parcelable WorkBundle {
+ /**
+ * A list of Work items.
+ */
+ Work[] works;
+ /**
+ * A list of blocks indexed by elements of #works.
+ */
+ BaseBlock[] baseBlocks;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl b/staging/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
new file mode 100644
index 0000000..eb8b244
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/WorkOrdinal.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+/**
+ * Ordering information of @ref FrameData objects. Each member is used for
+ * comparing urgency: a smaller difference from a reference value indicates that
+ * the associated Work object is more urgent. The reference value for each
+ * member is initialized the first time it is communicated between the client
+ * and the codec, and it may be updated to later values that are communicated.
+ *
+ * Each member of `WorkOrdinal` is stored as an unsigned integer, but the actual
+ * order it represents is derived by subtracting the reference value, then
+ * interpreting the result as a signed number with the same storage size (using
+ * two's complement).
+ *
+ * @note `WorkOrdinal` is the HIDL counterpart of `C2WorkOrdinalStruct` in the
+ * Codec 2.0 standard.
+ */
+parcelable WorkOrdinal {
+ /**
+ * Timestamp in microseconds.
+ */
+ long timestampUs;
+ /**
+ * Frame index.
+ */
+ long frameIndex;
+ /**
+ * Component specific frame ordinal.
+ */
+ long customOrdinal;
+}
diff --git a/staging/c2/aidl/android/hardware/media/c2/Worklet.aidl b/staging/c2/aidl/android/hardware/media/c2/Worklet.aidl
new file mode 100644
index 0000000..04c59c1
--- /dev/null
+++ b/staging/c2/aidl/android/hardware/media/c2/Worklet.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.media.c2;
+
+import android.hardware.media.c2.FrameData;
+import android.hardware.media.c2.SettingResult;
+
+/**
+ * In/out structure containing some instructions for and results from output
+ * processing.
+ *
+ * This is a part of @ref Work. One `Worklet` corresponds to one output
+ * @ref FrameData. The client must construct an original `Worklet` object inside
+ * a @ref Work object for each expected output before calling
+ * IComponent::queue().
+ */
+parcelable Worklet {
+ /**
+ * Component id. (Input)
+ *
+ * This is used only when tunneling is enabled.
+ *
+ * When used, this must match the return value from IConfigurable::getId().
+ */
+ int componentId;
+ /**
+ * List of C2Param objects describing tunings to be applied before
+ * processing this `Worklet`. (Input)
+ */
+ byte[] tunings;
+ /**
+ * List of failures. (Output)
+ */
+ SettingResult[] failures;
+ /**
+ * Output frame data. (Output)
+ */
+ FrameData output;
+}
diff --git a/staging/threadnetwork/aidl/Android.bp b/staging/threadnetwork/aidl/Android.bp
new file mode 100644
index 0000000..b59d6da
--- /dev/null
+++ b/staging/threadnetwork/aidl/Android.bp
@@ -0,0 +1,26 @@
+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.threadnetwork",
+ host_supported: true,
+ vendor_available: true,
+
+ srcs: [
+ "android/hardware/threadnetwork/*.aidl",
+ ],
+
+ unstable: true,
+
+ backend: {
+ ndk: {
+ enabled: true,
+ },
+ },
+}
diff --git a/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChip.aidl b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChip.aidl
new file mode 100644
index 0000000..3c57149
--- /dev/null
+++ b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChip.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.threadnetwork;
+
+import android.hardware.threadnetwork.IThreadChipCallback;
+
+/**
+ * Controls a Thread radio chip on the device.
+ */
+
+interface IThreadChip {
+ /**
+ * The operation failed for the internal error.
+ */
+ const int ERROR_FAILED = 1;
+
+ /**
+ * Insufficient buffers available to send frames.
+ */
+ const int ERROR_NO_BUFS = 2;
+
+ /**
+ * Service is busy and could not service the operation.
+ */
+ const int ERROR_BUSY = 3;
+
+ /**
+ * This method initializes the Thread HAL instance. If open completes
+ * successfully, then the Thread HAL instance is ready to accept spinel
+ * messages through sendSpinelFrame() API.
+ *
+ * @param callback A IThreadChipCallback callback instance. If multiple
+ * callbacks are passed in, the open() will return ERROR_BUSY.
+ *
+ * @throws EX_ILLEGAL_ARGUMENT if the callback handle is invalid (for example, it is null).
+ * @throws ServiceSpecificException with one of the following values:
+ * - ERROR_FAILED The interface cannot be opened due to an internal error.
+ * - ERROR_BUSY This interface is in use.
+ */
+ void open(in IThreadChipCallback callback);
+
+ /**
+ * Close the Thread HAL instance. Must free all resources.
+ *
+ * @throws EX_ILLEGAL_STATE if the Thread HAL instance is not opened.
+ *
+ */
+ void close();
+
+ /**
+ * This method resets the Thread HAL internal state. The callback registered by
+ * `open()` won’t be reset and the resource allocated by `open()` won’t be free.
+ *
+ */
+ void reset();
+
+ /**
+ * This method sends a spinel frame to the Thread HAL.
+ *
+ * This method should block until the frame is sent out successfully or
+ * the method throws errors immediately.
+ *
+ * Spinel Protocol:
+ * https://github.com/openthread/openthread/blob/main/src/lib/spinel/spinel.h
+ *
+ * @param frame The spinel frame to be sent.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * - ERROR_FAILED The Thread HAL failed to send the frame for an internal reason.
+ * - ERROR_NO_BUFS Insufficient buffer space to send the frame.
+ * - ERROR_BUSY The Thread HAL is busy.
+ */
+ void sendSpinelFrame(in byte[] frame);
+}
diff --git a/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChipCallback.aidl b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChipCallback.aidl
new file mode 100644
index 0000000..a0fe88c
--- /dev/null
+++ b/staging/threadnetwork/aidl/android/hardware/threadnetwork/IThreadChipCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.threadnetwork;
+
+interface IThreadChipCallback {
+ /**
+ * This method is called when a spinel frame is received. Thread network
+ * will process the received spinel frame.
+ *
+ * Spinel Protocol:
+ * https://github.com/openthread/openthread/blob/main/src/lib/spinel/spinel.h
+ *
+ * @param frame The received spinel frame.
+ */
+ oneway void onReceiveSpinelFrame(in byte[] frame);
+}
diff --git a/staging/threadnetwork/aidl/default/Android.bp b/staging/threadnetwork/aidl/default/Android.bp
new file mode 100644
index 0000000..8fc22ad
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/Android.bp
@@ -0,0 +1,63 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_defaults {
+ name: "threadnetwork_service_default",
+ vendor: true,
+ relative_install_path: "hw",
+
+ shared_libs: [
+ "android.hardware.threadnetwork-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+
+ static_libs: [
+ "openthread-common",
+ "openthread-hdlc",
+ "openthread-platform",
+ "openthread-posix",
+ "openthread-url",
+ ],
+
+ srcs: [
+ "main.cpp",
+ "service.cpp",
+ "thread_chip.cpp",
+ "utils.cpp",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.threadnetwork-service.sim",
+ defaults: ["threadnetwork_service_default"],
+ init_rc: ["android.hardware.threadnetwork-service.sim.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.threadnetwork-service",
+ defaults: ["threadnetwork_service_default"],
+}
diff --git a/staging/threadnetwork/aidl/default/android.hardware.threadnetwork-service.sim.rc b/staging/threadnetwork/aidl/default/android.hardware.threadnetwork-service.sim.rc
new file mode 100644
index 0000000..2fb409c
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/android.hardware.threadnetwork-service.sim.rc
@@ -0,0 +1,3 @@
+service vendor.threadnetwork_hal /vendor/bin/hw/android.hardware.threadnetwork-service.sim spinel+hdlc+forkpty:///vendor/bin/ot-rcp?forkpty-arg=1
+ class hal
+ user thread_network
diff --git a/staging/threadnetwork/aidl/default/main.cpp b/staging/threadnetwork/aidl/default/main.cpp
new file mode 100644
index 0000000..b6c8bbb
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/main.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <utils/Log.h>
+
+#include "service.hpp"
+
+int main(int argc, char* argv[]) {
+ CHECK_GT(argc, 1);
+ aidl::android::hardware::threadnetwork::Service service(&argv[1], argc - 1);
+
+ ALOGI("Thread Network HAL is running");
+
+ service.startLoop();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/staging/threadnetwork/aidl/default/service.cpp b/staging/threadnetwork/aidl/default/service.cpp
new file mode 100644
index 0000000..8047214
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/service.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "service.hpp"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "thread_chip.hpp"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+Service::Service(char* urls[], int numUrls) : mBinderFd(-1) {
+ int fd;
+
+ CHECK_NE(urls, nullptr);
+ CHECK_GT(numUrls, 0);
+
+ for (int i = 0; i < numUrls; i++) {
+ auto threadChip = ndk::SharedRefBase::make<ThreadChip>(i, urls[i]);
+ CHECK_NE(threadChip, nullptr);
+ mThreadChips.push_back(std::move(threadChip));
+ }
+
+ binder_status_t status = ABinderProcess_setupPolling(&fd);
+ CHECK_EQ(status, ::STATUS_OK);
+ CHECK_GE(fd, 0);
+ mBinderFd.reset(fd);
+}
+
+void Service::Update(otSysMainloopContext& context) {
+ FD_SET(mBinderFd.get(), &context.mReadFdSet);
+ context.mMaxFd = std::max(context.mMaxFd, mBinderFd.get());
+}
+
+void Service::Process(const otSysMainloopContext& context) {
+ if (FD_ISSET(mBinderFd.get(), &context.mReadFdSet)) {
+ ABinderProcess_handlePolledCommands();
+ }
+}
+
+void Service::startLoop(void) {
+ const struct timeval kPollTimeout = {1, 0};
+ otSysMainloopContext context;
+ int rval;
+
+ ot::Posix::Mainloop::Manager::Get().Add(*this);
+
+ while (true) {
+ context.mMaxFd = -1;
+ context.mTimeout = kPollTimeout;
+
+ FD_ZERO(&context.mReadFdSet);
+ FD_ZERO(&context.mWriteFdSet);
+ FD_ZERO(&context.mErrorFdSet);
+
+ ot::Posix::Mainloop::Manager::Get().Update(context);
+
+ rval = select(context.mMaxFd + 1, &context.mReadFdSet, &context.mWriteFdSet,
+ &context.mErrorFdSet, &context.mTimeout);
+
+ if (rval >= 0) {
+ ot::Posix::Mainloop::Manager::Get().Process(context);
+ } else if (errno != EINTR) {
+ ALOGE("select() failed: %s", strerror(errno));
+ break;
+ }
+ }
+}
+} // namespace threadnetwork
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/service.hpp b/staging/threadnetwork/aidl/default/service.hpp
new file mode 100644
index 0000000..6e6e868
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/service.hpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/unique_fd.h>
+
+#include "mainloop.hpp"
+#include "thread_chip.hpp"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+class Service : public ot::Posix::Mainloop::Source {
+ public:
+ Service(char* urls[], int numUrls);
+
+ void Update(otSysMainloopContext& context) override;
+ void Process(const otSysMainloopContext& context) override;
+ void startLoop(void);
+
+ private:
+ ::android::base::unique_fd mBinderFd;
+ std::vector<std::shared_ptr<ThreadChip>> mThreadChips;
+};
+} // namespace threadnetwork
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/thread_chip.cpp b/staging/threadnetwork/aidl/default/thread_chip.cpp
new file mode 100644
index 0000000..38abad4
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/thread_chip.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "thread_chip.hpp"
+
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+static ndk::ScopedAStatus errorStatus(int32_t error, const char* message) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(error, message));
+}
+
+ThreadChip::ThreadChip(uint8_t id, char* url)
+ : mUrl(),
+ mInterface(handleReceivedFrame, this, mRxFrameBuffer),
+ mRxFrameBuffer(),
+ mCallback(nullptr) {
+ const std::string name(std::string() + IThreadChip::descriptor + "/chip" + std::to_string(id));
+ binder_status_t status;
+
+ ALOGI("ServiceName: %s, Url: %s", name.c_str(), url);
+ CHECK_EQ(mUrl.Init(url), 0);
+ status = AServiceManager_addService(asBinder().get(), name.c_str());
+ CHECK_EQ(status, STATUS_OK);
+
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(
+ AIBinder_DeathRecipient_new(ThreadChip::onBinderDied));
+ AIBinder_DeathRecipient_setOnUnlinked(mDeathRecipient.get(), ThreadChip::onBinderUnlinked);
+}
+
+ThreadChip::~ThreadChip() {
+ AIBinder_DeathRecipient_delete(mDeathRecipient.get());
+}
+
+void ThreadChip::onBinderDied(void* context) {
+ reinterpret_cast<ThreadChip*>(context)->onBinderDied();
+}
+
+void ThreadChip::onBinderDied(void) {
+ ALOGW("Thread Network HAL client is dead.");
+}
+
+void ThreadChip::onBinderUnlinked(void* context) {
+ reinterpret_cast<ThreadChip*>(context)->onBinderUnlinked();
+}
+
+void ThreadChip::onBinderUnlinked(void) {
+ ALOGW("ThreadChip binder is unlinked.");
+ deinitChip();
+}
+
+void ThreadChip::handleReceivedFrame(void* context) {
+ reinterpret_cast<ThreadChip*>(context)->handleReceivedFrame();
+}
+
+void ThreadChip::handleReceivedFrame(void) {
+ if (mCallback != nullptr) {
+ mCallback->onReceiveSpinelFrame(std::vector<uint8_t>(
+ mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetFrame() + mRxFrameBuffer.GetLength()));
+ }
+
+ mRxFrameBuffer.DiscardFrame();
+}
+
+ndk::ScopedAStatus ThreadChip::open(const std::shared_ptr<IThreadChipCallback>& in_callback) {
+ ndk::ScopedAStatus status = initChip(in_callback);
+
+ if (status.isOk()) {
+ AIBinder_linkToDeath(in_callback->asBinder().get(), mDeathRecipient.get(), this);
+ ALOGI("Open IThreadChip successfully.");
+ } else {
+ ALOGW("Open IThreadChip failed, error: %s", status.getDescription().c_str());
+ }
+
+ return status;
+}
+
+ndk::ScopedAStatus ThreadChip::initChip(const std::shared_ptr<IThreadChipCallback>& in_callback) {
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ } else if (mCallback == nullptr) {
+ if (mInterface.Init(mUrl) != OT_ERROR_NONE) {
+ return errorStatus(ERROR_FAILED, "Failed to initialize the interface");
+ }
+
+ mCallback = in_callback;
+ ot::Posix::Mainloop::Manager::Get().Add(*this);
+ return ndk::ScopedAStatus::ok();
+ } else {
+ return errorStatus(ERROR_BUSY, "Interface is already opened");
+ }
+}
+
+ndk::ScopedAStatus ThreadChip::close() {
+ ndk::ScopedAStatus status;
+ std::shared_ptr<IThreadChipCallback> callback = mCallback;
+
+ status = deinitChip();
+ if (status.isOk()) {
+ if (callback != nullptr) {
+ AIBinder_unlinkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this);
+ }
+
+ ALOGI("Close IThreadChip successfully");
+ } else {
+ ALOGW("Close IThreadChip failed, error: %s", status.getDescription().c_str());
+ }
+
+ return status;
+}
+
+ndk::ScopedAStatus ThreadChip::deinitChip() {
+ if (mCallback != nullptr) {
+ mInterface.Deinit();
+ ot::Posix::Mainloop::Manager::Get().Remove(*this);
+ mCallback = nullptr;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+}
+
+ndk::ScopedAStatus ThreadChip::sendSpinelFrame(const std::vector<uint8_t>& in_frame) {
+ ndk::ScopedAStatus status;
+ otError error;
+
+ if (mCallback == nullptr) {
+ status = errorStatus(ERROR_FAILED, "The interface is not open");
+ } else {
+ error = mInterface.SendFrame(reinterpret_cast<const uint8_t*>(in_frame.data()),
+ in_frame.size());
+ if (error == OT_ERROR_NONE) {
+ status = ndk::ScopedAStatus::ok();
+ } else if (error == OT_ERROR_NO_BUFS) {
+ status = errorStatus(ERROR_NO_BUFS, "Insufficient buffer space to send");
+ } else if (error == OT_ERROR_BUSY) {
+ status = errorStatus(ERROR_BUSY, "The interface is busy");
+ } else {
+ status = errorStatus(ERROR_FAILED, "Failed to send the spinel frame");
+ }
+ }
+
+ if (!status.isOk()) {
+ ALOGW("Send spinel frame failed, error: %s", status.getDescription().c_str());
+ }
+
+ return status;
+}
+
+ndk::ScopedAStatus ThreadChip::reset() {
+ mInterface.OnRcpReset();
+ ALOGI("reset()");
+ return ndk::ScopedAStatus::ok();
+}
+
+void ThreadChip::Update(otSysMainloopContext& context) {
+ if (mCallback != nullptr) {
+ mInterface.UpdateFdSet(context.mReadFdSet, context.mWriteFdSet, context.mMaxFd,
+ context.mTimeout);
+ }
+}
+
+void ThreadChip::Process(const otSysMainloopContext& context) {
+ struct RadioProcessContext radioContext;
+
+ if (mCallback != nullptr) {
+ radioContext.mReadFdSet = &context.mReadFdSet;
+ radioContext.mWriteFdSet = &context.mWriteFdSet;
+ mInterface.Process(radioContext);
+ }
+}
+} // namespace threadnetwork
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/thread_chip.hpp b/staging/threadnetwork/aidl/default/thread_chip.hpp
new file mode 100644
index 0000000..da5cba7
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/thread_chip.hpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/threadnetwork/BnThreadChip.h>
+#include <aidl/android/hardware/threadnetwork/IThreadChipCallback.h>
+
+#include "hdlc_interface.hpp"
+#include "lib/spinel/spinel_interface.hpp"
+#include "mainloop.hpp"
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+#include <utils/Mutex.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace threadnetwork {
+
+class ThreadChip : public BnThreadChip, ot::Posix::Mainloop::Source {
+ public:
+ ThreadChip(uint8_t id, char* url);
+ ~ThreadChip();
+
+ ndk::ScopedAStatus open(const std::shared_ptr<IThreadChipCallback>& in_callback) override;
+ ndk::ScopedAStatus close() override;
+ ndk::ScopedAStatus sendSpinelFrame(const std::vector<uint8_t>& in_frame) override;
+ ndk::ScopedAStatus reset() override;
+ void Update(otSysMainloopContext& context) override;
+ void Process(const otSysMainloopContext& context) override;
+
+ private:
+ static void onBinderDied(void* context);
+ void onBinderDied(void);
+ static void onBinderUnlinked(void* context);
+ void onBinderUnlinked(void);
+ static void handleReceivedFrame(void* context);
+ void handleReceivedFrame(void);
+
+ ndk::ScopedAStatus initChip(const std::shared_ptr<IThreadChipCallback>& in_callback);
+ ndk::ScopedAStatus deinitChip();
+
+ ot::Url::Url mUrl;
+ ot::Posix::HdlcInterface mInterface;
+ ot::Spinel::SpinelInterface::RxFrameBuffer mRxFrameBuffer;
+ std::shared_ptr<IThreadChipCallback> mCallback;
+ ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+
+} // namespace threadnetwork
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/staging/threadnetwork/aidl/default/utils.cpp b/staging/threadnetwork/aidl/default/utils.cpp
new file mode 100644
index 0000000..d3b4062
--- /dev/null
+++ b/staging/threadnetwork/aidl/default/utils.cpp
@@ -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.
+ */
+
+#include <openthread/logging.h>
+#include <utils/Log.h>
+
+void otLogCritPlat(const char* format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ __android_log_vprint(ANDROID_LOG_FATAL, LOG_TAG, format, args);
+ va_end(args);
+}
+
+void otLogWarnPlat(const char* format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ __android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, args);
+ va_end(args);
+}
diff --git a/staging/threadnetwork/aidl/vts/Android.bp b/staging/threadnetwork/aidl/vts/Android.bp
new file mode 100644
index 0000000..e2609ed
--- /dev/null
+++ b/staging/threadnetwork/aidl/vts/Android.bp
@@ -0,0 +1,47 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalThreadNetworkTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "VtsHalThreadNetworkTargetTest.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.threadnetwork-ndk",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/staging/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp b/staging/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
new file mode 100644
index 0000000..3e43f9c
--- /dev/null
+++ b/staging/threadnetwork/aidl/vts/VtsHalThreadNetworkTargetTest.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ThreadNetworkHalTargetTest"
+
+#include <future>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <log/log.h>
+
+#include <aidl/android/hardware/threadnetwork/BnThreadChipCallback.h>
+#include <aidl/android/hardware/threadnetwork/IThreadChip.h>
+
+using aidl::android::hardware::threadnetwork::BnThreadChipCallback;
+using aidl::android::hardware::threadnetwork::IThreadChip;
+using android::ProcessState;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+namespace {
+constexpr static int kCallbackTimeoutMs = 5000;
+} // namespace
+
+class ThreadChipCallback : public BnThreadChipCallback {
+ public:
+ ThreadChipCallback(const std::function<void(const std::vector<uint8_t>&)>& on_spinel_message_cb)
+ : on_spinel_message_cb_(on_spinel_message_cb) {}
+
+ ScopedAStatus onReceiveSpinelFrame(const std::vector<uint8_t>& in_aFrame) {
+ on_spinel_message_cb_(in_aFrame);
+ return ScopedAStatus::ok();
+ }
+
+ private:
+ std::function<void(const std::vector<uint8_t>&)> on_spinel_message_cb_;
+};
+
+class ThreadNetworkAidl : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ std::string serviceName = GetParam();
+
+ ALOGI("serviceName: %s", serviceName.c_str());
+
+ thread_chip = IThreadChip::fromBinder(
+ SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+ ASSERT_NE(thread_chip, nullptr);
+ }
+
+ virtual void TearDown() override { thread_chip->close(); }
+
+ std::shared_ptr<IThreadChip> thread_chip;
+};
+
+TEST_P(ThreadNetworkAidl, Open) {
+ std::shared_ptr<ThreadChipCallback> callback =
+ ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
+
+ EXPECT_TRUE(thread_chip->open(callback).isOk());
+ EXPECT_EQ(thread_chip->open(callback).getServiceSpecificError(), IThreadChip::ERROR_BUSY);
+}
+
+TEST_P(ThreadNetworkAidl, Close) {
+ std::shared_ptr<ThreadChipCallback> callback =
+ ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
+
+ EXPECT_TRUE(thread_chip->open(callback).isOk());
+ EXPECT_TRUE(thread_chip->close().isOk());
+ EXPECT_EQ(thread_chip->close().getExceptionCode(), EX_ILLEGAL_STATE);
+}
+
+TEST_P(ThreadNetworkAidl, Reset) {
+ std::shared_ptr<ThreadChipCallback> callback =
+ ndk::SharedRefBase::make<ThreadChipCallback>([](auto /* data */) {});
+
+ EXPECT_TRUE(thread_chip->open(callback).isOk());
+ EXPECT_TRUE(thread_chip->reset().isOk());
+}
+
+TEST_P(ThreadNetworkAidl, SendSpinelFrame) {
+ const uint8_t kCmdOffset = 2;
+ const uint8_t kMajorVersionOffset = 3;
+ const uint8_t kMinorVersionOffset = 4;
+ const std::vector<uint8_t> kGetSpinelProtocolVersion({0x81, 0x02, 0x01});
+ const std::vector<uint8_t> kGetSpinelProtocolVersionResponse({0x81, 0x06, 0x01, 0x04, 0x03});
+ uint8_t min_major_version = kGetSpinelProtocolVersionResponse[kMajorVersionOffset];
+ uint8_t min_minor_version = kGetSpinelProtocolVersionResponse[kMinorVersionOffset];
+ uint8_t major_version;
+ uint8_t minor_version;
+ std::promise<void> open_cb_promise;
+ std::future<void> open_cb_future{open_cb_promise.get_future()};
+ std::shared_ptr<ThreadChipCallback> callback;
+ std::vector<uint8_t> received_frame;
+ std::chrono::milliseconds timeout{kCallbackTimeoutMs};
+
+ callback = ndk::SharedRefBase::make<ThreadChipCallback>(
+ [&](const std::vector<uint8_t>& in_aFrame) {
+ if (in_aFrame.size() == kGetSpinelProtocolVersionResponse.size() &&
+ in_aFrame[kCmdOffset] == kGetSpinelProtocolVersionResponse[kCmdOffset]) {
+ major_version = in_aFrame[kMajorVersionOffset];
+ minor_version = in_aFrame[kMinorVersionOffset];
+ open_cb_promise.set_value();
+ }
+ });
+
+ ASSERT_NE(callback, nullptr);
+
+ EXPECT_TRUE(thread_chip->open(callback).isOk());
+
+ EXPECT_TRUE(thread_chip->sendSpinelFrame(kGetSpinelProtocolVersion).isOk());
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+
+ EXPECT_GE(major_version, min_major_version);
+ if (major_version == min_major_version) {
+ EXPECT_GE(minor_version, min_minor_version);
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThreadNetworkAidl);
+INSTANTIATE_TEST_SUITE_P(
+ Thread, ThreadNetworkAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IThreadChip::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/tetheroffload/aidl/Android.bp b/tetheroffload/aidl/Android.bp
index 1d80586..b3b6ebf 100644
--- a/tetheroffload/aidl/Android.bp
+++ b/tetheroffload/aidl/Android.bp
@@ -4,6 +4,7 @@
aidl_interface {
name: "android.hardware.tetheroffload",
+ owner: "google",
vendor_available: true,
srcs: ["android/hardware/tetheroffload/*.aidl"],
stability: "vintf",
@@ -23,5 +24,4 @@
apps_enabled: false,
},
},
- frozen: false,
}
diff --git a/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp b/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
index f46c9ab..1049ea2 100644
--- a/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
+++ b/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
@@ -690,6 +690,7 @@
::android::PrintInstanceNameToString);
} // namespace
+} // namespace aidl::android::hardware::tetheroffload
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
@@ -697,5 +698,3 @@
ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}
-
-} // namespace aidl::android::hardware::tetheroffload
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index 73c5dd2..835fbfa 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -95,20 +95,15 @@
mThermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
ASSERT_NE(mThermalCallback, nullptr);
- auto status = mThermal->registerThermalChangedCallback(mThermalCallback);
- ASSERT_TRUE(status.isOk());
- // Expect to fail if register again
- status = mThermal->registerThermalChangedCallback(mThermalCallback);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
}
void TearDown() override {
- auto status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
- ASSERT_TRUE(status.isOk());
+ ::ndk::ScopedAStatus status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
// Expect to fail if unregister again
status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
- ASSERT_FALSE(status.isOk());
ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
}
@@ -121,11 +116,142 @@
// This just calls into and back from our local ThermalChangedCallback impl.
TEST_P(ThermalAidlTest, NotifyThrottlingTest) {
std::shared_ptr<ThermalCallback> thermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
- auto ret = thermalCallback->notifyThrottling(kThrottleTemp);
- ASSERT_TRUE(ret.isOk());
+ ::ndk::ScopedAStatus status = thermalCallback->notifyThrottling(kThrottleTemp);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
ASSERT_TRUE(thermalCallback->waitForCallback(200ms));
}
+// Test Thermal->registerThermalChangedCallback.
+TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackTest) {
+ // Expect to fail with same callback
+ ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ // Expect to fail with null callback
+ status = mThermal->registerThermalChangedCallback(nullptr);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ std::shared_ptr<ThermalCallback> localThermalCallback =
+ ndk::SharedRefBase::make<ThermalCallback>();
+ // Expect to succeed with different callback
+ status = mThermal->registerThermalChangedCallback(localThermalCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ // Remove the local callback
+ status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ // Expect to fail with null callback
+ status = mThermal->unregisterThermalChangedCallback(nullptr);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+}
+
+// Test Thermal->registerThermalChangedCallbackWithType.
+TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackWithTypeTest) {
+ // Expect to fail with same callback
+ ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallbackWithType(
+ mThermalCallback, TemperatureType::SKIN);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ // Expect to fail with null callback
+ status = mThermal->registerThermalChangedCallbackWithType(nullptr, TemperatureType::SKIN);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+ std::shared_ptr<ThermalCallback> localThermalCallback =
+ ndk::SharedRefBase::make<ThermalCallback>();
+ // Expect to succeed with different callback
+ status = mThermal->registerThermalChangedCallbackWithType(localThermalCallback,
+ TemperatureType::SKIN);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ // Remove the local callback
+ status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
+ ASSERT_TRUE(status.isOk()) << status.getMessage();
+ // Expect to fail with null callback
+ status = mThermal->unregisterThermalChangedCallback(nullptr);
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+}
+
+// Test Thermal->getCurrentTemperatures().
+TEST_P(ThermalAidlTest, TemperatureTest) {
+ std::vector<Temperature> ret;
+ ::ndk::ScopedAStatus status = mThermal->getTemperatures(&ret);
+ if (status.isOk()) {
+ for (auto& i : ret) {
+ EXPECT_LT(0u, i.name.size());
+ LOG(INFO) << i.name + " " + toString(i.type) << "\n";
+ }
+ } else {
+ ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+ }
+
+ auto types = ::ndk::enum_range<TemperatureType>();
+ for (const auto& type : types) {
+ status = mThermal->getTemperaturesWithType(type, &ret);
+
+ if (status.isOk()) {
+ for (auto& i : ret) {
+ EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
+ toString(i.type) + " for " + i.name;
+ EXPECT_LT(0u, i.name.size());
+ }
+ } else {
+ ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+ }
+ }
+}
+
+// Test Thermal->getTemperatureThresholds().
+TEST_P(ThermalAidlTest, TemperatureThresholdTest) {
+ std::vector<TemperatureThreshold> ret;
+ ::ndk::ScopedAStatus status = mThermal->getTemperatureThresholds(&ret);
+ if (status.isOk()) {
+ for (auto& i : ret) {
+ EXPECT_LT(0u, i.name.size());
+ LOG(INFO) << i.name + " " + toString(i.type) << "\n";
+ }
+ } else {
+ ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+ }
+
+ auto types = ::ndk::enum_range<TemperatureType>();
+ for (const auto& type : types) {
+ status = mThermal->getTemperatureThresholdsWithType(type, &ret);
+
+ if (status.isOk()) {
+ for (auto& i : ret) {
+ EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
+ toString(i.type) + " for " + i.name;
+ EXPECT_LT(0u, i.name.size());
+ }
+ } else {
+ ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+ }
+ }
+}
+
+// Test Thermal->getCoolingDevices().
+TEST_P(ThermalAidlTest, CoolingDeviceTest) {
+ std::vector<CoolingDevice> ret;
+ ::ndk::ScopedAStatus status = mThermal->getCoolingDevices(&ret);
+ if (status.isOk()) {
+ for (auto& i : ret) {
+ EXPECT_LT(0u, i.name.size());
+ LOG(INFO) << i.name + " " + toString(i.type) << "\n";
+ }
+ } else {
+ ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+ }
+
+ auto types = ::ndk::enum_range<CoolingType>();
+ for (const auto& type : types) {
+ status = mThermal->getCoolingDevicesWithType(type, &ret);
+ if (status.isOk()) {
+ ASSERT_TRUE(status.isOk());
+ for (auto& i : ret) {
+ EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
+ toString(i.type) + " for " + i.name;
+ EXPECT_LT(0u, i.name.size());
+ }
+ } else {
+ ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
+ }
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalAidlTest);
INSTANTIATE_TEST_SUITE_P(
Thermal, ThermalAidlTest,
@@ -133,6 +259,7 @@
::android::PrintInstanceNameToString);
} // namespace
+} // namespace aidl::android::hardware::thermal
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
@@ -140,5 +267,3 @@
ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}
-
-} // namespace aidl::android::hardware::thermal
diff --git a/thermal/utils/Android.bp b/thermal/utils/Android.bp
new file mode 100644
index 0000000..72e1e34
--- /dev/null
+++ b/thermal/utils/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_static {
+ name: "libthermalutils",
+ vendor_available: true,
+ export_include_dirs: ["include"],
+ srcs: [
+ "ThermalHidlWrapper.cpp",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "[email protected]",
+ "android.hardware.thermal-V1-ndk",
+ ],
+}
diff --git a/thermal/utils/ThermalHidlWrapper.cpp b/thermal/utils/ThermalHidlWrapper.cpp
new file mode 100644
index 0000000..05a992a
--- /dev/null
+++ b/thermal/utils/ThermalHidlWrapper.cpp
@@ -0,0 +1,305 @@
+/*
+ * 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 "include/thermalutils/ThermalHidlWrapper.h"
+
+#include <hidl/HidlTransportSupport.h>
+
+#include <cmath>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace thermal {
+
+using ::android::hardware::Void;
+
+namespace {
+
+template <typename T, typename U>
+Return<void> setFailureAndCallback(T _hidl_cb, hidl_vec<U> data, std::string_view debug_msg) {
+ ThermalStatus status;
+ status.code = ThermalStatusCode::FAILURE;
+ status.debugMessage = debug_msg.data();
+ _hidl_cb(status, data);
+ return Void();
+}
+
+template <typename T>
+Return<void> setFailureAndCallback(T _hidl_cb, std::string_view debug_msg) {
+ ThermalStatus status;
+ status.code = ThermalStatusCode::FAILURE;
+ status.debugMessage = debug_msg.data();
+ _hidl_cb(status);
+ return Void();
+}
+
+template <typename T, typename U>
+Return<void> setInitFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
+ return setFailureAndCallback(
+ _hidl_cb, data, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
+}
+
+template <typename T>
+Return<void> setInitFailureAndCallback(T _hidl_cb) {
+ return setFailureAndCallback(
+ _hidl_cb, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
+}
+
+template <typename T, typename U>
+Return<void> setUnsupportedFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
+ return setFailureAndCallback(_hidl_cb, data, "Operation unsupported by Thermal HIDL wrapper");
+}
+
+TemperatureType_2_0 convertAidlTemperatureType(const TemperatureType& type) {
+ if (type < TemperatureType::CPU || type > TemperatureType::NPU) {
+ return TemperatureType_2_0::UNKNOWN;
+ }
+ return static_cast<TemperatureType_2_0>(type);
+}
+
+CoolingType_2_0 convertAidlCoolingType(const CoolingType& type) {
+ if (type < CoolingType::FAN || type > CoolingType::COMPONENT) {
+ return CoolingType_2_0::COMPONENT;
+ }
+ return static_cast<CoolingType_2_0>(type);
+}
+
+Temperature_2_0 convertAidlTemperature(const Temperature& temperature) {
+ Temperature_2_0 t = Temperature_2_0{
+ convertAidlTemperatureType(temperature.type), temperature.name, temperature.value,
+ static_cast<ThrottlingSeverity_2_0>(temperature.throttlingStatus)};
+ return t;
+}
+
+CoolingDevice_2_0 convertAidlCoolingDevice(const CoolingDevice& cooling_device) {
+ CoolingDevice_2_0 t =
+ CoolingDevice_2_0{convertAidlCoolingType(cooling_device.type), cooling_device.name,
+ static_cast<uint64_t>(cooling_device.value)};
+ return t;
+}
+TemperatureThreshold_2_0 convertAidlTemperatureThreshold(const TemperatureThreshold& threshold) {
+ TemperatureThreshold_2_0 t =
+ TemperatureThreshold_2_0{convertAidlTemperatureType(threshold.type), threshold.name,
+ threshold.hotThrottlingThresholds.data(),
+ threshold.coldThrottlingThresholds.data(), NAN};
+ return t;
+}
+
+} // namespace
+
+// Methods from ::android::hardware::thermal::V1_0::IThermal follow.
+Return<void> ThermalHidlWrapper::getTemperatures(getTemperatures_cb _hidl_cb) {
+ hidl_vec<Temperature_1_0> ret_1_0;
+ setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
+ return Void();
+}
+
+Return<void> ThermalHidlWrapper::getCpuUsages(
+ std::function<void(const ThermalStatus&, const hidl_vec<CpuUsage>&)> _hidl_cb) {
+ hidl_vec<CpuUsage> ret_1_0;
+ setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
+ return Void();
+}
+
+Return<void> ThermalHidlWrapper::getCoolingDevices(
+ std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_1_0>&)> _hidl_cb) {
+ hidl_vec<CoolingDevice_1_0> ret_1_0;
+ setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
+ return Void();
+}
+
+// Methods from ::android::hardware::thermal::V2_0::IThermal follow.
+Return<void> ThermalHidlWrapper::getCurrentTemperatures(
+ bool filterType, TemperatureType_2_0 type,
+ std::function<void(const ThermalStatus&, const hidl_vec<Temperature_2_0>&)> _hidl_cb) {
+ hidl_vec<Temperature_2_0> ret_2_0;
+ if (!thermal_service_) {
+ setInitFailureAndCallback(_hidl_cb, ret_2_0);
+ }
+
+ std::vector<Temperature> ret_aidl;
+ ThermalStatus status;
+ ::ndk::ScopedAStatus a_status;
+ if (filterType) {
+ a_status = thermal_service_->getTemperaturesWithType(static_cast<TemperatureType>(type),
+ &ret_aidl);
+ } else {
+ a_status = thermal_service_->getTemperatures(&ret_aidl);
+ }
+ if (a_status.isOk()) {
+ std::vector<Temperature_2_0> ret;
+ for (const auto& temperature : ret_aidl) {
+ ret.push_back(convertAidlTemperature(temperature));
+ }
+ _hidl_cb(status, hidl_vec<Temperature_2_0>(ret));
+ } else {
+ setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
+ }
+ return Void();
+}
+
+Return<void> ThermalHidlWrapper::getTemperatureThresholds(
+ bool filterType, TemperatureType_2_0 type,
+ std::function<void(const ThermalStatus&, const hidl_vec<TemperatureThreshold_2_0>&)>
+ _hidl_cb) {
+ hidl_vec<TemperatureThreshold_2_0> ret_2_0;
+ if (!thermal_service_) {
+ setInitFailureAndCallback(_hidl_cb, ret_2_0);
+ }
+
+ std::vector<TemperatureThreshold> ret_aidl;
+ ThermalStatus status;
+ ::ndk::ScopedAStatus a_status;
+ if (filterType) {
+ a_status = thermal_service_->getTemperatureThresholdsWithType(
+ static_cast<TemperatureType>(type), &ret_aidl);
+ } else {
+ a_status = thermal_service_->getTemperatureThresholds(&ret_aidl);
+ }
+ if (a_status.isOk()) {
+ std::vector<TemperatureThreshold_2_0> ret;
+ for (const auto& threshold : ret_aidl) {
+ ret.push_back(convertAidlTemperatureThreshold(threshold));
+ }
+ _hidl_cb(status, hidl_vec<TemperatureThreshold_2_0>(ret));
+ } else {
+ setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
+ }
+ return Void();
+}
+
+Return<void> ThermalHidlWrapper::registerThermalChangedCallback(
+ const sp<IThermalChangedCallback_2_0>& callback, bool filterType, TemperatureType_2_0 type,
+ std::function<void(const ThermalStatus&)> _hidl_cb) {
+ if (!thermal_service_) {
+ setInitFailureAndCallback(_hidl_cb);
+ }
+ if (callback == nullptr) {
+ setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
+ return Void();
+ }
+ std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
+ for (const auto& callback_wrapper : callback_wrappers_) {
+ if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
+ callback.get())) {
+ setFailureAndCallback(_hidl_cb, "The callback was already registered through wrapper");
+ return Void();
+ }
+ }
+ std::shared_ptr<IThermalChangedCallbackWrapper> callback_wrapper =
+ ndk::SharedRefBase::make<IThermalChangedCallbackWrapper>(callback);
+ ::ndk::ScopedAStatus a_status;
+ ThermalStatus status;
+ if (filterType) {
+ a_status = thermal_service_->registerThermalChangedCallbackWithType(
+ callback_wrapper, static_cast<TemperatureType>(type));
+ } else {
+ a_status = thermal_service_->registerThermalChangedCallback(callback_wrapper);
+ }
+ if (a_status.isOk()) {
+ callback_wrappers_.push_back(callback_wrapper);
+ _hidl_cb(status);
+ } else {
+ setFailureAndCallback(_hidl_cb, a_status.getMessage());
+ }
+ return Void();
+}
+
+Return<void> ThermalHidlWrapper::unregisterThermalChangedCallback(
+ const sp<IThermalChangedCallback_2_0>& callback,
+ std::function<void(const ThermalStatus&)> _hidl_cb) {
+ if (!thermal_service_) {
+ setInitFailureAndCallback(_hidl_cb);
+ }
+ if (callback == nullptr) {
+ setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
+ return Void();
+ }
+ std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
+ for (auto it = callback_wrappers_.begin(); it != callback_wrappers_.end(); it++) {
+ auto callback_wrapper = *it;
+ if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
+ callback.get())) {
+ ::ndk::ScopedAStatus a_status;
+ ThermalStatus status;
+ a_status = thermal_service_->unregisterThermalChangedCallback(callback_wrapper);
+ if (a_status.isOk()) {
+ callback_wrappers_.erase(it);
+ _hidl_cb(status);
+ } else {
+ setFailureAndCallback(_hidl_cb, a_status.getMessage());
+ }
+ return Void();
+ }
+ }
+ setFailureAndCallback(_hidl_cb, "The callback was not registered through wrapper before");
+ return Void();
+}
+
+Return<void> ThermalHidlWrapper::getCurrentCoolingDevices(
+ bool filterType, CoolingType_2_0 type,
+ std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_2_0>&)> _hidl_cb) {
+ hidl_vec<CoolingDevice_2_0> ret_2_0;
+ if (!thermal_service_) {
+ setInitFailureAndCallback(_hidl_cb, ret_2_0);
+ }
+
+ std::vector<CoolingDevice> ret_aidl;
+ ThermalStatus status;
+ ::ndk::ScopedAStatus a_status;
+ if (filterType) {
+ a_status = thermal_service_->getCoolingDevicesWithType(static_cast<CoolingType>(type),
+ &ret_aidl);
+ } else {
+ a_status = thermal_service_->getCoolingDevices(&ret_aidl);
+ }
+ if (a_status.isOk()) {
+ std::vector<CoolingDevice_2_0> ret;
+ for (const auto& cooling_device : ret_aidl) {
+ ret.push_back(convertAidlCoolingDevice(cooling_device));
+ }
+ _hidl_cb(status, hidl_vec<CoolingDevice_2_0>(ret));
+ } else {
+ setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
+ }
+ return Void();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+Return<void> ThermalHidlWrapper::debug(const hidl_handle& handle,
+ const hidl_vec<hidl_string>& args) {
+ if (handle != nullptr && handle->numFds >= 1) {
+ int fd = handle->data[0];
+ char** arr = new char*[args.size()];
+ for (size_t i = 0; i < args.size(); i++) {
+ arr[i] = strdup(args[i].c_str());
+ }
+ thermal_service_->dump(fd, (const char**)arr, args.size());
+ }
+ return Void();
+}
+
+::ndk::ScopedAStatus ThermalHidlWrapper::IThermalChangedCallbackWrapper::notifyThrottling(
+ const Temperature& temperature) {
+ callback_2_0_->notifyThrottling(convertAidlTemperature(temperature));
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace thermal
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/thermal/utils/include/thermalutils/ThermalHidlWrapper.h b/thermal/utils/include/thermalutils/ThermalHidlWrapper.h
new file mode 100644
index 0000000..1fec100
--- /dev/null
+++ b/thermal/utils/include/thermalutils/ThermalHidlWrapper.h
@@ -0,0 +1,106 @@
+/*
+ * 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/thermal/BnThermalChangedCallback.h>
+#include <aidl/android/hardware/thermal/IThermal.h>
+#include <android/hardware/thermal/2.0/IThermal.h>
+#include <android/hardware/thermal/2.0/IThermalChangedCallback.h>
+#include <android/hardware/thermal/2.0/types.h>
+#include <hidl/Status.h>
+
+#include <utility>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace thermal {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+
+using IThermal_Aidl = ::aidl::android::hardware::thermal::IThermal;
+using ::android::hardware::thermal::V1_0::CpuUsage;
+using CoolingType_2_0 = ::android::hardware::thermal::V2_0::CoolingType;
+using CoolingDevice_1_0 = ::android::hardware::thermal::V1_0::CoolingDevice;
+using CoolingDevice_2_0 = ::android::hardware::thermal::V2_0::CoolingDevice;
+using IThermal_2_0 = ::android::hardware::thermal::V2_0::IThermal;
+using IThermalChangedCallback_2_0 = ::android::hardware::thermal::V2_0::IThermalChangedCallback;
+using Temperature_1_0 = ::android::hardware::thermal::V1_0::Temperature;
+using Temperature_2_0 = ::android::hardware::thermal::V2_0::Temperature;
+using TemperatureType_2_0 = ::android::hardware::thermal::V2_0::TemperatureType;
+
+using ::android::hardware::thermal::V1_0::ThermalStatus;
+using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+
+using TemperatureThreshold_2_0 = ::android::hardware::thermal::V2_0::TemperatureThreshold;
+using ThrottlingSeverity_2_0 = ::android::hardware::thermal::V2_0::ThrottlingSeverity;
+
+// This wrapper converts all Thermal HIDL 2.0 calls to AIDL calls and converts AIDL response to
+// HIDL 2.0 response.
+//
+// For Thermal HIDL 1.0 calls, it returns unsupported error.
+class ThermalHidlWrapper : public IThermal_2_0 {
+ public:
+ explicit ThermalHidlWrapper(::std::shared_ptr<IThermal_Aidl> thermal_service)
+ : thermal_service_(std::move(thermal_service)) {}
+
+ // Methods from ::android::hardware::thermal::V1_0::IThermal follow.
+ Return<void> getTemperatures(getTemperatures_cb _hidl_cb) override;
+ Return<void> getCpuUsages(getCpuUsages_cb _hidl_cb) override;
+ Return<void> getCoolingDevices(getCoolingDevices_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::thermal::V2_0::IThermal follow.
+ Return<void> getCurrentTemperatures(bool filterType, TemperatureType_2_0 type,
+ getCurrentTemperatures_cb _hidl_cb) override;
+ Return<void> getTemperatureThresholds(bool filterType, TemperatureType_2_0 type,
+ getTemperatureThresholds_cb _hidl_cb) override;
+ Return<void> registerThermalChangedCallback(
+ const sp<IThermalChangedCallback_2_0>& callback, bool filterType,
+ TemperatureType_2_0 type, registerThermalChangedCallback_cb _hidl_cb) override;
+ Return<void> unregisterThermalChangedCallback(
+ const sp<IThermalChangedCallback_2_0>& callback,
+ unregisterThermalChangedCallback_cb _hidl_cb) override;
+ Return<void> getCurrentCoolingDevices(bool filterType, CoolingType_2_0 type,
+ getCurrentCoolingDevices_cb _hidl_cb) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& args) override;
+
+ private:
+ class IThermalChangedCallbackWrapper : public BnThermalChangedCallback {
+ public:
+ explicit IThermalChangedCallbackWrapper(const sp<IThermalChangedCallback_2_0>& callback_2_0)
+ : callback_2_0_(callback_2_0) {}
+ ::ndk::ScopedAStatus notifyThrottling(const Temperature& temperature) override;
+ sp<IThermalChangedCallback_2_0> callback_2_0_;
+ };
+
+ // Reference to thermal service.
+ ::std::shared_ptr<IThermal_Aidl> thermal_service_;
+ // Mutex lock for read/write on callback wrappers.
+ std::mutex callback_wrappers_mutex_;
+ // All thermal changed callback wrappers registered.
+ ::std::vector<std::shared_ptr<IThermalChangedCallbackWrapper>> callback_wrappers_;
+};
+
+} // namespace thermal
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/thermal/utils/tests/Android.bp b/thermal/utils/tests/Android.bp
new file mode 100644
index 0000000..fd74e8b
--- /dev/null
+++ b/thermal/utils/tests/Android.bp
@@ -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.
+ */
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "ThermalHidlWrapperTest",
+ srcs: ["ThermalHidlWrapperTest.cpp"],
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "[email protected]",
+ "[email protected]",
+ "android.hardware.thermal-V1-ndk",
+ ],
+ static_libs: [
+ "libthermalutils",
+ "libgtest",
+ ],
+ test_suites: [
+ "device-tests",
+ ],
+}
diff --git a/thermal/utils/tests/ThermalHidlWrapperTest.cpp b/thermal/utils/tests/ThermalHidlWrapperTest.cpp
new file mode 100644
index 0000000..1723a1a
--- /dev/null
+++ b/thermal/utils/tests/ThermalHidlWrapperTest.cpp
@@ -0,0 +1,302 @@
+/*
+ * 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 "thermal_hidl_wrapper_test"
+#include <VtsHalHidlTargetCallbackBase.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/thermal/BnThermal.h>
+#include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/binder_status.h>
+#include <android/hardware/thermal/2.0/IThermal.h>
+#include <android/hardware/thermal/2.0/IThermalChangedCallback.h>
+#include <android/hardware/thermal/2.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <thermalutils/ThermalHidlWrapper.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <chrono>
+#include <cmath>
+#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
+
+namespace aidl::android::hardware::thermal {
+
+namespace {
+
+using ::android::sp;
+using ::android::hardware::hidl_enum_range;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::thermal::V1_0::ThermalStatus;
+using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+using ::android::hardware::thermal::V2_0::CoolingDevice;
+using ::android::hardware::thermal::V2_0::CoolingType;
+using IThermal_2_0 = ::android::hardware::thermal::V2_0::IThermal;
+using ::android::hardware::thermal::V2_0::IThermalChangedCallback;
+using ::android::hardware::thermal::V2_0::Temperature;
+using ::android::hardware::thermal::V2_0::TemperatureThreshold;
+using ::android::hardware::thermal::V2_0::TemperatureType;
+using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
+
+constexpr char kCallbackNameNotifyThrottling[] = "notifyThrottling";
+static const Temperature kThrottleTemp = {
+ .type = TemperatureType::SKIN,
+ .name = "test temperature sensor",
+ .value = 98.6,
+ .throttlingStatus = ThrottlingSeverity::CRITICAL,
+};
+
+class ThermalCallbackArgs {
+ public:
+ Temperature temperature;
+};
+
+// Callback class for receiving thermal event notifications from main class
+class ThermalCallback : public ::testing::VtsHalHidlTargetCallbackBase<ThermalCallbackArgs>,
+ public IThermalChangedCallback {
+ public:
+ Return<void> notifyThrottling(const Temperature& temperature) override {
+ ThermalCallbackArgs args;
+ args.temperature = temperature;
+ NotifyFromCallback(kCallbackNameNotifyThrottling, args);
+ return Void();
+ }
+};
+
+// The main test class for THERMAL HIDL HAL 2.0.
+class ThermalHidlWrapperTest : public ::testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
+ ASSERT_NE(binder, nullptr);
+ mThermal = sp<ThermalHidlWrapper>::make(IThermal::fromBinder(ndk::SpAIBinder(binder)));
+ ASSERT_NE(mThermal, nullptr);
+ mThermalCallback = new (std::nothrow) ThermalCallback();
+ ASSERT_NE(mThermalCallback, nullptr);
+ auto ret = mThermal->registerThermalChangedCallback(
+ mThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail if register again
+ ret = mThermal->registerThermalChangedCallback(
+ mThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ void TearDown() override {
+ auto ret = mThermal->unregisterThermalChangedCallback(
+ mThermalCallback,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail if unregister again
+ ret = mThermal->unregisterThermalChangedCallback(
+ mThermalCallback,
+ [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ protected:
+ sp<IThermal_2_0> mThermal;
+ sp<ThermalCallback> mThermalCallback;
+}; // class ThermalHidlWrapperTest
+
+// Test ThermalChangedCallback::notifyThrottling().
+// This just calls into and back from our local ThermalChangedCallback impl.
+TEST_P(ThermalHidlWrapperTest, NotifyThrottlingTest) {
+ sp<ThermalCallback> thermalCallback = new (std::nothrow) ThermalCallback();
+ auto ret = thermalCallback->notifyThrottling(kThrottleTemp);
+ ASSERT_TRUE(ret.isOk());
+ auto res = thermalCallback->WaitForCallback(kCallbackNameNotifyThrottling);
+ EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.args);
+ EXPECT_EQ(kThrottleTemp, res.args->temperature);
+}
+
+// Test Thermal->registerThermalChangedCallback.
+TEST_P(ThermalHidlWrapperTest, RegisterThermalChangedCallbackTest) {
+ // Expect to fail with same callback
+ auto ret = mThermal->registerThermalChangedCallback(
+ mThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail with null callback
+ ret = mThermal->registerThermalChangedCallback(
+ nullptr, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback();
+ // Expect to succeed with different callback
+ ret = mThermal->registerThermalChangedCallback(
+ localThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Remove the local callback
+ ret = mThermal->unregisterThermalChangedCallback(
+ localThermalCallback,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail with null callback
+ ret = mThermal->unregisterThermalChangedCallback(nullptr, [](ThermalStatus status) {
+ EXPECT_EQ(ThermalStatusCode::FAILURE, status.code);
+ });
+ ASSERT_TRUE(ret.isOk());
+}
+
+// Test Thermal->unregisterThermalChangedCallback.
+TEST_P(ThermalHidlWrapperTest, UnregisterThermalChangedCallbackTest) {
+ sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback();
+ // Expect to fail as the callback was not registered before
+ auto ret = mThermal->unregisterThermalChangedCallback(
+ localThermalCallback,
+ [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Register a local callback
+ ret = mThermal->registerThermalChangedCallback(
+ localThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to succeed with callback removed
+ ret = mThermal->unregisterThermalChangedCallback(
+ localThermalCallback,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail as the callback has been unregistered already
+ ret = mThermal->unregisterThermalChangedCallback(
+ localThermalCallback,
+ [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+ ASSERT_TRUE(ret.isOk());
+}
+
+// Sanity test for Thermal::getCurrentTemperatures().
+TEST_P(ThermalHidlWrapperTest, TemperatureTest) {
+ mThermal->getCurrentTemperatures(false, TemperatureType::SKIN,
+ [](ThermalStatus status, hidl_vec<Temperature> temperatures) {
+ if (temperatures.size()) {
+ EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+ } else {
+ EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+ }
+ for (int i = 0; i < temperatures.size(); ++i) {
+ EXPECT_LT(0u, temperatures[i].name.size());
+ }
+ });
+ auto types = hidl_enum_range<TemperatureType>();
+ for (const auto& type : types) {
+ mThermal->getCurrentTemperatures(
+ true, type, [&type](ThermalStatus status, hidl_vec<Temperature> temperatures) {
+ if (temperatures.size()) {
+ EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+ } else {
+ EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+ }
+ for (int i = 0; i < temperatures.size(); ++i) {
+ EXPECT_EQ(type, temperatures[i].type);
+ EXPECT_LT(0u, temperatures[i].name.size());
+ }
+ });
+ }
+}
+
+// Sanity test for Thermal::getTemperatureThresholds().
+TEST_P(ThermalHidlWrapperTest, TemperatureThresholdTest) {
+ mThermal->getTemperatureThresholds(
+ false, TemperatureType::SKIN,
+ [](ThermalStatus status, hidl_vec<TemperatureThreshold> temperatures) {
+ if (temperatures.size()) {
+ EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+ } else {
+ EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+ }
+ });
+ for (int i = static_cast<int>(TemperatureType::UNKNOWN);
+ i <= static_cast<int>(TemperatureType::POWER_AMPLIFIER); ++i) {
+ auto type = static_cast<TemperatureType>(i);
+ mThermal->getTemperatureThresholds(
+ true, type,
+ [&type](ThermalStatus status, hidl_vec<TemperatureThreshold> temperatures) {
+ if (temperatures.size()) {
+ EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+ } else {
+ EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+ }
+ for (int i = 0; i < temperatures.size(); ++i) {
+ EXPECT_EQ(type, temperatures[i].type);
+ }
+ });
+ }
+}
+
+// Sanity test for Thermal::getCurrentCoolingDevices().
+TEST_P(ThermalHidlWrapperTest, CoolingDeviceTest) {
+ mThermal->getCurrentCoolingDevices(
+ false, CoolingType::CPU,
+ [](ThermalStatus status, hidl_vec<CoolingDevice> cooling_devices) {
+ if (cooling_devices.size()) {
+ EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+ } else {
+ EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+ }
+ for (int i = 0; i < cooling_devices.size(); ++i) {
+ EXPECT_LT(0u, cooling_devices[i].name.size());
+ }
+ });
+ for (int i = 0; i <= static_cast<int>(CoolingType::COMPONENT); ++i) {
+ auto type = static_cast<CoolingType>(i);
+ mThermal->getCurrentCoolingDevices(
+ true, type, [&type](ThermalStatus status, hidl_vec<CoolingDevice> cooling_devices) {
+ if (cooling_devices.size()) {
+ EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+ } else {
+ EXPECT_NE(ThermalStatusCode::SUCCESS, status.code);
+ }
+ for (int i = 0; i < cooling_devices.size(); ++i) {
+ EXPECT_EQ(type, cooling_devices[i].type);
+ EXPECT_LT(0u, cooling_devices[i].name.size());
+ }
+ });
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalHidlWrapperTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, ThermalHidlWrapperTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IThermal::descriptor)),
+ ::android::hardware::PrintInstanceNameToString);
+
+} // namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
+
+} // namespace aidl::android::hardware::thermal
diff --git a/threadnetwork/OWNERS b/threadnetwork/OWNERS
new file mode 100644
index 0000000..54fd66d
--- /dev/null
+++ b/threadnetwork/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 1288834
+
+include platform/packages/modules/ThreadNetwork:/OWNERS
diff --git a/tv/cec/1.0/default/HdmiCecDefault.cpp b/tv/cec/1.0/default/HdmiCecDefault.cpp
index 26ccb7d..2a5197c 100644
--- a/tv/cec/1.0/default/HdmiCecDefault.cpp
+++ b/tv/cec/1.0/default/HdmiCecDefault.cpp
@@ -278,6 +278,10 @@
Return<bool> HdmiCecDefault::isConnected(int32_t portId) {
uint16_t addr;
+ if (portId < 0 || portId >= mHdmiCecPorts.size()) {
+ LOG(ERROR) << "Port id is out of bounds, portId = " << portId;
+ return false;
+ }
int ret = ioctl(mHdmiCecPorts[portId]->mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
if (ret) {
LOG(ERROR) << "Is connected failed, Error = " << strerror(errno);
diff --git a/tv/hdmi/connection/aidl/TEST_MAPPING b/tv/hdmi/connection/aidl/TEST_MAPPING
new file mode 100644
index 0000000..13cf0c2
--- /dev/null
+++ b/tv/hdmi/connection/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalTvHdmiConnectionAidlTargetTest"
+ }
+ ]
+}
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index be6247b..8f4411b 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -44,7 +44,7 @@
ScopedAStatus HdmiConnectionMock::isConnected(int32_t portId, bool* _aidl_return) {
// Maintain port connection status and update on hotplug event
if (portId <= mTotalPorts && portId >= 1) {
- *_aidl_return = mPortConnectionStatus[portId];
+ *_aidl_return = mPortConnectionStatus.at(portId - 1);
} else {
*_aidl_return = false;
}
@@ -135,10 +135,10 @@
ALOGD("[halimp_aidl] hot plug port id %x, is connected %x", (msgBuf[0] & 0xf),
(msgBuf[3] & 0xf));
- mPortConnectionStatus[portId] = connected;
- if (mPortInfos[portId].type == HdmiPortType::OUTPUT) {
+ mPortConnectionStatus.at(portId - 1) = connected;
+ if (mPortInfos.at(portId - 1).type == HdmiPortType::OUTPUT) {
mPhysicalAddress = (connected ? 0xffff : ((msgBuf[1] << 8) | (msgBuf[2])));
- mPortInfos[portId].physicalAddress = mPhysicalAddress;
+ mPortInfos.at(portId - 1).physicalAddress = mPhysicalAddress;
ALOGD("[halimp_aidl] hot plug physical address %x", mPhysicalAddress);
}
diff --git a/tv/hdmi/connection/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/connection/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5a7fed0
--- /dev/null
+++ b/tv/hdmi/connection/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+<configuration description="Runs VtsHalTvHdmiConnectionAidlTargetTest.">
+ <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="VtsHalTvHdmiConnectionAidlTargetTest->/data/local/tmp/VtsHalTvHdmiConnectionAidlTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalTvHdmiConnectionAidlTargetTest" />
+ <option name="native-test-timeout" value="30m" />
+ </test>
+</configuration>
diff --git a/tv/hdmi/earc/aidl/TEST_MAPPING b/tv/hdmi/earc/aidl/TEST_MAPPING
new file mode 100644
index 0000000..ccc48fc
--- /dev/null
+++ b/tv/hdmi/earc/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalTvHdmiEArcAidlTargetTest"
+ }
+ ]
+}
diff --git a/tv/hdmi/earc/aidl/default/EArcMock.cpp b/tv/hdmi/earc/aidl/default/EArcMock.cpp
index 93395fc..0e92fbd 100644
--- a/tv/hdmi/earc/aidl/default/EArcMock.cpp
+++ b/tv/hdmi/earc/aidl/default/EArcMock.cpp
@@ -54,7 +54,7 @@
ScopedAStatus EArcMock::getState(int32_t portId, IEArcStatus* _aidl_return) {
// Maintain port connection status and update on hotplug event
if (portId <= mTotalPorts && portId >= 1) {
- *_aidl_return = mPortStatus[portId];
+ *_aidl_return = mPortStatus.at(portId - 1);
} else {
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -65,7 +65,7 @@
ScopedAStatus EArcMock::getLastReportedAudioCapabilities(int32_t portId,
std::vector<uint8_t>* _aidl_return) {
if (portId <= mTotalPorts && portId >= 1) {
- *_aidl_return = mCapabilities[portId];
+ *_aidl_return = mCapabilities.at(portId - 1);
} else {
return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
diff --git a/tv/hdmi/earc/aidl/vts/functional/AndroidTest.xml b/tv/hdmi/earc/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..12dd1e4
--- /dev/null
+++ b/tv/hdmi/earc/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+<configuration description="Runs VtsHalTvHdmiEArcAidlTargetTest.">
+ <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="VtsHalTvHdmiEArcAidlTargetTest->/data/local/tmp/VtsHalTvHdmiEArcAidlTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalTvHdmiEArcAidlTargetTest" />
+ <option name="native-test-timeout" value="30m" />
+ </test>
+</configuration>
diff --git a/tv/input/OWNERS b/tv/input/OWNERS
index a02291a..ae65f67 100644
--- a/tv/input/OWNERS
+++ b/tv/input/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 105688
[email protected]
[email protected]
[email protected]
diff --git a/tv/input/aidl/Android.bp b/tv/input/aidl/Android.bp
new file mode 100644
index 0000000..2591151
--- /dev/null
+++ b/tv/input/aidl/Android.bp
@@ -0,0 +1,28 @@
+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.tv.input",
+ vendor_available: true,
+ srcs: ["android/hardware/tv/input/*.aidl"],
+ imports: [
+ "android.hardware.common-V2",
+ "android.media.audio.common.types-V1",
+ "android.hardware.common.fmq-V1",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ },
+ cpp: {
+ enabled: false,
+ },
+ },
+}
diff --git a/tv/input/aidl/TEST_MAPPING b/tv/input/aidl/TEST_MAPPING
new file mode 100644
index 0000000..981e46f
--- /dev/null
+++ b/tv/input/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "VtsHalTvInputTargetTest"
+ }
+ ]
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/CableConnectionStatus.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/CableConnectionStatus.aidl
new file mode 100644
index 0000000..a48bdb1
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/CableConnectionStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum CableConnectionStatus {
+ UNKNOWN = 0,
+ CONNECTED = 1,
+ DISCONNECTED = 2,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
new file mode 100644
index 0000000..84fe2fb
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+interface ITvInput {
+ void closeStream(in int deviceId, in int streamId);
+ android.hardware.tv.input.TvStreamConfig[] getStreamConfigurations(in int deviceId);
+ android.hardware.common.NativeHandle openStream(in int deviceId, in int streamId);
+ void setCallback(in android.hardware.tv.input.ITvInputCallback callback);
+ void setTvMessageEnabled(int deviceId, int streamId, in android.hardware.tv.input.TvMessageEventType type, boolean enabled);
+ void getTvMessageQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue, int deviceId, int streamId);
+ const int STATUS_UNKNOWN = 1;
+ const int STATUS_NO_RESOURCE = 2;
+ const int STATUS_INVALID_ARGUMENTS = 3;
+ const int STATUS_INVALID_STATE = 4;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInputCallback.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInputCallback.aidl
new file mode 100644
index 0000000..9747013
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInputCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+interface ITvInputCallback {
+ void notify(in android.hardware.tv.input.TvInputEvent event);
+ void notifyTvMessageEvent(in android.hardware.tv.input.TvMessageEvent event);
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputDeviceInfo.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputDeviceInfo.aidl
new file mode 100644
index 0000000..d095146
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputDeviceInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvInputDeviceInfo {
+ int deviceId;
+ android.hardware.tv.input.TvInputType type;
+ int portId;
+ android.hardware.tv.input.CableConnectionStatus cableConnectionStatus;
+ android.media.audio.common.AudioDevice audioDevice;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEvent.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEvent.aidl
new file mode 100644
index 0000000..cfa8a34
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvInputEvent {
+ android.hardware.tv.input.TvInputEventType type;
+ android.hardware.tv.input.TvInputDeviceInfo deviceInfo;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEventType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEventType.aidl
new file mode 100644
index 0000000..a9f518a
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvInputEventType {
+ DEVICE_AVAILABLE = 1,
+ DEVICE_UNAVAILABLE = 2,
+ STREAM_CONFIGURATIONS_CHANGED = 3,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputType.aidl
new file mode 100644
index 0000000..7e44a7d
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvInputType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvInputType {
+ OTHER = 1,
+ TUNER = 2,
+ COMPOSITE = 3,
+ SVIDEO = 4,
+ SCART = 5,
+ COMPONENT = 6,
+ VGA = 7,
+ DVI = 8,
+ HDMI = 9,
+ DISPLAY_PORT = 10,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessage.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessage.aidl
new file mode 100644
index 0000000..04cb099
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessage.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvMessage {
+ String subType;
+ long groupId;
+ int dataLengthBytes;
+ const long NO_GROUP_ID = (-1) /* -1 */;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEvent.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEvent.aidl
new file mode 100644
index 0000000..94fe665
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvMessageEvent {
+ android.hardware.tv.input.TvMessageEventType type;
+ int streamId;
+ android.hardware.tv.input.TvMessage[] messages;
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEventType.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEventType.aidl
new file mode 100644
index 0000000..3006198
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvMessageEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@Backing(type="int") @VintfStability
+enum TvMessageEventType {
+ WATERMARK = 1,
+ CLOSED_CAPTION = 2,
+ OTHER = 1000,
+}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvStreamConfig.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvStreamConfig.aidl
new file mode 100644
index 0000000..8378ff3
--- /dev/null
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/TvStreamConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.input;
+@VintfStability
+parcelable TvStreamConfig {
+ int streamId;
+ int maxVideoWidth;
+ int maxVideoHeight;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/CableConnectionStatus.aidl b/tv/input/aidl/android/hardware/tv/input/CableConnectionStatus.aidl
new file mode 100644
index 0000000..64b79dd
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/CableConnectionStatus.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+/**
+ * Status of cable connection.
+ * This status is for devices having availability to detect the cable in a mechanical way,
+ * regardless of whether the connected external device is electrically on or not.
+ * If the device does not have such capability, you must use UNKNOWN.
+ */
+@VintfStability
+@Backing(type="int")
+enum CableConnectionStatus {
+ UNKNOWN = 0,
+ CONNECTED = 1,
+ DISCONNECTED = 2,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
new file mode 100644
index 0000000..cbaf066
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.tv.input.ITvInputCallback;
+import android.hardware.tv.input.TvMessageEventType;
+import android.hardware.tv.input.TvStreamConfig;
+
+@VintfStability
+interface ITvInput {
+ /**
+ * ServiceSpecificException values for ITvInput requests
+ */
+ const int STATUS_UNKNOWN = 1;
+ const int STATUS_NO_RESOURCE = 2;
+ const int STATUS_INVALID_ARGUMENTS = 3;
+ const int STATUS_INVALID_STATE = 4;
+
+ /**
+ * Closes a specific stream in a device.
+ *
+ * @param deviceId Device ID for the stream to close.
+ * @param streamId Stream ID for the stream to close.
+ * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+ */
+ void closeStream(in int deviceId, in int streamId);
+
+ /**
+ * Gets stream configurations for a specific device.
+ *
+ * The configs object is valid only until the next
+ * STREAM_CONFIGURATIONS_CHANGED event.
+ *
+ * @param deviceId Device ID for the configurations.
+ * @return the array of available configurations.
+ * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+ */
+ TvStreamConfig[] getStreamConfigurations(in int deviceId);
+
+ /**
+ * Opens a specific stream in a device.
+ *
+ * @param deviceId Device ID for the stream to open.
+ * @param streamId Stream ID for the stream to open. Must be one of the
+ * stream IDs returned from getStreamConfigurations().
+ * @return the handle for sideband stream.
+ * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+ */
+ NativeHandle openStream(in int deviceId, in int streamId);
+
+ /**
+ * Sets a callback for events.
+ *
+ * Note that initially no device is available in the client side, so the
+ * implementation must notify all the currently available devices including
+ * static devices via callback once callback is set.
+ *
+ * @param callback Callback object to pass events.
+ * @throws ServiceSpecificException with values from the ITvInput::STATUS_* constants
+ */
+ void setCallback(in ITvInputCallback callback);
+
+ /**
+ * Enables or disables TV message detection for the specified stream on the device.
+ *
+ * @param deviceId The ID of the device that contains the stream to set the flag for.
+ * @param streamId The ID of the stream to set the flag for.
+ * @param type The type of {@link android.hardware.tv.input.TvMessageEventType}.
+ * @param enabled {@code true} if you want to enable TV message detection
+ * {@code false} otherwise.
+ */
+ void setTvMessageEnabled(
+ int deviceId, int streamId, in TvMessageEventType type, boolean enabled);
+
+ /**
+ * Gets the TV message queue for the specified stream on the device.
+ *
+ * The FMQ is used to relay events that are parsed from the specified stream to the
+ * app or service responsible for processing the message. The HAL implementation
+ * is expected to parse these messages and add them to the queue as new events are
+ * detected from the stream based on whether or not they are enabled by
+ * {@link #setTvMessageEnabled(int, int, TvMessageEventType, boolean)}.
+ *
+ * @param deviceId The ID of the device that contains the stream to get the queue for.
+ * @param streamId THe ID of the stream to get the queue for.
+ * @return The descriptor of the TV message queue.
+ */
+ void getTvMessageQueueDesc(
+ out MQDescriptor<byte, SynchronizedReadWrite> queue, int deviceId, int streamId);
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl
new file mode 100644
index 0000000..5d47317
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/ITvInputCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.TvInputEvent;
+import android.hardware.tv.input.TvMessageEvent;
+
+@VintfStability
+interface ITvInputCallback {
+ /**
+ * Notifies the client that an event has occurred. For possible event types,
+ * check TvInputEventType.
+ *
+ * @param event Event passed to the client.
+ */
+ void notify(in TvInputEvent event);
+ /**
+ * Notifies the client that an TV message event has occurred. For possible event types,
+ * check TvMessageEventType.
+ *
+ * @param event Event passed to the client.
+ */
+ void notifyTvMessageEvent(in TvMessageEvent event);
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputDeviceInfo.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputDeviceInfo.aidl
new file mode 100644
index 0000000..2782e90
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputDeviceInfo.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.CableConnectionStatus;
+import android.hardware.tv.input.TvInputType;
+import android.media.audio.common.AudioDevice;
+
+@VintfStability
+parcelable TvInputDeviceInfo {
+ int deviceId;
+ TvInputType type;
+
+ /* HDMI port ID number. e.g. 2 for HDMI 2. */
+ int portId;
+
+ /* Cable connection status. */
+ CableConnectionStatus cableConnectionStatus;
+
+ /* Audio device info. */
+ AudioDevice audioDevice;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputEvent.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputEvent.aidl
new file mode 100644
index 0000000..66ca7aa
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputEvent.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.TvInputDeviceInfo;
+import android.hardware.tv.input.TvInputEventType;
+
+@VintfStability
+parcelable TvInputEvent {
+ TvInputEventType type;
+
+ /**
+ * TvInputEventType::DEVICE_AVAILABLE: all fields are relevant.
+ * TvInputEventType::DEVICE_UNAVAILABLE: only deviceId is relevant.
+ * TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: only deviceId is relevant.
+ */
+ TvInputDeviceInfo deviceInfo;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputEventType.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputEventType.aidl
new file mode 100644
index 0000000..fcbc3c2
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputEventType.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+@Backing(type="int")
+enum TvInputEventType {
+ /**
+ * Hardware notifies the framework that a device is available.
+ *
+ * Note that DEVICE_AVAILABLE and DEVICE_UNAVAILABLE events do not represent
+ * hotplug events (i.e. plugging cable into or out of the physical port).
+ * These events notify the framework whether the port is available or not.
+ * For a concrete example, when a user plugs in or pulls out the HDMI cable
+ * from a HDMI port, it does not generate DEVICE_AVAILABLE and/or
+ * DEVICE_UNAVAILABLE events. However, if a user inserts a pluggable USB
+ * tuner into the Android device, it must generate a DEVICE_AVAILABLE event
+ * and when the port is removed, it must generate a DEVICE_UNAVAILABLE
+ * event.
+ *
+ * For hotplug events, please see STREAM_CONFIGURATION_CHANGED for more
+ * details.
+ *
+ * HAL implementation must register devices by using this event when the
+ * device boots up. The framework must recognize device reported via this
+ * event only.
+ */
+ DEVICE_AVAILABLE = 1,
+
+ /**
+ * Hardware notifies the framework that a device is unavailable.
+ *
+ * HAL implementation must generate this event when a device registered
+ * by DEVICE_AVAILABLE is no longer available. For example,
+ * the event can indicate that a USB tuner is plugged out from the Android
+ * device.
+ *
+ * Note that this event is not for indicating cable plugged out of the port;
+ * for that purpose, the implementation must use
+ * STREAM_CONFIGURATION_CHANGED event. This event represents the port itself
+ * being no longer available.
+ */
+ DEVICE_UNAVAILABLE = 2,
+
+ /**
+ * Stream configurations are changed. Client must regard all open streams
+ * at the specific device are closed, and must call
+ * getStreamConfigurations() again, opening some of them if necessary.
+ *
+ * HAL implementation must generate this event when the available stream
+ * configurations change for any reason. A typical use case of this event
+ * is to notify the framework that the input signal has changed resolution,
+ * or that the cable is plugged out so that the number of available streams
+ * is 0.
+ *
+ * The implementation must use this event to indicate hotplug status of the
+ * port. the framework regards input devices with no available streams as
+ * disconnected, so the implementation can generate this event with no
+ * available streams to indicate that this device is disconnected, and vice
+ * versa.
+ */
+ STREAM_CONFIGURATIONS_CHANGED = 3,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvInputType.aidl b/tv/input/aidl/android/hardware/tv/input/TvInputType.aidl
new file mode 100644
index 0000000..a0f8270
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvInputType.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+/**
+ * Type of physical TV input.
+ */
+@VintfStability
+@Backing(type="int")
+enum TvInputType {
+ OTHER = 1,
+ TUNER = 2,
+ COMPOSITE = 3,
+ SVIDEO = 4,
+ SCART = 5,
+ COMPONENT = 6,
+ VGA = 7,
+ DVI = 8,
+ HDMI = 9,
+ DISPLAY_PORT = 10,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl
new file mode 100644
index 0000000..88da538
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvMessage.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+parcelable TvMessage {
+ /**
+ * This value for TvMessage.groupId denotes that the message doesn't belong to any group.
+ */
+ const long NO_GROUP_ID = -1;
+ /**
+ * Extended data type, like “ATSC A/336 Watermark”, “ATSC_CC”, etc. This is opaque
+ * to the framework.
+ */
+ String subType;
+ /**
+ * This group id is used to optionally identify messages that belong together, such as
+ * headers and bodies of the same event. For messages that do not have a group, this value
+ * should be -1.
+ *
+ * As -1 is a reserved value, -1 should not be used as a valid groupId.
+ */
+ long groupId;
+ int dataLengthBytes;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessageEvent.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessageEvent.aidl
new file mode 100644
index 0000000..74a078a
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvMessageEvent.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+import android.hardware.tv.input.TvMessage;
+import android.hardware.tv.input.TvMessageEventType;
+
+@VintfStability
+parcelable TvMessageEvent {
+ TvMessageEventType type;
+
+ int streamId;
+ TvMessage[] messages;
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvMessageEventType.aidl b/tv/input/aidl/android/hardware/tv/input/TvMessageEventType.aidl
new file mode 100644
index 0000000..518c7fc
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvMessageEventType.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+@Backing(type="int")
+enum TvMessageEventType {
+ WATERMARK = 1,
+ CLOSED_CAPTION = 2,
+ OTHER = 1000,
+}
diff --git a/tv/input/aidl/android/hardware/tv/input/TvStreamConfig.aidl b/tv/input/aidl/android/hardware/tv/input/TvStreamConfig.aidl
new file mode 100644
index 0000000..af86953
--- /dev/null
+++ b/tv/input/aidl/android/hardware/tv/input/TvStreamConfig.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.input;
+
+@VintfStability
+parcelable TvStreamConfig {
+ int streamId;
+
+ /* Maximum video width in pixel. */
+ int maxVideoWidth;
+
+ /* Maximum video height in pixel. */
+ int maxVideoHeight;
+}
diff --git a/tv/input/aidl/default/Android.bp b/tv/input/aidl/default/Android.bp
new file mode 100644
index 0000000..05af6a9
--- /dev/null
+++ b/tv/input/aidl/default/Android.bp
@@ -0,0 +1,37 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "android.hardware.tv.input-service.example",
+ relative_install_path: "hw",
+ init_rc: ["input-default.rc"],
+ vintf_fragments: ["input-default.xml"],
+ vendor: true,
+ cflags: [
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
+ srcs: [
+ "TvInput.cpp",
+ "service.cpp",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ ],
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libfmq",
+ "libutils",
+ "libcutils",
+ "libbinder_ndk",
+ "android.hardware.tv.input-V1-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ ],
+}
diff --git a/tv/input/aidl/default/TvInput.cpp b/tv/input/aidl/default/TvInput.cpp
new file mode 100644
index 0000000..c986ef1
--- /dev/null
+++ b/tv/input/aidl/default/TvInput.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.input-service.example"
+
+#include <utils/Log.h>
+
+#include "TvInput.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+TvInput::TvInput() {}
+
+void TvInput::init() {
+ // Set up TvInputDeviceInfo and TvStreamConfig
+ mDeviceInfos[0] = shared_ptr<TvInputDeviceInfoWrapper>(
+ new TvInputDeviceInfoWrapper(0, TvInputType::TUNER, true));
+ mDeviceInfos[1] = shared_ptr<TvInputDeviceInfoWrapper>(
+ new TvInputDeviceInfoWrapper(1, TvInputType::HDMI, true));
+ mDeviceInfos[3] = shared_ptr<TvInputDeviceInfoWrapper>(
+ new TvInputDeviceInfoWrapper(3, TvInputType::DISPLAY_PORT, true));
+
+ mStreamConfigs[0] = {
+ {1, shared_ptr<TvStreamConfigWrapper>(new TvStreamConfigWrapper(1, 720, 1080, false))}};
+ mStreamConfigs[1] = {{11, shared_ptr<TvStreamConfigWrapper>(
+ new TvStreamConfigWrapper(11, 360, 480, false))}};
+ mStreamConfigs[3] = {{5, shared_ptr<TvStreamConfigWrapper>(
+ new TvStreamConfigWrapper(5, 1080, 1920, false))}};
+}
+
+::ndk::ScopedAStatus TvInput::setCallback(const shared_ptr<ITvInputCallback>& in_callback) {
+ ALOGV("%s", __FUNCTION__);
+
+ mCallback = in_callback;
+
+ TvInputEvent event;
+ event.type = TvInputEventType::DEVICE_AVAILABLE;
+
+ event.deviceInfo = mDeviceInfos[0]->deviceInfo;
+ mCallback->notify(event);
+
+ event.deviceInfo = mDeviceInfos[1]->deviceInfo;
+ mCallback->notify(event);
+
+ event.deviceInfo = mDeviceInfos[3]->deviceInfo;
+ mCallback->notify(event);
+
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::setTvMessageEnabled(int32_t deviceId, int32_t streamId,
+ TvMessageEventType in_type, bool enabled) {
+ ALOGV("%s", __FUNCTION__);
+ // TODO: Implement this
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::getTvMessageQueueDesc(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
+ int32_t in_streamId) {
+ ALOGV("%s", __FUNCTION__);
+ // TODO: Implement this
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::getStreamConfigurations(int32_t in_deviceId,
+ vector<TvStreamConfig>* _aidl_return) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mStreamConfigs.count(in_deviceId) == 0) {
+ ALOGW("Device with id %d isn't available", in_deviceId);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+ }
+
+ for (auto const& iconfig : mStreamConfigs[in_deviceId]) {
+ _aidl_return->push_back(iconfig.second->streamConfig);
+ }
+
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::openStream(int32_t in_deviceId, int32_t in_streamId,
+ NativeHandle* _aidl_return) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mStreamConfigs.count(in_deviceId) == 0 ||
+ mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
+ ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+ }
+ if (mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
+ ALOGW("Stream with device id %d, stream id %d is already opened", in_deviceId, in_streamId);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
+ }
+ mStreamConfigs[in_deviceId][in_streamId]->handle = createNativeHandle(in_streamId);
+ *_aidl_return = makeToAidl(mStreamConfigs[in_deviceId][in_streamId]->handle);
+ mStreamConfigs[in_deviceId][in_streamId]->isOpen = true;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInput::closeStream(int32_t in_deviceId, int32_t in_streamId) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mStreamConfigs.count(in_deviceId) == 0 ||
+ mStreamConfigs[in_deviceId].count(in_streamId) == 0) {
+ ALOGW("Stream with device id %d, stream id %d isn't available", in_deviceId, in_streamId);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_ARGUMENTS);
+ }
+ if (!mStreamConfigs[in_deviceId][in_streamId]->isOpen) {
+ ALOGW("Stream with device id %d, stream id %d is already closed", in_deviceId, in_streamId);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(STATUS_INVALID_STATE);
+ }
+ native_handle_delete(mStreamConfigs[in_deviceId][in_streamId]->handle);
+ mStreamConfigs[in_deviceId][in_streamId]->handle = nullptr;
+ mStreamConfigs[in_deviceId][in_streamId]->isOpen = false;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+native_handle_t* TvInput::createNativeHandle(int fd) {
+ native_handle_t* handle = native_handle_create(1, 1);
+ if (handle == nullptr) {
+ ALOGE("[TVInput] Failed to create native_handle %d", errno);
+ return nullptr;
+ }
+ handle->data[0] = dup(0);
+ handle->data[1] = fd;
+ return handle;
+}
+
+} // namespace input
+} // namespace tv
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/tv/input/aidl/default/TvInput.h b/tv/input/aidl/default/TvInput.h
new file mode 100644
index 0000000..92e7d4c
--- /dev/null
+++ b/tv/input/aidl/default/TvInput.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tv/input/BnTvInput.h>
+#include <utils/KeyedVector.h>
+
+#include <aidl/android/hardware/tv/input/TvMessageEventType.h>
+#include <fmq/AidlMessageQueue.h>
+#include <map>
+#include "TvInputDeviceInfoWrapper.h"
+#include "TvStreamConfigWrapper.h"
+
+using namespace android;
+using namespace std;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+class TvInput : public BnTvInput {
+ public:
+ TvInput();
+
+ ::ndk::ScopedAStatus setCallback(const shared_ptr<ITvInputCallback>& in_callback) override;
+ ::ndk::ScopedAStatus setTvMessageEnabled(int32_t deviceId, int32_t streamId,
+ TvMessageEventType in_type, bool enabled) override;
+ ::ndk::ScopedAStatus getTvMessageQueueDesc(
+ MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue, int32_t in_deviceId,
+ int32_t in_streamId) override;
+ ::ndk::ScopedAStatus getStreamConfigurations(int32_t in_deviceId,
+ vector<TvStreamConfig>* _aidl_return) override;
+ ::ndk::ScopedAStatus openStream(int32_t in_deviceId, int32_t in_streamId,
+ NativeHandle* _aidl_return) override;
+ ::ndk::ScopedAStatus closeStream(int32_t in_deviceId, int32_t in_streamId) override;
+
+ void init();
+
+ private:
+ native_handle_t* createNativeHandle(int fd);
+
+ shared_ptr<ITvInputCallback> mCallback;
+ map<int32_t, shared_ptr<TvInputDeviceInfoWrapper>> mDeviceInfos;
+ map<int32_t, map<int32_t, shared_ptr<TvStreamConfigWrapper>>> mStreamConfigs;
+};
+
+} // namespace input
+} // namespace tv
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/tv/input/aidl/default/TvInputDeviceInfoWrapper.h b/tv/input/aidl/default/TvInputDeviceInfoWrapper.h
new file mode 100644
index 0000000..d844cc8
--- /dev/null
+++ b/tv/input/aidl/default/TvInputDeviceInfoWrapper.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+class TvInputDeviceInfoWrapper {
+ public:
+ TvInputDeviceInfoWrapper() {}
+ TvInputDeviceInfoWrapper(int32_t deviceId_, TvInputType type_, bool isAvailable_) {
+ deviceInfo.deviceId = deviceId_;
+ deviceInfo.type = type_;
+ isAvailable = isAvailable_;
+ }
+
+ TvInputDeviceInfo deviceInfo;
+ bool isAvailable;
+};
+} // namespace input
+} // namespace tv
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/tv/input/aidl/default/TvStreamConfigWrapper.h b/tv/input/aidl/default/TvStreamConfigWrapper.h
new file mode 100644
index 0000000..05c7ca3
--- /dev/null
+++ b/tv/input/aidl/default/TvStreamConfigWrapper.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/tv/input/TvStreamConfig.h>
+#include <aidlcommonsupport/NativeHandle.h>
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace input {
+
+class TvStreamConfigWrapper {
+ public:
+ TvStreamConfigWrapper() {}
+ TvStreamConfigWrapper(int32_t streamId_, int32_t maxVideoWidth_, int32_t maxVideoHeight_,
+ bool isOpen_) {
+ streamConfig.streamId = streamId_;
+ streamConfig.maxVideoWidth = maxVideoWidth_;
+ streamConfig.maxVideoHeight = maxVideoHeight_;
+ isOpen = isOpen_;
+ handle = nullptr;
+ }
+
+ TvStreamConfig streamConfig;
+ bool isOpen;
+ native_handle_t* handle;
+};
+} // namespace input
+} // namespace tv
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/tv/input/aidl/default/input-default.rc b/tv/input/aidl/default/input-default.rc
new file mode 100644
index 0000000..1958b5c
--- /dev/null
+++ b/tv/input/aidl/default/input-default.rc
@@ -0,0 +1,5 @@
+service vendor.input-default /vendor/bin/hw/android.hardware.tv.input-service.example
+ interface aidl android.hardware.tv.input.ITvInput/default
+ class hal
+ user system
+ group system
diff --git a/tv/input/aidl/default/input-default.xml b/tv/input/aidl/default/input-default.xml
new file mode 100644
index 0000000..38ba151
--- /dev/null
+++ b/tv/input/aidl/default/input-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.tv.input</name>
+ <fqname>ITvInput/default</fqname>
+ </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/input/aidl/default/service.cpp b/tv/input/aidl/default/service.cpp
new file mode 100644
index 0000000..1021206
--- /dev/null
+++ b/tv/input/aidl/default/service.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.tv.input-service.example"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "TvInput.h"
+
+using ::aidl::android::hardware::tv::input::TvInput;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(8);
+ std::shared_ptr<TvInput> tvInput = ndk::SharedRefBase::make<TvInput>();
+ tvInput->init();
+
+ const std::string instance = std::string() + TvInput::descriptor + "/default";
+ binder_status_t status =
+ AServiceManager_addService(tvInput->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reached
+}
diff --git a/tv/input/aidl/vts/functional/Android.bp b/tv/input/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..22487ea
--- /dev/null
+++ b/tv/input/aidl/vts/functional/Android.bp
@@ -0,0 +1,38 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalTvInputTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ cflags: [
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
+ srcs: ["VtsHalTvInputTargetTest.cpp"],
+ static_libs: [
+ "android.media.audio.common.types-V1-ndk",
+ "android.hardware.common-V2-ndk",
+ "libaidlcommonsupport",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ "libvndksupport",
+ "libfmq",
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.tv.input-V1-ndk",
+ ],
+ require_root: true,
+}
diff --git a/tv/input/aidl/vts/functional/AndroidTest.xml b/tv/input/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..5549102
--- /dev/null
+++ b/tv/input/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalTvInputTargetTest.">
+ <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="VtsHalTvInputTargetTest->/data/local/tmp/VtsHalTvInputTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalTvInputTargetTest" />
+ <option name="native-test-timeout" value="30m" />
+ </test>
+</configuration>
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
new file mode 100644
index 0000000..a2415b4
--- /dev/null
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.cpp
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VtsHalTvInputTargetTest.h"
+
+#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_process.h>
+#include <android/binder_status.h>
+
+using namespace VtsHalTvInputTargetTest;
+
+TvInputAidlTest::TvInputCallback::TvInputCallback(shared_ptr<TvInputAidlTest> parent)
+ : parent_(parent) {}
+
+::ndk::ScopedAStatus TvInputAidlTest::TvInputCallback::notify(const TvInputEvent& in_event) {
+ unique_lock<mutex> lock(parent_->mutex_);
+
+ switch (in_event.type) {
+ case TvInputEventType::DEVICE_AVAILABLE:
+ parent_->onDeviceAvailable(in_event.deviceInfo);
+ break;
+ case TvInputEventType::DEVICE_UNAVAILABLE:
+ parent_->onDeviceUnavailable(in_event.deviceInfo.deviceId);
+ break;
+ case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED:
+ parent_->onStreamConfigurationsChanged(in_event.deviceInfo.deviceId);
+ break;
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TvInputAidlTest::TvInputCallback::notifyTvMessageEvent(
+ const TvMessageEvent& in_event) {
+ return ::ndk::ScopedAStatus::ok();
+}
+
+void TvInputAidlTest::SetUp() {
+ if (AServiceManager_isDeclared(GetParam().c_str())) {
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+ tv_input_ = ITvInput::fromBinder(binder);
+ } else {
+ tv_input_ = nullptr;
+ }
+ ASSERT_NE(tv_input_, nullptr);
+
+ tv_input_callback_ =
+ ::ndk::SharedRefBase::make<TvInputCallback>(shared_ptr<TvInputAidlTest>(this));
+ ASSERT_NE(tv_input_callback_, nullptr);
+
+ tv_input_->setCallback(tv_input_callback_);
+ // All events received within the timeout should be handled.
+ sleep(WAIT_FOR_EVENT_TIMEOUT);
+}
+
+void TvInputAidlTest::TearDown() {
+ tv_input_ = nullptr;
+}
+
+void TvInputAidlTest::onDeviceAvailable(const TvInputDeviceInfo& deviceInfo) {
+ ALOGD("onDeviceAvailable for device id %d", deviceInfo.deviceId);
+ device_info_.add(deviceInfo.deviceId, deviceInfo);
+}
+
+void TvInputAidlTest::onDeviceUnavailable(int32_t deviceId) {
+ ALOGD("onDeviceUnavailable for device id %d", deviceId);
+ device_info_.removeItem(deviceId);
+ stream_config_.removeItem(deviceId);
+}
+
+::ndk::ScopedAStatus TvInputAidlTest::onStreamConfigurationsChanged(int32_t deviceId) {
+ ALOGD("onStreamConfigurationsChanged for device id %d", deviceId);
+ return updateStreamConfigurations(deviceId);
+}
+
+::ndk::ScopedAStatus TvInputAidlTest::updateStreamConfigurations(int32_t deviceId) {
+ stream_config_.removeItem(deviceId);
+ vector<TvStreamConfig> list;
+ ::ndk::ScopedAStatus status = tv_input_->getStreamConfigurations(deviceId, &list);
+ if (status.isOk()) {
+ stream_config_.add(deviceId, list);
+ }
+ return status;
+}
+
+void TvInputAidlTest::updateAllStreamConfigurations() {
+ for (size_t i = 0; i < device_info_.size(); i++) {
+ int32_t device_id = device_info_.keyAt(i);
+ updateStreamConfigurations(device_id);
+ }
+}
+
+vector<size_t> TvInputAidlTest::getConfigIndices() {
+ vector<size_t> indices;
+ for (size_t i = 0; i < stream_config_.size(); i++) {
+ if (stream_config_.valueAt(i).size() != 0) {
+ indices.push_back(i);
+ }
+ }
+ return indices;
+}
+
+int32_t TvInputAidlTest::getNumNotIn(vector<int32_t>& nums) {
+ int32_t result = DEFAULT_ID;
+ int32_t size = static_cast<int32_t>(nums.size());
+ for (int32_t i = 0; i < size; i++) {
+ // Put every element to its target position, if possible.
+ int32_t target_pos = nums[i];
+ while (target_pos >= 0 && target_pos < size && i != target_pos &&
+ nums[i] != nums[target_pos]) {
+ swap(nums[i], nums[target_pos]);
+ target_pos = nums[i];
+ }
+ }
+
+ for (int32_t i = 0; i < size; i++) {
+ if (nums[i] != i) {
+ return i;
+ }
+ }
+ return result;
+}
+
+/*
+ * GetStreamConfigTest:
+ * Calls updateStreamConfigurations() for each existing device
+ * Checks returned results
+ */
+TEST_P(TvInputAidlTest, GetStreamConfigTest) {
+ unique_lock<mutex> lock(mutex_);
+
+ for (size_t i = 0; i < device_info_.size(); i++) {
+ int32_t device_id = device_info_.keyAt(i);
+ ALOGD("GetStreamConfigTest: device_id=%d", device_id);
+ ASSERT_TRUE(updateStreamConfigurations(device_id).isOk());
+ }
+}
+
+/*
+ * OpenAndCloseStreamTest:
+ * Calls openStream() and then closeStream() for each existing stream
+ * Checks returned results
+ */
+TEST_P(TvInputAidlTest, OpenAndCloseStreamTest) {
+ unique_lock<mutex> lock(mutex_);
+
+ updateAllStreamConfigurations();
+
+ for (size_t j = 0; j < stream_config_.size(); j++) {
+ int32_t device_id = stream_config_.keyAt(j);
+ vector<TvStreamConfig> config = stream_config_.valueAt(j);
+ for (size_t i = 0; i < config.size(); i++) {
+ NativeHandle handle;
+ int32_t stream_id = config[i].streamId;
+ ALOGD("OpenAndCloseStreamTest: open stream, device_id=%d, stream_id=%d", device_id,
+ stream_id);
+ ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
+ ALOGD("OpenAndCloseStreamTest: close stream, device_id=%d, stream_id=%d", device_id,
+ stream_id);
+ ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk());
+ }
+ }
+}
+
+/*
+ * InvalidDeviceIdTest:
+ * Calls updateStreamConfigurations(), openStream(), and closeStream()
+ * for a non-existing device
+ * Checks returned results
+ * The results should be ITvInput::STATUS_INVALID_ARGUMENTS
+ */
+TEST_P(TvInputAidlTest, InvalidDeviceIdTest) {
+ unique_lock<mutex> lock(mutex_);
+
+ vector<int32_t> device_ids;
+ for (size_t i = 0; i < device_info_.size(); i++) {
+ device_ids.push_back(device_info_.keyAt(i));
+ }
+ // Get a non-existing device ID.
+ int32_t id = getNumNotIn(device_ids);
+ ALOGD("InvalidDeviceIdTest: update stream config, device_id=%d", id);
+ ASSERT_TRUE(updateStreamConfigurations(id).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_ARGUMENTS);
+
+ int32_t stream_id = 0;
+ NativeHandle handle;
+
+ ALOGD("InvalidDeviceIdTest: open stream, device_id=%d, stream_id=%d", id, stream_id);
+ ASSERT_TRUE(tv_input_->openStream(id, stream_id, &handle).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_ARGUMENTS);
+
+ ALOGD("InvalidDeviceIdTest: close stream, device_id=%d, stream_id=%d", id, stream_id);
+ ASSERT_TRUE(tv_input_->closeStream(id, stream_id).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_ARGUMENTS);
+}
+
+/*
+ * InvalidStreamIdTest:
+ * Calls openStream(), and closeStream() for a non-existing stream
+ * Checks returned results
+ * The results should be ITvInput::STATUS_INVALID_ARGUMENTS
+ */
+TEST_P(TvInputAidlTest, InvalidStreamIdTest) {
+ unique_lock<mutex> lock(mutex_);
+
+ if (device_info_.isEmpty()) {
+ return;
+ }
+ updateAllStreamConfigurations();
+
+ int32_t device_id = device_info_.keyAt(0);
+ // Get a non-existing stream ID.
+ int32_t id = DEFAULT_ID;
+ if (stream_config_.indexOfKey(device_id) >= 0) {
+ vector<int32_t> stream_ids;
+ vector<TvStreamConfig> config = stream_config_.valueFor(device_id);
+ for (size_t i = 0; i < config.size(); i++) {
+ stream_ids.push_back(config[i].streamId);
+ }
+ id = getNumNotIn(stream_ids);
+ }
+
+ NativeHandle handle;
+
+ ALOGD("InvalidStreamIdTest: open stream, device_id=%d, stream_id=%d", device_id, id);
+ ASSERT_TRUE(tv_input_->openStream(device_id, id, &handle).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_ARGUMENTS);
+
+ ALOGD("InvalidStreamIdTest: close stream, device_id=%d, stream_id=%d", device_id, id);
+ ASSERT_TRUE(tv_input_->closeStream(device_id, id).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_ARGUMENTS);
+}
+
+/*
+ * OpenAnOpenedStreamsTest:
+ * Calls openStream() twice for a stream (if any)
+ * Checks returned results
+ * The result of the second call should be ITvInput::STATUS_INVALID_STATE
+ */
+TEST_P(TvInputAidlTest, OpenAnOpenedStreamsTest) {
+ unique_lock<mutex> lock(mutex_);
+
+ updateAllStreamConfigurations();
+ vector<size_t> indices = getConfigIndices();
+ if (indices.empty()) {
+ return;
+ }
+ int32_t device_id = stream_config_.keyAt(indices[0]);
+ int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId;
+
+ NativeHandle handle;
+
+ ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
+ ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).isOk());
+
+ ALOGD("OpenAnOpenedStreamsTest: open stream, device_id=%d, stream_id=%d", device_id, stream_id);
+ ASSERT_TRUE(tv_input_->openStream(device_id, stream_id, &handle).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_STATE);
+
+ // close stream as subsequent tests assume no open streams
+ ALOGD("OpenAnOpenedStreamsTest: close stream, device_id=%d, stream_id=%d", device_id,
+ stream_id);
+ ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).isOk());
+}
+
+/*
+ * CloseStreamBeforeOpenTest:
+ * Calls closeStream() without calling openStream() for a stream (if any)
+ * Checks the returned result
+ * The result should be ITvInput::STATUS_INVALID_STATE
+ */
+TEST_P(TvInputAidlTest, CloseStreamBeforeOpenTest) {
+ unique_lock<mutex> lock(mutex_);
+
+ updateAllStreamConfigurations();
+ vector<size_t> indices = getConfigIndices();
+ if (indices.empty()) {
+ return;
+ }
+ int32_t device_id = stream_config_.keyAt(indices[0]);
+ int32_t stream_id = stream_config_.valueAt(indices[0])[0].streamId;
+
+ ALOGD("CloseStreamBeforeOpenTest: close stream, device_id=%d, stream_id=%d", device_id,
+ stream_id);
+ ASSERT_TRUE(tv_input_->closeStream(device_id, stream_id).getServiceSpecificError() ==
+ ITvInput::STATUS_INVALID_STATE);
+}
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TvInputAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(ITvInput::descriptor)),
+ android::PrintInstanceNameToString);
+
+// TODO remove from the allow list once the cf tv target is enabled for testing
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TvInputAidlTest);
diff --git a/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
new file mode 100644
index 0000000..20d9227
--- /dev/null
+++ b/tv/input/aidl/vts/functional/VtsHalTvInputTargetTest.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/binder_manager.h>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/tv/input/BnTvInputCallback.h>
+#include <aidl/android/hardware/tv/input/ITvInput.h>
+#include <aidl/android/hardware/tv/input/TvInputDeviceInfo.h>
+#include <aidl/android/hardware/tv/input/TvInputEvent.h>
+#include <aidl/android/hardware/tv/input/TvMessageEvent.h>
+#include <aidl/android/hardware/tv/input/TvMessageEventType.h>
+#include <aidl/android/hardware/tv/input/TvStreamConfig.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <log/log.h>
+#include <utils/KeyedVector.h>
+
+using namespace aidl::android::hardware::tv::input;
+using namespace std;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::android::AidlMessageQueue;
+
+#define WAIT_FOR_EVENT_TIMEOUT 5
+#define DEFAULT_ID INT32_MIN
+
+namespace VtsHalTvInputTargetTest {
+
+class TvInputAidlTest : public testing::TestWithParam<string> {
+ public:
+ class TvInputCallback : public BnTvInputCallback {
+ public:
+ TvInputCallback(shared_ptr<TvInputAidlTest> parent);
+ ::ndk::ScopedAStatus notify(const TvInputEvent& in_event) override;
+ ::ndk::ScopedAStatus notifyTvMessageEvent(const TvMessageEvent& in_event) override;
+
+ private:
+ shared_ptr<TvInputAidlTest> parent_;
+ };
+
+ virtual void SetUp() override;
+ virtual void TearDown() override;
+
+ /* Called when a DEVICE_AVAILABLE event is received. */
+ void onDeviceAvailable(const TvInputDeviceInfo& deviceInfo);
+
+ /* Called when a DEVICE_UNAVAILABLE event is received. */
+ void onDeviceUnavailable(int32_t deviceId);
+
+ /* Called when a STREAM_CONFIGURATIONS_CHANGED event is received. */
+ ::ndk::ScopedAStatus onStreamConfigurationsChanged(int32_t deviceId);
+
+ /* Gets and updates the stream configurations for a device. */
+ ::ndk::ScopedAStatus updateStreamConfigurations(int32_t deviceId);
+
+ /* Gets and updates the stream configurations for all existing devices. */
+ void updateAllStreamConfigurations();
+
+ /* Returns a list of indices of stream_config_ whose corresponding values are not empty. */
+ vector<size_t> getConfigIndices();
+
+ /*
+ * Returns DEFAULT_ID if there is no missing integer in the range [0, the size of nums).
+ * Otherwise, returns the smallest missing non-negative integer.
+ */
+ int32_t getNumNotIn(vector<int32_t>& nums);
+
+ protected:
+ shared_ptr<ITvInput> tv_input_;
+ shared_ptr<TvInputCallback> tv_input_callback_;
+ android::KeyedVector<int32_t, TvInputDeviceInfo> device_info_;
+ android::KeyedVector<int32_t, vector<TvStreamConfig>> stream_config_;
+ mutex mutex_;
+};
+
+} // namespace VtsHalTvInputTargetTest
diff --git a/tv/tuner/OWNERS b/tv/tuner/OWNERS
new file mode 100644
index 0000000..83e090d
--- /dev/null
+++ b/tv/tuner/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 136752
+
[email protected]
[email protected]
[email protected]
[email protected]
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselection.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselection.aidl
new file mode 100644
index 0000000..ab0404e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselection.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPreselection {
+ int preselectionId;
+ android.hardware.tv.tuner.AudioPreselectionLabel[] labels;
+ String language;
+ android.hardware.tv.tuner.AudioPreselectionRenderingIndicationType renderingIndication;
+ boolean hasAudioDescription;
+ boolean hasSpokenSubtitles;
+ boolean hasDialogueEnhancement;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionLabel.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
new file mode 100644
index 0000000..79f3b6f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPreselectionLabel {
+ String language;
+ String text;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
new file mode 100644
index 0000000..783511f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioPreselectionRenderingIndicationType {
+ NOT_INDICATED = 0,
+ STEREO = 1,
+ TWO_DIMENSIONAL = 2,
+ THREE_DIMENSIONAL = 3,
+ HEADPHONE = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
new file mode 100644
index 0000000..96a6d98
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioPresentation {
+ android.hardware.tv.tuner.AudioPreselection preselection;
+ int ac4ShortProgramId = -1;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
index ab36188..28caf19 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -37,4 +37,5 @@
union DemuxFilterMediaEventExtraMetaData {
boolean noinit;
android.hardware.tv.tuner.AudioExtraMetaData audio;
+ android.hardware.tv.tuner.AudioPresentation[] audioPresentations = {};
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index 371e075..8dfc60e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -38,4 +38,5 @@
int scIndex;
int scAvc;
int scHevc;
+ int scVvc;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
index 36b40ea..1dc593a 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -39,4 +39,5 @@
LOW_WATER = 2,
HIGH_WATER = 4,
OVERFLOW = 8,
+ NO_DATA = 16,
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl
new file mode 100644
index 0000000..872d963
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxInfo {
+ int filterTypes = 0;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 30ec29a..fb4430b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -39,4 +39,5 @@
SC = 1,
SC_HEVC = 2,
SC_AVC = 3,
+ SC_VVC = 4,
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
new file mode 100644
index 0000000..3e08d26
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScVvcIndex {
+ UNDEFINED = 0,
+ SLICE_IDR_W_RADL = 1,
+ SLICE_IDR_N_LP = 2,
+ SLICE_CRA = 4,
+ SLICE_GDR = 8,
+ VPS = 16,
+ SPS = 32,
+ AUD = 64,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
index c013cd1..c9443b1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -45,4 +45,5 @@
android.hardware.tv.tuner.FrontendIsdbsCapabilities isdbsCaps;
android.hardware.tv.tuner.FrontendIsdbs3Capabilities isdbs3Caps;
android.hardware.tv.tuner.FrontendIsdbtCapabilities isdbtCaps;
+ @nullable android.hardware.tv.tuner.FrontendIptvCapabilities iptvCaps;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
new file mode 100644
index 0000000..543543d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvCapabilities.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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvCapabilities {
+ int protocolCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettings.aidl
new file mode 100644
index 0000000..73582f3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettings.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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvSettings {
+ android.hardware.tv.tuner.FrontendIptvSettingsProtocol protocol = android.hardware.tv.tuner.FrontendIptvSettingsProtocol.UNDEFINED;
+ android.hardware.tv.tuner.FrontendIptvSettingsFec fec;
+ android.hardware.tv.tuner.FrontendIptvSettingsIgmp igmp = android.hardware.tv.tuner.FrontendIptvSettingsIgmp.UNDEFINED;
+ long bitrate;
+ android.hardware.tv.tuner.DemuxIpAddress ipAddr;
+ String contentUrl;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
new file mode 100644
index 0000000..c361377
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFec.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.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIptvSettingsFec {
+ android.hardware.tv.tuner.FrontendIptvSettingsFecType type;
+ int fecColNum;
+ int fecRowNum;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
new file mode 100644
index 0000000..50a1208
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsFecType {
+ UNDEFINED = 0,
+ COLUMN = 1,
+ ROW = 2,
+ COLUMN_ROW = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
new file mode 100644
index 0000000..aa08496
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsIgmp {
+ UNDEFINED = 0,
+ V1 = 1,
+ V2 = 2,
+ V3 = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
new file mode 100644
index 0000000..08a01f1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.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.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIptvSettingsProtocol {
+ UNDEFINED = 0,
+ UDP = 1,
+ RTP = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
index 7eae9df..9810ba6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -45,4 +45,5 @@
android.hardware.tv.tuner.FrontendIsdbs3Settings isdbs3;
android.hardware.tv.tuner.FrontendIsdbtSettings isdbt;
android.hardware.tv.tuner.FrontendDtmbSettings dtmb;
+ @nullable android.hardware.tv.tuner.FrontendIptvSettings iptv;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
index 1e0f5f0..b991ab6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -77,4 +77,9 @@
int[] streamIdList;
int[] dvbtCellIds;
android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo[] allPlpInfo;
+ String iptvContentUrl = "";
+ long iptvPacketsReceived;
+ long iptvPacketsLost;
+ int iptvWorstJitterMs;
+ int iptvAverageJitterMs;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
index cd6ccb3..3791299 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -77,4 +77,9 @@
STREAM_ID_LIST = 39,
DVBT_CELL_IDS = 40,
ATSC3_ALL_PLP_INFO = 41,
+ IPTV_CONTENT_URL = 42,
+ IPTV_PACKETS_LOST = 43,
+ IPTV_PACKETS_RECEIVED = 44,
+ IPTV_WORST_JITTER_MS = 45,
+ IPTV_AVERAGE_JITTER_MS = 46,
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
index 99a120b..cbf5b47 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * 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.
@@ -46,4 +46,5 @@
ISDBS3 = 8,
ISDBT = 9,
DTMB = 10,
+ IPTV = 11,
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
index 450cd79..4648712 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
@@ -43,4 +43,5 @@
void stop();
void flush();
void close();
+ void setStatusCheckIntervalHint(in long milliseconds);
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
index 0ff2da9..732f3fd 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
@@ -47,4 +47,8 @@
void setLna(in boolean bEnable);
void setMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType, in int maxNumber);
int getMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType);
+ boolean isLnaSupported();
+ int[] getDemuxIds();
+ android.hardware.tv.tuner.IDemux openDemuxById(in int demuxId);
+ android.hardware.tv.tuner.DemuxInfo getDemuxInfo(in int demuxId);
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
index 9dfd686..dbb6033 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -48,4 +48,5 @@
AV1 = 10,
AVS = 11,
AVS2 = 12,
+ VVC = 13,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselection.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselection.aidl
new file mode 100644
index 0000000..16ef0dd
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselection.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.AudioPreselectionLabel;
+import android.hardware.tv.tuner.AudioPreselectionRenderingIndicationType;
+
+/**
+ * Audio preselection metadata according to ETSI EN 300 468 V1.17.1.
+ * @hide
+ */
+@VintfStability
+parcelable AudioPreselection {
+ /**
+ * Identifies this audio preselection. The value of this field shall match the corresponding
+ * field in the elementary stream.
+ */
+ int preselectionId;
+
+ /**
+ * Collection of audio preselection labels.
+ */
+ AudioPreselectionLabel[] labels;
+
+ /**
+ * ISO 639-2 3-character code.
+ */
+ String language;
+
+ /**
+ * A hint for a preferred reproduction channel layout.
+ */
+ AudioPreselectionRenderingIndicationType renderingIndication;
+
+ /**
+ * Audio preselection contains audio description for the visually impaired.
+ */
+ boolean hasAudioDescription;
+
+ /**
+ * Audio preselection contains spoken subtitles.
+ */
+ boolean hasSpokenSubtitles;
+
+ /**
+ * Audio preselection provides support for dialogue enhancement.
+ */
+ boolean hasDialogueEnhancement;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionLabel.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
new file mode 100644
index 0000000..429b026
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionLabel.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Audio preselection label according to ETSI EN 300 468 V1.17.1.
+ * @hide
+ */
+@VintfStability
+parcelable AudioPreselectionLabel {
+ /**
+ * ISO 639-2 3-character code.
+ */
+ String language;
+
+ /**
+ * Text information, written in the language specified, pertaining to the preselection.
+ */
+ String text;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
new file mode 100644
index 0000000..963c55a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Audio preselection audio rendering indication according to ETSI EN 300 468 V1.17.1.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum AudioPreselectionRenderingIndicationType {
+ /**
+ * No preference given for the reproduction channel layout.
+ */
+ NOT_INDICATED,
+
+ /**
+ * Preferred reproduction channel layout is stereo.
+ */
+ STEREO,
+
+ /**
+ * Preferred reproduction channel layout is two-dimensional (e.g. 5.1 multi-channel).
+ */
+ TWO_DIMENSIONAL,
+
+ /**
+ * Preferred reproduction channel layout is three-dimensional.
+ */
+ THREE_DIMENSIONAL,
+
+ /**
+ * Content is pre-rendered for consumption with headphones.
+ */
+ HEADPHONE,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioPresentation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPresentation.aidl
new file mode 100644
index 0000000..50f9d90
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioPresentation.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.AudioPreselection;
+
+/**
+ * Audio presentation metadata.
+ * @hide
+ */
+@VintfStability
+parcelable AudioPresentation {
+ /**
+ * Audio preselection.
+ */
+ AudioPreselection preselection;
+
+ /**
+ * Dolby AC-4 short program id specified in ETSI TS 103 190-2. For use in conjunction with
+ * an audio preselection to ensure contininuity of personalized experience during program
+ * transitions.
+ */
+ int ac4ShortProgramId = -1;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
index f01952b..4ff33a2 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -17,6 +17,7 @@
package android.hardware.tv.tuner;
import android.hardware.tv.tuner.AudioExtraMetaData;
+import android.hardware.tv.tuner.AudioPresentation;
/**
* Extra Meta Data for DemuxFilterMediaEvent.
@@ -30,4 +31,9 @@
boolean noinit;
AudioExtraMetaData audio;
+
+ /**
+ * Audio presentations available for user selection.
+ */
+ AudioPresentation[] audioPresentations = {};
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index 4036b06..d53bc5b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -39,4 +39,9 @@
* Indexes defined by DemuxScHevcIndex.
*/
int scHevc;
+
+ /**
+ * Indexes defined by DemuxScVvcIndex.
+ */
+ int scVvc;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
index e6f3b63..45a473e 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -46,4 +46,9 @@
* discarded.
*/
OVERFLOW = 1 << 3,
+
+ /**
+ * Indicating there is no data coming to the filter.
+ */
+ NO_DATA = 1 << 4,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxInfo.aidl
new file mode 100644
index 0000000..2720e21
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxInfo.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 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.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.DemuxFilterMainType;
+
+/**
+ * Information for the Demux.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxInfo {
+ /**
+ * Bitwise OR of DemuxFilterMainTypes
+ */
+ int filterTypes = DemuxFilterMainType.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 98427f7..265b978 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -42,4 +42,9 @@
* Use Start Code index for AVC
*/
SC_AVC,
+
+ /**
+ * Use Start Code index for VVC
+ */
+ SC_VVC,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScVvcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
new file mode 100644
index 0000000..8b47f62
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+/**
+ * Indexes can be tagged by start point of slice groups according to ISO/IEC 23090-3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScVvcIndex {
+ UNDEFINED = 0,
+
+ /**
+ * Coded slice of an IDR picture or subpicture with RADL pictures.
+ */
+ SLICE_IDR_W_RADL = 1 << 0,
+
+ /**
+ * Coded slice of an IDR picture or subpicture without leading pictures.
+ */
+ SLICE_IDR_N_LP = 1 << 1,
+
+ /**
+ * Coded slice of a CRA (clean random access) picture or subpicture.
+ */
+ SLICE_CRA = 1 << 2,
+
+ /**
+ * Coded slice of a GDR (gradual decoder refresh) picture or subpicture.
+ */
+ SLICE_GDR = 1 << 3,
+
+ /**
+ * Video parameter set (non-VCL NALU).
+ */
+ VPS = 1 << 4,
+
+ /**
+ * Sequence parameter set (non-VCL NALU).
+ */
+ SPS = 1 << 5,
+
+ /**
+ * Access unit delimiter (non-VCL NALU).
+ */
+ AUD = 1 << 6,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
index a6f1490..cfa1763 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -23,6 +23,7 @@
import android.hardware.tv.tuner.FrontendDvbcCapabilities;
import android.hardware.tv.tuner.FrontendDvbsCapabilities;
import android.hardware.tv.tuner.FrontendDvbtCapabilities;
+import android.hardware.tv.tuner.FrontendIptvCapabilities;
import android.hardware.tv.tuner.FrontendIsdbs3Capabilities;
import android.hardware.tv.tuner.FrontendIsdbsCapabilities;
import android.hardware.tv.tuner.FrontendIsdbtCapabilities;
@@ -51,4 +52,6 @@
FrontendIsdbs3Capabilities isdbs3Caps;
FrontendIsdbtCapabilities isdbtCaps;
+
+ @nullable FrontendIptvCapabilities iptvCaps;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvCapabilities.aidl
new file mode 100644
index 0000000..438492b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvCapabilities.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.tv.tuner;
+
+/**
+ * Capabilities for IPTV Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIptvCapabilities {
+ /**
+ * Transmission protocols for IPTV (UDP / RTP) defined in FrontendIptvSettingsProtocol.
+ */
+ int protocolCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettings.aidl
new file mode 100644
index 0000000..782695a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettings.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.tv.tuner;
+
+import android.hardware.tv.tuner.DemuxIpAddress;
+import android.hardware.tv.tuner.FrontendIptvSettingsFec;
+import android.hardware.tv.tuner.FrontendIptvSettingsFecType;
+import android.hardware.tv.tuner.FrontendIptvSettingsIgmp;
+import android.hardware.tv.tuner.FrontendIptvSettingsProtocol;
+
+/**
+ * Frontend Settings for IPTV.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIptvSettings {
+ FrontendIptvSettingsProtocol protocol = FrontendIptvSettingsProtocol.UNDEFINED;
+
+ FrontendIptvSettingsFec fec;
+
+ FrontendIptvSettingsIgmp igmp = FrontendIptvSettingsIgmp.UNDEFINED;
+
+ long bitrate;
+
+ /**
+ * Source and destination IP Address.
+ */
+ DemuxIpAddress ipAddr;
+
+ String contentUrl;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
new file mode 100644
index 0000000..e12f06f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFec.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.tv.tuner;
+
+import android.hardware.tv.tuner.FrontendIptvSettingsFecType;
+
+/**
+ * Configuration details for IPTV FEC.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIptvSettingsFec {
+ FrontendIptvSettingsFecType type;
+
+ /**
+ * The number of columns in the source block as well as the type of the repair packet.
+ */
+ int fecColNum;
+
+ /**
+ * The number of rows in the source block as well as the type of the repair packet.
+ */
+ int fecRowNum;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
new file mode 100644
index 0000000..421cbf8
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.tv.tuner;
+
+/**
+ * FEC type for IPTV.
+ * TS 102 542-3-2 - V1.3.2
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIptvSettingsFecType {
+ UNDEFINED = 0,
+
+ COLUMN = 1 << 0,
+
+ ROW = 1 << 1,
+
+ COLUMN_ROW = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
new file mode 100644
index 0000000..f6e39c8
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.tv.tuner;
+
+/**
+ * IGMP type for IPTV.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIptvSettingsIgmp {
+ UNDEFINED = 0,
+
+ V1 = 1 << 0,
+
+ V2 = 1 << 1,
+
+ V3 = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
new file mode 100644
index 0000000..0283445
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.tv.tuner;
+
+/**
+ * Protocol for IPTV.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIptvSettingsProtocol {
+ UNDEFINED = 0,
+
+ UDP = 1 << 0,
+
+ RTP = 1 << 1,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
index f78b2ae..e5a99e1 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -19,13 +19,14 @@
import android.hardware.tv.tuner.FrontendAnalogSettings;
import android.hardware.tv.tuner.FrontendAtsc3Settings;
import android.hardware.tv.tuner.FrontendAtscSettings;
+import android.hardware.tv.tuner.FrontendDtmbSettings;
import android.hardware.tv.tuner.FrontendDvbcSettings;
import android.hardware.tv.tuner.FrontendDvbsSettings;
import android.hardware.tv.tuner.FrontendDvbtSettings;
+import android.hardware.tv.tuner.FrontendIptvSettings;
import android.hardware.tv.tuner.FrontendIsdbs3Settings;
import android.hardware.tv.tuner.FrontendIsdbsSettings;
import android.hardware.tv.tuner.FrontendIsdbtSettings;
-import android.hardware.tv.tuner.FrontendDtmbSettings;
/**
* Signal Settings for Frontend.
@@ -52,4 +53,6 @@
FrontendIsdbtSettings isdbt;
FrontendDtmbSettings dtmb;
+
+ @nullable FrontendIptvSettings iptv;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index b5d0201..391f29b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -26,8 +26,8 @@
import android.hardware.tv.tuner.FrontendModulation;
import android.hardware.tv.tuner.FrontendModulationStatus;
import android.hardware.tv.tuner.FrontendRollOff;
-import android.hardware.tv.tuner.FrontendSpectralInversion;
import android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
import android.hardware.tv.tuner.FrontendStatusAtsc3PlpInfo;
import android.hardware.tv.tuner.FrontendTransmissionMode;
import android.hardware.tv.tuner.LnbVoltage;
@@ -247,4 +247,29 @@
* and not tuned PLPs for currently watching service.
*/
FrontendScanAtsc3PlpInfo[] allPlpInfo;
+
+ /**
+ * IPTV Content URL
+ */
+ String iptvContentUrl = "";
+
+ /**
+ * Packets Received (IPTV - UDP/RTP).
+ */
+ long iptvPacketsReceived;
+
+ /**
+ * Packets Lost (IPTV - RTP).
+ */
+ long iptvPacketsLost;
+
+ /**
+ * Worst jitter (milliseconds).
+ */
+ int iptvWorstJitterMs;
+
+ /**
+ * Average jitter (milliseconds).
+ */
+ int iptvAverageJitterMs;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 8f3f2c5..6804b2d 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -234,4 +234,29 @@
* and not tuned PLPs for currently watching service.
*/
ATSC3_ALL_PLP_INFO,
+
+ /**
+ * IPTV Content URL.
+ */
+ IPTV_CONTENT_URL,
+
+ /**
+ * Number of packets lost.
+ */
+ IPTV_PACKETS_LOST,
+
+ /**
+ * Number of packets received.
+ */
+ IPTV_PACKETS_RECEIVED,
+
+ /**
+ * Worst jitter (milliseconds).
+ */
+ IPTV_WORST_JITTER_MS,
+
+ /**
+ * Average jitter (milliseconds).
+ */
+ IPTV_AVERAGE_JITTER_MS,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
index 8ade389..e8d343e 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * 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.
@@ -79,4 +79,9 @@
* DTMB (Digital Terrestrial Multimedia Broadcast) standard.
*/
DTMB,
+
+ /**
+ * ITU IPTV (ITU-T FG IPTV)
+ */
+ IPTV,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
index 0534f9d..4cb5b15 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
@@ -18,7 +18,6 @@
import android.hardware.common.fmq.MQDescriptor;
import android.hardware.common.fmq.SynchronizedReadWrite;
-
import android.hardware.tv.tuner.DvrSettings;
import android.hardware.tv.tuner.IFilter;
@@ -101,4 +100,12 @@
* instance any more and all methods should return a failure.
*/
void close();
+
+ /**
+ * Set status check time interval.
+ *
+ * This time interval hint will be used by the Dvr to decide how often
+ * to evaluate data.
+ */
+ void setStatusCheckIntervalHint(in long milliseconds);
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
index 03def33..9ead7dd 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
@@ -17,6 +17,7 @@
package android.hardware.tv.tuner;
import android.hardware.tv.tuner.DemuxCapabilities;
+import android.hardware.tv.tuner.DemuxInfo;
import android.hardware.tv.tuner.FrontendInfo;
import android.hardware.tv.tuner.FrontendType;
import android.hardware.tv.tuner.IDemux;
@@ -65,7 +66,7 @@
IDemux openDemux(out int[] demuxId);
/**
- * Retrieve the Demux's Capabilities.
+ * Retrieve the system wide Demux's Capabilities
*
* @return the Demux's Capabilities.
*/
@@ -125,6 +126,9 @@
/**
* Enable or Disable Low Noise Amplifier (LNA).
*
+ * If the device doesn't support LNA, the HAL implement should set {@link Result#UNAVAILABLE}
+ * to EX_SERVICE_SPECIFIC as the service specific error.
+ *
* @param bEnable true if activate LNA module; false if deactivate LNA
*/
void setLna(in boolean bEnable);
@@ -148,4 +152,39 @@
* @return the maximum usable number of the queried frontend type.
*/
int getMaxNumberOfFrontends(in FrontendType frontendType);
+
+ /**
+ * Is Low Noise Amplifier (LNA) supported.
+ *
+ * @return true if supported, otherwise false
+ */
+ boolean isLnaSupported();
+
+ /**
+ * Get Demux IDs
+ *
+ * It is used by the client to get all available demuxes' IDs.
+ *
+ * @return an array of IDs for the available Demuxes.
+ */
+ int[] getDemuxIds();
+
+ /**
+ * Create a new instance of Demux given a demuxId.
+ *
+ * It is used by the client to create a demux instance.
+ *
+ * @param demuxId the id of the demux to be opened.
+ *
+ * @return the newly created demux interface.
+ */
+ IDemux openDemuxById(in int demuxId);
+
+ /**
+ * Retrieve the DemuxInfo of the specified Demux.
+ *
+ * @param demuxId the demux ID to query the DemuxInfo for.
+ * @return the DemuxInfo of the specified Demux by demuxId.
+ */
+ DemuxInfo getDemuxInfo(in int demuxId);
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
index 108d986..bd000d2 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -84,4 +84,9 @@
* New Chinese Standard
*/
AVS2,
+
+ /*
+ * ITU-T Rec. H.266 and ISO/IEC 23090-3
+ */
+ VVC,
}
diff --git a/tv/tuner/aidl/default/Android.bp b/tv/tuner/aidl/default/Android.bp
index cb8f87b..65fa821 100644
--- a/tv/tuner/aidl/default/Android.bp
+++ b/tv/tuner/aidl/default/Android.bp
@@ -7,10 +7,9 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-cc_binary {
- name: "android.hardware.tv.tuner-service.example",
+cc_defaults {
+ name: "tuner_hal_example_defaults",
relative_install_path: "hw",
- init_rc: ["tuner-default.rc"],
vintf_fragments: ["tuner-default.xml"],
vendor: true,
compile_multilib: "first",
@@ -30,7 +29,7 @@
],
shared_libs: [
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.tv.tuner-V1-ndk",
+ "android.hardware.tv.tuner-V2-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
@@ -44,3 +43,18 @@
"media_plugin_headers",
],
}
+
+cc_binary {
+ name: "android.hardware.tv.tuner-service.example",
+ defaults: ["tuner_hal_example_defaults"],
+ init_rc: ["tuner-default.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.tv.tuner-service.example-lazy",
+ defaults: ["tuner_hal_example_defaults"],
+ init_rc: ["tuner-default-lazy.rc"],
+ cflags: [
+ "-DLAZY_HAL",
+ ],
+}
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
index a94b4ad..11e7131 100644
--- a/tv/tuner/aidl/default/Demux.cpp
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -31,12 +31,17 @@
#define WAIT_TIMEOUT 3000000000
-Demux::Demux(int32_t demuxId, std::shared_ptr<Tuner> tuner) {
+Demux::Demux(int32_t demuxId, uint32_t filterTypes) {
mDemuxId = demuxId;
+ mFilterTypes = filterTypes;
+}
+
+void Demux::setTunerService(std::shared_ptr<Tuner> tuner) {
mTuner = tuner;
}
Demux::~Demux() {
+ ALOGV("%s", __FUNCTION__);
close();
}
@@ -180,7 +185,10 @@
mRecordFilterIds.clear();
mFilters.clear();
mLastUsedFilterId = -1;
- mTuner->removeDemux(mDemuxId);
+ if (mTuner != nullptr) {
+ mTuner->removeDemux(mDemuxId);
+ mTuner = nullptr;
+ }
return ::ndk::ScopedAStatus::ok();
}
@@ -342,6 +350,22 @@
return mFilters[filterId]->getTpid();
}
+int32_t Demux::getDemuxId() {
+ return mDemuxId;
+}
+
+bool Demux::isInUse() {
+ return mInUse;
+}
+
+void Demux::setInUse(bool inUse) {
+ mInUse = inUse;
+}
+
+void Demux::getDemuxInfo(DemuxInfo* demuxInfo) {
+ *demuxInfo = {.filterTypes = mFilterTypes};
+}
+
void Demux::startFrontendInputLoop() {
ALOGD("[Demux] start frontend on demux");
// Stop current Frontend thread loop first, in case the user starts a new
diff --git a/tv/tuner/aidl/default/Demux.h b/tv/tuner/aidl/default/Demux.h
index 7f0b0a7..7d7aee4 100644
--- a/tv/tuner/aidl/default/Demux.h
+++ b/tv/tuner/aidl/default/Demux.h
@@ -53,7 +53,7 @@
class Demux : public BnDemux {
public:
- Demux(int32_t demuxId, std::shared_ptr<Tuner> tuner);
+ Demux(int32_t demuxId, uint32_t filterTypes);
~Demux();
::ndk::ScopedAStatus setFrontendDataSource(int32_t in_frontendId) override;
@@ -98,6 +98,12 @@
void sendFrontendInputToRecord(vector<int8_t> data, uint16_t pid, uint64_t pts);
bool startRecordFilterDispatcher();
+ void getDemuxInfo(DemuxInfo* demuxInfo);
+ int32_t getDemuxId();
+ bool isInUse();
+ void setInUse(bool inUse);
+ void setTunerService(std::shared_ptr<Tuner> tuner);
+
private:
// Tuner service
std::shared_ptr<Tuner> mTuner;
@@ -183,6 +189,9 @@
vector<uint8_t> mPesOutput;
const bool DEBUG_DEMUX = false;
+
+ int32_t mFilterTypes;
+ bool mInUse = false;
};
} // namespace tuner
diff --git a/tv/tuner/aidl/default/Dvr.cpp b/tv/tuner/aidl/default/Dvr.cpp
index c157bdd..c046ae3 100644
--- a/tv/tuner/aidl/default/Dvr.cpp
+++ b/tv/tuner/aidl/default/Dvr.cpp
@@ -154,6 +154,14 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus Dvr::setStatusCheckIntervalHint(int64_t /* in_milliseconds */) {
+ ALOGV("%s", __FUNCTION__);
+
+ // There is no active polling in this default implementation,
+ // so directly return ok here.
+ return ::ndk::ScopedAStatus::ok();
+}
+
bool Dvr::createDvrMQ() {
ALOGV("%s", __FUNCTION__);
@@ -427,7 +435,7 @@
map<int64_t, std::shared_ptr<IFilter>>::iterator it;
// Handle the output data per filter type
for (it = mFilters.begin(); it != mFilters.end(); it++) {
- if (mDemux->startFilterHandler(it->first).isOk()) {
+ if (!mDemux->startFilterHandler(it->first).isOk()) {
return false;
}
}
diff --git a/tv/tuner/aidl/default/Dvr.h b/tv/tuner/aidl/default/Dvr.h
index 6ff71cd..293c533 100644
--- a/tv/tuner/aidl/default/Dvr.h
+++ b/tv/tuner/aidl/default/Dvr.h
@@ -70,6 +70,7 @@
::ndk::ScopedAStatus stop() override;
::ndk::ScopedAStatus flush() override;
::ndk::ScopedAStatus close() override;
+ ::ndk::ScopedAStatus setStatusCheckIntervalHint(int64_t in_milliseconds) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 769ebe2..ba9602e 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -329,7 +329,8 @@
// All the filter event callbacks in start are for testing purpose.
switch (mType.mainType) {
case DemuxFilterMainType::TS:
- createMediaEvent(events);
+ createMediaEvent(events, false);
+ createMediaEvent(events, true);
createTsRecordEvent(events);
createTemiEvent(events);
break;
@@ -432,12 +433,12 @@
if (mSharedAvMemHandle != nullptr) {
*out_avMemory = ::android::dupToAidl(mSharedAvMemHandle);
- *_aidl_return = BUFFER_SIZE_16M;
+ *_aidl_return = BUFFER_SIZE;
mUsingSharedAvMem = true;
return ::ndk::ScopedAStatus::ok();
}
- int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+ int av_fd = createAvIonFd(BUFFER_SIZE);
if (av_fd < 0) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::OUT_OF_MEMORY));
@@ -454,7 +455,7 @@
mUsingSharedAvMem = true;
*out_avMemory = ::android::dupToAidl(mSharedAvMemHandle);
- *_aidl_return = BUFFER_SIZE_16M;
+ *_aidl_return = BUFFER_SIZE;
return ::ndk::ScopedAStatus::ok();
}
@@ -691,6 +692,8 @@
return DemuxFilterStatus::OVERFLOW;
} else if (availableToRead > highThreshold) {
return DemuxFilterStatus::HIGH_WATER;
+ } else if (availableToRead == 0) {
+ return DemuxFilterStatus::NO_DATA;
} else if (availableToRead < lowThreshold) {
return DemuxFilterStatus::LOW_WATER;
}
@@ -793,7 +796,8 @@
}
if (prefix == 0x000001) {
// TODO handle mulptiple Pes filters
- mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
+ mPesSizeLeft = (static_cast<uint8_t>(mFilterOutput[i + 8]) << 8) |
+ static_cast<uint8_t>(mFilterOutput[i + 9]);
mPesSizeLeft += 6;
if (DEBUG_FILTER) {
ALOGD("[Filter] pes data length %d", mPesSizeLeft);
@@ -803,7 +807,7 @@
}
}
- int endPoint = min(184, mPesSizeLeft);
+ uint32_t endPoint = min(184u, mPesSizeLeft);
// append data and check size
vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
@@ -852,11 +856,17 @@
return ::ndk::ScopedAStatus::ok();
}
+// Read PES (Packetized Elementary Stream) Packets from TransportStreams
+// as defined in ISO/IEC 13818-1 Section 2.4.3.6. Create MediaEvents
+// containing only their data without TS or PES headers.
::ndk::ScopedAStatus Filter::startMediaFilterHandler() {
if (mFilterOutput.empty()) {
return ::ndk::ScopedAStatus::ok();
}
+ // mPts being set before our MediaFilterHandler begins indicates that all
+ // metadata has already been handled. We can therefore create an event
+ // with the existing data. This method is used when processing ES files.
::ndk::ScopedAStatus result;
if (mPts) {
result = createMediaFilterEventWithIon(mFilterOutput);
@@ -867,16 +877,38 @@
}
for (int i = 0; i < mFilterOutput.size(); i += 188) {
+ // Every packet has a 4 Byte TS Header preceding it
+ uint32_t headerSize = 4;
+
if (mPesSizeLeft == 0) {
- uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
- mFilterOutput[i + 6];
+ // Packet Start Code Prefix is defined as the first 3 bytes of
+ // the PES Header and should always have the value 0x000001
+ uint32_t prefix = (static_cast<uint8_t>(mFilterOutput[i + 4]) << 16) |
+ (static_cast<uint8_t>(mFilterOutput[i + 5]) << 8) |
+ static_cast<uint8_t>(mFilterOutput[i + 6]);
if (DEBUG_FILTER) {
ALOGD("[Filter] prefix %d", prefix);
}
if (prefix == 0x000001) {
- // TODO handle mulptiple Pes filters
- mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
- mPesSizeLeft += 6;
+ // TODO handle multiple Pes filters
+ // Location of PES fields from ISO/IEC 13818-1 Section 2.4.3.6
+ mPesSizeLeft = (static_cast<uint8_t>(mFilterOutput[i + 8]) << 8) |
+ static_cast<uint8_t>(mFilterOutput[i + 9]);
+ bool hasPts = static_cast<uint8_t>(mFilterOutput[i + 11]) & 0x80;
+ uint8_t optionalFieldsLength = static_cast<uint8_t>(mFilterOutput[i + 12]);
+ headerSize += 9 + optionalFieldsLength;
+
+ if (hasPts) {
+ // Pts is a 33-bit field which is stored across 5 bytes, with
+ // bits in between as reserved fields which must be ignored
+ mPts = 0;
+ mPts |= (static_cast<uint8_t>(mFilterOutput[i + 13]) & 0x0e) << 29;
+ mPts |= (static_cast<uint8_t>(mFilterOutput[i + 14]) & 0xff) << 22;
+ mPts |= (static_cast<uint8_t>(mFilterOutput[i + 15]) & 0xfe) << 14;
+ mPts |= (static_cast<uint8_t>(mFilterOutput[i + 16]) & 0xff) << 7;
+ mPts |= (static_cast<uint8_t>(mFilterOutput[i + 17]) & 0xfe) >> 1;
+ }
+
if (DEBUG_FILTER) {
ALOGD("[Filter] pes data length %d", mPesSizeLeft);
}
@@ -885,10 +917,10 @@
}
}
- int endPoint = min(184, mPesSizeLeft);
+ uint32_t endPoint = min(188u - headerSize, mPesSizeLeft);
// append data and check size
- vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
- vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
+ vector<int8_t>::const_iterator first = mFilterOutput.begin() + i + headerSize;
+ vector<int8_t>::const_iterator last = mFilterOutput.begin() + i + headerSize + endPoint;
mPesOutput.insert(mPesOutput.end(), first, last);
// size does not match then continue
mPesSizeLeft -= endPoint;
@@ -900,7 +932,8 @@
}
result = createMediaFilterEventWithIon(mPesOutput);
- if (result.isOk()) {
+ if (!result.isOk()) {
+ mFilterOutput.clear();
return result;
}
}
@@ -961,24 +994,65 @@
return ::ndk::ScopedAStatus::ok();
}
+// Read PSI (Program Specific Information) Sections from TransportStreams
+// as defined in ISO/IEC 13818-1 Section 2.4.4
bool Filter::writeSectionsAndCreateEvent(vector<int8_t>& data) {
// TODO check how many sections has been read
ALOGD("[Filter] section handler");
- if (!writeDataToFilterMQ(data)) {
- return false;
- }
- DemuxFilterSectionEvent secEvent;
- secEvent = {
- // temp dump meta data
- .tableId = 0,
- .version = 1,
- .sectionNum = 1,
- .dataLength = static_cast<int32_t>(data.size()),
- };
- {
- std::lock_guard<std::mutex> lock(mFilterEventsLock);
- mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+ // Transport Stream Packets are 188 bytes long, as defined in the
+ // Introduction of ISO/IEC 13818-1
+ for (int i = 0; i < data.size(); i += 188) {
+ if (mSectionSizeLeft == 0) {
+ // Location for sectionSize as defined by Section 2.4.4
+ // Note that the first 4 bytes skipped are the TsHeader
+ mSectionSizeLeft = ((static_cast<uint8_t>(data[i + 5]) & 0x0f) << 8) |
+ static_cast<uint8_t>(data[i + 6]);
+ mSectionSizeLeft += 3;
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] section data length %d", mSectionSizeLeft);
+ }
+ }
+
+ // 184 bytes per packet is derived by subtracting the 4 byte length of
+ // the TsHeader from its 188 byte packet size
+ uint32_t endPoint = min(184u, mSectionSizeLeft);
+ // append data and check size
+ vector<int8_t>::const_iterator first = data.begin() + i + 4;
+ vector<int8_t>::const_iterator last = data.begin() + i + 4 + endPoint;
+ mSectionOutput.insert(mSectionOutput.end(), first, last);
+ // size does not match then continue
+ mSectionSizeLeft -= endPoint;
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] section data left %d", mSectionSizeLeft);
+ }
+ if (mSectionSizeLeft > 0) {
+ continue;
+ }
+
+ if (!writeDataToFilterMQ(mSectionOutput)) {
+ mSectionOutput.clear();
+ return false;
+ }
+
+ DemuxFilterSectionEvent secEvent;
+ secEvent = {
+ // temp dump meta data
+ .tableId = 0,
+ .version = 1,
+ .sectionNum = 1,
+ .dataLength = static_cast<int32_t>(mSectionOutput.size()),
+ };
+ if (DEBUG_FILTER) {
+ ALOGD("[Filter] assembled section data length %" PRIu64, secEvent.dataLength);
+ }
+
+ {
+ std::lock_guard<std::mutex> lock(mFilterEventsLock);
+ mFilterEvents.push_back(
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+ }
+ mSectionOutput.clear();
}
return true;
@@ -1148,15 +1222,7 @@
return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
}
-void Filter::createMediaEvent(vector<DemuxFilterEvent>& events) {
- AudioExtraMetaData audio;
- audio.adFade = 1;
- audio.adPan = 2;
- audio.versionTextTag = 3;
- audio.adGainCenter = 4;
- audio.adGainFront = 5;
- audio.adGainSurround = 6;
-
+void Filter::createMediaEvent(vector<DemuxFilterEvent>& events, bool isAudioPresentation) {
DemuxFilterMediaEvent mediaEvent;
mediaEvent.streamId = 1;
mediaEvent.isPtsPresent = true;
@@ -1166,9 +1232,45 @@
mediaEvent.isSecureMemory = true;
mediaEvent.mpuSequenceNumber = 6;
mediaEvent.isPesPrivateData = true;
- mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
- int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+ if (isAudioPresentation) {
+ AudioPresentation audioPresentation0{
+ .preselection.preselectionId = 0,
+ .preselection.labels = {{"en", "Commentator"}, {"es", "Comentarista"}},
+ .preselection.language = "en",
+ .preselection.renderingIndication =
+ AudioPreselectionRenderingIndicationType::THREE_DIMENSIONAL,
+ .preselection.hasAudioDescription = false,
+ .preselection.hasSpokenSubtitles = false,
+ .preselection.hasDialogueEnhancement = true,
+ .ac4ShortProgramId = 42};
+ AudioPresentation audioPresentation1{
+ .preselection.preselectionId = 1,
+ .preselection.labels = {{"en", "Crowd"}, {"es", "Multitud"}},
+ .preselection.language = "en",
+ .preselection.renderingIndication =
+ AudioPreselectionRenderingIndicationType::THREE_DIMENSIONAL,
+ .preselection.hasAudioDescription = false,
+ .preselection.hasSpokenSubtitles = false,
+ .preselection.hasDialogueEnhancement = false,
+ .ac4ShortProgramId = 42};
+ vector<AudioPresentation> audioPresentations;
+ audioPresentations.push_back(audioPresentation0);
+ audioPresentations.push_back(audioPresentation1);
+ mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations>(
+ audioPresentations);
+ } else {
+ AudioExtraMetaData audio;
+ audio.adFade = 1;
+ audio.adPan = 2;
+ audio.versionTextTag = 3;
+ audio.adGainCenter = 4;
+ audio.adGainFront = 5;
+ audio.adGainSurround = 6;
+ mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
+ }
+
+ int av_fd = createAvIonFd(BUFFER_SIZE);
if (av_fd == -1) {
return;
}
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index e301249..0985296 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -50,7 +50,8 @@
using ::android::hardware::EventFlag;
using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
-const uint32_t BUFFER_SIZE_16M = 0x1000000;
+
+const uint32_t BUFFER_SIZE = 0x800000; // 8 MB
class Demux;
class Dvr;
@@ -229,7 +230,7 @@
::ndk::ScopedAStatus createShareMemMediaEvents(vector<int8_t>& output);
bool sameFile(int fd1, int fd2);
- void createMediaEvent(vector<DemuxFilterEvent>&);
+ void createMediaEvent(vector<DemuxFilterEvent>&, bool isAudioPresentation);
void createTsRecordEvent(vector<DemuxFilterEvent>&);
void createMmtpRecordEvent(vector<DemuxFilterEvent>&);
void createSectionEvent(vector<DemuxFilterEvent>&);
@@ -256,9 +257,13 @@
std::mutex mFilterOutputLock;
std::mutex mRecordFilterOutputLock;
+ // handle single Section filter
+ uint32_t mSectionSizeLeft = 0;
+ vector<int8_t> mSectionOutput;
+
// temp handle single PES filter
// TODO handle mulptiple Pes filters
- int mPesSizeLeft = 0;
+ uint32_t mPesSizeLeft = 0;
vector<int8_t> mPesOutput;
// A map from data id to ion handle
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index 3f7797c..cd072bf 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -28,10 +28,10 @@
namespace tv {
namespace tuner {
-Frontend::Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner) {
+Frontend::Frontend(FrontendType type, int32_t id) {
mType = type;
mId = id;
- mTuner = tuner;
+ mTuner = nullptr;
// Init callback to nullptr
mCallback = nullptr;
@@ -164,20 +164,39 @@
};
break;
}
+ case FrontendType::IPTV: {
+ mFrontendCaps.set<FrontendCapabilities::Tag::iptvCaps>(FrontendIptvCapabilities());
+ mFrontendStatusCaps = {
+ FrontendStatusType::IPTV_CONTENT_URL,
+ FrontendStatusType::IPTV_PACKETS_LOST,
+ FrontendStatusType::IPTV_PACKETS_RECEIVED,
+ FrontendStatusType::IPTV_AVERAGE_JITTER_MS,
+ FrontendStatusType::IPTV_WORST_JITTER_MS,
+ };
+ break;
+ }
default: {
break;
}
}
}
-Frontend::~Frontend() {}
+Frontend::~Frontend() {
+ ALOGV("%s", __FUNCTION__);
+ mCallback = nullptr;
+ mIsLocked = false;
+ mTuner = nullptr;
+}
::ndk::ScopedAStatus Frontend::close() {
ALOGV("%s", __FUNCTION__);
// Reset callback
mCallback = nullptr;
mIsLocked = false;
- mTuner->removeFrontend(mId);
+ if (mTuner != nullptr) {
+ mTuner->removeFrontend(mId);
+ }
+ mTuner = nullptr;
return ::ndk::ScopedAStatus::ok();
}
@@ -202,7 +221,10 @@
static_cast<int32_t>(Result::INVALID_STATE));
}
- mTuner->frontendStartTune(mId);
+ if (mType != FrontendType::IPTV) {
+ mTuner->frontendStartTune(mId);
+ }
+
mCallback->onEvent(FrontendEventType::LOCKED);
mIsLocked = true;
@@ -233,6 +255,10 @@
return ::ndk::ScopedAStatus::ok();
}
+void Frontend::setTunerService(std::shared_ptr<Tuner> tuner) {
+ mTuner = tuner;
+}
+
void Frontend::scanThreadLoop() {
if (mIsLocked) {
FrontendScanMessage msg;
@@ -863,6 +889,26 @@
status.set<FrontendStatus::allPlpInfo>(infos);
break;
}
+ case FrontendStatusType::IPTV_CONTENT_URL: {
+ status.set<FrontendStatus::iptvContentUrl>("");
+ break;
+ }
+ case FrontendStatusType::IPTV_PACKETS_LOST: {
+ status.set<FrontendStatus::iptvPacketsLost>(5);
+ break;
+ }
+ case FrontendStatusType::IPTV_PACKETS_RECEIVED: {
+ status.set<FrontendStatus::iptvPacketsReceived>(5);
+ break;
+ }
+ case FrontendStatusType::IPTV_WORST_JITTER_MS: {
+ status.set<FrontendStatus::iptvWorstJitterMs>(5);
+ break;
+ }
+ case FrontendStatusType::IPTV_AVERAGE_JITTER_MS: {
+ status.set<FrontendStatus::iptvAverageJitterMs>(5);
+ break;
+ }
default: {
continue;
}
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 1d9ab53..85bd636 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -34,7 +34,7 @@
class Frontend : public BnFrontend {
public:
- Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner);
+ Frontend(FrontendType type, int32_t id);
::ndk::ScopedAStatus setCallback(
const std::shared_ptr<IFrontendCallback>& in_callback) override;
@@ -62,6 +62,7 @@
string getSourceFile();
bool isLocked();
void getFrontendInfo(FrontendInfo* _aidl_return);
+ void setTunerService(std::shared_ptr<Tuner> tuner);
private:
virtual ~Frontend();
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index fa74288..197d866 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "android.hardware.tv.tuner-service.example-Tuner"
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMainType.h>
#include <aidl/android/hardware/tv/tuner/Result.h>
#include <utils/Log.h>
@@ -37,17 +38,18 @@
void Tuner::init() {
// Static Frontends array to maintain local frontends information
// Array index matches their FrontendId in the default impl
- mFrontendSize = 10;
- mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0, this->ref<Tuner>());
- mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1, this->ref<Tuner>());
- mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2, this->ref<Tuner>());
- mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3, this->ref<Tuner>());
- mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4, this->ref<Tuner>());
- mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5, this->ref<Tuner>());
- mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6, this->ref<Tuner>());
- mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7, this->ref<Tuner>());
- mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8, this->ref<Tuner>());
- mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9, this->ref<Tuner>());
+ mFrontendSize = 11;
+ mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0);
+ mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1);
+ mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2);
+ mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3);
+ mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4);
+ mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5);
+ mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6);
+ mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7);
+ mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8);
+ mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9);
+ mFrontends[10] = ndk::SharedRefBase::make<Frontend>(FrontendType::IPTV, 10);
mMaxUsableFrontends[FrontendType::ISDBS] = 1;
mMaxUsableFrontends[FrontendType::ATSC3] = 1;
@@ -59,6 +61,17 @@
mMaxUsableFrontends[FrontendType::ATSC] = 1;
mMaxUsableFrontends[FrontendType::ISDBS3] = 1;
mMaxUsableFrontends[FrontendType::DTMB] = 1;
+ mMaxUsableFrontends[FrontendType::IPTV] = 1;
+
+ mDemuxes[0] =
+ ndk::SharedRefBase::make<Demux>(0, (static_cast<int32_t>(DemuxFilterMainType::TS) |
+ static_cast<int32_t>(DemuxFilterMainType::MMTP) |
+ static_cast<int32_t>(DemuxFilterMainType::TLV)));
+ mDemuxes[1] =
+ ndk::SharedRefBase::make<Demux>(1, (static_cast<int32_t>(DemuxFilterMainType::MMTP) |
+ static_cast<int32_t>(DemuxFilterMainType::TLV)));
+ mDemuxes[2] = ndk::SharedRefBase::make<Demux>(2, static_cast<int32_t>(DemuxFilterMainType::IP));
+ mDemuxes[3] = ndk::SharedRefBase::make<Demux>(3, static_cast<int32_t>(DemuxFilterMainType::TS));
mLnbs.resize(2);
mLnbs[0] = ndk::SharedRefBase::make<Lnb>(0);
@@ -78,6 +91,28 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus Tuner::getDemuxInfo(int32_t in_demuxId, DemuxInfo* _aidl_return) {
+ if (mDemuxes.find(in_demuxId) == mDemuxes.end()) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_ARGUMENT));
+ } else {
+ mDemuxes[in_demuxId]->getDemuxInfo(_aidl_return);
+ return ::ndk::ScopedAStatus::ok();
+ }
+}
+
+::ndk::ScopedAStatus Tuner::getDemuxIds(std::vector<int32_t>* _aidl_return) {
+ ALOGV("%s", __FUNCTION__);
+
+ int numOfDemuxes = mDemuxes.size();
+ _aidl_return->resize(numOfDemuxes);
+ int i = 0;
+ for (auto e = mDemuxes.begin(); e != mDemuxes.end(); e++) {
+ (*_aidl_return)[i++] = e->first;
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
::ndk::ScopedAStatus Tuner::openFrontendById(int32_t in_frontendId,
std::shared_ptr<IFrontend>* _aidl_return) {
ALOGV("%s", __FUNCTION__);
@@ -89,21 +124,54 @@
static_cast<int32_t>(Result::INVALID_ARGUMENT));
}
+ mFrontends[in_frontendId]->setTunerService(this->ref<Tuner>());
*_aidl_return = mFrontends[in_frontendId];
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus Tuner::openDemuxById(int32_t in_demuxId,
+ std::shared_ptr<IDemux>* _aidl_return) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (mDemuxes.find(in_demuxId) == mDemuxes.end()) {
+ ALOGW("[ WARN ] Demux with id %d isn't available", in_demuxId);
+ *_aidl_return = nullptr;
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_ARGUMENT));
+ }
+
+ if (mDemuxes[in_demuxId]->isInUse()) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ } else {
+ mDemuxes[in_demuxId]->setTunerService(this->ref<Tuner>());
+ mDemuxes[in_demuxId]->setInUse(true);
+
+ *_aidl_return = mDemuxes[in_demuxId];
+ return ::ndk::ScopedAStatus::ok();
+ }
+}
+
::ndk::ScopedAStatus Tuner::openDemux(std::vector<int32_t>* out_demuxId,
std::shared_ptr<IDemux>* _aidl_return) {
ALOGV("%s", __FUNCTION__);
- mLastUsedId += 1;
- mDemuxes[mLastUsedId] = ndk::SharedRefBase::make<Demux>(mLastUsedId, this->ref<Tuner>());
+ bool found = false;
+ int32_t demuxId = 0;
+ for (auto e = mDemuxes.begin(); e != mDemuxes.end(); e++) {
+ if (!e->second->isInUse()) {
+ found = true;
+ demuxId = e->second->getDemuxId();
+ }
+ }
- out_demuxId->push_back(mLastUsedId);
- *_aidl_return = mDemuxes[mLastUsedId];
-
- return ::ndk::ScopedAStatus::ok();
+ if (found) {
+ out_demuxId->push_back(demuxId);
+ return openDemuxById(demuxId, _aidl_return);
+ } else {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
}
::ndk::ScopedAStatus Tuner::getDemuxCaps(DemuxCapabilities* _aidl_return) {
@@ -114,6 +182,18 @@
// Support time filter testing
_aidl_return->bTimeFilter = true;
+ // set filterCaps as the bitwize OR of all the demux' caps
+ std::vector<int32_t> demuxIds;
+ getDemuxIds(&demuxIds);
+ int32_t filterCaps = 0;
+
+ for (int i = 0; i < demuxIds.size(); i++) {
+ DemuxInfo demuxInfo;
+ getDemuxInfo(demuxIds[i], &demuxInfo);
+ filterCaps |= demuxInfo.filterTypes;
+ }
+ _aidl_return->filterCaps = filterCaps;
+
return ::ndk::ScopedAStatus::ok();
}
@@ -203,6 +283,13 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus Tuner::isLnaSupported(bool* _aidl_return) {
+ ALOGV("%s", __FUNCTION__);
+
+ *_aidl_return = true;
+ return ::ndk::ScopedAStatus::ok();
+}
+
binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
ALOGV("%s", __FUNCTION__);
{
@@ -242,13 +329,13 @@
break;
}
}
- mDemuxes.erase(demuxId);
+ mDemuxes[demuxId]->setInUse(false);
}
void Tuner::removeFrontend(int32_t frontendId) {
map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
if (it != mFrontendToDemux.end()) {
- mDemuxes.erase(it->second);
+ mDemuxes[it->second]->setInUse(false);
}
mFrontendToDemux.erase(frontendId);
}
diff --git a/tv/tuner/aidl/default/Tuner.h b/tv/tuner/aidl/default/Tuner.h
index ad73003..2656933 100644
--- a/tv/tuner/aidl/default/Tuner.h
+++ b/tv/tuner/aidl/default/Tuner.h
@@ -46,7 +46,11 @@
std::shared_ptr<IFrontend>* _aidl_return) override;
::ndk::ScopedAStatus openDemux(std::vector<int32_t>* out_demuxId,
std::shared_ptr<IDemux>* _aidl_return) override;
+ ::ndk::ScopedAStatus openDemuxById(int32_t in_demuxId,
+ std::shared_ptr<IDemux>* _aidl_return) override;
::ndk::ScopedAStatus getDemuxCaps(DemuxCapabilities* _aidl_return) override;
+ ::ndk::ScopedAStatus getDemuxInfo(int32_t in_demuxId, DemuxInfo* _aidl_return) override;
+ ::ndk::ScopedAStatus getDemuxIds(std::vector<int32_t>* _aidl_return) override;
::ndk::ScopedAStatus openDescrambler(std::shared_ptr<IDescrambler>* _aidl_return) override;
::ndk::ScopedAStatus getFrontendInfo(int32_t in_frontendId,
FrontendInfo* _aidl_return) override;
@@ -61,6 +65,7 @@
int32_t in_maxNumber) override;
::ndk::ScopedAStatus getMaxNumberOfFrontends(FrontendType in_frontendType,
int32_t* _aidl_return) override;
+ ::ndk::ScopedAStatus isLnaSupported(bool* _aidl_return) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
@@ -76,12 +81,10 @@
// Static mFrontends array to maintain local frontends information
map<int32_t, std::shared_ptr<Frontend>> mFrontends;
map<int32_t, int32_t> mFrontendToDemux;
- map<int32_t, std::shared_ptr<Demux>> mDemuxes;
+ map<int32_t, std::shared_ptr<Demux>> mDemuxes; // use demuxId as the key in
+ // this sample implementation
// To maintain how many Frontends we have
int mFrontendSize;
- // The last used demux id. Initial value is -1.
- // First used id will be 0.
- int32_t mLastUsedId = -1;
vector<std::shared_ptr<Lnb>> mLnbs;
map<FrontendType, int32_t> mMaxUsableFrontends;
};
diff --git a/tv/tuner/aidl/default/service.cpp b/tv/tuner/aidl/default/service.cpp
index ac8d779..aa9f796 100644
--- a/tv/tuner/aidl/default/service.cpp
+++ b/tv/tuner/aidl/default/service.cpp
@@ -26,12 +26,19 @@
using ::aidl::android::hardware::tv::tuner::Tuner;
int main() {
- ABinderProcess_setThreadPoolMaxThreadCount(8);
+ ABinderProcess_setThreadPoolMaxThreadCount(16);
std::shared_ptr<Tuner> tuner = ndk::SharedRefBase::make<Tuner>();
tuner->init();
+ binder_status_t status;
const std::string instance = std::string() + Tuner::descriptor + "/default";
- binder_status_t status = AServiceManager_addService(tuner->asBinder().get(), instance.c_str());
+#ifdef LAZY_HAL
+ ALOGD("Start as a lazy HAL");
+ status = AServiceManager_registerLazyService(tuner->asBinder().get(), instance.c_str());
+#else
+ ALOGD("Start as a normal HAL");
+ status = AServiceManager_addService(tuner->asBinder().get(), instance.c_str());
+#endif
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
diff --git a/tv/tuner/aidl/default/tuner-default-lazy.rc b/tv/tuner/aidl/default/tuner-default-lazy.rc
new file mode 100644
index 0000000..6b3b183
--- /dev/null
+++ b/tv/tuner/aidl/default/tuner-default-lazy.rc
@@ -0,0 +1,9 @@
+service vendor.tuner-default-lazy /vendor/bin/hw/android.hardware.tv.tuner-service.example-lazy
+ class hal
+ user media
+ group mediadrm drmrpc
+ ioprio rt 4
+ task_profiles ProcessCapacityHigh
+ interface aidl android.hardware.tv.tuner.ITuner/default
+ oneshot
+ disabled
diff --git a/tv/tuner/aidl/default/tuner-default.rc b/tv/tuner/aidl/default/tuner-default.rc
index d0248c2..f9315ae 100644
--- a/tv/tuner/aidl/default/tuner-default.rc
+++ b/tv/tuner/aidl/default/tuner-default.rc
@@ -3,5 +3,6 @@
user media
group mediadrm drmrpc
ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
+ task_profiles ProcessCapacityHigh
onrestart restart media.tuner
+ interface aidl android.hardware.tv.tuner.ITuner/default
diff --git a/tv/tuner/aidl/default/tuner-default.xml b/tv/tuner/aidl/default/tuner-default.xml
index f0d03ad..bff8ff0 100644
--- a/tv/tuner/aidl/default/tuner-default.xml
+++ b/tv/tuner/aidl/default/tuner-default.xml
@@ -2,5 +2,6 @@
<hal format="aidl">
<name>android.hardware.tv.tuner</name>
<fqname>ITuner/default</fqname>
+ <version>2</version>
</hal>
</manifest>
diff --git a/tv/tuner/aidl/vts/OWNERS b/tv/tuner/aidl/vts/OWNERS
index bf2b609..5b33bf2 100644
--- a/tv/tuner/aidl/vts/OWNERS
+++ b/tv/tuner/aidl/vts/OWNERS
@@ -1,3 +1,5 @@
+# Bug component: 136752
+
[email protected]
[email protected]
[email protected]
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
index e5fb1e6..513007b 100644
--- a/tv/tuner/aidl/vts/functional/Android.bp
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -51,9 +51,10 @@
"[email protected]",
"[email protected]",
"[email protected]",
+ "android.hardware.cas-V1-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.tv.tuner-V1-ndk",
+ "android.hardware.tv.tuner-V2-ndk",
"libaidlcommonsupport",
"libfmq",
"libcutils",
diff --git a/tv/tuner/aidl/vts/functional/DemuxTests.cpp b/tv/tuner/aidl/vts/functional/DemuxTests.cpp
index 9de01e1..b2fca6f 100644
--- a/tv/tuner/aidl/vts/functional/DemuxTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DemuxTests.cpp
@@ -16,6 +16,12 @@
#include "DemuxTests.h"
+AssertionResult DemuxTests::getDemuxIds(std::vector<int32_t>& demuxIds) {
+ ndk::ScopedAStatus status;
+ status = mService->getDemuxIds(&demuxIds);
+ return AssertionResult(status.isOk());
+}
+
AssertionResult DemuxTests::openDemux(std::shared_ptr<IDemux>& demux, int32_t& demuxId) {
std::vector<int32_t> id;
auto status = mService->openDemux(&id, &mDemux);
@@ -26,6 +32,14 @@
return AssertionResult(status.isOk());
}
+AssertionResult DemuxTests::openDemuxById(int32_t demuxId, std::shared_ptr<IDemux>& demux) {
+ auto status = mService->openDemuxById(demuxId, &mDemux);
+ if (status.isOk()) {
+ demux = mDemux;
+ }
+ return AssertionResult(status.isOk());
+}
+
AssertionResult DemuxTests::setDemuxFrontendDataSource(int32_t frontendId) {
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
auto status = mDemux->setFrontendDataSource(frontendId);
@@ -33,14 +47,15 @@
}
AssertionResult DemuxTests::getDemuxCaps(DemuxCapabilities& demuxCaps) {
- if (!mDemux) {
- ALOGW("[vts] Test with openDemux first.");
- return failure();
- }
auto status = mService->getDemuxCaps(&demuxCaps);
return AssertionResult(status.isOk());
}
+AssertionResult DemuxTests::getDemuxInfo(int32_t demuxId, DemuxInfo& demuxInfo) {
+ auto status = mService->getDemuxInfo(demuxId, &demuxInfo);
+ return AssertionResult(status.isOk());
+}
+
AssertionResult DemuxTests::getAvSyncId(std::shared_ptr<IFilter> filter, int32_t& avSyncHwId) {
EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
diff --git a/tv/tuner/aidl/vts/functional/DemuxTests.h b/tv/tuner/aidl/vts/functional/DemuxTests.h
index 7698de3..b58cf70 100644
--- a/tv/tuner/aidl/vts/functional/DemuxTests.h
+++ b/tv/tuner/aidl/vts/functional/DemuxTests.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/tv/tuner/DemuxCapabilities.h>
+#include <aidl/android/hardware/tv/tuner/DemuxInfo.h>
#include <aidl/android/hardware/tv/tuner/IDemux.h>
#include <aidl/android/hardware/tv/tuner/IFilter.h>
#include <aidl/android/hardware/tv/tuner/ITuner.h>
@@ -32,11 +33,14 @@
public:
void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
+ AssertionResult getDemuxIds(std::vector<int32_t>& demuxIds);
AssertionResult openDemux(std::shared_ptr<IDemux>& demux, int32_t& demuxId);
+ AssertionResult openDemuxById(int32_t demuxId, std::shared_ptr<IDemux>& demux);
AssertionResult setDemuxFrontendDataSource(int32_t frontendId);
AssertionResult getAvSyncId(std::shared_ptr<IFilter> filter, int32_t& avSyncHwId);
AssertionResult getAvSyncTime(int32_t avSyncId);
AssertionResult getDemuxCaps(DemuxCapabilities& demuxCaps);
+ AssertionResult getDemuxInfo(int32_t demuxId, DemuxInfo& demuxInfo);
AssertionResult closeDemux();
protected:
diff --git a/tv/tuner/aidl/vts/functional/DescramblerTests.cpp b/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
index 157fa04..f4855c2 100644
--- a/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
@@ -19,71 +19,115 @@
using namespace std;
AssertionResult DescramblerTests::createCasPlugin(int32_t caSystemId) {
- auto status = mMediaCasService->isSystemIdSupported(caSystemId);
- if (!status.isOk() || !status) {
- ALOGW("[vts] Failed to check isSystemIdSupported.");
- return failure();
+ mCasListener = ::ndk::SharedRefBase::make<MediaCasListener>();
+
+ if (mMediaCasServiceAidl != nullptr) {
+ bool rst = false;
+ ScopedAStatus status = mMediaCasServiceAidl->isSystemIdSupported(caSystemId, &rst);
+ if (!status.isOk() || !rst) {
+ ALOGW("[vts] Failed to check isSystemIdSupported for AIDL service.");
+ return failure();
+ }
+ status = mMediaCasServiceAidl->createPlugin(caSystemId, mCasListener, &mCasAidl);
+ if (!status.isOk()) {
+ ALOGW("[vts] Failed to createPlugin for AIDL service.");
+ return failure();
+ }
+ } else {
+ auto status = mMediaCasServiceHidl->isSystemIdSupported(caSystemId);
+ if (!status.isOk() || !status) {
+ ALOGW("[vts] Failed to check isSystemIdSupported for HIDL service.");
+ return failure();
+ }
+ auto pluginStatus = mMediaCasServiceHidl->createPluginExt(
+ caSystemId, sp<ICasListenerHidl>(mCasListener.get()));
+ if (!pluginStatus.isOk()) {
+ ALOGW("[vts] Failed to createPluginExt for HIDL service.");
+ return failure();
+ }
+ mCasHidl = ICasHidl::castFrom(pluginStatus);
+ if (mCasHidl == nullptr) {
+ ALOGW("[vts] Failed to get ICas for HIDL service.");
+ return failure();
+ }
}
- mCasListener = new MediaCasListener();
- auto pluginStatus = mMediaCasService->createPluginExt(caSystemId, mCasListener);
- if (!pluginStatus.isOk()) {
- ALOGW("[vts] Failed to createPluginExt.");
- return failure();
- }
- mCas = ICas::castFrom(pluginStatus);
- if (mCas == nullptr) {
- ALOGW("[vts] Failed to get ICas.");
- return failure();
- }
return success();
}
AssertionResult DescramblerTests::openCasSession(vector<uint8_t>& sessionId,
- vector<uint8_t>& hidlPvtData) {
- Status sessionStatus;
- SessionIntent intent = SessionIntent::LIVE;
- ScramblingMode mode = ScramblingMode::RESERVED;
- auto returnVoid =
- mCas->openSession_1_2(intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) {
- sessionStatus = status;
- sessionId = id;
- });
- if (!returnVoid.isOk() || (sessionStatus != Status::OK)) {
- ALOGW("[vts] Failed to open cas session.");
- mCas->closeSession(sessionId);
- return failure();
- }
-
- if (hidlPvtData.size() > 0) {
- auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData);
- if (status != android::hardware::cas::V1_0::Status::OK) {
- ALOGW("[vts] Failed to set session private data");
- mCas->closeSession(sessionId);
+ vector<uint8_t>& pvtData) {
+ if (mMediaCasServiceAidl != nullptr) {
+ SessionIntentAidl intent = SessionIntentAidl::LIVE;
+ ScramblingModeAidl mode = ScramblingModeAidl::RESERVED;
+ std::vector<uint8_t> sessionId;
+ ScopedAStatus status = mCasAidl->openSession(intent, mode, &sessionId);
+ if (!status.isOk()) {
+ ALOGW("[vts] Failed to open cas session for AIDL service.");
+ mCasAidl->closeSession(sessionId);
return failure();
}
+
+ if (pvtData.size() > 0) {
+ ScopedAStatus status = mCasAidl->setSessionPrivateData(sessionId, pvtData);
+ if (!status.isOk()) {
+ ALOGW("[vts] Failed to set session private data for AIDL service.");
+ mCasAidl->closeSession(sessionId);
+ return failure();
+ }
+ }
+ } else {
+ Status sessionStatus;
+ SessionIntentHidl intent = SessionIntentHidl::LIVE;
+ ScramblingModeHidl mode = ScramblingModeHidl::RESERVED;
+ auto returnVoid = mCasHidl->openSession_1_2(
+ intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) {
+ sessionStatus = status;
+ sessionId = id;
+ });
+ if (!returnVoid.isOk() || (sessionStatus != Status::OK)) {
+ ALOGW("[vts] Failed to open cas session for HIDL service.");
+ mCasHidl->closeSession(sessionId);
+ return failure();
+ }
+
+ if (pvtData.size() > 0) {
+ auto status = mCasHidl->setSessionPrivateData(sessionId, pvtData);
+ if (status != android::hardware::cas::V1_0::Status::OK) {
+ ALOGW("[vts] Failed to set session private data for HIDL service.");
+ mCasHidl->closeSession(sessionId);
+ return failure();
+ }
+ }
}
return success();
}
AssertionResult DescramblerTests::getKeyToken(int32_t caSystemId, string& provisonStr,
- vector<uint8_t>& hidlPvtData,
- vector<uint8_t>& token) {
+ vector<uint8_t>& pvtData, vector<uint8_t>& token) {
if (createCasPlugin(caSystemId) != success()) {
ALOGW("[vts] createCasPlugin failed.");
return failure();
}
if (provisonStr.size() > 0) {
- auto returnStatus = mCas->provision(hidl_string(provisonStr));
- if (returnStatus != android::hardware::cas::V1_0::Status::OK) {
- ALOGW("[vts] provision failed.");
- return failure();
+ if (mMediaCasServiceAidl != nullptr) {
+ ScopedAStatus status = mCasAidl->provision(provisonStr);
+ if (!status.isOk()) {
+ ALOGW("[vts] provision failed for AIDL service.");
+ return failure();
+ }
+ } else {
+ auto returnStatus = mCasHidl->provision(hidl_string(provisonStr));
+ if (returnStatus != android::hardware::cas::V1_0::Status::OK) {
+ ALOGW("[vts] provision failed for HIDL service.");
+ return failure();
+ }
}
}
- return openCasSession(token, hidlPvtData);
+ return openCasSession(token, pvtData);
}
AssertionResult DescramblerTests::openDescrambler(int32_t demuxId) {
diff --git a/tv/tuner/aidl/vts/functional/DescramblerTests.h b/tv/tuner/aidl/vts/functional/DescramblerTests.h
index f0b7691..bab1a88 100644
--- a/tv/tuner/aidl/vts/functional/DescramblerTests.h
+++ b/tv/tuner/aidl/vts/functional/DescramblerTests.h
@@ -30,11 +30,17 @@
#include <android/hardware/cas/1.2/IMediaCasService.h>
#include <android/hardware/cas/1.2/types.h>
+#include <aidl/android/hardware/cas/BnCasListener.h>
+#include <aidl/android/hardware/cas/ICas.h>
+#include <aidl/android/hardware/cas/IMediaCasService.h>
+#include <aidl/android/hardware/cas/ScramblingMode.h>
+#include <aidl/android/hardware/cas/SessionIntent.h>
#include <aidl/android/hardware/tv/tuner/IDescrambler.h>
#include <aidl/android/hardware/tv/tuner/IDvr.h>
#include <aidl/android/hardware/tv/tuner/IDvrCallback.h>
#include <aidl/android/hardware/tv/tuner/ITuner.h>
+using ::aidl::android::hardware::cas::BnCasListener;
using android::Condition;
using android::Mutex;
using android::sp;
@@ -42,19 +48,26 @@
using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::Void;
-using android::hardware::cas::V1_2::ICas;
-using android::hardware::cas::V1_2::ICasListener;
-using android::hardware::cas::V1_2::IMediaCasService;
-using android::hardware::cas::V1_2::ScramblingMode;
-using android::hardware::cas::V1_2::SessionIntent;
using android::hardware::cas::V1_2::Status;
using android::hardware::cas::V1_2::StatusEvent;
+using ICasAidl = ::aidl::android::hardware::cas::ICas;
+using ICasHidl = android::hardware::cas::V1_2::ICas;
+using ICasListenerHidl = android::hardware::cas::V1_2::ICasListener;
+using IMediaCasServiceAidl = ::aidl::android::hardware::cas::IMediaCasService;
+using IMediaCasServiceHidl = android::hardware::cas::V1_2::IMediaCasService;
+using ScramblingModeAidl = ::aidl::android::hardware::cas::ScramblingMode;
+using ScramblingModeHidl = android::hardware::cas::V1_2::ScramblingMode;
+using SessionIntentAidl = ::aidl::android::hardware::cas::SessionIntent;
+using SessionIntentHidl = android::hardware::cas::V1_2::SessionIntent;
+using ::ndk::ScopedAStatus;
using ::testing::AssertionResult;
using namespace aidl::android::hardware::tv::tuner;
-class MediaCasListener : public ICasListener {
+const std::string MEDIA_CAS_AIDL_SERVICE_NAME = "android.hardware.cas.IMediaCasService/default";
+
+class MediaCasListener : public ICasListenerHidl, public BnCasListener {
public:
virtual Return<void> onEvent(int32_t /*event*/, int32_t /*arg*/,
const hidl_vec<uint8_t>& /*data*/) override {
@@ -70,12 +83,33 @@
virtual Return<void> onStatusUpdate(StatusEvent /*event*/, int32_t /*arg*/) override {
return Void();
}
+
+ ScopedAStatus onEvent(int32_t /*in_event*/, int32_t /*in_arg*/,
+ const std::vector<uint8_t>& /*in_data*/) override {
+ return ScopedAStatus::ok();
+ }
+
+ ScopedAStatus onSessionEvent(const std::vector<uint8_t>& /*in_sessionId*/, int32_t /*in_event*/,
+ int32_t /*in_arg*/,
+ const std::vector<uint8_t>& /*in_data*/) override {
+ return ScopedAStatus::ok();
+ }
+
+ ScopedAStatus onStatusUpdate(::aidl::android::hardware::cas::StatusEvent /*in_event*/,
+ int32_t /*in_number*/) override {
+ return ScopedAStatus::ok();
+ }
};
class DescramblerTests {
public:
void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
- void setCasService(sp<IMediaCasService> casService) { mMediaCasService = casService; }
+ void setCasServiceHidl(sp<IMediaCasServiceHidl> casService) {
+ mMediaCasServiceHidl = casService;
+ }
+ void setCasServiceAidl(std::shared_ptr<IMediaCasServiceAidl> casService) {
+ mMediaCasServiceAidl = casService;
+ }
AssertionResult setKeyToken(std::vector<uint8_t>& token);
AssertionResult openDescrambler(int32_t demuxId);
@@ -95,12 +129,13 @@
std::shared_ptr<ITuner> mService;
std::shared_ptr<IDescrambler> mDescrambler;
- android::sp<ICas> mCas;
- android::sp<IMediaCasService> mMediaCasService;
- android::sp<MediaCasListener> mCasListener;
+ std::shared_ptr<ICasAidl> mCasAidl;
+ android::sp<ICasHidl> mCasHidl;
+ std::shared_ptr<IMediaCasServiceAidl> mMediaCasServiceAidl;
+ android::sp<IMediaCasServiceHidl> mMediaCasServiceHidl;
+ std::shared_ptr<MediaCasListener> mCasListener;
private:
- AssertionResult openCasSession(std::vector<uint8_t>& sessionId,
- std::vector<uint8_t>& hidlPvtData);
+ AssertionResult openCasSession(std::vector<uint8_t>& sessionId, std::vector<uint8_t>& pvtData);
AssertionResult createCasPlugin(int32_t caSystemId);
};
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.cpp b/tv/tuner/aidl/vts/functional/DvrTests.cpp
index a9c3b51..50f4de2 100644
--- a/tv/tuner/aidl/vts/functional/DvrTests.cpp
+++ b/tv/tuner/aidl/vts/functional/DvrTests.cpp
@@ -323,3 +323,41 @@
ASSERT_TRUE(mDvrRecord);
ASSERT_TRUE(mDvrRecord->close().isOk());
}
+
+AssertionResult DvrTests::setPlaybackStatusCheckIntervalHint(int64_t milliseconds) {
+ ndk::ScopedAStatus status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
+
+ status = mDvrPlayback->setStatusCheckIntervalHint(milliseconds);
+
+ if (getDvrPlaybackInterfaceVersion() < 2) {
+ return AssertionResult(status.getStatus() == STATUS_UNKNOWN_TRANSACTION);
+ }
+ return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::setRecordStatusCheckIntervalHint(int64_t milliseconds) {
+ ndk::ScopedAStatus status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+ status = mDvrRecord->setStatusCheckIntervalHint(milliseconds);
+
+ if (getDvrRecordInterfaceVersion() < 2) {
+ return AssertionResult(status.getStatus() == STATUS_UNKNOWN_TRANSACTION);
+ }
+ return AssertionResult(status.isOk());
+}
+
+int32_t DvrTests::getDvrPlaybackInterfaceVersion() {
+ int32_t version;
+ mDvrPlayback->getInterfaceVersion(&version);
+ return version;
+}
+
+int32_t DvrTests::getDvrRecordInterfaceVersion() {
+ int32_t version;
+ mDvrRecord->getInterfaceVersion(&version);
+ return version;
+}
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.h b/tv/tuner/aidl/vts/functional/DvrTests.h
index 6662637..a88ba24 100644
--- a/tv/tuner/aidl/vts/functional/DvrTests.h
+++ b/tv/tuner/aidl/vts/functional/DvrTests.h
@@ -162,8 +162,12 @@
AssertionResult startDvrPlayback();
AssertionResult stopDvrRecord();
AssertionResult startDvrRecord();
+ AssertionResult setPlaybackStatusCheckIntervalHint(int64_t milliseconds);
+ AssertionResult setRecordStatusCheckIntervalHint(int64_t milliseconds);
void closeDvrPlayback();
void closeDvrRecord();
+ int32_t getDvrPlaybackInterfaceVersion();
+ int32_t getDvrRecordInterfaceVersion();
protected:
static AssertionResult failure() { return ::testing::AssertionFailure(); }
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index a1f51df..b0f614e 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#include <aidl/android/hardware/tv/tuner/Result.h>
-
#include "FrontendTests.h"
+#include <aidl/android/hardware/tv/tuner/Result.h>
+
ndk::ScopedAStatus FrontendCallback::onEvent(FrontendEventType frontendEventType) {
android::Mutex::Autolock autoLock(mMsgLock);
ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
@@ -323,7 +323,10 @@
FrontendStatusType type = statusTypes[i];
switch (type) {
case FrontendStatusType::MODULATIONS: {
- // TODO: verify modulations
+ ASSERT_TRUE(std::equal(
+ realStatuses[i].get<FrontendStatus::Tag::modulations>().begin(),
+ realStatuses[i].get<FrontendStatus::Tag::modulations>().end(),
+ expectStatuses[i].get<FrontendStatus::Tag::modulations>().begin()));
break;
}
case FrontendStatusType::BERS: {
@@ -340,11 +343,13 @@
break;
}
case FrontendStatusType::GUARD_INTERVAL: {
- // TODO: verify interval
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::interval>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::interval>());
break;
}
case FrontendStatusType::TRANSMISSION_MODE: {
- // TODO: verify tranmission mode
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::transmissionMode>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::transmissionMode>());
break;
}
case FrontendStatusType::UEC: {
@@ -379,7 +384,8 @@
break;
}
case FrontendStatusType::ROLL_OFF: {
- // TODO: verify roll off
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::rollOff>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::rollOff>());
break;
}
case FrontendStatusType::IS_MISO: {
@@ -428,6 +434,31 @@
expectStatuses[i].get<FrontendStatus::Tag::allPlpInfo>().begin()));
break;
}
+ case FrontendStatusType::IPTV_CONTENT_URL: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvContentUrl>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::iptvContentUrl>());
+ break;
+ }
+ case FrontendStatusType::IPTV_PACKETS_LOST: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvPacketsLost>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::iptvPacketsLost>());
+ break;
+ }
+ case FrontendStatusType::IPTV_PACKETS_RECEIVED: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvPacketsReceived>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::iptvPacketsReceived>());
+ break;
+ }
+ case FrontendStatusType::IPTV_WORST_JITTER_MS: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvWorstJitterMs>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::iptvWorstJitterMs>());
+ break;
+ }
+ case FrontendStatusType::IPTV_AVERAGE_JITTER_MS: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::iptvAverageJitterMs>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::iptvAverageJitterMs>());
+ break;
+ }
default: {
continue;
}
@@ -599,9 +630,10 @@
ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
// TODO: find a better way to push all frontend status types
- for (int32_t i = 0; i < static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
+ for (int32_t i = 0; i <= static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
allTypes.push_back(static_cast<FrontendStatusType>(i));
}
+
ndk::ScopedAStatus status = mFrontend->getFrontendStatusReadiness(allTypes, &readiness);
ASSERT_TRUE(status.isOk());
ASSERT_TRUE(readiness.size() == allTypes.size());
diff --git a/tv/tuner/aidl/vts/functional/LnbTests.h b/tv/tuner/aidl/vts/functional/LnbTests.h
index d6b5a25..a21e68d 100644
--- a/tv/tuner/aidl/vts/functional/LnbTests.h
+++ b/tv/tuner/aidl/vts/functional/LnbTests.h
@@ -25,6 +25,8 @@
#include <utils/Mutex.h>
#include <map>
+#define INVALID_LNB_ID -1
+
using android::Condition;
using android::Mutex;
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 07e3e3c..9db82c8 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -129,8 +129,8 @@
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- if (mLnbId) {
- ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId));
+ if (mLnbId != INVALID_LNB_ID) {
+ ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
}
if (frontendConf.isSoftwareFe) {
mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]);
@@ -162,18 +162,19 @@
ASSERT_TRUE(mLnbTests.getLnbIds(ids));
ASSERT_TRUE(ids.size() > 0);
ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
- mLnbId = &ids[0];
+ mLnbId = ids[0];
} else {
- mLnbId = (int32_t*)malloc(sizeof(int32_t));
- ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, mLnbId));
}
ASSERT_TRUE(mLnbTests.setLnbCallback());
ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone));
ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position));
- broadcastSingleFilterTest(filterConf, frontendConf);
+ if (!frontendConf.isSoftwareFe) {
+ broadcastSingleFilterTest(filterConf, frontendConf);
+ }
ASSERT_TRUE(mLnbTests.closeLnb());
- mLnbId = nullptr;
+ mLnbId = INVALID_LNB_ID;
}
void TunerBroadcastAidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf,
@@ -240,6 +241,28 @@
ASSERT_TRUE(mDemuxTests.closeDemux());
}
+void TunerPlaybackAidlTest::setStatusCheckIntervalHintTest(int64_t statusCheckIntervalHint,
+ DvrConfig dvrConf) {
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+
+ ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+ mDvrTests.setDemux(demux);
+ ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+ ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings));
+ ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+
+ ASSERT_TRUE(mDvrTests.setPlaybackStatusCheckIntervalHint(statusCheckIntervalHint));
+
+ mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile,
+ dvrConf.settings.get<DvrSettings::Tag::playback>());
+ ASSERT_TRUE(mDvrTests.startDvrPlayback());
+ mDvrTests.stopPlaybackThread();
+ ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+ mDvrTests.closeDvrPlayback();
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
void TunerRecordAidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf,
FrontendConfig frontendConf,
DvrConfig dvrConf, LnbConfig lnbConf) {
@@ -248,10 +271,9 @@
ASSERT_TRUE(mLnbTests.getLnbIds(ids));
ASSERT_TRUE(ids.size() > 0);
ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
- mLnbId = &ids[0];
+ mLnbId = ids[0];
} else {
- mLnbId = (int32_t*)malloc(sizeof(int32_t));
- ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, mLnbId));
}
ASSERT_TRUE(mLnbTests.setLnbCallback());
ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
@@ -260,9 +282,11 @@
for (auto msgName : lnbRecord.diseqcMsgs) {
ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
}
- recordSingleFilterTest(filterConf, frontendConf, dvrConf);
+ if (!frontendConf.isSoftwareFe) {
+ recordSingleFilterTest(filterConf, frontendConf, dvrConf, Dataflow_Context::LNBRECORD);
+ }
ASSERT_TRUE(mLnbTests.closeLnb());
- mLnbId = nullptr;
+ mLnbId = INVALID_LNB_ID;
}
void TunerRecordAidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf,
@@ -318,29 +342,47 @@
}
void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
- FrontendConfig frontendConf, DvrConfig dvrConf) {
+ FrontendConfig frontendConf, DvrConfig dvrConf,
+ Dataflow_Context context) {
int32_t demuxId;
std::shared_ptr<IDemux> demux;
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
mDvrTests.setDemux(demux);
DvrConfig dvrSourceConfig;
- if (record.hasFrontendConnection) {
+ if (context == Dataflow_Context::RECORD) {
+ if (record.hasFrontendConnection) {
+ int32_t feId;
+ mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ if (frontendConf.isSoftwareFe) {
+ mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+ }
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ mFrontendTests.setDvrTests(&mDvrTests);
+ } else {
+ dvrSourceConfig = dvrMap[record.dvrSourceId];
+ ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+ ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+ ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+ }
+ } else if (context == Dataflow_Context::LNBRECORD) {
+ // If function arrives here, frontend should not be software, so no need to configure a dvr
+ // source or dvr fe connection that might be used for recording without an Lnb
int32_t feId;
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- if (frontendConf.isSoftwareFe) {
- mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+ if (mLnbId != INVALID_LNB_ID) {
+ ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
+ } else {
+ FAIL();
}
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFrontendTests.setDvrTests(&mDvrTests);
- } else {
- dvrSourceConfig = dvrMap[record.dvrSourceId];
- ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
- ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
- ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
}
int64_t filterId;
@@ -360,24 +402,31 @@
ASSERT_TRUE(mDvrTests.startDvrRecord());
ASSERT_TRUE(mFilterTests.startFilter(filterId));
- if (record.hasFrontendConnection) {
+ if (context == Dataflow_Context::RECORD) {
+ if (record.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+ } else {
+ // Start DVR Source
+ mDvrTests.startPlaybackInputThread(
+ dvrSourceConfig.playbackInputFile,
+ dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
+ ASSERT_TRUE(mDvrTests.startDvrPlayback());
+ }
+ } else if (context == Dataflow_Context::LNBRECORD) {
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
- } else {
- // Start DVR Source
- mDvrTests.startPlaybackInputThread(
- dvrSourceConfig.playbackInputFile,
- dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
- ASSERT_TRUE(mDvrTests.startDvrPlayback());
}
-
mDvrTests.testRecordOutput();
mDvrTests.stopRecordThread();
- if (record.hasFrontendConnection) {
+ if (context == Dataflow_Context::RECORD) {
+ if (record.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+ } else {
+ mDvrTests.stopPlaybackThread();
+ ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+ }
+ } else if (context == Dataflow_Context::LNBRECORD) {
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
- } else {
- mDvrTests.stopPlaybackThread();
- ASSERT_TRUE(mDvrTests.stopDvrPlayback());
}
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -386,39 +435,99 @@
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
mDvrTests.closeDvrRecord();
- if (record.hasFrontendConnection) {
+ if (context == Dataflow_Context::RECORD) {
+ if (record.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+ } else {
+ mDvrTests.closeDvrPlayback();
+ }
+ } else if (context == Dataflow_Context::LNBRECORD) {
ASSERT_TRUE(mFrontendTests.closeFrontend());
- } else {
- mDvrTests.closeDvrPlayback();
}
ASSERT_TRUE(mDemuxTests.closeDemux());
}
+void TunerRecordAidlTest::setStatusCheckIntervalHintTest(int64_t statusCheckIntervalHint,
+ FrontendConfig frontendConf,
+ DvrConfig dvrConf) {
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+ ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+ mDvrTests.setDemux(demux);
+
+ DvrConfig dvrSourceConfig;
+ if (record.hasFrontendConnection) {
+ int32_t feId;
+ mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ } else {
+ dvrSourceConfig = dvrMap[record.dvrSourceId];
+ ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+ ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+ ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+ }
+
+ ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+ ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
+ ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
+
+ ASSERT_TRUE(mDvrTests.setRecordStatusCheckIntervalHint(statusCheckIntervalHint));
+
+ ASSERT_TRUE(mDvrTests.startDvrRecord());
+ ASSERT_TRUE(mDvrTests.stopDvrRecord());
+ mDvrTests.closeDvrRecord();
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+
+ if (record.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+ }
+}
+
void TunerDescramblerAidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
FrontendConfig frontendConf,
- DescramblerConfig descConfig) {
+ DescramblerConfig descConfig,
+ Dataflow_Context context) {
int32_t demuxId;
std::shared_ptr<IDemux> demux;
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
DvrConfig dvrSourceConfig;
- if (descrambling.hasFrontendConnection) {
+ if (context == Dataflow_Context::DESCRAMBLING) {
+ if (descrambling.hasFrontendConnection) {
+ int32_t feId;
+ mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ if (frontendConf.isSoftwareFe) {
+ mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+ }
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ mFrontendTests.setDemux(demux);
+ } else {
+ dvrSourceConfig = dvrMap[descrambling.dvrSourceId];
+ mDvrTests.setDemux(demux);
+ ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+ ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+ ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+ }
+ } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
int32_t feId;
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- if (frontendConf.isSoftwareFe) {
- mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+ if (mLnbId != INVALID_LNB_ID) {
+ ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
+ } else {
+ // If, for some reason, the test got here without failing. We fail it here.
+ ALOGD("mLnbId is null. Something went wrong. Exiting ScrambledBroadcastWithLnbId.");
+ FAIL();
}
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFrontendTests.setDemux(demux);
- } else {
- dvrSourceConfig = dvrMap[descrambling.dvrSourceId];
- mDvrTests.setDemux(demux);
- ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
- ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
- ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
}
set<int64_t> filterIds;
@@ -449,24 +558,32 @@
ASSERT_TRUE(mFilterTests.startFilter(*id));
}
- if (descrambling.hasFrontendConnection) {
- // tune test
+ if (context == Dataflow_Context::DESCRAMBLING) {
+ if (descrambling.hasFrontendConnection) {
+ // tune test
+ ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+ } else {
+ // Start DVR Source
+ mDvrTests.startPlaybackInputThread(
+ dvrSourceConfig.playbackInputFile,
+ dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
+ ASSERT_TRUE(mDvrTests.startDvrPlayback());
+ }
+ } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
- } else {
- // Start DVR Source
- mDvrTests.startPlaybackInputThread(
- dvrSourceConfig.playbackInputFile,
- dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
- ASSERT_TRUE(mDvrTests.startDvrPlayback());
}
ASSERT_TRUE(filterDataOutputTest());
- if (descrambling.hasFrontendConnection) {
+ if (context == Dataflow_Context::DESCRAMBLING) {
+ if (descrambling.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+ } else {
+ mDvrTests.stopPlaybackThread();
+ ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+ }
+ } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
- } else {
- mDvrTests.stopPlaybackThread();
- ASSERT_TRUE(mDvrTests.stopDvrPlayback());
}
for (id = filterIds.begin(); id != filterIds.end(); id++) {
@@ -480,37 +597,80 @@
ASSERT_TRUE(mFilterTests.closeFilter(*id));
}
- if (descrambling.hasFrontendConnection) {
+ if (context == Dataflow_Context::DESCRAMBLING) {
+ if (descrambling.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+ } else {
+ mDvrTests.closeDvrPlayback();
+ }
+ } else if (context == Dataflow_Context::LNBDESCRAMBLING) {
ASSERT_TRUE(mFrontendTests.closeFrontend());
- } else {
- mDvrTests.closeDvrPlayback();
}
ASSERT_TRUE(mDemuxTests.closeDemux());
}
+void TunerDescramblerAidlTest::scrambledBroadcastTestWithLnb(
+ set<struct FilterConfig>& mediaFilterConfs, FrontendConfig& frontendConf,
+ DescramblerConfig& descConfig, LnbConfig& lnbConfig) {
+ // We can test the Lnb individually and make sure it functions properly. If the frontend is
+ // software, we cannot test the whole dataflow. If the frontend is hardware, we can
+ if (lnbConfig.name.compare(emptyHardwareId) == 0) {
+ vector<int32_t> ids;
+ ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+ ASSERT_TRUE(ids.size() > 0);
+ ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+ mLnbId = ids[0];
+ } else {
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbConfig.name, mLnbId));
+ }
+ // Once Lnb is opened, test some of its basic functionality
+ ASSERT_TRUE(mLnbTests.setLnbCallback());
+ ASSERT_TRUE(mLnbTests.setVoltage(lnbConfig.voltage));
+ ASSERT_TRUE(mLnbTests.setTone(lnbConfig.tone));
+ ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConfig.position));
+ if (!frontendConf.isSoftwareFe) {
+ ALOGD("Frontend is not software, testing entire dataflow.");
+ scrambledBroadcastTest(mediaFilterConfs, frontendConf, descConfig,
+ Dataflow_Context::LNBDESCRAMBLING);
+ } else {
+ ALOGD("Frontend is software, did not test the entire dataflow, but tested the Lnb "
+ "individually.");
+ }
+ ASSERT_TRUE(mLnbTests.closeLnb());
+ mLnbId = INVALID_LNB_ID;
+}
+
TEST_P(TunerLnbAidlTest, SendDiseqcMessageToLnb) {
description("Open and configure an Lnb with specific settings then send a diseqc msg to it.");
if (!lnbLive.support) {
return;
}
- if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
- vector<int32_t> ids;
- ASSERT_TRUE(mLnbTests.getLnbIds(ids));
- ASSERT_TRUE(ids.size() > 0);
- ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
- } else {
- int32_t id;
- ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+ vector<LnbLiveHardwareConnections> lnbLive_configs = generateLnbLiveConfigurations();
+ if (lnbLive_configs.empty()) {
+ ALOGD("No frontends that support satellites.");
+ return;
}
- ASSERT_TRUE(mLnbTests.setLnbCallback());
- ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
- ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
- ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
- for (auto msgName : lnbLive.diseqcMsgs) {
- ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+ for (auto& combination : lnbLive_configs) {
+ lnbLive = combination;
+ if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
+ vector<int32_t> ids;
+ ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+ ASSERT_TRUE(ids.size() > 0);
+ ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+ } else {
+ int32_t id;
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+ }
+ ASSERT_TRUE(mLnbTests.setLnbCallback());
+ ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
+ ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
+ ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
+ for (auto msgName : lnbLive.diseqcMsgs) {
+ ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+ }
+ ASSERT_TRUE(mLnbTests.closeLnb());
}
- ASSERT_TRUE(mLnbTests.closeLnb());
}
TEST_P(TunerDemuxAidlTest, openDemux) {
@@ -518,17 +678,49 @@
if (!live.hasFrontendConnection) {
return;
}
- int32_t feId;
- int32_t demuxId;
- std::shared_ptr<IDemux> demux;
- mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
- ASSERT_TRUE(feId != INVALID_ID);
- ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
- ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
- ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
- ASSERT_TRUE(mDemuxTests.closeDemux());
- ASSERT_TRUE(mFrontendTests.closeFrontend());
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ int32_t feId;
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+ mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+ }
+}
+
+TEST_P(TunerDemuxAidlTest, openDemuxById) {
+ description("Open (with id) and close a Demux.");
+ std::vector<int32_t> demuxIds;
+ ASSERT_TRUE(mDemuxTests.getDemuxIds(demuxIds));
+ for (int i = 0; i < demuxIds.size(); i++) {
+ std::shared_ptr<IDemux> demux;
+ ASSERT_TRUE(mDemuxTests.openDemuxById(demuxIds[i], demux));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+ }
+}
+
+TEST_P(TunerDemuxAidlTest, getDemuxInfo) {
+ description("Check getDemuxInfo against demux caps");
+ std::vector<int32_t> demuxIds;
+ ASSERT_TRUE(mDemuxTests.getDemuxIds(demuxIds));
+ int32_t combinedFilterTypes = 0;
+ for (int i = 0; i < demuxIds.size(); i++) {
+ DemuxInfo demuxInfo;
+ ASSERT_TRUE(mDemuxTests.getDemuxInfo(demuxIds[i], demuxInfo));
+ combinedFilterTypes |= demuxInfo.filterTypes;
+ }
+ if (demuxIds.size() > 0) {
+ DemuxCapabilities demuxCaps;
+ ASSERT_TRUE(mDemuxTests.getDemuxCaps(demuxCaps));
+ ASSERT_TRUE(demuxCaps.filterCaps == combinedFilterTypes);
+ }
}
TEST_P(TunerDemuxAidlTest, getAvSyncTime) {
@@ -536,40 +728,45 @@
if (!live.hasFrontendConnection) {
return;
}
- if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
- return;
- }
- int32_t feId;
- int32_t demuxId;
- std::shared_ptr<IDemux> demux;
- int64_t mediaFilterId;
- int64_t pcrFilterId;
- int32_t avSyncHwId;
- std::shared_ptr<IFilter> mediaFilter;
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
+ continue;
+ }
+ int32_t feId;
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+ int64_t mediaFilterId;
+ int64_t pcrFilterId;
+ int32_t avSyncHwId;
+ std::shared_ptr<IFilter> mediaFilter;
- mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
- ASSERT_TRUE(feId != INVALID_ID);
- ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
- ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
- ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
- mFilterTests.setDemux(demux);
- ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type,
- filterMap[live.videoFilterId].bufferSize));
- ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId));
- mediaFilter = mFilterTests.getFilterById(mediaFilterId);
- ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type,
- filterMap[live.pcrFilterId].bufferSize));
- ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId));
- ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId));
- ASSERT_TRUE(pcrFilterId == avSyncHwId);
- ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
- ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
- ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
- ASSERT_TRUE(mDemuxTests.closeDemux());
- ASSERT_TRUE(mFrontendTests.closeFrontend());
+ mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ mFilterTests.setDemux(demux);
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type,
+ filterMap[live.videoFilterId].bufferSize));
+ ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
+ ASSERT_TRUE(
+ mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId));
+ mediaFilter = mFilterTests.getFilterById(mediaFilterId);
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type,
+ filterMap[live.pcrFilterId].bufferSize));
+ ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
+ ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId));
+ ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId));
+ ASSERT_TRUE(pcrFilterId == avSyncHwId);
+ ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
+ ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
+ ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+ }
}
TEST_P(TunerFilterAidlTest, StartFilterInDemux) {
@@ -578,7 +775,11 @@
return;
}
// TODO use parameterized tests
- configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerFilterAidlTest, ConfigIpFilterInDemuxWithCid) {
@@ -587,10 +788,14 @@
if (!live.hasFrontendConnection) {
return;
}
- if (live.ipFilterId.compare(emptyHardwareId) == 0) {
- return;
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ if (live.ipFilterId.compare(emptyHardwareId) == 0) {
+ continue;
+ }
+ configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
}
- configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerFilterAidlTest, ReconfigFilterToReceiveStartId) {
@@ -599,8 +804,13 @@
return;
}
// TODO use parameterized tests
- reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId],
- frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId],
+ filterMap[live.videoFilterId],
+ frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerFilterAidlTest, SetFilterLinkage) {
@@ -637,7 +847,11 @@
return;
}
// TODO use parameterized tests
- testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+ auto timeFilter_configs = generateTimeFilterConfigurations();
+ for (auto& configuration : timeFilter_configs) {
+ timeFilter = configuration;
+ testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+ }
}
static bool isEventProducingFilter(const FilterConfig& filterConfig) {
@@ -839,10 +1053,16 @@
TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
description("Feed ts data from playback and configure Ts section filter to get output");
- if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
+ if (!playback.support) {
return;
}
- playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
+ vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+ for (auto& configuration : playback_configs) {
+ if (configuration.sectionFilterId.compare(emptyHardwareId) != 0) {
+ playback = configuration;
+ playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
+ }
+ }
}
TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsAudioFilterTest) {
@@ -850,7 +1070,11 @@
if (!playback.support) {
return;
}
- playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]);
+ vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+ for (auto& configuration : playback_configs) {
+ playback = configuration;
+ playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]);
+ }
}
TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsVideoFilterTest) {
@@ -858,7 +1082,23 @@
if (!playback.support) {
return;
}
- playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]);
+ vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+ for (auto& configuration : playback_configs) {
+ playback = configuration;
+ playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]);
+ }
+}
+
+TEST_P(TunerPlaybackAidlTest, SetStatusCheckIntervalHintToPlaybackTest) {
+ description("Set status check interval hint to playback test.");
+ if (!playback.support) {
+ return;
+ }
+ vector<DvrPlaybackHardwareConnections> playback_configs = generatePlaybackConfigs();
+ for (auto& configuration : playback_configs) {
+ playback = configuration;
+ setStatusCheckIntervalHintTest(STATUS_CHECK_INTERVAL_MS, dvrMap[playback.dvrId]);
+ }
}
TEST_P(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) {
@@ -866,8 +1106,12 @@
if (!record.support) {
return;
}
- recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
- dvrMap[record.dvrRecordId]);
+ auto record_configs = generateRecordConfigurations();
+ for (auto& configuration : record_configs) {
+ record = configuration;
+ recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
+ dvrMap[record.dvrRecordId], Dataflow_Context::RECORD);
+ }
}
TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) {
@@ -876,8 +1120,13 @@
if (!record.support) {
return;
}
- attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
- frontendMap[record.frontendId], dvrMap[record.dvrRecordId]);
+ auto record_configs = generateRecordConfigurations();
+ for (auto& configuration : record_configs) {
+ record = configuration;
+ attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
+ frontendMap[record.frontendId],
+ dvrMap[record.dvrRecordId]);
+ }
}
TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
@@ -885,9 +1134,30 @@
if (!lnbRecord.support) {
return;
}
- recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId],
- frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId],
- lnbMap[lnbRecord.lnbId]);
+ vector<LnbRecordHardwareConnections> lnbRecord_configs = generateLnbRecordConfigurations();
+ if (lnbRecord_configs.empty()) {
+ ALOGD("No frontends that support satellites.");
+ return;
+ }
+ for (auto& configuration : lnbRecord_configs) {
+ lnbRecord = configuration;
+ recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId],
+ frontendMap[lnbRecord.frontendId],
+ dvrMap[lnbRecord.dvrRecordId], lnbMap[lnbRecord.lnbId]);
+ }
+}
+
+TEST_P(TunerRecordAidlTest, SetStatusCheckIntervalHintToRecordTest) {
+ description("Set status check interval hint to record test.");
+ if (!record.support) {
+ return;
+ }
+ auto record_configs = generateRecordConfigurations();
+ for (auto& configuration : record_configs) {
+ record = configuration;
+ setStatusCheckIntervalHintTest(STATUS_CHECK_INTERVAL_MS, frontendMap[record.frontendId],
+ dvrMap[record.dvrRecordId]);
+ }
}
TEST_P(TunerFrontendAidlTest, TuneFrontend) {
@@ -895,7 +1165,11 @@
if (!live.hasFrontendConnection) {
return;
}
- mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerFrontendAidlTest, AutoScanFrontend) {
@@ -903,7 +1177,11 @@
if (!scan.hasFrontendConnection) {
return;
}
- mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
+ vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+ for (auto& configuration : scan_configs) {
+ scan = configuration;
+ mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
+ }
}
TEST_P(TunerFrontendAidlTest, BlindScanFrontend) {
@@ -911,7 +1189,11 @@
if (!scan.hasFrontendConnection) {
return;
}
- mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+ vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+ for (auto& configuration : scan_configs) {
+ scan = configuration;
+ mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+ }
}
TEST_P(TunerFrontendAidlTest, TuneFrontendWithFrontendSettings) {
@@ -919,7 +1201,11 @@
if (!live.hasFrontendConnection) {
return;
}
- mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerFrontendAidlTest, BlindScanFrontendWithEndFrequency) {
@@ -927,7 +1213,11 @@
if (!scan.hasFrontendConnection) {
return;
}
- mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+ vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
+ for (auto& configuration : scan_configs) {
+ scan = configuration;
+ mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+ }
}
TEST_P(TunerFrontendAidlTest, LinkToCiCam) {
@@ -935,10 +1225,14 @@
if (!live.hasFrontendConnection) {
return;
}
- if (!frontendMap[live.frontendId].canConnectToCiCam) {
- return;
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ if (!frontendMap[live.frontendId].canConnectToCiCam) {
+ continue;
+ }
+ mFrontendTests.tuneTest(frontendMap[live.frontendId]);
}
- mFrontendTests.tuneTest(frontendMap[live.frontendId]);
}
TEST_P(TunerFrontendAidlTest, getHardwareInfo) {
@@ -946,7 +1240,11 @@
if (!live.hasFrontendConnection) {
return;
}
- mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerFrontendAidlTest, maxNumberOfFrontends) {
@@ -962,7 +1260,11 @@
if (!live.hasFrontendConnection) {
return;
}
- mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) {
@@ -970,7 +1272,11 @@
if (!live.hasFrontendConnection) {
return;
}
- broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowAudioFilterTest) {
@@ -978,7 +1284,11 @@
if (!live.hasFrontendConnection) {
return;
}
- broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowSectionFilterTest) {
@@ -986,10 +1296,14 @@
if (!live.hasFrontendConnection) {
return;
}
- if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
- return;
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
+ continue;
+ }
+ broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
}
- broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerBroadcastAidlTest, IonBufferTest) {
@@ -997,7 +1311,11 @@
if (!live.hasFrontendConnection) {
return;
}
- broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerBroadcastAidlTest, LnbBroadcastDataFlowVideoFilterTest) {
@@ -1005,8 +1323,16 @@
if (!lnbLive.support) {
return;
}
- broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
- frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+ vector<LnbLiveHardwareConnections> lnbLive_configs = generateLnbLiveConfigurations();
+ if (lnbLive_configs.empty()) {
+ ALOGD("No frontends that support satellites.");
+ return;
+ }
+ for (auto& combination : lnbLive_configs) {
+ lnbLive = combination;
+ broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
+ frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+ }
}
TEST_P(TunerBroadcastAidlTest, MediaFilterWithSharedMemoryHandle) {
@@ -1014,7 +1340,12 @@
if (!live.hasFrontendConnection) {
return;
}
- mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+ auto live_configs = generateLiveConfigurations();
+ for (auto& configuration : live_configs) {
+ live = configuration;
+ mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId],
+ frontendMap[live.frontendId]);
+ }
}
TEST_P(TunerDescramblerAidlTest, CreateDescrambler) {
@@ -1022,25 +1353,34 @@
if (!descrambling.support) {
return;
}
- int32_t demuxId;
- std::shared_ptr<IDemux> demux;
- ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-
- if (descrambling.hasFrontendConnection) {
- int32_t feId;
- mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
- ASSERT_TRUE(feId != INVALID_ID);
- ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
- ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ vector<DescramblingHardwareConnections> descrambling_configs =
+ generateDescramblingConfigurations();
+ if (descrambling_configs.empty()) {
+ ALOGD("No valid descrambling combinations in the configuration file.");
+ return;
}
+ for (auto& combination : descrambling_configs) {
+ descrambling = combination;
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+ ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
- ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
- ASSERT_TRUE(mDescramblerTests.closeDescrambler());
- ASSERT_TRUE(mDemuxTests.closeDemux());
+ if (descrambling.hasFrontendConnection) {
+ int32_t feId;
+ mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ }
- if (descrambling.hasFrontendConnection) {
- ASSERT_TRUE(mFrontendTests.closeFrontend());
+ ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
+ ASSERT_TRUE(mDescramblerTests.closeDescrambler());
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+
+ if (descrambling.hasFrontendConnection) {
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+ }
}
}
@@ -1049,11 +1389,42 @@
if (!descrambling.support) {
return;
}
- set<FilterConfig> filterConfs;
- filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.audioFilterId]));
- filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.videoFilterId]));
- scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId],
- descramblerMap[descrambling.descramblerId]);
+ vector<DescramblingHardwareConnections> descrambling_configs =
+ generateDescramblingConfigurations();
+ if (descrambling_configs.empty()) {
+ ALOGD("No valid descrambling combinations in the configuration file.");
+ return;
+ }
+ for (auto& combination : descrambling_configs) {
+ descrambling = combination;
+ set<FilterConfig> filterConfs;
+ filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.audioFilterId]));
+ filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.videoFilterId]));
+ scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId],
+ descramblerMap[descrambling.descramblerId],
+ Dataflow_Context::DESCRAMBLING);
+ }
+}
+
+TEST_P(TunerDescramblerAidlTest, ScrambledBroadcastDataFlowMediaFiltersTestWithLnb) {
+ description("Test media filters in scrambled broadcast use case with Lnb");
+ if (!lnbDescrambling.support) {
+ return;
+ }
+ auto lnbDescrambling_configs = generateLnbDescramblingConfigurations();
+ if (lnbDescrambling_configs.empty()) {
+ ALOGD("No frontends that support satellites.");
+ return;
+ }
+ for (auto& configuration : lnbDescrambling_configs) {
+ lnbDescrambling = configuration;
+ set<FilterConfig> filterConfs;
+ filterConfs.insert(static_cast<FilterConfig>(filterMap[lnbDescrambling.audioFilterId]));
+ filterConfs.insert(static_cast<FilterConfig>(filterMap[lnbDescrambling.videoFilterId]));
+ scrambledBroadcastTestWithLnb(filterConfs, frontendMap[lnbDescrambling.frontendId],
+ descramblerMap[lnbDescrambling.descramblerId],
+ lnbMap[lnbDescrambling.lnbId]);
+ }
}
INSTANTIATE_TEST_SUITE_P(PerInstance, TunerBroadcastAidlTest,
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index 7f80d90..8ad6ee0 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -36,11 +36,17 @@
initFrontendConfig();
initFilterConfig();
initDvrConfig();
+ initTimeFilterConfig();
+ initDescramblerConfig();
+ initLnbConfig();
+ initDiseqcMsgsConfig();
connectHardwaresToTestCases();
if (!validateConnections()) {
ALOGW("[vts] failed to validate connections.");
return false;
}
+ determineDataFlows();
+
return true;
}
@@ -58,6 +64,24 @@
return success();
}
+void clearIds() {
+ lnbIds.clear();
+ diseqcMsgs.clear();
+ frontendIds.clear();
+ ipFilterIds.clear();
+ pcrFilterIds.clear();
+ recordDvrIds.clear();
+ timeFilterIds.clear();
+ descramblerIds.clear();
+ audioFilterIds.clear();
+ videoFilterIds.clear();
+ playbackDvrIds.clear();
+ recordFilterIds.clear();
+ sectionFilterIds.clear();
+}
+
+enum class Dataflow_Context { LNBRECORD, RECORD, DESCRAMBLING, LNBDESCRAMBLING };
+
class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
@@ -73,6 +97,11 @@
mLnbTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -101,6 +130,11 @@
mFilterTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -124,13 +158,18 @@
mService = nullptr;
}
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
mFilterTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -197,6 +236,11 @@
mDvrTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -211,6 +255,8 @@
AssertionResult filterDataOutputTest();
void playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf);
+
+ void setStatusCheckIntervalHintTest(int64_t milliseconds, DvrConfig dvrConf);
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerPlaybackAidlTest);
@@ -225,7 +271,7 @@
mService = nullptr;
}
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -234,6 +280,11 @@
mLnbTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -244,7 +295,9 @@
void recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
DvrConfig dvrConf, LnbConfig lnbConf);
void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
- DvrConfig dvrConf);
+ DvrConfig dvrConf, Dataflow_Context context);
+ void setStatusCheckIntervalHintTest(int64_t milliseconds, FrontendConfig frontendConf,
+ DvrConfig dvrConf);
std::shared_ptr<ITuner> mService;
FrontendTests mFrontendTests;
@@ -254,7 +307,7 @@
LnbTests mLnbTests;
private:
- int32_t* mLnbId = nullptr;
+ int32_t mLnbId = INVALID_LNB_ID;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordAidlTest);
@@ -269,11 +322,16 @@
mService = nullptr;
}
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -295,7 +353,7 @@
mService = nullptr;
}
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -304,6 +362,11 @@
mDvrTests.setService(mService);
}
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
+ }
+
protected:
static void description(const std::string& description) {
RecordProperty("description", description);
@@ -324,7 +387,7 @@
void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf);
private:
- int32_t* mLnbId = nullptr;
+ int32_t mLnbId = INVALID_LNB_ID;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastAidlTest);
@@ -338,16 +401,37 @@
} else {
mService = nullptr;
}
- mCasService = IMediaCasService::getService();
ASSERT_NE(mService, nullptr);
- ASSERT_NE(mCasService, nullptr);
+
+ // Get IMediaCasService. Try getting AIDL service first, if AIDL does not exist, try HIDL.
+ if (AServiceManager_isDeclared(MEDIA_CAS_AIDL_SERVICE_NAME.c_str())) {
+ ::ndk::SpAIBinder binder(
+ AServiceManager_waitForService(MEDIA_CAS_AIDL_SERVICE_NAME.c_str()));
+ mCasServiceAidl = IMediaCasServiceAidl::fromBinder(binder);
+ } else {
+ mCasServiceAidl = nullptr;
+ }
+ if (mCasServiceAidl == nullptr) {
+ mCasServiceHidl = IMediaCasServiceHidl::getService();
+ }
+ ASSERT_TRUE(mCasServiceAidl != nullptr || mCasServiceHidl != nullptr);
ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
mDvrTests.setService(mService);
mDescramblerTests.setService(mService);
- mDescramblerTests.setCasService(mCasService);
+ if (mCasServiceAidl != nullptr) {
+ mDescramblerTests.setCasServiceAidl(mCasServiceAidl);
+ } else {
+ mDescramblerTests.setCasServiceHidl(mCasServiceHidl);
+ }
+ mLnbTests.setService(mService);
+ }
+
+ virtual void TearDown() override {
+ clearIds();
+ mService = nullptr;
}
protected:
@@ -356,16 +440,25 @@
}
void scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
- FrontendConfig frontendConf, DescramblerConfig descConfig);
+ FrontendConfig frontendConf, DescramblerConfig descConfig,
+ Dataflow_Context context);
+ void scrambledBroadcastTestWithLnb(set<struct FilterConfig>& mediaFilterConfs,
+ FrontendConfig& frontendConf, DescramblerConfig& descConfig,
+ LnbConfig& lnbConfig);
AssertionResult filterDataOutputTest();
std::shared_ptr<ITuner> mService;
- android::sp<IMediaCasService> mCasService;
+ sp<IMediaCasServiceHidl> mCasServiceHidl;
+ std::shared_ptr<IMediaCasServiceAidl> mCasServiceAidl;
FrontendTests mFrontendTests;
DemuxTests mDemuxTests;
FilterTests mFilterTests;
DescramblerTests mDescramblerTests;
DvrTests mDvrTests;
+ LnbTests mLnbTests;
+
+ private:
+ int32_t mLnbId = INVALID_LNB_ID;
};
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDescramblerAidlTest);
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 5f1f9c5..516cb62 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -55,6 +55,7 @@
const string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1.xml";
#define FILTER_MAIN_TYPE_BIT_COUNT 5
+#define STATUS_CHECK_INTERVAL_MS 100L
// Hardware configs
static map<string, FrontendConfig> frontendMap;
@@ -74,6 +75,512 @@
static LnbLiveHardwareConnections lnbLive;
static LnbRecordHardwareConnections lnbRecord;
static TimeFilterHardwareConnections timeFilter;
+static LnbDescramblingHardwareConnections lnbDescrambling;
+
+/*
+ * This function takes in a 2d vector of device Id's
+ * The n vectors correlate to the ids for n different devices (eg frontends, filters)
+ * The resultant 2d vector is every combination of id's with 1 id from each vector
+ */
+inline vector<vector<string>> generateIdCombinations(vector<vector<string>>& ids) {
+ vector<vector<string>> combinations;
+
+ // The index of each vector in ids that will be used in the next combination
+ // EG {0, 2} means combo {ids[0][0] ids[1][2]} will be next
+ const int size = static_cast<int>(ids.size());
+ vector<int> indexes_used_in_combination(size, 0);
+
+ // The vector number from ids whose elements we will cycle through to make combinations.
+ // First, start at the right most vector
+ int cycled_vector = size - 1;
+
+ while (cycled_vector >= 0) {
+ // Make a combination (one at a time)
+ vector<string> combo;
+ for (size_t i = 0; i < indexes_used_in_combination.size(); ++i) {
+ const int combo_index = indexes_used_in_combination[i];
+ combo.push_back(ids[i][combo_index]);
+ }
+ combinations.push_back(combo);
+
+ // Find the right most vector that still has space [elements left] to cycle through and
+ // create a combination
+ while (cycled_vector >= 0 &&
+ indexes_used_in_combination[cycled_vector] == ids[cycled_vector].size() - 1) {
+ cycled_vector--;
+ }
+
+ // Use this check to avoid segmentation faults
+ if (cycled_vector >= 0) {
+ // Once found, we have a vector we can cycle through, so increase to its next element
+ indexes_used_in_combination[cycled_vector]++;
+
+ // Reset the other vectors to the right to their first element so we can cycle through
+ // them again with the new element from cycled vector
+ for (size_t i = cycled_vector + 1; i < indexes_used_in_combination.size(); ++i) {
+ indexes_used_in_combination[i] = 0;
+ }
+
+ // all the vectors to the right were reset, so we can cycle through them again
+ // Start at the furthest right vector
+ cycled_vector = size - 1;
+ }
+ }
+
+ return combinations;
+}
+
+/*
+ * index 0 - playback dvr
+ * index 1 - audio filters
+ * index 2 - optional section filters
+ */
+static inline vector<DvrPlaybackHardwareConnections> generatePlaybackCombinations() {
+ vector<DvrPlaybackHardwareConnections> combinations;
+ vector<string> sectionFilterIds_optional = sectionFilterIds;
+ sectionFilterIds_optional.push_back(emptyHardwareId);
+ vector<vector<string>> deviceIds{playbackDvrIds, audioFilterIds, sectionFilterIds_optional};
+
+ const int dvrIndex = 0;
+ const int audioFilterIndex = 1;
+ const int sectionFilterIndex = 2;
+
+ auto idCombinations = generateIdCombinations(deviceIds);
+ for (auto& combo : idCombinations) {
+ DvrPlaybackHardwareConnections mPlayback;
+ mPlayback.dvrId = combo[dvrIndex];
+ mPlayback.audioFilterId = combo[audioFilterIndex];
+ mPlayback.sectionFilterId = combo[sectionFilterIndex];
+ const int videoFilterIndex =
+ find(audioFilterIds.begin(), audioFilterIds.end(), mPlayback.audioFilterId) -
+ audioFilterIds.begin();
+ mPlayback.videoFilterId = videoFilterIds[videoFilterIndex];
+ combinations.push_back(mPlayback);
+ }
+
+ return combinations;
+}
+
+static inline vector<DvrPlaybackHardwareConnections> generatePlaybackConfigs() {
+ vector<DvrPlaybackHardwareConnections> playback_configs;
+ if (configuredPlayback) {
+ ALOGD("Using DVR playback configuration provided.");
+ playback_configs = {playback};
+ } else {
+ ALOGD("Dvr playback not provided. Generating possible combinations. Consider adding it to "
+ "the configuration file.");
+ playback_configs = generatePlaybackCombinations();
+ }
+
+ return playback_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - audio filters
+ * index 2 - lnbs
+ */
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveCombinations() {
+ vector<LnbLiveHardwareConnections> combinations;
+ vector<vector<string>> deviceIds{frontendIds, audioFilterIds, lnbIds};
+
+ const int frontendIndex = 0;
+ const int audioFilterIndex = 1;
+ const int lnbIndex = 2;
+
+ // TODO: Find a better way to vary diseqcMsgs, if at all
+ auto idCombinations = generateIdCombinations(deviceIds);
+ for (auto& combo : idCombinations) {
+ const string feId = combo[frontendIndex];
+ auto type = frontendMap[feId].type;
+ if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+ type == FrontendType::ISDBS3) {
+ LnbLiveHardwareConnections mLnbLive;
+ mLnbLive.frontendId = feId;
+ mLnbLive.audioFilterId = combo[audioFilterIndex];
+ const int videoFilterIndex =
+ find(audioFilterIds.begin(), audioFilterIds.end(), mLnbLive.audioFilterId) -
+ audioFilterIds.begin();
+ mLnbLive.videoFilterId = videoFilterIds[videoFilterIndex];
+ mLnbLive.lnbId = combo[lnbIndex];
+ mLnbLive.diseqcMsgs = diseqcMsgs;
+ combinations.push_back(mLnbLive);
+ }
+ }
+
+ return combinations;
+}
+
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveConfigurations() {
+ vector<LnbLiveHardwareConnections> lnbLive_configs;
+ if (configuredLnbLive) {
+ ALOGD("Using LnbLive configuration provided.");
+ lnbLive_configs = {lnbLive};
+ } else {
+ ALOGD("LnbLive not provided. Generating possible combinations. Consider adding it to the "
+ "configuration file.");
+ lnbLive_configs = generateLnbLiveCombinations();
+ }
+
+ return lnbLive_configs;
+}
+
+static inline vector<ScanHardwareConnections> generateScanCombinations() {
+ vector<ScanHardwareConnections> combinations;
+
+ for (auto& id : frontendIds) {
+ ScanHardwareConnections mScan;
+ mScan.frontendId = id;
+ combinations.push_back(mScan);
+ }
+
+ return combinations;
+}
+
+static inline vector<ScanHardwareConnections> generateScanConfigurations() {
+ vector<ScanHardwareConnections> scan_configs;
+ if (configuredScan) {
+ ALOGD("Using scan configuration provided.");
+ scan_configs = {scan};
+ } else {
+ ALOGD("Scan not provided. Generating possible combinations. Consider adding it to "
+ "the configuration file.");
+ scan_configs = generateScanCombinations();
+ }
+
+ return scan_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - record filter
+ * index 2 - Record Dvr
+ * index 3 - Lnb
+ */
+static inline vector<LnbRecordHardwareConnections> generateLnbRecordCombinations() {
+ vector<LnbRecordHardwareConnections> combinations;
+ vector<vector<string>> deviceIds{frontendIds, recordFilterIds, recordDvrIds, lnbIds};
+
+ const int frontendIndex = 0;
+ const int recordFilterIndex = 1;
+ const int dvrIndex = 2;
+ const int lnbIndex = 3;
+
+ auto idCombinations = generateIdCombinations(deviceIds);
+ // TODO : Find a better way to vary diseqcMsgs, if at all
+ for (auto& combo : idCombinations) {
+ const string feId = combo[frontendIndex];
+ auto type = frontendMap[feId].type;
+ if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+ type == FrontendType::ISDBS3) {
+ LnbRecordHardwareConnections mLnbRecord;
+ mLnbRecord.frontendId = feId;
+ mLnbRecord.recordFilterId = combo[recordFilterIndex];
+ mLnbRecord.dvrRecordId = combo[dvrIndex];
+ mLnbRecord.lnbId = combo[lnbIndex];
+ mLnbRecord.diseqcMsgs = diseqcMsgs;
+ combinations.push_back(mLnbRecord);
+ }
+ }
+
+ return combinations;
+}
+
+static inline vector<LnbRecordHardwareConnections> generateLnbRecordConfigurations() {
+ vector<LnbRecordHardwareConnections> lnbRecord_configs;
+ if (configuredLnbRecord) {
+ ALOGD("Using LnbRecord configuration provided.");
+ lnbRecord_configs = {lnbRecord};
+ } else {
+ ALOGD("LnbRecord not provided. Generating possible combinations. Consider adding it to "
+ "the configuration file.");
+ lnbRecord_configs = generateLnbRecordCombinations();
+ }
+
+ return lnbRecord_configs;
+}
+
+/*
+ * index 0 - decramblers
+ * index 1 - frontends
+ * index 2 - audio filters
+ * index 3 - Dvr SW Fe Connections
+ * index 4 - DVR Source Connections
+ */
+static inline vector<DescramblingHardwareConnections> generateDescramblingCombinations() {
+ vector<DescramblingHardwareConnections> combinations;
+ vector<string> mfrontendIds = frontendIds;
+ vector<string> mDvrFeConnectionIds = playbackDvrIds;
+ vector<string> mDvrSourceConnectionIds = playbackDvrIds;
+
+ // Add the empty hardware id to each vector to include combinations where these 3 fields might
+ // be optional
+ mfrontendIds.push_back(emptyHardwareId);
+ mDvrFeConnectionIds.push_back(emptyHardwareId);
+ mDvrSourceConnectionIds.push_back(emptyHardwareId);
+
+ const int descramblerIndex = 0;
+ const int frontendIndex = 1;
+ const int audioFilterIndex = 2;
+ const int dvrFeIdIndex = 3;
+ const int dvrSourceIdIndex = 4;
+
+ vector<vector<string>> deviceIds{descramblerIds, mfrontendIds, audioFilterIds,
+ mDvrFeConnectionIds, mDvrSourceConnectionIds};
+ auto idCombinations = generateIdCombinations(deviceIds);
+ for (auto& combo : idCombinations) {
+ DescramblingHardwareConnections mDescrambling;
+ const string feId = combo[frontendIndex];
+ const string dvrSwFeId = combo[dvrFeIdIndex];
+ const string dvrSourceId = combo[dvrSourceIdIndex];
+ mDescrambling.hasFrontendConnection = feId.compare(emptyHardwareId) == 0 ? false : true;
+ if (!mDescrambling.hasFrontendConnection) {
+ if (dvrSourceId.compare(emptyHardwareId) == 0) {
+ // If combination does not have a frontend or dvr source connection, do not include
+ // it
+ continue;
+ }
+ } else {
+ if (frontendMap[feId].isSoftwareFe && dvrSwFeId.compare(emptyHardwareId) == 0) {
+ // If combination has a software frontend and no dvr->software frontend connection,
+ // do not include it
+ continue;
+ }
+ }
+ if (dvrSwFeId.compare(dvrSourceId) == 0) {
+ // If dvr->software frontend connection is the same as dvr source input to tuner, do not
+ // include it.
+ continue;
+ }
+ mDescrambling.frontendId = feId;
+ mDescrambling.audioFilterId = combo[audioFilterIndex];
+ const int videoFilterIndex =
+ find(audioFilterIds.begin(), audioFilterIds.end(), mDescrambling.audioFilterId) -
+ audioFilterIds.begin();
+ mDescrambling.videoFilterId = videoFilterIds[videoFilterIndex];
+ mDescrambling.dvrSoftwareFeId = dvrSwFeId;
+ mDescrambling.dvrSourceId = dvrSourceId;
+ mDescrambling.descramblerId = combo[descramblerIndex];
+ combinations.push_back(mDescrambling);
+ }
+
+ return combinations;
+}
+
+static inline vector<DescramblingHardwareConnections> generateDescramblingConfigurations() {
+ vector<DescramblingHardwareConnections> descrambling_configs;
+ if (configuredDescrambling) {
+ ALOGD("Using Descrambling configuration provided.");
+ descrambling_configs = {descrambling};
+ } else {
+ ALOGD("Descrambling not provided. Generating possible combinations. Consider adding it to "
+ "the "
+ "configuration file.");
+ descrambling_configs = generateDescramblingCombinations();
+ }
+
+ return descrambling_configs;
+}
+
+static inline vector<TimeFilterHardwareConnections> generateTimeFilterCombinations() {
+ vector<TimeFilterHardwareConnections> combinations;
+
+ for (auto& id : timeFilterIds) {
+ TimeFilterHardwareConnections mTimeFilter;
+ mTimeFilter.timeFilterId = id;
+ combinations.push_back(mTimeFilter);
+ }
+
+ return combinations;
+}
+
+static inline vector<TimeFilterHardwareConnections> generateTimeFilterConfigurations() {
+ vector<TimeFilterHardwareConnections> timeFilter_configs;
+ if (configuredTimeFilter) {
+ ALOGD("Using TimeFilter configuration provided.");
+ timeFilter_configs = {timeFilter};
+ } else {
+ ALOGD("TimeFilter not provided. Generating possible combinations. Consider adding it to "
+ "the "
+ "configuration file.");
+ timeFilter_configs = generateTimeFilterCombinations();
+ }
+
+ return timeFilter_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - record dvrs
+ * index 2 - record filters
+ */
+static inline vector<DvrRecordHardwareConnections> generateRecordCombinations() {
+ vector<DvrRecordHardwareConnections> combinations;
+
+ const int frontendIdIndex = 0;
+ const int recordDvrIndex = 1;
+ const int recordFilterIndex = 2;
+
+ vector<vector<string>> deviceIds{frontendIds, recordDvrIds, recordFilterIds};
+
+ auto idCombinations = generateIdCombinations(deviceIds);
+ for (auto& combo : idCombinations) {
+ DvrRecordHardwareConnections mRecord;
+ const string feId = combo[frontendIdIndex];
+ mRecord.hasFrontendConnection = true;
+ if (frontendMap[feId].isSoftwareFe) {
+ // If we have a software frontend, do not include configuration for testing.
+ continue;
+ }
+ mRecord.frontendId = feId;
+ mRecord.support = true;
+ mRecord.dvrSourceId = emptyHardwareId;
+ mRecord.dvrSoftwareFeId = emptyHardwareId;
+ mRecord.recordFilterId = combo[recordFilterIndex];
+ mRecord.dvrRecordId = combo[recordDvrIndex];
+ combinations.push_back(mRecord);
+ }
+
+ return combinations;
+}
+
+static inline vector<DvrRecordHardwareConnections> generateRecordConfigurations() {
+ vector<DvrRecordHardwareConnections> record_configs;
+ if (configuredRecord) {
+ ALOGD("Using Record configuration provided.");
+ record_configs = {record};
+ } else {
+ ALOGD("Record not provided. Generating possible combinations. Consider adding it to "
+ "the "
+ "configuration file.");
+ record_configs = generateRecordCombinations();
+ }
+
+ return record_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - audio filters
+ * index 2 - playback dvrs
+ * index 3 - section Filters
+ */
+static inline vector<LiveBroadcastHardwareConnections> generateLiveCombinations() {
+ vector<LiveBroadcastHardwareConnections> combinations;
+ vector<string> mSectionFilterIds = sectionFilterIds;
+ vector<string> mDvrSwConnectionIds = playbackDvrIds;
+
+ // Adding the empty hardware id to cover cases where fields are optional
+ mSectionFilterIds.push_back(emptyHardwareId);
+ mDvrSwConnectionIds.push_back(emptyHardwareId);
+
+ const int frontendIdIndex = 0;
+ const int audioFilterIdIndex = 1;
+ const int dvrSwConnectionIdIndex = 2;
+ const int sectionFilterIdIndex = 3;
+
+ vector<vector<string>> deviceIds{frontendIds, audioFilterIds, mDvrSwConnectionIds,
+ mSectionFilterIds};
+
+ auto idCombinations = generateIdCombinations(deviceIds);
+ for (auto& combo : idCombinations) {
+ LiveBroadcastHardwareConnections mLive;
+ const string feId = combo[frontendIdIndex];
+ const string dvrSwConnectionId = combo[dvrSwConnectionIdIndex];
+ mLive.hasFrontendConnection = true;
+
+ if (frontendMap[feId].isSoftwareFe && dvrSwConnectionId.compare(emptyHardwareId) == 0) {
+ // If the frontend is a software frontend and there is no dvr playback connected, do not
+ // include configuration
+ continue;
+ }
+ mLive.frontendId = feId;
+ mLive.dvrSoftwareFeId = dvrSwConnectionId;
+ mLive.audioFilterId = combo[audioFilterIdIndex];
+ const int videoFilterIdIndex =
+ find(audioFilterIds.begin(), audioFilterIds.end(), mLive.audioFilterId) -
+ audioFilterIds.begin();
+ mLive.videoFilterId = videoFilterIds[videoFilterIdIndex];
+ mLive.sectionFilterId = combo[sectionFilterIdIndex];
+
+ if (pcrFilterIds.empty()) {
+ // If pcr Filters have not been provided, set it to empty hardware id
+ mLive.pcrFilterId = emptyHardwareId;
+ } else {
+ // If pcr Filters have been provided, use the first index if there is only 1, or choose
+ // the filter that corresponds to the correct audio and video filter pair
+ const int pcrFilterIdIndex = pcrFilterIds.size() == 1 ? 0 : videoFilterIdIndex;
+ mLive.pcrFilterId = pcrFilterIds[pcrFilterIdIndex];
+ }
+
+ combinations.push_back(mLive);
+ }
+
+ return combinations;
+}
+
+static inline vector<LiveBroadcastHardwareConnections> generateLiveConfigurations() {
+ vector<LiveBroadcastHardwareConnections> live_configs;
+ if (configuredLive) {
+ ALOGD("Using Live configuration provided.");
+ live_configs = {live};
+ } else {
+ ALOGD("Live not provided. Generating possible combinations. Consider adding it to "
+ "the "
+ "configuration file.");
+ live_configs = generateLiveCombinations();
+ }
+
+ return live_configs;
+}
+
+static inline vector<LnbDescramblingHardwareConnections> generateLnbDescramblingCombinations() {
+ vector<LnbDescramblingHardwareConnections> combinations;
+ vector<vector<string>> deviceIds{frontendIds, audioFilterIds, lnbIds, descramblerIds};
+
+ const int frontendIdIndex = 0;
+ const int audioFilterIdIndex = 1;
+ const int lnbIdIndex = 2;
+ const int descramblerIdIndex = 3;
+
+ auto idCombinations = generateIdCombinations(deviceIds);
+ // TODO : Find a better way to vary diseqcMsgs, if at all
+ for (auto& combo : idCombinations) {
+ const string feId = combo[frontendIdIndex];
+ auto type = frontendMap[feId].type;
+ if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+ type == FrontendType::ISDBS3) {
+ LnbDescramblingHardwareConnections mLnbDescrambling;
+ mLnbDescrambling.support = true;
+ mLnbDescrambling.frontendId = feId;
+ mLnbDescrambling.audioFilterId = combo[audioFilterIdIndex];
+ const int videoFilterIdIndex = find(audioFilterIds.begin(), audioFilterIds.end(),
+ mLnbDescrambling.audioFilterId) -
+ audioFilterIds.begin();
+ mLnbDescrambling.videoFilterId = videoFilterIds[videoFilterIdIndex];
+ mLnbDescrambling.lnbId = combo[lnbIdIndex];
+ mLnbDescrambling.descramblerId = combo[descramblerIdIndex];
+ mLnbDescrambling.diseqcMsgs = diseqcMsgs;
+ combinations.push_back(mLnbDescrambling);
+ }
+ }
+
+ return combinations;
+}
+
+static inline vector<LnbDescramblingHardwareConnections> generateLnbDescramblingConfigurations() {
+ vector<LnbDescramblingHardwareConnections> lnbDescrambling_configs;
+ if (configuredLnbDescrambling) {
+ ALOGD("Using LnbDescrambling configuration provided");
+ lnbDescrambling_configs = {lnbDescrambling};
+ } else {
+ ALOGD("LnbDescrambling not provided. Generating possible combinations. Consider adding it "
+ "to the configuration file.");
+ lnbDescrambling_configs = generateLnbDescramblingCombinations();
+ }
+
+ return lnbDescrambling_configs;
+}
/** Config all the frontends that would be used in the tests */
inline void initFrontendConfig() {
@@ -162,13 +669,141 @@
TunerTestingConfigAidlReader1_0::readDvrConfig1_0(dvrMap);
};
+inline void initTimeFilterConfig() {
+ // Read customized config
+ TunerTestingConfigAidlReader1_0::readTimeFilterConfig1_0(timeFilterMap);
+};
+
+inline void initDescramblerConfig() {
+ // Read customized config
+ TunerTestingConfigAidlReader1_0::readDescramblerConfig1_0(descramblerMap);
+}
+
+inline void initLnbConfig() {
+ // Read customized config
+ TunerTestingConfigAidlReader1_0::readLnbConfig1_0(lnbMap);
+};
+
+inline void initDiseqcMsgsConfig() {
+ // Read customized config
+ TunerTestingConfigAidlReader1_0::readDiseqcMessages(diseqcMsgMap);
+};
+
+inline void determineScan() {
+ if (!frontendMap.empty()) {
+ scan.hasFrontendConnection = true;
+ ALOGD("Can support scan");
+ }
+}
+
+inline void determineTimeFilter() {
+ if (!timeFilterMap.empty()) {
+ timeFilter.support = true;
+ ALOGD("Can support time filter");
+ }
+}
+
+inline void determineDvrPlayback() {
+ if (!playbackDvrIds.empty() && !audioFilterIds.empty() && !videoFilterIds.empty()) {
+ playback.support = true;
+ ALOGD("Can support dvr playback");
+ }
+}
+
+inline void determineLnbLive() {
+ if (!audioFilterIds.empty() && !videoFilterIds.empty() && !frontendMap.empty() &&
+ !lnbMap.empty()) {
+ lnbLive.support = true;
+ ALOGD("Can support lnb live");
+ }
+}
+
+inline void determineLnbRecord() {
+ if (!frontendMap.empty() && !recordFilterIds.empty() && !recordDvrIds.empty() &&
+ !lnbMap.empty()) {
+ lnbRecord.support = true;
+ ALOGD("Can support lnb record");
+ }
+}
+
+inline void determineLive() {
+ if (videoFilterIds.empty() || audioFilterIds.empty() || frontendMap.empty()) {
+ return;
+ }
+ if (hasSwFe && !hasHwFe && dvrMap.empty()) {
+ ALOGD("Cannot configure Live. Only software frontends and no dvr connections");
+ return;
+ }
+ ALOGD("Can support live");
+ live.hasFrontendConnection = true;
+}
+
+inline void determineDescrambling() {
+ if (descramblerMap.empty() || audioFilterIds.empty() || videoFilterIds.empty()) {
+ return;
+ }
+ if (frontendMap.empty() && playbackDvrIds.empty()) {
+ ALOGD("Cannot configure descrambling. No frontends or playback dvr's");
+ return;
+ }
+ if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) {
+ ALOGD("cannot configure descrambling. Only SW frontends and no playback dvr's");
+ return;
+ }
+ ALOGD("Can support descrambling");
+ descrambling.support = true;
+}
+
+inline void determineDvrRecord() {
+ if (recordDvrIds.empty() || recordFilterIds.empty()) {
+ return;
+ }
+ if (frontendMap.empty() && playbackDvrIds.empty()) {
+ ALOGD("Cannot support dvr record. No frontends and no playback dvr's");
+ return;
+ }
+ if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) {
+ ALOGD("Cannot support dvr record. Only SW frontends and no playback dvr's");
+ return;
+ }
+ ALOGD("Can support dvr record.");
+ record.support = true;
+}
+
+inline void determineLnbDescrambling() {
+ if (frontendIds.empty() || audioFilterIds.empty() || videoFilterIds.empty() || lnbIds.empty() ||
+ descramblerIds.empty()) {
+ return;
+ }
+ ALOGD("Can support LnbDescrambling.");
+ lnbDescrambling.support = true;
+}
+
/** Read the vendor configurations of which hardware to use for each test cases/data flows */
inline void connectHardwaresToTestCases() {
TunerTestingConfigAidlReader1_0::connectLiveBroadcast(live);
TunerTestingConfigAidlReader1_0::connectScan(scan);
TunerTestingConfigAidlReader1_0::connectDvrRecord(record);
+ TunerTestingConfigAidlReader1_0::connectTimeFilter(timeFilter);
+ TunerTestingConfigAidlReader1_0::connectDescrambling(descrambling);
+ TunerTestingConfigAidlReader1_0::connectLnbLive(lnbLive);
+ TunerTestingConfigAidlReader1_0::connectLnbRecord(lnbRecord);
+ TunerTestingConfigAidlReader1_0::connectDvrPlayback(playback);
+ TunerTestingConfigAidlReader1_0::connectLnbDescrambling(lnbDescrambling);
};
+inline void determineDataFlows() {
+ determineScan();
+ determineTimeFilter();
+ determineDvrPlayback();
+ determineLnbLive();
+ determineLnbRecord();
+ determineLive();
+ determineDescrambling();
+ determineDvrRecord();
+ determineLnbDescrambling();
+}
+
inline bool validateConnections() {
if (record.support && !record.hasFrontendConnection &&
record.dvrSourceId.compare(emptyHardwareId) == 0) {
@@ -183,6 +818,18 @@
feIsValid &= record.support && record.hasFrontendConnection
? frontendMap.find(record.frontendId) != frontendMap.end()
: true;
+ feIsValid &= descrambling.support && descrambling.hasFrontendConnection
+ ? frontendMap.find(descrambling.frontendId) != frontendMap.end()
+ : true;
+
+ feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true;
+
+ feIsValid &=
+ lnbRecord.support ? frontendMap.find(lnbRecord.frontendId) != frontendMap.end() : true;
+
+ feIsValid &= lnbDescrambling.support
+ ? frontendMap.find(lnbDescrambling.frontendId) != frontendMap.end()
+ : true;
if (!feIsValid) {
ALOGW("[vts config] dynamic config fe connection is invalid.");
@@ -204,6 +851,20 @@
dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end();
}
+ if (descrambling.support) {
+ if (descrambling.hasFrontendConnection) {
+ if (frontendMap[descrambling.frontendId].isSoftwareFe) {
+ dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end();
+ }
+ } else {
+ dvrIsValid &= dvrMap.find(descrambling.dvrSourceId) != dvrMap.end();
+ }
+ }
+
+ dvrIsValid &= lnbRecord.support ? dvrMap.find(lnbRecord.dvrRecordId) != dvrMap.end() : true;
+
+ dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true;
+
if (!dvrIsValid) {
ALOGW("[vts config] dynamic config dvr connection is invalid.");
return false;
@@ -216,10 +877,120 @@
filterIsValid &=
record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true;
+ filterIsValid &= descrambling.support
+ ? filterMap.find(descrambling.videoFilterId) != filterMap.end() &&
+ filterMap.find(descrambling.audioFilterId) != filterMap.end()
+ : true;
+
+ for (auto& filterId : descrambling.extraFilters) {
+ filterIsValid &= filterMap.find(filterId) != filterMap.end();
+ }
+
+ filterIsValid &= lnbLive.support
+ ? filterMap.find(lnbLive.audioFilterId) != filterMap.end() &&
+ filterMap.find(lnbLive.videoFilterId) != filterMap.end()
+ : true;
+
+ filterIsValid &=
+ lnbRecord.support ? filterMap.find(lnbRecord.recordFilterId) != filterMap.end() : true;
+
+ for (auto& filterId : lnbRecord.extraFilters) {
+ filterIsValid &= filterMap.find(filterId) != filterMap.end();
+ }
+
+ for (auto& filterId : lnbLive.extraFilters) {
+ filterIsValid &= filterMap.find(filterId) != filterMap.end();
+ }
+
+ filterIsValid &= playback.support
+ ? filterMap.find(playback.audioFilterId) != filterMap.end() &&
+ filterMap.find(playback.videoFilterId) != filterMap.end()
+ : true;
+ filterIsValid &= playback.sectionFilterId.compare(emptyHardwareId) == 0
+ ? true
+ : filterMap.find(playback.sectionFilterId) != filterMap.end();
+
+ for (auto& filterId : playback.extraFilters) {
+ filterIsValid &=
+ playback.hasExtraFilters ? filterMap.find(filterId) != filterMap.end() : true;
+ }
+
+ filterIsValid &=
+ lnbDescrambling.support
+ ? filterMap.find(lnbDescrambling.audioFilterId) != filterMap.end() &&
+ filterMap.find(lnbDescrambling.videoFilterId) != filterMap.end()
+ : true;
+
if (!filterIsValid) {
ALOGW("[vts config] dynamic config filter connection is invalid.");
return false;
}
+ if (audioFilterIds.size() != videoFilterIds.size()) {
+ ALOGW("[vts config] the number of audio and video filters should be equal");
+ return false;
+ }
+
+ if (!pcrFilterIds.empty() && pcrFilterIds.size() != 1 &&
+ pcrFilterIds.size() != audioFilterIds.size()) {
+ ALOGW("[vts config] When more than 1 pcr filter is configured, the number of pcr filters "
+ "must equal the number of audio and video filters.");
+ return false;
+ }
+
+ bool timeFilterIsValid =
+ timeFilter.support ? timeFilterMap.find(timeFilter.timeFilterId) != timeFilterMap.end()
+ : true;
+
+ if (!timeFilterIsValid) {
+ ALOGW("[vts config] dynamic config time filter connection is invalid.");
+ }
+
+ bool descramblerIsValid =
+ descrambling.support
+ ? descramblerMap.find(descrambling.descramblerId) != descramblerMap.end()
+ : true;
+
+ descramblerIsValid &=
+ lnbDescrambling.support
+ ? descramblerMap.find(lnbDescrambling.descramblerId) != descramblerMap.end()
+ : true;
+
+ if (!descramblerIsValid) {
+ ALOGW("[vts config] dynamic config descrambler connection is invalid.");
+ return false;
+ }
+
+ bool lnbIsValid = lnbLive.support ? lnbMap.find(lnbLive.lnbId) != lnbMap.end() : true;
+
+ lnbIsValid &= lnbRecord.support ? lnbMap.find(lnbRecord.lnbId) != lnbMap.end() : true;
+
+ lnbIsValid &=
+ lnbDescrambling.support ? lnbMap.find(lnbDescrambling.lnbId) != lnbMap.end() : true;
+
+ if (!lnbIsValid) {
+ ALOGW("[vts config] dynamic config lnb connection is invalid.");
+ return false;
+ }
+
+ bool diseqcMsgsIsValid = true;
+
+ for (auto& msg : lnbRecord.diseqcMsgs) {
+ diseqcMsgsIsValid &= diseqcMsgMap.find(msg) != diseqcMsgMap.end();
+ }
+
+ for (auto& msg : lnbLive.diseqcMsgs) {
+ diseqcMsgsIsValid &= diseqcMsgMap.find(msg) != diseqcMsgMap.end();
+ }
+
+ for (auto& msg : lnbDescrambling.diseqcMsgs) {
+ diseqcMsgsIsValid &= diseqcMsgMap.find(msg) != diseqcMsgMap.end();
+ }
+
+ if (!diseqcMsgsIsValid) {
+ ALOGW("[vts config] dynamic config diseqcMsg is invalid.");
+ return false;
+ }
+
return true;
}
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 189f5fd..9517520 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -62,10 +62,37 @@
using namespace aidl::android::hardware::tv::tuner;
using namespace android::media::tuner::testing::configuration::V1_0;
+static bool hasHwFe = false;
+static bool hasSwFe = false;
+static bool configFileRead = false;
+static bool configuredLive = false;
+static bool configuredScan = false;
+static bool configuredRecord = false;
+static bool configuredLnbLive = false;
+static bool configuredPlayback = false;
+static bool configuredLnbRecord = false;
+static bool configuredTimeFilter = false;
+static bool configuredDescrambling = false;
+static bool configuredLnbDescrambling = false;
+
const string emptyHardwareId = "";
static string mConfigFilePath;
+static vector<string> playbackDvrIds;
+static vector<string> ipFilterIds;
+static vector<string> recordDvrIds;
+static vector<string> pcrFilterIds;
+static vector<string> timeFilterIds;
+static vector<string> audioFilterIds;
+static vector<string> videoFilterIds;
+static vector<string> recordFilterIds;
+static vector<string> sectionFilterIds;
+static vector<string> frontendIds;
+static vector<string> lnbIds;
+static vector<string> diseqcMsgs;
+static vector<string> descramblerIds;
+
#define PROVISION_STR \
"{ " \
" \"id\": 21140844, " \
@@ -137,6 +164,7 @@
string ipFilterId;
string pcrFilterId;
/* list string of extra filters; */
+ vector<string> extraFilters;
};
struct ScanHardwareConnections {
@@ -146,12 +174,13 @@
struct DvrPlaybackHardwareConnections {
bool support;
+ bool hasExtraFilters = false;
string frontendId;
string dvrId;
string audioFilterId;
string videoFilterId;
string sectionFilterId;
- /* list string of extra filters; */
+ vector<string> extraFilters;
};
struct DvrRecordHardwareConnections {
@@ -173,7 +202,7 @@
string videoFilterId;
string descramblerId;
string dvrSourceId;
- /* list string of extra filters; */
+ vector<string> extraFilters;
};
struct LnbLiveHardwareConnections {
@@ -183,7 +212,7 @@
string videoFilterId;
string lnbId;
vector<string> diseqcMsgs;
- /* list string of extra filters; */
+ vector<string> extraFilters;
};
struct LnbRecordHardwareConnections {
@@ -193,7 +222,7 @@
string recordFilterId;
string lnbId;
vector<string> diseqcMsgs;
- /* list string of extra filters; */
+ vector<string> extraFilters;
};
struct TimeFilterHardwareConnections {
@@ -201,6 +230,16 @@
string timeFilterId;
};
+struct LnbDescramblingHardwareConnections {
+ bool support;
+ string frontendId;
+ string audioFilterId;
+ string videoFilterId;
+ string lnbId;
+ string descramblerId;
+ vector<string> diseqcMsgs;
+};
+
struct TunerTestingConfigAidlReader1_0 {
public:
static void setConfigFilePath(string path) { mConfigFilePath = path; }
@@ -248,6 +287,7 @@
auto frontends = *hardwareConfig.getFirstFrontends();
for (auto feConfig : frontends.getFrontend()) {
string id = feConfig.getId();
+ frontendIds.push_back(id);
if (id.compare(string("FE_DEFAULT")) == 0) {
// overrid default
frontendMap.erase(string("FE_DEFAULT"));
@@ -263,6 +303,9 @@
break;
case FrontendTypeEnum::ATSC:
type = FrontendType::ATSC;
+ frontendMap[id].settings.set<
+ FrontendSettings::Tag::atsc>(
+ readAtscFrontendSettings(feConfig));
break;
case FrontendTypeEnum::ATSC3:
type = FrontendType::ATSC3;
@@ -283,12 +326,16 @@
}
case FrontendTypeEnum::ISDBS:
type = FrontendType::ISDBS;
+ frontendMap[id].settings.set<FrontendSettings::Tag::isdbs>(
+ readIsdbsFrontendSettings(feConfig));
break;
case FrontendTypeEnum::ISDBS3:
type = FrontendType::ISDBS3;
break;
case FrontendTypeEnum::ISDBT:
type = FrontendType::ISDBT;
+ frontendMap[id].settings.set<FrontendSettings::Tag::isdbt>(
+ readIsdbtFrontendSettings(feConfig));
break;
case FrontendTypeEnum::DTMB:
type = FrontendType::DTMB;
@@ -302,6 +349,11 @@
}
frontendMap[id].type = type;
frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend();
+ if (frontendMap[id].isSoftwareFe) {
+ hasSwFe = true;
+ } else {
+ hasHwFe = true;
+ }
// TODO: b/182519645 complete the tune status config
frontendMap[id].tuneStatusTypes = types;
frontendMap[id].expectTuneStatuses = statuses;
@@ -376,11 +428,13 @@
DvrType type;
switch (dvrConfig.getType()) {
case DvrTypeEnum::PLAYBACK:
+ playbackDvrIds.push_back(id);
type = DvrType::PLAYBACK;
dvrMap[id].settings.set<DvrSettings::Tag::playback>(
readPlaybackSettings(dvrConfig));
break;
case DvrTypeEnum::RECORD:
+ recordDvrIds.push_back(id);
type = DvrType::RECORD;
dvrMap[id].settings.set<DvrSettings::Tag::record>(
readRecordSettings(dvrConfig));
@@ -404,6 +458,7 @@
auto lnbs = *hardwareConfig.getFirstLnbs();
for (auto lnbConfig : lnbs.getLnb()) {
string id = lnbConfig.getId();
+ lnbIds.push_back(id);
if (lnbConfig.hasName()) {
lnbMap[id].name = lnbConfig.getName();
} else {
@@ -422,6 +477,7 @@
auto descramblers = *hardwareConfig.getFirstDescramblers();
for (auto descramblerConfig : descramblers.getDescrambler()) {
string id = descramblerConfig.getId();
+ descramblerIds.push_back(id);
descramblerMap[id].casSystemId =
static_cast<int32_t>(descramblerConfig.getCasSystemId());
if (descramblerConfig.hasProvisionStr()) {
@@ -447,6 +503,7 @@
auto msgs = *hardwareConfig.getFirstDiseqcMessages();
for (auto msgConfig : msgs.getDiseqcMessage()) {
string name = msgConfig.getMsgName();
+ diseqcMsgs.push_back(name);
for (uint8_t atom : msgConfig.getMsgBody()) {
diseqcMsgMap[name].push_back(atom);
}
@@ -460,6 +517,7 @@
auto timeFilters = *hardwareConfig.getFirstTimeFilters();
for (auto timeFilterConfig : timeFilters.getTimeFilter()) {
string id = timeFilterConfig.getId();
+ timeFilterIds.push_back(id);
timeFilterMap[id].timeStamp = static_cast<int64_t>(timeFilterConfig.getTimeStamp());
}
}
@@ -469,6 +527,7 @@
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasClearLiveBroadcast()) {
live.hasFrontendConnection = true;
+ configuredLive = true;
} else {
live.hasFrontendConnection = false;
return;
@@ -496,12 +555,17 @@
} else {
live.ipFilterId = emptyHardwareId;
}
+ if (liveConfig.hasOptionalFilters()) {
+ auto optionalFilters = liveConfig.getOptionalFilters();
+ live.extraFilters = optionalFilters;
+ }
}
static void connectScan(ScanHardwareConnections& scan) {
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasScan()) {
scan.hasFrontendConnection = true;
+ configuredScan = true;
} else {
scan.hasFrontendConnection = false;
return;
@@ -514,6 +578,7 @@
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasDvrPlayback()) {
playback.support = true;
+ configuredPlayback = true;
} else {
playback.support = false;
return;
@@ -527,12 +592,17 @@
} else {
playback.sectionFilterId = emptyHardwareId;
}
+ if (playbackConfig.hasOptionalFilters()) {
+ auto optionalFilters = playbackConfig.getOptionalFilters();
+ playback.extraFilters = optionalFilters;
+ }
}
static void connectDvrRecord(DvrRecordHardwareConnections& record) {
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasDvrRecord()) {
record.support = true;
+ configuredRecord = true;
} else {
record.support = false;
return;
@@ -557,6 +627,7 @@
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasDescrambling()) {
descrambling.support = true;
+ configuredDescrambling = true;
} else {
descrambling.support = false;
return;
@@ -576,12 +647,17 @@
descrambling.hasFrontendConnection = false;
descrambling.dvrSourceId = descConfig.getDvrSourceConnection();
}
+ if (descConfig.hasOptionalFilters()) {
+ auto optionalFilters = descConfig.getOptionalFilters();
+ descrambling.extraFilters = optionalFilters;
+ }
}
static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) {
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasLnbLive()) {
lnbLive.support = true;
+ configuredLnbLive = true;
} else {
lnbLive.support = false;
return;
@@ -596,12 +672,17 @@
lnbLive.diseqcMsgs.push_back(msgName);
}
}
+ if (lnbLiveConfig.hasOptionalFilters()) {
+ auto optionalFilters = lnbLiveConfig.getOptionalFilters();
+ lnbLive.extraFilters = optionalFilters;
+ }
}
static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) {
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasLnbRecord()) {
lnbRecord.support = true;
+ configuredLnbRecord = true;
} else {
lnbRecord.support = false;
return;
@@ -616,12 +697,17 @@
lnbRecord.diseqcMsgs.push_back(msgName);
}
}
+ if (lnbRecordConfig.hasOptionalFilters()) {
+ auto optionalFilters = lnbRecordConfig.getOptionalFilters();
+ lnbRecord.extraFilters = optionalFilters;
+ }
}
static void connectTimeFilter(TimeFilterHardwareConnections& timeFilter) {
auto dataFlow = getDataFlowConfiguration();
if (dataFlow.hasTimeFilter()) {
timeFilter.support = true;
+ configuredTimeFilter = true;
} else {
timeFilter.support = false;
return;
@@ -630,6 +716,28 @@
timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection();
}
+ static void connectLnbDescrambling(LnbDescramblingHardwareConnections& lnbDescrambling) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasLnbDescrambling()) {
+ lnbDescrambling.support = true;
+ configuredLnbDescrambling = true;
+ } else {
+ lnbDescrambling.support = false;
+ return;
+ }
+ auto lnbDescramblingConfig = *dataFlow.getFirstLnbDescrambling();
+ lnbDescrambling.frontendId = lnbDescramblingConfig.getFrontendConnection();
+ lnbDescrambling.audioFilterId = lnbDescramblingConfig.getAudioFilterConnection();
+ lnbDescrambling.videoFilterId = lnbDescramblingConfig.getVideoFilterConnection();
+ lnbDescrambling.lnbId = lnbDescramblingConfig.getLnbConnection();
+ lnbDescrambling.descramblerId = lnbDescramblingConfig.getDescramblerConnection();
+ if (lnbDescramblingConfig.hasDiseqcMsgSender()) {
+ for (auto& msgName : lnbDescramblingConfig.getDiseqcMsgSender()) {
+ lnbDescrambling.diseqcMsgs.push_back(msgName);
+ }
+ }
+ }
+
private:
static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
ALOGW("[ConfigReader] fe type is dvbt");
@@ -677,25 +785,115 @@
ALOGW("[ConfigReader] no more dvbs settings");
return dvbsSettings;
}
- dvbsSettings.symbolRate = static_cast<int32_t>(
- feConfig.getFirstDvbsFrontendSettings_optional()->getSymbolRate());
- dvbsSettings.inputStreamId = static_cast<int32_t>(
- feConfig.getFirstDvbsFrontendSettings_optional()->getInputStreamId());
auto dvbs = feConfig.getFirstDvbsFrontendSettings_optional();
- if (dvbs->hasScanType()) {
- dvbsSettings.scanType = static_cast<FrontendDvbsScanType>(dvbs->getScanType());
- }
- if (dvbs->hasIsDiseqcRxMessage()) {
- dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage();
- }
+ dvbsSettings.symbolRate = static_cast<int32_t>(dvbs->getSymbolRate());
+ dvbsSettings.inputStreamId = static_cast<int32_t>(dvbs->getInputStreamId());
+ dvbsSettings.scanType = static_cast<FrontendDvbsScanType>(dvbs->getScanType());
+ dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage();
+ dvbsSettings.inversion = static_cast<FrontendSpectralInversion>(dvbs->getInversion());
+ dvbsSettings.modulation = static_cast<FrontendDvbsModulation>(dvbs->getModulation());
+ dvbsSettings.rolloff = static_cast<FrontendDvbsRolloff>(dvbs->getRolloff());
+ dvbsSettings.pilot = static_cast<FrontendDvbsPilot>(dvbs->getPilot());
+ dvbsSettings.standard = static_cast<FrontendDvbsStandard>(dvbs->getStandard());
+ dvbsSettings.vcmMode = static_cast<FrontendDvbsVcmMode>(dvbs->getVcmMode());
return dvbsSettings;
}
+ static FrontendAtscSettings readAtscFrontendSettings(Frontend& feConfig) {
+ ALOGW("[ConfigReader] fe type is atsc");
+ FrontendAtscSettings atscSettings{
+ .frequency = (int64_t)feConfig.getFrequency(),
+ };
+ if (feConfig.hasEndFrequency()) {
+ atscSettings.endFrequency = (int64_t)feConfig.getEndFrequency();
+ }
+ if (!feConfig.hasAtscFrontendSettings_optional()) {
+ ALOGW("[ConfigReader] no more atsc settings");
+ return atscSettings;
+ }
+ auto atsc = feConfig.getFirstAtscFrontendSettings_optional();
+ atscSettings.inversion = static_cast<FrontendSpectralInversion>(atsc->getInversion());
+ atscSettings.modulation = static_cast<FrontendAtscModulation>(atsc->getModulation());
+ return atscSettings;
+ }
+
+ static FrontendIsdbsSettings readIsdbsFrontendSettings(Frontend& feConfig) {
+ ALOGW("[ConfigReader] fe type is isdbs");
+ FrontendIsdbsSettings isdbsSettings{.frequency = (int64_t)feConfig.getFrequency()};
+ if (feConfig.hasEndFrequency()) {
+ isdbsSettings.endFrequency = (int64_t)feConfig.getEndFrequency();
+ }
+ if (!feConfig.hasIsdbsFrontendSettings_optional()) {
+ ALOGW("[ConfigReader] no more isdbs settings");
+ return isdbsSettings;
+ }
+ auto isdbs = feConfig.getFirstIsdbsFrontendSettings_optional();
+ isdbsSettings.streamId = (int32_t)isdbs->getStreamId();
+ isdbsSettings.symbolRate = (int32_t)isdbs->getSymbolRate();
+ isdbsSettings.modulation = static_cast<FrontendIsdbsModulation>(isdbs->getModulation());
+ isdbsSettings.coderate = static_cast<FrontendIsdbsCoderate>(isdbs->getCoderate());
+ isdbsSettings.rolloff = static_cast<FrontendIsdbsRolloff>(isdbs->getRolloff());
+ isdbsSettings.streamIdType =
+ static_cast<FrontendIsdbsStreamIdType>(isdbs->getStreamIdType());
+ return isdbsSettings;
+ }
+
+ static FrontendIsdbtSettings readIsdbtFrontendSettings(Frontend& feConfig) {
+ ALOGW("[ConfigReader] fe type is isdbt");
+ FrontendIsdbtSettings isdbtSettings{
+ .frequency = (int64_t)feConfig.getFrequency(),
+ };
+ if (feConfig.hasEndFrequency()) {
+ isdbtSettings.endFrequency = (int64_t)feConfig.getEndFrequency();
+ }
+ if (!feConfig.hasIsdbtFrontendSettings_optional()) {
+ ALOGW("[ConfigReader] no more isdbt settings");
+ return isdbtSettings;
+ }
+ auto isdbt = feConfig.getFirstIsdbtFrontendSettings_optional();
+ isdbtSettings.inversion = static_cast<FrontendSpectralInversion>(isdbt->getInversion());
+ isdbtSettings.bandwidth = static_cast<FrontendIsdbtBandwidth>(isdbt->getBandwidth());
+ isdbtSettings.mode = static_cast<FrontendIsdbtMode>(isdbt->getMode());
+ isdbtSettings.guardInterval =
+ static_cast<FrontendIsdbtGuardInterval>(isdbt->getGuardInterval());
+ isdbtSettings.serviceAreaId = (int32_t)isdbt->getServiceAreaId();
+ isdbtSettings.partialReceptionFlag =
+ static_cast<FrontendIsdbtPartialReceptionFlag>(isdbt->getPartialReceptionFlag());
+ if (!isdbt->hasFrontendIsdbtLayerSettings()) {
+ ALOGW("[ConfigReader] no isdbt layer settings");
+ return isdbtSettings;
+ }
+ auto layerSettings = isdbt->getFirstFrontendIsdbtLayerSettings();
+ ::aidl::android::hardware::tv::tuner::FrontendIsdbtLayerSettings mLayerSettings;
+ mLayerSettings.modulation =
+ static_cast<FrontendIsdbtModulation>(layerSettings->getModulation());
+ mLayerSettings.coderate = static_cast<FrontendIsdbtCoderate>(layerSettings->getCoderate());
+ mLayerSettings.timeInterleave =
+ static_cast<FrontendIsdbtTimeInterleaveMode>(layerSettings->getTimeInterleave());
+ mLayerSettings.numOfSegment = (int32_t)layerSettings->getNumOfSegment();
+ isdbtSettings.layerSettings.push_back(mLayerSettings);
+ return isdbtSettings;
+ }
+
static bool readFilterTypeAndSettings(Filter filterConfig, DemuxFilterType& type,
DemuxFilterSettings& settings) {
auto mainType = filterConfig.getMainType();
auto subType = filterConfig.getSubType();
+ if (subType == FilterSubTypeEnum::AUDIO) {
+ audioFilterIds.push_back(filterConfig.getId());
+ } else if (subType == FilterSubTypeEnum::VIDEO) {
+ videoFilterIds.push_back(filterConfig.getId());
+ } else if (subType == FilterSubTypeEnum::RECORD) {
+ recordFilterIds.push_back(filterConfig.getId());
+ } else if (subType == FilterSubTypeEnum::SECTION) {
+ sectionFilterIds.push_back(filterConfig.getId());
+ } else if (subType == FilterSubTypeEnum::PCR) {
+ pcrFilterIds.push_back(filterConfig.getId());
+ } else if (subType == FilterSubTypeEnum::IP) {
+ ipFilterIds.push_back(filterConfig.getId());
+ }
+
switch (mainType) {
case FilterMainTypeEnum::TS: {
ALOGW("[ConfigReader] filter main type is ts");
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 383d49f..dbd3486 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -1,6 +1,14 @@
// Signature format: 2.0
package android.media.tuner.testing.configuration.V1_0 {
+ public class AtscFrontendSettings {
+ ctor public AtscFrontendSettings();
+ method @Nullable public java.math.BigInteger getInversion();
+ method @Nullable public java.math.BigInteger getModulation();
+ method public void setInversion(@Nullable java.math.BigInteger);
+ method public void setModulation(@Nullable java.math.BigInteger);
+ }
+
public class AvFilterSettings {
ctor public AvFilterSettings();
method @Nullable public short getAudioStreamType_optional();
@@ -19,6 +27,7 @@
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling getDescrambling();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback getDvrPlayback();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord getDvrRecord();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbDescrambling getLnbDescrambling();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive getLnbLive();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord getLnbRecord();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan getScan();
@@ -27,6 +36,7 @@
method public void setDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling);
method public void setDvrPlayback(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback);
method public void setDvrRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord);
+ method public void setLnbDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbDescrambling);
method public void setLnbLive(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive);
method public void setLnbRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord);
method public void setScan(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan);
@@ -39,6 +49,7 @@
method @Nullable public String getDvrSoftwareFeConnection();
method @Nullable public String getFrontendConnection();
method @Nullable public String getIpFilterConnection();
+ method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
method @Nullable public String getPcrFilterConnection();
method @Nullable public String getSectionFilterConnection();
method @Nullable public String getVideoFilterConnection();
@@ -46,6 +57,7 @@
method public void setDvrSoftwareFeConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
method public void setIpFilterConnection(@Nullable String);
+ method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
method public void setPcrFilterConnection(@Nullable String);
method public void setSectionFilterConnection(@Nullable String);
method public void setVideoFilterConnection(@Nullable String);
@@ -59,6 +71,7 @@
method @Nullable public String getDvrSourceConnection();
method @Nullable public String getFrontendConnection();
method @Nullable public boolean getHasFrontendConnection();
+ method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
method @Nullable public String getVideoFilterConnection();
method public void setAudioFilterConnection(@Nullable String);
method public void setDescramblerConnection(@Nullable String);
@@ -66,6 +79,7 @@
method public void setDvrSourceConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
method public void setHasFrontendConnection(@Nullable boolean);
+ method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
method public void setVideoFilterConnection(@Nullable String);
}
@@ -73,10 +87,12 @@
ctor public DataFlowConfiguration.DvrPlayback();
method @Nullable public String getAudioFilterConnection();
method @Nullable public String getDvrConnection();
+ method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
method @Nullable public String getSectionFilterConnection();
method @Nullable public String getVideoFilterConnection();
method public void setAudioFilterConnection(@Nullable String);
method public void setDvrConnection(@Nullable String);
+ method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
method public void setSectionFilterConnection(@Nullable String);
method public void setVideoFilterConnection(@Nullable String);
}
@@ -97,17 +113,35 @@
method public void setRecordFilterConnection(@Nullable String);
}
+ public static class DataFlowConfiguration.LnbDescrambling {
+ ctor public DataFlowConfiguration.LnbDescrambling();
+ method @Nullable public String getAudioFilterConnection();
+ method @Nullable public String getDescramblerConnection();
+ method @Nullable public java.util.List<java.lang.String> getDiseqcMsgSender();
+ method @Nullable public String getFrontendConnection();
+ method @Nullable public String getLnbConnection();
+ method @Nullable public String getVideoFilterConnection();
+ method public void setAudioFilterConnection(@Nullable String);
+ method public void setDescramblerConnection(@Nullable String);
+ method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
+ method public void setFrontendConnection(@Nullable String);
+ method public void setLnbConnection(@Nullable String);
+ method public void setVideoFilterConnection(@Nullable String);
+ }
+
public static class DataFlowConfiguration.LnbLive {
ctor public DataFlowConfiguration.LnbLive();
method @Nullable public String getAudioFilterConnection();
method @Nullable public java.util.List<java.lang.String> getDiseqcMsgSender();
method @Nullable public String getFrontendConnection();
method @Nullable public String getLnbConnection();
+ method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
method @Nullable public String getVideoFilterConnection();
method public void setAudioFilterConnection(@Nullable String);
method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
method public void setFrontendConnection(@Nullable String);
method public void setLnbConnection(@Nullable String);
+ method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
method public void setVideoFilterConnection(@Nullable String);
}
@@ -117,11 +151,13 @@
method @Nullable public String getDvrRecordConnection();
method @Nullable public String getFrontendConnection();
method @Nullable public String getLnbConnection();
+ method @Nullable public java.util.List<java.lang.String> getOptionalFilters();
method @Nullable public String getRecordFilterConnection();
method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
method public void setDvrRecordConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
method public void setLnbConnection(@Nullable String);
+ method public void setOptionalFilters(@Nullable java.util.List<java.lang.String>);
method public void setRecordFilterConnection(@Nullable String);
}
@@ -160,13 +196,25 @@
public class DvbsFrontendSettings {
ctor public DvbsFrontendSettings();
method @Nullable public java.math.BigInteger getInputStreamId();
+ method @Nullable public java.math.BigInteger getInversion();
method @Nullable public boolean getIsDiseqcRxMessage();
+ method @Nullable public java.math.BigInteger getModulation();
+ method @Nullable public java.math.BigInteger getPilot();
+ method @Nullable public java.math.BigInteger getRolloff();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsScanType getScanType();
+ method @Nullable public java.math.BigInteger getStandard();
method @Nullable public java.math.BigInteger getSymbolRate();
+ method @Nullable public java.math.BigInteger getVcmMode();
method public void setInputStreamId(@Nullable java.math.BigInteger);
+ method public void setInversion(@Nullable java.math.BigInteger);
method public void setIsDiseqcRxMessage(@Nullable boolean);
+ method public void setModulation(@Nullable java.math.BigInteger);
+ method public void setPilot(@Nullable java.math.BigInteger);
+ method public void setRolloff(@Nullable java.math.BigInteger);
method public void setScanType(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsScanType);
+ method public void setStandard(@Nullable java.math.BigInteger);
method public void setSymbolRate(@Nullable java.math.BigInteger);
+ method public void setVcmMode(@Nullable java.math.BigInteger);
}
public enum DvbsScanType {
@@ -310,6 +358,7 @@
public class Frontend {
ctor public Frontend();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.AtscFrontendSettings getAtscFrontendSettings_optional();
method @Nullable public java.math.BigInteger getConnectToCicamId();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings getDvbsFrontendSettings_optional();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings getDvbtFrontendSettings_optional();
@@ -317,8 +366,11 @@
method @Nullable public java.math.BigInteger getFrequency();
method @Nullable public String getId();
method @Nullable public boolean getIsSoftwareFrontend();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings getIsdbsFrontendSettings_optional();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings getIsdbtFrontendSettings_optional();
method @Nullable public java.math.BigInteger getRemoveOutputPid();
method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum getType();
+ method public void setAtscFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AtscFrontendSettings);
method public void setConnectToCicamId(@Nullable java.math.BigInteger);
method public void setDvbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings);
method public void setDvbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings);
@@ -326,10 +378,24 @@
method public void setFrequency(@Nullable java.math.BigInteger);
method public void setId(@Nullable String);
method public void setIsSoftwareFrontend(@Nullable boolean);
+ method public void setIsdbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings);
+ method public void setIsdbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings);
method public void setRemoveOutputPid(@Nullable java.math.BigInteger);
method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum);
}
+ public class FrontendIsdbtLayerSettings {
+ ctor public FrontendIsdbtLayerSettings();
+ method @Nullable public java.math.BigInteger getCoderate();
+ method @Nullable public java.math.BigInteger getModulation();
+ method @Nullable public java.math.BigInteger getNumOfSegment();
+ method @Nullable public java.math.BigInteger getTimeInterleave();
+ method public void setCoderate(@Nullable java.math.BigInteger);
+ method public void setModulation(@Nullable java.math.BigInteger);
+ method public void setNumOfSegment(@Nullable java.math.BigInteger);
+ method public void setTimeInterleave(@Nullable java.math.BigInteger);
+ }
+
public enum FrontendTypeEnum {
method @NonNull public String getRawName();
enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ANALOG;
@@ -422,6 +488,40 @@
method public void setSrcPort(@Nullable long);
}
+ public class IsdbsFrontendSettings {
+ ctor public IsdbsFrontendSettings();
+ method @Nullable public java.math.BigInteger getCoderate();
+ method @Nullable public java.math.BigInteger getModulation();
+ method @Nullable public java.math.BigInteger getRolloff();
+ method @Nullable public java.math.BigInteger getStreamId();
+ method @Nullable public java.math.BigInteger getStreamIdType();
+ method @Nullable public java.math.BigInteger getSymbolRate();
+ method public void setCoderate(@Nullable java.math.BigInteger);
+ method public void setModulation(@Nullable java.math.BigInteger);
+ method public void setRolloff(@Nullable java.math.BigInteger);
+ method public void setStreamId(@Nullable java.math.BigInteger);
+ method public void setStreamIdType(@Nullable java.math.BigInteger);
+ method public void setSymbolRate(@Nullable java.math.BigInteger);
+ }
+
+ public class IsdbtFrontendSettings {
+ ctor public IsdbtFrontendSettings();
+ method @Nullable public java.math.BigInteger getBandwidth();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendIsdbtLayerSettings getFrontendIsdbtLayerSettings();
+ method @Nullable public java.math.BigInteger getGuardInterval();
+ method @Nullable public java.math.BigInteger getInversion();
+ method @Nullable public java.math.BigInteger getMode();
+ method @Nullable public java.math.BigInteger getPartialReceptionFlag();
+ method @Nullable public java.math.BigInteger getServiceAreaId();
+ method public void setBandwidth(@Nullable java.math.BigInteger);
+ method public void setFrontendIsdbtLayerSettings(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendIsdbtLayerSettings);
+ method public void setGuardInterval(@Nullable java.math.BigInteger);
+ method public void setInversion(@Nullable java.math.BigInteger);
+ method public void setMode(@Nullable java.math.BigInteger);
+ method public void setPartialReceptionFlag(@Nullable java.math.BigInteger);
+ method public void setServiceAreaId(@Nullable java.math.BigInteger);
+ }
+
public class Lnb {
ctor public Lnb();
method @Nullable public String getId();
@@ -462,6 +562,12 @@
enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_5V;
}
+ public class OptionalFilter {
+ ctor public OptionalFilter();
+ method @Nullable public String getFilterId();
+ method public void setFilterId(@Nullable String);
+ }
+
public class RecordFilterSettings {
ctor public RecordFilterSettings();
method @Nullable public android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum getScIndexType();
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
index fefe86e..f74af7e 100644
--- a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -1,19 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- 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.
-->
-
<!-- The Sample Tuner Testing Configuration.
Name the customized xml with "tuner_vts_config.xml" and push into the device
"/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
@@ -32,7 +28,6 @@
- The default settings can be found in the sample_tuner_vts_configurations.xml.
- The users can also override the default frontend settings using id="FE_DEFAULT".
- The users can configure 1 or more frontend elements in the frontends sections.
-
Each frontend element contain the following attributes:
"id": unique id of the frontend that could be used to connect to the test the
"dataFlowConfiguration"
@@ -46,7 +41,6 @@
output. Supported in Tuner 2.0 or higher.
"frequency": the frequency used to configure tune and scan.
"endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
-
Each frontend element also contains one and only one type-related "frontendSettings".
- The settings type should match the frontend "type" attribute.
- For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
@@ -54,14 +48,36 @@
config only to the hal.
-->
<frontends>
- <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+ <frontend id="FE_DEFAULT" type="ISDBS" isSoftwareFrontend="true"
connectToCicamId="0" removeOutputPid="10" frequency="578000000"
endFrequency="800000000">
- <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+ <isdbsFrontendSettings streamId="0" symbolRate="0" streamIdType="0" modulation="0" coderate="0" rolloff="0"/>
+ </frontend>
+ <frontend id="FE_ATSC_0" type="ATSC" isSoftwareFrontend="true"
+ connectToCicamId="0" removeOutputPid="10" frequency="578000000"
+ endFrequency="800000000">
+ <atscFrontendSettings inversion="0" modulation="0"/>
+ </frontend>
+ <frontend id="FE_ISDBT_0" type="ISDBT" isSoftwareFrontend="true"
+ connectToCicamId="0" removeOutputPid="10" frequency="578000000"
+ endFrequency="800000000">
+ <isdbtFrontendSettings serviceAreaId="0" inversion="0" bandwidth="0" mode="0" guardInterval="0" partialReceptionFlag="0">
+ <FrontendIsdbtLayerSettings modulation="0" coderate="0" timeInterleave="0" numOfSegment="0"/>
+ </isdbtFrontendSettings>
</frontend>
<frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
connectToCicamId="0" removeOutputPid="10" frequency="578000000"
endFrequency="800000000">
+ <dvbsFrontendSettings inputStreamId="0" symbolRate="0" inversion="0" modulation="0" coderate="0"
+ rolloff="0" pilot="0" standard="0" vcmMode="0" scanType="0" isDiseqcRxMessage="true"/>
+ </frontend>
+ <frontend id="FE_DVBT_0" type="DVBT" isSoftwareFrontend="true"
+ connectToCicamId="0" removeOutputPid="10" frequency="578000000"
+ endFrequency="800000000">
+ <dvbtFrontendSettings bandwidth="8" transmissionMode="1" isHighPriority="1"
+ constellation="1" hierarchy="1" hpCoderate="1" lpCoderate="1"
+ guardInterval="1" standard="1" isMiso="0" plpMode="1"
+ plpId="0" plpGroupId="0"/>
</frontend>
</frontends>
<!-- Filter section:
@@ -71,7 +87,6 @@
- The users can also override the default filter settings using
- id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
- The users can configure 1 or more filter elements in the filters sections.
-
Each filter element contain the following attributes:
"id": unique id of the filter that could be used to connect to the test the
"dataFlowConfiguration"
@@ -80,7 +95,6 @@
"bufferSize": the buffer size of the filter in hex.
"pid": the pid that would be used to configure the filter.
"useFMQ": if the filter uses FMQ.
-
Each filter element also contains at most one type-related "filterSettings".
- The settings type should match the filter "subType" attribute.
- For example, when filter subType is audio or video, the avFilterSettings can be
@@ -89,6 +103,9 @@
only to the hal.
-->
<filters>
+ <filter id="FILTER_SECTION_DEFAULT" mainType="TS" subType="SECTION"
+ bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+ </filter>
<filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
<avFilterSettings isPassthrough="false" isSecureMemory="false">
@@ -116,7 +133,6 @@
This section contains configurations of all the dvrs that would be used in the tests.
- This section is optional and can be skipped if DVR is not supported.
- The users can configure 1 or more dvr elements in the dvrs sections.
-
Each dvr element contain the following attributes:
"id": unique id of the dvr that could be used to connect to the test the
"dataFlowConfiguration"
@@ -140,8 +156,21 @@
statusMask="15" lowThreshold="4096" highThreshold="32767"
dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
</dvrs>
+ <descramblers>
+ <descrambler id="DESCRAMBLER_0" casSystemId="63192"/>
+ </descramblers>
+ <timeFilters>
+ <timeFilter id="TIME_FILTER_0" timeStamp="1"/>
+ </timeFilters>
+ <diseqcMessages>
+ <diseqcMessage msgName="DISEQC_POWER_ON" msgBody="14 0 0 0 0 3"/>
+ </diseqcMessages>
+ <lnbs>
+ <lnb id="LNB_0" voltage="VOLTAGE_12V" tone="NONE" position="UNDEFINED"/>
+ <lnb id="LNB_1" name="default_lnb_external" voltage="VOLTAGE_5V"
+ tone="NONE" position="UNDEFINED"/>
+ </lnbs>
</hardwareConfiguration>
-
<!-- Data flow configuration section connects each data flow under test to the ids of the
hardwares that would be used during the tests. -->
<dataFlowConfiguration>
@@ -151,13 +180,39 @@
ipFilterConnection="FILTER_IP_IP_0"
dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
<scan frontendConnection="FE_DEFAULT"/>
- <dvrPlayback dvrConnection="DVR_PLAYBACK_1"
- audioFilterConnection="FILTER_AUDIO_DEFAULT"
- videoFilterConnection="FILTER_VIDEO_DEFAULT"/>
<dvrRecord hasFrontendConnection="true"
frontendConnection="FE_DEFAULT"
recordFilterConnection="FILTER_TS_RECORD_0"
dvrRecordConnection="DVR_RECORD_0"
dvrSoftwareFeConnection="DVR_PLAYBACK_1"/>
+ <dvrPlayback dvrConnection="DVR_PLAYBACK_1"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ sectionFilterConnection="FILTER_SECTION_DEFAULT"/>
+ <descrambling hasFrontendConnection="true"
+ frontendConnection="FE_DEFAULT"
+ descramblerConnection="DESCRAMBLER_0"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"
+ dvrSourceConnection="DVR_PLAYBACK_1">
+ </descrambling>
+ <timeFilter timeFilterConnection="TIME_FILTER_0"/>
+ <lnbLive frontendConnection="FE_DVBS_0"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ lnbConnection="LNB_1"
+ diseqcMsgSender="DISEQC_POWER_ON"/>
+ <lnbRecord frontendConnection="FE_DVBS_0"
+ recordFilterConnection="FILTER_TS_RECORD_0"
+ dvrRecordConnection="DVR_RECORD_0"
+ lnbConnection="LNB_0"
+ diseqcMsgSender="DISEQC_POWER_ON"/>
+ <lnbDescrambling frontendConnection="FE_DVBS_0"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ lnbConnection="LNB_1"
+ descramblerConnection="DESCRAMBLER_0"/>
+
</dataFlowConfiguration>
</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 59abd9a..c51ac51 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -77,8 +77,41 @@
<xs:complexType name="dvbsFrontendSettings">
<xs:attribute name="inputStreamId" type="xs:nonNegativeInteger" use="required"/>
<xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
- <xs:attribute name="scanType" type="dvbsScanType" use="optional"/>
- <xs:attribute name="isDiseqcRxMessage" type="xs:boolean" use="optional"/>
+ <xs:attribute name="scanType" type="dvbsScanType" use="required"/>
+ <xs:attribute name="isDiseqcRxMessage" type="xs:boolean" use="required"/>
+ <xs:attribute name="inversion" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="pilot" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="standard" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="vcmMode" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="rolloff" type="xs:nonNegativeInteger" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="atscFrontendSettings">
+ <xs:attribute name="inversion" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="isdbsFrontendSettings">
+ <xs:attribute name="streamId" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="streamIdType" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="coderate" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="rolloff" type="xs:nonNegativeInteger" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="isdbtFrontendSettings">
+ <xs:attribute name="serviceAreaId" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="inversion" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="bandwidth" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="mode" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="guardInterval" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="partialReceptionFlag" type="xs:nonNegativeInteger" use="required"/>
+ <xs:element name="FrontendIsdbtLayerSettings" type="FrontendIsdbtLayerSettings"/>
+ </xs:complexType>
+ <xs:complexType name="FrontendIsdbtLayerSettings">
+ <xs:attribute name="modulation" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="coderate" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="timeInterleave" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="numOfSegment" type="xs:nonNegativeInteger" use="required"/>
</xs:complexType>
<xs:complexType name="frontend">
@@ -109,16 +142,16 @@
</xs:annotation>
<xs:choice minOccurs="0" maxOccurs="1">
<!-- TODO: b/182519645 finish all the frontend settings structures. -->
- <!--xs:element name="analog" type="analogSettings"/>
- <xs:element name="atsc" type="atscSettings"/>
- <xs:element name="atsc3" type="atsc3Settings"/>
+ <!--xs:element name="analog" type="analogSettings"/-->
+ <xs:element name="atscFrontendSettings" type="atscFrontendSettings"/>
+ <!--xs:element name="atsc3" type="atsc3Settings"/>
<xs:element name="dvbc" type="dvbcSettings"/-->
<xs:element name="dvbsFrontendSettings" type="dvbsFrontendSettings"/>
<xs:element name="dvbtFrontendSettings" type="dvbtFrontendSettings"/>
- <!--xs:element name="isdbs" type="isdbsSettings"/>
- <xs:element name="isdbs3" type="isdbs3Settings"/>
- <xs:element name="isdbt" type="isdbtSettings"/>
- <xs:element name="dtmb" type="dtmbSettings"/-->
+ <xs:element name="isdbsFrontendSettings" type="isdbsFrontendSettings"/>
+ <!--xs:element name="isdbs3" type="isdbs3Settings"/-->
+ <xs:element name="isdbtFrontendSettings" type="isdbtFrontendSettings"/>
+ <!--xs:element name="dtmb" type="dtmbSettings"/-->
</xs:choice>
<xs:attribute name="id" type="frontendId" use="required"/>
<xs:attribute name="type" type="frontendTypeEnum" use="required"/>
@@ -617,7 +650,7 @@
<xs:attribute name="pcrFilterConnection" type="filterId" use="optional"/>
<xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
<xs:attribute name="ipFilterConnection" type="filterId" use="optional"/>
- <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
<!-- DVR is only required when the frontend is using the software input -->
<xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
</xs:complexType>
@@ -638,7 +671,7 @@
<xs:attribute name="descramblerConnection" type="descramblerId" use="required"/>
<xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
<xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
- <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
<!-- This DVR is only required when the frontend is using the software input -->
<xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
<!-- This Dvr is only required when there's no frontend(sw or hw) connection -->
@@ -651,7 +684,7 @@
<xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
<xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
<xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
- <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
</xs:complexType>
</xs:element>
<xs:element name="dvrRecord" minOccurs="0" maxOccurs="1">
@@ -675,7 +708,7 @@
<xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
<xs:attribute name="lnbConnection" type="lnbId" use="required"/>
<xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
- <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
</xs:complexType>
</xs:element>
<xs:element name="lnbRecord" minOccurs="0" maxOccurs="1">
@@ -685,6 +718,7 @@
<xs:attribute name="dvrRecordConnection" type="dvrId" use="required"/>
<xs:attribute name="lnbConnection" type="lnbId" use="required"/>
<xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
+ <xs:element name="optionalFilters" type="filterConnections" minOccurs="0" maxOccurs="1"/>
</xs:complexType>
</xs:element>
<xs:element name="timeFilter" minOccurs="0" maxOccurs="1">
@@ -692,6 +726,16 @@
<xs:attribute name="timeFilterConnection" type="timeFilterId" use="required"/>
</xs:complexType>
</xs:element>
+ <xs:element name="lnbDescrambling" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="lnbConnection" type="lnbId" use="required"/>
+ <xs:attribute name="descramblerConnection" type="descramblerId" use="required"/>
+ <xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
+ </xs:complexType>
+ </xs:element>
</xs:sequence>
</xs:complexType>
@@ -729,4 +773,7 @@
<xs:field xpath="@id"/>
</xs:key>
</xs:element>
+ <xs:complexType name="optionalFilter">
+ <xs:attribute name="filterId" type="filterId" use="required"/>
+ </xs:complexType>
</xs:schema>
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/AltModeData.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/AltModeData.aidl
new file mode 100644
index 0000000..d25ee84
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/AltModeData.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not us e 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.usb;
+@VintfStability
+union AltModeData {
+ android.hardware.usb.AltModeData.DisplayPortAltModeData displayPortAltModeData;
+ @VintfStability
+ parcelable DisplayPortAltModeData {
+ android.hardware.usb.DisplayPortAltModeStatus partnerSinkStatus = android.hardware.usb.DisplayPortAltModeStatus.UNKNOWN;
+ android.hardware.usb.DisplayPortAltModeStatus cableStatus = android.hardware.usb.DisplayPortAltModeStatus.UNKNOWN;
+ android.hardware.usb.DisplayPortAltModePinAssignment pinAssignment = android.hardware.usb.DisplayPortAltModePinAssignment.NONE;
+ boolean hpd = false;
+ android.hardware.usb.LinkTrainingStatus linkTrainingStatus = android.hardware.usb.LinkTrainingStatus.UNKNOWN;
+ }
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..8b67070
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum ComplianceWarning {
+ OTHER = 1,
+ DEBUG_ACCESSORY = 2,
+ BC_1_2 = 3,
+ MISSING_RP = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModePinAssignment.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
new file mode 100644
index 0000000..5908117
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum DisplayPortAltModePinAssignment {
+ NONE = 0,
+ A = 1,
+ B = 2,
+ C = 3,
+ D = 4,
+ E = 5,
+ F = 6,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModeStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModeStatus.aidl
new file mode 100644
index 0000000..dc69b98
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/DisplayPortAltModeStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum DisplayPortAltModeStatus {
+ UNKNOWN = 0,
+ NOT_CAPABLE = 1,
+ CAPABLE = 2,
+ ENABLED = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
index f866c1e..859f526 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
@@ -41,5 +41,5 @@
oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
oneway void limitPowerTransfer(in String portName, boolean limit, long transactionId);
- oneway void resetUsbPort(in String portName,long transactionId);
+ oneway void resetUsbPort(in String portName, long transactionId);
}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/LinkTrainingStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/LinkTrainingStatus.aidl
new file mode 100644
index 0000000..1f0b2dc
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/LinkTrainingStatus.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.usb;
+@Backing(type="int") @VintfStability
+enum LinkTrainingStatus {
+ UNKNOWN = 0,
+ SUCCESS = 1,
+ FAILURE = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PlugOrientation.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PlugOrientation.aidl
new file mode 100644
index 0000000..e218544
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PlugOrientation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum PlugOrientation {
+ UNKNOWN = 0,
+ UNPLUGGED = 1,
+ PLUGGED_UNKNOWN = 2,
+ PLUGGED_NORMAL = 3,
+ PLUGGED_FLIPPED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
index dfd99fb..cefddba 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
@@ -50,4 +50,8 @@
android.hardware.usb.UsbDataStatus[] usbDataStatus;
boolean powerTransferLimited;
android.hardware.usb.PowerBrickStatus powerBrickStatus;
+ boolean supportsComplianceWarnings = false;
+ android.hardware.usb.ComplianceWarning[] complianceWarnings = {};
+ android.hardware.usb.PlugOrientation plugOrientation = android.hardware.usb.PlugOrientation.UNKNOWN;
+ android.hardware.usb.AltModeData[] supportedAltModes = {};
}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
index e2c0cfb..b976852 100644
--- a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/UsbDataStatus.aidl
@@ -41,4 +41,6 @@
DISABLED_DOCK = 4,
DISABLED_FORCE = 5,
DISABLED_DEBUG = 6,
+ DISABLED_DOCK_HOST_MODE = 7,
+ DISABLED_DOCK_DEVICE_MODE = 8,
}
diff --git a/usb/aidl/android/hardware/usb/AltModeData.aidl b/usb/aidl/android/hardware/usb/AltModeData.aidl
new file mode 100644
index 0000000..0b1e06a
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/AltModeData.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not us e 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.usb;
+
+import android.hardware.usb.DisplayPortAltModePinAssignment;
+import android.hardware.usb.DisplayPortAltModeStatus;
+import android.hardware.usb.LinkTrainingStatus;
+
+@VintfStability
+union AltModeData {
+ /**
+ * Holds data necessary to communicate the current DisplayPort
+ * Alt Mode status.
+ */
+ @VintfStability
+ parcelable DisplayPortAltModeData {
+ /**
+ * Indicates the current DisplayPort Alt Mode Status of
+ * the port partner acting as a DisplayPort sink.
+ */
+ DisplayPortAltModeStatus partnerSinkStatus = DisplayPortAltModeStatus.UNKNOWN;
+ /**
+ * Indicates the current status of the attached DisplayPort
+ * Alt Mode cable/adapter.
+ */
+ DisplayPortAltModeStatus cableStatus = DisplayPortAltModeStatus.UNKNOWN;
+ /**
+ * Indicates the DisplayPort Alt Mode pin assignment
+ * negotiated between the device, port partner, and cable.
+ */
+ DisplayPortAltModePinAssignment pinAssignment = DisplayPortAltModePinAssignment.NONE;
+ /**
+ * Indicates DisplayPort Hot Plug Detection (HPD) status for a partner
+ * sink device. If true, then a DisplayPort Alt Mode partner sink is
+ * connected and powered on, and if false, the partner sink is not
+ * powered or no partner sink is connected.
+ */
+ boolean hpd = false;
+ /**
+ * Indicates the current status of DisplayPort link training over USB-C
+ * for the attached DisplayPort Alt Mode partner sink.
+ */
+ LinkTrainingStatus linkTrainingStatus = LinkTrainingStatus.UNKNOWN;
+ }
+ DisplayPortAltModeData displayPortAltModeData;
+}
diff --git a/usb/aidl/android/hardware/usb/ComplianceWarning.aidl b/usb/aidl/android/hardware/usb/ComplianceWarning.aidl
new file mode 100644
index 0000000..4c18a31
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ComplianceWarning.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates the potential non-compliance reasons for the
+ * connected USB Type-C port partner which could be a power
+ * source, accessory or cable. Applicable for USB-C receptacles
+ * in Android devices.
+ */
+enum ComplianceWarning {
+ /**
+ * Used to indicate Type-C sources/cables/accessories/ports
+ * whose issue is not listed below but do not meet
+ * specification requirements from including but not limited to
+ * USB Type-C Cable and Connector Specification, Universal Serial Bus
+ * Power Delivery Specification, and Universal Serial Bus
+ * 1.x/2.0/3.x/4.0.
+ */
+ OTHER = 1,
+ /**
+ * Used to indicate Type-C port partner
+ * (cable/accessory/source) that identifies itself as debug
+ * accessory source as defined in USB Type-C Cable and
+ * Connector Specification. However, the specification
+ * states that this is meant for debug only and shall not
+ * be used for with commercial products.
+ */
+ DEBUG_ACCESSORY = 2,
+ /**
+ * Used to indicate Type-C port partner that does not
+ * identify itself as one of the charging port types
+ * (SDP/CDP/DCP etc) as defined by Battery Charging v1.2
+ * Specification.
+ */
+ BC_1_2 = 3,
+ /**
+ * Used to indicate Type-C sources/cables that are missing
+ * pull up resistors on the CC pins as required by USB
+ * Type-C Cable and Connector Specification.
+ */
+ MISSING_RP = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/DisplayPortAltModePinAssignment.aidl b/usb/aidl/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
new file mode 100644
index 0000000..d3284e5
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/DisplayPortAltModePinAssignment.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates DisplayPort Alt Mode pin assignments whose port
+ * pin configurations are as defined by DisplayPort Alt Mode
+ * v1.0 for deprecated pin assignments A, B, and F and
+ * DisplayPort Alt Mode v2.x for pin assignments C, D, and E.
+ *
+ */
+enum DisplayPortAltModePinAssignment {
+ /**
+ * Indicates that the pin assignment has not yet been
+ * configured, the attached cable/adapter does not support
+ * DisplayPort Alt Mode, or no cable/adapter is attached.
+ */
+ NONE = 0,
+ /**
+ * Intended for use with USB-C-to-USB-C cables and with
+ * adapters from USB-C to other video formats using
+ * four lanes for DisplayPort transmission, and is
+ * restricted by the USB Type-C r1.0 Active Cable
+ * definition.
+ */
+ A = 1,
+ /**
+ * Intended for use with USB-C-to-USB-C cables and with
+ * adapters from USB-C to other video formats using
+ * two lanes for DisplayPort transmission and two for
+ * USB SuperSpeed,and is restricted by the USB Type-C
+ * r1.0 Active Cable definition.
+ */
+ B = 2,
+ /**
+ * Intended for use with USB-C-to-USB-C cables and with
+ * adapters from USB-C to other video formats using
+ * four lanes for DisplayPort transmission.
+ */
+ C = 3,
+ /**
+ * Intended for use with USB-C-to-USB-C cables and with
+ * adapters from USB-C to other video formats using
+ * two lanes for DisplayPort transmission and two for
+ * USB SuperSpeed.
+ */
+ D = 4,
+ /**
+ * Intended for use with adapters from USB-C-to-DP plugs
+ * or receptacles.
+ */
+ E = 5,
+ /**
+ * Intended for use with adapters from USB-C-to-DP plugs
+ * or receptacles that also support two lanes of USB
+ * SuperSpeed.
+ */
+ F = 6,
+}
diff --git a/usb/aidl/android/hardware/usb/DisplayPortAltModeStatus.aidl b/usb/aidl/android/hardware/usb/DisplayPortAltModeStatus.aidl
new file mode 100644
index 0000000..275ed15
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/DisplayPortAltModeStatus.aidl
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Port Partners:
+ * Indicates the current status of the of DisplayPort Alt Mode
+ * partner, which can either be a DisplayPort Alt Mode source
+ * (ex. computer, tablet, phone) or DisplayPort Alt Mode sink
+ * (monitor, hub, adapter).
+ *
+ * Cables:
+ * Indicates the current status of the Type-C cable/adapter
+ * connected to the local Android device.
+ *
+ */
+enum DisplayPortAltModeStatus {
+ /**
+ * Port Partners:
+ * The port partner status is currently unknown for one of
+ * the following reasons:
+ * 1. No port partner is connected to the device
+ * 2. The USB Power Delivery Discover Identity command
+ * has not been issued to the port partner via SOP
+ * messaging.
+ *
+ * Cables:
+ * The cable’s capabilities are not yet known to the
+ * device, or no cable is plugged in.
+ */
+ UNKNOWN = 0,
+ /**
+ * Port Partners:
+ * The current port partner does not list DisplayPort as
+ * one of its Alt Modes,does not list the capability to
+ * act as a DisplayPort Source or Sink device, or a compatible
+ * configuration could not be established.
+ *
+ * Cables:
+ * The cable/adapter’s capabilities do not list DisplayPort
+ * as one of its Alt Modes, or a compatible configuration could
+ * not be established.
+ */
+ NOT_CAPABLE = 1,
+ /**
+ * Port Partners:
+ * The current port partner lists compatible DisplayPort
+ * capabilities with the device, however may not yet have
+ * entered DisplayPort Alt Mode or has configured its
+ * port for data transmission.
+ *
+ * Cables:
+ * The Type-C cable/adapter’s capabilities have been
+ * discovered and list DisplayPort Alt Mode as one of its
+ * capabilities, however may not yet have entered DisplayPort
+ * Alt Mode or has been configured for data transmission.
+ */
+ CAPABLE = 2,
+ /**
+ * Port Partners:
+ * The port partner and device are both configured for
+ * DisplayPort Alt Mode.
+ *
+ * Cables:
+ * The Type-C cable/adapter is configured for DisplayPort
+ * Alt Mode.
+ */
+ ENABLED = 3,
+}
diff --git a/usb/aidl/android/hardware/usb/LinkTrainingStatus.aidl b/usb/aidl/android/hardware/usb/LinkTrainingStatus.aidl
new file mode 100644
index 0000000..9f3b3c3
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/LinkTrainingStatus.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.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Indicates the current status of DisplayPort link training over USB-C for the
+ * attached DisplayPort Alt Mode partner sink as described in DisplayPort
+ * v1.4/2.1.
+ */
+enum LinkTrainingStatus {
+ /*
+ * Indicates the link training result is not available because link training
+ * has not completed or initiated yet.
+ */
+ UNKNOWN = 0,
+ /*
+ * Indicates that link training has completed and optimal settings for data
+ * transmission between the sink and source device have successfully been
+ * negotiated.
+ */
+ SUCCESS = 1,
+ /*
+ * Indicates that link training has failed and the link initialization has
+ * terminated.
+ */
+ FAILURE = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/PlugOrientation.aidl b/usb/aidl/android/hardware/usb/PlugOrientation.aidl
new file mode 100644
index 0000000..3c09cfe
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PlugOrientation.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+@VintfStability
+@Backing(type="int")
+/**
+ * Used to indicate plug orientation as defined by USB Type-C
+ * Cable and Connector Specification.
+ */
+enum PlugOrientation {
+ UNKNOWN = 0,
+ UNPLUGGED = 1,
+ /**
+ * The device can detect that a plug is inserted, but
+ * the plug may not present a normal or flipped orientation.
+ */
+ PLUGGED_UNKNOWN = 2,
+ PLUGGED_NORMAL = 3,
+ PLUGGED_FLIPPED = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl
index 51bee71..daed13c 100644
--- a/usb/aidl/android/hardware/usb/PortStatus.aidl
+++ b/usb/aidl/android/hardware/usb/PortStatus.aidl
@@ -16,9 +16,12 @@
package android.hardware.usb;
+import android.hardware.usb.AltModeData;
+import android.hardware.usb.ComplianceWarning;
import android.hardware.usb.ContaminantDetectionStatus;
import android.hardware.usb.ContaminantProtectionMode;
import android.hardware.usb.ContaminantProtectionStatus;
+import android.hardware.usb.PlugOrientation;
import android.hardware.usb.PortDataRole;
import android.hardware.usb.PortMode;
import android.hardware.usb.PortPowerRole;
@@ -101,7 +104,8 @@
/**
* Current status of contaminant detection algorithm.
*/
- ContaminantDetectionStatus contaminantDetectionStatus = ContaminantDetectionStatus.NOT_SUPPORTED;
+ ContaminantDetectionStatus contaminantDetectionStatus =
+ ContaminantDetectionStatus.NOT_SUPPORTED;
/**
* UsbData status of the port.
* Lists reasons for USB data being disabled.
@@ -115,4 +119,25 @@
* Denotes whether Power brick is connected.
*/
PowerBrickStatus powerBrickStatus;
+ /**
+ * True if the hal implementation can support identifying
+ * non compliant USB power source/cable/accessory. False other
+ * otherwise.
+ */
+ boolean supportsComplianceWarnings = false;
+ /**
+ * List of reasons as to why the attached USB
+ * power source/cable/accessory is non compliant.
+ */
+ ComplianceWarning[] complianceWarnings = {};
+ /**
+ * Indicates the current orientation of the cable/adapter
+ * plugged into the device.
+ */
+ PlugOrientation plugOrientation = PlugOrientation.UNKNOWN;
+ /**
+ * Lists Alt Modes supported by the device and holds their
+ * current information.
+ */
+ AltModeData[] supportedAltModes = {};
}
diff --git a/usb/aidl/android/hardware/usb/UsbDataStatus.aidl b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
index 4b6a41a..e6b5f55 100644
--- a/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
+++ b/usb/aidl/android/hardware/usb/UsbDataStatus.aidl
@@ -35,7 +35,8 @@
*/
DISABLED_CONTAMINANT = 3,
/**
- * USB data is disabled due to dock.
+ * DISABLED_DOCK implies both DISABLED_DOCK_HOST_MODE
+ * and DISABLED_DOCK_DEVICE_MODE.
*/
DISABLED_DOCK = 4,
/**
@@ -45,5 +46,13 @@
/**
* USB data disabled for debug.
*/
- DISABLED_DEBUG = 6
+ DISABLED_DEBUG = 6,
+ /**
+ * USB Host mode is disabled due to a docking event.
+ */
+ DISABLED_DOCK_HOST_MODE = 7,
+ /**
+ * USB device mode disabled due to a docking event.
+ */
+ DISABLED_DOCK_DEVICE_MODE = 8,
}
diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp
index ad331f9..472e732 100644
--- a/usb/aidl/default/Android.bp
+++ b/usb/aidl/default/Android.bp
@@ -34,7 +34,7 @@
"Usb.cpp",
],
shared_libs: [
- "android.hardware.usb-V1-ndk",
+ "android.hardware.usb-V2-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp
index 7e738c4..593dd4f 100644
--- a/usb/aidl/default/Usb.cpp
+++ b/usb/aidl/default/Usb.cpp
@@ -123,6 +123,15 @@
return Status::SUCCESS;
}
+Status queryNonCompliantChargerStatus(std::vector<PortStatus> *currentPortStatus) {
+ string reasons, path;
+
+ for (int i = 0; i < currentPortStatus->size(); i++) {
+ (*currentPortStatus)[i].supportsComplianceWarnings = false;
+ }
+ return Status::SUCCESS;
+}
+
string appendRoleNodeHelper(const string &portName, PortRole::Tag tag) {
string node(kTypecPath + portName);
@@ -508,11 +517,11 @@
(*currentPortStatus)[i].usbDataStatus.push_back(UsbDataStatus::ENABLED);
ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
- "usbDataEnabled:%d",
- i, port.first.c_str(), port.second,
- (*currentPortStatus)[i].canChangeMode,
- (*currentPortStatus)[i].canChangeDataRole,
- (*currentPortStatus)[i].canChangePowerRole, 0);
+ "usbDataEnabled:%d plugOrientation:%d",
+ i, port.first.c_str(), port.second, (*currentPortStatus)[i].canChangeMode,
+ (*currentPortStatus)[i].canChangeDataRole,
+ (*currentPortStatus)[i].canChangePowerRole, 0,
+ (*currentPortStatus)[i].plugOrientation);
}
return Status::SUCCESS;
@@ -527,6 +536,7 @@
pthread_mutex_lock(&usb->mLock);
status = getPortStatusHelper(currentPortStatus);
queryMoistureDetectionStatus(currentPortStatus);
+ queryNonCompliantChargerStatus(currentPortStatus);
if (usb->mCallback != NULL) {
ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus,
status);
diff --git a/usb/aidl/default/android.hardware.usb-service.example.xml b/usb/aidl/default/android.hardware.usb-service.example.xml
index 6088194..c3f07f5 100644
--- a/usb/aidl/default/android.hardware.usb-service.example.xml
+++ b/usb/aidl/default/android.hardware.usb-service.example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.usb</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IUsb</name>
<instance>default</instance>
diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp
index 00a7c93..d0e0eec 100644
--- a/usb/aidl/vts/Android.bp
+++ b/usb/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.usb-V1-ndk",
+ "android.hardware.usb-V2-ndk",
],
test_suites: [
"general-tests",
diff --git a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
index ea2f985..e9aa65b 100644
--- a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
+++ b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
@@ -42,15 +42,22 @@
#define TIMEOUT_PERIOD 10
+using ::aidl::android::hardware::usb::AltModeData;
using ::aidl::android::hardware::usb::BnUsbCallback;
+using ::aidl::android::hardware::usb::ComplianceWarning;
+using ::aidl::android::hardware::usb::DisplayPortAltModePinAssignment;
+using ::aidl::android::hardware::usb::DisplayPortAltModeStatus;
using ::aidl::android::hardware::usb::IUsb;
using ::aidl::android::hardware::usb::IUsbCallback;
+using ::aidl::android::hardware::usb::LinkTrainingStatus;
+using ::aidl::android::hardware::usb::PlugOrientation;
using ::aidl::android::hardware::usb::PortDataRole;
using ::aidl::android::hardware::usb::PortMode;
using ::aidl::android::hardware::usb::PortPowerRole;
using ::aidl::android::hardware::usb::PortRole;
using ::aidl::android::hardware::usb::PortStatus;
using ::aidl::android::hardware::usb::Status;
+using ::aidl::android::hardware::usb::UsbDataStatus;
using ::ndk::ScopedAStatus;
using ::ndk::SpAIBinder;
@@ -247,6 +254,9 @@
std::mutex usb_mtx;
std::condition_variable usb_cv;
int usb_count = 0;
+
+ // Stores usb version
+ int32_t usb_version;
};
/*
@@ -280,6 +290,42 @@
}
/*
+ * Query port status to Check to see whether only one of DISABLED_DOCK,
+ * DISABLED_DOCK_DEVICE_MODE, DISABLED_DOCK_HOST_MODE is set at the most.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, DisabledDataStatusCheck) {
+ int disabledCount = 0;
+
+ ALOGI("UsbAidlTest DataStatusCheck start");
+ auto retVersion = usb->getInterfaceVersion(&usb_version);
+ ASSERT_TRUE(retVersion.isOk()) << retVersion;
+ if (usb_version < 2) {
+ ALOGI("UsbAidlTest skipping DataStatusCheck on older interface versions");
+ GTEST_SKIP();
+ }
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+ ALOGI("UsbAidlTest DataStatusCheck portName: %s", usb_last_port_status.portName.c_str());
+ if (usb_last_port_status.usbDataStatus.size() > 1) {
+ for (UsbDataStatus dataStatus : usb_last_port_status.usbDataStatus) {
+ if (dataStatus == UsbDataStatus::DISABLED_DOCK ||
+ dataStatus == UsbDataStatus::DISABLED_DOCK_DEVICE_MODE ||
+ dataStatus == UsbDataStatus::DISABLED_DOCK_HOST_MODE) {
+ disabledCount++;
+ }
+ }
+ }
+ EXPECT_GE(1, disabledCount);
+ ALOGI("UsbAidlTest DataStatusCheck end");
+}
+
+/*
* Trying to switch a non-existent port should fail.
* This test case tried to switch the port with empty
* name which is expected to fail.
@@ -560,6 +606,135 @@
ALOGI("UsbAidlTest resetUsbPort end");
}
+/*
+ * Test charger compliance warning
+ * The test asserts that complianceWarnings is
+ * empty when the feature is not supported. i.e.
+ * supportsComplianceWarning is false.
+ */
+TEST_P(UsbAidlTest, nonCompliantChargerStatus) {
+ ALOGI("UsbAidlTest nonCompliantChargerStatus start");
+ auto retVersion = usb->getInterfaceVersion(&usb_version);
+ ASSERT_TRUE(retVersion.isOk()) << retVersion;
+ if (usb_version < 2) {
+ ALOGI("UsbAidlTest skipping nonCompliantChargerStatus on older interface versions");
+ GTEST_SKIP();
+ }
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+
+ if (!usb_last_port_status.supportsComplianceWarnings) {
+ EXPECT_TRUE(usb_last_port_status.complianceWarnings.empty());
+ }
+
+ ALOGI("UsbAidlTest nonCompliantChargerStatus end");
+}
+
+/*
+ * Test charger compliance warning values
+ * The test asserts that complianceWarning values
+ * are valid.
+ */
+TEST_P(UsbAidlTest, nonCompliantChargerValues) {
+ ALOGI("UsbAidlTest nonCompliantChargerValues start");
+ auto retVersion = usb->getInterfaceVersion(&usb_version);
+ ASSERT_TRUE(retVersion.isOk()) << retVersion;
+ if (usb_version < 2) {
+ ALOGI("UsbAidlTest skipping nonCompliantChargerValues on older interface versions");
+ GTEST_SKIP();
+ }
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+
+ // Current compliance values range from [1, 4]
+ if (usb_last_port_status.supportsComplianceWarnings) {
+ for (auto warning : usb_last_port_status.complianceWarnings) {
+ EXPECT_TRUE((int)warning >= (int)ComplianceWarning::OTHER);
+ EXPECT_TRUE((int)warning <= (int)ComplianceWarning::MISSING_RP);
+ }
+ }
+
+ ALOGI("UsbAidlTest nonCompliantChargerValues end");
+}
+
+/*
+ * Test PlugOrientation Values are within range in PortStatus
+ */
+TEST_P(UsbAidlTest, plugOrientationValues) {
+ ALOGI("UsbAidlTest plugOrientationValues start");
+ auto retVersion = usb->getInterfaceVersion(&usb_version);
+ ASSERT_TRUE(retVersion.isOk()) << retVersion;
+ if (usb_version < 2) {
+ ALOGI("UsbAidlTest skipping plugOrientationValues on older interface versions");
+ GTEST_SKIP();
+ }
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+
+ EXPECT_TRUE((int)usb_last_port_status.plugOrientation >= (int)PlugOrientation::UNKNOWN);
+ EXPECT_TRUE((int)usb_last_port_status.plugOrientation <= (int)PlugOrientation::PLUGGED_FLIPPED);
+}
+
+/*
+ * Test DisplayPortAltMode Values when DisplayPort Alt Mode
+ * is active.
+ */
+TEST_P(UsbAidlTest, dpAltModeValues) {
+ ALOGI("UsbAidlTest dpAltModeValues start");
+ auto retVersion = usb->getInterfaceVersion(&usb_version);
+ ASSERT_TRUE(retVersion.isOk()) << retVersion;
+ if (usb_version < 2) {
+ ALOGI("UsbAidlTest skipping dpAltModeValues on older interface versions");
+ GTEST_SKIP();
+ }
+ int64_t transactionId = rand() % 10000;
+ const auto& ret = usb->queryPortStatus(transactionId);
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(2, usb_last_cookie);
+ EXPECT_EQ(transactionId, last_transactionId);
+
+ // Discover DisplayPort Alt Mode
+ for (AltModeData altMode : usb_last_port_status.supportedAltModes) {
+ if (altMode.getTag() == AltModeData::displayPortAltModeData) {
+ AltModeData::DisplayPortAltModeData displayPortAltModeData =
+ altMode.get<AltModeData::displayPortAltModeData>();
+ EXPECT_TRUE((int)displayPortAltModeData.partnerSinkStatus >=
+ (int)DisplayPortAltModeStatus::UNKNOWN);
+ EXPECT_TRUE((int)displayPortAltModeData.partnerSinkStatus <=
+ (int)DisplayPortAltModeStatus::ENABLED);
+
+ EXPECT_TRUE((int)displayPortAltModeData.cableStatus >=
+ (int)DisplayPortAltModeStatus::UNKNOWN);
+ EXPECT_TRUE((int)displayPortAltModeData.cableStatus <=
+ (int)DisplayPortAltModeStatus::ENABLED);
+
+ EXPECT_TRUE((int)displayPortAltModeData.pinAssignment >=
+ (int)DisplayPortAltModePinAssignment::NONE);
+ EXPECT_TRUE((int)displayPortAltModeData.pinAssignment <=
+ (int)DisplayPortAltModePinAssignment::F);
+
+ EXPECT_TRUE((int)displayPortAltModeData.linkTrainingStatus >=
+ (int)LinkTrainingStatus::UNKNOWN);
+ EXPECT_TRUE((int)displayPortAltModeData.pinAssignment <= (int)LinkTrainingStatus::FAILURE);
+ }
+ }
+
+ ALOGI("UsbAidlTest dpAltModeValues end");
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, UsbAidlTest,
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
index c3f26d5..78b79e4 100644
--- a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -36,11 +36,12 @@
parcelable GadgetFunction {
const long NONE = 0;
const long ADB = 1;
- const long ACCESSORY = 2;
- const long MTP = 4;
- const long MIDI = 8;
- const long PTP = 16;
- const long RNDIS = 32;
- const long AUDIO_SOURCE = 64;
- const long NCM = 1024;
+ const long ACCESSORY = (1 << 1);
+ const long MTP = (1 << 2);
+ const long MIDI = (1 << 3);
+ const long PTP = (1 << 4);
+ const long RNDIS = (1 << 5);
+ const long AUDIO_SOURCE = (1 << 6);
+ const long UVC = (1 << 7);
+ const long NCM = (1 << 10);
}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
index ef45f8b..b5c0b5c 100644
--- a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -37,5 +37,5 @@
oneway void setCurrentUsbFunctions(in long functions, in android.hardware.usb.gadget.IUsbGadgetCallback callback, in long timeoutMs, long transactionId);
oneway void getCurrentUsbFunctions(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
oneway void getUsbSpeed(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
- oneway void reset();
+ oneway void reset(in android.hardware.usb.gadget.IUsbGadgetCallback callback, long transactionId);
}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
index 9de68de..b2b0e5a 100644
--- a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -37,4 +37,5 @@
oneway void setCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
oneway void getCurrentUsbFunctionsCb(in long functions, in android.hardware.usb.gadget.Status status, long transactionId);
oneway void getUsbSpeedCb(in android.hardware.usb.gadget.UsbSpeed speed, long transactionId);
+ oneway void resetCb(in android.hardware.usb.gadget.Status status, long transactionId);
}
diff --git a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
index 0f54ee5..7d4fa17 100644
--- a/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
+++ b/usb/gadget/aidl/aidl_api/android.hardware.usb.gadget/current/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -34,11 +34,15 @@
package android.hardware.usb.gadget;
@Backing(type="int") @VintfStability
enum UsbSpeed {
- UNKNOWN = 0,
- LOWSPEED = 1,
- FULLSPEED = 2,
- HIGHSPEED = 3,
- SUPERSPEED = 4,
- SUPERSPEED_10Gb = 5,
- SUPERSPEED_20Gb = 6,
+ UNKNOWN = (-1),
+ LOWSPEED = 0,
+ FULLSPEED = 1,
+ HIGHSPEED = 2,
+ SUPERSPEED = 3,
+ SUPERSPEED_10Gb = 4,
+ SUPERSPEED_20Gb = 5,
+ USB4_GEN2_10Gb = 6,
+ USB4_GEN2_20Gb = 7,
+ USB4_GEN3_20Gb = 8,
+ USB4_GEN3_40Gb = 9,
}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
index d82b427..dd7ee37 100644
--- a/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/GadgetFunction.aidl
@@ -51,6 +51,10 @@
*/
const long AUDIO_SOURCE = 1 << 6;
/**
+ * UVC - Universal Video Class function.
+ */
+ const long UVC = 1 << 7;
+ /**
* NCM - NCM function.
*/
const long NCM = 1 << 10;
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
index da644d6..a0c61ae 100644
--- a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadget.aidl
@@ -16,7 +16,6 @@
package android.hardware.usb.gadget;
-import android.hardware.usb.gadget.GadgetFunction;
import android.hardware.usb.gadget.IUsbGadgetCallback;
@VintfStability
@@ -60,6 +59,10 @@
* This function is used to reset USB gadget driver.
* Performs USB data connection reset. The connection will disconnect and
* reconnect.
+ *
+ * @param callback IUsbGadgetCallback::resetCb used to propagate
+ * the result of requesting resetUsbGadget.
+ * @param transactionId ID to be used when invoking the callback.
*/
- void reset();
+ void reset(in IUsbGadgetCallback callback, long transactionId);
}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
index 5a682d6..cd9a662 100644
--- a/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/IUsbGadgetCallback.aidl
@@ -16,7 +16,6 @@
package android.hardware.usb.gadget;
-import android.hardware.usb.gadget.GadgetFunction;
import android.hardware.usb.gadget.Status;
import android.hardware.usb.gadget.UsbSpeed;
@@ -60,4 +59,12 @@
* @param transactionId ID to be used when invoking the callback.
*/
void getUsbSpeedCb(in UsbSpeed speed, long transactionId);
+
+ /**
+ * Callback function used to propagate the result of requesting
+ * resetUsbGadget.
+ * @param status SUCCESS if current request succeeded. FAILURE otherwise.
+ * @param transactionId current transactionId sent during reset request.
+ */
+ void resetCb(in Status status, long transactionId);
}
diff --git a/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl b/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
index 0492757..2a3fb93 100644
--- a/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
+++ b/usb/gadget/aidl/android/hardware/usb/gadget/UsbSpeed.aidl
@@ -22,29 +22,55 @@
/**
* UNKNOWN - Not Connected or Unsupported Speed
*/
- UNKNOWN = 0,
+ UNKNOWN = -1,
+
/**
* USB Low Speed
*/
- LOWSPEED = 1,
+ LOWSPEED = 0,
+
/**
* USB Full Speed
*/
- FULLSPEED = 2,
+ FULLSPEED = 1,
+
/**
* USB High Speed
*/
- HIGHSPEED = 3,
+ HIGHSPEED = 2,
+
/**
* USB Super Speed
*/
- SUPERSPEED = 4,
+ SUPERSPEED = 3,
+
/**
* USB Super Speed 10Gbps
*/
- SUPERSPEED_10Gb = 5,
+ SUPERSPEED_10Gb = 4,
+
/**
* USB Super Speed 20Gbps
*/
- SUPERSPEED_20Gb = 6,
+ SUPERSPEED_20Gb = 5,
+
+ /**
+ * USB4 Gen2 x 1 (10Gbps)
+ */
+ USB4_GEN2_10Gb = 6,
+
+ /**
+ * USB4 Gen2 x 2 (20Gbps)
+ */
+ USB4_GEN2_20Gb = 7,
+
+ /**
+ * USB4 Gen3 x 1 (20Gbps)
+ */
+ USB4_GEN3_20Gb = 8,
+
+ /**
+ * USB4 Gen3 x 2 (40Gbps)
+ */
+ USB4_GEN3_40Gb = 9,
}
diff --git a/usb/gadget/aidl/default/UsbGadget.cpp b/usb/gadget/aidl/default/UsbGadget.cpp
index 51f7f5b..72d59c1 100644
--- a/usb/gadget/aidl/default/UsbGadget.cpp
+++ b/usb/gadget/aidl/default/UsbGadget.cpp
@@ -40,7 +40,8 @@
constexpr char kAccessoryLimitCurrent[] = "i2c-max77759tcpc/usb_limit_accessory_current";
constexpr char kAccessoryLimitCurrentEnable[] = "i2c-max77759tcpc/usb_limit_accessory_enable";
-UsbGadget::UsbGadget() : mGadgetIrqPath("") {}
+UsbGadget::UsbGadget() : mGadgetIrqPath("") {
+}
Status UsbGadget::getUsbGadgetIrqPath() {
std::string irqs;
@@ -84,8 +85,8 @@
return Status::SUCCESS;
}
-void currentFunctionsAppliedCallback(bool functionsApplied, void* payload) {
- UsbGadget* gadget = (UsbGadget*)payload;
+void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
+ UsbGadget *gadget = (UsbGadget *)payload;
gadget->mCurrentUsbFunctionsApplied = functionsApplied;
}
@@ -95,17 +96,17 @@
return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
}
ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
- mCurrentUsbFunctions,
- mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
- in_transactionId);
+ mCurrentUsbFunctions,
+ mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
+ in_transactionId);
if (!ret.isOk())
ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.getDescription().c_str());
return ScopedAStatus::ok();
}
-ScopedAStatus UsbGadget::getUsbSpeed(const shared_ptr<IUsbGadgetCallback>& callback,
- int64_t in_transactionId) {
+ScopedAStatus UsbGadget::getUsbSpeed(const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t in_transactionId) {
std::string current_speed;
if (ReadFileToString(SPEED_PATH, ¤t_speed)) {
current_speed = Trim(current_speed);
@@ -132,7 +133,8 @@
if (callback) {
ScopedAStatus ret = callback->getUsbSpeedCb(mUsbSpeed, in_transactionId);
- if (!ret.isOk()) ALOGE("Call to getUsbSpeedCb failed %s", ret.getDescription().c_str());
+ if (!ret.isOk())
+ ALOGE("Call to getUsbSpeedCb failed %s", ret.getDescription().c_str());
}
return ScopedAStatus::ok();
@@ -142,15 +144,19 @@
return Status::SUCCESS;
}
-ScopedAStatus UsbGadget::reset() {
+ScopedAStatus UsbGadget::reset(const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t in_transactionId) {
+ if (callback)
+ callback->resetCb(Status::SUCCESS, in_transactionId);
return ScopedAStatus::ok();
}
-Status UsbGadget::setupFunctions(long functions, const shared_ptr<IUsbGadgetCallback>& callback,
- uint64_t timeout, int64_t in_transactionId) {
+Status UsbGadget::setupFunctions(long functions,
+ const shared_ptr<IUsbGadgetCallback> &callback, uint64_t timeout,
+ int64_t in_transactionId) {
bool ffsEnabled = false;
if (timeout == 0) {
- ALOGI("timeout not setup");
+ ALOGI("timeout not setup");
}
if ((functions & GadgetFunction::ADB) != 0) {
@@ -172,12 +178,12 @@
return Status::SUCCESS;
}
-Status getI2cBusHelper(string* name) {
- DIR* dp;
+Status getI2cBusHelper(string *name) {
+ DIR *dp;
dp = opendir(kHsi2cPath);
if (dp != NULL) {
- struct dirent* ep;
+ struct dirent *ep;
while ((ep = readdir(dp))) {
if (ep->d_type == DT_DIR) {
@@ -196,8 +202,9 @@
}
ScopedAStatus UsbGadget::setCurrentUsbFunctions(int64_t functions,
- const shared_ptr<IUsbGadgetCallback>& callback,
- int64_t timeoutMs, int64_t in_transactionId) {
+ const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t timeoutMs,
+ int64_t in_transactionId) {
std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
std::string current_usb_power_operation_mode, current_usb_type;
std::string usb_limit_sink_enable;
@@ -212,7 +219,8 @@
accessoryCurrentLimitEnablePath = kI2CPath + path + "/" + kAccessoryLimitCurrentEnable;
// Get the gadget IRQ number before tearDownGadget()
- if (mGadgetIrqPath.empty()) getUsbGadgetIrqPath();
+ if (mGadgetIrqPath.empty())
+ getUsbGadgetIrqPath();
// Unlink the gadget and stop the monitor if running.
Status status = tearDownGadget();
@@ -223,13 +231,13 @@
ALOGI("Returned from tearDown gadget");
// Leave the gadget pulled down to give time for the host to sense disconnect.
- // usleep(kDisconnectWaitUs);
+ //usleep(kDisconnectWaitUs);
if (functions == GadgetFunction::NONE) {
if (callback == NULL)
- return ScopedAStatus::fromServiceSpecificErrorWithMessage(-1, "callback == NULL");
- ScopedAStatus ret =
- callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ -1, "callback == NULL");
+ ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
if (!ret.isOk())
ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
@@ -259,9 +267,10 @@
if (ReadFileToString(CURRENT_USB_POWER_OPERATION_MODE_PATH, ¤t_usb_power_operation_mode))
current_usb_power_operation_mode = Trim(current_usb_power_operation_mode);
- if (functions & GadgetFunction::ACCESSORY && current_usb_type == "Unknown SDP [CDP] DCP" &&
+ if (functions & GadgetFunction::ACCESSORY &&
+ current_usb_type == "Unknown SDP [CDP] DCP" &&
(current_usb_power_operation_mode == "default" ||
- current_usb_power_operation_mode == "1.5A")) {
+ current_usb_power_operation_mode == "1.5A")) {
if (!WriteStringToFile("1300000", accessoryCurrentLimitPath)) {
ALOGI("Write 1.3A to limit current fail");
} else {
@@ -276,7 +285,8 @@
ALOGI("Usb Gadget setcurrent functions called successfully");
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- -1, "Usb Gadget setcurrent functions called successfully");
+ -1, "Usb Gadget setcurrent functions called successfully");
+
error:
ALOGI("Usb Gadget setcurrent functions failed");
@@ -287,10 +297,10 @@
if (!ret.isOk())
ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- -1, "Error while calling setCurrentUsbFunctionsCb");
+ -1, "Error while calling setCurrentUsbFunctionsCb");
}
} // namespace gadget
} // namespace usb
} // namespace hardware
} // namespace android
-} // namespace aidl
+} // aidl
diff --git a/usb/gadget/aidl/default/UsbGadget.h b/usb/gadget/aidl/default/UsbGadget.h
index 5060194..5eaaa48 100644
--- a/usb/gadget/aidl/default/UsbGadget.h
+++ b/usb/gadget/aidl/default/UsbGadget.h
@@ -16,16 +16,16 @@
#pragma once
+#include <android-base/file.h>
+#include <android-base/properties.h>
+#include <android-base/unique_fd.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
#include <aidl/android/hardware/usb/gadget/BnUsbGadget.h>
#include <aidl/android/hardware/usb/gadget/BnUsbGadgetCallback.h>
#include <aidl/android/hardware/usb/gadget/GadgetFunction.h>
#include <aidl/android/hardware/usb/gadget/IUsbGadget.h>
#include <aidl/android/hardware/usb/gadget/IUsbGadgetCallback.h>
-#include <android-base/file.h>
-#include <android-base/parseint.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
#include <sched.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
@@ -43,16 +43,16 @@
namespace gadget {
using ::aidl::android::hardware::usb::gadget::GadgetFunction;
-using ::aidl::android::hardware::usb::gadget::IUsbGadget;
using ::aidl::android::hardware::usb::gadget::IUsbGadgetCallback;
+using ::aidl::android::hardware::usb::gadget::IUsbGadget;
using ::aidl::android::hardware::usb::gadget::Status;
using ::aidl::android::hardware::usb::gadget::UsbSpeed;
using ::android::base::GetProperty;
-using ::android::base::ParseUint;
-using ::android::base::ReadFileToString;
using ::android::base::SetProperty;
-using ::android::base::Trim;
+using ::android::base::ParseUint;
using ::android::base::unique_fd;
+using ::android::base::ReadFileToString;
+using ::android::base::Trim;
using ::android::base::WriteStringToFile;
using ::ndk::ScopedAStatus;
using ::std::shared_ptr;
@@ -65,19 +65,19 @@
#ifndef UDC_PATH
#define UDC_PATH "/sys/class/udc/11110000.dwc3/"
#endif
-// static MonitorFfs monitorFfs(kGadgetName);
+//static MonitorFfs monitorFfs(kGadgetName);
#define SPEED_PATH UDC_PATH "current_speed"
#define BIG_CORE "6"
#define MEDIUM_CORE "4"
-#define POWER_SUPPLY_PATH "/sys/class/power_supply/usb/"
-#define USB_PORT0_PATH "/sys/class/typec/port0/"
+#define POWER_SUPPLY_PATH "/sys/class/power_supply/usb/"
+#define USB_PORT0_PATH "/sys/class/typec/port0/"
-#define CURRENT_MAX_PATH POWER_SUPPLY_PATH "current_max"
-#define CURRENT_USB_TYPE_PATH POWER_SUPPLY_PATH "usb_type"
-#define CURRENT_USB_POWER_OPERATION_MODE_PATH USB_PORT0_PATH "power_operation_mode"
+#define CURRENT_MAX_PATH POWER_SUPPLY_PATH "current_max"
+#define CURRENT_USB_TYPE_PATH POWER_SUPPLY_PATH "usb_type"
+#define CURRENT_USB_POWER_OPERATION_MODE_PATH USB_PORT0_PATH "power_operation_mode"
struct UsbGadget : public BnUsbGadget {
UsbGadget();
@@ -90,26 +90,27 @@
UsbSpeed mUsbSpeed;
ScopedAStatus setCurrentUsbFunctions(int64_t functions,
- const shared_ptr<IUsbGadgetCallback>& callback,
- int64_t timeoutMs, int64_t in_transactionId) override;
+ const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t timeoutMs, int64_t in_transactionId) override;
- ScopedAStatus getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback>& callback,
- int64_t in_transactionId) override;
+ ScopedAStatus getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t in_transactionId) override;
- ScopedAStatus reset() override;
+ ScopedAStatus reset(const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t in_transactionId) override;
- ScopedAStatus getUsbSpeed(const shared_ptr<IUsbGadgetCallback>& callback,
- int64_t in_transactionId) override;
+ ScopedAStatus getUsbSpeed(const shared_ptr<IUsbGadgetCallback> &callback,
+ int64_t in_transactionId) override;
private:
Status tearDownGadget();
Status getUsbGadgetIrqPath();
- Status setupFunctions(long functions, const shared_ptr<IUsbGadgetCallback>& callback,
- uint64_t timeout, int64_t in_transactionId);
+ Status setupFunctions(long functions, const shared_ptr<IUsbGadgetCallback> &callback,
+ uint64_t timeout, int64_t in_transactionId);
};
} // namespace gadget
} // namespace usb
} // namespace hardware
} // namespace android
-} // namespace aidl
+} // aidl
diff --git a/usb/gadget/aidl/default/service_gadget.cpp b/usb/gadget/aidl/default/service_gadget.cpp
index 88678ab..7efbadd 100644
--- a/usb/gadget/aidl/default/service_gadget.cpp
+++ b/usb/gadget/aidl/default/service_gadget.cpp
@@ -22,8 +22,7 @@
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<UsbGadget> usbgadget = ndk::SharedRefBase::make<UsbGadget>();
const std::string instance = std::string() + UsbGadget::descriptor + "/default";
- binder_status_t status =
- AServiceManager_addService(usbgadget->asBinder().get(), instance.c_str());
+ binder_status_t status = AServiceManager_addService(usbgadget->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
ABinderProcess_joinThreadPool();
return -1;
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
index 00cb8e0..6ee5799 100644
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -71,8 +71,8 @@
* The UCI message format is as per UCI protocol and it is
* defined in "FiRa Consortium - UCI Generic Specification_v1.0" specification at FiRa
* consortium.
- * WIP doc link: https://groups.firaconsortium.org/wg/Technical/document/folder/127.
- * TODO(b/196004116): Link to the published specification.
+ *
+ * UCI 1.1 specification: https://groups.firaconsortium.org/wg/members/document/1949.
*
* This method may queue writes and return immediately, or it may block until data is written.
* Implementation must guarantee that writes are executed in order.
diff --git a/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl b/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl
index 75853cd..f31aeba 100755
--- a/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbClientCallback.aidl
@@ -28,8 +28,7 @@
* can use to pass incoming data to the stack. These include UCI
* responses and notifications from the UWB subsystem.
*
- * WIP doc link: https://groups.firaconsortium.org/wg/Technical/document/folder/127.
- * TODO(b/196004116): Link to the published specification.
+ * UCI 1.1 specification: https://groups.firaconsortium.org/wg/members/document/1949.
*
* @param data UCI packet sent.
*/
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
index 4cf2496..4207574 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -24,8 +24,8 @@
@Backing(type="int")
enum UwbVendorReasonCodes {
/**
- * Use values from the vendor specific reason code range: 0x80 – 0xFF defined in Table 16 of
- * UCI specification.
+ * Use values from the vendor specific reason code range: 0x80 – 0xFF defined in
+ * Table 15 (state change with reason codes) of UCI specification.
*/
/** Fira specific */
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index f50a5e7..c88cb59 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -602,10 +602,11 @@
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
<< toString(primitive);
- //TODO(b/187207798): revert back to conservative timeout values once
- //latencies have been fixed
- EXPECT_EQ(completionFuture.wait_for(duration * 4), std::future_status::ready)
- << toString(primitive);
+ // TODO(b/261130361): Investigate why latency from driver and hardware will cause test
+ // to fail when wait duration is ~40ms or less.
+ EXPECT_EQ(completionFuture.wait_for(duration + std::chrono::milliseconds(50)),
+ std::future_status::ready)
+ << toString(primitive);
end = high_resolution_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp
index caa92aa..74cec99f 100644
--- a/weaver/aidl/Android.bp
+++ b/weaver/aidl/Android.bp
@@ -17,5 +17,10 @@
platform_apis: true,
},
},
- versions: ["1"],
+ versions_with_info: [
+ {
+ version: "1",
+ imports: [],
+ },
+ ],
}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
index 47ee4c8..96e528f 100644
--- a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,4 +36,5 @@
parcelable WeaverReadResponse {
long timeout;
byte[] value;
+ android.hardware.weaver.WeaverReadStatus status = android.hardware.weaver.WeaverReadStatus.FAILED;
}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadStatus.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadStatus.aidl
new file mode 100644
index 0000000..fce9758
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.weaver;
+@Backing(type="int") @VintfStability
+enum WeaverReadStatus {
+ OK = 0,
+ FAILED = 1,
+ INCORRECT_KEY = 2,
+ THROTTLE = 3,
+}
diff --git a/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
index ec006e8..17ea718 100644
--- a/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
+++ b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,22 @@
package android.hardware.weaver;
+import android.hardware.weaver.WeaverReadStatus;
+
@VintfStability
parcelable WeaverReadResponse {
/**
- * The time to wait, in milliseconds, before making the next request.
+ * The time to wait, in milliseconds, before making the next request,
+ * must be greater than or equal to zero and less than INT_MAX.
*/
long timeout;
/**
* The value read from the slot or empty if the value was not read.
*/
byte[] value;
+ /**
+ * Status from WeaverReadStatus
+ */
+ WeaverReadStatus status = WeaverReadStatus.FAILED;
}
diff --git a/weaver/aidl/android/hardware/weaver/WeaverReadStatus.aidl b/weaver/aidl/android/hardware/weaver/WeaverReadStatus.aidl
new file mode 100644
index 0000000..36e731f
--- /dev/null
+++ b/weaver/aidl/android/hardware/weaver/WeaverReadStatus.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.weaver;
+
+@VintfStability
+@Backing(type="int")
+enum WeaverReadStatus {
+ OK,
+ FAILED,
+ INCORRECT_KEY,
+ THROTTLE,
+}
diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp
index 70d9171..494cb1b 100644
--- a/weaver/aidl/default/Android.bp
+++ b/weaver/aidl/default/Android.bp
@@ -34,7 +34,7 @@
"Weaver.cpp",
],
shared_libs: [
- "android.hardware.weaver-V1-ndk",
+ "android.hardware.weaver-V2-ndk",
"libbase",
"libbinder_ndk",
],
diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp
index 6b77924..c9ffe85 100644
--- a/weaver/aidl/default/Weaver.cpp
+++ b/weaver/aidl/default/Weaver.cpp
@@ -37,18 +37,19 @@
}
::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) {
+ using ::aidl::android::hardware::weaver::WeaverReadStatus;
if (in_slotId > 15 || in_key.size() > 16) {
- *out_response = {0, {}};
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_FAILED));
+ *out_response = {0, {}, WeaverReadStatus::FAILED};
+ return ndk::ScopedAStatus::ok();
}
if (slot_array[in_slotId].key != in_key) {
- *out_response = {0, {}};
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_INCORRECT_KEY));
+ *out_response = {0, {}, WeaverReadStatus::INCORRECT_KEY};
+ return ndk::ScopedAStatus::ok();
}
- *out_response = {0, slot_array[in_slotId].value};
+ *out_response = {0, slot_array[in_slotId].value, WeaverReadStatus::OK};
return ::ndk::ScopedAStatus::ok();
}
diff --git a/weaver/aidl/default/android.hardware.weaver-service.example.xml b/weaver/aidl/default/android.hardware.weaver-service.example.xml
index ed291cd..bfe4396 100644
--- a/weaver/aidl/default/android.hardware.weaver-service.example.xml
+++ b/weaver/aidl/default/android.hardware.weaver-service.example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.weaver</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IWeaver</name>
<instance>default</instance>
diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp
index cf1661c..557fe47 100644
--- a/weaver/aidl/vts/Android.bp
+++ b/weaver/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
"libbinder_ndk",
"libbase",
],
- static_libs: ["android.hardware.weaver-V1-ndk"],
+ static_libs: ["android.hardware.weaver-V2-ndk"],
test_suites: [
"general-tests",
"vts",
diff --git a/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
index 878c762..f016515 100644
--- a/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
+++ b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
@@ -25,6 +25,7 @@
using ::aidl::android::hardware::weaver::IWeaver;
using ::aidl::android::hardware::weaver::WeaverConfig;
using ::aidl::android::hardware::weaver::WeaverReadResponse;
+using ::aidl::android::hardware::weaver::WeaverReadStatus;
using ::ndk::SpAIBinder;
@@ -102,14 +103,17 @@
WeaverReadResponse response;
std::vector<uint8_t> readValue;
uint32_t timeout;
+ WeaverReadStatus status;
const auto readRet = weaver->read(slotId, KEY, &response);
readValue = response.value;
timeout = response.timeout;
+ status = response.status;
ASSERT_TRUE(readRet.isOk());
EXPECT_EQ(readValue, VALUE);
EXPECT_EQ(timeout, 0u);
+ EXPECT_EQ(status, WeaverReadStatus::OK);
}
/*
@@ -128,14 +132,17 @@
WeaverReadResponse response;
std::vector<uint8_t> readValue;
uint32_t timeout;
+ WeaverReadStatus status;
const auto readRet = weaver->read(slotId, KEY, &response);
readValue = response.value;
timeout = response.timeout;
+ status = response.status;
ASSERT_TRUE(readRet.isOk());
EXPECT_EQ(readValue, OTHER_VALUE);
EXPECT_EQ(timeout, 0u);
+ EXPECT_EQ(status, WeaverReadStatus::OK);
}
/*
@@ -149,15 +156,16 @@
WeaverReadResponse response;
std::vector<uint8_t> readValue;
+ WeaverReadStatus status;
const auto readRet =
weaver->read(slotId, WRONG_KEY, &response);
readValue = response.value;
+ status = response.status;
- ASSERT_FALSE(readRet.isOk());
- ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
- ASSERT_EQ(IWeaver::STATUS_INCORRECT_KEY, readRet.getServiceSpecificError());
+ ASSERT_TRUE(readRet.isOk());
EXPECT_TRUE(readValue.empty());
+ EXPECT_EQ(status, WeaverReadStatus::INCORRECT_KEY);
}
/*
@@ -193,17 +201,18 @@
WeaverReadResponse response;
std::vector<uint8_t> readValue;
uint32_t timeout;
+ WeaverReadStatus status;
const auto readRet =
weaver->read(config.slots, KEY, &response);
readValue = response.value;
timeout = response.timeout;
+ status = response.status;
- ASSERT_FALSE(readRet.isOk());
- ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
- ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
+ ASSERT_TRUE(readRet.isOk());
EXPECT_TRUE(readValue.empty());
EXPECT_EQ(timeout, 0u);
+ EXPECT_EQ(status, WeaverReadStatus::FAILED);
}
/*
@@ -250,17 +259,18 @@
WeaverReadResponse response;
std::vector<uint8_t> readValue;
uint32_t timeout;
+ WeaverReadStatus status;
const auto readRet =
weaver->read(slotId, bigKey, &response);
readValue = response.value;
timeout = response.timeout;
+ status = response.status;
- ASSERT_FALSE(readRet.isOk());
- ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
- ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
+ ASSERT_TRUE(readRet.isOk());
EXPECT_TRUE(readValue.empty());
EXPECT_EQ(timeout, 0u);
+ EXPECT_EQ(status, WeaverReadStatus::FAILED);
}
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverAidlTest);
diff --git a/wifi/1.6/default/Android.bp b/wifi/1.6/default/Android.bp
index 0f98e71..6038e36 100644
--- a/wifi/1.6/default/Android.bp
+++ b/wifi/1.6/default/Android.bp
@@ -26,6 +26,7 @@
"hidl_feature_disable_ap", // WIFI_HIDL_FEATURE_DISABLE_AP
"hidl_feature_disable_ap_mac_randomization", // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
"avoid_iface_reset_mac_change", // WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ "wifi_skip_state_toggle_off_on_for_nan", // WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
],
value_variables: [
"hal_interface_combinations", // WIFI_HAL_INTERFACE_COMBINATIONS
@@ -53,6 +54,9 @@
avoid_iface_reset_mac_change: {
cppflags: ["-DWIFI_AVOID_IFACE_RESET_MAC_CHANGE"],
},
+ wifi_skip_state_toggle_off_on_for_nan: {
+ cppflags: ["-DWIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN"],
+ },
hal_interface_combinations: {
cppflags: ["-DWIFI_HAL_INTERFACE_COMBINATIONS=%s"],
},
diff --git a/wifi/1.6/default/hal_legacy/AudioHardwareBase.h b/wifi/1.6/default/hal_legacy/AudioHardwareBase.h
new file mode 100644
index 0000000..eb61472
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/AudioHardwareBase.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_HARDWARE_BASE_H
+#define ANDROID_AUDIO_HARDWARE_BASE_H
+
+#include <hardware_legacy/AudioHardwareInterface.h>
+
+#include <system/audio.h>
+
+namespace android_audio_legacy {
+
+// ----------------------------------------------------------------------------
+
+/**
+ * AudioHardwareBase is a convenient base class used for implementing the
+ * AudioHardwareInterface interface.
+ */
+class AudioHardwareBase : public AudioHardwareInterface {
+ public:
+ AudioHardwareBase();
+ virtual ~AudioHardwareBase() {}
+
+ /**
+ * setMode is called when the audio mode changes. NORMAL mode is for
+ * standard audio playback, RINGTONE when a ringtone is playing, IN_CALL
+ * when a telephony call is in progress, IN_COMMUNICATION when a VoIP call is in progress.
+ */
+ virtual status_t setMode(int mode);
+
+ virtual status_t setParameters(const String8& keyValuePairs);
+ virtual String8 getParameters(const String8& keys);
+
+ virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+ virtual status_t getMasterVolume(float* volume);
+
+ /**This method dumps the state of the audio hardware */
+ virtual status_t dumpState(int fd, const Vector<String16>& args);
+
+ protected:
+ /** returns true if the given mode maps to a telephony or VoIP call is in progress */
+ virtual bool isModeInCall(int mode) {
+ return ((mode == AudioSystem::MODE_IN_CALL) ||
+ (mode == AudioSystem::MODE_IN_COMMUNICATION));
+ };
+ /** returns true if a telephony or VoIP call is in progress */
+ virtual bool isInCall() { return isModeInCall(mMode); };
+ int mMode;
+};
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIO_HARDWARE_BASE_H
diff --git a/wifi/1.6/default/hal_legacy/AudioHardwareInterface.h b/wifi/1.6/default/hal_legacy/AudioHardwareInterface.h
new file mode 100644
index 0000000..7befb79
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/AudioHardwareInterface.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_HARDWARE_INTERFACE_H
+#define ANDROID_AUDIO_HARDWARE_INTERFACE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include <hardware_legacy/AudioSystemLegacy.h>
+
+#include <hardware/audio.h>
+#include <system/audio.h>
+
+#include <cutils/bitops.h>
+
+namespace android_audio_legacy {
+using android::String16;
+using android::String8;
+using android::Vector;
+
+// ----------------------------------------------------------------------------
+
+/**
+ * AudioStreamOut is the abstraction interface for the audio output hardware.
+ *
+ * It provides information about various properties of the audio output hardware driver.
+ */
+class AudioStreamOut {
+ public:
+ virtual ~AudioStreamOut() = 0;
+
+ /** return audio sampling rate in hz - eg. 44100 */
+ virtual uint32_t sampleRate() const = 0;
+
+ /** returns size of output buffer - eg. 4800 */
+ virtual size_t bufferSize() const = 0;
+
+ /**
+ * returns the output channel mask
+ */
+ virtual uint32_t channels() const = 0;
+
+ /**
+ * return audio format in 8bit or 16bit PCM format -
+ * eg. AudioSystem:PCM_16_BIT
+ */
+ virtual int format() const = 0;
+
+ /**
+ * return the frame size (number of bytes per sample).
+ */
+ uint32_t frameSize() const {
+ return audio_channel_count_from_out_mask(channels()) *
+ ((format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(int8_t));
+ }
+
+ /**
+ * return the audio hardware driver latency in milli seconds.
+ */
+ virtual uint32_t latency() const = 0;
+
+ /**
+ * Use this method in situations where audio mixing is done in the
+ * hardware. This method serves as a direct interface with hardware,
+ * allowing you to directly set the volume as apposed to via the framework.
+ * This method might produce multiple PCM outputs or hardware accelerated
+ * codecs, such as MP3 or AAC.
+ */
+ virtual status_t setVolume(float left, float right) = 0;
+
+ /** write audio buffer to driver. Returns number of bytes written */
+ virtual ssize_t write(const void* buffer, size_t bytes) = 0;
+
+ /**
+ * Put the audio hardware output into standby mode. Returns
+ * status based on include/utils/Errors.h
+ */
+ virtual status_t standby() = 0;
+
+ /** dump the state of the audio output device */
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+
+ // set/get audio output parameters. The function accepts a list of parameters
+ // key value pairs in the form: key1=value1;key2=value2;...
+ // Some keys are reserved for standard parameters (See AudioParameter class).
+ // If the implementation does not accept a parameter change while the output is
+ // active but the parameter is acceptable otherwise, it must return INVALID_OPERATION.
+ // The audio flinger will put the output in standby and then change the parameter value.
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+
+ // return the number of audio frames written by the audio dsp to DAC since
+ // the output has exited standby
+ virtual status_t getRenderPosition(uint32_t* dspFrames) = 0;
+
+ /**
+ * get the local time at which the next write to the audio driver will be
+ * presented
+ */
+ virtual status_t getNextWriteTimestamp(int64_t* timestamp);
+
+ /**
+ * Return a recent count of the number of audio frames presented to an external observer.
+ */
+ virtual status_t getPresentationPosition(uint64_t* frames, struct timespec* timestamp);
+};
+
+/**
+ * AudioStreamIn is the abstraction interface for the audio input hardware.
+ *
+ * It defines the various properties of the audio hardware input driver.
+ */
+class AudioStreamIn {
+ public:
+ virtual ~AudioStreamIn() = 0;
+
+ /** return audio sampling rate in hz - eg. 44100 */
+ virtual uint32_t sampleRate() const = 0;
+
+ /** return the input buffer size allowed by audio driver */
+ virtual size_t bufferSize() const = 0;
+
+ /** return input channel mask */
+ virtual uint32_t channels() const = 0;
+
+ /**
+ * return audio format in 8bit or 16bit PCM format -
+ * eg. AudioSystem:PCM_16_BIT
+ */
+ virtual int format() const = 0;
+
+ /**
+ * return the frame size (number of bytes per sample).
+ */
+ uint32_t frameSize() const {
+ return audio_channel_count_from_in_mask(channels()) *
+ ((format() == AudioSystem::PCM_16_BIT) ? sizeof(int16_t) : sizeof(int8_t));
+ }
+
+ /** set the input gain for the audio driver. This method is for
+ * for future use */
+ virtual status_t setGain(float gain) = 0;
+
+ /** read audio buffer in from audio driver */
+ virtual ssize_t read(void* buffer, ssize_t bytes) = 0;
+
+ /** dump the state of the audio input device */
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+
+ /**
+ * Put the audio hardware input into standby mode. Returns
+ * status based on include/utils/Errors.h
+ */
+ virtual status_t standby() = 0;
+
+ // set/get audio input parameters. The function accepts a list of parameters
+ // key value pairs in the form: key1=value1;key2=value2;...
+ // Some keys are reserved for standard parameters (See AudioParameter class).
+ // If the implementation does not accept a parameter change while the output is
+ // active but the parameter is acceptable otherwise, it must return INVALID_OPERATION.
+ // The audio flinger will put the input in standby and then change the parameter value.
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+
+ // Return the number of input frames lost in the audio driver since the last call of this
+ // function. Audio driver is expected to reset the value to 0 and restart counting upon
+ // returning the current value by this function call. Such loss typically occurs when the user
+ // space process is blocked longer than the capacity of audio driver buffers. Unit: the number
+ // of input audio frames
+ virtual unsigned int getInputFramesLost() const = 0;
+
+ virtual status_t addAudioEffect(effect_handle_t effect) = 0;
+ virtual status_t removeAudioEffect(effect_handle_t effect) = 0;
+};
+
+/**
+ * AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer.
+ *
+ * The interface supports setting and getting parameters, selecting audio routing
+ * paths, and defining input and output streams.
+ *
+ * AudioFlinger initializes the audio hardware and immediately opens an output stream.
+ * You can set Audio routing to output to handset, speaker, Bluetooth, or a headset.
+ *
+ * The audio input stream is initialized when AudioFlinger is called to carry out
+ * a record operation.
+ */
+class AudioHardwareInterface {
+ public:
+ virtual ~AudioHardwareInterface() {}
+
+ /**
+ * check to see if the audio hardware interface has been initialized.
+ * return status based on values defined in include/utils/Errors.h
+ */
+ virtual status_t initCheck() = 0;
+
+ /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
+ virtual status_t setVoiceVolume(float volume) = 0;
+
+ /**
+ * set the audio volume for all audio activities other than voice call.
+ * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
+ * the software mixer will emulate this capability.
+ */
+ virtual status_t setMasterVolume(float volume) = 0;
+
+ /**
+ * Get the current master volume value for the HAL, if the HAL supports
+ * master volume control. AudioFlinger will query this value from the
+ * primary audio HAL when the service starts and use the value for setting
+ * the initial master volume across all HALs.
+ */
+ virtual status_t getMasterVolume(float* volume) = 0;
+
+ /**
+ * setMode is called when the audio mode changes. NORMAL mode is for
+ * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL
+ * when a call is in progress.
+ */
+ virtual status_t setMode(int mode) = 0;
+
+ // mic mute
+ virtual status_t setMicMute(bool state) = 0;
+ virtual status_t getMicMute(bool* state) = 0;
+
+ // set/get global audio parameters
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual String8 getParameters(const String8& keys) = 0;
+
+ // Returns audio input buffer size according to parameters passed or 0 if one of the
+ // parameters is not supported
+ virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
+
+ /** This method creates and opens the audio hardware output stream */
+ virtual AudioStreamOut* openOutputStream(uint32_t devices, int* format = 0,
+ uint32_t* channels = 0, uint32_t* sampleRate = 0,
+ status_t* status = 0) = 0;
+ virtual AudioStreamOut* openOutputStreamWithFlags(
+ uint32_t devices, audio_output_flags_t flags = (audio_output_flags_t)0, int* format = 0,
+ uint32_t* channels = 0, uint32_t* sampleRate = 0, status_t* status = 0) = 0;
+ virtual void closeOutputStream(AudioStreamOut* out) = 0;
+
+ /** This method creates and opens the audio hardware input stream */
+ virtual AudioStreamIn* openInputStream(uint32_t devices, int* format, uint32_t* channels,
+ uint32_t* sampleRate, status_t* status,
+ AudioSystem::audio_in_acoustics acoustics) = 0;
+ virtual void closeInputStream(AudioStreamIn* in) = 0;
+
+ /**This method dumps the state of the audio hardware */
+ virtual status_t dumpState(int fd, const Vector<String16>& args) = 0;
+
+ virtual status_t setMasterMute(bool muted) = 0;
+
+ static AudioHardwareInterface* create();
+
+ virtual int createAudioPatch(unsigned int num_sources, const struct audio_port_config* sources,
+ unsigned int num_sinks, const struct audio_port_config* sinks,
+ audio_patch_handle_t* handle) = 0;
+
+ virtual int releaseAudioPatch(audio_patch_handle_t handle) = 0;
+
+ virtual int getAudioPort(struct audio_port* port) = 0;
+
+ virtual int setAudioPortConfig(const struct audio_port_config* config) = 0;
+
+ protected:
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+extern "C" AudioHardwareInterface* createAudioHardware(void);
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIO_HARDWARE_INTERFACE_H
diff --git a/wifi/1.6/default/hal_legacy/AudioPolicyInterface.h b/wifi/1.6/default/hal_legacy/AudioPolicyInterface.h
new file mode 100644
index 0000000..ec9c432
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/AudioPolicyInterface.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIOPOLICYINTERFACE_H
+#define ANDROID_AUDIOPOLICYINTERFACE_H
+
+#include <media/AudioSystem.h>
+#include <media/ToneGenerator.h>
+#include <utils/String8.h>
+
+#include <hardware/audio_policy.h>
+#include <hardware_legacy/AudioSystemLegacy.h>
+
+namespace android_audio_legacy {
+using android::String8;
+using android::ToneGenerator;
+using android::Vector;
+
+// ----------------------------------------------------------------------------
+
+// The AudioPolicyInterface and AudioPolicyClientInterface classes define the communication
+// interfaces between the platform specific audio policy manager and Android generic audio policy
+// manager. The platform specific audio policy manager must implement methods of the
+// AudioPolicyInterface class. This implementation makes use of the AudioPolicyClientInterface to
+// control the activity and configuration of audio input and output streams.
+//
+// The platform specific audio policy manager is in charge of the audio routing and volume control
+// policies for a given platform.
+// The main roles of this module are:
+// - keep track of current system state (removable device connections, phone state, user
+// requests...). System state changes and user actions are notified to audio policy manager with
+// methods of the AudioPolicyInterface.
+// - process getOutput() queries received when AudioTrack objects are created: Those queries
+// return a handler on an output that has been selected, configured and opened by the audio policy
+// manager and that must be used by the AudioTrack when registering to the AudioFlinger with the
+// createTrack() method. When the AudioTrack object is released, a putOutput() query is received
+// and the audio policy manager can decide to close or reconfigure the output depending on other
+// streams using this output and current system state.
+// - similarly process getInput() and putInput() queries received from AudioRecord objects and
+// configure audio inputs.
+// - process volume control requests: the stream volume is converted from an index value (received
+// from UI) to a float value applicable to each output as a function of platform specific settings
+// and current output route (destination device). It also make sure that streams are not muted if
+// not allowed (e.g. camera shutter sound in some countries).
+//
+// The platform specific audio policy manager is provided as a shared library by platform vendors
+// (as for libaudio.so) and is linked with libaudioflinger.so
+
+// Audio Policy Manager Interface
+class AudioPolicyInterface {
+ public:
+ virtual ~AudioPolicyInterface() {}
+ //
+ // configuration functions
+ //
+
+ // indicate a change in device connection status
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ const char* device_address) = 0;
+ // retrieve a device connection status
+ virtual AudioSystem::device_connection_state getDeviceConnectionState(
+ audio_devices_t device, const char* device_address) = 0;
+ // indicate a change in phone state. Valid phones states are defined by AudioSystem::audio_mode
+ virtual void setPhoneState(int state) = 0;
+ // force using a specific device category for the specified usage
+ virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) = 0;
+ // retrieve current device category forced for a given usage
+ virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) = 0;
+ // set a system property (e.g. camera sound always audible)
+ virtual void setSystemProperty(const char* property, const char* value) = 0;
+ // check proper initialization
+ virtual status_t initCheck() = 0;
+
+ //
+ // Audio routing query functions
+ //
+
+ // request an output appropriate for playback of the supplied stream type and parameters
+ virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::output_flags flags,
+ const audio_offload_info_t* offloadInfo) = 0;
+ // indicates to the audio policy manager that the output starts being used by corresponding
+ // stream.
+ virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE) = 0;
+ // indicates to the audio policy manager that the output stops being used by corresponding
+ // stream.
+ virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE) = 0;
+ // releases the output.
+ virtual void releaseOutput(audio_io_handle_t output) = 0;
+
+ // request an input appropriate for record from the supplied device with supplied parameters.
+ virtual audio_io_handle_t getInput(int inputSource, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::audio_in_acoustics acoustics) = 0;
+ // indicates to the audio policy manager that the input starts being used.
+ virtual status_t startInput(audio_io_handle_t input) = 0;
+ // indicates to the audio policy manager that the input stops being used.
+ virtual status_t stopInput(audio_io_handle_t input) = 0;
+ // releases the input.
+ virtual void releaseInput(audio_io_handle_t input) = 0;
+
+ //
+ // volume control functions
+ //
+
+ // initialises stream volume conversion parameters by specifying volume index range.
+ virtual void initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax) = 0;
+
+ // sets the new stream volume at a level corresponding to the supplied index for the
+ // supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+ // setting volume for all devices
+ virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index,
+ audio_devices_t device) = 0;
+
+ // retrieve current volume index for the specified stream and the
+ // specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+ // querying the volume of the active device.
+ virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int* index,
+ audio_devices_t device) = 0;
+
+ // return the strategy corresponding to a given stream type
+ virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) = 0;
+
+ // return the enabled output devices for the given stream type
+ virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream) = 0;
+
+ // Audio effect management
+ virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t* desc) = 0;
+ virtual status_t registerEffect(const effect_descriptor_t* desc, audio_io_handle_t io,
+ uint32_t strategy, audio_session_t session, int id) = 0;
+ virtual status_t unregisterEffect(int id) = 0;
+ virtual status_t setEffectEnabled(int id, bool enabled) = 0;
+
+ virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
+ virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const = 0;
+ virtual bool isSourceActive(audio_source_t source) const = 0;
+
+ // dump state
+ virtual status_t dump(int fd) = 0;
+
+ virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo) = 0;
+};
+
+// Audio Policy client Interface
+class AudioPolicyClientInterface {
+ public:
+ virtual ~AudioPolicyClientInterface() {}
+
+ //
+ // Audio HW module functions
+ //
+
+ // loads a HW module.
+ virtual audio_module_handle_t loadHwModule(const char* name) = 0;
+
+ //
+ // Audio output Control functions
+ //
+
+ // opens an audio output with the requested parameters. The parameter values can indicate to use
+ // the default values in case the audio policy manager has no specific requirements for the
+ // output being opened. When the function returns, the parameter values reflect the actual
+ // values used by the audio hardware output stream. The audio policy manager can check if the
+ // proposed parameters are suitable or not and act accordingly.
+ virtual audio_io_handle_t openOutput(audio_module_handle_t module, audio_devices_t* pDevices,
+ uint32_t* pSamplingRate, audio_format_t* pFormat,
+ audio_channel_mask_t* pChannelMask, uint32_t* pLatencyMs,
+ audio_output_flags_t flags,
+ const audio_offload_info_t* offloadInfo = NULL) = 0;
+ // creates a special output that is duplicated to the two outputs passed as arguments. The
+ // duplication is performed by a special mixer thread in the AudioFlinger.
+ virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
+ audio_io_handle_t output2) = 0;
+ // closes the output stream
+ virtual status_t closeOutput(audio_io_handle_t output) = 0;
+ // suspends the output. When an output is suspended, the corresponding audio hardware output
+ // stream is placed in standby and the AudioTracks attached to the mixer thread are still
+ // processed but the output mix is discarded.
+ virtual status_t suspendOutput(audio_io_handle_t output) = 0;
+ // restores a suspended output.
+ virtual status_t restoreOutput(audio_io_handle_t output) = 0;
+
+ //
+ // Audio input Control functions
+ //
+
+ // opens an audio input
+ virtual audio_io_handle_t openInput(audio_module_handle_t module, audio_devices_t* pDevices,
+ uint32_t* pSamplingRate, audio_format_t* pFormat,
+ audio_channel_mask_t* pChannelMask) = 0;
+ // closes an audio input
+ virtual status_t closeInput(audio_io_handle_t input) = 0;
+ //
+ // misc control functions
+ //
+
+ // set a stream volume for a particular output. For the same user setting, a given stream type
+ // can have different volumes for each output (destination device) it is attached to.
+ virtual status_t setStreamVolume(AudioSystem::stream_type stream, float volume,
+ audio_io_handle_t output, int delayMs = 0) = 0;
+
+ // invalidate a stream type, causing a reroute to an unspecified new output
+ virtual status_t invalidateStream(AudioSystem::stream_type stream) = 0;
+
+ // function enabling to send proprietary informations directly from audio policy manager to
+ // audio hardware interface.
+ virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs,
+ int delayMs = 0) = 0;
+ // function enabling to receive proprietary informations directly from audio hardware interface
+ // to audio policy manager.
+ virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) = 0;
+
+ // request the playback of a tone on the specified stream: used for instance to replace
+ // notification sounds when playing over a telephony device during a phone call.
+ virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream) = 0;
+ virtual status_t stopTone() = 0;
+
+ // set down link audio volume.
+ virtual status_t setVoiceVolume(float volume, int delayMs = 0) = 0;
+
+ // move effect to the specified output
+ virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
+ audio_io_handle_t dstOutput) = 0;
+};
+
+extern "C" AudioPolicyInterface* createAudioPolicyManager(
+ AudioPolicyClientInterface* clientInterface);
+extern "C" void destroyAudioPolicyManager(AudioPolicyInterface* interface);
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIOPOLICYINTERFACE_H
diff --git a/wifi/1.6/default/hal_legacy/AudioPolicyManagerBase.h b/wifi/1.6/default/hal_legacy/AudioPolicyManagerBase.h
new file mode 100644
index 0000000..ccc0d32
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/AudioPolicyManagerBase.h
@@ -0,0 +1,567 @@
+/*
+ * Copyright (C) 2009 The Android Open 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 <cutils/config_utils.h>
+#include <cutils/misc.h>
+#include <hardware_legacy/AudioPolicyInterface.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
+#include <utils/Timers.h>
+
+namespace android_audio_legacy {
+using android::DefaultKeyedVector;
+using android::KeyedVector;
+using android::SortedVector;
+
+// ----------------------------------------------------------------------------
+
+#define MAX_DEVICE_ADDRESS_LEN 20
+// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
+#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
+// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
+#define SONIFICATION_HEADSET_VOLUME_MIN 0.016
+// Time in milliseconds during which we consider that music is still active after a music
+// track was stopped - see computeVolume()
+#define SONIFICATION_HEADSET_MUSIC_DELAY 5000
+// Time in milliseconds after media stopped playing during which we consider that the
+// sonification should be as unobtrusive as during the time media was playing.
+#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
+// Time in milliseconds during witch some streams are muted while the audio path
+// is switched
+#define MUTE_TIME_MS 2000
+
+#define NUM_TEST_OUTPUTS 5
+
+#define NUM_VOL_CURVE_KNEES 2
+
+// Default minimum length allowed for offloading a compressed track
+// Can be overridden by the audio.offload.min.duration.secs property
+#define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
+
+// ----------------------------------------------------------------------------
+// AudioPolicyManagerBase implements audio policy manager behavior common to all platforms.
+// Each platform must implement an AudioPolicyManager class derived from AudioPolicyManagerBase
+// and override methods for which the platform specific behavior differs from the implementation
+// in AudioPolicyManagerBase. Even if no specific behavior is required, the AudioPolicyManager
+// class must be implemented as well as the class factory function createAudioPolicyManager()
+// and provided in a shared library libaudiopolicy.so.
+// ----------------------------------------------------------------------------
+
+class AudioPolicyManagerBase : public AudioPolicyInterface
+#ifdef AUDIO_POLICY_TEST
+ ,
+ public Thread
+#endif // AUDIO_POLICY_TEST
+{
+
+ public:
+ AudioPolicyManagerBase(AudioPolicyClientInterface* clientInterface);
+ virtual ~AudioPolicyManagerBase();
+
+ // AudioPolicyInterface
+ virtual status_t setDeviceConnectionState(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ const char* device_address);
+ virtual AudioSystem::device_connection_state getDeviceConnectionState(
+ audio_devices_t device, const char* device_address);
+ virtual void setPhoneState(int state);
+ virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
+ virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
+ virtual void setSystemProperty(const char* property, const char* value);
+ virtual status_t initCheck();
+ virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::output_flags flags,
+ const audio_offload_info_t* offloadInfo);
+ virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE);
+ virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream,
+ audio_session_t session = AUDIO_SESSION_NONE);
+ virtual void releaseOutput(audio_io_handle_t output);
+ virtual audio_io_handle_t getInput(int inputSource, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ AudioSystem::audio_in_acoustics acoustics);
+
+ // indicates to the audio policy manager that the input starts being used.
+ virtual status_t startInput(audio_io_handle_t input);
+
+ // indicates to the audio policy manager that the input stops being used.
+ virtual status_t stopInput(audio_io_handle_t input);
+ virtual void releaseInput(audio_io_handle_t input);
+ virtual void closeAllInputs();
+ virtual void initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax);
+ virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index,
+ audio_devices_t device);
+ virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int* index,
+ audio_devices_t device);
+
+ // return the strategy corresponding to a given stream type
+ virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream);
+
+ // return the enabled output devices for the given stream type
+ virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream);
+
+ virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t* desc = NULL);
+ virtual status_t registerEffect(const effect_descriptor_t* desc, audio_io_handle_t io,
+ uint32_t strategy, audio_session_t session, int id);
+ virtual status_t unregisterEffect(int id);
+ virtual status_t setEffectEnabled(int id, bool enabled);
+
+ virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
+ // return whether a stream is playing remotely, override to change the definition of
+ // local/remote playback, used for instance by notification manager to not make
+ // media players lose audio focus when not playing locally
+ virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const;
+ virtual bool isSourceActive(audio_source_t source) const;
+
+ virtual status_t dump(int fd);
+
+ virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
+
+ protected:
+ enum routing_strategy {
+ STRATEGY_MEDIA,
+ STRATEGY_PHONE,
+ STRATEGY_SONIFICATION,
+ STRATEGY_SONIFICATION_RESPECTFUL,
+ STRATEGY_DTMF,
+ STRATEGY_ENFORCED_AUDIBLE,
+ NUM_STRATEGIES
+ };
+
+ // 4 points to define the volume attenuation curve, each characterized by the volume
+ // index (from 0 to 100) at which they apply, and the attenuation in dB at that index.
+ // we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl()
+
+ enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4 };
+
+ class VolumeCurvePoint {
+ public:
+ int mIndex;
+ float mDBAttenuation;
+ };
+
+ // device categories used for volume curve management.
+ enum device_category {
+ DEVICE_CATEGORY_HEADSET,
+ DEVICE_CATEGORY_SPEAKER,
+ DEVICE_CATEGORY_EARPIECE,
+ DEVICE_CATEGORY_CNT
+ };
+
+ class IOProfile;
+
+ class HwModule {
+ public:
+ HwModule(const char* name);
+ ~HwModule();
+
+ void dump(int fd);
+
+ const char* const mName; // base name of the audio HW module (primary, a2dp ...)
+ audio_module_handle_t mHandle;
+ Vector<IOProfile*> mOutputProfiles; // output profiles exposed by this module
+ Vector<IOProfile*> mInputProfiles; // input profiles exposed by this module
+ };
+
+ // the IOProfile class describes the capabilities of an output or input stream.
+ // It is currently assumed that all combination of listed parameters are supported.
+ // It is used by the policy manager to determine if an output or input is suitable for
+ // a given use case, open/close it accordingly and connect/disconnect audio tracks
+ // to/from it.
+ class IOProfile {
+ public:
+ IOProfile(HwModule* module);
+ ~IOProfile();
+
+ bool isCompatibleProfile(audio_devices_t device, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ audio_output_flags_t flags) const;
+
+ void dump(int fd);
+ void log();
+
+ // by convention, "0' in the first entry in mSamplingRates, mChannelMasks or mFormats
+ // indicates the supported parameters should be read from the output stream
+ // after it is opened for the first time
+ Vector<uint32_t> mSamplingRates; // supported sampling rates
+ Vector<audio_channel_mask_t> mChannelMasks; // supported channel masks
+ Vector<audio_format_t> mFormats; // supported audio formats
+ audio_devices_t mSupportedDevices; // supported devices (devices this output can be
+ // routed to)
+ audio_output_flags_t mFlags; // attribute flags (e.g primary output,
+ // direct output...). For outputs only.
+ HwModule* mModule; // audio HW module exposing this I/O stream
+ };
+
+ // default volume curve
+ static const VolumeCurvePoint sDefaultVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // default volume curve for media strategy
+ static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // volume curve for media strategy on speakers
+ static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // volume curve for sonification strategy on speakers
+ static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint
+ sSpeakerSonificationVolumeCurveDrc[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sDefaultSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sDefaultSystemVolumeCurveDrc[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManagerBase::VOLCNT];
+ // default volume curves per stream and device category. See initializeVolumeCurves()
+ static const VolumeCurvePoint* sVolumeProfiles[AudioSystem::NUM_STREAM_TYPES]
+ [DEVICE_CATEGORY_CNT];
+
+ // descriptor for audio outputs. Used to maintain current configuration of each opened audio
+ // output and keep track of the usage of this output by each audio stream type.
+ class AudioOutputDescriptor {
+ public:
+ AudioOutputDescriptor(const IOProfile* profile);
+
+ status_t dump(int fd);
+
+ audio_devices_t device() const;
+ void changeRefCount(AudioSystem::stream_type stream, int delta);
+
+ bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
+ audio_devices_t supportedDevices();
+ uint32_t latency();
+ bool sharesHwModuleWith(const AudioOutputDescriptor* outputDesc);
+ bool isActive(uint32_t inPastMs = 0) const;
+ bool isStreamActive(AudioSystem::stream_type stream, uint32_t inPastMs = 0,
+ nsecs_t sysTime = 0) const;
+ bool isStrategyActive(routing_strategy strategy, uint32_t inPastMs = 0,
+ nsecs_t sysTime = 0) const;
+
+ audio_io_handle_t mId; // output handle
+ uint32_t mSamplingRate; //
+ audio_format_t mFormat; //
+ audio_channel_mask_t mChannelMask; // output configuration
+ uint32_t mLatency; //
+ audio_output_flags_t mFlags; //
+ audio_devices_t mDevice; // current device this output is routed to
+ uint32_t mRefCount[AudioSystem::NUM_STREAM_TYPES]; // number of streams of each type using
+ // this output
+ nsecs_t mStopTime[AudioSystem::NUM_STREAM_TYPES];
+ AudioOutputDescriptor* mOutput1; // used by duplicated outputs: first output
+ AudioOutputDescriptor* mOutput2; // used by duplicated outputs: second output
+ float mCurVolume[AudioSystem::NUM_STREAM_TYPES]; // current stream volume
+ int mMuteCount[AudioSystem::NUM_STREAM_TYPES]; // mute request counter
+ const IOProfile* mProfile; // I/O profile this output derives from
+ bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
+ // device selection. See
+ // checkDeviceMuteStrategies()
+ uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
+ bool mForceRouting; // Next routing for this output will be forced as current device routed
+ // is null
+ };
+
+ // descriptor for audio inputs. Used to maintain current configuration of each opened audio
+ // input and keep track of the usage of this input.
+ class AudioInputDescriptor {
+ public:
+ AudioInputDescriptor(const IOProfile* profile);
+
+ status_t dump(int fd);
+
+ audio_io_handle_t mId; // input handle
+ uint32_t mSamplingRate; //
+ audio_format_t mFormat; // input configuration
+ audio_channel_mask_t mChannelMask; //
+ audio_devices_t mDevice; // current device this input is routed to
+ uint32_t mRefCount; // number of AudioRecord clients using this output
+ int mInputSource; // input source selected by application (mediarecorder.h)
+ const IOProfile* mProfile; // I/O profile this output derives from
+ };
+
+ // stream descriptor used for volume control
+ class StreamDescriptor {
+ public:
+ StreamDescriptor();
+
+ int getVolumeIndex(audio_devices_t device);
+ void dump(int fd);
+
+ int mIndexMin; // min volume index
+ int mIndexMax; // max volume index
+ KeyedVector<audio_devices_t, int> mIndexCur; // current volume index per device
+ bool mCanBeMuted; // true is the stream can be muted
+
+ const VolumeCurvePoint* mVolumeCurve[DEVICE_CATEGORY_CNT];
+ };
+
+ // stream descriptor used for volume control
+ class EffectDescriptor {
+ public:
+ status_t dump(int fd);
+
+ int mIo; // io the effect is attached to
+ routing_strategy mStrategy; // routing strategy the effect is associated to
+ audio_session_t mSession; // audio session the effect is on
+ effect_descriptor_t mDesc; // effect descriptor
+ bool mEnabled; // enabled state: CPU load being used or not
+ };
+
+ void addOutput(audio_io_handle_t id, AudioOutputDescriptor* outputDesc);
+ void addInput(audio_io_handle_t id, AudioInputDescriptor* inputDesc);
+
+ // return the strategy corresponding to a given stream type
+ static routing_strategy getStrategy(AudioSystem::stream_type stream);
+
+ // return appropriate device for streams handled by the specified strategy according to current
+ // phone state, connected devices...
+ // if fromCache is true, the device is returned from mDeviceForStrategy[],
+ // otherwise it is determine by current state
+ // (device connected,phone state, force use, a2dp output...)
+ // This allows to:
+ // 1 speed up process when the state is stable (when starting or stopping an output)
+ // 2 access to either current device selection (fromCache == true) or
+ // "future" device selection (fromCache == false) when called from a context
+ // where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
+ // before updateDevicesAndOutputs() is called.
+ virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy, bool fromCache);
+
+ // change the route of the specified output. Returns the number of ms we have slept to
+ // allow new routing to take effect in certain cases.
+ uint32_t setOutputDevice(audio_io_handle_t output, audio_devices_t device, bool force = false,
+ int delayMs = 0);
+
+ // select input device corresponding to requested audio source
+ virtual audio_devices_t getDeviceForInputSource(int inputSource);
+
+ // return io handle of active input or 0 if no input is active
+ // Only considers inputs from physical devices (e.g. main mic, headset mic) when
+ // ignoreVirtualInputs is true.
+ audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
+
+ // initialize volume curves for each strategy and device category
+ void initializeVolumeCurves();
+
+ // compute the actual volume for a given stream according to the requested index and a
+ // particular device
+ virtual float computeVolume(int stream, int index, audio_io_handle_t output,
+ audio_devices_t device);
+
+ // check that volume change is permitted, compute and send new volume to audio hardware
+ status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output,
+ audio_devices_t device, int delayMs = 0, bool force = false);
+
+ // apply all stream volumes to the specified output and device
+ void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0,
+ bool force = false);
+
+ // Mute or unmute all streams handled by the specified strategy on the specified output
+ void setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output,
+ int delayMs = 0, audio_devices_t device = (audio_devices_t)0);
+
+ // Mute or unmute the stream on the specified output
+ void setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs = 0,
+ audio_devices_t device = (audio_devices_t)0);
+
+ // handle special cases for sonification strategy while in call: mute streams or replace by
+ // a special tone in the device used for communication
+ void handleIncallSonification(int stream, bool starting, bool stateChange);
+
+ // true if device is in a telephony or VoIP call
+ virtual bool isInCall();
+
+ // true if given state represents a device in a telephony or VoIP call
+ virtual bool isStateInCall(int state);
+
+ // when a device is connected, checks if an open output can be routed
+ // to this device. If none is open, tries to open one of the available outputs.
+ // Returns an output suitable to this device or 0.
+ // when a device is disconnected, checks if an output is not used any more and
+ // returns its handle if any.
+ // transfers the audio tracks and effects from one output thread to another accordingly.
+ status_t checkOutputsForDevice(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ SortedVector<audio_io_handle_t>& outputs,
+ const String8 paramStr);
+
+ status_t checkInputsForDevice(audio_devices_t device,
+ AudioSystem::device_connection_state state,
+ SortedVector<audio_io_handle_t>& inputs, const String8 paramStr);
+
+ // close an output and its companion duplicating output.
+ void closeOutput(audio_io_handle_t output);
+
+ // checks and if necessary changes outputs used for all strategies.
+ // must be called every time a condition that affects the output choice for a given strategy
+ // changes: connected device, phone state, force use...
+ // Must be called before updateDevicesAndOutputs()
+ void checkOutputForStrategy(routing_strategy strategy);
+
+ // Same as checkOutputForStrategy() but for a all strategies in order of priority
+ void checkOutputForAllStrategies();
+
+ // manages A2DP output suspend/restore according to phone state and BT SCO usage
+ void checkA2dpSuspend();
+
+ // returns the A2DP output handle if it is open or 0 otherwise
+ audio_io_handle_t getA2dpOutput();
+
+ // selects the most appropriate device on output for current state
+ // must be called every time a condition that affects the device choice for a given output is
+ // changed: connected device, phone state, force use, output start, output stop..
+ // see getDeviceForStrategy() for the use of fromCache parameter
+
+ audio_devices_t getNewDevice(audio_io_handle_t output, bool fromCache);
+ // updates cache of device used by all strategies (mDeviceForStrategy[])
+ // must be called every time a condition that affects the device choice for a given strategy is
+ // changed: connected device, phone state, force use...
+ // cached values are used by getDeviceForStrategy() if parameter fromCache is true.
+ // Must be called after checkOutputForAllStrategies()
+
+ void updateDevicesAndOutputs();
+
+ virtual uint32_t getMaxEffectsCpuLoad();
+ virtual uint32_t getMaxEffectsMemory();
+#ifdef AUDIO_POLICY_TEST
+ virtual bool threadLoop();
+ void exit();
+ int testOutputIndex(audio_io_handle_t output);
+#endif // AUDIO_POLICY_TEST
+
+ status_t setEffectEnabled(EffectDescriptor* pDesc, bool enabled);
+
+ // returns the category the device belongs to with regard to volume curve management
+ static device_category getDeviceCategory(audio_devices_t device);
+
+ // extract one device relevant for volume control from multiple device selection
+ static audio_devices_t getDeviceForVolume(audio_devices_t device);
+
+ SortedVector<audio_io_handle_t> getOutputsForDevice(
+ audio_devices_t device,
+ DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor*> openOutputs);
+ bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
+ SortedVector<audio_io_handle_t>& outputs2);
+
+ // mute/unmute strategies using an incompatible device combination
+ // if muting, wait for the audio in pcm buffer to be drained before proceeding
+ // if unmuting, unmute only after the specified delay
+ // Returns the number of ms waited
+ uint32_t checkDeviceMuteStrategies(AudioOutputDescriptor* outputDesc,
+ audio_devices_t prevDevice, uint32_t delayMs);
+
+ audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
+ AudioSystem::output_flags flags);
+ IOProfile* getInputProfile(audio_devices_t device, uint32_t samplingRate, audio_format_t format,
+ audio_channel_mask_t channelMask);
+ IOProfile* getProfileForDirectOutput(audio_devices_t device, uint32_t samplingRate,
+ audio_format_t format, audio_channel_mask_t channelMask,
+ audio_output_flags_t flags);
+
+ audio_io_handle_t selectOutputForEffects(const SortedVector<audio_io_handle_t>& outputs);
+
+ bool isNonOffloadableEffectEnabled();
+
+ //
+ // Audio policy configuration file parsing (audio_policy.conf)
+ //
+ static uint32_t stringToEnum(const struct StringToEnum* table, size_t size, const char* name);
+ static bool stringToBool(const char* value);
+ static audio_output_flags_t parseFlagNames(char* name);
+ static audio_devices_t parseDeviceNames(char* name);
+ void loadSamplingRates(char* name, IOProfile* profile);
+ void loadFormats(char* name, IOProfile* profile);
+ void loadOutChannels(char* name, IOProfile* profile);
+ void loadInChannels(char* name, IOProfile* profile);
+ status_t loadOutput(cnode* root, HwModule* module);
+ status_t loadInput(cnode* root, HwModule* module);
+ void loadHwModule(cnode* root);
+ void loadHwModules(cnode* root);
+ void loadGlobalConfig(cnode* root);
+ status_t loadAudioPolicyConfig(const char* path);
+ void defaultAudioPolicyConfig(void);
+
+ AudioPolicyClientInterface* mpClientInterface; // audio policy client interface
+ audio_io_handle_t mPrimaryOutput; // primary output handle
+ // list of descriptors for outputs currently opened
+ DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor*> mOutputs;
+ // copy of mOutputs before setDeviceConnectionState() opens new outputs
+ // reset to mOutputs when updateDevicesAndOutputs() is called.
+ DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor*> mPreviousOutputs;
+
+ // list of input descriptors currently opened
+ DefaultKeyedVector<audio_io_handle_t, AudioInputDescriptor*> mInputs;
+
+ audio_devices_t mAvailableOutputDevices; // bit field of all available output devices
+ audio_devices_t mAvailableInputDevices; // bit field of all available input devices
+ // without AUDIO_DEVICE_BIT_IN to allow direct bit
+ // field comparisons
+ int mPhoneState; // current phone state
+ AudioSystem::forced_config
+ mForceUse[AudioSystem::NUM_FORCE_USE]; // current forced use configuration
+
+ StreamDescriptor
+ mStreams[AudioSystem::NUM_STREAM_TYPES]; // stream descriptors for volume control
+ String8 mA2dpDeviceAddress; // A2DP device MAC address
+ String8 mScoDeviceAddress; // SCO device MAC address
+ String8 mUsbOutCardAndDevice; // USB audio ALSA card and device numbers:
+ // card=<card_number>;device=<><device_number>
+ bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected
+ audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
+ float mLastVoiceVolume; // last voice volume value sent to audio HAL
+
+ // Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
+ static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
+ // Maximum memory allocated to audio effects in KB
+ static const uint32_t MAX_EFFECTS_MEMORY = 512;
+ uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
+ uint32_t mTotalEffectsMemory; // current memory used by effects
+ KeyedVector<int, EffectDescriptor*> mEffects; // list of registered audio effects
+ bool mA2dpSuspended; // true if A2DP output is suspended
+ bool mHasA2dp; // true on platforms with support for bluetooth A2DP
+ bool mHasUsb; // true on platforms with support for USB audio
+ bool mHasRemoteSubmix; // true on platforms with support for remote presentation of a submix
+ audio_devices_t mAttachedOutputDevices; // output devices always available on the platform
+ audio_devices_t mDefaultOutputDevice; // output device selected by default at boot time
+ // (must be in mAttachedOutputDevices)
+ bool mSpeakerDrcEnabled; // true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path
+ // to boost soft sounds, used to adjust volume curves accordingly
+
+ Vector<HwModule*> mHwModules;
+
+#ifdef AUDIO_POLICY_TEST
+ Mutex mLock;
+ Condition mWaitWorkCV;
+
+ int mCurOutput;
+ bool mDirectOutput;
+ audio_io_handle_t mTestOutputs[NUM_TEST_OUTPUTS];
+ int mTestInput;
+ uint32_t mTestDevice;
+ uint32_t mTestSamplingRate;
+ uint32_t mTestFormat;
+ uint32_t mTestChannels;
+ uint32_t mTestLatencyMs;
+#endif // AUDIO_POLICY_TEST
+
+ private:
+ static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
+ int indexInUi);
+ // updates device caching and output for streams that can influence the
+ // routing of notifications
+ void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
+ static bool isVirtualInputDevice(audio_devices_t device);
+};
+
+}; // namespace android_audio_legacy
diff --git a/wifi/1.6/default/hal_legacy/AudioSystemLegacy.h b/wifi/1.6/default/hal_legacy/AudioSystemLegacy.h
new file mode 100644
index 0000000..943b0db
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/AudioSystemLegacy.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIOSYSTEM_LEGACY_H_
+#define ANDROID_AUDIOSYSTEM_LEGACY_H_
+
+#include <cutils/bitops.h>
+#include <media/AudioParameter.h>
+#include <utils/Errors.h>
+
+#include <system/audio.h>
+#include <system/audio_policy.h>
+
+namespace android_audio_legacy {
+
+using android::AudioParameter;
+using android::status_t;
+
+enum {
+ OK = android::OK,
+ NO_ERROR = android::NO_ERROR,
+
+ UNKNOWN_ERROR = android::UNKNOWN_ERROR,
+
+ NO_MEMORY = android::NO_MEMORY,
+ INVALID_OPERATION = android::INVALID_OPERATION,
+ BAD_VALUE = android::BAD_VALUE,
+ BAD_TYPE = android::BAD_TYPE,
+ NAME_NOT_FOUND = android::NAME_NOT_FOUND,
+ PERMISSION_DENIED = android::PERMISSION_DENIED,
+ NO_INIT = android::NO_INIT,
+ ALREADY_EXISTS = android::ALREADY_EXISTS,
+ DEAD_OBJECT = android::DEAD_OBJECT,
+ FAILED_TRANSACTION = android::FAILED_TRANSACTION,
+ BAD_INDEX = android::BAD_INDEX,
+ NOT_ENOUGH_DATA = android::NOT_ENOUGH_DATA,
+ WOULD_BLOCK = android::WOULD_BLOCK,
+ TIMED_OUT = android::TIMED_OUT,
+ UNKNOWN_TRANSACTION = android::UNKNOWN_TRANSACTION,
+};
+
+enum audio_source {
+ AUDIO_SOURCE_DEFAULT = 0,
+ AUDIO_SOURCE_MIC = 1,
+ AUDIO_SOURCE_VOICE_UPLINK = 2,
+ AUDIO_SOURCE_VOICE_DOWNLINK = 3,
+ AUDIO_SOURCE_VOICE_CALL = 4,
+ AUDIO_SOURCE_CAMCORDER = 5,
+ AUDIO_SOURCE_VOICE_RECOGNITION = 6,
+ AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
+ AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_COMMUNICATION,
+
+ AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type
+};
+
+class AudioSystem {
+ public:
+#if 1
+ enum stream_type {
+ DEFAULT = -1,
+ VOICE_CALL = 0,
+ SYSTEM = 1,
+ RING = 2,
+ MUSIC = 3,
+ ALARM = 4,
+ NOTIFICATION = 5,
+ BLUETOOTH_SCO = 6,
+ ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker
+ DTMF = 8,
+ TTS = 9,
+ NUM_STREAM_TYPES
+ };
+
+ // Audio sub formats (see AudioSystem::audio_format).
+ enum pcm_sub_format {
+ PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility
+ PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility
+ };
+
+ enum audio_sessions {
+ SESSION_OUTPUT_STAGE = AUDIO_SESSION_OUTPUT_STAGE,
+ SESSION_OUTPUT_MIX = AUDIO_SESSION_OUTPUT_MIX,
+ };
+
+ // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to
+ // specify bit rate, stereo mode, version...
+ enum mp3_sub_format {
+ // TODO
+ };
+
+ // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient
+ // or octet aligned, encoding mode for recording...
+ enum amr_sub_format {
+ // TODO
+ };
+
+ // AAC sub format field definition: specify profile or bitrate for recording...
+ enum aac_sub_format {
+ // TODO
+ };
+
+ // VORBIS sub format field definition: specify quality for recording...
+ enum vorbis_sub_format {
+ // TODO
+ };
+
+ // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24
+ // bits). The main format indicates the main codec type. The sub format field indicates options
+ // and parameters for each format. The sub format is mainly used for record to indicate for
+ // instance the requested bitrate or profile. It can also be used for certain formats to give
+ // informations not present in the encoded audio stream (e.g. octet alignement for AMR).
+ enum audio_format {
+ INVALID_FORMAT = -1,
+ FORMAT_DEFAULT = 0,
+ PCM = 0x00000000, // must be 0 for backward compatibility
+ MP3 = 0x01000000,
+ AMR_NB = 0x02000000,
+ AMR_WB = 0x03000000,
+ AAC = 0x04000000,
+ HE_AAC_V1 = 0x05000000,
+ HE_AAC_V2 = 0x06000000,
+ VORBIS = 0x07000000,
+ MAIN_FORMAT_MASK = 0xFF000000,
+ SUB_FORMAT_MASK = 0x00FFFFFF,
+ // Aliases
+ PCM_16_BIT = (PCM | PCM_SUB_16_BIT),
+ PCM_8_BIT = (PCM | PCM_SUB_8_BIT)
+ };
+
+ enum audio_channels {
+ // output channels
+ CHANNEL_OUT_FRONT_LEFT = 0x1,
+ CHANNEL_OUT_FRONT_RIGHT = 0x2,
+ CHANNEL_OUT_FRONT_CENTER = 0x4,
+ CHANNEL_OUT_LOW_FREQUENCY = 0x8,
+ CHANNEL_OUT_BACK_LEFT = 0x10,
+ CHANNEL_OUT_BACK_RIGHT = 0x20,
+ CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40,
+ CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80,
+ CHANNEL_OUT_BACK_CENTER = 0x100,
+ CHANNEL_OUT_SIDE_LEFT = 0x200,
+ CHANNEL_OUT_SIDE_RIGHT = 0x400,
+ CHANNEL_OUT_TOP_CENTER = 0x800,
+ CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000,
+ CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000,
+ CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000,
+ CHANNEL_OUT_TOP_BACK_LEFT = 0x8000,
+ CHANNEL_OUT_TOP_BACK_CENTER = 0x10000,
+ CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000,
+
+ CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT,
+ CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT),
+ CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
+ CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+ CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER),
+ CHANNEL_OUT_5POINT1 =
+ (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER |
+ CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT),
+ // matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND definition for 7.1
+ CHANNEL_OUT_7POINT1 =
+ (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER |
+ CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+ CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT),
+ CHANNEL_OUT_ALL =
+ (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | CHANNEL_OUT_FRONT_CENTER |
+ CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+ CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
+ CHANNEL_OUT_BACK_CENTER | CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT |
+ CHANNEL_OUT_TOP_CENTER | CHANNEL_OUT_TOP_FRONT_LEFT |
+ CHANNEL_OUT_TOP_FRONT_CENTER | CHANNEL_OUT_TOP_FRONT_RIGHT |
+ CHANNEL_OUT_TOP_BACK_LEFT | CHANNEL_OUT_TOP_BACK_CENTER |
+ CHANNEL_OUT_TOP_BACK_RIGHT),
+
+ // input channels
+ CHANNEL_IN_LEFT = 0x4,
+ CHANNEL_IN_RIGHT = 0x8,
+ CHANNEL_IN_FRONT = 0x10,
+ CHANNEL_IN_BACK = 0x20,
+ CHANNEL_IN_LEFT_PROCESSED = 0x40,
+ CHANNEL_IN_RIGHT_PROCESSED = 0x80,
+ CHANNEL_IN_FRONT_PROCESSED = 0x100,
+ CHANNEL_IN_BACK_PROCESSED = 0x200,
+ CHANNEL_IN_PRESSURE = 0x400,
+ CHANNEL_IN_X_AXIS = 0x800,
+ CHANNEL_IN_Y_AXIS = 0x1000,
+ CHANNEL_IN_Z_AXIS = 0x2000,
+ CHANNEL_IN_VOICE_UPLINK = 0x4000,
+ CHANNEL_IN_VOICE_DNLINK = 0x8000,
+ CHANNEL_IN_MONO = CHANNEL_IN_FRONT,
+ CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT),
+ CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK |
+ CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED |
+ CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED |
+ CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS |
+ CHANNEL_IN_Z_AXIS | CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK)
+ };
+
+ enum audio_mode {
+ MODE_INVALID = -2,
+ MODE_CURRENT = -1,
+ MODE_NORMAL = 0,
+ MODE_RINGTONE,
+ MODE_IN_CALL,
+ MODE_IN_COMMUNICATION,
+ NUM_MODES // not a valid entry, denotes end-of-list
+ };
+
+ enum audio_in_acoustics {
+ AGC_ENABLE = 0x0001,
+ AGC_DISABLE = 0,
+ NS_ENABLE = 0x0002,
+ NS_DISABLE = 0,
+ TX_IIR_ENABLE = 0x0004,
+ TX_DISABLE = 0
+ };
+
+ // DO NOT USE: the "audio_devices" enumeration below is obsolete, use type "audio_devices_t" and
+ // audio device enumeration from system/audio.h instead.
+ enum audio_devices {
+ // output devices
+ DEVICE_OUT_EARPIECE = 0x1,
+ DEVICE_OUT_SPEAKER = 0x2,
+ DEVICE_OUT_WIRED_HEADSET = 0x4,
+ DEVICE_OUT_WIRED_HEADPHONE = 0x8,
+ DEVICE_OUT_BLUETOOTH_SCO = 0x10,
+ DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
+ DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
+ DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
+ DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
+ DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
+ DEVICE_OUT_AUX_DIGITAL = 0x400,
+ DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
+ DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
+ DEVICE_OUT_DEFAULT = 0x8000,
+ DEVICE_OUT_ALL =
+ (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET |
+ DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO |
+ DEVICE_OUT_BLUETOOTH_SCO_HEADSET | DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
+ DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+ DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL |
+ DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET | DEVICE_OUT_DEFAULT),
+ DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+ DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
+
+ // input devices
+ DEVICE_IN_COMMUNICATION = 0x10000,
+ DEVICE_IN_AMBIENT = 0x20000,
+ DEVICE_IN_BUILTIN_MIC = 0x40000,
+ DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000,
+ DEVICE_IN_WIRED_HEADSET = 0x100000,
+ DEVICE_IN_AUX_DIGITAL = 0x200000,
+ DEVICE_IN_VOICE_CALL = 0x400000,
+ DEVICE_IN_BACK_MIC = 0x800000,
+ DEVICE_IN_DEFAULT = 0x80000000,
+
+ DEVICE_IN_ALL =
+ (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC |
+ DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL |
+ DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT)
+ };
+
+ // request to open a direct output with getOutput() (by opposition to sharing an output with
+ // other AudioTracks)
+ enum output_flags { OUTPUT_FLAG_INDIRECT = 0x0, OUTPUT_FLAG_DIRECT = 0x1 };
+
+ // device categories used for setForceUse()
+ enum forced_config {
+ FORCE_NONE,
+ FORCE_SPEAKER,
+ FORCE_HEADPHONES,
+ FORCE_BT_SCO,
+ FORCE_BT_A2DP,
+ FORCE_WIRED_ACCESSORY,
+ FORCE_BT_CAR_DOCK,
+ FORCE_BT_DESK_DOCK,
+ FORCE_ANALOG_DOCK,
+ FORCE_DIGITAL_DOCK,
+ FORCE_NO_BT_A2DP,
+ FORCE_SYSTEM_ENFORCED,
+ NUM_FORCE_CONFIG,
+ FORCE_DEFAULT = FORCE_NONE
+ };
+
+ // usages used for setForceUse()
+ enum force_use {
+ FOR_COMMUNICATION,
+ FOR_MEDIA,
+ FOR_RECORD,
+ FOR_DOCK,
+ FOR_SYSTEM,
+ NUM_FORCE_USE
+ };
+
+ //
+ // AudioPolicyService interface
+ //
+
+ // device connection states used for setDeviceConnectionState()
+ enum device_connection_state {
+ DEVICE_STATE_UNAVAILABLE,
+ DEVICE_STATE_AVAILABLE,
+ NUM_DEVICE_STATES
+ };
+
+#endif
+
+ static uint32_t popCount(uint32_t u) { return popcount(u); }
+
+#if 1
+ static bool isOutputDevice(audio_devices device) {
+ if ((popcount(device) == 1) && ((device & ~DEVICE_OUT_ALL) == 0))
+ return true;
+ else
+ return false;
+ }
+ static bool isInputDevice(audio_devices device) {
+ if ((popcount(device) == 1) && ((device & ~DEVICE_IN_ALL) == 0))
+ return true;
+ else
+ return false;
+ }
+ static bool isA2dpDevice(audio_devices device) {
+ return audio_is_a2dp_device((audio_devices_t)device);
+ }
+ static bool isBluetoothScoDevice(audio_devices device) {
+ return audio_is_bluetooth_sco_device((audio_devices_t)device);
+ }
+ static bool isValidFormat(uint32_t format) {
+ return audio_is_valid_format((audio_format_t)format);
+ }
+ static bool isLinearPCM(uint32_t format) { return audio_is_linear_pcm((audio_format_t)format); }
+ static bool isOutputChannel(audio_channel_mask_t channel) {
+ return audio_is_output_channel(channel);
+ }
+ static bool isInputChannel(audio_channel_mask_t channel) {
+ return audio_is_input_channel(channel);
+ }
+
+#endif
+};
+
+}; // namespace android_audio_legacy
+
+#endif // ANDROID_AUDIOSYSTEM_LEGACY_H_
diff --git a/wifi/1.6/default/hal_legacy/IMountService.h b/wifi/1.6/default/hal_legacy/IMountService.h
new file mode 100644
index 0000000..158ff59
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/IMountService.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+#ifndef ANDROID_HARDWARE_IMOUNTSERVICE_H
+#define ANDROID_HARDWARE_IMOUNTSERVICE_H
+
+#include <binder/IInterface.h>
+#include <utils/String16.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IMountService : public IInterface {
+ public:
+ static const int OperationSucceeded = 0;
+ static const int OperationFailedInternalError = -1;
+ static const int OperationFailedNoMedia = -2;
+ static const int OperationFailedMediaBlank = -3;
+ static const int OperationFailedMediaCorrupt = -4;
+ static const int OperationFailedVolumeNotMounted = -5;
+
+ public:
+ DECLARE_META_INTERFACE(MountService);
+
+ virtual void getShareMethodList() = 0;
+ virtual bool getShareMethodAvailable(String16 method) = 0;
+ virtual int shareVolume(String16 path, String16 method) = 0;
+ virtual int unshareVolume(String16 path, String16 method) = 0;
+ virtual bool getVolumeShared(String16 path, String16 method) = 0;
+ virtual int mountVolume(String16 path) = 0;
+ virtual int unmountVolume(String16 path) = 0;
+ virtual int formatVolume(String16 path) = 0;
+ virtual String16 getVolumeState(String16 mountPoint) = 0;
+ virtual int createSecureContainer(String16 id, int sizeMb, String16 fstype, String16 key,
+ int ownerUid) = 0;
+ virtual int finalizeSecureContainer(String16 id) = 0;
+ virtual int destroySecureContainer(String16 id) = 0;
+ virtual int mountSecureContainer(String16 id, String16 key, int ownerUid) = 0;
+ virtual int unmountSecureContainer(String16 id) = 0;
+ virtual int renameSecureContainer(String16 oldId, String16 newId) = 0;
+ virtual String16 getSecureContainerPath(String16 id) = 0;
+ virtual void getSecureContainerList() = 0;
+ virtual void shutdown() = 0;
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_HARDWARE_IMOUNTSERVICE_H
diff --git a/wifi/1.6/default/hal_legacy/audio_policy_conf.h b/wifi/1.6/default/hal_legacy/audio_policy_conf.h
new file mode 100644
index 0000000..13d62f9
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/audio_policy_conf.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_AUDIO_POLICY_CONF_H
+#define ANDROID_AUDIO_POLICY_CONF_H
+
+/////////////////////////////////////////////////
+// Definitions for audio policy configuration file (audio_policy.conf)
+/////////////////////////////////////////////////
+
+#define AUDIO_HARDWARE_MODULE_ID_MAX_LEN 32
+
+#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
+#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"
+
+// global configuration
+#define GLOBAL_CONFIG_TAG "global_configuration"
+
+#define ATTACHED_OUTPUT_DEVICES_TAG "attached_output_devices"
+#define DEFAULT_OUTPUT_DEVICE_TAG "default_output_device"
+#define ATTACHED_INPUT_DEVICES_TAG "attached_input_devices"
+#define SPEAKER_DRC_ENABLED_TAG "speaker_drc_enabled"
+
+// hw modules descriptions
+#define AUDIO_HW_MODULE_TAG "audio_hw_modules"
+
+#define OUTPUTS_TAG "outputs"
+#define INPUTS_TAG "inputs"
+
+#define SAMPLING_RATES_TAG "sampling_rates"
+#define FORMATS_TAG "formats"
+#define CHANNELS_TAG "channel_masks"
+#define DEVICES_TAG "devices"
+#define FLAGS_TAG "flags"
+
+#define DYNAMIC_VALUE_TAG \
+ "dynamic" // special value for "channel_masks", "sampling_rates" and
+ // "formats" in outputs descriptors indicating that supported
+ // values should be queried after opening the output.
+
+#endif // ANDROID_AUDIO_POLICY_CONF_H
diff --git a/wifi/1.6/default/hal_legacy/gscan.h b/wifi/1.6/default/hal_legacy/gscan.h
new file mode 100644
index 0000000..c6c52c6
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/gscan.h
@@ -0,0 +1,427 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_GSCAN_H__
+#define __WIFI_HAL_GSCAN_H__
+
+// Define static_assert() unless already defined by compiler.
+#ifndef __has_feature
+#define __has_feature(__x) 0
+#endif
+#if !(__has_feature(cxx_static_assert)) && !defined(static_assert)
+#define static_assert(__b, __m) \
+ extern int compile_time_assert_failed[(__b) ? 1 : -1] __attribute__((unused));
+#endif
+
+/* AP Scans */
+
+typedef enum {
+ WIFI_BAND_UNSPECIFIED,
+ WIFI_BAND_BG = 1, // 2.4 GHz
+ WIFI_BAND_A = 2, // 5 GHz without DFS
+ WIFI_BAND_A_DFS = 4, // 5 GHz DFS only
+ WIFI_BAND_A_WITH_DFS = 6, // 5 GHz with DFS
+ WIFI_BAND_ABG = 3, // 2.4 GHz + 5 GHz; no DFS
+ WIFI_BAND_ABG_WITH_DFS = 7, // 2.4 GHz + 5 GHz with DFS
+} wifi_band;
+
+#define MAX_CHANNELS 16
+#define MAX_BUCKETS 16
+#define MAX_HOTLIST_APS 128
+#define MAX_SIGNIFICANT_CHANGE_APS 64
+#define MAX_EPNO_NETWORKS 64
+#define MAX_HOTLIST_SSID 8
+#define MAX_AP_CACHE_PER_SCAN 32
+
+wifi_error wifi_get_valid_channels(wifi_interface_handle handle, int band, int max_channels,
+ wifi_channel* channels, int* num_channels);
+
+typedef struct {
+ int max_scan_cache_size; // total space allocated for scan (in bytes)
+ int max_scan_buckets; // maximum number of channel buckets
+ int max_ap_cache_per_scan; // maximum number of APs that can be stored per scan
+ int max_rssi_sample_size; // number of RSSI samples used for averaging RSSI
+ int max_scan_reporting_threshold; // max possible report_threshold as described
+ // in wifi_scan_cmd_params
+ int max_hotlist_bssids; // maximum number of entries for hotlist BSSIDs
+ int max_hotlist_ssids; // maximum number of entries for hotlist SSIDs
+ int max_significant_wifi_change_aps; // maximum number of entries for
+ // significant wifi change APs
+ int max_bssid_history_entries; // number of BSSID/RSSI entries that device can hold
+ int max_number_epno_networks; // max number of epno entries
+ int max_number_epno_networks_by_ssid; // max number of epno entries if ssid is specified,
+ // that is, epno entries for which an exact match is
+ // required, or entries corresponding to hidden ssids
+ int max_number_of_white_listed_ssid; // max number of white listed SSIDs, M target is 2 to 4
+} wifi_gscan_capabilities;
+
+wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle,
+ wifi_gscan_capabilities* capabilities);
+
+typedef enum {
+ WIFI_SCAN_RESULTS_AVAILABLE, // reported when REPORT_EVENTS_EACH_SCAN is set and a scan
+ // completes. WIFI_SCAN_THRESHOLD_NUM_SCANS or
+ // WIFI_SCAN_THRESHOLD_PERCENT can be reported instead if the
+ // reason for the event is available; however, at most one of
+ // these events should be reported per scan. If there are
+ // multiple buckets that were scanned this period and one has the
+ // EACH_SCAN flag set then this event should be prefered.
+ WIFI_SCAN_THRESHOLD_NUM_SCANS, // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+ // report_threshold_num_scans is reached.
+ WIFI_SCAN_THRESHOLD_PERCENT, // can be reported when REPORT_EVENTS_EACH_SCAN is not set and
+ // report_threshold_percent is reached.
+ WIFI_SCAN_FAILED, // reported when currently executing gscans have failed.
+ // start_gscan will need to be called again in order to continue
+ // scanning. This is intended to indicate abnormal scan
+ // terminations (not those as a result of stop_gscan).
+} wifi_scan_event;
+
+/* Format of information elements found in the beacon */
+typedef struct {
+ byte id; // element identifier
+ byte len; // number of bytes to follow
+ byte data[];
+} wifi_information_element;
+
+typedef struct {
+ wifi_timestamp ts; // time since boot (in microsecond) when the result was
+ // retrieved
+ char ssid[32 + 1]; // null terminated
+ mac_addr bssid;
+ wifi_channel channel; // channel frequency in MHz
+ wifi_rssi rssi; // in db
+ wifi_timespan rtt; // in nanoseconds
+ wifi_timespan rtt_sd; // standard deviation in rtt
+ unsigned short beacon_period; // period advertised in the beacon
+ unsigned short capability; // capabilities advertised in the beacon
+ unsigned int ie_length; // size of the ie_data blob
+ char ie_data[1]; // blob of all the information elements found in the
+ // beacon; this data should be a packed list of
+ // wifi_information_element objects, one after the other.
+ // other fields
+} wifi_scan_result;
+
+static_assert(
+ MAX_BUCKETS <= 8 * sizeof(unsigned),
+ "The buckets_scanned bitset is represented by an unsigned int and cannot support this many "
+ "buckets on this platform.");
+typedef struct {
+ /* reported when each probe response is received, if report_events
+ * enabled in wifi_scan_cmd_params. buckets_scanned is a bitset of the
+ * buckets that are currently being scanned. See the buckets_scanned field
+ * in the wifi_cached_scan_results struct for more details.
+ */
+ void (*on_full_scan_result)(wifi_request_id id, wifi_scan_result* result,
+ unsigned buckets_scanned);
+
+ /* indicates progress of scanning statemachine */
+ void (*on_scan_event)(wifi_request_id id, wifi_scan_event event);
+
+} wifi_scan_result_handler;
+
+typedef struct {
+ wifi_channel channel; // frequency
+ int dwellTimeMs; // dwell time hint
+ int passive; // 0 => active, 1 => passive scan; ignored for DFS
+ /* Add channel class */
+} wifi_scan_channel_spec;
+
+#define REPORT_EVENTS_EACH_SCAN (1 << 0)
+#define REPORT_EVENTS_FULL_RESULTS (1 << 1)
+#define REPORT_EVENTS_NO_BATCH (1 << 2)
+
+typedef struct {
+ int bucket; // bucket index, 0 based
+ wifi_band band; // when UNSPECIFIED, use channel list
+ int period; // desired period, in millisecond; if this is too
+ // low, the firmware should choose to generate results as
+ // fast as it can instead of failing the command.
+ // for exponential backoff bucket this is the min_period
+ /* report_events semantics -
+ * This is a bit field; which defines following bits -
+ * REPORT_EVENTS_EACH_SCAN => report a scan completion event after scan. If this is not set
+ * then scan completion events should be reported if
+ * report_threshold_percent or report_threshold_num_scans is
+ * reached.
+ * REPORT_EVENTS_FULL_RESULTS => forward scan results (beacons/probe responses + IEs)
+ * in real time to HAL, in addition to completion events
+ * Note: To keep backward compatibility, fire completion
+ * events regardless of REPORT_EVENTS_EACH_SCAN.
+ * REPORT_EVENTS_NO_BATCH => controls if scans for this bucket should be placed in the
+ * history buffer
+ */
+ byte report_events;
+ int max_period; // if max_period is non zero or different than period, then this bucket is
+ // an exponential backoff bucket and the scan period will grow exponentially
+ // as per formula: actual_period(N) = period * (base ^ (N/step_count))
+ // to a maximum period of max_period
+ int base; // for exponential back off bucket: multiplier: new_period=old_period*base
+ int step_count; // for exponential back off bucket, number of scans to perform for a given
+ // period
+
+ int num_channels;
+ // channels to scan; these may include DFS channels
+ // Note that a given channel may appear in multiple buckets
+ wifi_scan_channel_spec channels[MAX_CHANNELS];
+} wifi_scan_bucket_spec;
+
+typedef struct {
+ int base_period; // base timer period in ms
+ int max_ap_per_scan; // number of access points to store in each scan entry in
+ // the BSSID/RSSI history buffer (keep the highest RSSI
+ // access points)
+ int report_threshold_percent; // in %, when scan buffer is this much full, wake up apps
+ // processor
+ int report_threshold_num_scans; // in number of scans, wake up AP after these many scans
+ int num_buckets;
+ wifi_scan_bucket_spec buckets[MAX_BUCKETS];
+} wifi_scan_cmd_params;
+
+/*
+ * Start periodic GSCAN
+ * When this is called all requested buckets should be scanned, starting the beginning of the cycle
+ *
+ * For example:
+ * If there are two buckets specified
+ * - Bucket 1: period=10s
+ * - Bucket 2: period=20s
+ * - Bucket 3: period=30s
+ * Then the following scans should occur
+ * - t=0 buckets 1, 2, and 3 are scanned
+ * - t=10 bucket 1 is scanned
+ * - t=20 bucket 1 and 2 are scanned
+ * - t=30 bucket 1 and 3 are scanned
+ * - t=40 bucket 1 and 2 are scanned
+ * - t=50 bucket 1 is scanned
+ * - t=60 buckets 1, 2, and 3 are scanned
+ * - and the patter repeats
+ *
+ * If any scan does not occur or is incomplete (error, interrupted, etc) then a cached scan result
+ * should still be recorded with the WIFI_SCAN_FLAG_INTERRUPTED flag set.
+ */
+wifi_error wifi_start_gscan(wifi_request_id id, wifi_interface_handle iface,
+ wifi_scan_cmd_params params, wifi_scan_result_handler handler);
+
+/* Stop periodic GSCAN */
+wifi_error wifi_stop_gscan(wifi_request_id id, wifi_interface_handle iface);
+
+typedef enum {
+ WIFI_SCAN_FLAG_INTERRUPTED = 1 // Indicates that scan results are not complete because
+ // probes were not sent on some channels
+} wifi_scan_flags;
+
+/* Get the GSCAN cached scan results */
+typedef struct {
+ int scan_id; // a unique identifier for the scan unit
+ int flags; // a bitmask with additional
+ // information about scan.
+ unsigned buckets_scanned; // a bitset of the buckets that were scanned.
+ // for example a value of 13 (0b1101) would
+ // indicate that buckets 0, 2 and 3 were
+ // scanned to produce this list of results.
+ // should be set to 0 if this information is
+ // not available.
+ int num_results; // number of bssids retrieved by the scan
+ wifi_scan_result results[MAX_AP_CACHE_PER_SCAN]; // scan results - one for each bssid
+} wifi_cached_scan_results;
+
+wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, byte flush, int max,
+ wifi_cached_scan_results* results, int* num);
+
+/* BSSID Hotlist */
+typedef struct {
+ void (*on_hotlist_ap_found)(wifi_request_id id, unsigned num_results,
+ wifi_scan_result* results);
+ void (*on_hotlist_ap_lost)(wifi_request_id id, unsigned num_results, wifi_scan_result* results);
+} wifi_hotlist_ap_found_handler;
+
+typedef struct {
+ mac_addr bssid; // AP BSSID
+ wifi_rssi low; // low threshold
+ wifi_rssi high; // high threshold
+} ap_threshold_param;
+
+typedef struct {
+ int lost_ap_sample_size;
+ int num_bssid; // number of hotlist APs
+ ap_threshold_param ap[MAX_HOTLIST_APS]; // hotlist APs
+} wifi_bssid_hotlist_params;
+
+/* Set the BSSID Hotlist */
+wifi_error wifi_set_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface,
+ wifi_bssid_hotlist_params params,
+ wifi_hotlist_ap_found_handler handler);
+
+/* Clear the BSSID Hotlist */
+wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, wifi_interface_handle iface);
+
+/* SSID Hotlist */
+typedef struct {
+ void (*on_hotlist_ssid_found)(wifi_request_id id, unsigned num_results,
+ wifi_scan_result* results);
+ void (*on_hotlist_ssid_lost)(wifi_request_id id, unsigned num_results,
+ wifi_scan_result* results);
+} wifi_hotlist_ssid_handler;
+
+typedef struct {
+ char ssid[32 + 1]; // SSID
+ wifi_band band; // band for this set of threshold params
+ wifi_rssi low; // low threshold
+ wifi_rssi high; // high threshold
+} ssid_threshold_param;
+
+typedef struct {
+ int lost_ssid_sample_size;
+ int num_ssid; // number of hotlist SSIDs
+ ssid_threshold_param ssid[MAX_HOTLIST_SSID]; // hotlist SSIDs
+} wifi_ssid_hotlist_params;
+
+/* Significant wifi change */
+typedef struct {
+ mac_addr bssid; // BSSID
+ wifi_channel channel; // channel frequency in MHz
+ int num_rssi; // number of rssi samples
+ wifi_rssi rssi[]; // RSSI history in db
+} wifi_significant_change_result;
+
+typedef struct {
+ void (*on_significant_change)(wifi_request_id id, unsigned num_results,
+ wifi_significant_change_result** results);
+} wifi_significant_change_handler;
+
+// The sample size parameters in the wifi_significant_change_params structure
+// represent the number of occurence of a g-scan where the BSSID was seen and RSSI was
+// collected for that BSSID, or, the BSSID was expected to be seen and didn't.
+// for instance: lost_ap_sample_size : number of time a g-scan was performed on the
+// channel the BSSID was seen last, and the BSSID was not seen during those g-scans
+typedef struct {
+ int rssi_sample_size; // number of samples for averaging RSSI
+ int lost_ap_sample_size; // number of samples to confirm AP loss
+ int min_breaching; // number of APs breaching threshold
+ int num_bssid; // max 64
+ ap_threshold_param ap[MAX_SIGNIFICANT_CHANGE_APS];
+} wifi_significant_change_params;
+
+/* Set the Signifcant AP change list */
+wifi_error wifi_set_significant_change_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_significant_change_params params,
+ wifi_significant_change_handler handler);
+
+/* Clear the Signifcant AP change list */
+wifi_error wifi_reset_significant_change_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/* Random MAC OUI for PNO */
+wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui);
+
+// Enhanced PNO:
+// Enhanced PNO feature is expected to be enabled all of the time (e.g. screen lit) and may thus
+// require firmware to store a large number of networks, covering the whole list of known networks.
+// Therefore, it is acceptable for firmware to store a crc24, crc32 or other short hash of the SSID,
+// such that a low but non-zero probability of collision exist. With that scheme it should be
+// possible for firmware to keep an entry as small as 4 bytes for each pno network.
+// For instance, a firmware pn0 entry can be implemented in the form of:
+// PNO ENTRY = crc24(3 bytes) | flags>>3 (5 bits) | auth flags(3 bits)
+//
+// No scans should be automatically performed by the chip. Instead all scan results from gscan
+// should be scored and the wifi_epno_handler on_network_found callback should be called with
+// the scan results.
+//
+// A PNO network shall be reported once, that is, once a network is reported by firmware
+// its entry shall be marked as "done" until framework calls wifi_set_epno_list again.
+// Calling wifi_set_epno_list shall reset the "done" status of pno networks in firmware.
+//
+// A network should only be considered found if its RSSI is above the minimum RSSI for its
+// frequency range (min5GHz_rssi and min24GHz_rssi for 5GHz and 2.4GHz networks respectively).
+// When disconnected the list of scan results should be returned if any network is found.
+// When connected the scan results shall be reported only if the score of any network in the scan
+// is greater than that of the currently connected BSSID.
+//
+// The FW should calculate the score of all the candidates (including currently connected one)
+// with following equation:
+// RSSI score = (RSSI + 85) * 4;
+// If RSSI score > initial_score_max , RSSI score = initial_score_max;
+// final score = RSSI score
+// + current_connection_bonus (if currently connected BSSID)
+// + same_network_bonus (if network has SAME_NETWORK flag)
+// + secure_bonus (if the network is not open)
+// + band5GHz_bonus (if BSSID is on 5G)
+// If there is a BSSID’s score > current BSSID’s score, then report the cached scan results
+// at the end of the scan (excluding the ones on blacklist) to the upper layer.
+// Additionally, all BSSIDs that are in the BSSID blacklist should be ignored by Enhanced PNO
+
+// Whether directed scan needs to be performed (for hidden SSIDs)
+#define WIFI_PNO_FLAG_DIRECTED_SCAN (1 << 0)
+// Whether PNO event shall be triggered if the network is found on A band
+#define WIFI_PNO_FLAG_A_BAND (1 << 1)
+// Whether PNO event shall be triggered if the network is found on G band
+#define WIFI_PNO_FLAG_G_BAND (1 << 2)
+// Whether strict matching is required
+// If required then the firmware must store the network's SSID and not just a hash
+#define WIFI_PNO_FLAG_STRICT_MATCH (1 << 3)
+// If this SSID should be considered the same network as the currently connected one for scoring
+#define WIFI_PNO_FLAG_SAME_NETWORK (1 << 4)
+
+// Code for matching the beacon AUTH IE - additional codes TBD
+#define WIFI_PNO_AUTH_CODE_OPEN (1 << 0) // open
+#define WIFI_PNO_AUTH_CODE_PSK (1 << 1) // WPA_PSK or WPA2PSK
+#define WIFI_PNO_AUTH_CODE_EAPOL (1 << 2) // any EAPOL
+
+typedef struct {
+ char ssid[32 + 1]; // null terminated
+ byte flags; // WIFI_PNO_FLAG_XXX
+ byte auth_bit_field; // auth bit field for matching WPA IE
+} wifi_epno_network;
+
+/* ePNO Parameters */
+typedef struct {
+ int min5GHz_rssi; // minimum 5GHz RSSI for a BSSID to be considered
+ int min24GHz_rssi; // minimum 2.4GHz RSSI for a BSSID to be considered
+ int initial_score_max; // the maximum score that a network can have before bonuses
+ int current_connection_bonus; // only report when there is a network's score this much higher
+ // than the current connection.
+ int same_network_bonus; // score bonus for all networks with the same network flag
+ int secure_bonus; // score bonus for networks that are not open
+ int band5GHz_bonus; // 5GHz RSSI score bonus (applied to all 5GHz networks)
+ int num_networks; // number of wifi_epno_network objects
+ wifi_epno_network networks[MAX_EPNO_NETWORKS]; // PNO networks
+} wifi_epno_params;
+
+typedef struct {
+ // on results
+ void (*on_network_found)(wifi_request_id id, unsigned num_results, wifi_scan_result* results);
+} wifi_epno_handler;
+
+/* Set the ePNO list - enable ePNO with the given parameters */
+wifi_error wifi_set_epno_list(wifi_request_id id, wifi_interface_handle iface,
+ const wifi_epno_params* epno_params, wifi_epno_handler handler);
+
+/* Reset the ePNO list - no ePNO networks should be matched after this */
+wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface);
+
+typedef struct {
+ int id; // identifier of this network block, report this in event
+ char realm[256]; // null terminated UTF8 encoded realm, 0 if unspecified
+ int64_t roamingConsortiumIds[16]; // roaming consortium ids to match, 0s if unspecified
+ byte plmn[3]; // mcc/mnc combination as per rules, 0s if unspecified
+} wifi_passpoint_network;
+
+typedef struct {
+ void (*on_passpoint_network_found)(
+ wifi_request_id id,
+ int net_id, // network block identifier for the matched network
+ wifi_scan_result* result, // scan result, with channel and beacon information
+ int anqp_len, // length of ANQP blob
+ byte* anqp // ANQP data, in the information_element format
+ );
+} wifi_passpoint_event_handler;
+
+/* Sets a list for passpoint networks for PNO purposes; it should be matched
+ * against any passpoint networks (designated by Interworking element) found
+ * during regular PNO scan. */
+wifi_error wifi_set_passpoint_list(wifi_request_id id, wifi_interface_handle iface, int num,
+ wifi_passpoint_network* networks,
+ wifi_passpoint_event_handler handler);
+
+/* Reset passpoint network list - no Passpoint networks should be matched after this */
+wifi_error wifi_reset_passpoint_list(wifi_request_id id, wifi_interface_handle iface);
+
+#endif
diff --git a/wifi/1.6/default/hal_legacy/link_layer_stats.h b/wifi/1.6/default/hal_legacy/link_layer_stats.h
new file mode 100644
index 0000000..7585cdf
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/link_layer_stats.h
@@ -0,0 +1,285 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_STATS_H
+#define __WIFI_HAL_STATS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define STATS_MAJOR_VERSION 1
+#define STATS_MINOR_VERSION 0
+#define STATS_MICRO_VERSION 0
+
+typedef enum {
+ WIFI_DISCONNECTED = 0,
+ WIFI_AUTHENTICATING = 1,
+ WIFI_ASSOCIATING = 2,
+ WIFI_ASSOCIATED = 3,
+ WIFI_EAPOL_STARTED = 4, // if done by firmware/driver
+ WIFI_EAPOL_COMPLETED = 5, // if done by firmware/driver
+} wifi_connection_state;
+
+typedef enum {
+ WIFI_ROAMING_IDLE = 0,
+ WIFI_ROAMING_ACTIVE = 1,
+} wifi_roam_state;
+
+typedef enum {
+ WIFI_INTERFACE_STA = 0,
+ WIFI_INTERFACE_SOFTAP = 1,
+ WIFI_INTERFACE_IBSS = 2,
+ WIFI_INTERFACE_P2P_CLIENT = 3,
+ WIFI_INTERFACE_P2P_GO = 4,
+ WIFI_INTERFACE_NAN = 5,
+ WIFI_INTERFACE_MESH = 6,
+ WIFI_INTERFACE_TDLS = 7,
+ WIFI_INTERFACE_UNKNOWN = -1
+} wifi_interface_mode;
+
+#define WIFI_CAPABILITY_QOS 0x00000001 // set for QOS association
+#define WIFI_CAPABILITY_PROTECTED \
+ 0x00000002 // set for protected association (802.11 beacon frame control protected bit set)
+#define WIFI_CAPABILITY_INTERWORKING \
+ 0x00000004 // set if 802.11 Extended Capabilities element interworking bit is set
+#define WIFI_CAPABILITY_HS20 0x00000008 // set for HS20 association
+#define WIFI_CAPABILITY_SSID_UTF8 \
+ 0x00000010 // set is 802.11 Extended Capabilities element UTF-8 SSID bit is set
+#define WIFI_CAPABILITY_COUNTRY 0x00000020 // set is 802.11 Country Element is present
+
+typedef struct {
+ wifi_interface_mode mode; // interface mode
+ u8 mac_addr[6]; // interface mac address (self)
+ wifi_connection_state state; // connection state (valid for STA, CLI only)
+ wifi_roam_state roaming; // roaming state
+ u32 capabilities; // WIFI_CAPABILITY_XXX (self)
+ u8 ssid[33]; // null terminated SSID
+ u8 bssid[6]; // bssid
+ u8 ap_country_str[3]; // country string advertised by AP
+ u8 country_str[3]; // country string for this association
+ u8 time_slicing_duty_cycle_percent; // if this iface is being served using time slicing on a
+ // radio with one or more ifaces (i.e MCC), then the duty
+ // cycle assigned to this iface in %. If not using time
+ // slicing (i.e SCC or DBS), set to 100.
+} wifi_interface_link_layer_info;
+
+/* channel information */
+typedef struct {
+ wifi_channel_width width; // channel width (20, 40, 80, 80+80, 160, 320)
+ wifi_channel center_freq; // primary 20 MHz channel
+ wifi_channel center_freq0; // center frequency (MHz) first segment
+ wifi_channel center_freq1; // center frequency (MHz) second segment
+} wifi_channel_info;
+
+/* wifi rate */
+typedef struct {
+ u32 preamble : 3; // 0: OFDM, 1:CCK, 2:HT 3:VHT 4:HE 5:EHT 6..7 reserved
+ u32 nss : 2; // 0:1x1, 1:2x2, 3:3x3, 4:4x4
+ u32 bw : 3; // 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz 4:320Mhz
+ u32 rateMcsIdx : 8; // OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps
+ // HT/VHT/HE/EHT it would be mcs index
+ u32 reserved : 16; // reserved
+ u32 bitrate; // units of 100 Kbps
+} wifi_rate;
+
+/* channel statistics */
+typedef struct {
+ wifi_channel_info channel; // channel
+ u32 on_time; // msecs the radio is awake (32 bits number accruing over time)
+ u32 cca_busy_time; // msecs the CCA register is busy (32 bits number accruing over time)
+} wifi_channel_stat;
+
+// Max number of tx power levels. The actual number vary per device and is specified by
+// |num_tx_levels|
+#define RADIO_STAT_MAX_TX_LEVELS 256
+
+/* radio statistics */
+typedef struct {
+ wifi_radio radio; // wifi radio (if multiple radio supported)
+ u32 on_time; // msecs the radio is awake (32 bits number accruing over time)
+ u32 tx_time; // msecs the radio is transmitting (32 bits number accruing over time)
+ u32 num_tx_levels; // number of radio transmit power levels
+ u32* tx_time_per_levels; // pointer to an array of radio transmit per power levels in
+ // msecs accured over time
+ u32 rx_time; // msecs the radio is in active receive (32 bits number accruing over time)
+ u32 on_time_scan; // msecs the radio is awake due to all scan (32 bits number accruing over
+ // time)
+ u32 on_time_nbd; // msecs the radio is awake due to NAN (32 bits number accruing over time)
+ u32 on_time_gscan; // msecs the radio is awake due to G?scan (32 bits number accruing over
+ // time)
+ u32 on_time_roam_scan; // msecs the radio is awake due to roam?scan (32 bits number accruing
+ // over time)
+ u32 on_time_pno_scan; // msecs the radio is awake due to PNO scan (32 bits number accruing over
+ // time)
+ u32 on_time_hs20; // msecs the radio is awake due to HS2.0 scans and GAS exchange (32 bits
+ // number accruing over time)
+ u32 num_channels; // number of channels
+ wifi_channel_stat channels[]; // channel statistics
+} wifi_radio_stat;
+
+/**
+ * Packet statistics reporting by firmware is performed on MPDU basi (i.e. counters increase by 1
+ * for each MPDU) As well, "data packet" in associated comments, shall be interpreted as 802.11 data
+ * packet, that is, 802.11 frame control subtype == 2 and excluding management and control frames.
+ *
+ * As an example, in the case of transmission of an MSDU fragmented in 16 MPDUs which are
+ * transmitted OTA in a 16 units long a-mpdu, for which a block ack is received with 5 bits set:
+ * tx_mpdu : shall increase by 5
+ * retries : shall increase by 16
+ * tx_ampdu : shall increase by 1
+ * data packet counters shall not increase regardless of the number of BAR potentially sent by
+ * device for this a-mpdu data packet counters shall not increase regardless of the number of BA
+ * received by device for this a-mpdu
+ *
+ * For each subsequent retransmission of the 11 remaining non ACK'ed mpdus
+ * (regardless of the fact that they are transmitted in a-mpdu or not)
+ * retries : shall increase by 1
+ *
+ * If no subsequent BA or ACK are received from AP, until packet lifetime expires for those 11
+ * packet that were not ACK'ed mpdu_lost : shall increase by 11
+ */
+
+/* per rate statistics */
+typedef struct {
+ wifi_rate rate; // rate information
+ u32 tx_mpdu; // number of successfully transmitted data pkts (ACK rcvd)
+ u32 rx_mpdu; // number of received data pkts
+ u32 mpdu_lost; // number of data packet losses (no ACK)
+ u32 retries; // total number of data pkt retries
+ u32 retries_short; // number of short data pkt retries
+ u32 retries_long; // number of long data pkt retries
+} wifi_rate_stat;
+
+/* access categories */
+typedef enum {
+ WIFI_AC_VO = 0,
+ WIFI_AC_VI = 1,
+ WIFI_AC_BE = 2,
+ WIFI_AC_BK = 3,
+ WIFI_AC_MAX = 4,
+} wifi_traffic_ac;
+
+/* wifi peer type */
+typedef enum {
+ WIFI_PEER_STA,
+ WIFI_PEER_AP,
+ WIFI_PEER_P2P_GO,
+ WIFI_PEER_P2P_CLIENT,
+ WIFI_PEER_NAN,
+ WIFI_PEER_TDLS,
+ WIFI_PEER_INVALID,
+} wifi_peer_type;
+
+/* per peer statistics */
+typedef struct bssload_info {
+ u16 sta_count; // station count
+ u16 chan_util; // channel utilization
+ u8 PAD[4];
+} bssload_info_t;
+
+typedef struct {
+ wifi_peer_type type; // peer type (AP, TDLS, GO etc.)
+ u8 peer_mac_address[6]; // mac address
+ u32 capabilities; // peer WIFI_CAPABILITY_XXX
+ bssload_info_t bssload; // STA count and CU
+ u32 num_rate; // number of rates
+ wifi_rate_stat rate_stats[]; // per rate statistics, number of entries = num_rate
+} wifi_peer_info;
+
+/* Per access category statistics */
+typedef struct {
+ wifi_traffic_ac ac; // access category (VI, VO, BE, BK)
+ u32 tx_mpdu; // number of successfully transmitted unicast data pkts (ACK rcvd)
+ u32 rx_mpdu; // number of received unicast data packets
+ u32 tx_mcast; // number of succesfully transmitted multicast data packets
+ // STA case: implies ACK received from AP for the unicast packet in which mcast
+ // pkt was sent
+ u32 rx_mcast; // number of received multicast data packets
+ u32 rx_ampdu; // number of received unicast a-mpdus; support of this counter is optional
+ u32 tx_ampdu; // number of transmitted unicast a-mpdus; support of this counter is optional
+ u32 mpdu_lost; // number of data pkt losses (no ACK)
+ u32 retries; // total number of data pkt retries
+ u32 retries_short; // number of short data pkt retries
+ u32 retries_long; // number of long data pkt retries
+ u32 contention_time_min; // data pkt min contention time (usecs)
+ u32 contention_time_max; // data pkt max contention time (usecs)
+ u32 contention_time_avg; // data pkt avg contention time (usecs)
+ u32 contention_num_samples; // num of data pkts used for contention statistics
+} wifi_wmm_ac_stat;
+
+/* interface statistics */
+typedef struct {
+ wifi_interface_handle iface; // wifi interface
+ wifi_interface_link_layer_info info; // current state of the interface
+ u32 beacon_rx; // access point beacon received count from connected AP
+ u64 average_tsf_offset; // average beacon offset encountered (beacon_TSF - TBTT)
+ // The average_tsf_offset field is used so as to calculate the
+ // typical beacon contention time on the channel as well may be
+ // used to debug beacon synchronization and related power consumption
+ // issue
+ u32 leaky_ap_detected; // indicate that this AP typically leaks packets beyond the driver guard
+ // time.
+ u32 leaky_ap_avg_num_frames_leaked; // average number of frame leaked by AP after frame with PM
+ // bit set was ACK'ed by AP
+ u32 leaky_ap_guard_time; // guard time currently in force (when implementing IEEE power
+ // management based on frame control PM bit), How long driver waits
+ // before shutting down the radio and after receiving an ACK for a
+ // data frame with PM bit set)
+ u32 mgmt_rx; // access point mgmt frames received count from connected AP (including Beacon)
+ u32 mgmt_action_rx; // action frames received count
+ u32 mgmt_action_tx; // action frames transmit count
+ wifi_rssi rssi_mgmt; // access Point Beacon and Management frames RSSI (averaged)
+ wifi_rssi rssi_data; // access Point Data Frames RSSI (averaged) from connected AP
+ wifi_rssi rssi_ack; // access Point ACK RSSI (averaged) from connected AP
+ wifi_wmm_ac_stat ac[WIFI_AC_MAX]; // per ac data packet statistics
+ u32 num_peers; // number of peers
+ wifi_peer_info peer_info[]; // per peer statistics
+} wifi_iface_stat;
+
+/* configuration params */
+typedef struct {
+ u32 mpdu_size_threshold; // threshold to classify the pkts as short or long
+ // packet size < mpdu_size_threshold => short
+ u32 aggressive_statistics_gathering; // set for field debug mode. Driver should collect all
+ // statistics regardless of performance impact.
+} wifi_link_layer_params;
+
+/* API to trigger the link layer statistics collection.
+ Unless his API is invoked - link layer statistics will not be collected.
+ Radio statistics (once started) do not stop or get reset unless wifi_clear_link_stats is invoked
+ Interface statistics (once started) reset and start afresh after each connection */
+wifi_error wifi_set_link_stats(wifi_interface_handle iface, wifi_link_layer_params params);
+
+/* callback for reporting link layer stats */
+typedef struct {
+ void (*on_link_stats_results)(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
+ wifi_radio_stat* radio_stat);
+} wifi_stats_result_handler;
+
+/* api to collect the link layer statistics for a given iface and all the radio stats */
+wifi_error wifi_get_link_stats(wifi_request_id id, wifi_interface_handle iface,
+ wifi_stats_result_handler handler);
+
+/* wifi statistics bitmap */
+#define WIFI_STATS_RADIO 0x00000001 // all radio statistics
+#define WIFI_STATS_RADIO_CCA 0x00000002 // cca_busy_time (within radio statistics)
+#define WIFI_STATS_RADIO_CHANNELS 0x00000004 // all channel statistics (within radio statistics)
+#define WIFI_STATS_RADIO_SCAN 0x00000008 // all scan statistics (within radio statistics)
+#define WIFI_STATS_IFACE 0x00000010 // all interface statistics
+#define WIFI_STATS_IFACE_TXRATE 0x00000020 // all tx rate statistics (within interface statistics)
+#define WIFI_STATS_IFACE_AC 0x00000040 // all ac statistics (within interface statistics)
+#define WIFI_STATS_IFACE_CONTENTION \
+ 0x00000080 // all contention (min, max, avg) statistics (within ac statisctics)
+
+/* clear api to reset statistics, stats_clear_rsp_mask identifies what stats have been cleared
+ stop_req = 1 will imply whether to stop the statistics collection.
+ stop_rsp = 1 will imply that stop_req was honored and statistics collection was stopped.
+ */
+wifi_error wifi_clear_link_stats(wifi_interface_handle iface, u32 stats_clear_req_mask,
+ u32* stats_clear_rsp_mask, u8 stop_req, u8* stop_rsp);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/1.6/default/hal_legacy/power.h b/wifi/1.6/default/hal_legacy/power.h
new file mode 100644
index 0000000..2b6d12a
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/power.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HARDWARE_POWER_H
+#define _HARDWARE_POWER_H
+
+#include <stdint.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+enum {
+ PARTIAL_WAKE_LOCK = 1, // the cpu stays on, but the screen is off
+ FULL_WAKE_LOCK = 2 // the screen is also on
+};
+
+// while you have a lock held, the device will stay on at least at the
+// level you request.
+int acquire_wake_lock(int lock, const char* id);
+int release_wake_lock(const char* id);
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _HARDWARE_POWER_H
diff --git a/wifi/1.6/default/hal_legacy/roam.h b/wifi/1.6/default/hal_legacy/roam.h
new file mode 100644
index 0000000..3369e3e
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/roam.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_ROAM_H__
+#define __WIFI_HAL_ROAM_H__
+
+#include "wifi_hal.h"
+
+#define MAX_BLACKLIST_BSSID 16
+#define MAX_WHITELIST_SSID 8
+#define MAX_SSID_LENGTH 32
+
+typedef struct {
+ u32 max_blacklist_size;
+ u32 max_whitelist_size;
+} wifi_roaming_capabilities;
+
+typedef enum { ROAMING_DISABLE, ROAMING_ENABLE } fw_roaming_state_t;
+
+typedef struct {
+ u32 length;
+ char ssid_str[MAX_SSID_LENGTH];
+} ssid_t;
+
+typedef struct {
+ u32 num_blacklist_bssid; // Number of bssids valid in blacklist_bssid[].
+ mac_addr blacklist_bssid[MAX_BLACKLIST_BSSID]; // List of bssids which should not be considered
+ // for romaing by firmware/driver.
+ u32 num_whitelist_ssid; // Number of ssids valid in whitelist_ssid[].
+ ssid_t whitelist_ssid[MAX_WHITELIST_SSID]; // List of ssids to which firmware/driver can
+ // consider to roam to.
+} wifi_roaming_config;
+
+/* Get the chipset roaming capabilities. */
+wifi_error wifi_get_roaming_capabilities(wifi_interface_handle handle,
+ wifi_roaming_capabilities* caps);
+/* Enable/disable firmware roaming */
+wifi_error wifi_enable_firmware_roaming(wifi_interface_handle handle, fw_roaming_state_t state);
+
+/* Pass down the blacklist BSSID and whitelist SSID to firmware. */
+wifi_error wifi_configure_roaming(wifi_interface_handle handle,
+ wifi_roaming_config* roaming_config);
+
+#endif /* __WIFI_HAL_ROAM_H__ */
diff --git a/wifi/1.6/default/hal_legacy/rtt.h b/wifi/1.6/default/hal_legacy/rtt.h
new file mode 100644
index 0000000..8be7fd3
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/rtt.h
@@ -0,0 +1,314 @@
+
+#include "gscan.h"
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_RTT_H__
+#define __WIFI_HAL_RTT_H__
+
+/* Ranging status */
+typedef enum {
+ RTT_STATUS_SUCCESS = 0,
+ RTT_STATUS_FAILURE = 1, // general failure status
+ RTT_STATUS_FAIL_NO_RSP = 2, // target STA does not respond to request
+ RTT_STATUS_FAIL_REJECTED = 3, // request rejected. Applies to 2-sided RTT only
+ RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4,
+ RTT_STATUS_FAIL_TM_TIMEOUT = 5, // timing measurement times out
+ RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6, // Target on different channel, cannot range
+ RTT_STATUS_FAIL_NO_CAPABILITY = 7, // ranging not supported
+ RTT_STATUS_ABORTED = 8, // request aborted for unknown reason
+ RTT_STATUS_FAIL_INVALID_TS = 9, // Invalid T1-T4 timestamp
+ RTT_STATUS_FAIL_PROTOCOL = 10, // 11mc protocol failed
+ RTT_STATUS_FAIL_SCHEDULE = 11, // request could not be scheduled
+ RTT_STATUS_FAIL_BUSY_TRY_LATER = 12, // responder cannot collaborate at time of request
+ RTT_STATUS_INVALID_REQ = 13, // bad request args
+ RTT_STATUS_NO_WIFI = 14, // WiFi not enabled
+ RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE =
+ 15, // Responder overrides param info, cannot range with new params
+ RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE = 16, // Negotiation failure
+ RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17, // concurrency not supported (NDP+RTT)
+} wifi_rtt_status;
+
+/* RTT peer type */
+typedef enum {
+ RTT_PEER_AP = 0x1,
+ RTT_PEER_STA = 0x2,
+ RTT_PEER_P2P_GO = 0x3,
+ RTT_PEER_P2P_CLIENT = 0x4,
+ RTT_PEER_NAN = 0x5
+} rtt_peer_type;
+
+/* RTT Measurement Bandwidth */
+typedef enum {
+ WIFI_RTT_BW_5 = 0x01,
+ WIFI_RTT_BW_10 = 0x02,
+ WIFI_RTT_BW_20 = 0x04,
+ WIFI_RTT_BW_40 = 0x08,
+ WIFI_RTT_BW_80 = 0x10,
+ WIFI_RTT_BW_160 = 0x20,
+ WIFI_RTT_BW_320 = 0x40
+} wifi_rtt_bw;
+
+/* RTT Measurement Preamble */
+typedef enum {
+ WIFI_RTT_PREAMBLE_LEGACY = 0x1,
+ WIFI_RTT_PREAMBLE_HT = 0x2,
+ WIFI_RTT_PREAMBLE_VHT = 0x4,
+ WIFI_RTT_PREAMBLE_HE = 0x8,
+ WIFI_RTT_PREAMBLE_EHT = 0x10,
+} wifi_rtt_preamble;
+
+/* RTT Type */
+typedef enum {
+ RTT_TYPE_1_SIDED = 0x1,
+ RTT_TYPE_2_SIDED = 0x2,
+} wifi_rtt_type;
+
+/* RTT configuration */
+typedef struct {
+ mac_addr addr; // peer device mac address
+ wifi_rtt_type type; // 1-sided or 2-sided RTT
+ rtt_peer_type peer; // optional - peer device hint (STA, P2P, AP)
+ wifi_channel_info channel; // Required for STA-AP mode, optional for P2P, NBD etc.
+ unsigned burst_period; // 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)
+ unsigned num_burst; // Total number of RTT bursts to be executed. It will be
+ // specified in the same way as the parameter "Number of
+ // Burst Exponent" found in the FTM frame format. It
+ // applies to both: 1-sided RTT and 2-sided RTT. Valid
+ // values are 0 to 15 as defined in 802.11mc std.
+ // 0 means single shot
+ // The implication of this parameter on the maximum
+ // 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)
+ unsigned num_frames_per_burst; // num of frames per burst.
+ // Minimum value = 1, Maximum value = 31
+ // For 2-sided this equals the number of FTM frames
+ // to be attempted in a single burst. This also
+ // equals the number of FTM frames that the
+ // initiator will request that the responder send
+ // in a single frame.
+ unsigned
+ num_retries_per_rtt_frame; // number of retries for a failed RTT frame. Applies
+ // to 1-sided RTT only. Minimum value = 0, Maximum value = 3
+
+ // following fields are only valid for 2-side RTT
+ unsigned num_retries_per_ftmr; // Maximum number of retries that the initiator can
+ // retry an FTMR frame.
+ // Minimum value = 0, Maximum value = 3
+ byte LCI_request; // 1: request LCI, 0: do not request LCI
+ byte LCR_request; // 1: request LCR, 0: do not request LCR
+ unsigned burst_duration; // Applies to 1-sided and 2-sided RTT. Valid values will
+ // be 2-11 and 15 as specified by the 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
+ // request if responder overrides with larger value,
+ // the initiator will sent TMR_STOP to terminate RTT
+ // at the end of the burst_duration it requested.
+ wifi_rtt_preamble preamble; // RTT preamble to be used in the RTT frames
+ wifi_rtt_bw bw; // RTT BW to be used in the RTT frames
+} wifi_rtt_config;
+
+/* RTT results */
+typedef struct {
+ mac_addr addr; // device mac address
+ unsigned burst_num; // burst number in a multi-burst request
+ unsigned measurement_number; // Total RTT measurement frames attempted
+ unsigned success_number; // Total successful RTT measurement frames
+ byte number_per_burst_peer; // Maximum number of "FTM frames per burst" supported by
+ // the responder STA. Applies to 2-sided 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
+ // many frames as originally requested.
+ // - for multi-burst request, initiator will return
+ // failure right away.
+ wifi_rtt_status status; // ranging status
+ byte retry_after_duration; // When status == 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-31sec.
+ wifi_rtt_type type; // RTT type
+ wifi_rssi rssi; // average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB
+ wifi_rssi rssi_spread; // rssi spread in 0.5 dB steps e.g. 5 implies 2.5 dB spread (optional)
+ wifi_rate tx_rate; // 1-sided RTT: TX rate of RTT frame.
+ // 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
+ wifi_rate rx_rate; // 1-sided RTT: TX rate of Ack from other side.
+ // 2-sided RTT: TX rate of FTM frame coming from responder.
+ wifi_timespan rtt; // round trip time in picoseconds
+ wifi_timespan rtt_sd; // rtt standard deviation in picoseconds
+ wifi_timespan rtt_spread; // difference between max and min rtt times recorded in picoseconds
+ int distance_mm; // distance in mm (optional)
+ int distance_sd_mm; // standard deviation in mm (optional)
+ int distance_spread_mm; // difference between max and min distance recorded in mm (optional)
+ wifi_timestamp ts; // time of the measurement (in microseconds since boot)
+ int burst_duration; // in ms, actual time taken by the FW to finish one burst
+ // measurement. Applies to 1-sided and 2-sided RTT.
+ int negotiated_burst_num; // Number of bursts allowed by the responder. Applies
+ // to 2-sided RTT only.
+ wifi_information_element* LCI; // for 11mc only
+ wifi_information_element* LCR; // for 11mc only
+} wifi_rtt_result;
+
+/* RTT result callback */
+typedef struct {
+ void (*on_rtt_results)(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_result[]);
+} wifi_rtt_event_handler;
+
+/* API to request RTT measurement */
+wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
+ unsigned num_rtt_config, wifi_rtt_config rtt_config[],
+ wifi_rtt_event_handler handler);
+
+/* API to cancel RTT measurements */
+wifi_error wifi_rtt_range_cancel(wifi_request_id id, wifi_interface_handle iface,
+ unsigned num_devices, mac_addr addr[]);
+
+/* NBD ranging channel map */
+typedef struct {
+ wifi_channel availablity[32]; // specifies the channel map for each of the 16 TU windows
+ // frequency of 0 => unspecified; which means firmware is
+ // free to do whatever it wants in this window.
+} wifi_channel_map;
+
+/* API to start publishing the channel map on responder device in a NBD cluster.
+ Responder device will take this request and schedule broadcasting the channel map
+ in a NBD ranging attribute in a SDF. DE will automatically remove the ranging
+ attribute from the OTA queue after number of DW specified by num_dw
+ where Each DW is 512 TUs apart */
+wifi_error wifi_rtt_channel_map_set(wifi_request_id id, wifi_interface_handle iface,
+ wifi_channel_map* params, unsigned num_dw);
+
+/* API to clear the channel map on the responder device in a NBD cluster.
+ Responder device will cancel future ranging channel request, starting from “next”
+ DW interval and will also stop broadcasting NBD ranging attribute in SDF */
+wifi_error wifi_rtt_channel_map_clear(wifi_request_id id, wifi_interface_handle iface);
+
+// Preamble definition for bit mask used in wifi_rtt_capabilities
+#define PREAMBLE_LEGACY 0x1
+#define PREAMBLE_HT 0x2
+#define PREAMBLE_VHT 0x4
+#define PREAMBLE_HE 0x8
+#define PREAMBLE_EHT 0x10
+
+// BW definition for bit mask used in wifi_rtt_capabilities
+#define BW_5_SUPPORT 0x1
+#define BW_10_SUPPORT 0x2
+#define BW_20_SUPPORT 0x4
+#define BW_40_SUPPORT 0x8
+#define BW_80_SUPPORT 0x10
+#define BW_160_SUPPORT 0x20
+#define BW_320_SUPPORT 0x40
+
+/* RTT Capabilities */
+typedef struct {
+ byte rtt_one_sided_supported; // if 1-sided rtt data collection is supported
+ byte rtt_ftm_supported; // if ftm rtt data collection is supported
+ byte lci_support; // if initiator supports LCI request. Applies to 2-sided RTT
+ byte lcr_support; // if initiator supports LCR request. Applies to 2-sided RTT
+ byte preamble_support; // bit mask indicates what preamble is supported by initiator
+ byte bw_support; // bit mask indicates what BW is supported by initiator
+ byte responder_supported; // if 11mc responder mode is supported
+ byte mc_version; // draft 11mc spec version supported by chip. For instance,
+ // version 4.0 should be 40 and version 4.3 should be 43 etc.
+} wifi_rtt_capabilities;
+
+/* RTT capabilities of the device */
+wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
+ wifi_rtt_capabilities* capabilities);
+
+/* debugging definitions */
+enum {
+ RTT_DEBUG_DISABLE,
+ RTT_DEBUG_LOG,
+ RTT_DEBUG_PROTO,
+ RTT_DEBUG_BURST,
+ RTT_DEBUG_ACCURACY,
+ RTT_DEBUG_LOGDETAIL
+}; // rtt debug type
+
+enum { RTT_DEBUG_FORMAT_TXT, RTT_DEBUG_FORMAT_BINARY }; // rtt debug format
+
+typedef struct rtt_debug {
+ unsigned version;
+ unsigned len; // total length of after len field
+ unsigned type; // rtt debug type
+ unsigned format; // rtt debug format
+ char dbuf[0]; // debug content
+} rtt_debug_t;
+
+/* set configuration for debug */
+wifi_error wifi_rtt_debug_cfg(wifi_interface_handle h, unsigned rtt_dbg_type, char* cfgbuf,
+ unsigned cfg_buf_size);
+/* get the debug information */
+wifi_error wifi_rtt_debug_get(wifi_interface_handle h, rtt_debug_t** debugbuf);
+/* free the debug buffer */
+wifi_error wifi_rtt_debug_free(wifi_interface_handle h, rtt_debug_t* debugbuf);
+
+/* API for setting LCI/LCR information to be provided to a requestor */
+typedef enum {
+ WIFI_MOTION_NOT_EXPECTED = 0, // Not expected to change location
+ WIFI_MOTION_EXPECTED = 1, // Expected to change location
+ WIFI_MOTION_UNKNOWN = 2, // Movement pattern unknown
+} wifi_motion_pattern;
+
+typedef struct {
+ long latitude; // latitude in degrees * 2^25 , 2's complement
+ long longitude; // latitude in degrees * 2^25 , 2's complement
+ int altitude; // Altitude in units of 1/256 m
+ byte latitude_unc; // As defined in Section 2.3.2 of IETF RFC 6225
+ byte longitude_unc; // As defined in Section 2.3.2 of IETF RFC 6225
+ byte altitude_unc; // As defined in Section 2.4.5 from IETF RFC 6225:
+
+ // Following element for configuring the Z subelement
+ wifi_motion_pattern motion_pattern;
+ int floor; // floor in units of 1/16th of floor. 0x80000000 if unknown.
+ int height_above_floor; // in units of 1/64 m
+ int height_unc; // in units of 1/64 m. 0 if unknown
+} wifi_lci_information;
+
+typedef struct {
+ char country_code[2]; // country code
+ int length; // length of the info field
+ char civic_info[256]; // Civic info to be copied in FTM frame
+} wifi_lcr_information;
+
+// API to configure the LCI. Used in RTT Responder mode only
+wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface, wifi_lci_information* lci);
+
+// API to configure the LCR. Used in RTT Responder mode only.
+wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface, wifi_lcr_information* lcr);
+
+/**
+ * RTT Responder information
+ */
+typedef struct {
+ wifi_channel_info channel;
+ wifi_rtt_preamble preamble;
+} wifi_rtt_responder;
+
+/**
+ * Get RTT responder information e.g. WiFi channel to enable responder on.
+ */
+wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
+ wifi_rtt_responder* responder_info);
+
+/**
+ * Enable RTT responder mode.
+ * channel_hint - hint of the channel information where RTT responder should be enabled on.
+ * max_duration_seconds - timeout of responder mode.
+ * channel_used - channel used for RTT responder, NULL if responder is not enabled.
+ */
+wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
+ wifi_channel_info channel_hint, unsigned max_duration_seconds,
+ wifi_rtt_responder* responder_info);
+
+/**
+ * Disable RTT responder mode.
+ */
+wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface);
+
+#endif
diff --git a/wifi/1.6/default/hal_legacy/tdls.h b/wifi/1.6/default/hal_legacy/tdls.h
new file mode 100644
index 0000000..787b13a
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/tdls.h
@@ -0,0 +1,84 @@
+
+#include "wifi_hal.h"
+
+#ifndef _TDLS_H_
+#define _TDLS_H_
+
+typedef enum {
+ WIFI_TDLS_DISABLED = 1, /* TDLS is not enabled, default status for all STAs */
+ WIFI_TDLS_ENABLED, /* TDLS is enabled, but not yet tried */
+ WIFI_TDLS_ESTABLISHED, /* Direct link is established */
+ WIFI_TDLS_ESTABLISHED_OFF_CHANNEL, /* Direct link is established using MCC */
+ WIFI_TDLS_DROPPED, /* Direct link was established,
+ * but is temporarily dropped now */
+ WIFI_TDLS_FAILED /* TDLS permanent failed. Inform error to upper layer
+ * and go back to WIFI_TDLS_DISABLED */
+} wifi_tdls_state;
+
+typedef enum {
+ WIFI_TDLS_SUCCESS, /* Success */
+ WIFI_TDLS_UNSPECIFIED = -1, /* Unspecified reason */
+ WIFI_TDLS_NOT_SUPPORTED = -2, /* Remote side doesn't support TDLS */
+ WIFI_TDLS_UNSUPPORTED_BAND = -3, /* Remote side doesn't support this band */
+ WIFI_TDLS_NOT_BENEFICIAL = -4, /* Going to AP is better than going direct */
+ WIFI_TDLS_DROPPED_BY_REMOTE = -5 /* Remote side doesn't want it anymore */
+} wifi_tdls_reason;
+
+typedef struct {
+ int channel; /* channel hint, in channel number (NOT frequency ) */
+ int global_operating_class; /* operating class to use */
+ int max_latency_ms; /* max latency that can be tolerated by apps */
+ int min_bandwidth_kbps; /* bandwidth required by apps, in kilo bits per second */
+} wifi_tdls_params;
+
+typedef struct {
+ int channel;
+ int global_operating_class;
+ wifi_tdls_state state;
+ wifi_tdls_reason reason;
+} wifi_tdls_status;
+
+typedef struct {
+ int max_concurrent_tdls_session_num; /* Maximum TDLS session number can be supported by the
+ * Firmware and hardware*/
+ int is_global_tdls_supported; /* 1 -- support, 0 -- not support */
+ int is_per_mac_tdls_supported; /* 1 -- support, 0 -- not support */
+ int is_off_channel_tdls_supported; /* 1 -- support, 0 -- not support */
+} wifi_tdls_capabilities;
+
+typedef struct {
+ /* on_tdls_state_changed - reports state of TDLS link to framework
+ * Report this event when the state of TDLS link changes */
+ void (*on_tdls_state_changed)(mac_addr addr, wifi_tdls_status status);
+} wifi_tdls_handler;
+
+/* wifi_enable_tdls - enables TDLS-auto mode for a specific route
+ *
+ * params specifies hints, which provide more information about
+ * why TDLS is being sought. The firmware should do its best to
+ * honor the hints before downgrading regular AP link
+ * If upper layer has no specific values, this should be NULL
+ *
+ * handler is used to inform the upper layer about the status change and the corresponding reason
+ */
+wifi_error wifi_enable_tdls(wifi_interface_handle iface, mac_addr addr, wifi_tdls_params* params,
+ wifi_tdls_handler handler);
+
+/* wifi_disable_tdls - disables TDLS-auto mode for a specific route
+ *
+ * This terminates any existing TDLS with addr device, and frees the
+ * device resources to make TDLS connections on new routes.
+ *
+ * DON'T fire any more events on 'handler' specified in earlier call to
+ * wifi_enable_tdls after this action.
+ */
+wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr);
+
+/* wifi_get_tdls_status - allows getting the status of TDLS for a specific route */
+wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr,
+ wifi_tdls_status* status);
+
+/* return the current HW + Firmware combination's TDLS capabilities */
+wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface,
+ wifi_tdls_capabilities* capabilities);
+#endif
diff --git a/wifi/1.6/default/hal_legacy/uevent.h b/wifi/1.6/default/hal_legacy/uevent.h
new file mode 100644
index 0000000..5b82b32
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/uevent.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HARDWARE_UEVENT_H
+#define _HARDWARE_UEVENT_H
+
+#if __cplusplus
+extern "C" {
+#endif
+
+int uevent_init();
+int uevent_get_fd();
+int uevent_next_event(char* buffer, int buffer_length);
+int uevent_add_native_handler(void (*handler)(void* data, const char* msg, int msg_len),
+ void* handler_data);
+int uevent_remove_native_handler(void (*handler)(void* data, const char* msg, int msg_len));
+
+#if __cplusplus
+} // extern "C"
+#endif
+
+#endif // _HARDWARE_UEVENT_H
diff --git a/wifi/1.6/default/hal_legacy/wifi_cached_scan_results.h b/wifi/1.6/default/hal_legacy/wifi_cached_scan_results.h
new file mode 100644
index 0000000..c7392c2
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_cached_scan_results.h
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+#ifndef __WIFI_CACHED_SCAN_RESULTS_H__
+#define __WIFI_CACHED_SCAN_RESULTS_H__
+
+#include "wifi_hal.h"
+
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_NONE (0)
+/* Element ID 61 (HT Operation) is present (see HT 7.3.2) */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT (1 << 0)
+/* Element ID 192 (VHT Operation) is present (see VHT 8.4.2) */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT (1 << 1)
+/* Element ID 255 + Extension 36 (HE Operation) is present
+ * (see 802.11ax 9.4.2.1)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT (1 << 2)
+/* Element ID 255 + Extension 106 (HE Operation) is present
+ * (see 802.11be D1.5 9.4.2.1)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT (1 << 3)
+/* Element ID 127 (Extended Capabilities) is present, and bit 70
+ * (Fine Timing Measurement Responder) is set to 1
+ * (see IEEE Std 802.11-2016 9.4.2.27)
+ */
+#define WIFI_CACHED_SCAN_RESULT_FLAGS_IS_FTM_RESPONDER (1 << 4)
+
+/**
+ * Provides information about a single access point (AP) detected in a scan.
+ */
+typedef struct {
+ /* Number of milliseconds prior to ts in the enclosing
+ * wifi_cached_scan_result_report struct when
+ * the probe response or beacon frame that
+ * was used to populate this structure was received.
+ */
+ u32 age_ms;
+ /* The Capability Information field */
+ u16 capability;
+ /* null terminated */
+ u8 ssid[33];
+ u8 ssid_len;
+ u8 bssid[6];
+ /* A set of flags from WIFI_CACHED_SCAN_RESULT_FLAGS_* */
+ u8 flags;
+ s8 rssi;
+ wifi_channel_spec chanspec;
+} wifi_cached_scan_result;
+
+/*
+ * Data structure sent with events of type WifiCachedScanResult.
+ */
+typedef struct {
+ /* time since boot (in microsecond) when the result was retrieved */
+ wifi_timestamp ts;
+ /* If 0, indicates that all frequencies in current regulation were
+ * scanned. Otherwise, indicates the number of frequencies scanned, as
+ * specified in scanned_freq_list.
+ */
+ u16 scanned_freq_num;
+ /* Pointer to an array containing scanned_freq_num values comprising the
+ * set of frequencies that were scanned. Frequencies are specified as
+ * channel center frequencies in MHz. May be NULL if scannedFreqListLen is
+ * 0.
+ */
+ const u32* scanned_freq_list;
+ /* The total number of cached results returned. */
+ u8 result_cnt;
+ /* Pointer to an array containing result_cnt entries. May be NULL if
+ * result_cnt is 0.
+ */
+ const wifi_cached_scan_result* results;
+} wifi_cached_scan_report;
+
+/* callback for reporting cached scan report */
+typedef struct {
+ void (*on_cached_scan_results)(wifi_cached_scan_report* cache_report);
+} wifi_cached_scan_result_handler;
+#endif
diff --git a/wifi/1.6/default/hal_legacy/wifi_config.h b/wifi/1.6/default/hal_legacy/wifi_config.h
new file mode 100644
index 0000000..459a3fe
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_config.h
@@ -0,0 +1,44 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_CONFIG_H
+#define __WIFI_HAL_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define CONFIG_MAJOR_VERSION 1
+#define CONFIG_MINOR_VERSION 0
+#define CONFIG_MICRO_VERSION 0
+
+// whether the wifi chipset wakes at every dtim beacon or a multiple of the dtim period
+// if extended_dtim is set to 3, the STA shall wake up every 3 DTIM beacons
+wifi_error wifi_extended_dtim_config_set(wifi_request_id id, wifi_interface_handle iface,
+ int extended_dtim);
+
+// set the country code to driver
+wifi_error wifi_set_country_code(wifi_interface_handle iface, const char* country_code);
+
+// set the wifi_iface stats averaging factor used to calculate
+// statistics like average the TSF offset or average number of frame leaked
+// For instance, upon beacon reception:
+// current_avg = ((beacon_TSF - TBTT) * factor + previous_avg * (0x10000 - factor) ) / 0x10000
+// For instance, when evaluating leaky APs:
+// current_avg = ((num frame received within guard time) * factor + previous_avg * (0x10000 -
+// factor)) / 0x10000
+
+wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor(wifi_request_id id,
+ wifi_interface_handle iface,
+ u16 factor);
+
+// configure guard time, i.e. when implementing IEEE power management based on
+// frame control PM bit, how long driver waits before shutting down the radio and
+// after receiving an ACK for a data frame with PM bit set
+wifi_error wifi_set_guard_time(wifi_request_id id, wifi_interface_handle iface, u32 guard_time);
+
+#ifdef __cplusplus
+}
+
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/1.6/default/hal_legacy/wifi_hal.h b/wifi/1.6/default/hal_legacy/wifi_hal.h
new file mode 100644
index 0000000..383ba71
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_hal.h
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_H__
+#define __WIFI_HAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <stdint.h>
+
+#define IFNAMSIZ 16
+
+/* typedefs */
+typedef unsigned char byte;
+typedef unsigned char u8;
+typedef signed char s8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint64_t u64;
+typedef int64_t s64;
+typedef int wifi_request_id;
+typedef int wifi_channel; // indicates channel frequency in MHz
+typedef int wifi_rssi;
+typedef int wifi_radio;
+typedef byte mac_addr[6];
+typedef byte oui[3];
+typedef int64_t wifi_timestamp; // In microseconds (us)
+typedef int64_t wifi_timespan; // In picoseconds (ps)
+typedef uint64_t feature_set;
+
+/* forward declarations */
+struct wifi_info;
+struct wifi_interface_info;
+typedef struct wifi_info* wifi_handle;
+typedef struct wifi_interface_info* wifi_interface_handle;
+
+/* WiFi Common definitions */
+/* channel operating width */
+typedef enum {
+ WIFI_CHAN_WIDTH_20 = 0,
+ WIFI_CHAN_WIDTH_40 = 1,
+ WIFI_CHAN_WIDTH_80 = 2,
+ WIFI_CHAN_WIDTH_160 = 3,
+ WIFI_CHAN_WIDTH_80P80 = 4,
+ WIFI_CHAN_WIDTH_5 = 5,
+ WIFI_CHAN_WIDTH_10 = 6,
+ WIFI_CHAN_WIDTH_320 = 7,
+ WIFI_CHAN_WIDTH_INVALID = -1
+} wifi_channel_width;
+
+/* Pre selected Power scenarios to be applied from BDF file */
+typedef enum {
+ WIFI_POWER_SCENARIO_INVALID = -2,
+ WIFI_POWER_SCENARIO_DEFAULT = -1,
+ WIFI_POWER_SCENARIO_VOICE_CALL = 0,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF = 1,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON = 2,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF = 3,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON = 4,
+ WIFI_POWER_SCENARIO_ON_BODY_BT = 5,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT = 6,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW = 7,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT = 8,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT = 9,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT = 10,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW = 11,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW = 12,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF_UNFOLDED = 13,
+ WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON_UNFOLDED = 14,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_UNFOLDED = 15,
+ WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW_UNFOLDED = 16,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF_UNFOLDED = 17,
+ WIFI_POWER_SCENARIO_ON_BODY_BT_UNFOLDED = 18,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_UNFOLDED = 19,
+ WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT_UNFOLDED = 20,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_UNFOLDED = 21,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_UNFOLDED = 22,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_MMW_UNFOLDED = 23,
+ WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT_BT_MMW_UNFOLDED = 24,
+} wifi_power_scenario;
+
+typedef enum {
+ WIFI_LATENCY_MODE_NORMAL = 0,
+ WIFI_LATENCY_MODE_LOW = 1,
+} wifi_latency_mode;
+
+/* Wifi Thermal mitigation modes */
+typedef enum {
+ WIFI_MITIGATION_NONE = 0,
+ WIFI_MITIGATION_LIGHT = 1,
+ WIFI_MITIGATION_MODERATE = 2,
+ WIFI_MITIGATION_SEVERE = 3,
+ WIFI_MITIGATION_CRITICAL = 4,
+ WIFI_MITIGATION_EMERGENCY = 5,
+} wifi_thermal_mode;
+
+/*
+ * Wifi voice over IP mode
+ * may add new modes later, for example, voice + video over IP mode.
+ */
+typedef enum {
+ WIFI_VOIP_MODE_OFF = 0,
+ WIFI_VOIP_MODE_ON = 1,
+} wifi_voip_mode;
+
+/* List of interface types supported */
+typedef enum {
+ WIFI_INTERFACE_TYPE_STA = 0,
+ WIFI_INTERFACE_TYPE_AP = 1,
+ WIFI_INTERFACE_TYPE_P2P = 2,
+ WIFI_INTERFACE_TYPE_NAN = 3,
+} wifi_interface_type;
+
+/*
+ * enum wlan_mac_band - Band information corresponding to the WLAN MAC.
+ */
+typedef enum {
+ /* WLAN MAC Operates in 2.4 GHz Band */
+ WLAN_MAC_2_4_BAND = 1 << 0,
+ /* WLAN MAC Operates in 5 GHz Band */
+ WLAN_MAC_5_0_BAND = 1 << 1,
+ /* WLAN MAC Operates in 6 GHz Band */
+ WLAN_MAC_6_0_BAND = 1 << 2,
+ /* WLAN MAC Operates in 60 GHz Band */
+ WLAN_MAC_60_0_BAND = 1 << 3,
+} wlan_mac_band;
+
+/* List of chre nan rtt state */
+typedef enum {
+ CHRE_PREEMPTED = 0,
+ CHRE_UNAVAILABLE = 1,
+ CHRE_AVAILABLE = 2,
+} chre_nan_rtt_state;
+
+typedef struct {
+ wifi_channel_width width;
+ int center_frequency0;
+ int center_frequency1;
+ int primary_frequency;
+} wifi_channel_spec;
+
+/*
+ * wifi_usable_channel specifies a channel frequency, bandwidth, and bitmask
+ * of modes allowed on the channel.
+ */
+typedef struct {
+ /* Channel frequency in MHz */
+ wifi_channel freq;
+ /* Channel operating width (20, 40, 80, 160, 320 etc.) */
+ wifi_channel_width width;
+ /* BIT MASK of BIT(WIFI_INTERFACE_*) represented by |wifi_interface_mode|
+ * Bitmask does not represent concurrency.
+ * Examples:
+ * - If a channel is usable only for STA, then only the WIFI_INTERFACE_STA
+ * bit would be set for that channel.
+ * - If 5GHz SAP is not allowed, then none of the 5GHz channels will have
+ * WIFI_INTERFACE_SOFTAP bit set.
+ * Note: TDLS bit is set only if there is a STA connection. TDLS bit is set
+ * on non-STA channels only if TDLS off channel is supported.
+ */
+ u32 iface_mode_mask;
+} wifi_usable_channel;
+
+/*
+ * wifi_usable_channel_filter
+ */
+typedef enum {
+ /* Filter Wifi channels that should be avoided due to cellular coex
+ * restrictions. Some Wifi channels can have extreme interference
+ * from/to cellular due to short frequency separation with neighboring
+ * cellular channels or when there is harmonic and intermodulation
+ * interference. Channels which only have some performance degradation
+ * (e.g. power back off is sufficient to deal with coexistence issue)
+ * can be included and should not be filtered out.
+ */
+ WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE = 1 << 0,
+ /* Filter channels due to concurrency state.
+ * Examples:
+ * - 5GHz SAP operation may be supported in standalone mode, but if
+ * there is STA connection on 5GHz DFS channel, none of the 5GHz
+ * channels are usable for SAP if device does not support DFS SAP mode.
+ * - P2P GO may not be supported on indoor channels in EU during
+ * standalone mode but if there is a STA connection on indoor channel,
+ * P2P GO may be supported by some vendors on the same STA channel.
+ */
+ WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY = 1 << 1,
+ /* This Filter queries Wifi channels and bands that are supported for
+ * NAN3.1 Instant communication mode. This filter should only be applied to NAN interface.
+ * If 5G is supported default discovery channel 149/44 is considered,
+ * If 5G is not supported then channel 6 has to be considered.
+ * Based on regulatory domain if channel 149 and 44 are restricted, channel 6 should
+ * be considered for instant communication channel
+ */
+ WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE = 1 << 2,
+} wifi_usable_channel_filter;
+
+typedef enum {
+ WIFI_SUCCESS = 0,
+ WIFI_ERROR_NONE = 0,
+ WIFI_ERROR_UNKNOWN = -1,
+ WIFI_ERROR_UNINITIALIZED = -2,
+ WIFI_ERROR_NOT_SUPPORTED = -3,
+ WIFI_ERROR_NOT_AVAILABLE = -4, // Not available right now, but try later
+ WIFI_ERROR_INVALID_ARGS = -5,
+ WIFI_ERROR_INVALID_REQUEST_ID = -6,
+ WIFI_ERROR_TIMED_OUT = -7,
+ WIFI_ERROR_TOO_MANY_REQUESTS = -8, // Too many instances of this request
+ WIFI_ERROR_OUT_OF_MEMORY = -9,
+ WIFI_ERROR_BUSY = -10,
+} wifi_error;
+
+typedef enum {
+ WIFI_ACCESS_CATEGORY_BEST_EFFORT = 0,
+ WIFI_ACCESS_CATEGORY_BACKGROUND = 1,
+ WIFI_ACCESS_CATEGORY_VIDEO = 2,
+ WIFI_ACCESS_CATEGORY_VOICE = 3
+} wifi_access_category;
+
+/* Antenna configuration */
+typedef enum {
+ WIFI_ANTENNA_UNSPECIFIED = 0,
+ WIFI_ANTENNA_1X1 = 1,
+ WIFI_ANTENNA_2X2 = 2,
+ WIFI_ANTENNA_3X3 = 3,
+ WIFI_ANTENNA_4X4 = 4,
+} wifi_antenna_configuration;
+
+/* Wifi Radio configuration */
+typedef struct {
+ /* Operating band */
+ wlan_mac_band band;
+ /* Antenna configuration */
+ wifi_antenna_configuration antenna_cfg;
+} wifi_radio_configuration;
+
+/* WiFi Radio Combination */
+typedef struct {
+ u32 num_radio_configurations;
+ wifi_radio_configuration radio_configurations[];
+} wifi_radio_combination;
+
+/* WiFi Radio combinations matrix */
+/* For Example in case of a chip which has two radios, where one radio is
+ * capable of 2.4GHz 2X2 only and another radio which is capable of either
+ * 5GHz or 6GHz 2X2, number of possible radio combinations in this case
+ * are 5 and possible combinations are
+ * {{{2G 2X2}}, //Standalone 2G
+ * {{5G 2X2}}, //Standalone 5G
+ * {{6G 2X2}}, //Standalone 6G
+ * {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
+ * {{2G 2X2}, {6G 2X2}}} //2G+6G DBS
+ * Note: Since this chip doesn’t support 5G+6G simultaneous operation
+ * as there is only one radio which can support both, So it can only
+ * do MCC 5G+6G. This table should not get populated with possible MCC
+ * configurations. This is only for simultaneous radio configurations
+ * (such as Standalone, multi band simultaneous or single band simultaneous).
+ */
+typedef struct {
+ u32 num_radio_combinations;
+ /* Each row represents possible radio combinations */
+ wifi_radio_combination radio_combinations[];
+} wifi_radio_combination_matrix;
+
+/* Initialize/Cleanup */
+
+wifi_error wifi_initialize(wifi_handle* handle);
+
+/**
+ * wifi_wait_for_driver
+ * Function should block until the driver is ready to proceed.
+ * Any errors from this function is considered fatal & will fail the HAL startup sequence.
+ *
+ * on success returns WIFI_SUCCESS
+ * on failure returns WIFI_ERROR_TIMED_OUT
+ */
+wifi_error wifi_wait_for_driver_ready(void);
+
+typedef void (*wifi_cleaned_up_handler)(wifi_handle handle);
+void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler);
+void wifi_event_loop(wifi_handle handle);
+
+/* Error handling */
+void wifi_get_error_info(wifi_error err, const char** msg); // return a pointer to a static string
+
+/* Feature enums */
+#define WIFI_FEATURE_INFRA (uint64_t)0x1 // Basic infrastructure mode
+#define WIFI_FEATURE_INFRA_5G (uint64_t)0x2 // Support for 5 GHz Band
+#define WIFI_FEATURE_HOTSPOT (uint64_t)0x4 // Support for GAS/ANQP
+#define WIFI_FEATURE_P2P (uint64_t)0x8 // Wifi-Direct
+#define WIFI_FEATURE_SOFT_AP (uint64_t)0x10 // Soft AP
+#define WIFI_FEATURE_GSCAN (uint64_t)0x20 // Google-Scan APIs
+#define WIFI_FEATURE_NAN (uint64_t)0x40 // Neighbor Awareness Networking
+#define WIFI_FEATURE_D2D_RTT (uint64_t)0x80 // Device-to-device RTT
+#define WIFI_FEATURE_D2AP_RTT (uint64_t)0x100 // Device-to-AP RTT
+#define WIFI_FEATURE_BATCH_SCAN (uint64_t)0x200 // Batched Scan (legacy)
+#define WIFI_FEATURE_PNO (uint64_t)0x400 // Preferred network offload
+#define WIFI_FEATURE_ADDITIONAL_STA (uint64_t)0x800 // Support for two STAs
+#define WIFI_FEATURE_TDLS (uint64_t)0x1000 // Tunnel directed link setup
+#define WIFI_FEATURE_TDLS_OFFCHANNEL (uint64_t)0x2000 // Support for TDLS off channel
+#define WIFI_FEATURE_EPR (uint64_t)0x4000 // Enhanced power reporting
+#define WIFI_FEATURE_AP_STA (uint64_t)0x8000 // Support for AP STA Concurrency
+#define WIFI_FEATURE_LINK_LAYER_STATS (uint64_t)0x10000 // Link layer stats collection
+#define WIFI_FEATURE_LOGGER (uint64_t)0x20000 // WiFi Logger
+#define WIFI_FEATURE_HAL_EPNO (uint64_t)0x40000 // WiFi PNO enhanced
+#define WIFI_FEATURE_RSSI_MONITOR (uint64_t)0x80000 // RSSI Monitor
+#define WIFI_FEATURE_MKEEP_ALIVE (uint64_t)0x100000 // WiFi mkeep_alive
+#define WIFI_FEATURE_CONFIG_NDO (uint64_t)0x200000 // ND offload configure
+#define WIFI_FEATURE_TX_TRANSMIT_POWER (uint64_t)0x400000 // Capture Tx transmit power levels
+#define WIFI_FEATURE_CONTROL_ROAMING (uint64_t)0x800000 // Enable/Disable firmware roaming
+#define WIFI_FEATURE_IE_WHITELIST (uint64_t)0x1000000 // Support Probe IE white listing
+#define WIFI_FEATURE_SCAN_RAND \
+ (uint64_t)0x2000000 // Support MAC & Probe Sequence Number randomization
+#define WIFI_FEATURE_SET_TX_POWER_LIMIT (uint64_t)0x4000000 // Support Tx Power Limit setting
+#define WIFI_FEATURE_USE_BODY_HEAD_SAR \
+ (uint64_t)0x8000000 // Support Using Body/Head Proximity for SAR
+#define WIFI_FEATURE_DYNAMIC_SET_MAC \
+ (uint64_t)0x10000000 // Support changing MAC address without iface reset(down and up)
+#define WIFI_FEATURE_SET_LATENCY_MODE (uint64_t)0x40000000 // Support Latency mode setting
+#define WIFI_FEATURE_P2P_RAND_MAC (uint64_t)0x80000000 // Support P2P MAC randomization
+#define WIFI_FEATURE_INFRA_60G (uint64_t)0x100000000 // Support for 60GHz Band
+// Add more features here
+
+#define IS_MASK_SET(mask, flags) (((flags) & (mask)) == (mask))
+
+#define IS_SUPPORTED_FEATURE(feature, featureSet) IS_MASK_SET(feature, featureSet)
+
+/* Feature set */
+wifi_error wifi_get_supported_feature_set(wifi_interface_handle handle, feature_set* set);
+
+/*
+ * Each row represents a valid feature combination;
+ * all other combinations are invalid!
+ */
+wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, int set_size_max,
+ feature_set set[], int* set_size);
+
+/* multiple interface support */
+
+wifi_error wifi_get_ifaces(wifi_handle handle, int* num_ifaces, wifi_interface_handle** ifaces);
+wifi_error wifi_get_iface_name(wifi_interface_handle iface, char* name, size_t size);
+wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char* name);
+
+/* STA + STA support - Supported if WIFI_FEATURE_ADDITIONAL_STA is set */
+
+/**
+ * Invoked to indicate that the provided iface is the primary STA iface when there are more
+ * than 1 STA iface concurrently active.
+ *
+ * Note: If the wifi firmware/chip cannot support multiple instances of any offload
+ * (like roaming, APF, rssi threshold, etc), the firmware should ensure that these
+ * offloads are at least enabled for the primary interface. If the new primary interface is
+ * already connected to a network, the firmware must switch all the offloads on
+ * this new interface without disconnecting.
+ */
+wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, wifi_interface_handle iface);
+
+/**
+ * When there are 2 or more simultaneous STA connections, this use case hint indicates what
+ * use-case is being enabled by the framework. This use case hint can be used by the firmware
+ * to modify various firmware configurations like:
+ * - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts.
+ * - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode.
+ * - Whether roaming, APF and other offloads needs to be enabled or not.
+ *
+ * Note:
+ * - This will be invoked before an active wifi connection is established on the second interface.
+ * - This use-case hint is implicitly void when the second STA interface is brought down.
+ */
+typedef enum {
+ /**
+ * Usage:
+ * - This will be sent down for make before break use-case.
+ * - Platform is trying to speculatively connect to a second network and evaluate it without
+ * disrupting the primary connection.
+ *
+ * Requirements for Firmware:
+ * - Do not reduce the number of tx/rx chains of primary connection.
+ * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
+ * the secondary connection (maybe 70/30 split).
+ * - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent of
+ * the primary STA:
+ * - Don’t optimize for DBS vs MCC/SCC
+ * - Should not impact the primary connection’s bssid selection:
+ * - Don’t downgrade chains of the existing primary connection.
+ * - Don’t optimize for DBS vs MCC/SCC.
+ */
+ WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+ /**
+ * Usage:
+ * - This will be sent down for any app requested peer to peer connections.
+ * - In this case, both the connections needs to be allocated equal resources.
+ * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
+ * framework.
+ *
+ * Requirements for Firmware:
+ * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
+ * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the secondary
+ * connection.
+ * - Prefer BSSID candidates which will help provide the best "overall" performance for both the
+ * connections.
+ */
+ WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED = 1
+} wifi_multi_sta_use_case;
+
+wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, wifi_multi_sta_use_case use_case);
+
+/* Configuration events */
+
+typedef struct {
+ void (*on_country_code_changed)(char code[2]); // We can get this from supplicant too
+
+ // More event handlers
+} wifi_event_handler;
+
+typedef struct {
+ char iface_name[IFNAMSIZ + 1];
+ wifi_channel channel;
+} wifi_iface_info;
+
+typedef struct {
+ u32 wlan_mac_id;
+ /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+ u32 mac_band;
+ /* Represents the connected Wi-Fi interfaces associated with each MAC */
+ int num_iface;
+ wifi_iface_info* iface_info;
+} wifi_mac_info;
+
+typedef struct {
+ void (*on_radio_mode_change)(wifi_request_id id, unsigned num_mac, wifi_mac_info* mac_info);
+} wifi_radio_mode_change_handler;
+
+typedef struct {
+ void (*on_rssi_threshold_breached)(wifi_request_id id, u8* cur_bssid, s8 cur_rssi);
+} wifi_rssi_event_handler;
+
+typedef struct {
+ void (*on_subsystem_restart)(const char* error);
+} wifi_subsystem_restart_handler;
+
+typedef struct {
+ void (*on_chre_nan_rtt_change)(chre_nan_rtt_state state);
+} wifi_chre_handler;
+
+wifi_error wifi_set_iface_event_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_event_handler eh);
+wifi_error wifi_reset_iface_event_handler(wifi_request_id id, wifi_interface_handle iface);
+
+wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs);
+wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
+ wifi_power_scenario scenario);
+wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle);
+wifi_error wifi_set_latency_mode(wifi_interface_handle handle, wifi_latency_mode mode);
+wifi_error wifi_map_dscp_access_category(wifi_handle handle, uint32_t start, uint32_t end,
+ uint32_t access_category);
+wifi_error wifi_reset_dscp_mapping(wifi_handle handle);
+
+wifi_error wifi_set_subsystem_restart_handler(wifi_handle handle,
+ wifi_subsystem_restart_handler handler);
+
+/**
+ * Wifi HAL Thermal Mitigation API
+ *
+ * wifi_handle : wifi global handle (note: this is not a interface specific
+ * command). Mitigation is expected to be applied across all active interfaces
+ * The implementation and the mitigation action mapping to each mode is chip
+ * specific. Mitigation will be active until Wifi is turned off or
+ * WIFI_MITIGATION_NONE mode is sent
+ *
+ * mode: Thermal mitigation mode
+ * WIFI_MITIGATION_NONE : Clear all Wifi thermal mitigation actions
+ * WIFI_MITIGATION_LIGHT : Light Throttling where UX is not impacted
+ * WIFI_MITIGATION_MODERATE : Moderate throttling where UX not largely impacted
+ * WIFI_MITIGATION_SEVERE : Severe throttling where UX is largely impacted
+ * WIFI_MITIGATION_CRITICAL : Platform has done everything to reduce power
+ * WIFI_MITIGATION_EMERGENCY: Key components in platform are shutting down
+ *
+ * completion_window
+ * Deadline (in milliseconds) to complete this request, value 0 implies apply
+ * immediately. Deadline is basically a relaxed limit and allows vendors to
+ * apply the mitigation within the window (if it cannot apply immediately)
+ *
+ * Return
+ * WIFI_ERROR_NOT_SUPPORTED : Chip does not support thermal mitigation
+ * WIFI_ERROR_BUSY : Mitigation is supported, but retry later
+ * WIFI_ERROR_NONE : Mitigation request has been accepted
+ */
+wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle, wifi_thermal_mode mode,
+ u32 completion_window);
+
+typedef struct rx_data_cnt_details_t {
+ int rx_unicast_cnt; /*Total rx unicast packet which woke up host */
+ int rx_multicast_cnt; /*Total rx multicast packet which woke up host */
+ int rx_broadcast_cnt; /*Total rx broadcast packet which woke up host */
+} RX_DATA_WAKE_CNT_DETAILS;
+
+typedef struct rx_wake_pkt_type_classification_t {
+ int icmp_pkt; /*wake icmp packet count */
+ int icmp6_pkt; /*wake icmp6 packet count */
+ int icmp6_ra; /*wake icmp6 RA packet count */
+ int icmp6_na; /*wake icmp6 NA packet count */
+ int icmp6_ns; /*wake icmp6 NS packet count */
+ // ToDo: Any more interesting classification to add?
+} RX_WAKE_PKT_TYPE_CLASSFICATION;
+
+typedef struct rx_multicast_cnt_t {
+ int ipv4_rx_multicast_addr_cnt; /*Rx wake packet was ipv4 multicast */
+ int ipv6_rx_multicast_addr_cnt; /*Rx wake packet was ipv6 multicast */
+ int other_rx_multicast_addr_cnt; /*Rx wake packet was non-ipv4 and non-ipv6*/
+} RX_MULTICAST_WAKE_DATA_CNT;
+
+/*
+ * Structure holding all the driver/firmware wake count reasons.
+ *
+ * Buffers for the array fields (cmd_event_wake_cnt/driver_fw_local_wake_cnt)
+ * are allocated and freed by the framework. The size of each allocated
+ * array is indicated by the corresponding |_cnt| field. HAL needs to fill in
+ * the corresponding |_used| field to indicate the number of elements used in
+ * the array.
+ */
+typedef struct wlan_driver_wake_reason_cnt_t {
+ int total_cmd_event_wake; /* Total count of cmd event wakes */
+ int* cmd_event_wake_cnt; /* Individual wake count array, each index a reason */
+ int cmd_event_wake_cnt_sz; /* Max number of cmd event wake reasons */
+ int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */
+
+ int total_driver_fw_local_wake; /* Total count of drive/fw wakes, for local reasons */
+ int* driver_fw_local_wake_cnt; /* Individual wake count array, each index a reason */
+ int driver_fw_local_wake_cnt_sz; /* Max number of local driver/fw wake reasons */
+ int driver_fw_local_wake_cnt_used; /* Number of local driver/fw wake reasons specific to the
+ driver */
+
+ int total_rx_data_wake; /* total data rx packets, that woke up host */
+ RX_DATA_WAKE_CNT_DETAILS rx_wake_details;
+ RX_WAKE_PKT_TYPE_CLASSFICATION rx_wake_pkt_classification_info;
+ RX_MULTICAST_WAKE_DATA_CNT rx_multicast_wake_pkt_info;
+} WLAN_DRIVER_WAKE_REASON_CNT;
+
+/* Wi-Fi coex channel avoidance support */
+
+#define WIFI_COEX_NO_POWER_CAP (int32_t)0x7FFFFFF
+
+typedef enum { WIFI_AWARE = 1 << 0, SOFTAP = 1 << 1, WIFI_DIRECT = 1 << 2 } wifi_coex_restriction;
+
+/**
+ * Representation of a Wi-Fi channel to be avoided for Wi-Fi coex channel avoidance.
+ *
+ * band is represented as an WLAN_MAC* enum value defined in wlan_mac_band.
+ * If power_cap_dbm is WIFI_COEX_NO_POWER_CAP, then no power cap should be applied if the specified
+ * channel is used.
+ */
+typedef struct {
+ wlan_mac_band band;
+ u32 channel;
+ s32 power_cap_dbm;
+} wifi_coex_unsafe_channel;
+
+/* include various feature headers */
+
+#include "gscan.h"
+#include "link_layer_stats.h"
+#include "roam.h"
+#include "rtt.h"
+#include "tdls.h"
+#include "wifi_cached_scan_results.h"
+#include "wifi_config.h"
+#include "wifi_logger.h"
+#include "wifi_nan.h"
+#include "wifi_offload.h"
+#include "wifi_twt.h"
+
+// wifi HAL function pointer table
+typedef struct {
+ wifi_error (*wifi_initialize)(wifi_handle*);
+ wifi_error (*wifi_wait_for_driver_ready)(void);
+ void (*wifi_cleanup)(wifi_handle, wifi_cleaned_up_handler);
+ void (*wifi_event_loop)(wifi_handle);
+ void (*wifi_get_error_info)(wifi_error, const char**);
+ wifi_error (*wifi_get_supported_feature_set)(wifi_interface_handle, feature_set*);
+ wifi_error (*wifi_get_concurrency_matrix)(wifi_interface_handle, int, feature_set*, int*);
+ wifi_error (*wifi_set_scanning_mac_oui)(wifi_interface_handle, unsigned char*);
+ wifi_error (*wifi_get_supported_channels)(wifi_handle, int*, wifi_channel*);
+ wifi_error (*wifi_is_epr_supported)(wifi_handle);
+ wifi_error (*wifi_get_ifaces)(wifi_handle, int*, wifi_interface_handle**);
+ wifi_error (*wifi_get_iface_name)(wifi_interface_handle, char* name, size_t);
+ wifi_error (*wifi_set_iface_event_handler)(wifi_request_id, wifi_interface_handle,
+ wifi_event_handler);
+ wifi_error (*wifi_reset_iface_event_handler)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_start_gscan)(wifi_request_id, wifi_interface_handle, wifi_scan_cmd_params,
+ wifi_scan_result_handler);
+ wifi_error (*wifi_stop_gscan)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_get_cached_gscan_results)(wifi_interface_handle, byte, int,
+ wifi_cached_scan_results*, int*);
+ wifi_error (*wifi_set_bssid_hotlist)(wifi_request_id, wifi_interface_handle,
+ wifi_bssid_hotlist_params, wifi_hotlist_ap_found_handler);
+ wifi_error (*wifi_reset_bssid_hotlist)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_set_significant_change_handler)(wifi_request_id, wifi_interface_handle,
+ wifi_significant_change_params,
+ wifi_significant_change_handler);
+ wifi_error (*wifi_reset_significant_change_handler)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_get_gscan_capabilities)(wifi_interface_handle, wifi_gscan_capabilities*);
+ wifi_error (*wifi_set_link_stats)(wifi_interface_handle, wifi_link_layer_params);
+ wifi_error (*wifi_get_link_stats)(wifi_request_id, wifi_interface_handle,
+ wifi_stats_result_handler);
+ wifi_error (*wifi_clear_link_stats)(wifi_interface_handle, u32, u32*, u8, u8*);
+ wifi_error (*wifi_get_valid_channels)(wifi_interface_handle, int, int, wifi_channel*, int*);
+ wifi_error (*wifi_rtt_range_request)(wifi_request_id, wifi_interface_handle, unsigned,
+ wifi_rtt_config[], wifi_rtt_event_handler);
+ wifi_error (*wifi_rtt_range_cancel)(wifi_request_id, wifi_interface_handle, unsigned,
+ mac_addr[]);
+ wifi_error (*wifi_get_rtt_capabilities)(wifi_interface_handle, wifi_rtt_capabilities*);
+ wifi_error (*wifi_rtt_get_responder_info)(wifi_interface_handle iface,
+ wifi_rtt_responder* responder_info);
+ wifi_error (*wifi_enable_responder)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_channel_info channel_hint,
+ unsigned max_duration_seconds,
+ wifi_rtt_responder* responder_info);
+ wifi_error (*wifi_disable_responder)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_set_nodfs_flag)(wifi_interface_handle, u32);
+ wifi_error (*wifi_start_logging)(wifi_interface_handle, u32, u32, u32, u32, char*);
+ wifi_error (*wifi_set_epno_list)(wifi_request_id, wifi_interface_handle,
+ const wifi_epno_params*, wifi_epno_handler);
+ wifi_error (*wifi_reset_epno_list)(wifi_request_id, wifi_interface_handle);
+ wifi_error (*wifi_set_country_code)(wifi_interface_handle, const char*);
+ wifi_error (*wifi_get_firmware_memory_dump)(wifi_interface_handle iface,
+ wifi_firmware_memory_dump_handler handler);
+ wifi_error (*wifi_set_log_handler)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_ring_buffer_data_handler handler);
+ wifi_error (*wifi_reset_log_handler)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_set_alert_handler)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_alert_handler handler);
+ wifi_error (*wifi_reset_alert_handler)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_get_firmware_version)(wifi_interface_handle iface, char* buffer,
+ int buffer_size);
+ wifi_error (*wifi_get_ring_buffers_status)(wifi_interface_handle iface, u32* num_rings,
+ wifi_ring_buffer_status* status);
+ wifi_error (*wifi_get_logger_supported_feature_set)(wifi_interface_handle iface,
+ unsigned int* support);
+ wifi_error (*wifi_get_ring_data)(wifi_interface_handle iface, char* ring_name);
+ wifi_error (*wifi_enable_tdls)(wifi_interface_handle, mac_addr, wifi_tdls_params*,
+ wifi_tdls_handler);
+ wifi_error (*wifi_disable_tdls)(wifi_interface_handle, mac_addr);
+ wifi_error (*wifi_get_tdls_status)(wifi_interface_handle, mac_addr, wifi_tdls_status*);
+ wifi_error (*wifi_get_tdls_capabilities)(wifi_interface_handle iface,
+ wifi_tdls_capabilities* capabilities);
+ wifi_error (*wifi_get_driver_version)(wifi_interface_handle iface, char* buffer,
+ int buffer_size);
+ wifi_error (*wifi_set_passpoint_list)(wifi_request_id id, wifi_interface_handle iface, int num,
+ wifi_passpoint_network* networks,
+ wifi_passpoint_event_handler handler);
+ wifi_error (*wifi_reset_passpoint_list)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_set_lci)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_lci_information* lci);
+ wifi_error (*wifi_set_lcr)(wifi_request_id id, wifi_interface_handle iface,
+ wifi_lcr_information* lcr);
+ wifi_error (*wifi_start_sending_offloaded_packet)(wifi_request_id id,
+ wifi_interface_handle iface, u16 ether_type,
+ u8* ip_packet, u16 ip_packet_len,
+ u8* src_mac_addr, u8* dst_mac_addr,
+ u32 period_msec);
+ wifi_error (*wifi_stop_sending_offloaded_packet)(wifi_request_id id,
+ wifi_interface_handle iface);
+ wifi_error (*wifi_start_rssi_monitoring)(wifi_request_id id, wifi_interface_handle iface,
+ s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh);
+ wifi_error (*wifi_stop_rssi_monitoring)(wifi_request_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_get_wake_reason_stats)(wifi_interface_handle iface,
+ WLAN_DRIVER_WAKE_REASON_CNT* wifi_wake_reason_cnt);
+ wifi_error (*wifi_configure_nd_offload)(wifi_interface_handle iface, u8 enable);
+ wifi_error (*wifi_get_driver_memory_dump)(wifi_interface_handle iface,
+ wifi_driver_memory_dump_callbacks callbacks);
+ wifi_error (*wifi_start_pkt_fate_monitoring)(wifi_interface_handle iface);
+ wifi_error (*wifi_get_tx_pkt_fates)(wifi_interface_handle handle,
+ wifi_tx_report* tx_report_bufs, size_t n_requested_fates,
+ size_t* n_provided_fates);
+ wifi_error (*wifi_get_rx_pkt_fates)(wifi_interface_handle handle,
+ wifi_rx_report* rx_report_bufs, size_t n_requested_fates,
+ size_t* n_provided_fates);
+
+ /* NAN functions */
+ wifi_error (*wifi_nan_enable_request)(transaction_id id, wifi_interface_handle iface,
+ NanEnableRequest* msg);
+ wifi_error (*wifi_nan_disable_request)(transaction_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_nan_publish_request)(transaction_id id, wifi_interface_handle iface,
+ NanPublishRequest* msg);
+ wifi_error (*wifi_nan_publish_cancel_request)(transaction_id id, wifi_interface_handle iface,
+ NanPublishCancelRequest* msg);
+ wifi_error (*wifi_nan_subscribe_request)(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeRequest* msg);
+ wifi_error (*wifi_nan_subscribe_cancel_request)(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeCancelRequest* msg);
+ wifi_error (*wifi_nan_transmit_followup_request)(transaction_id id, wifi_interface_handle iface,
+ NanTransmitFollowupRequest* msg);
+ wifi_error (*wifi_nan_stats_request)(transaction_id id, wifi_interface_handle iface,
+ NanStatsRequest* msg);
+ wifi_error (*wifi_nan_config_request)(transaction_id id, wifi_interface_handle iface,
+ NanConfigRequest* msg);
+ wifi_error (*wifi_nan_tca_request)(transaction_id id, wifi_interface_handle iface,
+ NanTCARequest* msg);
+ wifi_error (*wifi_nan_beacon_sdf_payload_request)(transaction_id id,
+ wifi_interface_handle iface,
+ NanBeaconSdfPayloadRequest* msg);
+ wifi_error (*wifi_nan_register_handler)(wifi_interface_handle iface,
+ NanCallbackHandler handlers);
+ wifi_error (*wifi_nan_get_version)(wifi_handle handle, NanVersion* version);
+ wifi_error (*wifi_nan_get_capabilities)(transaction_id id, wifi_interface_handle iface);
+ wifi_error (*wifi_nan_data_interface_create)(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+ wifi_error (*wifi_nan_data_interface_delete)(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+ wifi_error (*wifi_nan_data_request_initiator)(transaction_id id, wifi_interface_handle iface,
+ NanDataPathInitiatorRequest* msg);
+ wifi_error (*wifi_nan_data_indication_response)(transaction_id id, wifi_interface_handle iface,
+ NanDataPathIndicationResponse* msg);
+ wifi_error (*wifi_nan_data_end)(transaction_id id, wifi_interface_handle iface,
+ NanDataPathEndRequest* msg);
+ wifi_error (*wifi_select_tx_power_scenario)(wifi_interface_handle iface,
+ wifi_power_scenario scenario);
+ wifi_error (*wifi_reset_tx_power_scenario)(wifi_interface_handle iface);
+
+ /**
+ * Returns the chipset's hardware filtering capabilities:
+ * @param version pointer to version of the packet filter interpreter
+ * supported, filled in upon return. 0 indicates no support.
+ * @param max_len pointer to maximum size of the filter bytecode, filled in
+ * upon return.
+ */
+ wifi_error (*wifi_get_packet_filter_capabilities)(wifi_interface_handle handle, u32* version,
+ u32* max_len);
+ /**
+ * Programs the packet filter.
+ * @param program pointer to the program byte-code.
+ * @param len length of the program byte-code.
+ */
+ wifi_error (*wifi_set_packet_filter)(wifi_interface_handle handle, const u8* program, u32 len);
+ wifi_error (*wifi_read_packet_filter)(wifi_interface_handle handle, u32 src_offset,
+ u8* host_dst, u32 length);
+ wifi_error (*wifi_get_roaming_capabilities)(wifi_interface_handle handle,
+ wifi_roaming_capabilities* caps);
+ wifi_error (*wifi_enable_firmware_roaming)(wifi_interface_handle handle,
+ fw_roaming_state_t state);
+ wifi_error (*wifi_configure_roaming)(wifi_interface_handle handle,
+ wifi_roaming_config* roaming_config);
+ wifi_error (*wifi_set_radio_mode_change_handler)(wifi_request_id id,
+ wifi_interface_handle iface,
+ wifi_radio_mode_change_handler eh);
+ wifi_error (*wifi_set_latency_mode)(wifi_interface_handle iface, wifi_latency_mode mode);
+ wifi_error (*wifi_set_thermal_mitigation_mode)(wifi_handle handle, wifi_thermal_mode mode,
+ u32 completion_window);
+ wifi_error (*wifi_map_dscp_access_category)(wifi_handle handle, u32 start, u32 end,
+ u32 access_category);
+ wifi_error (*wifi_reset_dscp_mapping)(wifi_handle handle);
+
+ wifi_error (*wifi_virtual_interface_create)(wifi_handle handle, const char* ifname,
+ wifi_interface_type iface_type);
+ wifi_error (*wifi_virtual_interface_delete)(wifi_handle handle, const char* ifname);
+
+ wifi_error (*wifi_set_subsystem_restart_handler)(wifi_handle handle,
+ wifi_subsystem_restart_handler handler);
+
+ /**
+ * Allow vendor HAL to choose interface name when creating
+ * an interface. This can be implemented by chips with their
+ * own interface naming policy.
+ * If not implemented, the default naming will be used.
+ */
+ wifi_error (*wifi_get_supported_iface_name)(wifi_handle handle, u32 iface_type, char* name,
+ size_t len);
+
+ /**
+ * Perform early initialization steps that are needed when WIFI
+ * is disabled.
+ * If the function returns failure, it means the vendor HAL is unusable
+ * (for example, if chip hardware is not installed) and no further
+ * functions should be called.
+ */
+ wifi_error (*wifi_early_initialize)(void);
+
+ /**
+ * Get supported feature set which are chip-global, that is
+ * not dependent on any created interface.
+ */
+ wifi_error (*wifi_get_chip_feature_set)(wifi_handle handle, feature_set* set);
+
+ /**
+ * Invoked to indicate that the provided iface is the primary STA iface when there are more
+ * than 1 STA iface concurrently active.
+ */
+ wifi_error (*wifi_multi_sta_set_primary_connection)(wifi_handle handle,
+ wifi_interface_handle iface);
+
+ /**
+ * When there are 2 simultaneous STA connections, this use case hint
+ * indicates what STA + STA use-case is being enabled by the framework.
+ */
+ wifi_error (*wifi_multi_sta_set_use_case)(wifi_handle handle, wifi_multi_sta_use_case use_case);
+
+ /**
+ * Invoked to indicate that the following list of wifi_coex_unsafe_channel should be avoided
+ * with the specified restrictions.
+ * @param unsafeChannels list of current |wifi_coex_unsafe_channel| to avoid.
+ * @param restrictions bitmask of |wifi_coex_restriction| indicating wifi interfaces to
+ * restrict from the current unsafe channels.
+ */
+ wifi_error (*wifi_set_coex_unsafe_channels)(wifi_handle handle, u32 num_channels,
+ wifi_coex_unsafe_channel* unsafeChannels,
+ u32 restrictions);
+
+ /**
+ * Invoked to set voip optimization mode for the provided STA iface
+ */
+ wifi_error (*wifi_set_voip_mode)(wifi_interface_handle iface, wifi_voip_mode mode);
+
+ /**@brief twt_register_handler
+ * Request to register TWT callback before sending any TWT request
+ * @param wifi_interface_handle:
+ * @param TwtCallbackHandler: callback function pointers
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_twt_register_handler)(wifi_interface_handle iface,
+ TwtCallbackHandler handler);
+
+ /**@brief twt_get_capability
+ * Request TWT capability
+ * @param wifi_interface_handle:
+ * @return Synchronous wifi_error and TwtCapabilitySet
+ */
+ wifi_error (*wifi_twt_get_capability)(wifi_interface_handle iface,
+ TwtCapabilitySet* twt_cap_set);
+
+ /**@brief twt_setup_request
+ * Request to send TWT setup frame
+ * @param wifi_interface_handle:
+ * @param TwtSetupRequest: detailed parameters of setup request
+ * @return Synchronous wifi_error
+ * @return Asynchronous EventTwtSetupResponse CB return TwtSetupResponse
+ */
+ wifi_error (*wifi_twt_setup_request)(wifi_interface_handle iface, TwtSetupRequest* msg);
+
+ /**@brief twt_teardown_request
+ * Request to send TWT teardown frame
+ * @param wifi_interface_handle:
+ * @param TwtTeardownRequest: detailed parameters of teardown request
+ * @return Synchronous wifi_error
+ * @return Asynchronous EventTwtTeardownCompletion CB return TwtTeardownCompletion
+ * TwtTeardownCompletion may also be received due to other events
+ * like CSA, BTCX, TWT scheduler, MultiConnection, peer-initiated teardown, etc.
+ */
+ wifi_error (*wifi_twt_teardown_request)(wifi_interface_handle iface, TwtTeardownRequest* msg);
+
+ /**@brief twt_info_frame_request
+ * Request to send TWT info frame
+ * @param wifi_interface_handle:
+ * @param TwtInfoFrameRequest: detailed parameters in info frame
+ * @return Synchronous wifi_error
+ * @return Asynchronous EventTwtInfoFrameReceived CB return TwtInfoFrameReceived
+ * Driver may also receive Peer-initiated TwtInfoFrame
+ */
+ wifi_error (*wifi_twt_info_frame_request)(wifi_interface_handle iface,
+ TwtInfoFrameRequest* msg);
+
+ /**@brief twt_get_stats
+ * Request to get TWT stats
+ * @param wifi_interface_handle:
+ * @param config_id: configuration ID of TWT request
+ * @return Synchronous wifi_error and TwtStats
+ */
+ wifi_error (*wifi_twt_get_stats)(wifi_interface_handle iface, u8 config_id, TwtStats* stats);
+
+ /**@brief twt_clear_stats
+ * Request to clear TWT stats
+ * @param wifi_interface_handle:
+ * @param config_id: configuration ID of TWT request
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_twt_clear_stats)(wifi_interface_handle iface, u8 config_id);
+
+ /**
+ * Invoked to set DTIM configuration when the host is in the suspend mode
+ * @param wifi_interface_handle:
+ * @param multiplier: when STA in the power saving mode, the wake up interval will be set to
+ * 1) multiplier * DTIM period if multiplier > 0.
+ * 2) the device default value if multiplier <=0
+ * Some implementations may apply an additional cap to wake up interval in the case of 1).
+ */
+ wifi_error (*wifi_set_dtim_config)(wifi_interface_handle handle, u32 multiplier);
+
+ /**@brief wifi_get_usable_channels
+ * Request list of usable channels for the requested bands and modes. Usable
+ * implies channel is allowed as per regulatory for the current country code
+ * and not restricted due to other hard limitations (e.g. DFS, Coex) In
+ * certain modes (e.g. STA+SAP) there could be other hard restrictions
+ * since MCC operation many not be supported by SAP. This API also allows
+ * driver to return list of usable channels for each mode uniquely to
+ * distinguish cases where only a limited set of modes are allowed on
+ * a given channel e.g. srd channels may be supported for P2P but not
+ * for SAP or P2P-Client may be allowed on an indoor channel but P2P-GO
+ * may not be allowed. This API is not interface specific and will be
+ * used to query capabilities of driver in terms of what modes (STA, SAP,
+ * P2P_CLI, P2P_GO, NAN, TDLS) can be supported on each of the channels.
+ * @param handle global wifi_handle
+ * @param band_mask BIT MASK of WLAN_MAC* as represented by |wlan_mac_band|
+ * @param iface_mode_mask BIT MASK of BIT(WIFI_INTERFACE_*) represented by
+ * |wifi_interface_mode|. Bitmask respresents all the modes that the
+ * caller is interested in (e.g. STA, SAP, WFD-CLI, WFD-GO, TDLS, NAN).
+ * Note: Bitmask does not represent concurrency matrix. If the caller
+ * is interested in CLI, GO modes, the iface_mode_mask would be set
+ * to WIFI_INTERFACE_P2P_CLIENT|WIFI_INTERFACE_P2P_GO.
+ * @param filter_mask BIT MASK of WIFI_USABLE_CHANNEL_FILTER_* represented by
+ * |wifi_usable_channel_filter|. Indicates if the channel list should
+ * be filtered based on additional criteria. If filter_mask is not
+ * specified, driver should return list of usable channels purely
+ * based on regulatory constraints.
+ * @param max_size maximum number of |wifi_usable_channel|
+ * @param size actual number of |wifi_usable_channel| entries returned by driver
+ * @param channels list of usable channels represented by |wifi_usable_channel|
+ */
+ wifi_error (*wifi_get_usable_channels)(wifi_handle handle, u32 band_mask, u32 iface_mode_mask,
+ u32 filter_mask, u32 max_size, u32* size,
+ wifi_usable_channel* channels);
+
+ /**
+ * Trigger wifi subsystem restart to reload firmware
+ */
+ wifi_error (*wifi_trigger_subsystem_restart)(wifi_handle handle);
+
+ /**
+ * Invoked to set that the device is operating in an indoor environment.
+ * @param handle global wifi_handle
+ * @param isIndoor: true if the device is operating in an indoor
+ * environment, false otherwise.
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_set_indoor_state)(wifi_handle handle, bool isIndoor);
+
+ /**@brief wifi_get_supported_radio_combinations_matrix
+ * Request all the possible radio combinations this device can offer.
+ * @param handle global wifi_handle
+ * @param max_size maximum size allocated for filling the wifi_radio_combination_matrix
+ * @param wifi_radio_combination_matrix to return all the possible radio
+ * combinations.
+ * @param size actual size of wifi_radio_combination_matrix returned from
+ * lower layer
+ *
+ */
+ wifi_error (*wifi_get_supported_radio_combinations_matrix)(
+ wifi_handle handle, u32 max_size, u32* size,
+ wifi_radio_combination_matrix* radio_combination_matrix);
+
+ /**@brief wifi_nan_rtt_chre_enable_request
+ * Request to enable CHRE NAN RTT
+ * @param transaction_id: NAN transaction id
+ * @param wifi_interface_handle
+ * @param NanEnableRequest request message
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_nan_rtt_chre_enable_request)(transaction_id id, wifi_interface_handle iface,
+ NanEnableRequest* msg);
+
+ /**@brief wifi_nan_rtt_chre_disable_request
+ * Request to disable CHRE NAN RTT
+ * @param transaction_id: NAN transaction id
+ * @param wifi_interface_handle
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_nan_rtt_chre_disable_request)(transaction_id id, wifi_interface_handle iface);
+
+ /**@brief wifi_chre_register_handler
+ * register a handler to get the state of CHR
+ * @param wifi_interface_handle
+ * @param wifi_chre_handler: callback function pointer
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_chre_register_handler)(wifi_interface_handle iface,
+ wifi_chre_handler handler);
+
+ /**@brief wifi_enable_tx_power_limits
+ * Enable WiFi Tx power limis
+ * @param wifi_interface_handle
+ * @param isEnable : If enable TX limit or not
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_enable_tx_power_limits)(wifi_interface_handle iface, bool isEnable);
+
+ /**@brief wifi_get_cached_scan_results
+ * Retrieve scan results cached in wifi firmware
+ * @param wifi_interface_handle
+ * @param wifi_cached_scan_result_handler : callback function pointer
+ * @return Synchronous wifi_error
+ */
+ wifi_error (*wifi_get_cached_scan_results)(wifi_interface_handle iface,
+ wifi_cached_scan_result_handler handler);
+ /*
+ * when adding new functions make sure to add stubs in
+ * hal_tool.cpp::init_wifi_stub_hal_func_table
+ */
+} wifi_hal_fn;
+
+wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn* fn);
+typedef wifi_error (*init_wifi_vendor_hal_func_table_t)(wifi_hal_fn* fn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/wifi/1.6/default/hal_legacy/wifi_logger.h b/wifi/1.6/default/hal_legacy/wifi_logger.h
new file mode 100644
index 0000000..76d6f74
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_logger.h
@@ -0,0 +1,650 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_LOGGER_H
+#define __WIFI_HAL_LOGGER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define LOGGER_MAJOR_VERSION 1
+#define LOGGER_MINOR_VERSION 0
+#define LOGGER_MICRO_VERSION 0
+
+/**
+ * WiFi logger life cycle is as follow:
+ *
+ * - At initialization time, framework will call wifi_get_ring_buffers_status
+ * so as to obtain the names and list of supported buffers.
+ * - When WiFi operation start framework will call wifi_start_logging
+ * so as to trigger log collection.
+ * - Developper UI will provide an option to the user, so as it can set the verbose level
+ * of individual buffer as reported by wifi_get_ring_buffers_status.
+ * - During wifi operations, driver will periodically report per ring data to framework
+ * by invoking the on_ring_buffer_data call back.
+ * - when capturing a bug report, framework will indicate to driver that all the data
+ * has to be uploaded, urgently, by calling wifi_get_ring_data.
+ *
+ * The data uploaded by driver will be stored by framework in separate files, with one stream
+ * of file per ring.
+ * Framework will store the files in pcapng format, allowing for easy merging and parsing
+ * with network analyzer tools.
+ */
+
+typedef int wifi_ring_buffer_id;
+
+#define PER_PACKET_ENTRY_FLAGS_DIRECTION_TX 1 // 0: TX, 1: RX
+#define PER_PACKET_ENTRY_FLAGS_TX_SUCCESS \
+ 2 // whether packet was transmitted or
+ // received/decrypted successfully
+#define PER_PACKET_ENTRY_FLAGS_80211_HEADER 4 // has full 802.11 header, else has 802.3 header
+#define PER_PACKET_ENTRY_FLAGS_PROTECTED 8 // whether packet was encrypted
+
+typedef struct {
+ u8 flags;
+ u8 tid; // transmit or received tid
+ u16 MCS; // modulation and bandwidth
+ u8 rssi; // TX: RSSI of ACK for that packet
+ // RX: RSSI of packet
+ u8 num_retries; // number of attempted retries
+ u16 last_transmit_rate; // last transmit rate in .5 mbps
+ u16 link_layer_transmit_sequence; // transmit/reeive sequence for that MPDU packet
+ u64 firmware_entry_timestamp; // TX: firmware timestamp (us) when packet is queued within
+ // firmware buffer for SDIO/HSIC or into PCIe buffer
+ // RX: firmware receive timestamp
+ u64 start_contention_timestamp; // firmware timestamp (us) when packet start contending for the
+ // medium for the first time, at head of its AC queue,
+ // or as part of an MPDU or A-MPDU. This timestamp is
+ // not updated for each retry, only the first transmit attempt.
+ u64 transmit_success_timestamp; // fimrware timestamp (us) when packet is successfully
+ // transmitted or aborted because it has exhausted
+ // its maximum number of retries.
+ u8 data[0]; // packet data. The length of packet data is determined by the entry_size field of
+ // the wifi_ring_buffer_entry structure. It is expected that first bytes of the
+ // packet, or packet headers only (up to TCP or RTP/UDP headers)
+ // will be copied into the ring
+} __attribute__((packed)) wifi_ring_per_packet_status_entry;
+
+/* Below events refer to the wifi_connectivity_event ring and shall be supported */
+#define WIFI_EVENT_ASSOCIATION_REQUESTED 0 // driver receives association command from kernel
+#define WIFI_EVENT_AUTH_COMPLETE 1
+#define WIFI_EVENT_ASSOC_COMPLETE 2
+#define WIFI_EVENT_FW_AUTH_STARTED 3 // fw event indicating auth frames are sent
+#define WIFI_EVENT_FW_ASSOC_STARTED 4 // fw event indicating assoc frames are sent
+#define WIFI_EVENT_FW_RE_ASSOC_STARTED 5 // fw event indicating reassoc frames are sent
+#define WIFI_EVENT_DRIVER_SCAN_REQUESTED 6
+#define WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND 7
+#define WIFI_EVENT_DRIVER_SCAN_COMPLETE 8
+#define WIFI_EVENT_G_SCAN_STARTED 9
+#define WIFI_EVENT_G_SCAN_COMPLETE 10
+#define WIFI_EVENT_DISASSOCIATION_REQUESTED 11
+#define WIFI_EVENT_RE_ASSOCIATION_REQUESTED 12
+#define WIFI_EVENT_ROAM_REQUESTED 13
+#define WIFI_EVENT_BEACON_RECEIVED \
+ 14 // received beacon from AP (event enabled
+ // only in verbose mode)
+#define WIFI_EVENT_ROAM_SCAN_STARTED 15 // firmware has triggered a roam scan (not g-scan)
+#define WIFI_EVENT_ROAM_SCAN_COMPLETE 16 // firmware has completed a roam scan (not g-scan)
+#define WIFI_EVENT_ROAM_SEARCH_STARTED \
+ 17 // firmware has started searching for roam
+ // candidates (with reason =xx)
+#define WIFI_EVENT_ROAM_SEARCH_STOPPED \
+ 18 // firmware has stopped searching for roam
+ // candidates (with reason =xx)
+#define WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT 20 // received channel switch anouncement from AP
+#define WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START \
+ 21 // fw start transmit eapol frame, with
+ // EAPOL index 1-4
+#define WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP \
+ 22 // fw gives up eapol frame, with rate,
+ // success/failure and number retries
+#define WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED \
+ 23 // kernel queue EAPOL for transmission
+ // in driver with EAPOL index 1-4
+#define WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED \
+ 24 // with rate, regardless of the fact that
+ // EAPOL frame is accepted or rejected by fw
+#define WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED \
+ 26 // with rate, and eapol index, driver has
+ // received EAPOL frame and will queue it up
+ // to wpa_supplicant
+#define WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE 27 // with success/failure, parameters
+#define WIFI_EVENT_BT_COEX_BT_SCO_START 28
+#define WIFI_EVENT_BT_COEX_BT_SCO_STOP 29
+#define WIFI_EVENT_BT_COEX_BT_SCAN_START \
+ 30 // for paging/scan etc., when BT starts transmiting
+ // twice per BT slot
+#define WIFI_EVENT_BT_COEX_BT_SCAN_STOP 31
+#define WIFI_EVENT_BT_COEX_BT_HID_START 32
+#define WIFI_EVENT_BT_COEX_BT_HID_STOP 33
+#define WIFI_EVENT_ROAM_AUTH_STARTED 34 // fw sends auth frame in roaming to next candidate
+#define WIFI_EVENT_ROAM_AUTH_COMPLETE 35 // fw receive auth confirm from ap
+#define WIFI_EVENT_ROAM_ASSOC_STARTED \
+ 36 // firmware sends assoc/reassoc frame in
+ // roaming to next candidate
+#define WIFI_EVENT_ROAM_ASSOC_COMPLETE 37 // firmware receive assoc/reassoc confirm from ap
+#define WIFI_EVENT_G_SCAN_STOP 38 // firmware sends stop G_SCAN
+#define WIFI_EVENT_G_SCAN_CYCLE_STARTED 39 // firmware indicates G_SCAN scan cycle started
+#define WIFI_EVENT_G_SCAN_CYCLE_COMPLETED 40 // firmware indicates G_SCAN scan cycle completed
+#define WIFI_EVENT_G_SCAN_BUCKET_STARTED \
+ 41 // firmware indicates G_SCAN scan start
+ // for a particular bucket
+#define WIFI_EVENT_G_SCAN_BUCKET_COMPLETED \
+ 42 // firmware indicates G_SCAN scan completed for
+ // for a particular bucket
+#define WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE \
+ 43 // Event received from firmware about G_SCAN scan
+ // results being available
+#define WIFI_EVENT_G_SCAN_CAPABILITIES \
+ 44 // Event received from firmware with G_SCAN
+ // capabilities
+#define WIFI_EVENT_ROAM_CANDIDATE_FOUND \
+ 45 // Event received from firmware when eligible
+ // candidate is found
+#define WIFI_EVENT_ROAM_SCAN_CONFIG \
+ 46 // Event received from firmware when roam scan
+ // configuration gets enabled or disabled
+#define WIFI_EVENT_AUTH_TIMEOUT 47 // firmware/driver timed out authentication
+#define WIFI_EVENT_ASSOC_TIMEOUT 48 // firmware/driver timed out association
+#define WIFI_EVENT_MEM_ALLOC_FAILURE 49 // firmware/driver encountered allocation failure
+#define WIFI_EVENT_DRIVER_PNO_ADD 50 // driver added a PNO network in firmware
+#define WIFI_EVENT_DRIVER_PNO_REMOVE 51 // driver removed a PNO network in firmware
+#define WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND \
+ 52 // driver received PNO networks
+ // found indication from firmware
+#define WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED 53 // driver triggered a scan for PNO networks
+#define WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND \
+ 54 // driver received scan results
+ // of PNO networks
+#define WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE \
+ 55 // driver updated scan results from
+ // PNO networks to cfg80211
+
+/**
+ * Parameters of wifi logger events are TLVs
+ * Event parameters tags are defined as:
+ */
+#define WIFI_TAG_VENDOR_SPECIFIC 0 // take a byte stream as parameter
+#define WIFI_TAG_BSSID 1 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR 2 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_SSID 3 // takes a 32 bytes SSID address as parameter
+#define WIFI_TAG_STATUS 4 // takes an integer as parameter
+#define WIFI_TAG_CHANNEL_SPEC 5 // takes one or more wifi_channel_spec as parameter
+#define WIFI_TAG_WAKE_LOCK_EVENT 6 // takes a wake_lock_event struct as parameter
+#define WIFI_TAG_ADDR1 7 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR2 8 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR3 9 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_ADDR4 10 // takes a 6 bytes MAC address as parameter
+#define WIFI_TAG_TSF 11 // take a 64 bits TSF value as parameter
+#define WIFI_TAG_IE \
+ 12 // take one or more specific 802.11 IEs parameter,
+ // IEs are in turn indicated in TLV format as per
+ // 802.11 spec
+#define WIFI_TAG_INTERFACE 13 // take interface name as parameter
+#define WIFI_TAG_REASON_CODE 14 // take a reason code as per 802.11 as parameter
+#define WIFI_TAG_RATE_MBPS 15 // take a wifi rate in 0.5 mbps
+#define WIFI_TAG_REQUEST_ID 16 // take an integer as parameter
+#define WIFI_TAG_BUCKET_ID 17 // take an integer as parameter
+#define WIFI_TAG_GSCAN_PARAMS 18 // takes a wifi_scan_cmd_params struct as parameter
+#define WIFI_TAG_GSCAN_CAPABILITIES 19 // takes a wifi_gscan_capabilities struct as parameter
+#define WIFI_TAG_SCAN_ID 20 // take an integer as parameter
+#define WIFI_TAG_RSSI 21 // take an integer as parameter
+#define WIFI_TAG_CHANNEL 22 // take an integer as parameter
+#define WIFI_TAG_LINK_ID 23 // take an integer as parameter
+#define WIFI_TAG_LINK_ROLE 24 // take an integer as parameter
+#define WIFI_TAG_LINK_STATE 25 // take an integer as parameter
+#define WIFI_TAG_LINK_TYPE 26 // take an integer as parameter
+#define WIFI_TAG_TSCO 27 // take an integer as parameter
+#define WIFI_TAG_RSCO 28 // take an integer as parameter
+#define WIFI_TAG_EAPOL_MESSAGE_TYPE \
+ 29 // take an integer as parameter
+ // M1-1, M2-2, M3-3, M4-4
+
+typedef struct {
+ u16 tag;
+ u16 length; // length of value
+ u8 value[0];
+} __attribute__((packed)) tlv_log;
+
+typedef struct {
+ u16 event;
+ tlv_log tlvs[0]; // separate parameter structure per event to be provided and optional data
+ // the event_data is expected to include an official android part, with some
+ // parameter as transmit rate, num retries, num scan result found etc...
+ // as well, event_data can include a vendor proprietary part which is
+ // understood by the developer only.
+} __attribute__((packed)) wifi_ring_buffer_driver_connectivity_event;
+
+/**
+ * Ring buffer name for power events ring. note that power event are extremely frequents
+ * and thus should be stored in their own ring/file so as not to clobber connectivity events.
+ */
+typedef struct {
+ int status; // 0 taken, 1 released
+ int reason; // reason why this wake lock is taken
+ char name[0]; // null terminated
+} __attribute__((packed)) wake_lock_event;
+
+typedef struct {
+ u16 event;
+ tlv_log tlvs[0];
+} __attribute__((packed)) wifi_power_event;
+
+/**
+ * This structure represent a logger entry within a ring buffer.
+ * Wifi driver are responsible to manage the ring buffer and write the debug
+ * information into those rings.
+ *
+ * In general, the debug entries can be used to store meaningful 802.11 information (SME, MLME,
+ * connection and packet statistics) as well as vendor proprietary data that is specific to a
+ * specific driver or chipset.
+ * Binary entries can be used so as to store packet data or vendor specific information and
+ * will be treated as blobs of data by android.
+ *
+ * A user land process will be started by framework so as to periodically retrieve the
+ * data logged by drivers into their ring buffer, store the data into log files and include
+ * the logs into android bugreports.
+ */
+enum {
+ RING_BUFFER_ENTRY_FLAGS_HAS_BINARY = (1 << (0)), // set for binary entries
+ RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1)) // set if 64 bits timestamp is present
+};
+
+enum {
+ ENTRY_TYPE_CONNECT_EVENT = 1,
+ ENTRY_TYPE_PKT,
+ ENTRY_TYPE_WAKE_LOCK,
+ ENTRY_TYPE_POWER_EVENT,
+ ENTRY_TYPE_DATA
+};
+
+typedef struct {
+ u16 entry_size; // the size of payload excluding the header.
+ u8 flags;
+ u8 type; // entry type
+ u64 timestamp; // present if has_timestamp bit is set.
+} __attribute__((packed)) wifi_ring_buffer_entry;
+
+#define WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES 0x00000001 // set if binary entries are present
+#define WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES 0x00000002 // set if ascii entries are present
+
+/* ring buffer params */
+/**
+ * written_bytes and read_bytes implement a producer consumer API
+ * hence written_bytes >= read_bytes
+ * a modulo arithmetic of the buffer size has to be applied to those counters:
+ * actual offset into ring buffer = written_bytes % ring_buffer_byte_size
+ *
+ */
+typedef struct {
+ u8 name[32];
+ u32 flags;
+ wifi_ring_buffer_id ring_id; // unique integer representing the ring
+ u32 ring_buffer_byte_size; // total memory size allocated for the buffer
+ u32 verbose_level; // verbose level for ring buffer
+ u32 written_bytes; // number of bytes that was written to the buffer by driver,
+ // monotonously increasing integer
+ u32 read_bytes; // number of bytes that was read from the buffer by user land,
+ // monotonously increasing integer
+ u32 written_records; // number of records that was written to the buffer by driver,
+ // monotonously increasing integer
+} wifi_ring_buffer_status;
+
+/**
+ * Callback for reporting ring data
+ *
+ * The ring buffer data collection is event based:
+ * - Driver calls on_ring_buffer_data when new records are available, the wifi_ring_buffer_status
+ * passed up to framework in the call back indicates to framework if more data is available in
+ * the ring buffer. It is not expected that driver will necessarily always empty the ring
+ * immediately as data is available, instead driver will report data every X seconds or if
+ * N bytes are available.
+ * - In the case where a bug report has to be captured, framework will require driver to upload
+ * all data immediately. This is indicated to driver when framework calls wifi_get_ringdata.
+ * When framework calls wifi_get_ring_data, driver will start sending all available data in the
+ * indicated ring by repeatedly invoking the on_ring_buffer_data callback.
+ *
+ * The callback is called by log handler whenever ring data comes in driver.
+ */
+typedef struct {
+ void (*on_ring_buffer_data)(char* ring_name, char* buffer, int buffer_size,
+ wifi_ring_buffer_status* status);
+} wifi_ring_buffer_data_handler;
+
+/**
+ * API to set the log handler for getting ring data
+ * - Only a single instance of log handler can be instantiated for each ring buffer.
+ */
+wifi_error wifi_set_log_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_ring_buffer_data_handler handler);
+
+/* API to reset the log handler */
+wifi_error wifi_reset_log_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/**
+ * Callback for reporting FW dump
+ *
+ * The buffer data collection is event based such as FW health check or FW dump.
+ * The callback is called by alert handler.
+ */
+typedef struct {
+ void (*on_alert)(wifi_request_id id, char* buffer, int buffer_size, int err_code);
+} wifi_alert_handler;
+
+/*
+ * API to set the alert handler for the alert case in Wi-Fi Chip
+ * - Only a single instance of alert handler can be instantiated.
+ */
+wifi_error wifi_set_alert_handler(wifi_request_id id, wifi_interface_handle iface,
+ wifi_alert_handler handler);
+
+/* API to reset the alert handler */
+wifi_error wifi_reset_alert_handler(wifi_request_id id, wifi_interface_handle iface);
+
+/* API for framework to indicate driver has to upload and drain all data of a given ring */
+wifi_error wifi_get_ring_data(wifi_interface_handle iface, char* ring_name);
+
+/**
+ * API to trigger the debug collection.
+ * Unless his API is invoked - logging is not triggered.
+ * - Verbose_level 0 corresponds to no collection,
+ * and it makes log handler stop by no more events from driver.
+ * - Verbose_level 1 correspond to normal log level, with minimal user impact.
+ * This is the default value.
+ * - Verbose_level 2 are enabled when user is lazily trying to reproduce a problem,
+ * wifi performances and power can be impacted but device should not otherwise be
+ * significantly impacted.
+ * - Verbose_level 3+ are used when trying to actively debug a problem.
+ *
+ * ring_name represent the name of the ring for which data collection shall start.
+ *
+ * flags: TBD parameter used to enable/disable specific events on a ring
+ * max_interval: maximum interval in seconds for driver to invoke on_ring_buffer_data,
+ * ignore if zero
+ * min_data_size: minimum data size in buffer for driver to invoke on_ring_buffer_data,
+ * ignore if zero
+ */
+wifi_error wifi_start_logging(wifi_interface_handle iface, u32 verbose_level, u32 flags,
+ u32 max_interval_sec, u32 min_data_size, char* ring_name);
+
+/**
+ * API to get the status of all ring buffers supported by driver.
+ * - Caller is responsible to allocate / free ring buffer status.
+ * - Maximum no of ring buffer would be 10.
+ */
+wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface, u32* num_rings,
+ wifi_ring_buffer_status* status);
+
+/**
+ * Synchronous memory dump by user request.
+ * - Caller is responsible to store memory dump data into a local,
+ * e.g., /data/misc/wifi/memdump.bin
+ */
+typedef struct {
+ void (*on_firmware_memory_dump)(char* buffer, int buffer_size);
+} wifi_firmware_memory_dump_handler;
+
+/**
+ * API to collect a firmware memory dump for a given iface by async memdump event.
+ * - Triggered by Alerthandler, esp. when FW problem or FW health check happens
+ * - Caller is responsible to store fw dump data into a local,
+ * e.g., /data/misc/wifi/alertdump-1.bin
+ */
+wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface,
+ wifi_firmware_memory_dump_handler handler);
+
+/**
+ * API to collect a firmware version string.
+ * - Caller is responsible to allocate / free a buffer to retrieve firmware verion info.
+ * - Max string will be at most 256 bytes.
+ */
+wifi_error wifi_get_firmware_version(wifi_interface_handle iface, char* buffer, int buffer_size);
+
+/**
+ * API to collect a driver version string.
+ * - Caller is responsible to allocate / free a buffer to retrieve driver verion info.
+ * - Max string will be at most 256 bytes.
+ */
+wifi_error wifi_get_driver_version(wifi_interface_handle iface, char* buffer, int buffer_size);
+
+/* Feature set */
+enum {
+ WIFI_LOGGER_MEMORY_DUMP_SUPPORTED = (1 << (0)), // Memory dump of FW
+ WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), // PKT status
+ WIFI_LOGGER_CONNECT_EVENT_SUPPORTED = (1 << (2)), // Connectivity event
+ WIFI_LOGGER_POWER_EVENT_SUPPORTED = (1 << (3)), // POWER of Driver
+ WIFI_LOGGER_WAKE_LOCK_SUPPORTED = (1 << (4)), // WAKE LOCK of Driver
+ WIFI_LOGGER_VERBOSE_SUPPORTED = (1 << (5)), // verbose log of FW
+ WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED = (1 << (6)), // monitor the health of FW
+ WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)), // dumps driver state
+ WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)), // tracks connection packets' fate
+};
+
+/**
+ * API to retrieve the current supportive features.
+ * - An integer variable is enough to have bit mapping info by caller.
+ */
+wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface,
+ unsigned int* support);
+
+typedef struct {
+ /* Buffer is to be allocated and freed by HAL implementation. */
+ void (*on_driver_memory_dump)(char* buffer, int buffer_size);
+} wifi_driver_memory_dump_callbacks;
+
+/**
+ API to collect driver state.
+
+ Framework will call this API soon before or after (but not
+ concurrently with) wifi_get_firmware_memory_dump(). Capturing
+ firmware and driver dumps is intended to help identify
+ inconsistent state between these components.
+
+ - In response to this call, HAL implementation should make one or
+ more calls to callbacks.on_driver_memory_dump(). Framework will
+ copy data out of the received |buffer|s, and concatenate the
+ contents thereof.
+ - HAL implemention will indicate completion of the driver memory
+ dump by returning from this call.
+*/
+wifi_error wifi_get_driver_memory_dump(wifi_interface_handle iface,
+ wifi_driver_memory_dump_callbacks callbacks);
+
+/* packet fate logs */
+
+#define MD5_PREFIX_LEN 4
+#define MAX_FATE_LOG_LEN 32
+#define MAX_FRAME_LEN_ETHERNET 1518
+#define MAX_FRAME_LEN_80211_MGMT 2352 // 802.11-2012 Fig. 8-34
+
+typedef enum {
+ // Sent over air and ACKed.
+ TX_PKT_FATE_ACKED,
+
+ // Sent over air but not ACKed. (Normal for broadcast/multicast.)
+ TX_PKT_FATE_SENT,
+
+ // Queued within firmware, but not yet sent over air.
+ TX_PKT_FATE_FW_QUEUED,
+
+ // Dropped by firmware as invalid. E.g. bad source address, bad checksum,
+ // or invalid for current state.
+ TX_PKT_FATE_FW_DROP_INVALID,
+
+ // Dropped by firmware due to lack of buffer space.
+ TX_PKT_FATE_FW_DROP_NOBUFS,
+
+ // Dropped by firmware for any other reason. Includes frames that
+ // were sent by driver to firmware, but unaccounted for by
+ // firmware.
+ TX_PKT_FATE_FW_DROP_OTHER,
+
+ // Queued within driver, not yet sent to firmware.
+ TX_PKT_FATE_DRV_QUEUED,
+
+ // Dropped by driver as invalid. E.g. bad source address, or
+ // invalid for current state.
+ TX_PKT_FATE_DRV_DROP_INVALID,
+
+ // Dropped by driver due to lack of buffer space.
+ TX_PKT_FATE_DRV_DROP_NOBUFS,
+
+ // Dropped by driver for any other reason.
+ TX_PKT_FATE_DRV_DROP_OTHER,
+} wifi_tx_packet_fate;
+
+typedef enum {
+ // Valid and delivered to network stack (e.g., netif_rx()).
+ RX_PKT_FATE_SUCCESS,
+
+ // Queued within firmware, but not yet sent to driver.
+ RX_PKT_FATE_FW_QUEUED,
+
+ // Dropped by firmware due to host-programmable filters.
+ RX_PKT_FATE_FW_DROP_FILTER,
+
+ // Dropped by firmware as invalid. E.g. bad checksum, decrypt failed,
+ // or invalid for current state.
+ RX_PKT_FATE_FW_DROP_INVALID,
+
+ // Dropped by firmware due to lack of buffer space.
+ RX_PKT_FATE_FW_DROP_NOBUFS,
+
+ // Dropped by firmware for any other reason.
+ RX_PKT_FATE_FW_DROP_OTHER,
+
+ // Queued within driver, not yet delivered to network stack.
+ RX_PKT_FATE_DRV_QUEUED,
+
+ // Dropped by driver due to filter rules.
+ RX_PKT_FATE_DRV_DROP_FILTER,
+
+ // Dropped by driver as invalid. E.g. not permitted in current state.
+ RX_PKT_FATE_DRV_DROP_INVALID,
+
+ // Dropped by driver due to lack of buffer space.
+ RX_PKT_FATE_DRV_DROP_NOBUFS,
+
+ // Dropped by driver for any other reason.
+ RX_PKT_FATE_DRV_DROP_OTHER,
+} wifi_rx_packet_fate;
+
+typedef enum {
+ FRAME_TYPE_UNKNOWN,
+ FRAME_TYPE_ETHERNET_II,
+ FRAME_TYPE_80211_MGMT,
+} frame_type;
+
+typedef struct {
+ // The type of MAC-layer frame that this frame_info holds.
+ // - For data frames, use FRAME_TYPE_ETHERNET_II.
+ // - For management frames, use FRAME_TYPE_80211_MGMT.
+ // - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+ frame_type payload_type;
+
+ // The number of bytes included in |frame_content|. If the frame
+ // contents are missing (e.g. RX frame dropped in firmware),
+ // |frame_len| should be set to 0.
+ size_t frame_len;
+
+ // Host clock when this frame was received by the driver (either
+ // outbound from the host network stack, or inbound from the
+ // firmware).
+ // - The timestamp should be taken from a clock which includes time
+ // the host spent suspended (e.g. ktime_get_boottime()).
+ // - If no host timestamp is available (e.g. RX frame was dropped in
+ // firmware), this field should be set to 0.
+ u32 driver_timestamp_usec;
+
+ // Firmware clock when this frame was received by the firmware
+ // (either outbound from the host, or inbound from a remote
+ // station).
+ // - The timestamp should be taken from a clock which includes time
+ // firmware spent suspended (if applicable).
+ // - If no firmware timestamp is available (e.g. TX frame was
+ // dropped by driver), this field should be set to 0.
+ // - Consumers of |frame_info| should _not_ assume any
+ // synchronization between driver and firmware clocks.
+ u32 firmware_timestamp_usec;
+
+ // Actual frame content.
+ // - Should be provided for TX frames originated by the host.
+ // - Should be provided for RX frames received by the driver.
+ // - Optionally provided for TX frames originated by firmware. (At
+ // discretion of HAL implementation.)
+ // - Optionally provided for RX frames dropped in firmware. (At
+ // discretion of HAL implementation.)
+ // - If frame content is not provided, |frame_len| should be set
+ // to 0.
+ union {
+ char ethernet_ii_bytes[MAX_FRAME_LEN_ETHERNET];
+ char ieee_80211_mgmt_bytes[MAX_FRAME_LEN_80211_MGMT];
+ } frame_content;
+} frame_info;
+
+typedef struct {
+ // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+ // content is not provided, prefix of MD5 hash over the same data
+ // that would be in frame_content, if frame content were provided.
+ char md5_prefix[MD5_PREFIX_LEN];
+ wifi_tx_packet_fate fate;
+ frame_info frame_inf;
+} wifi_tx_report;
+
+typedef struct {
+ // Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+ // content is not provided, prefix of MD5 hash over the same data
+ // that would be in frame_content, if frame content were provided.
+ char md5_prefix[MD5_PREFIX_LEN];
+ wifi_rx_packet_fate fate;
+ frame_info frame_inf;
+} wifi_rx_report;
+
+/**
+ API to start packet fate monitoring.
+ - Once stared, monitoring should remain active until HAL is unloaded.
+ - When HAL is unloaded, all packet fate buffers should be cleared.
+*/
+wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle handle);
+
+/**
+ API to retrieve fates of outbound packets.
+ - HAL implementation should fill |tx_report_bufs| with fates of
+ _first_ min(n_requested_fates, actual packets) frames
+ transmitted for the most recent association. The fate reports
+ should follow the same order as their respective packets.
+ - HAL implementation may choose (but is not required) to include
+ reports for management frames.
+ - Packets reported by firmware, but not recognized by driver,
+ should be included. However, the ordering of the corresponding
+ reports is at the discretion of HAL implementation.
+ - Framework may call this API multiple times for the same association.
+ - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+ - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle handle, wifi_tx_report* tx_report_bufs,
+ size_t n_requested_fates, size_t* n_provided_fates);
+
+/**
+ API to retrieve fates of inbound packets.
+ - HAL implementation should fill |rx_report_bufs| with fates of
+ _first_ min(n_requested_fates, actual packets) frames
+ received for the most recent association. The fate reports
+ should follow the same order as their respective packets.
+ - HAL implementation may choose (but is not required) to include
+ reports for management frames.
+ - Packets reported by firmware, but not recognized by driver,
+ should be included. However, the ordering of the corresponding
+ reports is at the discretion of HAL implementation.
+ - Framework may call this API multiple times for the same association.
+ - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|.
+ - Framework will allocate and free the referenced storage.
+*/
+wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle handle, wifi_rx_report* rx_report_bufs,
+ size_t n_requested_fates, size_t* n_provided_fates);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_STATS_ */
diff --git a/wifi/1.6/default/hal_legacy/wifi_nan.h b/wifi/1.6/default/hal_legacy/wifi_nan.h
new file mode 100644
index 0000000..3591b98
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_nan.h
@@ -0,0 +1,2726 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NAN_H__
+#define __NAN_H__
+
+#include <net/if.h>
+#include <stdbool.h>
+#include "wifi_hal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*****************************************************************************
+ * Neighbour Aware Network Service Structures and Functions
+ *****************************************************************************/
+
+/*
+ Definitions
+ All multi-byte fields within all NAN protocol stack messages are assumed to be in Little Endian
+ order.
+*/
+
+typedef int NanVersion;
+typedef u16 transaction_id;
+typedef u32 NanDataPathId;
+
+#define NAN_MAC_ADDR_LEN 6
+#define NAN_MAJOR_VERSION 2
+#define NAN_MINOR_VERSION 0
+#define NAN_MICRO_VERSION 1
+#define NAN_MAX_SOCIAL_CHANNELS 3
+
+/* NAN Maximum Lengths */
+#define NAN_MAX_SERVICE_NAME_LEN 255
+#define NAN_MAX_MATCH_FILTER_LEN 255
+#define NAN_MAX_SERVICE_SPECIFIC_INFO_LEN 1024
+#define NAN_MAX_VSA_DATA_LEN 1024
+#define NAN_MAX_MESH_DATA_LEN 32
+#define NAN_MAX_INFRA_DATA_LEN 32
+#define NAN_MAX_CLUSTER_ATTRIBUTE_LEN 255
+#define NAN_MAX_SUBSCRIBE_MAX_ADDRESS 42
+#define NAN_MAX_FAM_CHANNELS 32
+#define NAN_MAX_POSTDISCOVERY_LEN 5
+#define NAN_MAX_FRAME_DATA_LEN 504
+#define NAN_DP_MAX_APP_INFO_LEN 512
+#define NAN_ERROR_STR_LEN 255
+#define NAN_PMK_INFO_LEN 32
+#define NAN_MAX_SCID_BUF_LEN 1024
+#define NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN 1024
+#define NAN_SECURITY_MIN_PASSPHRASE_LEN 8
+#define NAN_SECURITY_MAX_PASSPHRASE_LEN 63
+#define NAN_MAX_CHANNEL_INFO_SUPPORTED 4
+
+/*
+ Definition of various NanResponseType
+*/
+typedef enum {
+ NAN_RESPONSE_ENABLED = 0,
+ NAN_RESPONSE_DISABLED = 1,
+ NAN_RESPONSE_PUBLISH = 2,
+ NAN_RESPONSE_PUBLISH_CANCEL = 3,
+ NAN_RESPONSE_TRANSMIT_FOLLOWUP = 4,
+ NAN_RESPONSE_SUBSCRIBE = 5,
+ NAN_RESPONSE_SUBSCRIBE_CANCEL = 6,
+ NAN_RESPONSE_STATS = 7,
+ NAN_RESPONSE_CONFIG = 8,
+ NAN_RESPONSE_TCA = 9,
+ NAN_RESPONSE_ERROR = 10,
+ NAN_RESPONSE_BEACON_SDF_PAYLOAD = 11,
+ NAN_GET_CAPABILITIES = 12,
+ NAN_DP_INTERFACE_CREATE = 13,
+ NAN_DP_INTERFACE_DELETE = 14,
+ NAN_DP_INITIATOR_RESPONSE = 15,
+ NAN_DP_RESPONDER_RESPONSE = 16,
+ NAN_DP_END = 17
+} NanResponseType;
+
+/* NAN Publish Types */
+typedef enum {
+ NAN_PUBLISH_TYPE_UNSOLICITED = 0,
+ NAN_PUBLISH_TYPE_SOLICITED,
+ NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED
+} NanPublishType;
+
+/* NAN Transmit Priorities */
+typedef enum { NAN_TX_PRIORITY_NORMAL = 0, NAN_TX_PRIORITY_HIGH } NanTxPriority;
+
+/* NAN Statistics Request ID Codes */
+typedef enum {
+ NAN_STATS_ID_DE_PUBLISH = 0,
+ NAN_STATS_ID_DE_SUBSCRIBE,
+ NAN_STATS_ID_DE_MAC,
+ NAN_STATS_ID_DE_TIMING_SYNC,
+ NAN_STATS_ID_DE_DW,
+ NAN_STATS_ID_DE
+} NanStatsType;
+
+/* NAN Protocol Event ID Codes */
+typedef enum {
+ NAN_EVENT_ID_DISC_MAC_ADDR = 0,
+ NAN_EVENT_ID_STARTED_CLUSTER,
+ NAN_EVENT_ID_JOINED_CLUSTER
+} NanDiscEngEventType;
+
+/* NAN Data Path type */
+typedef enum { NAN_DATA_PATH_UNICAST_MSG = 0, NAN_DATA_PATH_MULTICAST_MSG } NdpType;
+
+/* NAN Ranging Configuration */
+typedef enum { NAN_RANGING_DISABLE = 0, NAN_RANGING_ENABLE } NanRangingState;
+
+/* TCA Type */
+typedef enum { NAN_TCA_ID_CLUSTER_SIZE = 0 } NanTcaType;
+
+/* NAN Channel Info */
+typedef struct {
+ u32 channel;
+ u32 bandwidth;
+ u32 nss;
+} NanChannelInfo;
+
+/*
+ Various NAN Protocol Response code
+*/
+typedef enum {
+ /* NAN Protocol Response Codes */
+ NAN_STATUS_SUCCESS = 0,
+ /* NAN Discovery Engine/Host driver failures */
+ NAN_STATUS_INTERNAL_FAILURE = 1,
+ /* NAN OTA failures */
+ NAN_STATUS_PROTOCOL_FAILURE = 2,
+ /* if the publish/subscribe id is invalid */
+ NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID = 3,
+ /* If we run out of resources allocated */
+ NAN_STATUS_NO_RESOURCE_AVAILABLE = 4,
+ /* if invalid params are passed */
+ NAN_STATUS_INVALID_PARAM = 5,
+ /* if the requestor instance id is invalid */
+ NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID = 6,
+ /* if the ndp id is invalid */
+ NAN_STATUS_INVALID_NDP_ID = 7,
+ /* if NAN is enabled when wifi is turned off */
+ NAN_STATUS_NAN_NOT_ALLOWED = 8,
+ /* if over the air ack is not received */
+ NAN_STATUS_NO_OTA_ACK = 9,
+ /* If NAN is already enabled and we are try to re-enable the same */
+ NAN_STATUS_ALREADY_ENABLED = 10,
+ /* If followup message internal queue is full */
+ NAN_STATUS_FOLLOWUP_QUEUE_FULL = 11,
+ /* Unsupported concurrency session enabled, NAN disabled notified */
+ NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12
+} NanStatusType;
+
+/* NAN Transmit Types */
+typedef enum { NAN_TX_TYPE_BROADCAST = 0, NAN_TX_TYPE_UNICAST } NanTxType;
+
+/* NAN Subscribe Type */
+typedef enum { NAN_SUBSCRIBE_TYPE_PASSIVE = 0, NAN_SUBSCRIBE_TYPE_ACTIVE } NanSubscribeType;
+
+/* NAN Service Response Filter Attribute Bit */
+typedef enum { NAN_SRF_ATTR_BLOOM_FILTER = 0, NAN_SRF_ATTR_PARTIAL_MAC_ADDR } NanSRFType;
+
+/* NAN Service Response Filter Include Bit */
+typedef enum { NAN_SRF_INCLUDE_DO_NOT_RESPOND = 0, NAN_SRF_INCLUDE_RESPOND } NanSRFIncludeType;
+
+/* NAN Match indication type */
+typedef enum {
+ NAN_MATCH_ALG_MATCH_ONCE = 0,
+ NAN_MATCH_ALG_MATCH_CONTINUOUS,
+ NAN_MATCH_ALG_MATCH_NEVER
+} NanMatchAlg;
+
+/* NAN Transmit Window Type */
+typedef enum { NAN_TRANSMIT_IN_DW = 0, NAN_TRANSMIT_IN_FAW } NanTransmitWindowType;
+
+/* NAN SRF State in Subscribe */
+typedef enum { NAN_DO_NOT_USE_SRF = 0, NAN_USE_SRF } NanSRFState;
+
+/* NAN Include SSI in MatchInd */
+typedef enum {
+ NAN_SSI_NOT_REQUIRED_IN_MATCH_IND = 0,
+ NAN_SSI_REQUIRED_IN_MATCH_IND
+} NanSsiInMatchInd;
+
+/* NAN DP security Configuration */
+typedef enum { NAN_DP_CONFIG_NO_SECURITY = 0, NAN_DP_CONFIG_SECURITY } NanDataPathSecurityCfgStatus;
+
+typedef enum { NAN_QOS_NOT_REQUIRED = 0, NAN_QOS_REQUIRED } NanQosCfgStatus;
+
+/* Data request Responder's response */
+typedef enum { NAN_DP_REQUEST_ACCEPT = 0, NAN_DP_REQUEST_REJECT } NanDataPathResponseCode;
+
+/* NAN DP channel config options */
+typedef enum {
+ NAN_DP_CHANNEL_NOT_REQUESTED = 0,
+ NAN_DP_REQUEST_CHANNEL_SETUP,
+ NAN_DP_FORCE_CHANNEL_SETUP
+} NanDataPathChannelCfg;
+
+/* Enable/Disable NAN Ranging Auto response */
+typedef enum {
+ NAN_RANGING_AUTO_RESPONSE_ENABLE = 1,
+ NAN_RANGING_AUTO_RESPONSE_DISABLE
+} NanRangingAutoResponse;
+
+/* Enable/Disable NAN service range report */
+typedef enum { NAN_DISABLE_RANGE_REPORT = 1, NAN_ENABLE_RANGE_REPORT } NanRangeReport;
+
+/* NAN Range Response */
+typedef enum {
+ NAN_RANGE_REQUEST_ACCEPT = 1,
+ NAN_RANGE_REQUEST_REJECT,
+ NAN_RANGE_REQUEST_CANCEL
+} NanRangeResponse;
+
+/* NAN Security Key Input Type*/
+typedef enum {
+ NAN_SECURITY_KEY_INPUT_PMK = 1,
+ NAN_SECURITY_KEY_INPUT_PASSPHRASE
+} NanSecurityKeyInputType;
+
+typedef struct {
+ /* pmk length */
+ u32 pmk_len;
+ /*
+ PMK: Info is optional in Discovery phase.
+ PMK info can be passed during
+ the NDP session.
+ */
+ u8 pmk[NAN_PMK_INFO_LEN];
+} NanSecurityPmk;
+
+typedef struct {
+ /* passphrase length */
+ u32 passphrase_len;
+ /*
+ passphrase info is optional in Discovery phase.
+ passphrase info can be passed during
+ the NDP session.
+ */
+ u8 passphrase[NAN_SECURITY_MAX_PASSPHRASE_LEN];
+} NanSecurityPassPhrase;
+
+typedef struct {
+ NanSecurityKeyInputType key_type;
+ union {
+ NanSecurityPmk pmk_info;
+ NanSecurityPassPhrase passphrase_info;
+ } body;
+} NanSecurityKeyInfo;
+
+/* NAN Security Cipher Suites Mask */
+#define NAN_CIPHER_SUITE_SHARED_KEY_NONE 0x00
+#define NAN_CIPHER_SUITE_SHARED_KEY_128_MASK 0x01
+#define NAN_CIPHER_SUITE_SHARED_KEY_256_MASK 0x02
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_128_MASK 0x04
+#define NAN_CIPHER_SUITE_PUBLIC_KEY_2WDH_256_MASK 0x08
+
+/* NAN ranging indication condition MASKS */
+#define NAN_RANGING_INDICATE_CONTINUOUS_MASK 0x01
+#define NAN_RANGING_INDICATE_INGRESS_MET_MASK 0x02
+#define NAN_RANGING_INDICATE_EGRESS_MET_MASK 0x04
+
+/* NAN schedule update reason MASKS */
+#define NAN_SCHEDULE_UPDATE_NSS_MASK 0x01
+#define NAN_SCHEDULE_UPDATE_CHANNEL_MASK 0x02
+
+/*
+ Structure to set the Service Descriptor Extension
+ Attribute (SDEA) passed as part of NanPublishRequest/
+ NanSubscribeRequest/NanMatchInd.
+*/
+typedef struct {
+ /*
+ Optional configuration of Data Path Enable request.
+ configure flag determines whether configuration needs
+ to be passed or not.
+ */
+ u8 config_nan_data_path;
+ NdpType ndp_type;
+ /*
+ NAN secuirty required flag to indicate
+ if the security is enabled or disabled
+ */
+ NanDataPathSecurityCfgStatus security_cfg;
+ /*
+ NAN ranging required flag to indicate
+ if ranging is enabled on disabled
+ */
+ NanRangingState ranging_state;
+ /*
+ Enable/Disable Ranging report,
+ when configured NanRangeReportInd received
+ */
+ NanRangeReport range_report;
+ /*
+ NAN QOS required flag to indicate
+ if QOS is required or not.
+ */
+ NanQosCfgStatus qos_cfg;
+} NanSdeaCtrlParams;
+
+/*
+ Nan Ranging Peer Info in MatchInd
+*/
+typedef struct {
+ /*
+ Distance to the NAN device with the MAC address indicated
+ with ranged mac address.
+ */
+ u32 range_measurement_mm;
+ /* Ranging event matching the configuration of continuous/ingress/egress. */
+ u32 ranging_event_type;
+} NanRangeInfo;
+
+/* Nan/NDP Capabilites info */
+typedef struct {
+ u32 max_concurrent_nan_clusters;
+ u32 max_publishes;
+ u32 max_subscribes;
+ u32 max_service_name_len;
+ u32 max_match_filter_len;
+ u32 max_total_match_filter_len;
+ u32 max_service_specific_info_len;
+ u32 max_vsa_data_len;
+ u32 max_mesh_data_len;
+ u32 max_ndi_interfaces;
+ u32 max_ndp_sessions;
+ u32 max_app_info_len;
+ u32 max_queued_transmit_followup_msgs;
+ u32 ndp_supported_bands;
+ u32 cipher_suites_supported;
+ u32 max_scid_len;
+ bool is_ndp_security_supported;
+ u32 max_sdea_service_specific_info_len;
+ u32 max_subscribe_address;
+ u32 ndpe_attr_supported;
+ bool is_instant_mode_supported;
+} NanCapabilities;
+
+/*
+ Nan accept policy: Per service basis policy
+ Based on this policy(ALL/NONE), responder side
+ will send ACCEPT/REJECT
+*/
+typedef enum {
+ NAN_SERVICE_ACCEPT_POLICY_NONE = 0,
+ /* Default value */
+ NAN_SERVICE_ACCEPT_POLICY_ALL
+} NanServiceAcceptPolicy;
+
+/*
+ Host can send Vendor specific attributes which the Discovery Engine can
+ enclose in Beacons and/or Service Discovery frames transmitted.
+ Below structure is used to populate that.
+*/
+typedef struct {
+ /*
+ 0 = transmit only in the next discovery window
+ 1 = transmit in next 16 discovery window
+ */
+ u8 payload_transmit_flag;
+ /*
+ Below flags will determine in which all frames
+ the vendor specific attributes should be included
+ */
+ u8 tx_in_discovery_beacon;
+ u8 tx_in_sync_beacon;
+ u8 tx_in_service_discovery;
+ /* Organizationally Unique Identifier */
+ u32 vendor_oui;
+ /*
+ vendor specific attribute to be transmitted
+ vsa_len : Length of the vsa data.
+ */
+ u32 vsa_len;
+ u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanTransmitVendorSpecificAttribute;
+
+/*
+ Discovery Engine will forward any Vendor Specific Attributes
+ which it received as part of this structure.
+*/
+/* Mask to determine on which frames attribute was received */
+#define RX_DISCOVERY_BEACON_MASK 0x01
+#define RX_SYNC_BEACON_MASK 0x02
+#define RX_SERVICE_DISCOVERY_MASK 0x04
+typedef struct {
+ /*
+ Frames on which this vendor specific attribute
+ was received. Mask defined above
+ */
+ u8 vsa_received_on;
+ /* Organizationally Unique Identifier */
+ u32 vendor_oui;
+ /* vendor specific attribute */
+ u32 attr_len;
+ u8 vsa[NAN_MAX_VSA_DATA_LEN];
+} NanReceiveVendorSpecificAttribute;
+
+/*
+ NAN Beacon SDF Payload Received structure
+ Discovery engine sends the details of received Beacon or
+ Service Discovery Frames as part of this structure.
+*/
+typedef struct {
+ /* Frame data */
+ u32 frame_len;
+ u8 frame_data[NAN_MAX_FRAME_DATA_LEN];
+} NanBeaconSdfPayloadReceive;
+
+/*
+ Host can set the Periodic scan parameters for each of the
+ 3(6, 44, 149) Social channels. Only these channels are allowed
+ any other channels are rejected
+*/
+typedef enum {
+ NAN_CHANNEL_24G_BAND = 0,
+ NAN_CHANNEL_5G_BAND_LOW,
+ NAN_CHANNEL_5G_BAND_HIGH
+} NanChannelIndex;
+
+/*
+ Structure to set the Social Channel Scan parameters
+ passed as part of NanEnableRequest/NanConfigRequest
+*/
+typedef struct {
+ /*
+ Dwell time of each social channel in milliseconds
+ NanChannelIndex corresponds to the respective channel
+ If time set to 0 then the FW default time will be used.
+ */
+ u8 dwell_time[NAN_MAX_SOCIAL_CHANNELS]; // default value 200 msec
+
+ /*
+ Scan period of each social channel in seconds
+ NanChannelIndex corresponds to the respective channel
+ If time set to 0 then the FW default time will be used.
+ */
+ u16 scan_period[NAN_MAX_SOCIAL_CHANNELS]; // default value 20 sec
+} NanSocialChannelScanParams;
+
+/*
+ Host can send Post Connectivity Capability attributes
+ to be included in Service Discovery frames transmitted
+ as part of this structure.
+*/
+typedef struct {
+ /*
+ 0 = transmit only in the next discovery window
+ 1 = transmit in next 16 discovery window
+ */
+ u8 payload_transmit_flag;
+ /* 1 - Wifi Direct supported 0 - Not supported */
+ u8 is_wfd_supported;
+ /* 1 - Wifi Direct Services supported 0 - Not supported */
+ u8 is_wfds_supported;
+ /* 1 - TDLS supported 0 - Not supported */
+ u8 is_tdls_supported;
+ /* 1 - IBSS supported 0 - Not supported */
+ u8 is_ibss_supported;
+ /* 1 - Mesh supported 0 - Not supported */
+ u8 is_mesh_supported;
+ /*
+ 1 - NAN Device currently connect to WLAN Infra AP
+ 0 - otherwise
+ */
+ u8 wlan_infra_field;
+} NanTransmitPostConnectivityCapability;
+
+/*
+ Discovery engine providing the post connectivity capability
+ received.
+*/
+typedef struct {
+ /* 1 - Wifi Direct supported 0 - Not supported */
+ u8 is_wfd_supported;
+ /* 1 - Wifi Direct Services supported 0 - Not supported */
+ u8 is_wfds_supported;
+ /* 1 - TDLS supported 0 - Not supported */
+ u8 is_tdls_supported;
+ /* 1 - IBSS supported 0 - Not supported */
+ u8 is_ibss_supported;
+ /* 1 - Mesh supported 0 - Not supported */
+ u8 is_mesh_supported;
+ /*
+ 1 - NAN Device currently connect to WLAN Infra AP
+ 0 - otherwise
+ */
+ u8 wlan_infra_field;
+} NanReceivePostConnectivityCapability;
+
+/*
+ Indicates the availability interval duration associated with the
+ Availability Intervals Bitmap field
+*/
+typedef enum {
+ NAN_DURATION_16MS = 0,
+ NAN_DURATION_32MS = 1,
+ NAN_DURATION_64MS = 2
+} NanAvailDuration;
+
+/* Further availability per channel information */
+typedef struct {
+ /* Defined above */
+ NanAvailDuration entry_control;
+ /*
+ 1 byte field indicating the frequency band the NAN Device
+ will be available as defined in IEEE Std. 802.11-2012
+ Annex E Table E-4 Global Operating Classes
+ */
+ u8 class_val;
+ /*
+ 1 byte field indicating the channel the NAN Device
+ will be available.
+ */
+ u8 channel;
+ /*
+ Map Id - 4 bit field which identifies the Further
+ availability map attribute.
+ */
+ u8 mapid;
+ /*
+ divides the time between the beginnings of consecutive Discovery
+ Windows of a given NAN cluster into consecutive time intervals
+ of equal durations. The time interval duration is specified by
+ the Availability Interval Duration subfield of the Entry Control
+ field.
+
+ A Nan device that sets the i-th bit of the Availability
+ Intervals Bitmap to 1 shall be present during the corresponding
+ i-th time interval in the operation channel indicated by the
+ Operating Class and Channel Number fields in the same Availability Entry.
+
+ A Nan device that sets the i-th bit of the Availability Intervals Bitmap to
+ 0 may be present during the corresponding i-th time interval in the operation
+ channel indicated by the Operating Class and Channel Number fields in the same
+ Availability Entry.
+
+ The size of the Bitmap is dependent upon the Availability Interval Duration
+ chosen in the Entry Control Field. The size can be either 1, 2 or 4 bytes long
+
+ - Duration field is equal to 0, only AIB[0] is valid
+ - Duration field is equal to 1, only AIB [0] and AIB [1] is valid
+ - Duration field is equal to 2, AIB [0], AIB [1], AIB [2] and AIB [3] are valid
+ */
+ u32 avail_interval_bitmap;
+} NanFurtherAvailabilityChannel;
+
+/*
+ Further availability map which can be sent and received from
+ Discovery engine
+*/
+typedef struct {
+ /*
+ Number of channels indicates the number of channel
+ entries which is part of fam
+ */
+ u8 numchans;
+ NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS];
+} NanFurtherAvailabilityMap;
+
+/*
+ Host can send Post-Nan Discovery attributes which the Discovery Engine can
+ enclose in Service Discovery frames
+*/
+/* Possible connection types in Post NAN Discovery attributes */
+typedef enum {
+ NAN_CONN_WLAN_INFRA = 0,
+ NAN_CONN_P2P_OPER = 1,
+ NAN_CONN_WLAN_IBSS = 2,
+ NAN_CONN_WLAN_MESH = 3,
+ NAN_CONN_FURTHER_SERVICE_AVAILABILITY = 4,
+ NAN_CONN_WLAN_RANGING = 5
+} NanConnectionType;
+
+/* Possible device roles in Post NAN Discovery attributes */
+typedef enum {
+ NAN_WLAN_INFRA_AP = 0,
+ NAN_WLAN_INFRA_STA = 1,
+ NAN_P2P_OPER_GO = 2,
+ NAN_P2P_OPER_DEV = 3,
+ NAN_P2P_OPER_CLI = 4
+} NanDeviceRole;
+
+/* Configuration params of NAN Ranging */
+typedef struct {
+ /*
+ Interval in milli sec between two ranging measurements.
+ If the Awake DW intervals in NanEnable/Config are larger
+ than the ranging intervals priority is given to Awake DW
+ Intervals. Only on a match the ranging is initiated for the
+ peer
+ */
+ u32 ranging_interval_msec;
+ /*
+ Flags indicating the type of ranging event to be notified
+ NAN_RANGING_INDICATE_ MASKS are used to set these.
+ BIT0 - Continuous Ranging event notification.
+ BIT1 - Ingress distance is <=.
+ BIT2 - Egress distance is >=.
+ */
+ u32 config_ranging_indications;
+ /* Ingress distance in millimeters (optional) */
+ u32 distance_ingress_mm;
+ /* Egress distance in millmilliimeters (optional) */
+ u32 distance_egress_mm;
+} NanRangingCfg;
+
+/* NAN Ranging request's response */
+typedef struct {
+ /* Publish Id of an earlier Publisher */
+ u16 publish_id;
+ /*
+ A 32 bit Requestor instance Id which is sent to the Application.
+ This Id will be used in subsequent RangeResponse on Subscribe side.
+ */
+ u32 requestor_instance_id;
+ /* Peer MAC addr of Range Requestor */
+ u8 peer_addr[NAN_MAC_ADDR_LEN];
+ /* Response indicating ACCEPT/REJECT/CANCEL of Range Request */
+ NanRangeResponse ranging_response;
+} NanRangeResponseCfg;
+
+/* Structure of Post NAN Discovery attribute */
+typedef struct {
+ /* Connection type of the host */
+ NanConnectionType type;
+ /*
+ Device role of the host based on
+ the connection type
+ */
+ NanDeviceRole role;
+ /*
+ Flag to send the information as a single shot or repeated
+ for next 16 discovery windows
+ 0 - Single_shot
+ 1 - next 16 discovery windows
+ */
+ u8 transmit_freq;
+ /* Duration of the availability bitmask */
+ NanAvailDuration duration;
+ /* Availability interval bitmap based on duration */
+ u32 avail_interval_bitmap;
+ /*
+ Mac address depending on the conn type and device role
+ --------------------------------------------------
+ | Conn Type | Device Role | Mac address Usage |
+ --------------------------------------------------
+ | WLAN_INFRA | AP/STA | BSSID of the AP |
+ --------------------------------------------------
+ | P2P_OPER | GO | GO's address |
+ --------------------------------------------------
+ | P2P_OPER | P2P_DEVICE | Address of who |
+ | | | would become GO |
+ --------------------------------------------------
+ | WLAN_IBSS | NA | BSSID |
+ --------------------------------------------------
+ | WLAN_MESH | NA | BSSID |
+ --------------------------------------------------
+ */
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Mandatory mesh id value if connection type is WLAN_MESH
+ Mesh id contains 0-32 octet identifier and should be
+ as per IEEE Std.802.11-2012 spec.
+ */
+ u16 mesh_id_len;
+ u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+ /*
+ Optional infrastructure SSID if conn_type is set to
+ NAN_CONN_WLAN_INFRA
+ */
+ u16 infrastructure_ssid_len;
+ u8 infrastructure_ssid_val[NAN_MAX_INFRA_DATA_LEN];
+} NanTransmitPostDiscovery;
+
+/*
+ Discovery engine providing the structure of Post NAN
+ Discovery
+*/
+typedef struct {
+ /* Connection type of the host */
+ NanConnectionType type;
+ /*
+ Device role of the host based on
+ the connection type
+ */
+ NanDeviceRole role;
+ /* Duration of the availability bitmask */
+ NanAvailDuration duration;
+ /* Availability interval bitmap based on duration */
+ u32 avail_interval_bitmap;
+ /*
+ Map Id - 4 bit field which identifies the Further
+ availability map attribute.
+ */
+ u8 mapid;
+ /*
+ Mac address depending on the conn type and device role
+ --------------------------------------------------
+ | Conn Type | Device Role | Mac address Usage |
+ --------------------------------------------------
+ | WLAN_INFRA | AP/STA | BSSID of the AP |
+ --------------------------------------------------
+ | P2P_OPER | GO | GO's address |
+ --------------------------------------------------
+ | P2P_OPER | P2P_DEVICE | Address of who |
+ | | | would become GO |
+ --------------------------------------------------
+ | WLAN_IBSS | NA | BSSID |
+ --------------------------------------------------
+ | WLAN_MESH | NA | BSSID |
+ --------------------------------------------------
+ */
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Mandatory mesh id value if connection type is WLAN_MESH
+ Mesh id contains 0-32 octet identifier and should be
+ as per IEEE Std.802.11-2012 spec.
+ */
+ u16 mesh_id_len;
+ u8 mesh_id[NAN_MAX_MESH_DATA_LEN];
+ /*
+ Optional infrastructure SSID if conn_type is set to
+ NAN_CONN_WLAN_INFRA
+ */
+ u16 infrastructure_ssid_len;
+ u8 infrastructure_ssid_val[NAN_MAX_INFRA_DATA_LEN];
+} NanReceivePostDiscovery;
+
+/*
+ NAN device level configuration of SDF and Sync beacons in both
+ 2.4/5GHz bands
+*/
+typedef struct {
+ /* Configure 2.4GHz DW Band */
+ u8 config_2dot4g_dw_band;
+ /*
+ Indicates the interval for Sync beacons and SDF's in 2.4GHz band.
+ Valid values of DW Interval are: 1, 2, 3, 4 and 5, 0 is reserved.
+ The SDF includes in OTA when enabled. The publish/subscribe period
+ values don't override the device level configurations.
+ */
+ u32 dw_2dot4g_interval_val; // default value 1
+ /* Configure 5GHz DW Band */
+ u8 config_5g_dw_band;
+ /*
+ Indicates the interval for Sync beacons and SDF's in 5GHz band
+ Valid values of DW Interval are: 1, 2, 3, 4 and 5, 0 no wake up for
+ any interval. The SDF includes in OTA when enabled. The publish/subscribe
+ period values don't override the device level configurations.
+ */
+ u32 dw_5g_interval_val; // default value 1 when 5G is enabled
+} NanConfigDW;
+
+/*
+ Enable Request Message Structure
+ The NanEnableReq message instructs the Discovery Engine to enter an operational state
+*/
+typedef struct {
+ /* Mandatory parameters below */
+ u8 master_pref; // default value 0x02
+ /*
+ A cluster_low value matching cluster_high indicates a request to join
+ a cluster with that value. If the requested cluster is not found the
+ device will start its own cluster.
+ */
+ u16 cluster_low; // default value 0
+ u16 cluster_high; // default value 0xFFFF
+
+ /*
+ Optional configuration of Enable request.
+ Each of the optional parameters have configure flag which
+ determine whether configuration is to be passed or not.
+ */
+ u8 config_support_5g;
+ u8 support_5g_val; // default value 0; turned off by default
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 config_sid_beacon;
+ u8 sid_beacon_val; // default value 0x01
+ /*
+ The rssi values below should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_2dot4g_rssi_close;
+ u8 rssi_close_2dot4g_val; // default value -60 dBm
+
+ u8 config_2dot4g_rssi_middle;
+ u8 rssi_middle_2dot4g_val; // default value -70 dBm
+
+ u8 config_2dot4g_rssi_proximity;
+ u8 rssi_proximity_2dot4g_val; // default value -60dBm
+
+ u8 config_hop_count_limit;
+ u8 hop_count_limit_val; // default value 0x02
+
+ /*
+ Defines 2.4G channel access support
+ 0 - No Support
+ 1 - Supported
+ */
+ u8 config_2dot4g_support;
+ u8 support_2dot4g_val; // default value 0x01
+ /*
+ Defines 2.4G channels will be used for sync/discovery beacons
+ 0 - 2.4G channels not used for beacons
+ 1 - 2.4G channels used for beacons
+ */
+ u8 config_2dot4g_beacons;
+ u8 beacon_2dot4g_val; // default value 1
+ /*
+ Defines 2.4G channels will be used for Service Discovery frames
+ 0 - 2.4G channels not used for Service Discovery frames
+ 1 - 2.4G channels used for Service Discovery frames
+ */
+ u8 config_2dot4g_sdf;
+ u8 sdf_2dot4g_val; // default value 1
+ /*
+ Defines 5G channels will be used for sync/discovery beacons
+ 0 - 5G channels not used for beacons
+ 1 - 5G channels used for beacons
+ */
+ u8 config_5g_beacons;
+ u8 beacon_5g_val; // default value 1 when 5G is enabled
+ /*
+ Defines 5G channels will be used for Service Discovery frames
+ 0 - 5G channels not used for Service Discovery frames
+ 1 - 5G channels used for Service Discovery frames
+ */
+ u8 config_5g_sdf;
+ u8 sdf_5g_val; // default value is 0 when 5G is enabled
+ /*
+ 1 byte value which defines the RSSI in
+ dBm for a close by Peer in 5 Ghz channels.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_close;
+ u8 rssi_close_5g_val; // default value -60dBm when 5G is enabled
+ /*
+ 1 byte value which defines the RSSI value in
+ dBm for a close by Peer in 5 Ghz channels.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_middle;
+ u8 rssi_middle_5g_val; // default value -75dBm when 5G is enabled
+ /*
+ 1 byte value which defines the RSSI filter
+ threshold. Any Service Descriptors received above this
+ value that are configured for RSSI filtering will be dropped.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_close_proximity;
+ u8 rssi_close_proximity_5g_val; // default value -60dBm when 5G is enabled
+ /*
+ 1 byte quantity which defines the window size over
+ which the “average RSSI” will be calculated over.
+ */
+ u8 config_rssi_window_size;
+ u8 rssi_window_size_val; // default value 0x08
+ /*
+ The 24 bit Organizationally Unique ID + the 8 bit Network Id.
+ */
+ u8 config_oui;
+ u32 oui_val; // default value {0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00}
+ /*
+ NAN Interface Address, If not configured the Discovery Engine
+ will generate a 6 byte Random MAC.
+ */
+ u8 config_intf_addr;
+ u8 intf_addr_val[NAN_MAC_ADDR_LEN];
+ /*
+ If set to 1, the Discovery Engine will enclose the Cluster
+ Attribute only sent in Beacons in a Vendor Specific Attribute
+ and transmit in a Service Descriptor Frame.
+ */
+ u8 config_cluster_attribute_val;
+ /*
+ The periodicity in seconds between full scan’s to find any new
+ clusters available in the area. A Full scan should not be done
+ more than every 10 seconds and should not be done less than every
+ 30 seconds.
+ */
+ u8 config_scan_params;
+ NanSocialChannelScanParams scan_params_val;
+ /*
+ 1 byte quantity which forces the Random Factor to a particular
+ value for all transmitted Sync/Discovery beacons
+ */
+ u8 config_random_factor_force;
+ u8 random_factor_force_val; // default value off and set to 0x00
+ /*
+ 1 byte quantity which forces the HC for all transmitted Sync and
+ Discovery Beacon NO matter the real HC being received over the
+ air.
+ */
+ u8 config_hop_count_force;
+ u8 hop_count_force_val; // default value 0x00
+
+ /* channel frequency in MHz to enable Nan on */
+ u8 config_24g_channel;
+ wifi_channel channel_24g_val; // default value channel 0x6
+
+ u8 config_5g_channel;
+ wifi_channel channel_5g_val; // default value channel 44 or 149 regulatory
+ // domain
+ /* Configure 2.4/5GHz DW */
+ NanConfigDW config_dw;
+
+ /*
+ By default discovery MAC address randomization is enabled
+ and default interval value is 30 minutes i.e. 1800 seconds.
+ The value 0 is used to disable MAC addr randomization.
+ */
+ u8 config_disc_mac_addr_randomization;
+ u32 disc_mac_addr_rand_interval_sec; // default value 1800 sec
+
+ /*
+ Set/Enable corresponding bits to disable Discovery indications:
+ BIT0 - Disable Discovery MAC Address Event.
+ BIT1 - Disable Started Cluster Event.
+ BIT2 - Disable Joined Cluster Event.
+ */
+ u8 discovery_indication_cfg; // default value 0x0
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 config_subscribe_sid_beacon;
+ u32 subscribe_sid_beacon_val; // default value 0x0
+ /*
+ Discovery Beacon Interval config.
+ Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW.
+ When 0 value is passed it is reset to default value of 128 or 176 msec.
+ */
+ u8 config_discovery_beacon_int;
+ u32 discovery_beacon_interval;
+ /*
+ Enable Number of Spatial Streams.
+ This is NAN Power Optimization feature for NAN discovery.
+ */
+ u8 config_nss;
+ // default value is implementation specific and passing 0 sets it to default
+ u32 nss;
+ /*
+ Enable device level NAN Ranging feature.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_ranging;
+ u32 enable_ranging;
+ /*
+ Enable/Disable DW Early termination.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_dw_early_termination;
+ u32 enable_dw_termination;
+ /*
+ Indicate whether to use NDPE attribute to bring-up TCP/IP connection.
+ If config_ndpe_attr is not configured, the default behavior is
+ not using NDPE attr, and the capability is not advertised.
+ 0 - Not use
+ 1 - Use
+ */
+ u8 config_ndpe_attr;
+ u32 use_ndpe_attr;
+ /*
+ Enable NAN v3.1 instant communication mode.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_instant_mode;
+ u32 enable_instant_mode;
+ /*
+ Config NAN v3.1 instant communication channel frequency selected over NFC/OOB method.
+ If dual band is supported default channel is 149 or 44 as per regulatory domain,
+ else channel 6 (send frequency in MHz).
+ Sometimes depending on country code retrictions, even 149/44 may be restricted
+ in those cases instant channel will be operational only in 2.4GHz.
+ Use wifi_get_usable_channels() API to get supported bands/channels before
+ Instant mode NFC handshake is triggered
+ */
+ u8 config_instant_mode_channel;
+ wifi_channel instant_mode_channel;
+} NanEnableRequest;
+
+/*
+ Publish Msg Structure
+ Message is used to request the DE to publish the Service Name
+ using the parameters passed into the Discovery Window
+*/
+typedef struct {
+ u16 publish_id; /* id 0 means new publish, any other id is existing publish */
+ u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+ /*
+ period: Awake DW Interval for publish(service)
+ Indicates the interval between two Discovery Windows in which
+ the device supporting the service is awake to transmit or
+ receive the Service Discovery frames.
+ Valid values of Awake DW Interval are: 1, 2, 4, 8 and 16, value 0 will
+ default to 1.
+ */
+ u16 period;
+ NanPublishType publish_type; /* 0= unsolicited, solicited = 1, 2= both */
+ NanTxType tx_type; /* 0 = broadcast, 1= unicast if solicited publish */
+ u8 publish_count; /* number of OTA Publish, 0 means forever until canceled */
+ u16 service_name_len; /* length of service name */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN]; /* UTF-8 encoded string identifying the service */
+ /*
+ Field which specifies how the matching indication to host is controlled.
+ 0 - Match and Indicate Once
+ 1 - Match and Indicate continuous
+ 2 - Match and Indicate never. This means don't indicate the match to the host.
+ 3 - Reserved
+ */
+ NanMatchAlg publish_match_indicator;
+
+ /*
+ Sequence of values
+ NAN Device that has invoked a Subscribe method corresponding to this Publish method
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs which specify further response conditions
+ beyond the service name used to filter subscribe messages to respond to.
+ This is only needed when the PT is set to NAN_SOLICITED or NAN_SOLICITED_UNSOLICITED.
+ */
+ u16 rx_match_filter_len;
+ u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs to be included in the Discovery Frame.
+ If present it is always sent in a Discovery Frame
+ */
+ u16 tx_match_filter_len;
+ u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ flag which specifies that the Publish should use the configured RSSI
+ threshold and the received RSSI in order to filter requests
+ 0 – ignore the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+ 1 – use the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+ */
+ u8 rssi_threshold_flag;
+
+ /*
+ 8-bit bitmap which allows the Host to associate this publish
+ with a particular Post-NAN Connectivity attribute
+ which has been sent down in a NanConfigureRequest/NanEnableRequest
+ message. If the DE fails to find a configured Post-NAN
+ connectivity attributes referenced by the bitmap,
+ the DE will return an error code to the Host.
+ If the Publish is configured to use a Post-NAN Connectivity
+ attribute and the Host does not refresh the Post-NAN Connectivity
+ attribute the Publish will be canceled and the Host will be sent
+ a PublishTerminatedIndication message.
+ */
+ u8 connmap;
+ /*
+ Set/Enable corresponding bits to disable any indications that follow a publish.
+ BIT0 - Disable publish termination indication.
+ BIT1 - Disable match expired indication.
+ BIT2 - Disable followUp indication received (OTA).
+ BIT3 - Disable publishReplied indication.
+ */
+ u8 recv_indication_cfg;
+ /*
+ Nan accept policy for the specific service(publish)
+ */
+ NanServiceAcceptPolicy service_responder_policy;
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+ /* NAN configure service discovery extended attributes */
+ NanSdeaCtrlParams sdea_params;
+
+ /* NAN Ranging configuration */
+ NanRangingCfg ranging_cfg;
+
+ /* Enable/disable NAN serivce Ranging auto response mode */
+ NanRangingAutoResponse ranging_auto_response;
+
+ /*
+ When the ranging_auto_response_cfg is not set, NanRangeRequestInd is
+ received. Nan Range Response to Peer MAC Addr is notified to indicate
+ ACCEPT/REJECT/CANCEL to the requestor.
+ */
+ NanRangeResponseCfg range_response_cfg;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanPublishRequest;
+
+/*
+ Publish Cancel Msg Structure
+ The PublishServiceCancelReq Message is used to request the DE to stop publishing
+ the Service Name identified by the Publish Id in the message.
+*/
+typedef struct {
+ u16 publish_id;
+} NanPublishCancelRequest;
+
+/*
+ NAN Subscribe Structure
+ The SubscribeServiceReq message is sent to the Discovery Engine
+ whenever the Upper layers would like to listen for a Service Name
+*/
+typedef struct {
+ u16 subscribe_id; /* id 0 means new subscribe, non zero is existing subscribe */
+ u16 ttl; /* how many seconds to run for. 0 means forever until canceled */
+ /*
+ period: Awake DW Interval for subscribe(service)
+ Indicates the interval between two Discovery Windows in which
+ the device supporting the service is awake to transmit or
+ receive the Service Discovery frames.
+ Valid values of Awake DW Interval are: 1, 2, 4, 8 and 16, value 0 will
+ default to 1.
+ */
+ u16 period;
+
+ /* Flag which specifies how the Subscribe request shall be processed. */
+ NanSubscribeType subscribe_type; /* 0 - PASSIVE , 1- ACTIVE */
+
+ /* Flag which specifies on Active Subscribes how the Service Response Filter attribute is
+ * populated.*/
+ NanSRFType serviceResponseFilter; /* 0 - Bloom Filter, 1 - MAC Addr */
+
+ /* Flag which specifies how the Service Response Filter Include bit is populated.*/
+ NanSRFIncludeType
+ serviceResponseInclude; /* 0=Do not respond if in the Address Set, 1= Respond */
+
+ /* Flag which specifies if the Service Response Filter should be used when creating
+ * Subscribes.*/
+ NanSRFState useServiceResponseFilter; /* 0=Do not send the Service Response Filter,1= send */
+
+ /*
+ Flag which specifies if the Service Specific Info is needed in
+ the Publish message before creating the MatchIndication
+ */
+ NanSsiInMatchInd ssiRequiredForMatchIndication; /* 0=Not needed, 1= Required */
+
+ /*
+ Field which specifies how the matching indication to host is controlled.
+ 0 - Match and Indicate Once
+ 1 - Match and Indicate continuous
+ 2 - Match and Indicate never. This means don't indicate the match to the host.
+ 3 - Reserved
+ */
+ NanMatchAlg subscribe_match_indicator;
+
+ /*
+ The number of Subscribe Matches which should occur
+ before the Subscribe request is automatically terminated.
+ */
+ u8 subscribe_count; /* If this value is 0 this field is not used by the DE.*/
+
+ u16 service_name_len; /* length of service name */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN]; /* UTF-8 encoded string identifying the service */
+
+ /* Sequence of values which further specify the published service beyond the service name*/
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs used to filter out received publish discovery
+ messages. This can be sent both for a Passive or an Active Subscribe
+ */
+ u16 rx_match_filter_len;
+ u8 rx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs included in the
+ Discovery Frame when an Active Subscribe is used.
+ */
+ u16 tx_match_filter_len;
+ u8 tx_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ Flag which specifies that the Subscribe should use the configured RSSI
+ threshold and the received RSSI in order to filter requests
+ 0 – ignore the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+ 1 – use the configured RSSI threshold when running a Service
+ Descriptor attribute or Service ID List Attribute through the DE matching logic.
+
+ */
+ u8 rssi_threshold_flag;
+
+ /*
+ 8-bit bitmap which allows the Host to associate this Active
+ Subscribe with a particular Post-NAN Connectivity attribute
+ which has been sent down in a NanConfigureRequest/NanEnableRequest
+ message. If the DE fails to find a configured Post-NAN
+ connectivity attributes referenced by the bitmap,
+ the DE will return an error code to the Host.
+ If the Subscribe is configured to use a Post-NAN Connectivity
+ attribute and the Host does not refresh the Post-NAN Connectivity
+ attribute the Subscribe will be canceled and the Host will be sent
+ a SubscribeTerminatedIndication message.
+ */
+ u8 connmap;
+ /*
+ NAN Interface Address, conforming to the format as described in
+ 8.2.4.3.2 of IEEE Std. 802.11-2012.
+ */
+ u8 num_intf_addr_present;
+ u8 intf_addr[NAN_MAX_SUBSCRIBE_MAX_ADDRESS][NAN_MAC_ADDR_LEN];
+ /*
+ Set/Enable corresponding bits to disable indications that follow a subscribe.
+ BIT0 - Disable subscribe termination indication.
+ BIT1 - Disable match expired indication.
+ BIT2 - Disable followUp indication received (OTA).
+ */
+ u8 recv_indication_cfg;
+
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+ /* NAN configure service discovery extended attributes */
+ NanSdeaCtrlParams sdea_params;
+
+ /* NAN Ranging configuration */
+ NanRangingCfg ranging_cfg;
+
+ /* Enable/disable NAN serivce Ranging auto response mode */
+ NanRangingAutoResponse ranging_auto_response;
+
+ /*
+ When the ranging_auto_response_cfg is not set, NanRangeRequestInd is
+ received. Nan Range Response to Peer MAC Addr is notified to indicate
+ ACCEPT/REJECT/CANCEL to the requestor.
+ */
+ NanRangeResponseCfg range_response_cfg;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanSubscribeRequest;
+
+/*
+ NAN Subscribe Cancel Structure
+ The SubscribeCancelReq Message is used to request the DE to stop looking for the Service Name.
+*/
+typedef struct {
+ u16 subscribe_id;
+} NanSubscribeCancelRequest;
+
+/*
+ Transmit follow up Structure
+ The TransmitFollowupReq message is sent to the DE to allow the sending of the
+ Service_Specific_Info to a particular MAC address.
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+
+ /*
+ This Id is the Requestor Instance that is passed as
+ part of earlier MatchInd/FollowupInd message.
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN]; /* Unicast address */
+ NanTxPriority priority; /* priority of the request 2=high */
+ NanTransmitWindowType dw_or_faw; /* 0= send in a DW, 1=send in FAW */
+
+ /*
+ Sequence of values which further specify the published service beyond
+ the service name.
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+ /*
+ Set/Enable corresponding bits to disable responses after followUp.
+ BIT0 - Disable followUp response from FW.
+ */
+ u8 recv_indication_cfg;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanTransmitFollowupRequest;
+
+/*
+ Stats Request structure
+ The Discovery Engine can be queried at runtime by the Host processor for statistics
+ concerning various parts of the Discovery Engine.
+*/
+typedef struct {
+ NanStatsType stats_type; /* NAN Statistics Request Type */
+ u8 clear; /* 0= Do not clear the stats and return the current contents , 1= Clear the associated
+ stats */
+} NanStatsRequest;
+
+/*
+ Config Structure
+ The NanConfigurationReq message is sent by the Host to the
+ Discovery Engine in order to configure the Discovery Engine during runtime.
+*/
+typedef struct {
+ u8 config_sid_beacon;
+ u8 sid_beacon;
+ u8 config_rssi_proximity;
+ u8 rssi_proximity; // default value -60dBm
+ u8 config_master_pref;
+ u8 master_pref; // default value 0x02
+ /*
+ 1 byte value which defines the RSSI filter threshold.
+ Any Service Descriptors received above this value
+ that are configured for RSSI filtering will be dropped.
+ The rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 config_5g_rssi_close_proximity;
+ u8 rssi_close_proximity_5g_val; // default value -60dBm
+ /*
+ Optional configuration of Configure request.
+ Each of the optional parameters have configure flag which
+ determine whether configuration is to be passed or not.
+ */
+ /*
+ 1 byte quantity which defines the window size over
+ which the “average RSSI” will be calculated over.
+ */
+ u8 config_rssi_window_size;
+ u8 rssi_window_size_val; // default value 0x08
+ /*
+ If set to 1, the Discovery Engine will enclose the Cluster
+ Attribute only sent in Beacons in a Vendor Specific Attribute
+ and transmit in a Service Descriptor Frame.
+ */
+ u8 config_cluster_attribute_val;
+ /*
+ The periodicity in seconds between full scan’s to find any new
+ clusters available in the area. A Full scan should not be done
+ more than every 10 seconds and should not be done less than every
+ 30 seconds.
+ */
+ u8 config_scan_params;
+ NanSocialChannelScanParams scan_params_val;
+ /*
+ 1 byte quantity which forces the Random Factor to a particular
+ value for all transmitted Sync/Discovery beacons
+ */
+ u8 config_random_factor_force;
+ u8 random_factor_force_val; // default value 0x00
+ /*
+ 1 byte quantity which forces the HC for all transmitted Sync and
+ Discovery Beacon NO matter the real HC being received over the
+ air.
+ */
+ u8 config_hop_count_force;
+ u8 hop_count_force_val; // default value of 0
+ /* NAN Post Connectivity Capability */
+ u8 config_conn_capability;
+ NanTransmitPostConnectivityCapability conn_capability_val;
+ /* NAN Post Discover Capability */
+ u8 num_config_discovery_attr;
+ NanTransmitPostDiscovery discovery_attr_val[NAN_MAX_POSTDISCOVERY_LEN];
+ /* NAN Further availability Map */
+ u8 config_fam;
+ NanFurtherAvailabilityMap fam_val;
+ /* Configure 2.4/5GHz DW */
+ NanConfigDW config_dw;
+ /*
+ By default discovery MAC address randomization is enabled
+ and default interval value is 30 minutes i.e. 1800 seconds.
+ The value 0 is used to disable MAC addr randomization.
+ */
+ u8 config_disc_mac_addr_randomization;
+ u32 disc_mac_addr_rand_interval_sec; // default value of 30 minutes
+
+ /*
+ Set/Enable corresponding bits to disable Discovery indications:
+ BIT0 - Disable Discovery MAC Address Event.
+ BIT1 - Disable Started Cluster Event.
+ BIT2 - Disable Joined Cluster Event.
+ */
+ u8 discovery_indication_cfg; // default value of 0
+ /*
+ BIT 0 is used to specify to include Service IDs in Sync/Discovery beacons
+ 0 - Do not include SIDs in any beacons
+ 1 - Include SIDs in all beacons.
+ Rest 7 bits are count field which allows control over the number of SIDs
+ included in the Beacon. 0 means to include as many SIDs that fit into
+ the maximum allow Beacon frame size
+ */
+ u8 config_subscribe_sid_beacon;
+ u32 subscribe_sid_beacon_val; // default value 0x0
+ /*
+ Discovery Beacon Interval config.
+ Default value is 128 msec in 2G DW and 176 msec in 2G/5G DW.
+ When 0 value is passed it is reset to default value of 128 or 176 msec.
+ */
+ u8 config_discovery_beacon_int;
+ u32 discovery_beacon_interval;
+ /*
+ Enable Number of Spatial Streams.
+ This is NAN Power Optimization feature for NAN discovery.
+ */
+ u8 config_nss;
+ // default value is implementation specific and passing 0 sets it to default
+ u32 nss;
+ /*
+ Enable device level NAN Ranging feature.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_ranging;
+ u32 enable_ranging;
+ /*
+ Enable/Disable DW Early termination.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_dw_early_termination;
+ u32 enable_dw_termination;
+ /*
+ Indicate whether to use NDPE attribute to bring-up TCP/IP connection
+ If config_ndpe_attr is not configured, the default behavior is
+ not using NDPE attr, and the capability is not advertised.
+ 0 - Not use
+ 1 - Use
+ */
+ u8 config_ndpe_attr;
+ u32 use_ndpe_attr;
+ /*
+ Enable NAN v3.1 instant communication mode.
+ 0 - Disable
+ 1 - Enable
+ */
+ u8 config_enable_instant_mode;
+ u32 enable_instant_mode;
+ /*
+ Config NAN v3.1 instant communication channel selected over NFC/OOB method.
+ If dual band is supported default channel is 149 or 44 as per regulatory domain,
+ else channel 6 (send frequency in MHz).
+ Sometimes depending on country code retrictions, even 149/44 may be restricted
+ in those cases instant channel will be operational only in 2.4GHz.
+ Use wifi_get_usable_channels() API to get supported bands/channels before
+ Instant mode NFC handshake is triggered
+ */
+ u8 config_instant_mode_channel;
+ wifi_channel instant_mode_channel;
+} NanConfigRequest;
+
+/*
+ TCA Structure
+ The Discovery Engine can be configured to send up Events whenever a configured
+ Threshold Crossing Alert (TCA) Type crosses an integral threshold in a particular direction.
+*/
+typedef struct {
+ NanTcaType tca_type; /* Nan Protocol Threshold Crossing Alert (TCA) Codes */
+
+ /* flag which control whether or not an event is generated for the Rising direction */
+ u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which control whether or not an event is generated for the Falling direction */
+ u8 falling_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which requests a previous TCA request to be cleared from the DE */
+ u8 clear; /*0= Do not clear the TCA, 1=Clear the TCA */
+
+ /* 32 bit value which represents the threshold to be used.*/
+ u32 threshold;
+} NanTCARequest;
+
+/*
+ Beacon Sdf Payload Structure
+ The Discovery Engine can be configured to publish vendor specific attributes as part of
+ beacon or service discovery frame transmitted as part of this request..
+*/
+typedef struct {
+ /*
+ NanVendorAttribute will have the Vendor Specific Attribute which the
+ vendor wants to publish as part of Discovery or Sync or Service discovery frame
+ */
+ NanTransmitVendorSpecificAttribute vsa;
+} NanBeaconSdfPayloadRequest;
+
+/* Publish statistics. */
+typedef struct {
+ u32 validPublishServiceReqMsgs;
+ u32 validPublishServiceRspMsgs;
+ u32 validPublishServiceCancelReqMsgs;
+ u32 validPublishServiceCancelRspMsgs;
+ u32 validPublishRepliedIndMsgs;
+ u32 validPublishTerminatedIndMsgs;
+ u32 validActiveSubscribes;
+ u32 validMatches;
+ u32 validFollowups;
+ u32 invalidPublishServiceReqMsgs;
+ u32 invalidPublishServiceCancelReqMsgs;
+ u32 invalidActiveSubscribes;
+ u32 invalidMatches;
+ u32 invalidFollowups;
+ u32 publishCount;
+ u32 publishNewMatchCount;
+ u32 pubsubGlobalNewMatchCount;
+} NanPublishStats;
+
+/* Subscribe statistics. */
+typedef struct {
+ u32 validSubscribeServiceReqMsgs;
+ u32 validSubscribeServiceRspMsgs;
+ u32 validSubscribeServiceCancelReqMsgs;
+ u32 validSubscribeServiceCancelRspMsgs;
+ u32 validSubscribeTerminatedIndMsgs;
+ u32 validSubscribeMatchIndMsgs;
+ u32 validSubscribeUnmatchIndMsgs;
+ u32 validSolicitedPublishes;
+ u32 validMatches;
+ u32 validFollowups;
+ u32 invalidSubscribeServiceReqMsgs;
+ u32 invalidSubscribeServiceCancelReqMsgs;
+ u32 invalidSubscribeFollowupReqMsgs;
+ u32 invalidSolicitedPublishes;
+ u32 invalidMatches;
+ u32 invalidFollowups;
+ u32 subscribeCount;
+ u32 bloomFilterIndex;
+ u32 subscribeNewMatchCount;
+ u32 pubsubGlobalNewMatchCount;
+} NanSubscribeStats;
+
+/* NAN DW Statistics*/
+typedef struct {
+ /* RX stats */
+ u32 validFrames;
+ u32 validActionFrames;
+ u32 validBeaconFrames;
+ u32 ignoredActionFrames;
+ u32 ignoredBeaconFrames;
+ u32 invalidFrames;
+ u32 invalidActionFrames;
+ u32 invalidBeaconFrames;
+ u32 invalidMacHeaders;
+ u32 invalidPafHeaders;
+ u32 nonNanBeaconFrames;
+
+ u32 earlyActionFrames;
+ u32 inDwActionFrames;
+ u32 lateActionFrames;
+
+ /* TX stats */
+ u32 framesQueued;
+ u32 totalTRSpUpdates;
+ u32 completeByTRSp;
+ u32 completeByTp75DW;
+ u32 completeByTendDW;
+ u32 lateActionFramesTx;
+} NanDWStats;
+
+/* NAN MAC Statistics. */
+typedef struct {
+ /* RX stats */
+ u32 validFrames;
+ u32 validActionFrames;
+ u32 validBeaconFrames;
+ u32 ignoredActionFrames;
+ u32 ignoredBeaconFrames;
+ u32 invalidFrames;
+ u32 invalidActionFrames;
+ u32 invalidBeaconFrames;
+ u32 invalidMacHeaders;
+ u32 invalidPafHeaders;
+ u32 nonNanBeaconFrames;
+
+ u32 earlyActionFrames;
+ u32 inDwActionFrames;
+ u32 lateActionFrames;
+
+ /* TX stats */
+ u32 framesQueued;
+ u32 totalTRSpUpdates;
+ u32 completeByTRSp;
+ u32 completeByTp75DW;
+ u32 completeByTendDW;
+ u32 lateActionFramesTx;
+
+ u32 twIncreases;
+ u32 twDecreases;
+ u32 twChanges;
+ u32 twHighwater;
+ u32 bloomFilterIndex;
+} NanMacStats;
+
+/* NAN Sync Statistics*/
+typedef struct {
+ u64 currTsf;
+ u64 myRank;
+ u64 currAmRank;
+ u64 lastAmRank;
+ u32 currAmBTT;
+ u32 lastAmBTT;
+ u8 currAmHopCount;
+ u8 currRole;
+ u16 currClusterId;
+
+ u64 timeSpentInCurrRole;
+ u64 totalTimeSpentAsMaster;
+ u64 totalTimeSpentAsNonMasterSync;
+ u64 totalTimeSpentAsNonMasterNonSync;
+ u32 transitionsToAnchorMaster;
+ u32 transitionsToMaster;
+ u32 transitionsToNonMasterSync;
+ u32 transitionsToNonMasterNonSync;
+ u32 amrUpdateCount;
+ u32 amrUpdateRankChangedCount;
+ u32 amrUpdateBTTChangedCount;
+ u32 amrUpdateHcChangedCount;
+ u32 amrUpdateNewDeviceCount;
+ u32 amrExpireCount;
+ u32 mergeCount;
+ u32 beaconsAboveHcLimit;
+ u32 beaconsBelowRssiThresh;
+ u32 beaconsIgnoredNoSpace;
+ u32 beaconsForOurCluster;
+ u32 beaconsForOtherCluster;
+ u32 beaconCancelRequests;
+ u32 beaconCancelFailures;
+ u32 beaconUpdateRequests;
+ u32 beaconUpdateFailures;
+ u32 syncBeaconTxAttempts;
+ u32 syncBeaconTxFailures;
+ u32 discBeaconTxAttempts;
+ u32 discBeaconTxFailures;
+ u32 amHopCountExpireCount;
+ u32 ndpChannelFreq;
+ u32 ndpChannelFreq2;
+ u32 schedUpdateChannelFreq;
+} NanSyncStats;
+
+/* NAN Misc DE Statistics */
+typedef struct {
+ u32 validErrorRspMsgs;
+ u32 validTransmitFollowupReqMsgs;
+ u32 validTransmitFollowupRspMsgs;
+ u32 validFollowupIndMsgs;
+ u32 validConfigurationReqMsgs;
+ u32 validConfigurationRspMsgs;
+ u32 validStatsReqMsgs;
+ u32 validStatsRspMsgs;
+ u32 validEnableReqMsgs;
+ u32 validEnableRspMsgs;
+ u32 validDisableReqMsgs;
+ u32 validDisableRspMsgs;
+ u32 validDisableIndMsgs;
+ u32 validEventIndMsgs;
+ u32 validTcaReqMsgs;
+ u32 validTcaRspMsgs;
+ u32 validTcaIndMsgs;
+ u32 invalidTransmitFollowupReqMsgs;
+ u32 invalidConfigurationReqMsgs;
+ u32 invalidStatsReqMsgs;
+ u32 invalidEnableReqMsgs;
+ u32 invalidDisableReqMsgs;
+ u32 invalidTcaReqMsgs;
+} NanDeStats;
+
+/* Publish Response Message structure */
+typedef struct {
+ u16 publish_id;
+} NanPublishResponse;
+
+/* Subscribe Response Message structure */
+typedef struct {
+ u16 subscribe_id;
+} NanSubscribeResponse;
+
+/*
+ Stats Response Message structure
+ The Discovery Engine response to a request by the Host for statistics.
+*/
+typedef struct {
+ NanStatsType stats_type;
+ union {
+ NanPublishStats publish_stats;
+ NanSubscribeStats subscribe_stats;
+ NanMacStats mac_stats;
+ NanSyncStats sync_stats;
+ NanDeStats de_stats;
+ NanDWStats dw_stats;
+ } data;
+} NanStatsResponse;
+
+/* Response returned for Initiators Data request */
+typedef struct {
+ /*
+ Unique token Id generated on the initiator
+ side used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+} NanDataPathRequestResponse;
+
+/*
+ NAN Response messages
+*/
+typedef struct {
+ NanStatusType status; /* contains the result code */
+ char nan_error[NAN_ERROR_STR_LEN]; /* Describe the NAN error type */
+ NanResponseType response_type; /* NanResponseType Definitions */
+ union {
+ NanPublishResponse publish_response;
+ NanSubscribeResponse subscribe_response;
+ NanStatsResponse stats_response;
+ NanDataPathRequestResponse data_request_response;
+ NanCapabilities nan_capabilities;
+ } body;
+} NanResponseMsg;
+
+/*
+ Publish Replied Indication
+ The PublishRepliedInd Message is sent by the DE when an Active Subscribe is
+ received over the air and it matches a Solicited PublishServiceReq which had
+ been created with the replied_event_flag set.
+*/
+typedef struct {
+ /*
+ A 32 bit Requestor Instance Id which is sent to the Application.
+ This Id will be sent in any subsequent UnmatchInd/FollowupInd
+ messages
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ If RSSI filtering was configured in NanPublishRequest then this
+ field will contain the received RSSI value. 0 if not
+ */
+ u8 rssi_value;
+} NanPublishRepliedInd;
+
+/*
+ Publish Terminated
+ The PublishTerminatedInd message is sent by the DE whenever a Publish
+ terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+ /* Id returned during the initial Publish */
+ u16 publish_id;
+ /*
+ For all user configured termination NAN_STATUS_SUCCESS
+ and no other reasons expected from firmware.
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanPublishTerminatedInd;
+
+/*
+ Match Indication
+ The MatchInd message is sent once per responding MAC address whenever
+ the Discovery Engine detects a match for a previous SubscribeServiceReq
+ or PublishServiceReq.
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+ /*
+ A 32 bit Requestor Instance Id which is sent to the Application.
+ This Id will be sent in any subsequent UnmatchInd/FollowupInd
+ messages
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN];
+
+ /*
+ Sequence of octets which were received in a Discovery Frame matching the
+ Subscribe Request.
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Ordered sequence of <length, value> pairs received in the Discovery Frame
+ matching the Subscribe Request.
+ */
+ u16 sdf_match_filter_len;
+ u8 sdf_match_filter[NAN_MAX_MATCH_FILTER_LEN];
+
+ /*
+ flag to indicate if the Match occurred in a Beacon Frame or in a
+ Service Discovery Frame.
+ 0 - Match occured in a Service Discovery Frame
+ 1 - Match occured in a Beacon Frame
+ */
+ u8 match_occured_flag;
+
+ /*
+ flag to indicate FW is out of resource and that it can no longer
+ track this Service Name. The Host still need to send the received
+ Match_Handle but duplicate MatchInd messages may be received on
+ this Handle until the resource frees up.
+ 0 - FW is caching this match
+ 1 - FW is unable to cache this match
+ */
+ u8 out_of_resource_flag;
+
+ /*
+ If RSSI filtering was configured in NanSubscribeRequest then this
+ field will contain the received RSSI value. 0 if not.
+ All rssi values should be specified without sign.
+ For eg: -70dBm should be specified as 70.
+ */
+ u8 rssi_value;
+
+ /*
+ optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Post Connectivity Capability received */
+ u8 is_conn_capability_valid;
+ NanReceivePostConnectivityCapability conn_capability;
+
+ /* NAN Post Discover Capability */
+ u8 num_rx_discovery_attr;
+ NanReceivePostDiscovery discovery_attr[NAN_MAX_POSTDISCOVERY_LEN];
+
+ /* NAN Further availability Map */
+ u8 num_chans;
+ NanFurtherAvailabilityChannel famchan[NAN_MAX_FAM_CHANNELS];
+
+ /* NAN Cluster Attribute */
+ u8 cluster_attribute_len;
+ u8 cluster_attribute[NAN_MAX_CLUSTER_ATTRIBUTE_LEN];
+
+ /* NAN Cipher Suite */
+ u32 peer_cipher_type;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+
+ /* Peer service discovery extended attributes */
+ NanSdeaCtrlParams peer_sdea_params;
+
+ /*
+ Ranging indication and NanMatchAlg are not tied.
+ Ex: NanMatchAlg can indicate Match_ONCE, but ranging
+ indications can be continuous. All ranging indications
+ depend on SDEA control parameters of ranging required for
+ continuous, and ingress/egress values in the ranging config.
+ Ranging indication data is notified if:
+ 1) Ranging required is enabled in SDEA.
+ range info notified continuous.
+ 2) if range_limit ingress/egress MASKS are enabled
+ notify once for ingress >= ingress_distance
+ and egress <= egress_distance, same for ingress_egress_both
+ 3) if the Awake DW intervals are higher than the ranging intervals,
+ priority is given to the device DW intervalsi.
+ */
+ /*
+ Range Info includes:
+ 1) distance to the NAN device with the MAC address indicated
+ with ranged mac address.
+ 2) Ranging event matching the configuration of continuous/ingress/egress.
+ */
+ NanRangeInfo range_info;
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanMatchInd;
+
+/*
+ MatchExpired Indication
+ The MatchExpiredInd message is sent whenever the Discovery Engine detects that
+ a previously Matched Service has been gone for too long. If the previous
+ MatchInd message for this Publish/Subscribe Id had the out_of_resource_flag
+ set then this message will not be received
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+ /*
+ 32 bit value sent by the DE in a previous
+ MatchInd/FollowupInd to the application.
+ */
+ u32 requestor_instance_id;
+} NanMatchExpiredInd;
+
+/*
+ Subscribe Terminated
+ The SubscribeTerminatedInd message is sent by the DE whenever a
+ Subscribe terminates from a user-specified timeout or a unrecoverable error in the DE.
+*/
+typedef struct {
+ /* Id returned during initial Subscribe */
+ u16 subscribe_id;
+ /*
+ For all user configured termination NAN_STATUS_SUCCESS
+ and no other reasons expected from firmware.
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanSubscribeTerminatedInd;
+
+/*
+ Followup Indication Message
+ The FollowupInd message is sent by the DE to the Host whenever it receives a
+ Followup message from another peer.
+*/
+typedef struct {
+ /* Publish or Subscribe Id of an earlier Publish/Subscribe */
+ u16 publish_subscribe_id;
+ /*
+ A 32 bit Requestor instance Id which is sent to the Application.
+ This Id will be used in subsequent UnmatchInd/FollowupInd messages.
+ */
+ u32 requestor_instance_id;
+ u8 addr[NAN_MAC_ADDR_LEN];
+
+ /* Flag which the DE uses to decide if received in a DW or a FAW*/
+ u8 dw_or_faw; /* 0=Received in a DW, 1 = Received in a FAW*/
+
+ /*
+ Sequence of values which further specify the published service beyond
+ the service name
+ */
+ u16 service_specific_info_len;
+ u8 service_specific_info[NAN_MAX_SERVICE_SPECIFIC_INFO_LEN];
+
+ /*
+ Sequence of values indicating the service specific info in SDEA
+ */
+ u16 sdea_service_specific_info_len;
+ u8 sdea_service_specific_info[NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN];
+} NanFollowupInd;
+
+/*
+ Event data notifying the Mac address of the Discovery engine.
+ which is reported as one of the Discovery engine event
+*/
+typedef struct {
+ u8 addr[NAN_MAC_ADDR_LEN];
+} NanMacAddressEvent;
+
+/*
+ Event data notifying the Cluster address of the cluster
+ which is reported as one of the Discovery engine event
+*/
+typedef struct {
+ u8 addr[NAN_MAC_ADDR_LEN];
+} NanClusterEvent;
+
+/*
+ Discovery Engine Event Indication
+ The Discovery Engine can inform the Host when significant events occur
+ The data following the EventId is dependent upon the EventId type.
+ In other words, each new event defined will carry a different
+ structure of information back to the host.
+*/
+typedef struct {
+ NanDiscEngEventType event_type; /* NAN Protocol Event Codes */
+ union {
+ /*
+ MacAddressEvent which will have 6 byte mac address
+ of the Discovery engine.
+ */
+ NanMacAddressEvent mac_addr;
+ /*
+ Cluster Event Data which will be obtained when the
+ device starts a new cluster or joins a cluster.
+ The event data will have 6 byte octet string of the
+ cluster started or joined.
+ */
+ NanClusterEvent cluster;
+ } data;
+} NanDiscEngEventInd;
+
+/* Cluster size TCA event*/
+typedef struct {
+ /* size of the cluster*/
+ u32 cluster_size;
+} NanTcaClusterEvent;
+
+/*
+ NAN TCA Indication
+ The Discovery Engine can inform the Host when significant events occur.
+ The data following the TcaId is dependent upon the TcaId type.
+ In other words, each new event defined will carry a different structure
+ of information back to the host.
+*/
+typedef struct {
+ NanTcaType tca_type;
+ /* flag which defines if the configured Threshold has risen above the threshold */
+ u8 rising_direction_evt_flag; /* 0 - no event, 1 - event */
+
+ /* flag which defines if the configured Threshold has fallen below the threshold */
+ u8 falling_direction_evt_flag; /* 0 - no event, 1 - event */
+ union {
+ /*
+ This event in obtained when the cluser size threshold
+ is crossed. Event will have the cluster size
+ */
+ NanTcaClusterEvent cluster;
+ } data;
+} NanTCAInd;
+
+/*
+ NAN Disabled Indication
+ The NanDisableInd message indicates to the upper layers that the Discovery
+ Engine has flushed all state and has been shutdown. When this message is received
+ the DE is guaranteed to have left the NAN cluster it was part of and will have terminated
+ any in progress Publishes or Subscribes.
+*/
+typedef struct {
+ /*
+ Following reasons expected:
+ NAN_STATUS_SUCCESS
+ NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanDisabledInd;
+
+/*
+ NAN Beacon or SDF Payload Indication
+ The NanBeaconSdfPayloadInd message indicates to the upper layers that information
+ elements were received either in a Beacon or SDF which needs to be delivered
+ outside of a Publish/Subscribe Handle.
+*/
+typedef struct {
+ /* The MAC address of the peer which sent the attributes.*/
+ u8 addr[NAN_MAC_ADDR_LEN];
+ /*
+ Optional attributes. Each optional attribute is associated with a flag
+ which specifies whether the attribute is valid or not
+ */
+ /* NAN Receive Vendor Specific Attribute*/
+ u8 is_vsa_received;
+ NanReceiveVendorSpecificAttribute vsa;
+
+ /* NAN Beacon or SDF Payload Received*/
+ u8 is_beacon_sdf_payload_received;
+ NanBeaconSdfPayloadReceive data;
+} NanBeaconSdfPayloadInd;
+
+/*
+ Event Indication notifying the
+ transmit followup in progress
+*/
+typedef struct {
+ transaction_id id;
+ /*
+ Following reason codes returned:
+ NAN_STATUS_SUCCESS
+ NAN_STATUS_NO_OTA_ACK
+ NAN_STATUS_PROTOCOL_FAILURE
+ */
+ NanStatusType reason;
+ char nan_reason[NAN_ERROR_STR_LEN]; /* Describe the NAN reason type */
+} NanTransmitFollowupInd;
+
+/*
+ Data request Initiator/Responder
+ app/service related info
+*/
+typedef struct {
+ u16 ndp_app_info_len;
+ u8 ndp_app_info[NAN_DP_MAX_APP_INFO_LEN];
+} NanDataPathAppInfo;
+
+/* QoS configuration */
+typedef enum { NAN_DP_CONFIG_NO_QOS = 0, NAN_DP_CONFIG_QOS } NanDataPathQosCfg;
+
+/* Configuration params of Data request Initiator/Responder */
+typedef struct {
+ /* Status Indicating Security/No Security */
+ NanDataPathSecurityCfgStatus security_cfg;
+ NanDataPathQosCfg qos_cfg;
+} NanDataPathCfg;
+
+/* Nan Data Path Initiator requesting a data session */
+typedef struct {
+ /*
+ Unique Instance Id identifying the Responder's service.
+ This is same as publish_id notified on the subscribe side
+ in a publish/subscribe scenario
+ */
+ u32 requestor_instance_id; /* Value 0 for no publish/subscribe */
+
+ /* Config flag for channel request */
+ NanDataPathChannelCfg channel_request_type;
+ /* Channel frequency in MHz to start data-path */
+ wifi_channel channel;
+ /*
+ Discovery MAC addr of the publisher/peer
+ */
+ u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Interface name on which this NDP session is to be started.
+ This will be the same interface name provided during interface
+ create.
+ */
+ char ndp_iface[IFNAMSIZ + 1];
+ /* Initiator/Responder Security/QoS configuration */
+ NanDataPathCfg ndp_cfg;
+ /* App/Service information of the Initiator */
+ NanDataPathAppInfo app_info;
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+ /* length of service name */
+ u32 service_name_len;
+ /*
+ UTF-8 encoded string identifying the service name.
+ The service name field is only used if a Nan discovery
+ is not associated with the NDP (out-of-band discovery).
+ */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN];
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+} NanDataPathInitiatorRequest;
+
+/*
+ Data struct to initiate a data response on the responder side
+ for an indication received with a data request
+*/
+typedef struct {
+ /*
+ Unique token Id generated on the initiator/responder
+ side used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+ /*
+ Interface name on which this NDP session is to be started.
+ This will be the same interface name provided during interface
+ create.
+ */
+ char ndp_iface[IFNAMSIZ + 1];
+ /* Initiator/Responder Security/QoS configuration */
+ NanDataPathCfg ndp_cfg;
+ /* App/Service information of the responder */
+ NanDataPathAppInfo app_info;
+ /* Response Code indicating ACCEPT/REJECT/DEFER */
+ NanDataPathResponseCode rsp_code;
+ /* NAN Cipher Suite Type */
+ u32 cipher_type;
+ /*
+ Nan Security Key Info is optional in Discovery phase.
+ PMK or passphrase info can be passed during
+ the NDP session.
+ */
+ NanSecurityKeyInfo key_info;
+ /* length of service name */
+ u32 service_name_len;
+ /*
+ UTF-8 encoded string identifying the service name.
+ The service name field is only used if a Nan discovery
+ is not associated with the NDP (out-of-band discovery).
+ */
+ u8 service_name[NAN_MAX_SERVICE_NAME_LEN];
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+} NanDataPathIndicationResponse;
+
+/* NDP termination info */
+typedef struct {
+ u8 num_ndp_instances;
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id[];
+} NanDataPathEndRequest;
+
+/*
+ Event indication received on the
+ responder side when a Nan Data request or
+ NDP session is initiated on the Initiator side
+*/
+typedef struct {
+ /*
+ Unique Instance Id corresponding to a service/session.
+ This is similar to the publish_id generated on the
+ publisher side
+ */
+ u16 service_instance_id;
+ /* Discovery MAC addr of the peer/initiator */
+ u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+ /* Initiator/Responder Security/QoS configuration */
+ NanDataPathCfg ndp_cfg;
+ /* App/Service information of the initiator */
+ NanDataPathAppInfo app_info;
+
+ /* Security Context Identifiers length */
+ u32 scid_len;
+ /*
+ Security Context Identifier attribute contains PMKID
+ shall be included in NDP setup and response messages.
+ Security Context Identifier, Identifies the Security
+ Context. For NAN Shared Key Cipher Suite, this field
+ contains the 16 octet PMKID identifying the PMK used
+ for setting up the Secure Data Path.
+ */
+ u8 scid[NAN_MAX_SCID_BUF_LEN];
+} NanDataPathRequestInd;
+
+/*
+ Event indication of data confirm is received on both
+ initiator and responder side confirming a NDP session
+*/
+typedef struct {
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id;
+ /*
+ NDI mac address of the peer
+ (required to derive target ipv6 address)
+ */
+ u8 peer_ndi_mac_addr[NAN_MAC_ADDR_LEN];
+ /* App/Service information of Initiator/Responder */
+ NanDataPathAppInfo app_info;
+ /* Response code indicating ACCEPT/REJECT/DEFER */
+ NanDataPathResponseCode rsp_code;
+ /*
+ Reason code indicating the cause for REJECT.
+ NAN_STATUS_SUCCESS and NAN_STATUS_PROTOCOL_FAILURE are
+ expected reason codes.
+ */
+ NanStatusType reason_code;
+ /* Number of channels for which info is indicated */
+ u32 num_channels;
+ /*
+ Data indicating the Channel list and BW of the channel.
+ */
+ NanChannelInfo channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED];
+} NanDataPathConfirmInd;
+
+/*
+ Event indication of schedule update is received on both
+ initiator and responder when a schedule change occurs
+*/
+typedef struct {
+ /*
+ NMI mac address
+ */
+ u8 peer_mac_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Reason code indicating the cause of schedule update.
+ BIT_0 NSS Update
+ BIT_1 Channel list update
+ */
+ u32 schedule_update_reason_code;
+ /* Number of channels for which info is indicated */
+ u32 num_channels;
+ /*
+ Data indicating the Channel list and BW of the channel.
+ */
+ NanChannelInfo channel_info[NAN_MAX_CHANNEL_INFO_SUPPORTED];
+ /* Number of NDP instance Ids */
+ u8 num_ndp_instances;
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id[];
+} NanDataPathScheduleUpdateInd;
+
+/*
+ Event indication received on the
+ initiator/responder side terminating
+ a NDP session
+*/
+typedef struct {
+ u8 num_ndp_instances;
+ /*
+ Unique token Id generated on the initiator/responder side
+ used for a NDP session between two NAN devices
+ */
+ NanDataPathId ndp_instance_id[];
+} NanDataPathEndInd;
+
+/*
+ Event indicating Range Request received on the
+ Published side.
+*/
+typedef struct {
+ u16 publish_id; /* id is existing publish */
+ /* Range Requestor's MAC address */
+ u8 range_req_intf_addr[NAN_MAC_ADDR_LEN];
+} NanRangeRequestInd;
+
+/*
+ Event indicating Range report on the
+ Published side.
+*/
+typedef struct {
+ u16 publish_id; /* id is existing publish */
+ /* Range Requestor's MAC address */
+ u8 range_req_intf_addr[NAN_MAC_ADDR_LEN];
+ /*
+ Distance to the NAN device with the MAC address indicated
+ with ranged mac address.
+ */
+ u32 range_measurement_mm;
+} NanRangeReportInd;
+
+/* Response and Event Callbacks */
+typedef struct {
+ /* NotifyResponse invoked to notify the status of the Request */
+ void (*NotifyResponse)(transaction_id id, NanResponseMsg* rsp_data);
+ /* Callbacks for various Events */
+ void (*EventPublishReplied)(NanPublishRepliedInd* event);
+ void (*EventPublishTerminated)(NanPublishTerminatedInd* event);
+ void (*EventMatch)(NanMatchInd* event);
+ void (*EventMatchExpired)(NanMatchExpiredInd* event);
+ void (*EventSubscribeTerminated)(NanSubscribeTerminatedInd* event);
+ void (*EventFollowup)(NanFollowupInd* event);
+ void (*EventDiscEngEvent)(NanDiscEngEventInd* event);
+ void (*EventDisabled)(NanDisabledInd* event);
+ void (*EventTca)(NanTCAInd* event);
+ void (*EventBeaconSdfPayload)(NanBeaconSdfPayloadInd* event);
+ void (*EventDataRequest)(NanDataPathRequestInd* event);
+ void (*EventDataConfirm)(NanDataPathConfirmInd* event);
+ void (*EventDataEnd)(NanDataPathEndInd* event);
+ void (*EventTransmitFollowup)(NanTransmitFollowupInd* event);
+ void (*EventRangeRequest)(NanRangeRequestInd* event);
+ void (*EventRangeReport)(NanRangeReportInd* event);
+ void (*EventScheduleUpdate)(NanDataPathScheduleUpdateInd* event);
+} NanCallbackHandler;
+
+/**@brief nan_enable_request
+ * Enable NAN functionality
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanEnableRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_ALREADY_ENABLED
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_NAN_NOT_ALLOWED
+ */
+wifi_error nan_enable_request(transaction_id id, wifi_interface_handle iface,
+ NanEnableRequest* msg);
+
+/**@brief nan_disbale_request
+ * Disable NAN functionality.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDisableRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_PROTOCOL_FAILURE
+ *
+ */
+wifi_error nan_disable_request(transaction_id id, wifi_interface_handle iface);
+
+/**@brief nan_publish_request
+ * Publish request to advertize a service
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPublishRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_NO_RESOURCE_AVAILABLE
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ */
+wifi_error nan_publish_request(transaction_id id, wifi_interface_handle iface,
+ NanPublishRequest* msg);
+
+/**@brief nan_publish_cancel_request
+ * Cancel previous publish request
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanPublishCancelRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_publish_cancel_request(transaction_id id, wifi_interface_handle iface,
+ NanPublishCancelRequest* msg);
+
+/**@brief nan_subscribe_request
+ * Subscribe request to search for a service
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanSubscribeRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_NO_SPACE_AVAILABLE
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ */
+wifi_error nan_subscribe_request(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeRequest* msg);
+
+/**@brief nan_subscribe_cancel_request
+ * Cancel previous subscribe requests.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanSubscribeRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_subscribe_cancel_request(transaction_id id, wifi_interface_handle iface,
+ NanSubscribeCancelRequest* msg);
+
+/**@brief nan_transmit_followup_request
+ * NAN transmit follow up request
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanTransmitFollowupRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID
+ * NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ * NAN_STATUS_FOLLOWUP_QUEUE_FULL
+ * @return Asynchronous TransmitFollowupInd CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_NO_OTA_ACK
+ */
+wifi_error nan_transmit_followup_request(transaction_id id, wifi_interface_handle iface,
+ NanTransmitFollowupRequest* msg);
+
+/**@brief nan_stats_request
+ * Request NAN statistics from Discovery Engine.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_INVALID_PARAM
+ */
+wifi_error nan_stats_request(transaction_id id, wifi_interface_handle iface, NanStatsRequest* msg);
+
+/**@brief nan_config_request
+ * NAN configuration request.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanConfigRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_config_request(transaction_id id, wifi_interface_handle iface,
+ NanConfigRequest* msg);
+
+/**@brief nan_tca_request
+ * Configure the various Threshold crossing alerts
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_tca_request(transaction_id id, wifi_interface_handle iface, NanTCARequest* msg);
+
+/**@brief nan_beacon_sdf_payload_request
+ * Set NAN Beacon or sdf payload to discovery engine.
+ * This instructs the Discovery Engine to begin publishing the
+ * received payload in any Beacon or Service Discovery Frame transmitted
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanStatsRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_beacon_sdf_payload_request(transaction_id id, wifi_interface_handle iface,
+ NanBeaconSdfPayloadRequest* msg);
+
+/* Register NAN callbacks. */
+wifi_error nan_register_handler(wifi_interface_handle iface, NanCallbackHandler handlers);
+
+/* Get NAN HAL version. */
+wifi_error nan_get_version(wifi_handle handle, NanVersion* version);
+
+/**@brief nan_get_capabilities
+ * Get NAN Capabilities
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ */
+/* Get NAN capabilities. */
+wifi_error nan_get_capabilities(transaction_id id, wifi_interface_handle iface);
+
+/* ========== Nan Data Path APIs ================ */
+/**@brief nan_data_interface_create
+ * Create NAN Data Interface.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param iface_name:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_data_interface_create(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+
+/**@brief nan_data_interface_delete
+ * Delete NAN Data Interface.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param iface_name:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ */
+wifi_error nan_data_interface_delete(transaction_id id, wifi_interface_handle iface,
+ char* iface_name);
+
+/**@brief nan_data_request_initiator
+ * Initiate a NAN Data Path session.
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathInitiatorRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID
+ */
+wifi_error nan_data_request_initiator(transaction_id id, wifi_interface_handle iface,
+ NanDataPathInitiatorRequest* msg);
+
+/**@brief nan_data_indication_response
+ * Response to a data indication received
+ * corresponding to a NDP session. An indication
+ * is received with a data request and the responder
+ * will send a data response
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathIndicationResponse:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INVALID_NDP_ID
+ */
+wifi_error nan_data_indication_response(transaction_id id, wifi_interface_handle iface,
+ NanDataPathIndicationResponse* msg);
+
+/**@brief nan_data_end
+ * NDL termination request: from either Initiator/Responder
+ *
+ * @param transaction_id:
+ * @param wifi_interface_handle:
+ * @param NanDataPathEndRequest:
+ * @return Synchronous wifi_error
+ * @return Asynchronous NotifyResponse CB return
+ * NAN_STATUS_SUCCESS
+ * NAN_STATUS_INVALID_PARAM
+ * NAN_STATUS_INTERNAL_FAILURE
+ * NAN_STATUS_PROTOCOL_FAILURE
+ * NAN_STATUS_INVALID_NDP_ID
+ */
+wifi_error nan_data_end(transaction_id id, wifi_interface_handle iface, NanDataPathEndRequest* msg);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NAN_H__ */
diff --git a/wifi/1.6/default/hal_legacy/wifi_offload.h b/wifi/1.6/default/hal_legacy/wifi_offload.h
new file mode 100644
index 0000000..0c69e39
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_offload.h
@@ -0,0 +1,30 @@
+#include "wifi_hal.h"
+
+#ifndef __WIFI_HAL_OFFLOAD_H
+#define __WIFI_HAL_OFFLOAD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define ETHER_ADDR_LEN 6 // Ethernet frame address length
+#define N_AVAIL_ID 3 // available mkeep_alive IDs from 1 to 3
+#define MKEEP_ALIVE_IP_PKT_MAX 256 // max size of IP packet for keep alive
+
+/**
+ * Send specified keep alive packet periodically.
+ */
+wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface,
+ u16 ether_type, u8* ip_packet, u16 ip_packet_len,
+ u8* src_mac_addr, u8* dst_mac_addr, u32 period_msec);
+
+/**
+ * Stop sending keep alive packet.
+ */
+wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id, wifi_interface_handle iface);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /*__WIFI_HAL_OFFLOAD_H */
diff --git a/wifi/1.6/default/hal_legacy/wifi_twt.h b/wifi/1.6/default/hal_legacy/wifi_twt.h
new file mode 100644
index 0000000..994bb18
--- /dev/null
+++ b/wifi/1.6/default/hal_legacy/wifi_twt.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __WIFI_HAL_TWT_H__
+#define __WIFI_HAL_TWT_H__
+
+#include "wifi_hal.h"
+
+typedef struct {
+ u8 requester_supported; // 0 for not supporting requester
+ u8 responder_supported; // 0 for not supporting responder
+ u8 broadcast_twt_supported; // 0 for not supporting broadcast TWT
+ u8 flexibile_twt_supported; // 0 for not supporting flexible TWT
+} TwtCapability;
+
+typedef struct {
+ TwtCapability device_capability;
+ TwtCapability peer_capability;
+} TwtCapabilitySet;
+
+// For all optional fields below, if no value specify -1
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+ u8 trigger_type; // 0 for non-triggered TWT, 1 for triggered TWT
+ s32 wake_dur_us; // Proposed wake duration in us
+ s32 wake_int_us; // Average wake interval in us
+ s32 wake_int_min_us; // Min wake interval in us. Optional.
+ s32 wake_int_max_us; // Max wake interval in us. Optional.
+ s32 wake_dur_min_us; // Min wake duration in us. Optional.
+ s32 wake_dur_max_us; // Max wake duration in us. Optional.
+ s32 avg_pkt_size; // Average bytes of each packet to send in each wake
+ // duration. Optional.
+ s32 avg_pkt_num; // Average number of packets to send in each wake
+ // duration. Optional.
+ s32 wake_time_off_us; // First wake duration time offset in us. Optional.
+} TwtSetupRequest;
+
+typedef enum {
+ TWT_SETUP_SUCCESS = 0, // TWT setup is accepted.
+ TWT_SETUP_REJECT = 1, // TWT setup is rejected by AP.
+ TWT_SETUP_TIMEOUT = 2, // TWT setup response from AP times out.
+ TWT_SETUP_IE = 3, // AP sent TWT Setup IE parsing failure.
+ TWT_SETUP_PARAMS = 4, // AP sent TWT Setup IE Parameters invalid.
+ TWT_SETUP_ERROR = 255, // Generic error
+} TwtSetupReasonCode;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 status; // 0 for success, non-zero for failure
+ TwtSetupReasonCode reason_code;
+ u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+ u8 trigger_type; // 0 for non-triggered TWT, 1 for triggered TWT
+ s32 wake_dur_us; // Proposed wake duration in us
+ s32 wake_int_us; // Average wake interval in us
+ s32 wake_time_off_us; // First wake duration time offset in us.
+} TwtSetupResponse;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setp request, 1 for all TWT
+ u8 negotiation_type; // 0 for individual TWT, 1 for broadcast TWT
+} TwtTeardownRequest;
+
+typedef enum {
+ TWT_TD_RC_HOST = 0, // Teardown triggered by Host
+ TWT_TD_RC_PEER = 1, // Peer initiated teardown
+ TWT_TD_RC_MCHAN = 2, // Teardown due to MCHAN Active
+ TWT_TD_RC_MCNX = 3, // Teardown due to MultiConnection
+ TWT_TD_RC_CSA = 4, // Teardown due to CSA
+ TWT_TD_RC_BTCX = 5, // Teardown due to BT Coex
+ TWT_TD_RC_SETUP_FAIL = 6, // Setup fails midway. Teardown all connections
+ TWT_TD_RC_SCHED = 7, // Teardown by TWT Scheduler
+ TWT_TD_RC_ERROR = 255, // Generic error cases
+} TwtTeardownReason;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setp request, 1 for all TWT
+ u8 status; // 0 for success, non-zero for failure
+ TwtTeardownReason reason;
+} TwtTeardownCompletion;
+
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setup request, 1 for all TWT
+ s32 resume_time_us; // If -1, TWT is suspended for indefinite time.
+ // Otherwise, TWT is suspended for resume_time_us
+} TwtInfoFrameRequest;
+
+typedef enum {
+ TWT_INFO_RC_HOST = 0, // Host initiated TWT Info frame */
+ TWT_INFO_RC_PEER = 1, // Peer initiated TWT Info frame
+ TWT_INFO_RC_ERROR = 2, // Generic error conditions */
+} TwtInfoFrameReason;
+
+// TWT Info frame triggered externally.
+// Device should not send TwtInfoFrameReceived to Host for internally
+// triggered TWT Info frame during SCAN, MCHAN operations.
+typedef struct {
+ u8 config_id; // An unique ID for an individual TWT request
+ u8 all_twt; // 0 for individual setup request, 1 for all TWT
+ u8 status; // 0 for success, non-zero for failure
+ TwtInfoFrameReason reason;
+ u8 twt_resumed; // 1 - TWT resumed, 0 - TWT suspended
+} TwtInfoFrameReceived;
+
+typedef struct {
+ u8 config_id;
+ u32 avg_pkt_num_tx; // Average number of Tx packets in each wake duration.
+ u32 avg_pkt_num_rx; // Average number of Rx packets in each wake duration.
+ u32 avg_tx_pkt_size; // Average bytes per Rx packet in each wake duration.
+ u32 avg_rx_pkt_size; // Average bytes per Rx packet in each wake duration.
+ u32 avg_eosp_dur_us; // Average duration of early terminated SP
+ u32 eosp_count; // Count of early terminations
+ u32 num_sp; // Count of service period (SP), also known as wake duration.
+} TwtStats;
+
+// Asynchronous notification from the device.
+// For example, TWT was torn down by the device and later when the device is
+// ready, it can send this async notification.
+// This can be expandable in future.
+typedef enum {
+ TWT_NOTIF_ALLOW_TWT = 1, // Device ready to process TWT Setup request
+} TwtNotification;
+
+typedef struct {
+ TwtNotification notification;
+} TwtDeviceNotify;
+
+// Callbacks for various TWT responses and events
+typedef struct {
+ // Callback for TWT setup response
+ void (*EventTwtSetupResponse)(TwtSetupResponse* event);
+ // Callback for TWT teardown completion
+ void (*EventTwtTeardownCompletion)(TwtTeardownCompletion* event);
+ // Callback for TWT info frame received event
+ void (*EventTwtInfoFrameReceived)(TwtInfoFrameReceived* event);
+ // Callback for TWT notification from the device
+ void (*EventTwtDeviceNotify)(TwtDeviceNotify* event);
+} TwtCallbackHandler;
+
+#endif /* __WIFI_HAL_TWT_H__ */
diff --git a/wifi/1.6/default/wifi_chip.cpp b/wifi/1.6/default/wifi_chip.cpp
index c7c00b1..920beb8 100644
--- a/wifi/1.6/default/wifi_chip.cpp
+++ b/wifi/1.6/default/wifi_chip.cpp
@@ -1926,9 +1926,10 @@
// concurrent STA and not dual AP, else start with idx 0.
std::string WifiChip::allocateApIfaceName() {
// Check if we have a dedicated iface for AP.
- std::vector<std::string> ifnames = getPredefinedApIfaceNames(false);
- if (!ifnames.empty()) {
- return ifnames[0];
+ std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
+ for (auto const& ifname : ifnames) {
+ if (findUsingName(ap_ifaces_, ifname)) continue;
+ return ifname;
}
return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
}
diff --git a/wifi/1.6/default/wifi_legacy_hal.cpp b/wifi/1.6/default/wifi_legacy_hal.cpp
index c9bcdc5..43cb7c4 100644
--- a/wifi/1.6/default/wifi_legacy_hal.cpp
+++ b/wifi/1.6/default/wifi_legacy_hal.cpp
@@ -366,6 +366,14 @@
}
}
+// 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) {
+ if (on_cached_scan_results_internal_callback) {
+ on_cached_scan_results_internal_callback(cache_report);
+ }
+}
+
// End of the free-standing "C" style callbacks.
WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
@@ -1589,6 +1597,17 @@
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 status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
+ {onSyncCachedScanResults});
+
+ on_cached_scan_results_internal_callback = nullptr;
+ return status;
+}
+
void WifiLegacyHal::invalidate() {
global_handle_ = nullptr;
iface_name_to_handle_.clear();
diff --git a/wifi/1.6/default/wifi_legacy_hal.h b/wifi/1.6/default/wifi_legacy_hal.h
index 2b923b4..b6bd5ea 100644
--- a/wifi/1.6/default/wifi_legacy_hal.h
+++ b/wifi/1.6/default/wifi_legacy_hal.h
@@ -23,7 +23,7 @@
#include <thread>
#include <vector>
-#include <hardware_legacy/wifi_hal.h>
+#include <hal_legacy/wifi_hal.h>
#include <wifi_system/interface_tool.h>
namespace android {
@@ -218,6 +218,7 @@
using ::WIFI_BAND_ABG_WITH_DFS;
using ::WIFI_BAND_BG;
using ::WIFI_BAND_UNSPECIFIED;
+using ::wifi_cached_scan_report;
using ::wifi_cached_scan_results;
using ::WIFI_CHAN_WIDTH_10;
using ::WIFI_CHAN_WIDTH_160;
@@ -465,6 +466,12 @@
std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
};
+// Cached Scan Results response and event callbacks struct.
+struct CachedScanResultsCallbackHandlers {
+ // Callback for Cached Scan Results
+ std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
+};
+
/**
* Class that encapsulates all legacy HAL interactions.
* This class manages the lifetime of the event loop thread used by legacy HAL.
@@ -684,6 +691,8 @@
const ChreCallbackHandlers& handler);
wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
+ wifi_error getWifiCachedScanResults(const std::string& iface_name,
+ const CachedScanResultsCallbackHandlers& handler);
private:
// Retrieve interface handles for all the available interfaces.
diff --git a/wifi/1.6/default/wifi_legacy_hal_stubs.cpp b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
index b3bd373..8f8527a 100644
--- a/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
@@ -167,6 +167,7 @@
populateStubFor(&hal_fn->wifi_nan_rtt_chre_disable_request);
populateStubFor(&hal_fn->wifi_chre_register_handler);
populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
+ populateStubFor(&hal_fn->wifi_get_cached_scan_results);
return true;
}
} // namespace legacy_hal
diff --git a/wifi/1.6/default/wifi_legacy_hal_stubs.h b/wifi/1.6/default/wifi_legacy_hal_stubs.h
index c9a03bf..ebc0347 100644
--- a/wifi/1.6/default/wifi_legacy_hal_stubs.h
+++ b/wifi/1.6/default/wifi_legacy_hal_stubs.h
@@ -17,7 +17,7 @@
#ifndef WIFI_LEGACY_HAL_STUBS_H_
#define WIFI_LEGACY_HAL_STUBS_H_
-#include <hardware_legacy/wifi_hal.h>
+#include <hal_legacy/wifi_hal.h>
namespace android {
namespace hardware {
diff --git a/wifi/1.6/default/wifi_nan_iface.cpp b/wifi/1.6/default/wifi_nan_iface.cpp
index ac2ebc9..4c61ba7 100644
--- a/wifi/1.6/default/wifi_nan_iface.cpp
+++ b/wifi/1.6/default/wifi_nan_iface.cpp
@@ -453,6 +453,7 @@
// Register for iface state toggle events.
iface_util::IfaceEventHandlers event_handlers = {};
+#ifndef WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
const auto shared_ptr_this = weak_ptr_this.promote();
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
@@ -467,6 +468,7 @@
}
}
};
+#endif
iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
}
diff --git a/wifi/aidl/Android.bp b/wifi/aidl/Android.bp
index c0ca667..0c8572c 100644
--- a/wifi/aidl/Android.bp
+++ b/wifi/aidl/Android.bp
@@ -37,6 +37,8 @@
],
min_sdk_version: "30",
lint: {
+ // Disable linter to avoid error about fixed size arrays.
+ // Interface will only be accessed on devices >= U.
enabled: false,
},
},
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AfcChannelAllowance.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AfcChannelAllowance.aidl
new file mode 100644
index 0000000..4d3cd6e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AfcChannelAllowance.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;
+@VintfStability
+parcelable AfcChannelAllowance {
+ android.hardware.wifi.AvailableAfcFrequencyInfo[] availableAfcFrequencyInfos;
+ android.hardware.wifi.AvailableAfcChannelInfo[] availableAfcChannelInfos;
+ long availabilityExpireTimeMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcChannelInfo.aidl
new file mode 100644
index 0000000..d238640
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcChannelInfo.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;
+@VintfStability
+parcelable AvailableAfcChannelInfo {
+ int globalOperatingClass;
+ int channelCfi;
+ int maxEirpDbm;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..cbea5af
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/AvailableAfcFrequencyInfo.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;
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+ int startFrequencyMhz;
+ int endFrequencyMhz;
+ int maxPsd;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
index a102b97..e71dde4 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
@@ -38,7 +38,6 @@
String[] getBridgedInstances();
byte[6] getFactoryMacAddress();
void setCountryCode(in byte[2] code);
- int[] getValidFrequenciesForBand(in android.hardware.wifi.WifiBand band);
void resetToFactoryMacAddress();
void setMacAddress(in byte[6] mac);
}
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 647891f..4ea2081 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
@@ -47,7 +47,7 @@
@PropagateAllowBlocking android.hardware.wifi.IWifiApIface getApIface(in String ifname);
String[] getApIfaceNames();
android.hardware.wifi.IWifiChip.ChipMode[] getAvailableModes();
- android.hardware.wifi.IWifiChip.ChipCapabilityMask getCapabilities();
+ int getFeatureSet();
android.hardware.wifi.WifiDebugHostWakeReasonStats getDebugHostWakeReasonStats();
android.hardware.wifi.WifiDebugRingBufferStatus[] getDebugRingBuffersStatus();
int getId();
@@ -58,8 +58,10 @@
String[] getP2pIfaceNames();
@PropagateAllowBlocking android.hardware.wifi.IWifiStaIface getStaIface(in String ifname);
String[] getStaIfaceNames();
- android.hardware.wifi.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
- android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in android.hardware.wifi.WifiIfaceMode ifaceModeMask, in android.hardware.wifi.IWifiChip.UsableChannelFilter filterMask);
+ android.hardware.wifi.WifiRadioCombination[] getSupportedRadioCombinations();
+ android.hardware.wifi.WifiChipCapabilities getWifiChipCapabilities();
+ android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in int ifaceModeMask, in int filterMask);
+ void setAfcChannelAllowance(in android.hardware.wifi.AfcChannelAllowance afcChannelAllowance);
void registerEventCallback(in android.hardware.wifi.IWifiChipEventCallback callback);
void removeApIface(in String ifname);
void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
@@ -71,7 +73,7 @@
byte[] requestFirmwareDebugDump();
void resetTxPowerScenario();
void selectTxPowerScenario(in android.hardware.wifi.IWifiChip.TxPowerScenario scenario);
- void setCoexUnsafeChannels(in android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] unsafeChannels, in android.hardware.wifi.IWifiChip.CoexRestriction restrictions);
+ void setCoexUnsafeChannels(in android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] unsafeChannels, in int restrictions);
void setCountryCode(in byte[2] code);
void setLatencyMode(in android.hardware.wifi.IWifiChip.LatencyMode mode);
void setMultiStaPrimaryConnection(in String ifName);
@@ -79,24 +81,20 @@
void startLoggingToDebugRingBuffer(in String ringName, in android.hardware.wifi.WifiDebugRingBufferVerboseLevel verboseLevel, in int maxIntervalInSec, in int minDataSizeInBytes);
void stopLoggingToDebugRingBuffer();
void triggerSubsystemRestart();
- const int NO_POWER_CAP_CONSTANT = 2147483647;
+ void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
+ void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
+ const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
@Backing(type="int") @VintfStability
- enum ChipCapabilityMask {
- DEBUG_MEMORY_FIRMWARE_DUMP = 1,
- DEBUG_MEMORY_DRIVER_DUMP = 2,
- DEBUG_RING_BUFFER_CONNECT_EVENT = 4,
- DEBUG_RING_BUFFER_POWER_EVENT = 8,
- DEBUG_RING_BUFFER_WAKELOCK_EVENT = 16,
- DEBUG_RING_BUFFER_VENDOR_DATA = 32,
- DEBUG_HOST_WAKE_REASON_STATS = 64,
- DEBUG_ERROR_ALERTS = 128,
- SET_TX_POWER_LIMIT = 256,
- D2D_RTT = 512,
- D2AP_RTT = 1024,
- USE_BODY_HEAD_SAR = 2048,
- SET_LATENCY_MODE = 4096,
- P2P_RAND_MAC = 8192,
- WIGIG = 16384,
+ enum FeatureSetMask {
+ SET_TX_POWER_LIMIT = (1 << 0) /* 1 */,
+ D2D_RTT = (1 << 1) /* 2 */,
+ D2AP_RTT = (1 << 2) /* 4 */,
+ USE_BODY_HEAD_SAR = (1 << 3) /* 8 */,
+ SET_LATENCY_MODE = (1 << 4) /* 16 */,
+ P2P_RAND_MAC = (1 << 5) /* 32 */,
+ WIGIG = (1 << 6) /* 64 */,
+ SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
+ T2LM_NEGOTIATION = (1 << 8) /* 256 */,
}
@VintfStability
parcelable ChipConcurrencyCombinationLimit {
@@ -128,9 +126,9 @@
}
@Backing(type="int") @VintfStability
enum CoexRestriction {
- WIFI_DIRECT = 1,
- SOFTAP = 2,
- WIFI_AWARE = 4,
+ WIFI_DIRECT = (1 << 0) /* 1 */,
+ SOFTAP = (1 << 1) /* 2 */,
+ WIFI_AWARE = (1 << 2) /* 4 */,
}
@VintfStability
parcelable CoexUnsafeChannel {
@@ -158,8 +156,20 @@
}
@Backing(type="int") @VintfStability
enum UsableChannelFilter {
- CELLULAR_COEXISTENCE = 1,
- CONCURRENCY = 2,
- NAN_INSTANT_MODE = 4,
+ CELLULAR_COEXISTENCE = (1 << 0) /* 1 */,
+ CONCURRENCY = (1 << 1) /* 2 */,
+ NAN_INSTANT_MODE = (1 << 2) /* 4 */,
+ }
+ @Backing(type="int") @VintfStability
+ enum ChannelCategoryMask {
+ INDOOR_CHANNEL = (1 << 0) /* 1 */,
+ DFS_CHANNEL = (1 << 1) /* 2 */,
+ }
+ @Backing(type="int") @VintfStability
+ enum ChipMloMode {
+ DEFAULT = 0,
+ LOW_LATENCY = 1,
+ HIGH_THROUGHPUT = 2,
+ LOW_POWER = 3,
}
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
index 070ca24..0e2f90f 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
@@ -49,7 +49,14 @@
void stopPublishRequest(in char cmdId, in byte sessionId);
void stopSubscribeRequest(in char cmdId, in byte sessionId);
void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
+ void suspendRequest(in char cmdId, in byte sessionId);
+ void resumeRequest(in char cmdId, in byte sessionId);
void transmitFollowupRequest(in char cmdId, in android.hardware.wifi.NanTransmitFollowupRequest msg);
+ void initiatePairingRequest(in char cmdId, in android.hardware.wifi.NanPairingRequest msg);
+ void respondToPairingIndicationRequest(in char cmdId, in android.hardware.wifi.NanRespondToPairingIndicationRequest msg);
+ void initiateBootstrappingRequest(in char cmdId, in android.hardware.wifi.NanBootstrappingRequest msg);
+ void respondToBootstrappingIndicationRequest(in char cmdId, in android.hardware.wifi.NanBootstrappingResponse msg);
+ void terminatePairingRequest(in char cmdId, in int pairingInstanceId);
const int MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 8;
const int MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 63;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
index 591cd8c..8c44330 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -46,6 +46,7 @@
oneway void eventPublishTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
oneway void eventSubscribeTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
oneway void eventTransmitFollowup(in char id, in android.hardware.wifi.NanStatus status);
+ oneway void eventSuspensionModeChanged(in android.hardware.wifi.NanSuspensionModeChangeInd event);
oneway void notifyCapabilitiesResponse(in char id, in android.hardware.wifi.NanStatus status, in android.hardware.wifi.NanCapabilities capabilities);
oneway void notifyConfigResponse(in char id, in android.hardware.wifi.NanStatus status);
oneway void notifyCreateDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
@@ -59,5 +60,16 @@
oneway void notifyStopPublishResponse(in char id, in android.hardware.wifi.NanStatus status);
oneway void notifyStopSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status);
oneway void notifyTerminateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status);
+ oneway void notifySuspendResponse(in char id, in android.hardware.wifi.NanStatus status);
+ oneway void notifyResumeResponse(in char id, in android.hardware.wifi.NanStatus status);
oneway void notifyTransmitFollowupResponse(in char id, in android.hardware.wifi.NanStatus status);
+ oneway void eventPairingRequest(in android.hardware.wifi.NanPairingRequestInd event);
+ oneway void eventPairingConfirm(in android.hardware.wifi.NanPairingConfirmInd event);
+ oneway void notifyInitiatePairingResponse(in char id, in android.hardware.wifi.NanStatus status, in int pairingInstanceId);
+ oneway void notifyRespondToPairingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+ oneway void eventBootstrappingRequest(in android.hardware.wifi.NanBootstrappingRequestInd event);
+ oneway void eventBootstrappingConfirm(in android.hardware.wifi.NanBootstrappingConfirmInd event);
+ oneway void notifyInitiateBootstrappingResponse(in char id, in android.hardware.wifi.NanStatus status, in int bootstrappingInstanceId);
+ oneway void notifyRespondToBootstrappingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+ oneway void notifyTerminatePairingResponse(in char id, in android.hardware.wifi.NanStatus status);
}
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 2f0dfa1..923deff 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
@@ -41,13 +41,12 @@
void enableNdOffload(in boolean enable);
android.hardware.wifi.StaApfPacketFilterCapabilities getApfPacketFilterCapabilities();
android.hardware.wifi.StaBackgroundScanCapabilities getBackgroundScanCapabilities();
- android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask getCapabilities();
+ int getFeatureSet();
android.hardware.wifi.WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
android.hardware.wifi.WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
byte[6] getFactoryMacAddress();
android.hardware.wifi.StaLinkLayerStats getLinkLayerStats();
android.hardware.wifi.StaRoamingCapabilities getRoamingCapabilities();
- int[] getValidFrequenciesForBand(in android.hardware.wifi.WifiBand band);
void installApfPacketFilter(in byte[] program);
byte[] readApfPacketFilterData();
void registerEventCallback(in android.hardware.wifi.IWifiStaIfaceEventCallback callback);
@@ -61,22 +60,22 @@
void stopBackgroundScan(in int cmdId);
void stopRssiMonitoring(in int cmdId);
void stopSendingKeepAlivePackets(in int cmdId);
+ void setDtimMultiplier(in int multiplier);
@Backing(type="int") @VintfStability
- enum StaIfaceCapabilityMask {
- APF = 1,
- BACKGROUND_SCAN = 2,
- LINK_LAYER_STATS = 4,
- RSSI_MONITOR = 8,
- CONTROL_ROAMING = 16,
- PROBE_IE_ALLOWLIST = 32,
- SCAN_RAND = 64,
- STA_5G = 128,
- HOTSPOT = 256,
- PNO = 512,
- TDLS = 1024,
- TDLS_OFFCHANNEL = 2048,
- ND_OFFLOAD = 4096,
- KEEP_ALIVE = 8192,
- DEBUG_PACKET_FATE = 16384,
+ enum FeatureSetMask {
+ APF = (1 << 0) /* 1 */,
+ BACKGROUND_SCAN = (1 << 1) /* 2 */,
+ LINK_LAYER_STATS = (1 << 2) /* 4 */,
+ RSSI_MONITOR = (1 << 3) /* 8 */,
+ CONTROL_ROAMING = (1 << 4) /* 16 */,
+ PROBE_IE_ALLOWLIST = (1 << 5) /* 32 */,
+ SCAN_RAND = (1 << 6) /* 64 */,
+ STA_5G = (1 << 7) /* 128 */,
+ HOTSPOT = (1 << 8) /* 256 */,
+ PNO = (1 << 9) /* 512 */,
+ TDLS = (1 << 10) /* 1024 */,
+ TDLS_OFFCHANNEL = (1 << 11) /* 2048 */,
+ ND_OFFLOAD = (1 << 12) /* 4096 */,
+ KEEP_ALIVE = (1 << 13) /* 8192 */,
}
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
index 0a3ad1a..d584423 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
@@ -34,9 +34,9 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum IfaceConcurrencyType {
- STA = 0,
- AP = 1,
- AP_BRIDGED = 2,
- P2P = 3,
- NAN_IFACE = 4,
+ STA,
+ AP,
+ AP_BRIDGED,
+ P2P,
+ NAN_IFACE,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
index dbdc439..67022df 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
@@ -34,8 +34,8 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum IfaceType {
- STA = 0,
- AP = 1,
- P2P = 2,
- NAN_IFACE = 3,
+ STA,
+ AP,
+ P2P,
+ NAN_IFACE,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
index ca6c910..3f1ea5e 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum NanBandIndex {
NAN_BAND_24GHZ = 0,
- NAN_BAND_5GHZ = 1,
+ NAN_BAND_5GHZ,
NAN_BAND_6GHZ = 2,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
new file mode 100644
index 0000000..5ab8dcd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingConfirmInd {
+ int bootstrappingInstanceId;
+ android.hardware.wifi.NanBootstrappingResponseCode responseCode;
+ android.hardware.wifi.NanStatus reasonCode;
+ int comeBackDelay;
+ byte[] cookie;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingMethod.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingMethod.aidl
new file mode 100644
index 0000000..6ff62b2
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingMethod.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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;
+@Backing(type="int") @VintfStability
+enum NanBootstrappingMethod {
+ BOOTSTRAPPING_OPPORTUNISTIC_MASK = (1 << 0) /* 1 */,
+ BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK = (1 << 1) /* 2 */,
+ BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK = (1 << 2) /* 4 */,
+ BOOTSTRAPPING_QR_DISPLAY_MASK = (1 << 3) /* 8 */,
+ BOOTSTRAPPING_NFC_TAG_MASK = (1 << 4) /* 16 */,
+ BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK = (1 << 5) /* 32 */,
+ BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK = (1 << 6) /* 64 */,
+ BOOTSTRAPPING_QR_SCAN_MASK = (1 << 7) /* 128 */,
+ BOOTSTRAPPING_NFC_READER_MASK = (1 << 8) /* 256 */,
+ BOOTSTRAPPING_SERVICE_MANAGED_MASK = (1 << 14) /* 16384 */,
+ BOOTSTRAPPING_HANDSHAKE_SHIP_MASK = (1 << 15) /* 32768 */,
+}
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
new file mode 100644
index 0000000..dd0a5ed
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingRequest {
+ int peerId;
+ byte[6] peerDiscMacAddr;
+ android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
+ byte[] cookie;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequestInd.aidl
new file mode 100644
index 0000000..a4398e9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequestInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingRequestInd {
+ byte discoverySessionId;
+ int peerId;
+ byte[6] peerDiscMacAddr;
+ int bootstrappingInstanceId;
+ android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
+}
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
new file mode 100644
index 0000000..6dd9b26
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBootstrappingResponse {
+ int bootstrappingInstanceId;
+ boolean acceptRequest;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponseCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponseCode.aidl
new file mode 100644
index 0000000..a3e9e4d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponseCode.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;
+@Backing(type="int") @VintfStability
+enum NanBootstrappingResponseCode {
+ NAN_BOOTSTRAPPING_REQUEST_ACCEPT = 0,
+ NAN_BOOTSTRAPPING_REQUEST_REJECT,
+ NAN_BOOTSTRAPPING_REQUEST_COMEBACK,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
index c44654e..a30893a 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
@@ -47,6 +47,11 @@
int maxAppInfoLen;
int maxQueuedTransmitFollowupMsgs;
int maxSubscribeInterfaceAddresses;
- android.hardware.wifi.NanCipherSuiteType supportedCipherSuites;
+ int supportedCipherSuites;
boolean instantCommunicationModeSupportFlag;
+ boolean supports6g;
+ boolean supportsHe;
+ boolean supportsPairing;
+ boolean supportsSetClusterId;
+ boolean supportsSuspension;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
index 4450956..6f3158e 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -35,8 +35,10 @@
@Backing(type="int") @VintfStability
enum NanCipherSuiteType {
NONE = 0,
- SHARED_KEY_128_MASK = 1,
- SHARED_KEY_256_MASK = 2,
- PUBLIC_KEY_128_MASK = 4,
- PUBLIC_KEY_256_MASK = 8,
+ SHARED_KEY_128_MASK = (1 << 0) /* 1 */,
+ SHARED_KEY_256_MASK = (1 << 1) /* 2 */,
+ PUBLIC_KEY_2WDH_128_MASK = (1 << 2) /* 4 */,
+ PUBLIC_KEY_2WDH_256_MASK = (1 << 3) /* 8 */,
+ PUBLIC_KEY_PASN_128_MASK = (1 << 6) /* 64 */,
+ PUBLIC_KEY_PASN_256_MASK = (1 << 7) /* 128 */,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
index 1dfa45f..6c20543 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum NanClusterEventType {
DISCOVERY_MAC_ADDRESS_CHANGED = 0,
- STARTED_CLUSTER = 1,
- JOINED_CLUSTER = 2,
+ STARTED_CLUSTER,
+ JOINED_CLUSTER,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
index 682699e..99f2af7 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -40,4 +40,5 @@
boolean enableRanging;
boolean enableInstantCommunicationMode;
int instantModeChannel;
+ int clusterId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
index ce75288..4233c32 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum NanDataPathChannelCfg {
CHANNEL_NOT_REQUESTED = 0,
- REQUEST_CHANNEL_SETUP = 1,
- FORCE_CHANNEL_SETUP = 2,
+ REQUEST_CHANNEL_SETUP,
+ FORCE_CHANNEL_SETUP,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
index 64288ca..cb7904d 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum NanDataPathSecurityType {
- OPEN = 0,
- PMK = 1,
- PASSPHRASE = 2,
+ OPEN,
+ PMK,
+ PASSPHRASE,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
index 761cdbb..96d940a 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -51,7 +51,8 @@
android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
boolean rangingRequired;
int rangingIntervalMs;
- android.hardware.wifi.NanRangingIndication configRangingIndications;
+ int configRangingIndications;
char distanceIngressCm;
char distanceEgressCm;
+ boolean enableSessionSuspendability;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanIdentityResolutionAttribute.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
new file mode 100644
index 0000000..843107e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanIdentityResolutionAttribute {
+ byte[8] nonce;
+ byte[8] tag;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
index 697e29a..740a140 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -42,4 +42,5 @@
android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
byte[] appInfo;
byte[] serviceNameOutOfBand;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
index dab33ad..93ac26b 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum NanMatchAlg {
MATCH_ONCE = 0,
- MATCH_CONTINUOUS = 1,
- MATCH_NEVER = 2,
+ MATCH_CONTINUOUS,
+ MATCH_NEVER,
}
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 ae430c4..317489f 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
@@ -47,6 +47,8 @@
boolean peerRequiresSecurityEnabledInNdp;
boolean peerRequiresRanging;
int rangingMeasurementInMm;
- android.hardware.wifi.NanRangingIndication rangingIndicationType;
+ int rangingIndicationType;
byte[] scid;
+ android.hardware.wifi.NanPairingConfig peerPairingConfig;
+ android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingAkm.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingAkm.aidl
new file mode 100644
index 0000000..05bbaee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingAkm.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingAkm {
+ SAE = 0,
+ PASN = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfig.aidl
new file mode 100644
index 0000000..1c04a96
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingConfig {
+ boolean enablePairingSetup;
+ boolean enablePairingCache;
+ boolean enablePairingVerification;
+ int supportedBootstrappingMethods;
+}
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
new file mode 100644
index 0000000..8ecf22a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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 NanPairingConfirmInd {
+ int pairingInstanceId;
+ boolean pairingSuccess;
+ android.hardware.wifi.NanStatus status;
+ android.hardware.wifi.NanPairingRequestType requestType;
+ boolean enablePairingCache;
+ android.hardware.wifi.NpkSecurityAssociation npksa;
+}
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
new file mode 100644
index 0000000..2a644ae
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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 NanPairingRequest {
+ int peerId;
+ byte[6] peerDiscMacAddr;
+ android.hardware.wifi.NanPairingRequestType requestType;
+ boolean enablePairingCache;
+ byte[16] pairingIdentityKey;
+ android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+}
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
new file mode 100644
index 0000000..66762b9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingRequestInd {
+ byte discoverySessionId;
+ int peerId;
+ byte[6] peerDiscMacAddr;
+ int pairingInstanceId;
+ android.hardware.wifi.NanPairingRequestType requestType;
+ boolean enablePairingCache;
+ android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestType.aidl
new file mode 100644
index 0000000..3488340
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingRequestType {
+ NAN_PAIRING_SETUP = 0,
+ NAN_PAIRING_VERIFICATION,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityConfig.aidl
new file mode 100644
index 0000000..1a6a13c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPairingSecurityConfig {
+ android.hardware.wifi.NanPairingSecurityType securityType;
+ byte[32] pmk;
+ byte[] passphrase;
+ android.hardware.wifi.NanPairingAkm akm;
+ android.hardware.wifi.NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityType.aidl
new file mode 100644
index 0000000..9f6c774
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingSecurityType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPairingSecurityType {
+ OPPORTUNISTIC,
+ PMK,
+ PASSPHRASE,
+}
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 d8d6b1b..c49f5f9 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
@@ -38,4 +38,6 @@
android.hardware.wifi.NanPublishType publishType;
android.hardware.wifi.NanTxType txType;
boolean autoAcceptDataPathRequests;
+ android.hardware.wifi.NanPairingConfig pairingConfig;
+ byte[16] identityKey;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
index fc9b7a0..30dffb2 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum NanPublishType {
UNSOLICITED = 0,
- SOLICITED = 1,
- UNSOLICITED_SOLICITED = 2,
+ SOLICITED,
+ UNSOLICITED_SOLICITED,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
index d03dffc..cf72dce 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum NanRangingIndication {
- CONTINUOUS_INDICATION_MASK = 1,
- INGRESS_MET_MASK = 2,
- EGRESS_MET_MASK = 4,
+ CONTINUOUS_INDICATION_MASK = (1 << 0) /* 1 */,
+ INGRESS_MET_MASK = (1 << 1) /* 2 */,
+ EGRESS_MET_MASK = (1 << 2) /* 4 */,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
index 5542ff6..0f873b5 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -40,4 +40,5 @@
android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
byte[] appInfo;
byte[] serviceNameOutOfBand;
+ byte discoverySessionId;
}
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
new file mode 100644
index 0000000..a58890c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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 NanRespondToPairingIndicationRequest {
+ boolean acceptRequest;
+ int pairingInstanceId;
+ android.hardware.wifi.NanPairingRequestType requestType;
+ boolean enablePairingCache;
+ byte[16] pairingIdentityKey;
+ android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
index 3c0583c..82409fd 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
@@ -35,5 +35,5 @@
@Backing(type="int") @VintfStability
enum NanSrfType {
BLOOM_FILTER = 0,
- PARTIAL_MAC_ADDR = 1,
+ PARTIAL_MAC_ADDR,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
index 9eaf518..ec12eb0 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
@@ -47,4 +47,9 @@
ALREADY_ENABLED = 10,
FOLLOWUP_TX_QUEUE_FULL = 11,
UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+ INVALID_PAIRING_ID = 13,
+ INVALID_BOOTSTRAPPING_ID = 14,
+ REDUNDANT_REQUEST = 15,
+ NOT_SUPPORTED = 16,
+ NO_CONNECTION = 17,
}
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 bf176a5..96be096 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
@@ -41,4 +41,6 @@
boolean shouldUseSrf;
boolean isSsiRequiredForMatch;
android.hardware.wifi.MacAddress[] intfAddr;
+ android.hardware.wifi.NanPairingConfig pairingConfig;
+ byte[16] identityKey;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
index 325e40b..4f06df9 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
@@ -35,5 +35,5 @@
@Backing(type="int") @VintfStability
enum NanSubscribeType {
PASSIVE = 0,
- ACTIVE = 1,
+ ACTIVE,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSuspensionModeChangeInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
new file mode 100644
index 0000000..557fc79
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSuspensionModeChangeInd.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.wifi;
+@VintfStability
+parcelable NanSuspensionModeChangeInd {
+ boolean isSuspended;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
index 6f7696f..798d3a2 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
@@ -35,5 +35,5 @@
@Backing(type="int") @VintfStability
enum NanTxType {
BROADCAST = 0,
- UNICAST = 1,
+ UNICAST,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NpkSecurityAssociation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NpkSecurityAssociation.aidl
new file mode 100644
index 0000000..508e920
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NpkSecurityAssociation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NpkSecurityAssociation {
+ byte[16] peerNanIdentityKey;
+ byte[16] localNanIdentityKey;
+ byte[32] npk;
+ android.hardware.wifi.NanPairingAkm akm;
+ android.hardware.wifi.NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
index bd7efff..7cc7002 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
@@ -34,11 +34,12 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum RttBw {
- BW_5MHZ = 1,
- BW_10MHZ = 2,
- BW_20MHZ = 4,
- BW_40MHZ = 8,
- BW_80MHZ = 16,
- BW_160MHZ = 32,
- BW_320MHZ = 64,
+ BW_UNSPECIFIED = 0x0,
+ BW_5MHZ = 0x01,
+ BW_10MHZ = 0x02,
+ BW_20MHZ = 0x04,
+ BW_40MHZ = 0x08,
+ BW_80MHZ = 0x10,
+ BW_160MHZ = 0x20,
+ BW_320MHZ = 0x40,
}
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 02e6479..de26f28 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,9 +34,9 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum RttPreamble {
- LEGACY = 1,
- HT = 2,
- VHT = 4,
- HE = 8,
- EHT = 16,
+ LEGACY = 0x1,
+ HT = 0x2,
+ VHT = 0x4,
+ HE = 0x8,
+ EHT = 0x10,
}
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 743e0bd..8375dcb 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
@@ -57,4 +57,6 @@
int negotiatedBurstNum;
android.hardware.wifi.WifiInformationElement lci;
android.hardware.wifi.WifiInformationElement lcr;
+ int channelFreqMHz;
+ android.hardware.wifi.RttBw packetBw;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
index 1041dd7..249d876 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum StaBackgroundScanBucketEventReportSchemeMask {
- EACH_SCAN = 1,
- FULL_RESULTS = 2,
- NO_BATCH = 4,
+ EACH_SCAN = (1 << 0) /* 1 */,
+ FULL_RESULTS = (1 << 1) /* 2 */,
+ NO_BATCH = (1 << 2) /* 4 */,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
index b49d406..4e9671a 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -38,7 +38,7 @@
android.hardware.wifi.WifiBand band;
int[] frequencies;
int periodInMs;
- android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask eventReportScheme;
+ int eventReportScheme;
int exponentialMaxPeriodInMs;
int exponentialBase;
int exponentialStepCount;
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
index cf68fc6..a419207 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -34,16 +34,5 @@
package android.hardware.wifi;
@VintfStability
parcelable StaLinkLayerIfaceStats {
- int beaconRx;
- int avgRssiMgmt;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
- byte timeSliceDutyCycleInPercent;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
- android.hardware.wifi.StaPeerInfo[] peers;
+ android.hardware.wifi.StaLinkLayerLinkStats[] links;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..cd21c25
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+ int linkId;
+ int radioId;
+ int frequencyMhz;
+ int beaconRx;
+ int avgRssiMgmt;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
+ byte timeSliceDutyCycleInPercent;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+ android.hardware.wifi.StaPeerInfo[] peers;
+ android.hardware.wifi.StaLinkLayerLinkStats.StaLinkState state;
+ @Backing(type="int") @VintfStability
+ enum StaLinkState {
+ UNKNOWN = 0,
+ NOT_IN_USE = (1 << 0) /* 1 */,
+ IN_USE = (1 << 1) /* 2 */,
+ }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
index 5903760..7c75232 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@VintfStability
parcelable StaScanData {
- android.hardware.wifi.StaScanDataFlagMask flags;
+ int flags;
int bucketsScanned;
android.hardware.wifi.StaScanResult[] results;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
index dc8f2f1..0ca4b4b 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
@@ -34,5 +34,5 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum StaScanDataFlagMask {
- INTERRUPTED = 1,
+ INTERRUPTED = (1 << 0) /* 1 */,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
index 8c45044..e6ea642 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiChannelWidthInMhz {
- WIDTH_INVALID = -1,
+ WIDTH_INVALID = (-1) /* -1 */,
WIDTH_20 = 0,
WIDTH_40 = 1,
WIDTH_80 = 2,
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..b5034ea
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChipCapabilities {
+ int maxMloAssociationLinkCount;
+ int maxMloStrLinkCount;
+ int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
index ee26f2e..6db96ef 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiDebugPacketFateFrameType {
- UNKNOWN = 0,
- ETHERNET_II = 1,
- MGMT_80211 = 2,
+ UNKNOWN,
+ ETHERNET_II,
+ MGMT_80211,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
index f210e82..9ababc3 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiDebugRingBufferFlags {
- HAS_BINARY_ENTRIES = 1,
- HAS_ASCII_ENTRIES = 2,
- HAS_PER_PACKET_ENTRIES = 4,
+ HAS_BINARY_ENTRIES = (1 << 0) /* 1 */,
+ HAS_ASCII_ENTRIES = (1 << 1) /* 2 */,
+ HAS_PER_PACKET_ENTRIES = (1 << 2) /* 4 */,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
index 75abb4e..f638c4f 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
@@ -34,15 +34,15 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiDebugRxPacketFate {
- SUCCESS = 0,
- FW_QUEUED = 1,
- FW_DROP_FILTER = 2,
- FW_DROP_INVALID = 3,
- FW_DROP_NOBUFS = 4,
- FW_DROP_OTHER = 5,
- DRV_QUEUED = 6,
- DRV_DROP_FILTER = 7,
- DRV_DROP_INVALID = 8,
- DRV_DROP_NOBUFS = 9,
- DRV_DROP_OTHER = 10,
+ SUCCESS,
+ FW_QUEUED,
+ FW_DROP_FILTER,
+ FW_DROP_INVALID,
+ FW_DROP_NOBUFS,
+ FW_DROP_OTHER,
+ DRV_QUEUED,
+ DRV_DROP_FILTER,
+ DRV_DROP_INVALID,
+ DRV_DROP_NOBUFS,
+ DRV_DROP_OTHER,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
index e360c2c..778ca5d 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
@@ -34,14 +34,14 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiDebugTxPacketFate {
- ACKED = 0,
- SENT = 1,
- FW_QUEUED = 2,
- FW_DROP_INVALID = 3,
- FW_DROP_NOBUFS = 4,
- FW_DROP_OTHER = 5,
- DRV_QUEUED = 6,
- DRV_DROP_INVALID = 7,
- DRV_DROP_NOBUFS = 8,
- DRV_DROP_OTHER = 9,
+ ACKED,
+ SENT,
+ FW_QUEUED,
+ FW_DROP_INVALID,
+ FW_DROP_NOBUFS,
+ FW_DROP_OTHER,
+ DRV_QUEUED,
+ DRV_DROP_INVALID,
+ DRV_DROP_NOBUFS,
+ DRV_DROP_OTHER,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
index e2fe57a..557cef4 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
@@ -34,12 +34,12 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiIfaceMode {
- IFACE_MODE_STA = 1,
- IFACE_MODE_SOFTAP = 2,
- IFACE_MODE_IBSS = 4,
- IFACE_MODE_P2P_CLIENT = 8,
- IFACE_MODE_P2P_GO = 16,
- IFACE_MODE_NAN = 32,
- IFACE_MODE_MESH = 64,
- IFACE_MODE_TDLS = 128,
+ IFACE_MODE_STA = (1 << 0) /* 1 */,
+ IFACE_MODE_SOFTAP = (1 << 1) /* 2 */,
+ IFACE_MODE_IBSS = (1 << 2) /* 4 */,
+ IFACE_MODE_P2P_CLIENT = (1 << 3) /* 8 */,
+ IFACE_MODE_P2P_GO = (1 << 4) /* 16 */,
+ IFACE_MODE_NAN = (1 << 5) /* 32 */,
+ IFACE_MODE_MESH = (1 << 6) /* 64 */,
+ IFACE_MODE_TDLS = (1 << 7) /* 128 */,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
deleted file mode 100644
index ea86c4f..0000000
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.wifi;
-@VintfStability
-parcelable WifiRadioCombinationMatrix {
- android.hardware.wifi.WifiRadioCombination[] radioCombinations;
-}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
index f27661c..9a15fa1 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
@@ -34,14 +34,14 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum WifiStatusCode {
- SUCCESS = 0,
- ERROR_WIFI_CHIP_INVALID = 1,
- ERROR_WIFI_IFACE_INVALID = 2,
- ERROR_WIFI_RTT_CONTROLLER_INVALID = 3,
- ERROR_NOT_SUPPORTED = 4,
- ERROR_NOT_AVAILABLE = 5,
- ERROR_NOT_STARTED = 6,
- ERROR_INVALID_ARGS = 7,
- ERROR_BUSY = 8,
- ERROR_UNKNOWN = 9,
+ SUCCESS,
+ ERROR_WIFI_CHIP_INVALID,
+ ERROR_WIFI_IFACE_INVALID,
+ ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ ERROR_NOT_SUPPORTED,
+ ERROR_NOT_AVAILABLE,
+ ERROR_NOT_STARTED,
+ ERROR_INVALID_ARGS,
+ ERROR_BUSY,
+ ERROR_UNKNOWN,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
index 94e3a8a..774b242 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
@@ -36,5 +36,5 @@
parcelable WifiUsableChannel {
int channel;
android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
- android.hardware.wifi.WifiIfaceMode ifaceModeMask;
+ int ifaceModeMask;
}
diff --git a/wifi/aidl/android/hardware/wifi/AfcChannelAllowance.aidl b/wifi/aidl/android/hardware/wifi/AfcChannelAllowance.aidl
new file mode 100644
index 0000000..289383c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AfcChannelAllowance.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.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.AvailableAfcChannelInfo;
+import android.hardware.wifi.AvailableAfcFrequencyInfo;
+
+/**
+ * Defines the maximum permissible power spectral density to support 6Ghz with standard power for
+ * AFC. The maximum power can be either defined based on frequencies or channel number.
+ *
+ * Note, based on AFC server support, either availableAfcFrequencyInfos or availableAfcChannelInfos
+ * may be empty. If one of them is empty while the other is not, use the non-empty one and ignore
+ * the empty one. If both are empty then it means 6Ghz standard power should not be supported at
+ * all.
+ *
+ * If availableAfcFrequencyInfos is non-empty, set the max permissible power according to the maxPsd
+ * per frequency range, and disallow emmision on 6Ghz frequencies not included in the structure.
+ *
+ * If availableAfcChannelInfos is non-empty, set the max permissible power according to the
+ * maxEirpDbm per channel, and disallow emmision on 6Ghz channels not included in the structure.
+ */
+@VintfStability
+parcelable AfcChannelAllowance {
+ /**
+ * AFC max permissible information queried from AFC server based on frequency.
+ */
+ AvailableAfcFrequencyInfo[] availableAfcFrequencyInfos;
+ /**
+ * AFC max permissible information queried from AFC server on channel number.
+ */
+ AvailableAfcChannelInfo[] availableAfcChannelInfos;
+ /**
+ * The time in UTC at which this information expires, as the difference, measured in
+ * milliseconds between the expiration time and midnight, January 1, 1970 UTC.
+ */
+ long availabilityExpireTimeMs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/AvailableAfcChannelInfo.aidl b/wifi/aidl/android/hardware/wifi/AvailableAfcChannelInfo.aidl
new file mode 100644
index 0000000..398cd12
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AvailableAfcChannelInfo.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;
+
+/**
+ * Defines the maximum EIRP per channel for supporting 6Ghz standard power for AFC. The format of
+ * the data structure is derived from the Wi-Fi Alliance AFC System to AFC Device Interface
+ * Specification: AvailableChannelInfo object.
+ */
+@VintfStability
+parcelable AvailableAfcChannelInfo {
+ /**
+ * The global operating class used to define the channel center frequency indices
+ * and operating bandwidth.
+ */
+ int globalOperatingClass;
+
+ /**
+ * The channel center frequency index.
+ */
+ int channelCfi;
+
+ /**
+ * The maximum permissible EIRP in units of dBm available for the channel
+ * specified by channelCfi. In addition, in any portion of the channel, the conducted PSD plus
+ * the maximum antenna gain cannot exceed the maxEirp divided by the channel width defined by
+ * the globalOperatingClass.
+ */
+ int maxEirpDbm;
+}
diff --git a/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl b/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.aidl
new file mode 100644
index 0000000..5de360c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/AvailableAfcFrequencyInfo.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.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Defines the maximum permissible power spectral density on a range of
+ * frequencies to support 6Ghz with standard power for AFC.
+ * The format of the data follows spec from the Wi-Fi Alliance AFC System to
+ * AFC Device Interface Specification: AvailableFrequencyInfo object.
+ */
+@VintfStability
+parcelable AvailableAfcFrequencyInfo {
+ /**
+ * Defines the lowest frequency included in this 6Ghz frequency range.
+ */
+ int startFrequencyMhz;
+ /**
+ * Defines the highest frequency included in this 6Ghz frequency range.
+ */
+ int endFrequencyMhz;
+ /**
+ * The maximum permissible EIRP available in any one MHz bin within the
+ * frequency range specified. The limit is expressed as a power spectral
+ * density with units of dBm per MHz.
+ */
+ int maxPsd;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
index 71ea385..b14a800 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
@@ -68,20 +68,6 @@
void setCountryCode(in byte[2] code);
/**
- * Used to query the list of valid frequencies (depending on country code set)
- * for the provided band.
- *
- * @param band Band for which the frequency list is being generated.
- * @return Vector of valid frequencies for the provided band.
- * @throws ServiceSpecificException with one of the following values:
- * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
- * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
- * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
- * |WifiStatusCode.ERROR_UNKNOWN|
- */
- int[] getValidFrequenciesForBand(in WifiBand band);
-
- /**
* Reset all of the AP interfaces' MAC address to the factory MAC address.
*
* @throws ServiceSpecificException with one of the following values:
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index fe9a6f3..c1caa7e 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi;
+import android.hardware.wifi.AfcChannelAllowance;
import android.hardware.wifi.IWifiApIface;
import android.hardware.wifi.IWifiChipEventCallback;
import android.hardware.wifi.IWifiNanIface;
@@ -25,11 +26,12 @@
import android.hardware.wifi.IfaceConcurrencyType;
import android.hardware.wifi.IfaceType;
import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiChipCapabilities;
import android.hardware.wifi.WifiDebugHostWakeReasonStats;
import android.hardware.wifi.WifiDebugRingBufferStatus;
import android.hardware.wifi.WifiDebugRingBufferVerboseLevel;
import android.hardware.wifi.WifiIfaceMode;
-import android.hardware.wifi.WifiRadioCombinationMatrix;
+import android.hardware.wifi.WifiRadioCombination;
import android.hardware.wifi.WifiUsableChannel;
/**
@@ -42,68 +44,44 @@
*/
@VintfStability
@Backing(type="int")
- enum ChipCapabilityMask {
- /**
- * Memory dump of Firmware.
- */
- DEBUG_MEMORY_FIRMWARE_DUMP = 1 << 0,
- /**
- * Memory dump of Driver.
- */
- DEBUG_MEMORY_DRIVER_DUMP = 1 << 1,
- /**
- * Connectivity events reported via debug ring buffer.
- */
- DEBUG_RING_BUFFER_CONNECT_EVENT = 1 << 2,
- /**
- * Power events reported via debug ring buffer.
- */
- DEBUG_RING_BUFFER_POWER_EVENT = 1 << 3,
- /**
- * Wakelock events reported via debug ring buffer.
- */
- DEBUG_RING_BUFFER_WAKELOCK_EVENT = 1 << 4,
- /**
- * Vendor data reported via debug ring buffer.
- * This mostly contains firmware event logs.
- */
- DEBUG_RING_BUFFER_VENDOR_DATA = 1 << 5,
- /**
- * Host wake reasons stats collection.
- */
- DEBUG_HOST_WAKE_REASON_STATS = 1 << 6,
- /**
- * Error alerts.
- */
- DEBUG_ERROR_ALERTS = 1 << 7,
+ enum FeatureSetMask {
/**
* Set/Reset Tx Power limits.
*/
- SET_TX_POWER_LIMIT = 1 << 8,
+ SET_TX_POWER_LIMIT = 1 << 0,
/**
* Device to Device RTT.
*/
- D2D_RTT = 1 << 9,
+ D2D_RTT = 1 << 1,
/**
* Device to AP RTT.
*/
- D2AP_RTT = 1 << 10,
+ D2AP_RTT = 1 << 2,
/**
* Set/Reset Tx Power limits.
*/
- USE_BODY_HEAD_SAR = 1 << 11,
+ USE_BODY_HEAD_SAR = 1 << 3,
/**
* Set Latency Mode.
*/
- SET_LATENCY_MODE = 1 << 12,
+ SET_LATENCY_MODE = 1 << 4,
/**
* Support P2P MAC randomization.
*/
- P2P_RAND_MAC = 1 << 13,
+ P2P_RAND_MAC = 1 << 5,
/**
* Chip can operate in the 60GHz band (WiGig chip).
*/
- WIGIG = 1 << 14,
+ WIGIG = 1 << 6,
+ /**
+ * Chip supports setting allowed channels along with PSD in 6GHz band
+ * for AFC purposes.
+ */
+ SET_AFC_CHANNEL_ALLOWANCE = 1 << 7,
+ /**
+ * Chip supports Tid-To-Link mapping negotiation.
+ */
+ T2LM_NEGOTIATION = 1 << 8,
}
/**
@@ -533,7 +511,6 @@
* API to enable/disable alert notifications from the chip.
* These alerts must be used to notify the framework of any fatal error events
* that the chip encounters via |IWifiChipEventCallback.onDebugErrorAlert| method.
- * Must fail if |ChipCapabilityMask.DEBUG_ERROR_ALERTS| is not set.
*
* @param enable true to enable, false to disable.
* @throws ServiceSpecificException with one of the following values:
@@ -605,15 +582,15 @@
ChipMode[] getAvailableModes();
/**
- * Get the capabilities supported by this chip.
+ * Get the features supported by this chip.
*
- * @return Bitset of |ChipCapabilityMask| values.
+ * @return Bitset of |FeatureSetMask| values.
* @throws ServiceSpecificException with one of the following values:
* |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
* |WifiStatusCode.ERROR_NOT_AVAILABLE|,
* |WifiStatusCode.ERROR_UNKNOWN|
*/
- ChipCapabilityMask getCapabilities();
+ int getFeatureSet();
/**
* API to retrieve the wifi wake up reason stats for debugging.
@@ -760,8 +737,7 @@
* Retrieve the list of all the possible radio combinations supported by this
* chip.
*
- * @return A list of all the possible radio combinations represented by
- * |WifiRadioCombinationMatrix|.
+ * @return A list of all the possible radio combinations.
* For example, in case of a chip which has two radios, where one radio is
* capable of 2.4GHz 2X2 only and another radio which is capable of either
* 5GHz or 6GHz 2X2, the number of possible radio combinations in this case
@@ -782,7 +758,19 @@
* |WifiStatusCode.FAILURE_UNKNOWN|
*
*/
- WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+ WifiRadioCombination[] getSupportedRadioCombinations();
+
+ /**
+ * Get capabilities supported by this chip.
+ *
+ * @return Chip capabilities represented by |WifiChipCapabilities|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.FAILURE_UNKNOWN|
+ *
+ */
+ WifiChipCapabilities getWifiChipCapabilities();
/**
* Retrieve a list of usable Wifi channels for the specified band &
@@ -820,7 +808,15 @@
* |WifiStatusCode.FAILURE_UNKNOWN|
*/
WifiUsableChannel[] getUsableChannels(
- in WifiBand band, in WifiIfaceMode ifaceModeMask, in UsableChannelFilter filterMask);
+ in WifiBand band, in int ifaceModeMask, in int filterMask);
+
+ /*
+ * Set the max power level the chip is allowed to transmit on for 6Ghz AFC.
+ * @param afcChannelAllowance Specifies the power limitations for 6Ghz AFC.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|
+ */
+ void setAfcChannelAllowance(in AfcChannelAllowance afcChannelAllowance);
/**
* Requests notifications of significant events on this chip. Multiple calls
@@ -982,8 +978,7 @@
* |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
* |WifiStatusCode.ERROR_INVALID_ARGS|,
*/
- void setCoexUnsafeChannels(
- in CoexUnsafeChannel[] unsafeChannels, in CoexRestriction restrictions);
+ void setCoexUnsafeChannels(in CoexUnsafeChannel[] unsafeChannels, in int restrictions);
/**
* Set country code for this Wifi chip.
@@ -1093,4 +1088,65 @@
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void triggerSubsystemRestart();
+
+ /**
+ * Channel category mask.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum ChannelCategoryMask {
+ INDOOR_CHANNEL = 1 << 0,
+ DFS_CHANNEL = 1 << 1,
+ }
+
+ /**
+ * API to enable or disable the feature of allowing current STA-connected channel for WFA GO,
+ * SAP and Aware when the regulatory allows.
+ * If the channel category is enabled and allowed by the regulatory, the HAL method
+ * getUsableChannels() will contain the current STA-connected channel if that channel belongs
+ * to that category.
+ * @param channelCategoryEnableFlag Bitmask of |ChannelCategoryMask| values.
+ * For each bit, 1 enables the channel category and 0 disables that channel category.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.FAILURE_UNKNOWN|
+ */
+ void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
+
+ /**
+ * Multi-Link Operation modes.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum ChipMloMode {
+ /**
+ * Default mode for Multi-Link Operation.
+ */
+ DEFAULT = 0,
+ /**
+ * Low latency mode for Multi-link operation.
+ */
+ LOW_LATENCY = 1,
+ /**
+ * High throughput mode for Multi-link operation.
+ */
+ HIGH_THROUGHPUT = 2,
+ /**
+ * Low power mode for Multi-link operation.
+ */
+ LOW_POWER = 3,
+ }
+
+ /**
+ * Set mode for Multi-Link Operation. Various modes are defined by the enum |ChipMloMode|.
+ *
+ * @param mode MLO mode as defined by the enum |ChipMloMode|
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ *
+ */
+ void setMloMode(in ChipMloMode mode);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
index 45644b4..3ce8d02 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
@@ -17,12 +17,16 @@
package android.hardware.wifi;
import android.hardware.wifi.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.NanBootstrappingRequest;
+import android.hardware.wifi.NanBootstrappingResponse;
import android.hardware.wifi.NanConfigRequest;
import android.hardware.wifi.NanConfigRequestSupplemental;
import android.hardware.wifi.NanEnableRequest;
import android.hardware.wifi.NanInitiateDataPathRequest;
+import android.hardware.wifi.NanPairingRequest;
import android.hardware.wifi.NanPublishRequest;
import android.hardware.wifi.NanRespondToDataPathIndicationRequest;
+import android.hardware.wifi.NanRespondToPairingIndicationRequest;
import android.hardware.wifi.NanSubscribeRequest;
import android.hardware.wifi.NanTransmitFollowupRequest;
@@ -75,6 +79,7 @@
* Asynchronous response is with |IWifiNanIfaceEventCallback.notifyCreateDataInterfaceResponse|.
*
* @param cmdId Command Id to use for this invocation.
+ * @param ifaceName The name of the interface, e.g. "aware0".
* @throws ServiceSpecificException with one of the following values:
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
* |WifiStatusCode.ERROR_UNKNOWN|
@@ -86,6 +91,7 @@
* Asynchronous response is with |IWifiNanIfaceEventCallback.notifyDeleteDataInterfaceResponse|.
*
* @param cmdId Command Id to use for this invocation.
+ * @param ifaceName The name of the interface, e.g. "aware0".
* @throws ServiceSpecificException with one of the following values:
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
* |WifiStatusCode.ERROR_UNKNOWN|
@@ -237,6 +243,32 @@
void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
/**
+ * Start the suspension of a discovery service.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifySuspendResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param sessionId ID of the publish/subscribe discovery session to be suspended.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void suspendRequest(in char cmdId, in byte sessionId);
+
+ /**
+ * Stop the suspension of a discovery service.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyResumeResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param sessionId ID of the publish/subscribe discovery session to be resumed.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void resumeRequest(in char cmdId, in byte sessionId);
+
+ /**
* NAN transmit follow up message request.
* Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTransmitFollowupResponse|.
*
@@ -248,4 +280,74 @@
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void transmitFollowupRequest(in char cmdId, in NanTransmitFollowupRequest msg);
+
+ /**
+ * Initiate a NAN pairing operation: Initiator.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyInitiatePairingResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param msg Instance of |NanPairingRequest|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void initiatePairingRequest(in char cmdId, in NanPairingRequest msg);
+
+ /**
+ * Respond to a received request indication of NAN pairing setup operation.
+ * An indication is received by the Responder from the Initiator.
+ * Asynchronous response is with
+ * |IWifiNanIfaceEventCallback.notifyRespondToPairingIndicationResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param msg Instance of |NanRespondToPairingIndicationRequest|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void respondToPairingIndicationRequest(
+ in char cmdId, in NanRespondToPairingIndicationRequest msg);
+
+ /**
+ * Initiate a NAN pairing bootstrapping operation: Initiator.
+ * Asynchronous response is with
+ * |IWifiNanIfaceEventCallback.notifyInitiateBootstrappingResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param msg Instance of |NanBootstrappingRequest|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void initiateBootstrappingRequest(in char cmdId, in NanBootstrappingRequest msg);
+
+ /**
+ * Respond to a received request indication of NAN pairing bootstrapping operation.
+ * An indication is received by the Responder from the Initiator.
+ * Asynchronous response is with
+ * |IWifiNanIfaceEventCallback.notifyRespondToPairingIndicationResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param msg Instance of |notifyRespondToBootstrappingIndicationResponse|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void respondToBootstrappingIndicationRequest(in char cmdId, in NanBootstrappingResponse msg);
+
+ /**
+ * Aware pairing termination request. Executed by either the Initiator or Responder.
+ * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTerminatePairingResponse|.
+ *
+ * @param cmdId Command Id to use for this invocation.
+ * @param pairingInstanceId Pairing instance ID to be terminated.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void terminatePairingRequest(in char cmdId, in int pairingInstanceId);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
index 470b7ba..3649b7b 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -16,6 +16,8 @@
package android.hardware.wifi;
+import android.hardware.wifi.NanBootstrappingConfirmInd;
+import android.hardware.wifi.NanBootstrappingRequestInd;
import android.hardware.wifi.NanCapabilities;
import android.hardware.wifi.NanClusterEventInd;
import android.hardware.wifi.NanDataPathConfirmInd;
@@ -23,8 +25,10 @@
import android.hardware.wifi.NanDataPathScheduleUpdateInd;
import android.hardware.wifi.NanFollowupReceivedInd;
import android.hardware.wifi.NanMatchInd;
+import android.hardware.wifi.NanPairingConfirmInd;
+import android.hardware.wifi.NanPairingRequestInd;
import android.hardware.wifi.NanStatus;
-
+import android.hardware.wifi.NanSuspensionModeChangeInd;
/**
* NAN Response and Asynchronous Event Callbacks.
*
@@ -128,7 +132,7 @@
/**
* Callback providing status on a completed followup message transmit operation.
*
- * @param cmdId Command Id corresponding to the original |transmitFollowupRequest| request.
+ * @param id Command ID corresponding to the original |transmitFollowupRequest| request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.NO_OTA_ACK|
@@ -137,10 +141,17 @@
void eventTransmitFollowup(in char id, in NanStatus status);
/**
+ * Callback indicating that device suspension mode status change
+ *
+ * @param event NanSuspensionModeChangeInd containing event details.
+ */
+ void eventSuspensionModeChanged(in NanSuspensionModeChangeInd event);
+
+ /**
* Callback invoked in response to a capability request
* |IWifiNanIface.getCapabilitiesRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* @param capabilities Capability data.
@@ -151,7 +162,7 @@
/**
* Callback invoked in response to a config request |IWifiNanIface.configRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -164,7 +175,7 @@
* Callback invoked in response to a create data interface request
* |IWifiNanIface.createDataInterfaceRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -176,7 +187,7 @@
* Callback invoked in response to a delete data interface request
* |IWifiNanIface.deleteDataInterfaceRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -187,7 +198,7 @@
/**
* Callback invoked in response to a disable request |IWifiNanIface.disableRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.PROTOCOL_FAILURE|
@@ -197,7 +208,7 @@
/**
* Callback invoked in response to an enable request |IWifiNanIface.enableRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.ALREADY_ENABLED|
@@ -212,7 +223,7 @@
* Callback invoked in response to an initiate data path request
* |IWifiNanIface.initiateDataPathRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -227,7 +238,7 @@
* Callback invoked in response to a respond to data path indication request
* |IWifiNanIface.respondToDataPathIndicationRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -241,7 +252,7 @@
* Callback invoked to notify the status of the start publish request
* |IWifiNanIface.startPublishRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -256,7 +267,7 @@
* Callback invoked to notify the status of the start subscribe request
* |IWifiNanIface.startSubscribeRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -271,7 +282,7 @@
* Callback invoked in response to a stop publish request
* |IWifiNanIface.stopPublishRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_SESSION_ID|
@@ -283,7 +294,7 @@
* Callback invoked in response to a stop subscribe request
* |IWifiNanIface.stopSubscribeRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_SESSION_ID|
@@ -295,7 +306,7 @@
* Callback invoked in response to a terminate data path request
* |IWifiNanIface.terminateDataPathRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -306,10 +317,36 @@
void notifyTerminateDataPathResponse(in char id, in NanStatus status);
/**
+ * Callback invoked in response to a suspension request
+ * |IWifiNanIface.suspendRequest|.
+ *
+ * @param id Command ID corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_SESSION_ID|
+ * |NanStatusCode.INVALID_STATE|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ */
+ void notifySuspendResponse(in char id, in NanStatus status);
+
+ /**
+ * Callback invoked in response to a resume request
+ * |IWifiNanIface.resumeRequest|.
+ *
+ * @param id Command ID corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_SESSION_ID|
+ * |NanStatusCode.INVALID_STATE|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ */
+ void notifyResumeResponse(in char id, in NanStatus status);
+
+ /**
* Callback invoked in response to a transmit followup request
* |IWifiNanIface.transmitFollowupRequest|.
*
- * @param cmdId Command Id corresponding to the original request.
+ * @param id Command ID corresponding to the original request.
* @param status NanStatus of the operation. Possible status codes are:
* |NanStatusCode.SUCCESS|
* |NanStatusCode.INVALID_ARGS|
@@ -319,4 +356,109 @@
* |NanStatusCode.FOLLOWUP_TX_QUEUE_FULL|
*/
void notifyTransmitFollowupResponse(in char id, in NanStatus status);
+
+ /**
+ * Callback indicating that a NAN pairing setup/verification has been requested by
+ * an Initiator peer (received by the intended Responder).
+ *
+ * @param event NanPairingRequestInd containing event details.
+ */
+ void eventPairingRequest(in NanPairingRequestInd event);
+
+ /**
+ * Callback indicating that a NAN pairing setup/verification has been completed.
+ * Received by both Initiator and Responder.
+ *
+ * @param event NanPairingConfirmInd containing event details.
+ */
+ void eventPairingConfirm(in NanPairingConfirmInd event);
+
+ /**
+ * Callback invoked in response to an initiate NAN pairing request
+ * |IWifiNanIface.initiatePairingRequest|.
+ *
+ * @param id Command ID corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_ARGS|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ * |NanStatusCode.PROTOCOL_FAILURE|
+ * |NanStatusCode.INVALID_PEER_ID|
+ * @param pairingInstanceId ID of the new pairing being negotiated (on successful status).
+ */
+ void notifyInitiatePairingResponse(in char id, in NanStatus status, in int pairingInstanceId);
+
+ /**
+ * Callback invoked in response to a respond to NAN pairing indication request
+ * |IWifiNanIface.respondToPairingIndicationRequest|.
+ *
+ * @param id Command ID corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_ARGS|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ * |NanStatusCode.PROTOCOL_FAILURE|
+ * |NanStatusCode.INVALID_NDP_ID|
+ */
+ void notifyRespondToPairingIndicationResponse(in char id, in NanStatus status);
+
+ /**
+ * Callback indicating that a NAN bootstrapping setup has been requested by
+ * an Initiator peer (received by the intended Responder).
+ *
+ * @param event NanBootstrappingRequestInd containing event details.
+ */
+ void eventBootstrappingRequest(in NanBootstrappingRequestInd event);
+
+ /**
+ * Callback indicating that a NAN bootstrapping setuphas been completed.
+ * Received by Initiator.
+ *
+ * @param event NanBootstrappingConfirmInd containing event details.
+ */
+ void eventBootstrappingConfirm(in NanBootstrappingConfirmInd event);
+
+ /**
+ * Callback invoked in response to an initiate NAN pairing bootstrapping request
+ * |IWifiNanIface.initiateBootstrappingRequest|.
+ *
+ * @param id Command ID corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_ARGS|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ * |NanStatusCode.PROTOCOL_FAILURE|
+ * |NanStatusCode.INVALID_PEER_ID|
+ * @param bootstrappingInstanceId ID of the new pairing being negotiated (on successful status).
+ */
+ void notifyInitiateBootstrappingResponse(
+ in char id, in NanStatus status, in int bootstrappingInstanceId);
+
+ /**
+ * Callback invoked in response to a respond to pairing bootstrapping indication request
+ * |IWifiNanIface.respondToBootstrappingIndicationRequest|.
+ *
+ * @param id Command ID corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_ARGS|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ * |NanStatusCode.PROTOCOL_FAILURE|
+ * |NanStatusCode.INVALID_NDP_ID|
+ */
+ void notifyRespondToBootstrappingIndicationResponse(in char id, in NanStatus status);
+
+ /**
+ * Callback invoked in response to a terminate pairing request
+ * |IWifiNanIface.terminatePairingRequest|.
+ *
+ * @param id Command Id corresponding to the original request.
+ * @param status NanStatus of the operation. Possible status codes are:
+ * |NanStatusCode.SUCCESS|
+ * |NanStatusCode.INVALID_ARGS|
+ * |NanStatusCode.INTERNAL_FAILURE|
+ * |NanStatusCode.PROTOCOL_FAILURE|
+ * |NanStatusCode.INVALID_PAIRING_ID|
+ */
+ void notifyTerminatePairingResponse(in char id, in NanStatus status);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
index 2dd57b2..2c81984 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -38,7 +38,7 @@
*/
@VintfStability
@Backing(type="int")
- enum StaIfaceCapabilityMask {
+ enum FeatureSetMask {
/**
* Support for APF APIs. APF (Android Packet Filter) is a
* BPF-like packet filtering bytecode executed by the firmware.
@@ -99,10 +99,6 @@
* Support for keep alive packet offload.
*/
KEEP_ALIVE = 1 << 13,
- /**
- * Support for tracking connection packets' fate.
- */
- DEBUG_PACKET_FATE = 1 << 14,
}
/**
@@ -194,15 +190,15 @@
StaBackgroundScanCapabilities getBackgroundScanCapabilities();
/**
- * Get the capabilities supported by this STA iface.
+ * Get the features supported by this STA iface.
*
- * @return Bitset of |StaIfaceCapabilityMask| values.
+ * @return Bitset of |FeatureSetMask| values.
* @throws ServiceSpecificException with one of the following values:
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
* |WifiStatusCode.ERROR_NOT_AVAILABLE|,
* |WifiStatusCode.ERROR_UNKNOWN|
*/
- StaIfaceCapabilityMask getCapabilities();
+ int getFeatureSet();
/**
* API to retrieve the fates of inbound packets.
@@ -292,22 +288,6 @@
StaRoamingCapabilities getRoamingCapabilities();
/**
- * Used to query the list of valid frequencies (depending on the country
- * code set) for the provided band. These channels may be specified in the
- * |BackgroundScanBucketParameters.frequenciesInMhz| for a background scan
- * request.
- *
- * @param band Band for which the frequency list is being generated.
- * @return Vector of valid frequencies for the provided band.
- * @throws ServiceSpecificException with one of the following values:
- * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
- * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
- * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
- * |WifiStatusCode.ERROR_UNKNOWN|
- */
- int[] getValidFrequenciesForBand(in WifiBand band);
-
- /**
* Installs an APF program on this iface, replacing an existing
* program if present.
* Must fail if |StaIfaceCapabilityMask.APF| is not set.
@@ -552,4 +532,20 @@
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void stopSendingKeepAlivePackets(in int cmdId);
+
+ /**
+ * Set DTIM multiplier used when the system is in the suspended mode.
+ * When STA is in the power saving mode and system is suspended,
+ * the wake up interval will be set to:
+ * 1) multiplier * DTIM period if multiplier > 0.
+ * 2) the driver default value if multiplier <= 0.
+ * Some implementations may apply an additional cap to wake up interval in the case of 1).
+ *
+ * @param multiplier integer DTIM multiplier value to set.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void setDtimMultiplier(in int multiplier);
}
diff --git a/wifi/aidl/android/hardware/wifi/MacAddress.aidl b/wifi/aidl/android/hardware/wifi/MacAddress.aidl
index d59dfe3..d238565 100644
--- a/wifi/aidl/android/hardware/wifi/MacAddress.aidl
+++ b/wifi/aidl/android/hardware/wifi/MacAddress.aidl
@@ -20,8 +20,6 @@
* Byte array representing a Mac Address. Use when we need to
* pass an array of Mac Addresses to a method, as variable-sized
* 2D arrays are not supported in AIDL.
- *
- * TODO (b/210705533): Replace this type with a 2D byte array.
*/
@VintfStability
parcelable MacAddress {
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
new file mode 100644
index 0000000..e72c940
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingConfirmInd.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingResponseCode;
+import android.hardware.wifi.NanStatus;
+
+/**
+ * See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingConfirmInd {
+ /**
+ * Id of the bootstrapping session. Obtained as part of earlier
+ |IWifiNanIface.initiateBootstrappingRequest| success notification.
+ */
+ int bootstrappingInstanceId;
+
+ /**
+ * Indicate whether the bootstrapping method negotiation accept or not
+ */
+ NanBootstrappingResponseCode responseCode;
+
+ /**
+ * Failure reason if |acceptRequest| is false.
+ */
+ NanStatus reasonCode;
+
+ /**
+ * The delay of bootstrapping in seconds for the follow up request.
+ */
+ int comeBackDelay;
+
+ /**
+ * Cookie received from peer with |comeBackDelay| for follow up |NanBootstrappingRequest|
+ */
+ byte[] cookie;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingMethod.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingMethod.aidl
new file mode 100644
index 0000000..da2ff25
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingMethod.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Pairing bootstrapping method flag.
+ * See Wi-Fi Aware R4.0 section 9.5.21.7 table 128
+ */
+@VintfStability
+@Backing(type="int")
+enum NanBootstrappingMethod {
+ BOOTSTRAPPING_OPPORTUNISTIC_MASK = 1 << 0,
+ BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK = 1 << 1,
+ BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK = 1 << 2,
+ BOOTSTRAPPING_QR_DISPLAY_MASK = 1 << 3,
+ BOOTSTRAPPING_NFC_TAG_MASK = 1 << 4,
+ BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK = 1 << 5,
+ BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK = 1 << 6,
+ BOOTSTRAPPING_QR_SCAN_MASK = 1 << 7,
+ BOOTSTRAPPING_NFC_READER_MASK = 1 << 8,
+ BOOTSTRAPPING_SERVICE_MANAGED_MASK = 1 << 14,
+ BOOTSTRAPPING_HANDSHAKE_SHIP_MASK = 1 << 15
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
new file mode 100644
index 0000000..4b74cd9
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingMethod;
+
+/**
+ * See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingRequest {
+ /**
+ * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+ * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+ */
+ int peerId;
+
+ /**
+ * NAN management interface MAC address of the peer. Obtained as part of an earlier
+ * |IWifiNanIfaceEventCallback.eventMatch| or
+ * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+ */
+ byte[6] peerDiscMacAddr;
+
+ /**
+ * One of |NanBootstrappingMethod| indicating the bootstrapping method in the request.
+ */
+ NanBootstrappingMethod requestBootstrappingMethod;
+
+ /**
+ * Cookie received from previous |NanBootstrappingConfirmInd| for comeback request.
+ */
+ byte[] cookie;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequestInd.aidl
new file mode 100644
index 0000000..6f43892
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequestInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanBootstrappingMethod;
+
+/**
+ * NAN Data path request indication message structure.
+ * Event indication received by an intended Responder when a NAN
+ * data request is initiated by an Initiator. See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingRequestInd {
+ /**
+ * Discovery session (publish or subscribe) ID of a previously created discovery session. The
+ * bootstrapping request is received in the context of this discovery session.
+ * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+ */
+ byte discoverySessionId;
+ /**
+ * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+ * or to set up a data-path.
+ */
+ int peerId;
+ /**
+ * MAC address of the Initiator peer. This is the MAC address of the peer's
+ * management/discovery NAN interface.
+ */
+ byte[6] peerDiscMacAddr;
+
+ /**
+ * ID of bootstrapping session. Used to identify the bootstrapping further negotiation/APIs.
+ */
+ int bootstrappingInstanceId;
+
+ /**
+ * One of |NanBootstrappingMethod| indicating the bootstrapping method in the incoming request.
+ */
+ NanBootstrappingMethod requestBootstrappingMethod;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
new file mode 100644
index 0000000..dbe8923
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * See Wi-Fi Aware R4.0 section 9.5.21.7
+ */
+@VintfStability
+parcelable NanBootstrappingResponse {
+ /**
+ * ID of bootstrapping session. Used to identify the bootstrapping further negotiation/APIs.
+ */
+ int bootstrappingInstanceId;
+ /**
+ * True if accept the request, false otherwise.
+ */
+ boolean acceptRequest;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponseCode.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponseCode.aidl
new file mode 100644
index 0000000..17076bf
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponseCode.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+/**
+ * Response code from peer NAN Bootstrapping request
+ */
+@VintfStability
+@Backing(type="int")
+enum NanBootstrappingResponseCode {
+ NAN_BOOTSTRAPPING_REQUEST_ACCEPT = 0,
+ NAN_BOOTSTRAPPING_REQUEST_REJECT,
+ NAN_BOOTSTRAPPING_REQUEST_COMEBACK,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
index 6042a05..f581c5e 100644
--- a/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
@@ -16,8 +16,6 @@
package android.hardware.wifi;
-import android.hardware.wifi.NanCipherSuiteType;
-
/**
* NDP Capabilities response.
*/
@@ -78,11 +76,31 @@
*/
int maxSubscribeInterfaceAddresses;
/**
- * The set of supported Cipher suites. The |NanCipherSuiteType| bit fields are used.
+ * Bitmap of |NanCipherSuiteType| values indicating the set of supported cipher suites.
*/
- NanCipherSuiteType supportedCipherSuites;
+ int supportedCipherSuites;
/**
- * Flag to indicate id instant communication mode is supported.
+ * Flag to indicate if instant communication mode is supported.
*/
boolean instantCommunicationModeSupportFlag;
+ /**
+ * Flag to indicate if 6 GHz is supported.
+ */
+ boolean supports6g;
+ /**
+ * Flag to indicate if High Efficiency is supported.
+ */
+ boolean supportsHe;
+ /**
+ * Flag to indicate if NAN pairing is supported.
+ */
+ boolean supportsPairing;
+ /**
+ * Flag to indicate if setting NAN cluster ID is supported.
+ */
+ boolean supportsSetClusterId;
+ /**
+ * Flag to indicate if NAN suspension is supported.
+ */
+ boolean supportsSuspension;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
index 9e3d684..91b5caf 100644
--- a/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -17,20 +17,38 @@
package android.hardware.wifi;
/**
- * Cipher suite flags.
+ * Cipher suite flags. Wi-Fi Aware Specification 4.0 section 9.5.21.1.
*/
@VintfStability
@Backing(type="int")
enum NanCipherSuiteType {
NONE = 0,
+ /**
+ * NCS-SK-128
+ */
SHARED_KEY_128_MASK = 1 << 0,
+ /**
+ * NCS-SK-256
+ */
SHARED_KEY_256_MASK = 1 << 1,
/**
- * NCS-PK-128
+ * NCS-PK-2WDH-128
*/
- PUBLIC_KEY_128_MASK = 1 << 2,
+ PUBLIC_KEY_2WDH_128_MASK = 1 << 2,
/**
- * NCS-PK-256
+ * NCS-PK-2WDH-256
*/
- PUBLIC_KEY_256_MASK = 1 << 3,
+ PUBLIC_KEY_2WDH_256_MASK = 1 << 3,
+ /**
+ * bit 4 and bit 5 are reserved for NCS-GTK-CCMP-128 and NCS-GTK-CCMP-256. Which are not used
+ * from framework
+ */
+ /**
+ * NCS-PK-PASN-128
+ */
+ PUBLIC_KEY_PASN_128_MASK = 1 << 6,
+ /**
+ * NCS-PK-PASN-256
+ */
+ PUBLIC_KEY_PASN_256_MASK = 1 << 7,
}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
index eb01a9f..338a549 100644
--- a/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -60,4 +60,8 @@
* Controls which channel NAN instant communication mode operates on.
*/
int instantModeChannel;
+ /**
+ * Controls which cluster to join.
+ */
+ int clusterId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
index 42a5616..9a2013b 100644
--- a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -31,7 +31,8 @@
*/
NanDataPathSecurityType securityType;
/**
- * Cipher type for data-paths. If |securityType| is |NanDataPathSecurityType.OPEN| then must
+ * One of |NanCipherSuiteType| indicating the cipher type for data-paths.
+ * If |securityType| is |NanDataPathSecurityType.OPEN|, then this must
* be set to |NanCipherSuiteType.NONE|. Otherwise a non-|NanCipherSuiteType.NONE| cipher suite
* must be specified.
*/
diff --git a/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
index ca1e016..58777c5 100644
--- a/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -18,7 +18,6 @@
import android.hardware.wifi.NanDataPathSecurityConfig;
import android.hardware.wifi.NanMatchAlg;
-import android.hardware.wifi.NanRangingIndication;
/**
* Configurations of NAN discovery sessions. Common to publish and subscribe discovery.
@@ -143,10 +142,11 @@
*/
int rangingIntervalMs;
/**
- * The type of ranging feedback to be provided by discovery session matches
- * |IWifiNanIfaceEventCallback.eventMatch|. Only relevant if |rangingRequired| is true.
+ * Bitmap of |NanRangingIndication| values indicating the type of ranging feedback
+ * to be provided by discovery session matches in |IWifiNanIfaceEventCallback.eventMatch|.
+ * Only relevant if |rangingRequired| is true.
*/
- NanRangingIndication configRangingIndications;
+ int configRangingIndications;
/**
* The ingress and egress distance in cm. If ranging is enabled (|rangingEnabled| is true) then
* |configRangingIndications| is used to determine whether ingress and/or egress (or neither)
@@ -155,4 +155,10 @@
*/
char distanceIngressCm;
char distanceEgressCm;
+ /**
+ * Specifies whether suspension can be possible in this discovery session.
+ * The request would fail if |enableSessionSuspendability| is true but
+ * |NanCapabilities.supportsSuspension| is false.
+ */
+ boolean enableSessionSuspendability;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanIdentityResolutionAttribute.aidl b/wifi/aidl/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
new file mode 100644
index 0000000..807081b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanIdentityResolutionAttribute.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NIRA for pairing identity resolution.
+ * See Wi-Fi Aware R4.0 section 9.5.21.6
+ */
+@VintfStability
+parcelable NanIdentityResolutionAttribute {
+ /**
+ * A random byte string to generate tag
+ */
+ byte[8] nonce;
+
+ /**
+ * A resolvable identity to identify Nan identity key
+ */
+ byte[8] tag;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
index 264a873..2f25329 100644
--- a/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -69,4 +69,9 @@
* NAN Spec: Appendix: Mapping pass-phrase to PMK for NCS-SK Cipher Suites
*/
byte[] serviceNameOutOfBand;
+ /**
+ * ID of an active publish or subscribe discovery session.
+ * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
index 896cde0..5a04376 100644
--- a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
@@ -17,7 +17,8 @@
package android.hardware.wifi;
import android.hardware.wifi.NanCipherSuiteType;
-import android.hardware.wifi.NanRangingIndication;
+import android.hardware.wifi.NanIdentityResolutionAttribute;
+import android.hardware.wifi.NanPairingConfig;
/**
* Match indication structure.
@@ -79,8 +80,9 @@
*/
byte rssiValue;
/**
- * Cipher type for data-paths constructed in the context of this discovery session. Valid if
- * |peerRequiresSecurityEnabledInNdp| is true.
+ * One of |NanCipherSuiteType| indicating the cipher type for data-paths constructed
+ * in the context of this discovery session.
+ * Valid if |peerRequiresSecurityEnabledInNdp| is true.
*/
NanCipherSuiteType peerCipherType;
/**
@@ -115,15 +117,24 @@
*/
int rangingMeasurementInMm;
/**
- * The ranging event(s) which triggered the ranging. e.g. can indicate that continuous ranging
- * was requested, or else that an ingress event occurred.
+ * Bitmap of |NanRangingIndication| values indicating the ranging event(s) which triggered the
+ * ranging. e.g. can indicate that continuous ranging was requested, or else that an ingress
+ * event occurred.
*/
- NanRangingIndication rangingIndicationType;
+ int rangingIndicationType;
/**
* Security Context Identifier attribute contains PMKID. Shall be included in NDP setup and
- * response messages. Security Context Identifie identifies the Security Context. For NAN
+ * response messages. Security Context Identifier identifies the Security Context. For NAN
* Shared Key Cipher Suite, this field contains the 16 octet PMKID identifying the PMK used for
* setting up the Secure Data Path.
*/
byte[] scid;
+ /**
+ * The config for NAN pairing set by the peer
+ */
+ NanPairingConfig peerPairingConfig;
+ /**
+ * The NIRA from peer for NAN pairing verification
+ */
+ NanIdentityResolutionAttribute peerNira;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingAkm.aidl b/wifi/aidl/android/hardware/wifi/NanPairingAkm.aidl
new file mode 100644
index 0000000..a823a3f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingAkm.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * The AKM used in the NAN pairing.
+ */
+@VintfStability @Backing(type="int") enum NanPairingAkm { SAE = 0, PASN=1 }
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingConfig.aidl b/wifi/aidl/android/hardware/wifi/NanPairingConfig.aidl
new file mode 100644
index 0000000..609dac2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * The NAN pairing config
+ */
+@VintfStability
+parcelable NanPairingConfig {
+ /**
+ * Enable NAN pairing setup
+ */
+ boolean enablePairingSetup;
+ /**
+ * Enable cache NIK/NPK after NAN pairing setup
+ */
+ boolean enablePairingCache;
+ /**
+ * Enable NAN pairing verification with cached NIK/NPK
+ */
+ boolean enablePairingVerification;
+ /**
+ * Bitmap of |NanBootstrappingMethod| values indicating the set of
+ * supported bootstrapping methods.
+ */
+ int supportedBootstrappingMethods;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
new file mode 100644
index 0000000..a5670ec
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.NanStatus;
+import android.hardware.wifi.NpkSecurityAssociation;
+
+/**
+ * NAN pairing confirmation indication structure. Event indication is
+ * received on both initiator and responder side when negotiation for a
+ * pairing finishes on success or failure. See Wi-Fi Aware R4.0 section 7.6.1.4
+ */
+@VintfStability
+parcelable NanPairingConfirmInd {
+ /**
+ * ID of the pairing session.
+ */
+ int pairingInstanceId;
+ /**
+ * Indicates whether the pairing setup succeeded (true) or failed (false).
+ */
+ boolean pairingSuccess;
+ /**
+ * Failure reason if |pairingSuccess| is false.
+ */
+ NanStatus status;
+ /**
+ * Indicate the pairing session is of setup or verification
+ */
+ NanPairingRequestType requestType;
+ /**
+ * Whether should cache the negotiated NIK/NPK for future verification
+ */
+ boolean enablePairingCache;
+ /**
+ * The security association negotiated for the pairing, can be cached for future verification
+ */
+ NpkSecurityAssociation npksa;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
new file mode 100644
index 0000000..0c2080b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.NanPairingSecurityConfig;
+
+/**
+ * NAN pairing initiate request.
+ * Can be used for setup (the initial pairing request) or
+ * verification (re-pairing for paired devices).
+ * See Wi-Fi Aware R4.0 section 7.6.1.1
+ */
+@VintfStability
+parcelable NanPairingRequest {
+ /**
+ * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+ * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+ */
+ int peerId;
+ /**
+ * NAN management interface MAC address of the peer. Obtained as part of an earlier
+ * |IWifiNanIfaceEventCallback.eventMatch| or
+ * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+ */
+ byte[6] peerDiscMacAddr;
+ /**
+ * Indicate the pairing session is for setup or verification
+ */
+ NanPairingRequestType requestType;
+ /**
+ * Whether to cache the negotiated NIK/NPK for future verification
+ */
+ boolean enablePairingCache;
+ /**
+ * The Identity key for pairing, can be used for pairing verification
+ */
+ byte[16] pairingIdentityKey;
+ /**
+ * Security config used for the pairing
+ */
+ NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
new file mode 100644
index 0000000..ec8548f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanIdentityResolutionAttribute;
+import android.hardware.wifi.NanPairingRequestType;
+
+/**
+ * NAN pairing request indication message structure.
+ * Event indication received by an intended Responder when a
+ * pairing request is initiated by an Initiator. See Wi-Fi Aware R4.0 section 7.6.1.3
+ */
+@VintfStability
+parcelable NanPairingRequestInd {
+ /**
+ * Discovery session (publish or subscribe) ID of a previously created discovery session. The
+ * pairing request is received in the context of this discovery session.
+ * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+ */
+ byte discoverySessionId;
+ /**
+ * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+ * or to set up a data-path.
+ */
+ int peerId;
+ /**
+ * MAC address of the Initiator peer. This is the MAC address of the peer's
+ * management/discovery NAN interface.
+ */
+ byte[6] peerDiscMacAddr;
+ /**
+ * ID of the NAN pairing Used to identify the pairing in further negotiation/APIs.
+ */
+ int pairingInstanceId;
+ /**
+ * Indicate the pairing session is of setup or verification
+ */
+ NanPairingRequestType requestType;
+ /**
+ * Whether should cache the negotiated NIK/NPK for future verification
+ */
+ boolean enablePairingCache;
+ /**
+ * The NIRA from peer for NAN pairing verification
+ */
+ NanIdentityResolutionAttribute peerNira;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequestType.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequestType.aidl
new file mode 100644
index 0000000..a69d04e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequestType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Type of the request of pairing
+ */
+@VintfStability
+@Backing(type="int")
+enum NanPairingRequestType {
+ NAN_PAIRING_SETUP = 0,
+ NAN_PAIRING_VERIFICATION
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanPairingSecurityConfig.aidl
new file mode 100644
index 0000000..a601751
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingSecurityConfig.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanPairingAkm;
+import android.hardware.wifi.NanPairingSecurityType;
+
+/**
+ * Configuration of NAN data-path security.
+ */
+@VintfStability
+parcelable NanPairingSecurityConfig {
+ /**
+ * Security configuration of the NAN pairing. |NanPairingSecurityType.PMK| for verification.
+ * |NanPairingSecurityType.PASSPHRASE| and |NanPairingSecurityType.OPPORTUNISTIC| for setup
+ */
+ NanPairingSecurityType securityType;
+ /**
+ * Optional Pairwise Master Key (PMK). Must be specified (and is only used) if |securityType| is
+ * set to |NanDataPathSecurityType.PMK|.
+ * Ref: IEEE 802.11i
+ */
+ byte[32] pmk;
+ /**
+ * Optional Passphrase. Must be specified (and is only used) if |securityType| is set to
+ * |NanDataPathSecurityType.PASSPHRASE|.
+ * Min length: |IWifiNanIface.MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+ * Max length: |IWifiNanIface.MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+ * NAN Spec: Appendix: Mapping passphrase to PMK for NCS-SK Cipher Suites
+ */
+ byte[] passphrase;
+ /**
+ * The AKM for key exchange
+ */
+ NanPairingAkm akm;
+ /**
+ * Cipher type for pairing. Must be one of |NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK|
+ * or |NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK|.
+ */
+ NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingSecurityType.aidl b/wifi/aidl/android/hardware/wifi/NanPairingSecurityType.aidl
new file mode 100644
index 0000000..0f97d51
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPairingSecurityType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * NAN pairing security configuration options.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanPairingSecurityType {
+ OPPORTUNISTIC,
+ PMK,
+ PASSPHRASE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
index 6dd079c..956a7df 100644
--- a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
@@ -17,6 +17,7 @@
package android.hardware.wifi;
import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanPairingConfig;
import android.hardware.wifi.NanPublishType;
import android.hardware.wifi.NanTxType;
@@ -46,4 +47,12 @@
* the device must automatically accept the data-path request and complete the negotiation.
*/
boolean autoAcceptDataPathRequests;
+ /**
+ * The config for NAN pairing
+ */
+ NanPairingConfig pairingConfig;
+ /**
+ * The Identity key for pairing, will generate NIRA for verification by the peer
+ */
+ byte[16] identityKey;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
index 6960e71..e543b7b 100644
--- a/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -58,4 +58,9 @@
* NAN Spec: Appendix: Mapping pass-phrase to PMK for NCS-SK Cipher Suites
*/
byte[] serviceNameOutOfBand;
+ /**
+ * ID of an active publish or subscribe discovery session.
+ * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
new file mode 100644
index 0000000..fab2a40
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.NanPairingSecurityConfig;
+
+/**
+ * Response to a pairing request from a peer.
+ * See Wi-Fi Aware R4.0 section 7.6.1.2
+ */
+@VintfStability
+parcelable NanRespondToPairingIndicationRequest {
+ /**
+ * Accept (true) or reject (false) the request.
+ * NAN Spec: Data Path Attributes / NDP Attribute / Type and Status
+ */
+ boolean acceptRequest;
+ /**
+ * ID of the NAN pairing for which we're responding. Obtained as part of the request in
+ * |IWifiNanIfaceEventCallback.eventPairingRequest|.
+ */
+ int pairingInstanceId;
+ /**
+ * Indicate the pairing session is of setup or verification
+ */
+ NanPairingRequestType requestType;
+ /**
+ * Whether should cache the negotiated NIK/NPK for future verification
+ */
+ boolean enablePairingCache;
+ /**
+ * The Identity key for pairing, can be used for pairing verification
+ */
+ byte[16] pairingIdentityKey;
+ /**
+ * Security config used for the pairing
+ */
+ NanPairingSecurityConfig securityConfig;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
index d63a50e..6706839 100644
--- a/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
@@ -71,4 +71,24 @@
* Unsupported concurrency of NAN and another feature - NAN disabled.
*/
UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+ /**
+ * If the pairing id is invalid
+ */
+ INVALID_PAIRING_ID = 13,
+ /**
+ * If the bootstrapping id is invalid
+ */
+ INVALID_BOOTSTRAPPING_ID = 14,
+ /*
+ * If same request is received again
+ */
+ REDUNDANT_REQUEST = 15,
+ /*
+ * If current request is not supported
+ */
+ NOT_SUPPORTED = 16,
+ /*
+ * If no Wifi Aware connection is active
+ */
+ NO_CONNECTION = 17
}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
index 12c1170..0b246ed 100644
--- a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.MacAddress;
import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanPairingConfig;
import android.hardware.wifi.NanSrfType;
import android.hardware.wifi.NanSubscribeType;
@@ -67,4 +68,12 @@
* NAN Spec: Service Descriptor Attribute (SDA) / Service Response Filter / Address Set
*/
MacAddress[] intfAddr;
+ /**
+ * Security config used for the pairing
+ */
+ NanPairingConfig pairingConfig;
+ /**
+ * The Identity key for pairing, will generate NIRA for verification by the peer
+ */
+ byte[16] identityKey;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanSuspensionModeChangeInd.aidl b/wifi/aidl/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
new file mode 100644
index 0000000..057e63b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSuspensionModeChangeInd.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+/**
+ * Event indication that the device entered or exited the suspension mode
+ */
+@VintfStability
+parcelable NanSuspensionModeChangeInd {
+ /**
+ * Indication whether the device has entered or exited the NAN suspension mode(deep sleep)
+ */
+ boolean isSuspended;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NpkSecurityAssociation.aidl b/wifi/aidl/android/hardware/wifi/NpkSecurityAssociation.aidl
new file mode 100644
index 0000000..4d65a41
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NpkSecurityAssociation.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanPairingAkm;
+
+/**
+ * The security association info after Aware Pairing setup.
+ */
+@VintfStability
+parcelable NpkSecurityAssociation {
+ /**
+ * The Aware pairing identity from the peer
+ */
+ byte[16] peerNanIdentityKey;
+ /**
+ * The Aware pairing identity for local device
+ */
+ byte[16] localNanIdentityKey;
+ /**
+ * The PMK is used in this security association
+ */
+ byte[32] npk;
+ /**
+ * The AKM is used for key exchange in this security association
+ */
+ NanPairingAkm akm;
+ /**
+ * Cipher type for pairing. Must be one of |NanCipherSuiteType.PUBLIC_KEY_PASN_128_MASK| or
+ * |NanCipherSuiteType.PUBLIC_KEY_PASN_256_MASK|.
+ */
+ NanCipherSuiteType cipherType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttBw.aidl b/wifi/aidl/android/hardware/wifi/RttBw.aidl
index 9d42dc0..be9ecbd 100644
--- a/wifi/aidl/android/hardware/wifi/RttBw.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttBw.aidl
@@ -22,6 +22,7 @@
@VintfStability
@Backing(type="int")
enum RttBw {
+ BW_UNSPECIFIED = 0x0,
BW_5MHZ = 0x01,
BW_10MHZ = 0x02,
BW_20MHZ = 0x04,
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index 565cce7..6c45e2c 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi;
+import android.hardware.wifi.RttBw;
import android.hardware.wifi.RttStatus;
import android.hardware.wifi.RttType;
import android.hardware.wifi.WifiInformationElement;
@@ -132,4 +133,15 @@
* For 11mc only.
*/
WifiInformationElement lcr;
+ /**
+ * RTT channel frequency in MHz
+ * If frequency is unknown, this will be set to 0.
+ */
+ 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.
+ */
+ RttBw packetBw;
}
diff --git a/wifi/aidl/android/hardware/wifi/Ssid.aidl b/wifi/aidl/android/hardware/wifi/Ssid.aidl
index fd985a3..230cef6 100644
--- a/wifi/aidl/android/hardware/wifi/Ssid.aidl
+++ b/wifi/aidl/android/hardware/wifi/Ssid.aidl
@@ -20,8 +20,6 @@
* Byte array representing an Ssid. Use when we need to
* pass an array of Ssid's to a method, as variable-sized
* 2D arrays are not supported in AIDL.
- *
- * TODO (b/210705533): Replace this type with a 2D byte array.
*/
@VintfStability
parcelable Ssid {
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
index 7bd87b2..76b510d 100644
--- a/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -16,7 +16,6 @@
package android.hardware.wifi;
-import android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask;
import android.hardware.wifi.WifiBand;
/**
@@ -50,7 +49,7 @@
* Bitset of |StaBackgroundScanBucketEventReportSchemeMask| values controlling
* when events for this bucket must be reported.
*/
- StaBackgroundScanBucketEventReportSchemeMask eventReportScheme;
+ int eventReportScheme;
/**
* For exponential back off. If |exponentialMaxPeriodInMs| is non-zero or
* different than period, then this bucket is an exponential backoff bucket
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
index 78f8caa..3f8718f 100644
--- a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -16,64 +16,13 @@
package android.hardware.wifi;
-import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
-import android.hardware.wifi.StaLinkLayerIfacePacketStats;
-import android.hardware.wifi.StaPeerInfo;
+import android.hardware.wifi.StaLinkLayerLinkStats;
/**
- * Iface statistics for the current connection.
+ * Iface statistics for the current connection. Current connection may have
+ * single or multiple links.
*/
@VintfStability
parcelable StaLinkLayerIfaceStats {
- /**
- * Number beacons received from the connected AP.
- */
- int beaconRx;
- /**
- * Access Point Beacon and Management frames RSSI (averaged).
- */
- int avgRssiMgmt;
- /**
- * WME Best Effort Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeBePktStats;
- /**
- * WME Background Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeBkPktStats;
- /**
- * WME Video Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeViPktStats;
- /**
- * WME Voice Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeVoPktStats;
- /**
- * Duty cycle for the iface.
- * If this iface is being served using time slicing on a radio with one or more ifaces
- * (i.e MCC), then the duty cycle assigned to this iface in %.
- * If not using time slicing (i.e SCC or DBS), set to 100.
- */
- byte timeSliceDutyCycleInPercent;
- /**
- * WME Best Effort (BE) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
- /**
- * WME Background (BK) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
- /**
- * WME Video (VI) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
- /**
- * WME Voice (VO) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
- /**
- * Per peer statistics.
- */
- StaPeerInfo[] peers;
+ StaLinkLayerLinkStats[] links;
}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..2519543
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
+import android.hardware.wifi.StaLinkLayerIfacePacketStats;
+import android.hardware.wifi.StaPeerInfo;
+
+/**
+ * Per Link statistics for the current connection. For MLO, this is
+ * the statistics for one link in the connection.
+ */
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+ /**
+ * Identifier for the link within MLO. For single link operation this field
+ * is not relevant and can be set to 0.
+ */
+ int linkId;
+ /**
+ * Radio identifier on which the link is currently operating. Refer
+ * |StaLinkLayerRadioStats.radioId|.
+ */
+ int radioId;
+ /**
+ * Frequency of the link in Mhz.
+ */
+ int frequencyMhz;
+ /**
+ * Number of beacons received from the connected AP on the link.
+ */
+ int beaconRx;
+ /**
+ * Access Point Beacon and Management frames RSSI (averaged) on the link.
+ */
+ int avgRssiMgmt;
+ /**
+ * WME Best Effort Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeBePktStats;
+ /**
+ * WME Background Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeBkPktStats;
+ /**
+ * WME Video Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeViPktStats;
+ /**
+ * WME Voice Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeVoPktStats;
+ /**
+ * Duty cycle for the link.
+ * If this link is being served using time slicing on a radio with one or
+ * more links then the duty cycle assigned to this link in %. If not using
+ * time slicing, set to 100.
+ */
+ byte timeSliceDutyCycleInPercent;
+ /**
+ * WME Best Effort (BE) Access Category (AC) contention time statistics on
+ * the link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+ /**
+ * WME Background (BK) Access Category (AC) contention time statistics on
+ * the link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+ /**
+ * WME Video (VI) Access Category (AC) contention time statistics on the
+ * link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+ /**
+ * WME Voice (VO) Access Category (AC) contention time statistics on the
+ * link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+ /**
+ * Per peer statistics for the link.
+ */
+ StaPeerInfo[] peers;
+ /**
+ * Various states of the link.
+ */
+ @Backing(type="int")
+ @VintfStability
+ enum StaLinkState {
+ /**
+ * Chip does not support reporting the state of the link.
+ */
+ UNKNOWN = 0,
+ /**
+ * Link has not been in use since last report. It is placed in power save. All management,
+ * control and data frames for the MLO connection are carried over other links. In this
+ * state the link will not listen to beacons even in DTIM period and does not perform any
+ * GTK/IGTK/BIGTK updates but remains associated.
+ */
+ NOT_IN_USE = 1 << 0,
+ /**
+ * Link is in use. In presence of traffic, it is set to be power active. When the traffic
+ * stops, the link will go into power save mode and will listen for beacons every DTIM
+ * period.
+ *
+ */
+ IN_USE = 1 << 1,
+ }
+ /**
+ * State of the link. Refer |StaLinkState|.
+ */
+ StaLinkState state;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/android/hardware/wifi/StaScanData.aidl
index 9d6bd53..abc5638 100644
--- a/wifi/aidl/android/hardware/wifi/StaScanData.aidl
+++ b/wifi/aidl/android/hardware/wifi/StaScanData.aidl
@@ -16,7 +16,6 @@
package android.hardware.wifi;
-import android.hardware.wifi.StaScanDataFlagMask;
import android.hardware.wifi.StaScanResult;
/**
@@ -26,9 +25,9 @@
@VintfStability
parcelable StaScanData {
/**
- * Bitset containing |ScanDataFlagMask| values.
+ * Bitset of |ScanDataFlagMask| values.
*/
- StaScanDataFlagMask flags;
+ int flags;
/**
* Bitset where each bit indicates if the bucket with that index (starting at
* 0) was scanned.
diff --git a/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl b/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl
new file mode 100644
index 0000000..77b9049
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChipCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * WifiChipCapabilities captures various Wifi chip capability params.
+ */
+@VintfStability
+parcelable WifiChipCapabilities {
+ /**
+ * Maximum number of links supported by the chip for MLO association.
+ */
+ int maxMloAssociationLinkCount;
+ /**
+ * Maximum number of Simultaneous Transmit and Receive (STR) links used
+ * in Multi-Link Operation. The maximum number of STR links used can be
+ * different from the maximum number of radios supported by the chip.
+ *
+ * This is a static configuration of the chip.
+ */
+ int maxMloStrLinkCount;
+ /**
+ * Maximum number of concurrent TDLS sessions that can be enabled
+ * by framework via ISupplicantStaIface#initiateTdlsSetup().
+ */
+ int maxConcurrentTdlsSessionCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
deleted file mode 100644
index b79a818..0000000
--- a/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.wifi;
-
-import android.hardware.wifi.WifiRadioCombination;
-
-/**
- * Wifi radio combinations matrix retrieved via
- * |IWifiChip.getSupportedRadioCombinationsMatrix|.
- */
-@VintfStability
-parcelable WifiRadioCombinationMatrix {
- /**
- * List of all the possible radio combinations that the chip can operate.
- */
- WifiRadioCombination[] radioCombinations;
-}
diff --git a/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
index d92e4cc..077c17e 100644
--- a/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
+++ b/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
@@ -17,7 +17,6 @@
package android.hardware.wifi;
import android.hardware.wifi.WifiChannelWidthInMhz;
-import android.hardware.wifi.WifiIfaceMode;
/**
* Wifi usable channel information.
@@ -33,7 +32,8 @@
*/
WifiChannelWidthInMhz channelBandwidth;
/**
- * Iface modes feasible on this channel.
+ * Iface modes feasible on this channel, represented as a bitmask
+ * of |WifiIfaceMode| values.
*/
- WifiIfaceMode ifaceModeMask;
+ int ifaceModeMask;
}
diff --git a/wifi/aidl/default/Android.bp b/wifi/aidl/default/Android.bp
new file mode 100644
index 0000000..91d609d
--- /dev/null
+++ b/wifi/aidl/default/Android.bp
@@ -0,0 +1,218 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+soong_config_module_type {
+ name: "wifi_hal_cc_defaults",
+ module_type: "cc_defaults",
+ config_namespace: "wifi",
+ bool_variables: [
+ "hidl_feature_aware", // WIFI_HIDL_FEATURE_AWARE
+ "hidl_feature_dual_interface", // WIFI_HIDL_FEATURE_DUAL_INTERFACE
+ "hidl_feature_disable_ap", // WIFI_HIDL_FEATURE_DISABLE_AP
+ "hidl_feature_disable_ap_mac_randomization", // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+ "avoid_iface_reset_mac_change", // WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ "wifi_skip_state_toggle_off_on_for_nan", // WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+ ],
+ value_variables: [
+ "hal_interface_combinations", // WIFI_HAL_INTERFACE_COMBINATIONS
+ ],
+ properties: [
+ "cppflags",
+ ],
+}
+
+wifi_hal_cc_defaults {
+ name: "android.hardware.wifi-service-cppflags-defaults",
+ soong_config_variables: {
+ hidl_feature_aware: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_AWARE"],
+ },
+ hidl_feature_dual_interface: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_DUAL_INTERFACE"],
+ },
+ hidl_feature_disable_ap: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP"],
+ },
+ hidl_feature_disable_ap_mac_randomization: {
+ cppflags: ["-DWIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION"],
+ },
+ avoid_iface_reset_mac_change: {
+ cppflags: ["-DWIFI_AVOID_IFACE_RESET_MAC_CHANGE"],
+ },
+ wifi_skip_state_toggle_off_on_for_nan: {
+ cppflags: ["-DWIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN"],
+ },
+ hal_interface_combinations: {
+ cppflags: ["-DWIFI_HAL_INTERFACE_COMBINATIONS=%s"],
+ },
+ },
+}
+
+cc_library_static {
+ name: "android.hardware.wifi-service-lib",
+ defaults: ["android.hardware.wifi-service-cppflags-defaults"],
+ proprietary: true,
+ compile_multilib: "first",
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ // Allow implicit fallthroughs in wifi_legacy_hal.cpp until they are fixed.
+ cflags: ["-Wno-error=implicit-fallthrough"],
+ srcs: [
+ "aidl_struct_util.cpp",
+ "aidl_sync_util.cpp",
+ "ringbuffer.cpp",
+ "wifi.cpp",
+ "wifi_ap_iface.cpp",
+ "wifi_chip.cpp",
+ "wifi_feature_flags.cpp",
+ "wifi_iface_util.cpp",
+ "wifi_legacy_hal.cpp",
+ "wifi_legacy_hal_factory.cpp",
+ "wifi_legacy_hal_stubs.cpp",
+ "wifi_mode_controller.cpp",
+ "wifi_nan_iface.cpp",
+ "wifi_p2p_iface.cpp",
+ "wifi_rtt_controller.cpp",
+ "wifi_sta_iface.cpp",
+ "wifi_status_util.cpp",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ "libxml2",
+ "android.hardware.wifi-V1-ndk",
+ ],
+
+ export_include_dirs: ["."],
+}
+
+cc_binary {
+ name: "android.hardware.wifi-service",
+ vintf_fragments: ["android.hardware.wifi-service.xml"],
+ relative_install_path: "hw",
+ proprietary: true,
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ srcs: ["service.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ "libxml2",
+ "android.hardware.wifi-V1-ndk",
+ ],
+ static_libs: ["android.hardware.wifi-service-lib"],
+ init_rc: ["android.hardware.wifi-service.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.wifi-service-lazy",
+ vintf_fragments: ["android.hardware.wifi-service.xml"],
+ overrides: ["android.hardware.wifi-service"],
+ cflags: ["-DLAZY_SERVICE"],
+ relative_install_path: "hw",
+ proprietary: true,
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ srcs: ["service.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ "libxml2",
+ "android.hardware.wifi-V1-ndk",
+ ],
+ static_libs: ["android.hardware.wifi-service-lib"],
+ init_rc: ["android.hardware.wifi-service-lazy.rc"],
+}
+
+cc_test {
+ name: "android.hardware.wifi-service-tests",
+ proprietary: true,
+ compile_multilib: "first",
+ cppflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+ srcs: [
+ "tests/aidl_struct_util_unit_tests.cpp",
+ "tests/main.cpp",
+ "tests/mock_interface_tool.cpp",
+ "tests/mock_wifi_feature_flags.cpp",
+ "tests/mock_wifi_iface_util.cpp",
+ "tests/mock_wifi_legacy_hal.cpp",
+ "tests/mock_wifi_mode_controller.cpp",
+ "tests/ringbuffer_unit_tests.cpp",
+ "tests/wifi_nan_iface_unit_tests.cpp",
+ "tests/wifi_chip_unit_tests.cpp",
+ "tests/wifi_iface_util_unit_tests.cpp",
+ ],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ "android.hardware.wifi-V1-ndk",
+ "android.hardware.wifi-service-lib",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libnl",
+ "libutils",
+ "libwifi-hal",
+ "libwifi-system-iface",
+ ],
+}
+
+filegroup {
+ name: "default-android.hardware.wifi-service.rc",
+ srcs: ["android.hardware.wifi-service.rc"],
+}
+
+filegroup {
+ name: "default-android.hardware.wifi-service.xml",
+ srcs: ["android.hardware.wifi-service.xml"],
+}
diff --git a/wifi/aidl/default/THREADING.README b/wifi/aidl/default/THREADING.README
new file mode 100644
index 0000000..45679da
--- /dev/null
+++ b/wifi/aidl/default/THREADING.README
@@ -0,0 +1,35 @@
+Vendor HAL Threading Model
+==========================
+The vendor HAL service has two threads:
+1. AIDL thread: This is the main thread which processes all the incoming AIDL
+RPC's.
+2. Legacy HAL event loop thread: This is the thread forked off for processing
+the legacy HAL event loop (wifi_event_loop()). This thread is used to process
+any asynchronous netlink events posted by the driver. Any asynchronous
+callbacks passed to the legacy HAL API's are invoked on this thread.
+
+Synchronization Concerns
+========================
+wifi_legacy_hal.cpp has a bunch of global "C" style functions to handle the
+legacy callbacks. Each of these "C" style functions invokes a corresponding
+"std::function" version of the callback which does the actual processing.
+The variables holding these "std::function" callbacks are reset from the AIDL
+thread when they are no longer used. For example: stopGscan() will reset the
+corresponding "on_gscan_*" callback variables which were set when startGscan()
+was invoked. This is not thread safe since these callback variables are
+accesed from the legacy hal event loop thread as well.
+
+Synchronization Solution
+========================
+Adding a global lock seems to be the most trivial solution to the problem.
+a) All of the asynchronous "C" style callbacks will acquire the global lock
+before invoking the corresponding "std::function" callback variables.
+b) All of the AIDL methods will also acquire the global lock before processing
+(in aidl_return_util::validateAndCall()).
+
+Note: It's important that we only acquire the global lock for asynchronous
+callbacks, because there is no guarantee (or documentation to clarify) that the
+synchronous callbacks are invoked on the same invocation thread. If that is not
+the case in some implementation, we will end up deadlocking the system since the
+AIDL thread would have acquired the global lock which is needed by the
+synchronous callback executed on the legacy hal event loop thread.
diff --git a/wifi/aidl/default/aidl_callback_util.h b/wifi/aidl/default/aidl_callback_util.h
new file mode 100644
index 0000000..41d70a5
--- /dev/null
+++ b/wifi/aidl/default/aidl_callback_util.h
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_CALLBACK_UTIL_H_
+#define AIDL_CALLBACK_UTIL_H_
+
+#include <android-base/logging.h>
+
+#include <set>
+#include <unordered_map>
+
+namespace {
+std::unordered_map<void* /* callback */, void* /* handler */> callback_handler_map_;
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_callback_util {
+
+// Provides a class to manage callbacks for the various AIDL interfaces and
+// handle the death of the process hosting each callback.
+template <typename CallbackType>
+class AidlCallbackHandler {
+ public:
+ AidlCallbackHandler() {
+ death_handler_ = AIBinder_DeathRecipient_new(AidlCallbackHandler::onCallbackDeath);
+ }
+ ~AidlCallbackHandler() { invalidate(); }
+
+ bool addCallback(const std::shared_ptr<CallbackType>& cb) {
+ void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get());
+ const auto& cbPosition = findCbInSet(cbPtr);
+ if (cbPosition != cb_set_.end()) {
+ LOG(WARNING) << "Duplicate death notification registration";
+ return true;
+ }
+
+ if (AIBinder_linkToDeath(cb->asBinder().get(), death_handler_, cbPtr /* cookie */) !=
+ STATUS_OK) {
+ LOG(ERROR) << "Failed to register death notification";
+ return false;
+ }
+
+ callback_handler_map_[cbPtr] = reinterpret_cast<void*>(this);
+ cb_set_.insert(cb);
+ return true;
+ }
+
+ const std::set<std::shared_ptr<CallbackType>>& getCallbacks() { return cb_set_; }
+
+ void invalidate() {
+ for (auto cb : cb_set_) {
+ void* cookie = reinterpret_cast<void*>(cb->asBinder().get());
+ if (AIBinder_unlinkToDeath(cb->asBinder().get(), death_handler_, cookie) != STATUS_OK) {
+ LOG(ERROR) << "Failed to deregister death notification";
+ }
+ if (!removeCbFromHandlerMap(cookie)) {
+ LOG(ERROR) << "Failed to remove callback from handler map";
+ }
+ }
+ cb_set_.clear();
+ }
+
+ // Entry point for the death handling logic. AIBinder_DeathRecipient
+ // can only call a static function, so use the cookie to find the
+ // proper handler and route the request there.
+ static void onCallbackDeath(void* cookie) {
+ auto cbQuery = callback_handler_map_.find(cookie);
+ if (cbQuery == callback_handler_map_.end()) {
+ LOG(ERROR) << "Invalid death cookie received";
+ return;
+ }
+
+ AidlCallbackHandler* cbHandler = reinterpret_cast<AidlCallbackHandler*>(cbQuery->second);
+ if (cbHandler == nullptr) {
+ LOG(ERROR) << "Handler mapping contained an invalid handler";
+ return;
+ }
+ cbHandler->handleCallbackDeath(cbQuery->first);
+ }
+
+ private:
+ std::set<std::shared_ptr<CallbackType>> cb_set_;
+ AIBinder_DeathRecipient* death_handler_;
+
+ typename std::set<std::shared_ptr<CallbackType>>::iterator findCbInSet(void* cbPtr) {
+ const auto& cbPosition = std::find_if(
+ cb_set_.begin(), cb_set_.end(), [cbPtr](const std::shared_ptr<CallbackType>& p) {
+ return cbPtr == reinterpret_cast<void*>(p->asBinder().get());
+ });
+ return cbPosition;
+ }
+
+ bool removeCbFromHandlerMap(void* cbPtr) {
+ auto cbQuery = callback_handler_map_.find(cbPtr);
+ if (cbQuery != callback_handler_map_.end()) {
+ callback_handler_map_.erase(cbQuery);
+ return true;
+ }
+ return false;
+ }
+
+ void handleCallbackDeath(void* cbPtr) {
+ const auto& cbPosition = findCbInSet(cbPtr);
+ if (cbPosition == cb_set_.end()) {
+ LOG(ERROR) << "Unknown callback death notification received";
+ return;
+ }
+ cb_set_.erase(cbPosition);
+
+ if (!removeCbFromHandlerMap(cbPtr)) {
+ LOG(ERROR) << "Callback was not in callback handler map";
+ }
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(AidlCallbackHandler);
+};
+
+} // namespace aidl_callback_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // AIDL_CALLBACK_UTIL_H_
diff --git a/wifi/aidl/default/aidl_return_util.h b/wifi/aidl/default/aidl_return_util.h
new file mode 100644
index 0000000..9a49a22
--- /dev/null
+++ b/wifi/aidl/default/aidl_return_util.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_RETURN_UTIL_H_
+#define AIDL_RETURN_UTIL_H_
+
+#include "aidl_sync_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_return_util {
+using aidl::android::hardware::wifi::WifiStatusCode;
+using aidl::android::hardware::wifi::aidl_sync_util::acquireGlobalLock;
+
+/**
+ * These utility functions are used to invoke a method on the provided
+ * AIDL interface object.
+ * These functions checks if the provided AIDL interface object is valid.
+ * a) If valid, Invokes the corresponding internal implementation function of
+ * the AIDL method.
+ * b) If invalid, return without calling the internal implementation function.
+ */
+
+// Use for AIDL methods which return only an AIDL status.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work, Args&&... args) {
+ const auto lock = acquireGlobalLock();
+ if (obj->isValid()) {
+ return (obj->*work)(std::forward<Args>(args)...);
+ } else {
+ return createWifiStatus(status_code_if_invalid);
+ }
+}
+
+// Use for AIDL methods which return only an AIDL status.
+// This version passes the global lock acquired to the body of the method.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+::ndk::ScopedAStatus validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work, Args&&... args) {
+ auto lock = acquireGlobalLock();
+ if (obj->isValid()) {
+ return (obj->*work)(&lock, std::forward<Args>(args)...);
+ } else {
+ return createWifiStatus(status_code_if_invalid);
+ }
+}
+
+// Use for AIDL methods which have a return value along with the AIDL status
+template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work, ReturnT* ret_val, Args&&... args) {
+ const auto lock = acquireGlobalLock();
+ if (obj->isValid()) {
+ auto call_pair = (obj->*work)(std::forward<Args>(args)...);
+ *ret_val = call_pair.first;
+ return std::forward<::ndk::ScopedAStatus>(call_pair.second);
+ } else {
+ return ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(status_code_if_invalid));
+ }
+}
+
+} // namespace aidl_return_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+#endif // AIDL_RETURN_UTIL_H_
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
new file mode 100644
index 0000000..7bc2eeb
--- /dev/null
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -0,0 +1,3359 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <utils/SystemClock.h>
+
+#include "aidl_struct_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_struct_util {
+
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToAidl(legacy_hal::wifi_channel_width type);
+
+std::string safeConvertChar(const char* str, size_t max_len) {
+ const char* c = str;
+ size_t size = 0;
+ while (*c && (unsigned char)*c < 128 && size < max_len) {
+ ++size;
+ ++c;
+ }
+ return std::string(str, size);
+}
+
+inline std::vector<int32_t> uintToIntVec(const std::vector<uint32_t>& in) {
+ return std::vector<int32_t>(in.begin(), in.end());
+}
+
+IWifiChip::FeatureSetMask convertLegacyChipFeatureToAidl(uint64_t feature) {
+ switch (feature) {
+ case WIFI_FEATURE_SET_TX_POWER_LIMIT:
+ return IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT;
+ case WIFI_FEATURE_USE_BODY_HEAD_SAR:
+ return IWifiChip::FeatureSetMask::USE_BODY_HEAD_SAR;
+ case WIFI_FEATURE_D2D_RTT:
+ return IWifiChip::FeatureSetMask::D2D_RTT;
+ case WIFI_FEATURE_D2AP_RTT:
+ return IWifiChip::FeatureSetMask::D2AP_RTT;
+ case WIFI_FEATURE_INFRA_60G:
+ return IWifiChip::FeatureSetMask::WIGIG;
+ case WIFI_FEATURE_SET_LATENCY_MODE:
+ return IWifiChip::FeatureSetMask::SET_LATENCY_MODE;
+ case WIFI_FEATURE_P2P_RAND_MAC:
+ return IWifiChip::FeatureSetMask::P2P_RAND_MAC;
+ case WIFI_FEATURE_AFC_CHANNEL:
+ return IWifiChip::FeatureSetMask::SET_AFC_CHANNEL_ALLOWANCE;
+ };
+ CHECK(false) << "Unknown legacy feature: " << feature;
+ return {};
+}
+
+IWifiStaIface::FeatureSetMask convertLegacyStaIfaceFeatureToAidl(uint64_t feature) {
+ switch (feature) {
+ case WIFI_FEATURE_GSCAN:
+ return IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN;
+ case WIFI_FEATURE_LINK_LAYER_STATS:
+ return IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS;
+ case WIFI_FEATURE_RSSI_MONITOR:
+ return IWifiStaIface::FeatureSetMask::RSSI_MONITOR;
+ case WIFI_FEATURE_CONTROL_ROAMING:
+ return IWifiStaIface::FeatureSetMask::CONTROL_ROAMING;
+ case WIFI_FEATURE_IE_WHITELIST:
+ return IWifiStaIface::FeatureSetMask::PROBE_IE_ALLOWLIST;
+ case WIFI_FEATURE_SCAN_RAND:
+ return IWifiStaIface::FeatureSetMask::SCAN_RAND;
+ case WIFI_FEATURE_INFRA_5G:
+ return IWifiStaIface::FeatureSetMask::STA_5G;
+ case WIFI_FEATURE_HOTSPOT:
+ return IWifiStaIface::FeatureSetMask::HOTSPOT;
+ case WIFI_FEATURE_PNO:
+ return IWifiStaIface::FeatureSetMask::PNO;
+ case WIFI_FEATURE_TDLS:
+ return IWifiStaIface::FeatureSetMask::TDLS;
+ case WIFI_FEATURE_TDLS_OFFCHANNEL:
+ return IWifiStaIface::FeatureSetMask::TDLS_OFFCHANNEL;
+ case WIFI_FEATURE_CONFIG_NDO:
+ return IWifiStaIface::FeatureSetMask::ND_OFFLOAD;
+ case WIFI_FEATURE_MKEEP_ALIVE:
+ return IWifiStaIface::FeatureSetMask::KEEP_ALIVE;
+ };
+ CHECK(false) << "Unknown legacy feature: " << feature;
+ return {};
+}
+
+bool convertLegacyChipFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set) {
+ if (!aidl_feature_set) {
+ return false;
+ }
+ *aidl_feature_set = 0;
+ std::vector<uint64_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT,
+ WIFI_FEATURE_USE_BODY_HEAD_SAR,
+ WIFI_FEATURE_D2D_RTT,
+ WIFI_FEATURE_D2AP_RTT,
+ WIFI_FEATURE_INFRA_60G,
+ WIFI_FEATURE_SET_LATENCY_MODE,
+ WIFI_FEATURE_P2P_RAND_MAC,
+ WIFI_FEATURE_AFC_CHANNEL};
+ for (const auto feature : features) {
+ if (feature & legacy_feature_set) {
+ *aidl_feature_set |= static_cast<uint32_t>(convertLegacyChipFeatureToAidl(feature));
+ }
+ }
+
+ return true;
+}
+
+WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToAidl(uint32_t flag) {
+ switch (flag) {
+ case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES:
+ return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES;
+ case WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES:
+ return WifiDebugRingBufferFlags::HAS_ASCII_ENTRIES;
+ };
+ CHECK(false) << "Unknown legacy flag: " << flag;
+ return {};
+}
+
+bool convertLegacyDebugRingBufferStatusToAidl(
+ const legacy_hal::wifi_ring_buffer_status& legacy_status,
+ WifiDebugRingBufferStatus* aidl_status) {
+ if (!aidl_status) {
+ return false;
+ }
+ *aidl_status = {};
+ aidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
+ sizeof(legacy_status.name));
+ aidl_status->flags = 0;
+ for (const auto flag :
+ {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
+ if (flag & legacy_status.flags) {
+ aidl_status->flags |= static_cast<std::underlying_type<WifiDebugRingBufferFlags>::type>(
+ convertLegacyDebugRingBufferFlagsToAidl(flag));
+ }
+ }
+ aidl_status->ringId = legacy_status.ring_id;
+ aidl_status->sizeInBytes = legacy_status.ring_buffer_byte_size;
+ // Calculate free size of the ring the buffer. We don't need to send the
+ // exact read/write pointers that were there in the legacy HAL interface.
+ if (legacy_status.written_bytes >= legacy_status.read_bytes) {
+ aidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size -
+ (legacy_status.written_bytes - legacy_status.read_bytes);
+ } else {
+ aidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes;
+ }
+ aidl_status->verboseLevel = legacy_status.verbose_level;
+ return true;
+}
+
+bool convertLegacyVectorOfDebugRingBufferStatusToAidl(
+ const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+ std::vector<WifiDebugRingBufferStatus>* aidl_status_vec) {
+ if (!aidl_status_vec) {
+ return false;
+ }
+ *aidl_status_vec = {};
+ for (const auto& legacy_status : legacy_status_vec) {
+ WifiDebugRingBufferStatus aidl_status;
+ if (!convertLegacyDebugRingBufferStatusToAidl(legacy_status, &aidl_status)) {
+ return false;
+ }
+ aidl_status_vec->push_back(aidl_status);
+ }
+ return true;
+}
+
+bool convertLegacyWakeReasonStatsToAidl(const legacy_hal::WakeReasonStats& legacy_stats,
+ WifiDebugHostWakeReasonStats* aidl_stats) {
+ if (!aidl_stats) {
+ return false;
+ }
+ *aidl_stats = {};
+ aidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake;
+ aidl_stats->cmdEventWakeCntPerType = uintToIntVec(legacy_stats.cmd_event_wake_cnt);
+ aidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake;
+ aidl_stats->driverFwLocalWakeCntPerType = uintToIntVec(legacy_stats.driver_fw_local_wake_cnt);
+ aidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake;
+ aidl_stats->rxPktWakeDetails.rxUnicastCnt =
+ legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt;
+ aidl_stats->rxPktWakeDetails.rxMulticastCnt =
+ legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt;
+ aidl_stats->rxPktWakeDetails.rxBroadcastCnt =
+ legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt;
+ aidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt =
+ legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt;
+ aidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt =
+ legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt;
+ aidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt =
+ legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt;
+ aidl_stats->rxIcmpPkWakeDetails.icmpPkt =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt;
+ aidl_stats->rxIcmpPkWakeDetails.icmp6Pkt =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt;
+ aidl_stats->rxIcmpPkWakeDetails.icmp6Ra =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra;
+ aidl_stats->rxIcmpPkWakeDetails.icmp6Na =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na;
+ aidl_stats->rxIcmpPkWakeDetails.icmp6Ns =
+ legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns;
+ return true;
+}
+
+legacy_hal::wifi_power_scenario convertAidlTxPowerScenarioToLegacy(
+ IWifiChip::TxPowerScenario aidl_scenario) {
+ switch (aidl_scenario) {
+ case IWifiChip::TxPowerScenario::VOICE_CALL:
+ return legacy_hal::WIFI_POWER_SCENARIO_VOICE_CALL;
+ case IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
+ case IWifiChip::TxPowerScenario::ON_HEAD_CELL_ON:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
+ case IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
+ case IWifiChip::TxPowerScenario::ON_BODY_CELL_ON:
+ return legacy_hal::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
+ };
+ CHECK(false);
+}
+
+legacy_hal::wifi_latency_mode convertAidlLatencyModeToLegacy(
+ IWifiChip::LatencyMode aidl_latency_mode) {
+ switch (aidl_latency_mode) {
+ case IWifiChip::LatencyMode::NORMAL:
+ return legacy_hal::WIFI_LATENCY_MODE_NORMAL;
+ case IWifiChip::LatencyMode::LOW:
+ return legacy_hal::WIFI_LATENCY_MODE_LOW;
+ }
+ CHECK(false);
+}
+
+bool convertLegacyWifiMacInfoToAidl(const legacy_hal::WifiMacInfo& legacy_mac_info,
+ IWifiChipEventCallback::RadioModeInfo* aidl_radio_mode_info) {
+ if (!aidl_radio_mode_info) {
+ return false;
+ }
+ *aidl_radio_mode_info = {};
+
+ aidl_radio_mode_info->radioId = legacy_mac_info.wlan_mac_id;
+ // Convert from bitmask of bands in the legacy HAL to enum value in
+ // the AIDL interface.
+ if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_6GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND &&
+ legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ;
+ } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ;
+ } else {
+ aidl_radio_mode_info->bandInfo = WifiBand::BAND_UNSPECIFIED;
+ }
+ std::vector<IWifiChipEventCallback::IfaceInfo> iface_info_vec;
+ for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) {
+ IWifiChipEventCallback::IfaceInfo iface_info;
+ iface_info.name = legacy_iface_info.name;
+ iface_info.channel = legacy_iface_info.channel;
+ iface_info_vec.push_back(iface_info);
+ }
+ aidl_radio_mode_info->ifaceInfos = iface_info_vec;
+ return true;
+}
+
+uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand aidl_band) {
+ switch (aidl_band) {
+ case WifiBand::BAND_24GHZ:
+ return legacy_hal::WLAN_MAC_2_4_BAND;
+ case WifiBand::BAND_5GHZ:
+ case WifiBand::BAND_5GHZ_DFS:
+ case WifiBand::BAND_5GHZ_WITH_DFS:
+ return legacy_hal::WLAN_MAC_5_0_BAND;
+ case WifiBand::BAND_24GHZ_5GHZ:
+ case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+ return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND);
+ case WifiBand::BAND_6GHZ:
+ return legacy_hal::WLAN_MAC_6_0_BAND;
+ case WifiBand::BAND_5GHZ_6GHZ:
+ return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND);
+ case WifiBand::BAND_24GHZ_5GHZ_6GHZ:
+ case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
+ return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+ legacy_hal::WLAN_MAC_6_0_BAND);
+ case WifiBand::BAND_60GHZ:
+ return legacy_hal::WLAN_MAC_60_0_BAND;
+ default:
+ return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+ legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
+ }
+}
+
+WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band) {
+ switch (band) {
+ case legacy_hal::WLAN_MAC_2_4_BAND:
+ return WifiBand::BAND_24GHZ;
+ case legacy_hal::WLAN_MAC_5_0_BAND:
+ return WifiBand::BAND_5GHZ;
+ case legacy_hal::WLAN_MAC_6_0_BAND:
+ return WifiBand::BAND_6GHZ;
+ case legacy_hal::WLAN_MAC_60_0_BAND:
+ return WifiBand::BAND_60GHZ;
+ default:
+ return WifiBand::BAND_UNSPECIFIED;
+ }
+}
+
+uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask) {
+ uint32_t legacy_iface_mask = 0;
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_STA)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_SOFTAP)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_NAN)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_TDLS)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_MESH)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH);
+ }
+ if (aidl_iface_mask & static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_IBSS)) {
+ legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS);
+ }
+ return legacy_iface_mask;
+}
+
+uint32_t convertLegacyWifiInterfaceModeToAidl(uint32_t legacy_iface_mask) {
+ uint32_t aidl_iface_mask = 0;
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_STA);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_SOFTAP);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_NAN);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_TDLS);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_MESH);
+ }
+ if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) {
+ aidl_iface_mask |= static_cast<int32_t>(WifiIfaceMode::IFACE_MODE_IBSS);
+ }
+ return aidl_iface_mask;
+}
+
+uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask) {
+ uint32_t legacy_filter_mask = 0;
+ if (aidl_filter_mask &
+ static_cast<int32_t>(IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE)) {
+ legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+ }
+ if (aidl_filter_mask & static_cast<int32_t>(IWifiChip::UsableChannelFilter::CONCURRENCY)) {
+ legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+ }
+ if (aidl_filter_mask & static_cast<int32_t>(IWifiChip::UsableChannelFilter::NAN_INSTANT_MODE)) {
+ legacy_filter_mask |= WIFI_USABLE_CHANNEL_FILTER_NAN_INSTANT_MODE;
+ }
+ return legacy_filter_mask;
+}
+
+bool convertLegacyWifiUsableChannelToAidl(
+ const legacy_hal::wifi_usable_channel& legacy_usable_channel,
+ WifiUsableChannel* aidl_usable_channel) {
+ if (!aidl_usable_channel) {
+ return false;
+ }
+ *aidl_usable_channel = {};
+ aidl_usable_channel->channel = legacy_usable_channel.freq;
+ aidl_usable_channel->channelBandwidth =
+ convertLegacyWifiChannelWidthToAidl(legacy_usable_channel.width);
+ aidl_usable_channel->ifaceModeMask =
+ convertLegacyWifiInterfaceModeToAidl(legacy_usable_channel.iface_mode_mask);
+
+ return true;
+}
+
+bool convertLegacyWifiUsableChannelsToAidl(
+ const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+ std::vector<WifiUsableChannel>* aidl_usable_channels) {
+ if (!aidl_usable_channels) {
+ return false;
+ }
+ *aidl_usable_channels = {};
+ for (const auto& legacy_usable_channel : legacy_usable_channels) {
+ WifiUsableChannel aidl_usable_channel;
+ if (!convertLegacyWifiUsableChannelToAidl(legacy_usable_channel, &aidl_usable_channel)) {
+ return false;
+ }
+ aidl_usable_channels->push_back(aidl_usable_channel);
+ }
+ return true;
+}
+
+bool convertLegacyWifiMacInfosToAidl(
+ const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* aidl_radio_mode_infos) {
+ if (!aidl_radio_mode_infos) {
+ return false;
+ }
+ *aidl_radio_mode_infos = {};
+
+ for (const auto& legacy_mac_info : legacy_mac_infos) {
+ IWifiChipEventCallback::RadioModeInfo aidl_radio_mode_info;
+ if (!convertLegacyWifiMacInfoToAidl(legacy_mac_info, &aidl_radio_mode_info)) {
+ return false;
+ }
+ aidl_radio_mode_infos->push_back(aidl_radio_mode_info);
+ }
+ return true;
+}
+
+bool convertLegacyStaIfaceFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set) {
+ if (!aidl_feature_set) {
+ return false;
+ }
+ *aidl_feature_set = 0;
+ for (const auto feature :
+ {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}) {
+ if (feature & legacy_feature_set) {
+ *aidl_feature_set |= static_cast<uint32_t>(convertLegacyStaIfaceFeatureToAidl(feature));
+ }
+ }
+ // There is no flag for this one in the legacy feature set. Adding it to the
+ // set because all the current devices support it.
+ *aidl_feature_set |= static_cast<uint32_t>(IWifiStaIface::FeatureSetMask::APF);
+ return true;
+}
+
+bool convertLegacyApfCapabilitiesToAidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+ StaApfPacketFilterCapabilities* aidl_caps) {
+ if (!aidl_caps) {
+ return false;
+ }
+ *aidl_caps = {};
+ aidl_caps->version = legacy_caps.version;
+ aidl_caps->maxLength = legacy_caps.max_len;
+ return true;
+}
+
+uint8_t convertAidlGscanReportEventFlagToLegacy(
+ StaBackgroundScanBucketEventReportSchemeMask aidl_flag) {
+ using AidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
+ switch (aidl_flag) {
+ case AidlFlag::EACH_SCAN:
+ return REPORT_EVENTS_EACH_SCAN;
+ case AidlFlag::FULL_RESULTS:
+ return REPORT_EVENTS_FULL_RESULTS;
+ case AidlFlag::NO_BATCH:
+ return REPORT_EVENTS_NO_BATCH;
+ };
+ CHECK(false);
+}
+
+StaScanDataFlagMask convertLegacyGscanDataFlagToAidl(uint8_t legacy_flag) {
+ switch (legacy_flag) {
+ case legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED:
+ return StaScanDataFlagMask::INTERRUPTED;
+ };
+ CHECK(false) << "Unknown legacy flag: " << legacy_flag;
+ // To silence the compiler warning about reaching the end of non-void
+ // function.
+ return {};
+}
+
+bool convertLegacyGscanCapabilitiesToAidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+ StaBackgroundScanCapabilities* aidl_caps) {
+ if (!aidl_caps) {
+ return false;
+ }
+ *aidl_caps = {};
+ aidl_caps->maxCacheSize = legacy_caps.max_scan_cache_size;
+ aidl_caps->maxBuckets = legacy_caps.max_scan_buckets;
+ aidl_caps->maxApCachePerScan = legacy_caps.max_ap_cache_per_scan;
+ aidl_caps->maxReportingThreshold = legacy_caps.max_scan_reporting_threshold;
+ return true;
+}
+
+legacy_hal::wifi_band convertAidlWifiBandToLegacy(WifiBand band) {
+ switch (band) {
+ case WifiBand::BAND_UNSPECIFIED:
+ return legacy_hal::WIFI_BAND_UNSPECIFIED;
+ case WifiBand::BAND_24GHZ:
+ return legacy_hal::WIFI_BAND_BG;
+ case WifiBand::BAND_5GHZ:
+ return legacy_hal::WIFI_BAND_A;
+ case WifiBand::BAND_5GHZ_DFS:
+ return legacy_hal::WIFI_BAND_A_DFS;
+ case WifiBand::BAND_5GHZ_WITH_DFS:
+ return legacy_hal::WIFI_BAND_A_WITH_DFS;
+ case WifiBand::BAND_24GHZ_5GHZ:
+ return legacy_hal::WIFI_BAND_ABG;
+ case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+ return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
+ default:
+ CHECK(false);
+ return {};
+ };
+}
+
+bool convertAidlGscanParamsToLegacy(const StaBackgroundScanParameters& aidl_scan_params,
+ legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
+ if (!legacy_scan_params) {
+ return false;
+ }
+ *legacy_scan_params = {};
+ legacy_scan_params->base_period = aidl_scan_params.basePeriodInMs;
+ legacy_scan_params->max_ap_per_scan = aidl_scan_params.maxApPerScan;
+ legacy_scan_params->report_threshold_percent = aidl_scan_params.reportThresholdPercent;
+ legacy_scan_params->report_threshold_num_scans = aidl_scan_params.reportThresholdNumScans;
+ if (aidl_scan_params.buckets.size() > MAX_BUCKETS) {
+ return false;
+ }
+ legacy_scan_params->num_buckets = aidl_scan_params.buckets.size();
+ for (uint32_t bucket_idx = 0; bucket_idx < aidl_scan_params.buckets.size(); bucket_idx++) {
+ const StaBackgroundScanBucketParameters& aidl_bucket_spec =
+ aidl_scan_params.buckets[bucket_idx];
+ legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec =
+ legacy_scan_params->buckets[bucket_idx];
+ if (aidl_bucket_spec.bucketIdx >= MAX_BUCKETS) {
+ return false;
+ }
+ legacy_bucket_spec.bucket = aidl_bucket_spec.bucketIdx;
+ legacy_bucket_spec.band = convertAidlWifiBandToLegacy(aidl_bucket_spec.band);
+ legacy_bucket_spec.period = aidl_bucket_spec.periodInMs;
+ legacy_bucket_spec.max_period = aidl_bucket_spec.exponentialMaxPeriodInMs;
+ legacy_bucket_spec.base = aidl_bucket_spec.exponentialBase;
+ legacy_bucket_spec.step_count = aidl_bucket_spec.exponentialStepCount;
+ legacy_bucket_spec.report_events = 0;
+ using AidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
+ for (const auto flag : {AidlFlag::EACH_SCAN, AidlFlag::FULL_RESULTS, AidlFlag::NO_BATCH}) {
+ if (aidl_bucket_spec.eventReportScheme &
+ static_cast<std::underlying_type<AidlFlag>::type>(flag)) {
+ legacy_bucket_spec.report_events |= convertAidlGscanReportEventFlagToLegacy(flag);
+ }
+ }
+ if (aidl_bucket_spec.frequencies.size() > MAX_CHANNELS) {
+ return false;
+ }
+ legacy_bucket_spec.num_channels = aidl_bucket_spec.frequencies.size();
+ for (uint32_t freq_idx = 0; freq_idx < aidl_bucket_spec.frequencies.size(); freq_idx++) {
+ legacy_bucket_spec.channels[freq_idx].channel = aidl_bucket_spec.frequencies[freq_idx];
+ }
+ }
+ return true;
+}
+
+bool convertLegacyIeToAidl(const legacy_hal::wifi_information_element& legacy_ie,
+ WifiInformationElement* aidl_ie) {
+ if (!aidl_ie) {
+ return false;
+ }
+ *aidl_ie = {};
+ aidl_ie->id = legacy_ie.id;
+ aidl_ie->data = std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
+ return true;
+}
+
+bool convertLegacyIeBlobToAidl(const uint8_t* ie_blob, uint32_t ie_blob_len,
+ std::vector<WifiInformationElement>* aidl_ies) {
+ if (!ie_blob || !aidl_ies) {
+ return false;
+ }
+ *aidl_ies = {};
+ const uint8_t* ies_begin = ie_blob;
+ const uint8_t* ies_end = ie_blob + ie_blob_len;
+ const uint8_t* next_ie = ies_begin;
+ using wifi_ie = legacy_hal::wifi_information_element;
+ constexpr size_t kIeHeaderLen = sizeof(wifi_ie);
+ // Each IE should at least have the header (i.e |id| & |len| fields).
+ while (next_ie + kIeHeaderLen <= ies_end) {
+ const wifi_ie& legacy_ie = (*reinterpret_cast<const wifi_ie*>(next_ie));
+ uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
+ if (next_ie + curr_ie_len > ies_end) {
+ LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie
+ << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end;
+ break;
+ }
+ WifiInformationElement aidl_ie;
+ if (!convertLegacyIeToAidl(legacy_ie, &aidl_ie)) {
+ LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len;
+ break;
+ }
+ aidl_ies->push_back(std::move(aidl_ie));
+ next_ie += curr_ie_len;
+ }
+ // Check if the blob has been fully consumed.
+ if (next_ie != ies_end) {
+ LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie
+ << ", IEs End: " << (void*)ies_end;
+ }
+ return true;
+}
+
+bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+ bool has_ie_data, StaScanResult* aidl_scan_result) {
+ if (!aidl_scan_result) {
+ return false;
+ }
+ *aidl_scan_result = {};
+ aidl_scan_result->timeStampInUs = legacy_scan_result.ts;
+ aidl_scan_result->ssid = std::vector<uint8_t>(
+ legacy_scan_result.ssid,
+ legacy_scan_result.ssid +
+ strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1));
+ 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->frequency = legacy_scan_result.channel;
+ aidl_scan_result->rssi = legacy_scan_result.rssi;
+ aidl_scan_result->beaconPeriodInMs = legacy_scan_result.beacon_period;
+ aidl_scan_result->capability = legacy_scan_result.capability;
+ if (has_ie_data) {
+ std::vector<WifiInformationElement> ies;
+ if (!convertLegacyIeBlobToAidl(reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
+ legacy_scan_result.ie_length, &ies)) {
+ return false;
+ }
+ aidl_scan_result->informationElements = std::move(ies);
+ }
+ return true;
+}
+
+bool convertLegacyCachedGscanResultsToAidl(
+ const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
+ StaScanData* aidl_scan_data) {
+ if (!aidl_scan_data) {
+ return false;
+ }
+ *aidl_scan_data = {};
+ int32_t flags = 0;
+ for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) {
+ if (legacy_cached_scan_result.flags & flag) {
+ flags |= static_cast<std::underlying_type<StaScanDataFlagMask>::type>(
+ convertLegacyGscanDataFlagToAidl(flag));
+ }
+ }
+ aidl_scan_data->flags = flags;
+ aidl_scan_data->bucketsScanned = legacy_cached_scan_result.buckets_scanned;
+
+ CHECK(legacy_cached_scan_result.num_results >= 0 &&
+ legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN);
+ std::vector<StaScanResult> aidl_scan_results;
+ for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) {
+ StaScanResult aidl_scan_result;
+ if (!convertLegacyGscanResultToAidl(legacy_cached_scan_result.results[result_idx], false,
+ &aidl_scan_result)) {
+ return false;
+ }
+ aidl_scan_results.push_back(aidl_scan_result);
+ }
+ aidl_scan_data->results = std::move(aidl_scan_results);
+ return true;
+}
+
+bool convertLegacyVectorOfCachedGscanResultsToAidl(
+ const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+ std::vector<StaScanData>* aidl_scan_datas) {
+ if (!aidl_scan_datas) {
+ return false;
+ }
+ *aidl_scan_datas = {};
+ for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) {
+ StaScanData aidl_scan_data;
+ if (!convertLegacyCachedGscanResultsToAidl(legacy_cached_scan_result, &aidl_scan_data)) {
+ return false;
+ }
+ aidl_scan_datas->push_back(aidl_scan_data);
+ }
+ return true;
+}
+
+WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToAidl(legacy_hal::wifi_tx_packet_fate fate) {
+ switch (fate) {
+ case legacy_hal::TX_PKT_FATE_ACKED:
+ return WifiDebugTxPacketFate::ACKED;
+ case legacy_hal::TX_PKT_FATE_SENT:
+ return WifiDebugTxPacketFate::SENT;
+ case legacy_hal::TX_PKT_FATE_FW_QUEUED:
+ return WifiDebugTxPacketFate::FW_QUEUED;
+ case legacy_hal::TX_PKT_FATE_FW_DROP_INVALID:
+ return WifiDebugTxPacketFate::FW_DROP_INVALID;
+ case legacy_hal::TX_PKT_FATE_FW_DROP_NOBUFS:
+ return WifiDebugTxPacketFate::FW_DROP_NOBUFS;
+ case legacy_hal::TX_PKT_FATE_FW_DROP_OTHER:
+ return WifiDebugTxPacketFate::FW_DROP_OTHER;
+ case legacy_hal::TX_PKT_FATE_DRV_QUEUED:
+ return WifiDebugTxPacketFate::DRV_QUEUED;
+ case legacy_hal::TX_PKT_FATE_DRV_DROP_INVALID:
+ return WifiDebugTxPacketFate::DRV_DROP_INVALID;
+ case legacy_hal::TX_PKT_FATE_DRV_DROP_NOBUFS:
+ return WifiDebugTxPacketFate::DRV_DROP_NOBUFS;
+ case legacy_hal::TX_PKT_FATE_DRV_DROP_OTHER:
+ return WifiDebugTxPacketFate::DRV_DROP_OTHER;
+ };
+ CHECK(false) << "Unknown legacy fate type: " << fate;
+}
+
+WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToAidl(legacy_hal::wifi_rx_packet_fate fate) {
+ switch (fate) {
+ case legacy_hal::RX_PKT_FATE_SUCCESS:
+ return WifiDebugRxPacketFate::SUCCESS;
+ case legacy_hal::RX_PKT_FATE_FW_QUEUED:
+ return WifiDebugRxPacketFate::FW_QUEUED;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_FILTER:
+ return WifiDebugRxPacketFate::FW_DROP_FILTER;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_INVALID:
+ return WifiDebugRxPacketFate::FW_DROP_INVALID;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_NOBUFS:
+ return WifiDebugRxPacketFate::FW_DROP_NOBUFS;
+ case legacy_hal::RX_PKT_FATE_FW_DROP_OTHER:
+ return WifiDebugRxPacketFate::FW_DROP_OTHER;
+ case legacy_hal::RX_PKT_FATE_DRV_QUEUED:
+ return WifiDebugRxPacketFate::DRV_QUEUED;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_FILTER:
+ return WifiDebugRxPacketFate::DRV_DROP_FILTER;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_INVALID:
+ return WifiDebugRxPacketFate::DRV_DROP_INVALID;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_NOBUFS:
+ return WifiDebugRxPacketFate::DRV_DROP_NOBUFS;
+ case legacy_hal::RX_PKT_FATE_DRV_DROP_OTHER:
+ return WifiDebugRxPacketFate::DRV_DROP_OTHER;
+ };
+ CHECK(false) << "Unknown legacy fate type: " << fate;
+}
+
+WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToAidl(
+ legacy_hal::frame_type type) {
+ switch (type) {
+ case legacy_hal::FRAME_TYPE_UNKNOWN:
+ return WifiDebugPacketFateFrameType::UNKNOWN;
+ case legacy_hal::FRAME_TYPE_ETHERNET_II:
+ return WifiDebugPacketFateFrameType::ETHERNET_II;
+ case legacy_hal::FRAME_TYPE_80211_MGMT:
+ return WifiDebugPacketFateFrameType::MGMT_80211;
+ };
+ CHECK(false) << "Unknown legacy frame type: " << type;
+}
+
+bool convertLegacyDebugPacketFateFrameToAidl(const legacy_hal::frame_info& legacy_frame,
+ WifiDebugPacketFateFrameInfo* aidl_frame) {
+ if (!aidl_frame) {
+ return false;
+ }
+ *aidl_frame = {};
+ aidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToAidl(legacy_frame.payload_type);
+ aidl_frame->frameLen = legacy_frame.frame_len;
+ aidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec;
+ aidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec;
+ const uint8_t* frame_begin =
+ reinterpret_cast<const uint8_t*>(legacy_frame.frame_content.ethernet_ii_bytes);
+ aidl_frame->frameContent =
+ std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len);
+ return true;
+}
+
+bool convertLegacyDebugTxPacketFateToAidl(const legacy_hal::wifi_tx_report& legacy_fate,
+ WifiDebugTxPacketFateReport* aidl_fate) {
+ if (!aidl_fate) {
+ return false;
+ }
+ *aidl_fate = {};
+ aidl_fate->fate = convertLegacyDebugTxPacketFateToAidl(legacy_fate.fate);
+ return convertLegacyDebugPacketFateFrameToAidl(legacy_fate.frame_inf, &aidl_fate->frameInfo);
+}
+
+bool convertLegacyVectorOfDebugTxPacketFateToAidl(
+ const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+ std::vector<WifiDebugTxPacketFateReport>* aidl_fates) {
+ if (!aidl_fates) {
+ return false;
+ }
+ *aidl_fates = {};
+ for (const auto& legacy_fate : legacy_fates) {
+ WifiDebugTxPacketFateReport aidl_fate;
+ if (!convertLegacyDebugTxPacketFateToAidl(legacy_fate, &aidl_fate)) {
+ return false;
+ }
+ aidl_fates->push_back(aidl_fate);
+ }
+ return true;
+}
+
+bool convertLegacyDebugRxPacketFateToAidl(const legacy_hal::wifi_rx_report& legacy_fate,
+ WifiDebugRxPacketFateReport* aidl_fate) {
+ if (!aidl_fate) {
+ return false;
+ }
+ *aidl_fate = {};
+ aidl_fate->fate = convertLegacyDebugRxPacketFateToAidl(legacy_fate.fate);
+ return convertLegacyDebugPacketFateFrameToAidl(legacy_fate.frame_inf, &aidl_fate->frameInfo);
+}
+
+bool convertLegacyVectorOfDebugRxPacketFateToAidl(
+ const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+ std::vector<WifiDebugRxPacketFateReport>* aidl_fates) {
+ if (!aidl_fates) {
+ return false;
+ }
+ *aidl_fates = {};
+ for (const auto& legacy_fate : legacy_fates) {
+ WifiDebugRxPacketFateReport aidl_fate;
+ if (!convertLegacyDebugRxPacketFateToAidl(legacy_fate, &aidl_fate)) {
+ return false;
+ }
+ aidl_fates->push_back(aidl_fate);
+ }
+ return true;
+}
+
+bool convertLegacyLinkLayerRadioStatsToAidl(
+ const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
+ StaLinkLayerRadioStats* aidl_radio_stat) {
+ if (!aidl_radio_stat) {
+ return false;
+ }
+ *aidl_radio_stat = {};
+
+ aidl_radio_stat->radioId = legacy_radio_stat.stats.radio;
+ aidl_radio_stat->onTimeInMs = legacy_radio_stat.stats.on_time;
+ aidl_radio_stat->txTimeInMs = legacy_radio_stat.stats.tx_time;
+ aidl_radio_stat->rxTimeInMs = legacy_radio_stat.stats.rx_time;
+ aidl_radio_stat->onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan;
+ aidl_radio_stat->txTimeInMsPerLevel = uintToIntVec(legacy_radio_stat.tx_time_per_levels);
+ aidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd;
+ aidl_radio_stat->onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan;
+ aidl_radio_stat->onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan;
+ aidl_radio_stat->onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan;
+ aidl_radio_stat->onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20;
+
+ std::vector<WifiChannelStats> aidl_channel_stats;
+
+ for (const auto& channel_stat : legacy_radio_stat.channel_stats) {
+ WifiChannelStats aidl_channel_stat;
+ aidl_channel_stat.onTimeInMs = channel_stat.on_time;
+ aidl_channel_stat.ccaBusyTimeInMs = channel_stat.cca_busy_time;
+ aidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20;
+ aidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq;
+ aidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0;
+ aidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1;
+ aidl_channel_stats.push_back(aidl_channel_stat);
+ }
+
+ aidl_radio_stat->channelStats = aidl_channel_stats;
+
+ return true;
+}
+
+bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
+ StaLinkLayerStats* aidl_stats) {
+ if (!aidl_stats) {
+ return false;
+ }
+ *aidl_stats = {};
+ std::vector<StaLinkLayerLinkStats> links;
+ // Iterate over each links
+ for (const auto& link : legacy_ml_stats.links) {
+ StaLinkLayerLinkStats linkStats = {};
+ linkStats.linkId = link.stat.link_id;
+ linkStats.radioId = link.stat.radio;
+ linkStats.frequencyMhz = link.stat.frequency;
+ linkStats.beaconRx = link.stat.beacon_rx;
+ linkStats.avgRssiMgmt = link.stat.rssi_mgmt;
+ linkStats.wmeBePktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+ linkStats.wmeBePktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+ linkStats.wmeBePktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+ linkStats.wmeBePktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_BE].retries;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+ linkStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+ linkStats.wmeBeContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+ linkStats.wmeBkPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+ linkStats.wmeBkPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+ linkStats.wmeBkPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+ linkStats.wmeBkPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_BK].retries;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+ linkStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+ linkStats.wmeBkContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+ linkStats.wmeViPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+ linkStats.wmeViPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+ linkStats.wmeViPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+ linkStats.wmeViPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_VI].retries;
+ linkStats.wmeViContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+ linkStats.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+ linkStats.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+ linkStats.wmeViContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+ linkStats.wmeVoPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+ linkStats.wmeVoPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+ linkStats.wmeVoPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+ linkStats.wmeVoPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_VO].retries;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+ linkStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+ linkStats.wmeVoContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+ linkStats.timeSliceDutyCycleInPercent = link.stat.time_slicing_duty_cycle_percent;
+ // peer info legacy_stats conversion.
+ std::vector<StaPeerInfo> aidl_peers_info_stats;
+ for (const auto& legacy_peer_info_stats : link.peers) {
+ StaPeerInfo aidl_peer_info_stats;
+ if (!convertLegacyPeerInfoStatsToAidl(legacy_peer_info_stats, &aidl_peer_info_stats)) {
+ return false;
+ }
+ aidl_peers_info_stats.push_back(aidl_peer_info_stats);
+ }
+ linkStats.peers = aidl_peers_info_stats;
+ // Push link stats to aidl stats.
+ links.push_back(linkStats);
+ }
+ aidl_stats->iface.links = links;
+ // radio legacy_stats conversion.
+ std::vector<StaLinkLayerRadioStats> aidl_radios_stats;
+ for (const auto& legacy_radio_stats : legacy_ml_stats.radios) {
+ StaLinkLayerRadioStats aidl_radio_stats;
+ if (!convertLegacyLinkLayerRadioStatsToAidl(legacy_radio_stats, &aidl_radio_stats)) {
+ return false;
+ }
+ aidl_radios_stats.push_back(aidl_radio_stats);
+ }
+ aidl_stats->radios = aidl_radios_stats;
+ aidl_stats->timeStampInMs = ::android::uptimeMillis();
+
+ return true;
+}
+
+bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
+ StaLinkLayerStats* aidl_stats) {
+ if (!aidl_stats) {
+ return false;
+ }
+ *aidl_stats = {};
+ std::vector<StaLinkLayerLinkStats> links;
+ StaLinkLayerLinkStats linkStats = {};
+ // iface legacy_stats conversion.
+ linkStats.linkId = 0;
+ linkStats.beaconRx = legacy_stats.iface.beacon_rx;
+ linkStats.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
+ linkStats.wmeBePktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+ linkStats.wmeBePktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+ linkStats.wmeBePktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+ linkStats.wmeBePktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+ linkStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+ linkStats.wmeBeContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+ linkStats.wmeBkPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+ linkStats.wmeBkPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+ linkStats.wmeBkPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+ linkStats.wmeBkPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+ linkStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+ linkStats.wmeBkContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+ linkStats.wmeViPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+ linkStats.wmeViPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+ linkStats.wmeViPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+ linkStats.wmeViPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
+ linkStats.wmeViContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+ linkStats.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+ linkStats.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+ linkStats.wmeViContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+ linkStats.wmeVoPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+ linkStats.wmeVoPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+ linkStats.wmeVoPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+ linkStats.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+ linkStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+ linkStats.wmeVoContentionTimeStats.contentionNumSamples =
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+ linkStats.timeSliceDutyCycleInPercent = legacy_stats.iface.info.time_slicing_duty_cycle_percent;
+ // peer info legacy_stats conversion.
+ std::vector<StaPeerInfo> aidl_peers_info_stats;
+ for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
+ StaPeerInfo aidl_peer_info_stats;
+ if (!convertLegacyPeerInfoStatsToAidl(legacy_peer_info_stats, &aidl_peer_info_stats)) {
+ return false;
+ }
+ aidl_peers_info_stats.push_back(aidl_peer_info_stats);
+ }
+ linkStats.peers = aidl_peers_info_stats;
+ links.push_back(linkStats);
+ aidl_stats->iface.links = links;
+ // radio legacy_stats conversion.
+ std::vector<StaLinkLayerRadioStats> aidl_radios_stats;
+ for (const auto& legacy_radio_stats : legacy_stats.radios) {
+ StaLinkLayerRadioStats aidl_radio_stats;
+ if (!convertLegacyLinkLayerRadioStatsToAidl(legacy_radio_stats, &aidl_radio_stats)) {
+ return false;
+ }
+ aidl_radios_stats.push_back(aidl_radio_stats);
+ }
+ aidl_stats->radios = aidl_radios_stats;
+ aidl_stats->timeStampInMs = ::android::uptimeMillis();
+ return true;
+}
+
+bool convertLegacyPeerInfoStatsToAidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+ StaPeerInfo* aidl_peer_info_stats) {
+ if (!aidl_peer_info_stats) {
+ return false;
+ }
+ *aidl_peer_info_stats = {};
+ aidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count;
+ aidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util;
+
+ std::vector<StaRateStat> aidlRateStats;
+ for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) {
+ StaRateStat rateStat;
+ if (!convertLegacyWifiRateInfoToAidl(legacy_rate_stats.rate, &rateStat.rateInfo)) {
+ return false;
+ }
+ rateStat.txMpdu = legacy_rate_stats.tx_mpdu;
+ rateStat.rxMpdu = legacy_rate_stats.rx_mpdu;
+ rateStat.mpduLost = legacy_rate_stats.mpdu_lost;
+ rateStat.retries = legacy_rate_stats.retries;
+ aidlRateStats.push_back(rateStat);
+ }
+ aidl_peer_info_stats->rateStats = aidlRateStats;
+ return true;
+}
+
+bool convertLegacyRoamingCapabilitiesToAidl(
+ const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+ StaRoamingCapabilities* aidl_caps) {
+ if (!aidl_caps) {
+ return false;
+ }
+ *aidl_caps = {};
+ aidl_caps->maxBlocklistSize = legacy_caps.max_blacklist_size;
+ aidl_caps->maxAllowlistSize = legacy_caps.max_whitelist_size;
+ return true;
+}
+
+bool convertAidlRoamingConfigToLegacy(const StaRoamingConfig& aidl_config,
+ legacy_hal::wifi_roaming_config* legacy_config) {
+ if (!legacy_config) {
+ return false;
+ }
+ *legacy_config = {};
+ if (aidl_config.bssidBlocklist.size() > MAX_BLACKLIST_BSSID ||
+ aidl_config.ssidAllowlist.size() > MAX_WHITELIST_SSID) {
+ return false;
+ }
+ legacy_config->num_blacklist_bssid = aidl_config.bssidBlocklist.size();
+ uint32_t i = 0;
+ for (const auto& bssid : aidl_config.bssidBlocklist) {
+ CHECK(bssid.data.size() == sizeof(legacy_hal::mac_addr));
+ memcpy(legacy_config->blacklist_bssid[i++], bssid.data.data(), bssid.data.size());
+ }
+ legacy_config->num_whitelist_ssid = aidl_config.ssidAllowlist.size();
+ i = 0;
+ for (const auto& ssid : aidl_config.ssidAllowlist) {
+ CHECK(ssid.data.size() <= sizeof(legacy_hal::ssid_t::ssid_str));
+ legacy_config->whitelist_ssid[i].length = ssid.data.size();
+ memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data.data(), ssid.data.size());
+ i++;
+ }
+ return true;
+}
+
+legacy_hal::fw_roaming_state_t convertAidlRoamingStateToLegacy(StaRoamingState state) {
+ switch (state) {
+ case StaRoamingState::ENABLED:
+ return legacy_hal::ROAMING_ENABLE;
+ case StaRoamingState::DISABLED:
+ return legacy_hal::ROAMING_DISABLE;
+ };
+ CHECK(false);
+}
+
+legacy_hal::NanMatchAlg convertAidlNanMatchAlgToLegacy(NanMatchAlg type) {
+ switch (type) {
+ case NanMatchAlg::MATCH_ONCE:
+ return legacy_hal::NAN_MATCH_ALG_MATCH_ONCE;
+ case NanMatchAlg::MATCH_CONTINUOUS:
+ return legacy_hal::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+ case NanMatchAlg::MATCH_NEVER:
+ return legacy_hal::NAN_MATCH_ALG_MATCH_NEVER;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanPublishType convertAidlNanPublishTypeToLegacy(NanPublishType type) {
+ switch (type) {
+ case NanPublishType::UNSOLICITED:
+ return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
+ case NanPublishType::SOLICITED:
+ return legacy_hal::NAN_PUBLISH_TYPE_SOLICITED;
+ case NanPublishType::UNSOLICITED_SOLICITED:
+ return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanTxType convertAidlNanTxTypeToLegacy(NanTxType type) {
+ switch (type) {
+ case NanTxType::BROADCAST:
+ return legacy_hal::NAN_TX_TYPE_BROADCAST;
+ case NanTxType::UNICAST:
+ return legacy_hal::NAN_TX_TYPE_UNICAST;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanSubscribeType convertAidlNanSubscribeTypeToLegacy(NanSubscribeType type) {
+ switch (type) {
+ case NanSubscribeType::PASSIVE:
+ return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
+ case NanSubscribeType::ACTIVE:
+ return legacy_hal::NAN_SUBSCRIBE_TYPE_ACTIVE;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanSRFType convertAidlNanSrfTypeToLegacy(NanSrfType type) {
+ switch (type) {
+ case NanSrfType::BLOOM_FILTER:
+ return legacy_hal::NAN_SRF_ATTR_BLOOM_FILTER;
+ case NanSrfType::PARTIAL_MAC_ADDR:
+ return legacy_hal::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanDataPathChannelCfg convertAidlNanDataPathChannelCfgToLegacy(
+ NanDataPathChannelCfg type) {
+ switch (type) {
+ case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED:
+ return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED;
+ case NanDataPathChannelCfg::REQUEST_CHANNEL_SETUP:
+ return legacy_hal::NAN_DP_REQUEST_CHANNEL_SETUP;
+ case NanDataPathChannelCfg::FORCE_CHANNEL_SETUP:
+ return legacy_hal::NAN_DP_FORCE_CHANNEL_SETUP;
+ }
+ CHECK(false);
+}
+
+legacy_hal::NanPairingRequestType convertAidlNanPairingRequestTypeToLegacy(
+ NanPairingRequestType type) {
+ switch (type) {
+ case NanPairingRequestType::NAN_PAIRING_SETUP:
+ return legacy_hal::NAN_PAIRING_SETUP;
+ case NanPairingRequestType::NAN_PAIRING_VERIFICATION:
+ return legacy_hal::NAN_PAIRING_VERIFICATION;
+ }
+ LOG(FATAL);
+}
+
+NanPairingRequestType convertLegacyNanPairingRequestTypeToAidl(
+ legacy_hal::NanPairingRequestType type) {
+ switch (type) {
+ case legacy_hal::NAN_PAIRING_SETUP:
+ return NanPairingRequestType::NAN_PAIRING_SETUP;
+ case legacy_hal::NAN_PAIRING_VERIFICATION:
+ return NanPairingRequestType::NAN_PAIRING_VERIFICATION;
+ }
+ LOG(FATAL);
+}
+
+legacy_hal::NanAkm convertAidlAkmTypeToLegacy(NanPairingAkm type) {
+ switch (type) {
+ case NanPairingAkm::SAE:
+ return legacy_hal::SAE;
+ case NanPairingAkm::PASN:
+ return legacy_hal::PASN;
+ }
+ LOG(FATAL);
+}
+
+NanPairingAkm convertLegacyAkmTypeToAidl(legacy_hal::NanAkm type) {
+ switch (type) {
+ case legacy_hal::SAE:
+ return NanPairingAkm::SAE;
+ case legacy_hal::PASN:
+ return NanPairingAkm::PASN;
+ }
+ LOG(FATAL);
+}
+
+uint16_t convertAidlBootstrappingMethodToLegacy(NanBootstrappingMethod type) {
+ switch (type) {
+ case NanBootstrappingMethod::BOOTSTRAPPING_OPPORTUNISTIC_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_OPPORTUNISTIC_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_QR_DISPLAY_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_QR_DISPLAY_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_NFC_TAG_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_NFC_TAG_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_QR_SCAN_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_QR_SCAN_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_NFC_READER_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_NFC_READER_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_SERVICE_MANAGED_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_SERVICE_MANAGED_MASK;
+ case NanBootstrappingMethod::BOOTSTRAPPING_HANDSHAKE_SHIP_MASK:
+ return NAN_PAIRING_BOOTSTRAPPING_HANDSHAKE_SHIP_MASK;
+ }
+ LOG(FATAL);
+}
+
+NanBootstrappingMethod convertLegacyBootstrappingMethodToAidl(uint16_t type) {
+ switch (type) {
+ case NAN_PAIRING_BOOTSTRAPPING_OPPORTUNISTIC_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_OPPORTUNISTIC_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_DISPLAY_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_DISPLAY_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_QR_DISPLAY_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_QR_DISPLAY_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_NFC_TAG_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_NFC_TAG_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_PIN_CODE_KEYPAD_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_PASSPHRASE_KEYPAD_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_QR_SCAN_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_QR_SCAN_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_NFC_READER_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_NFC_READER_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_SERVICE_MANAGED_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_SERVICE_MANAGED_MASK;
+ case NAN_PAIRING_BOOTSTRAPPING_HANDSHAKE_SHIP_MASK:
+ return NanBootstrappingMethod::BOOTSTRAPPING_HANDSHAKE_SHIP_MASK;
+ }
+ LOG(FATAL);
+ return {};
+}
+
+bool covertAidlPairingConfigToLegacy(const NanPairingConfig& aidl_config,
+ legacy_hal::NanPairingConfig* legacy_config) {
+ if (!legacy_config) {
+ LOG(ERROR) << "covertAidlPairingConfigToLegacy: legacy_config is null";
+ return false;
+ }
+ legacy_config->enable_pairing_setup = aidl_config.enablePairingSetup ? 0x1 : 0x0;
+ legacy_config->enable_pairing_cache = aidl_config.enablePairingCache ? 0x1 : 0x0;
+ legacy_config->enable_pairing_verification = aidl_config.enablePairingVerification ? 0x1 : 0x0;
+ legacy_config->supported_bootstrapping_methods = aidl_config.supportedBootstrappingMethods;
+ return true;
+}
+
+bool convertLegacyPairingConfigToAidl(const legacy_hal::NanPairingConfig& legacy_config,
+ NanPairingConfig* aidl_config) {
+ if (!aidl_config) {
+ LOG(ERROR) << "convertLegacyPairingConfigToAidl: aidl_nira is null";
+ return false;
+ }
+ *aidl_config = {};
+ aidl_config->enablePairingSetup = legacy_config.enable_pairing_setup == 0x1;
+ aidl_config->enablePairingCache = legacy_config.enable_pairing_cache == 0x1;
+ aidl_config->enablePairingVerification = legacy_config.enable_pairing_verification == 0x1;
+ aidl_config->supportedBootstrappingMethods = legacy_config.supported_bootstrapping_methods;
+ return true;
+}
+
+bool convertLegacyNiraToAidl(const legacy_hal::NanIdentityResolutionAttribute& legacy_nira,
+ NanIdentityResolutionAttribute* aidl_nira) {
+ if (!aidl_nira) {
+ LOG(ERROR) << "convertLegacyNiraToAidl: aidl_nira is null";
+ return false;
+ }
+ *aidl_nira = {};
+ aidl_nira->nonce = std::array<uint8_t, 8>();
+ std::copy(legacy_nira.nonce, legacy_nira.nonce + 8, std::begin(aidl_nira->nonce));
+ aidl_nira->tag = std::array<uint8_t, 8>();
+ std::copy(legacy_nira.tag, legacy_nira.tag + 8, std::begin(aidl_nira->tag));
+ return true;
+}
+
+bool convertLegacyNpsaToAidl(const legacy_hal::NpkSecurityAssociation& legacy_npsa,
+ NpkSecurityAssociation* aidl_npsa) {
+ if (!aidl_npsa) {
+ LOG(ERROR) << "convertLegacyNiraToAidl: aidl_nira is null";
+ return false;
+ }
+ *aidl_npsa = {};
+ aidl_npsa->peerNanIdentityKey = std::array<uint8_t, 16>();
+ std::copy(legacy_npsa.peer_nan_identity_key, legacy_npsa.peer_nan_identity_key + 16,
+ std::begin(aidl_npsa->peerNanIdentityKey));
+ aidl_npsa->localNanIdentityKey = std::array<uint8_t, 16>();
+ std::copy(legacy_npsa.local_nan_identity_key, legacy_npsa.local_nan_identity_key + 16,
+ std::begin(aidl_npsa->localNanIdentityKey));
+ aidl_npsa->npk = std::array<uint8_t, 32>();
+ std::copy(legacy_npsa.npk.pmk, legacy_npsa.npk.pmk + 32, std::begin(aidl_npsa->npk));
+ aidl_npsa->akm = convertLegacyAkmTypeToAidl(legacy_npsa.akm);
+ aidl_npsa->cipherType = (NanCipherSuiteType)legacy_npsa.cipher_type;
+ return true;
+}
+
+NanStatusCode convertLegacyNanStatusTypeToAidl(legacy_hal::NanStatusType type) {
+ switch (type) {
+ case legacy_hal::NAN_STATUS_SUCCESS:
+ return NanStatusCode::SUCCESS;
+ case legacy_hal::NAN_STATUS_INTERNAL_FAILURE:
+ return NanStatusCode::INTERNAL_FAILURE;
+ case legacy_hal::NAN_STATUS_PROTOCOL_FAILURE:
+ return NanStatusCode::PROTOCOL_FAILURE;
+ case legacy_hal::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID:
+ return NanStatusCode::INVALID_SESSION_ID;
+ case legacy_hal::NAN_STATUS_NO_RESOURCE_AVAILABLE:
+ return NanStatusCode::NO_RESOURCES_AVAILABLE;
+ case legacy_hal::NAN_STATUS_INVALID_PARAM:
+ return NanStatusCode::INVALID_ARGS;
+ case legacy_hal::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID:
+ return NanStatusCode::INVALID_PEER_ID;
+ case legacy_hal::NAN_STATUS_INVALID_NDP_ID:
+ return NanStatusCode::INVALID_NDP_ID;
+ case legacy_hal::NAN_STATUS_NAN_NOT_ALLOWED:
+ return NanStatusCode::NAN_NOT_ALLOWED;
+ case legacy_hal::NAN_STATUS_NO_OTA_ACK:
+ return NanStatusCode::NO_OTA_ACK;
+ case legacy_hal::NAN_STATUS_ALREADY_ENABLED:
+ return NanStatusCode::ALREADY_ENABLED;
+ case legacy_hal::NAN_STATUS_FOLLOWUP_QUEUE_FULL:
+ return NanStatusCode::FOLLOWUP_TX_QUEUE_FULL;
+ case legacy_hal::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED:
+ return NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+ case legacy_hal::NAN_STATUS_INVALID_PAIRING_ID:
+ return NanStatusCode::INVALID_PAIRING_ID;
+ case legacy_hal::NAN_STATUS_INVALID_BOOTSTRAPPING_ID:
+ return NanStatusCode::INVALID_BOOTSTRAPPING_ID;
+ case legacy_hal::NAN_STATUS_REDUNDANT_REQUEST:
+ return NanStatusCode::REDUNDANT_REQUEST;
+ case legacy_hal::NAN_STATUS_NOT_SUPPORTED:
+ return NanStatusCode::NOT_SUPPORTED;
+ case legacy_hal::NAN_STATUS_NO_CONNECTION:
+ return NanStatusCode::NO_CONNECTION;
+ }
+ CHECK(false);
+}
+
+void convertToNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+ NanStatus* nanStatus) {
+ nanStatus->status = convertLegacyNanStatusTypeToAidl(type);
+ nanStatus->description = safeConvertChar(str, max_len);
+}
+
+bool convertAidlNanEnableRequestToLegacy(const NanEnableRequest& aidl_request1,
+ const NanConfigRequestSupplemental& aidl_request2,
+ legacy_hal::NanEnableRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: null legacy_request";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->config_2dot4g_support = 1;
+ legacy_request->support_2dot4g_val =
+ aidl_request1.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_support_5g = 1;
+ legacy_request->support_5g_val =
+ aidl_request1.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ legacy_request->config_hop_count_limit = 1;
+ legacy_request->hop_count_limit_val = aidl_request1.hopCountMax;
+ legacy_request->master_pref = aidl_request1.configParams.masterPref;
+ legacy_request->discovery_indication_cfg = 0;
+ legacy_request->discovery_indication_cfg |=
+ aidl_request1.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ aidl_request1.configParams.disableStartedClusterIndication ? 0x2 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ aidl_request1.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
+ legacy_request->config_sid_beacon = 1;
+ if (aidl_request1.configParams.numberOfPublishServiceIdsInBeacon < 0) {
+ LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: "
+ "numberOfPublishServiceIdsInBeacon < 0";
+ return false;
+ }
+ legacy_request->sid_beacon_val =
+ (aidl_request1.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+ (aidl_request1.configParams.numberOfPublishServiceIdsInBeacon << 1);
+ legacy_request->config_subscribe_sid_beacon = 1;
+ if (aidl_request1.configParams.numberOfSubscribeServiceIdsInBeacon < 0) {
+ LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: "
+ "numberOfSubscribeServiceIdsInBeacon < 0";
+ return false;
+ }
+ legacy_request->subscribe_sid_beacon_val =
+ (aidl_request1.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+ (aidl_request1.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
+ legacy_request->config_rssi_window_size = 1;
+ legacy_request->rssi_window_size_val = aidl_request1.configParams.rssiWindowSize;
+ legacy_request->config_disc_mac_addr_randomization = 1;
+ legacy_request->disc_mac_addr_rand_interval_sec =
+ aidl_request1.configParams.macAddressRandomizationIntervalSec;
+ legacy_request->config_2dot4g_rssi_close = 1;
+ if (aidl_request1.configParams.bandSpecificConfig.size() != 3) {
+ LOG(ERROR) << "convertAidlNanEnableRequestToLegacy: "
+ "bandSpecificConfig.size() != 3";
+ return false;
+ }
+ legacy_request->rssi_close_2dot4g_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .rssiClose;
+ legacy_request->config_2dot4g_rssi_middle = 1;
+ legacy_request->rssi_middle_2dot4g_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .rssiMiddle;
+ legacy_request->config_2dot4g_rssi_proximity = 1;
+ legacy_request->rssi_proximity_2dot4g_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .rssiCloseProximity;
+ legacy_request->config_scan_params = 1;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .scanPeriodSec;
+ legacy_request->config_dw.config_2dot4g_dw_band =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_2dot4g_interval_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal;
+ legacy_request->config_5g_rssi_close = 1;
+ legacy_request->rssi_close_5g_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiClose;
+ legacy_request->config_5g_rssi_middle = 1;
+ legacy_request->rssi_middle_5g_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiMiddle;
+ legacy_request->config_5g_rssi_close_proximity = 1;
+ legacy_request->rssi_close_proximity_5g_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiCloseProximity;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .scanPeriodSec;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .scanPeriodSec;
+ legacy_request->config_dw.config_5g_dw_band =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_5g_interval_val =
+ aidl_request1.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal;
+ if (aidl_request1.debugConfigs.validClusterIdVals) {
+ legacy_request->cluster_low = aidl_request1.debugConfigs.clusterIdBottomRangeVal;
+ legacy_request->cluster_high = aidl_request1.debugConfigs.clusterIdTopRangeVal;
+ } else { // need 'else' since not configurable in legacy HAL
+ legacy_request->cluster_low = 0x0000;
+ legacy_request->cluster_high = 0xFFFF;
+ }
+ legacy_request->config_intf_addr = aidl_request1.debugConfigs.validIntfAddrVal;
+ memcpy(legacy_request->intf_addr_val, aidl_request1.debugConfigs.intfAddrVal.data(), 6);
+ legacy_request->config_oui = aidl_request1.debugConfigs.validOuiVal;
+ legacy_request->oui_val = aidl_request1.debugConfigs.ouiVal;
+ legacy_request->config_random_factor_force =
+ aidl_request1.debugConfigs.validRandomFactorForceVal;
+ legacy_request->random_factor_force_val = aidl_request1.debugConfigs.randomFactorForceVal;
+ legacy_request->config_hop_count_force = aidl_request1.debugConfigs.validHopCountForceVal;
+ legacy_request->hop_count_force_val = aidl_request1.debugConfigs.hopCountForceVal;
+ legacy_request->config_24g_channel = aidl_request1.debugConfigs.validDiscoveryChannelVal;
+ legacy_request->channel_24g_val =
+ aidl_request1.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_5g_channel = aidl_request1.debugConfigs.validDiscoveryChannelVal;
+ legacy_request->channel_5g_val =
+ aidl_request1.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ legacy_request->config_2dot4g_beacons = aidl_request1.debugConfigs.validUseBeaconsInBandVal;
+ legacy_request->beacon_2dot4g_val =
+ aidl_request1.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_5g_beacons = aidl_request1.debugConfigs.validUseBeaconsInBandVal;
+ legacy_request->beacon_5g_val =
+ aidl_request1.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+ legacy_request->config_2dot4g_sdf = aidl_request1.debugConfigs.validUseSdfInBandVal;
+ legacy_request->sdf_2dot4g_val =
+ aidl_request1.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+ legacy_request->config_5g_sdf = aidl_request1.debugConfigs.validUseSdfInBandVal;
+ legacy_request->sdf_5g_val =
+ aidl_request1.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+
+ legacy_request->config_discovery_beacon_int = 1;
+ legacy_request->discovery_beacon_interval = aidl_request2.discoveryBeaconIntervalMs;
+ legacy_request->config_nss = 1;
+ legacy_request->nss = aidl_request2.numberOfSpatialStreamsInDiscovery;
+ legacy_request->config_dw_early_termination = 1;
+ legacy_request->enable_dw_termination = aidl_request2.enableDiscoveryWindowEarlyTermination;
+ legacy_request->config_enable_ranging = 1;
+ legacy_request->enable_ranging = aidl_request2.enableRanging;
+
+ legacy_request->config_enable_instant_mode = 1;
+ legacy_request->enable_instant_mode = aidl_request2.enableInstantCommunicationMode;
+ legacy_request->config_instant_mode_channel = 1;
+ legacy_request->instant_mode_channel = aidl_request2.instantModeChannel;
+
+ return true;
+}
+
+bool convertAidlNanConfigRequestToLegacy(const NanConfigRequest& aidl_request1,
+ const NanConfigRequestSupplemental& aidl_request2,
+ legacy_hal::NanConfigRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanConfigRequestToLegacy: null legacy_request";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->master_pref = aidl_request1.masterPref;
+ legacy_request->discovery_indication_cfg = 0;
+ legacy_request->discovery_indication_cfg |=
+ aidl_request1.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ aidl_request1.disableStartedClusterIndication ? 0x2 : 0x0;
+ legacy_request->discovery_indication_cfg |=
+ aidl_request1.disableJoinedClusterIndication ? 0x4 : 0x0;
+ legacy_request->config_sid_beacon = 1;
+ if (aidl_request1.numberOfPublishServiceIdsInBeacon < 0) {
+ LOG(ERROR) << "convertAidlNanConfigRequestToLegacy: "
+ "numberOfPublishServiceIdsInBeacon < 0";
+ return false;
+ }
+ legacy_request->sid_beacon = (aidl_request1.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+ (aidl_request1.numberOfPublishServiceIdsInBeacon << 1);
+ legacy_request->config_subscribe_sid_beacon = 1;
+ if (aidl_request1.numberOfSubscribeServiceIdsInBeacon < 0) {
+ LOG(ERROR) << "convertAidlNanConfigRequestToLegacy: "
+ "numberOfSubscribeServiceIdsInBeacon < 0";
+ return false;
+ }
+ legacy_request->subscribe_sid_beacon_val =
+ (aidl_request1.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+ (aidl_request1.numberOfSubscribeServiceIdsInBeacon << 1);
+ legacy_request->config_rssi_window_size = 1;
+ legacy_request->rssi_window_size_val = aidl_request1.rssiWindowSize;
+ legacy_request->config_disc_mac_addr_randomization = 1;
+ legacy_request->disc_mac_addr_rand_interval_sec =
+ aidl_request1.macAddressRandomizationIntervalSec;
+
+ legacy_request->config_scan_params = 1;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec;
+ legacy_request->config_dw.config_2dot4g_dw_band =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_2dot4g_interval_val =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+ .discoveryWindowIntervalVal;
+
+ legacy_request->config_5g_rssi_close_proximity = 1;
+ legacy_request->rssi_close_proximity_5g_val =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .rssiCloseProximity;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+ legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+ legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+ legacy_request->config_dw.config_5g_dw_band =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .validDiscoveryWindowIntervalVal;
+ legacy_request->config_dw.dw_5g_interval_val =
+ aidl_request1.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+ .discoveryWindowIntervalVal;
+
+ legacy_request->config_discovery_beacon_int = 1;
+ legacy_request->discovery_beacon_interval = aidl_request2.discoveryBeaconIntervalMs;
+ legacy_request->config_nss = 1;
+ legacy_request->nss = aidl_request2.numberOfSpatialStreamsInDiscovery;
+ legacy_request->config_dw_early_termination = 1;
+ legacy_request->enable_dw_termination = aidl_request2.enableDiscoveryWindowEarlyTermination;
+ legacy_request->config_enable_ranging = 1;
+ legacy_request->enable_ranging = aidl_request2.enableRanging;
+
+ legacy_request->config_enable_instant_mode = 1;
+ legacy_request->enable_instant_mode = aidl_request2.enableInstantCommunicationMode;
+ legacy_request->config_instant_mode_channel = 1;
+ legacy_request->instant_mode_channel = aidl_request2.instantModeChannel;
+ legacy_request->config_cluster_id = 1;
+ legacy_request->cluster_id_val = aidl_request2.clusterId;
+
+ return true;
+}
+
+bool convertAidlNanPublishRequestToLegacy(const NanPublishRequest& aidl_request,
+ legacy_hal::NanPublishRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: null legacy_request";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->publish_id = static_cast<uint8_t>(aidl_request.baseConfigs.sessionId);
+ legacy_request->ttl = aidl_request.baseConfigs.ttlSec;
+ legacy_request->period = aidl_request.baseConfigs.discoveryWindowPeriod;
+ legacy_request->publish_count = aidl_request.baseConfigs.discoveryCount;
+ legacy_request->service_name_len = aidl_request.baseConfigs.serviceName.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: service_name_len "
+ "too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, aidl_request.baseConfigs.serviceName.data(),
+ legacy_request->service_name_len);
+ legacy_request->publish_match_indicator =
+ convertAidlNanMatchAlgToLegacy(aidl_request.baseConfigs.discoveryMatchIndicator);
+ legacy_request->service_specific_info_len = aidl_request.baseConfigs.serviceSpecificInfo.size();
+ if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+ "service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_specific_info,
+ aidl_request.baseConfigs.serviceSpecificInfo.data(),
+ legacy_request->service_specific_info_len);
+ legacy_request->sdea_service_specific_info_len =
+ aidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+ if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+ "sdea_service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->sdea_service_specific_info,
+ aidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
+ legacy_request->sdea_service_specific_info_len);
+ legacy_request->rx_match_filter_len = aidl_request.baseConfigs.rxMatchFilter.size();
+ if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+ "rx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->rx_match_filter, aidl_request.baseConfigs.rxMatchFilter.data(),
+ legacy_request->rx_match_filter_len);
+ legacy_request->tx_match_filter_len = aidl_request.baseConfigs.txMatchFilter.size();
+ if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+ "tx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->tx_match_filter, aidl_request.baseConfigs.txMatchFilter.data(),
+ legacy_request->tx_match_filter_len);
+ legacy_request->rssi_threshold_flag = aidl_request.baseConfigs.useRssiThreshold;
+ legacy_request->recv_indication_cfg = 0;
+ legacy_request->recv_indication_cfg |=
+ aidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ aidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ aidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+ legacy_request->recv_indication_cfg |= 0x8;
+ legacy_request->cipher_type = (unsigned int)aidl_request.baseConfigs.securityConfig.cipherType;
+
+ legacy_request->scid_len = aidl_request.baseConfigs.securityConfig.scid.size();
+ if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: scid_len too large";
+ return false;
+ }
+ memcpy(legacy_request->scid, aidl_request.baseConfigs.securityConfig.scid.data(),
+ legacy_request->scid_len);
+
+ if (aidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len =
+ aidl_request.baseConfigs.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk,
+ aidl_request.baseConfigs.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (aidl_request.baseConfigs.securityConfig.securityType ==
+ NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ aidl_request.baseConfigs.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ aidl_request.baseConfigs.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->sdea_params.security_cfg =
+ (aidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+
+ legacy_request->sdea_params.ranging_state = aidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_ENABLE
+ : legacy_hal::NAN_RANGING_DISABLE;
+ legacy_request->ranging_cfg.ranging_interval_msec = aidl_request.baseConfigs.rangingIntervalMs;
+ legacy_request->ranging_cfg.config_ranging_indications =
+ aidl_request.baseConfigs.configRangingIndications;
+ legacy_request->ranging_cfg.distance_ingress_mm =
+ aidl_request.baseConfigs.distanceIngressCm * 10;
+ legacy_request->ranging_cfg.distance_egress_mm = aidl_request.baseConfigs.distanceEgressCm * 10;
+ legacy_request->ranging_auto_response = aidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+ : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+ legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+ legacy_request->publish_type = convertAidlNanPublishTypeToLegacy(aidl_request.publishType);
+ legacy_request->tx_type = convertAidlNanTxTypeToLegacy(aidl_request.txType);
+ legacy_request->service_responder_policy = aidl_request.autoAcceptDataPathRequests
+ ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL
+ : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
+ memcpy(legacy_request->nan_identity_key, aidl_request.identityKey.data(), NAN_IDENTITY_KEY_LEN);
+ if (!covertAidlPairingConfigToLegacy(aidl_request.pairingConfig,
+ &legacy_request->nan_pairing_config)) {
+ LOG(ERROR) << "convertAidlNanPublishRequestToLegacy: invalid pairing config";
+ return false;
+ }
+ legacy_request->enable_suspendability = aidl_request.baseConfigs.enableSessionSuspendability;
+
+ return true;
+}
+
+bool convertAidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& aidl_request,
+ legacy_hal::NanSubscribeRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->subscribe_id = static_cast<uint8_t>(aidl_request.baseConfigs.sessionId);
+ legacy_request->ttl = aidl_request.baseConfigs.ttlSec;
+ legacy_request->period = aidl_request.baseConfigs.discoveryWindowPeriod;
+ legacy_request->subscribe_count = aidl_request.baseConfigs.discoveryCount;
+ legacy_request->service_name_len = aidl_request.baseConfigs.serviceName.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, aidl_request.baseConfigs.serviceName.data(),
+ legacy_request->service_name_len);
+ legacy_request->subscribe_match_indicator =
+ convertAidlNanMatchAlgToLegacy(aidl_request.baseConfigs.discoveryMatchIndicator);
+ legacy_request->service_specific_info_len = aidl_request.baseConfigs.serviceSpecificInfo.size();
+ if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_specific_info,
+ aidl_request.baseConfigs.serviceSpecificInfo.data(),
+ legacy_request->service_specific_info_len);
+ legacy_request->sdea_service_specific_info_len =
+ aidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+ if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "sdea_service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->sdea_service_specific_info,
+ aidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
+ legacy_request->sdea_service_specific_info_len);
+ legacy_request->rx_match_filter_len = aidl_request.baseConfigs.rxMatchFilter.size();
+ if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "rx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->rx_match_filter, aidl_request.baseConfigs.rxMatchFilter.data(),
+ legacy_request->rx_match_filter_len);
+ legacy_request->tx_match_filter_len = aidl_request.baseConfigs.txMatchFilter.size();
+ if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "tx_match_filter_len too large";
+ return false;
+ }
+ memcpy(legacy_request->tx_match_filter, aidl_request.baseConfigs.txMatchFilter.data(),
+ legacy_request->tx_match_filter_len);
+ legacy_request->rssi_threshold_flag = aidl_request.baseConfigs.useRssiThreshold;
+ legacy_request->recv_indication_cfg = 0;
+ legacy_request->recv_indication_cfg |=
+ aidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ aidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+ legacy_request->recv_indication_cfg |=
+ aidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+ legacy_request->cipher_type = (unsigned int)aidl_request.baseConfigs.securityConfig.cipherType;
+ if (aidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len =
+ aidl_request.baseConfigs.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk,
+ aidl_request.baseConfigs.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (aidl_request.baseConfigs.securityConfig.securityType ==
+ NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ aidl_request.baseConfigs.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ aidl_request.baseConfigs.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->sdea_params.security_cfg =
+ (aidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->sdea_params.ranging_state = aidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_ENABLE
+ : legacy_hal::NAN_RANGING_DISABLE;
+ legacy_request->ranging_cfg.ranging_interval_msec = aidl_request.baseConfigs.rangingIntervalMs;
+ legacy_request->ranging_cfg.config_ranging_indications =
+ aidl_request.baseConfigs.configRangingIndications;
+ legacy_request->ranging_cfg.distance_ingress_mm =
+ aidl_request.baseConfigs.distanceIngressCm * 10;
+ legacy_request->ranging_cfg.distance_egress_mm = aidl_request.baseConfigs.distanceEgressCm * 10;
+ legacy_request->ranging_auto_response = aidl_request.baseConfigs.rangingRequired
+ ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+ : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+ legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+ legacy_request->subscribe_type =
+ convertAidlNanSubscribeTypeToLegacy(aidl_request.subscribeType);
+ legacy_request->serviceResponseFilter = convertAidlNanSrfTypeToLegacy(aidl_request.srfType);
+ legacy_request->serviceResponseInclude = aidl_request.srfRespondIfInAddressSet
+ ? legacy_hal::NAN_SRF_INCLUDE_RESPOND
+ : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+ legacy_request->useServiceResponseFilter =
+ aidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF;
+ legacy_request->ssiRequiredForMatchIndication =
+ aidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
+ : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+ legacy_request->num_intf_addr_present = aidl_request.intfAddr.size();
+ if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: "
+ "num_intf_addr_present - too many";
+ return false;
+ }
+ for (int i = 0; i < legacy_request->num_intf_addr_present; i++) {
+ memcpy(legacy_request->intf_addr[i], aidl_request.intfAddr[i].data.data(), 6);
+ }
+ memcpy(legacy_request->nan_identity_key, aidl_request.identityKey.data(), NAN_IDENTITY_KEY_LEN);
+ if (!covertAidlPairingConfigToLegacy(aidl_request.pairingConfig,
+ &legacy_request->nan_pairing_config)) {
+ LOG(ERROR) << "convertAidlNanSubscribeRequestToLegacy: invalid pairing config";
+ return false;
+ }
+ legacy_request->enable_suspendability = aidl_request.baseConfigs.enableSessionSuspendability;
+
+ return true;
+}
+
+bool convertAidlNanTransmitFollowupRequestToLegacy(
+ const NanTransmitFollowupRequest& aidl_request,
+ legacy_hal::NanTransmitFollowupRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanTransmitFollowupRequestToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->requestor_instance_id = aidl_request.peerId;
+ memcpy(legacy_request->addr, aidl_request.addr.data(), 6);
+ legacy_request->priority = aidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH
+ : legacy_hal::NAN_TX_PRIORITY_NORMAL;
+ legacy_request->dw_or_faw = aidl_request.shouldUseDiscoveryWindow
+ ? legacy_hal::NAN_TRANSMIT_IN_DW
+ : legacy_hal::NAN_TRANSMIT_IN_FAW;
+ legacy_request->service_specific_info_len = aidl_request.serviceSpecificInfo.size();
+ if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanTransmitFollowupRequestToLegacy: "
+ "service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_specific_info, aidl_request.serviceSpecificInfo.data(),
+ legacy_request->service_specific_info_len);
+ legacy_request->sdea_service_specific_info_len =
+ aidl_request.extendedServiceSpecificInfo.size();
+ if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanTransmitFollowupRequestToLegacy: "
+ "sdea_service_specific_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->sdea_service_specific_info,
+ aidl_request.extendedServiceSpecificInfo.data(),
+ legacy_request->sdea_service_specific_info_len);
+ legacy_request->recv_indication_cfg = aidl_request.disableFollowupResultIndication ? 0x1 : 0x0;
+
+ return true;
+}
+
+bool convertAidlNanDataPathInitiatorRequestToLegacy(
+ const NanInitiateDataPathRequest& aidl_request,
+ legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->requestor_instance_id = aidl_request.peerId;
+ memcpy(legacy_request->peer_disc_mac_addr, aidl_request.peerDiscMacAddr.data(), 6);
+ legacy_request->channel_request_type =
+ convertAidlNanDataPathChannelCfgToLegacy(aidl_request.channelRequestType);
+ legacy_request->channel = aidl_request.channel;
+ if (strnlen(aidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strlcpy(legacy_request->ndp_iface, aidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+ legacy_request->ndp_cfg.security_cfg =
+ (aidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->app_info.ndp_app_info_len = aidl_request.appInfo.size();
+ if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "ndp_app_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->app_info.ndp_app_info, aidl_request.appInfo.data(),
+ legacy_request->app_info.ndp_app_info_len);
+ legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+ if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ aidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ aidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->service_name_len = aidl_request.serviceNameOutOfBand.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, aidl_request.serviceNameOutOfBand.data(),
+ legacy_request->service_name_len);
+ legacy_request->scid_len = aidl_request.securityConfig.scid.size();
+ if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathInitiatorRequestToLegacy: scid_len too large";
+ return false;
+ }
+ 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);
+
+ return true;
+}
+
+bool convertAidlNanDataPathIndicationResponseToLegacy(
+ const NanRespondToDataPathIndicationRequest& aidl_request,
+ legacy_hal::NanDataPathIndicationResponse* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->rsp_code = aidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
+ : legacy_hal::NAN_DP_REQUEST_REJECT;
+ legacy_request->ndp_instance_id = aidl_request.ndpInstanceId;
+ if (strnlen(aidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "ifaceName too long";
+ return false;
+ }
+ strlcpy(legacy_request->ndp_iface, aidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
+ legacy_request->ndp_cfg.security_cfg =
+ (aidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+ ? legacy_hal::NAN_DP_CONFIG_SECURITY
+ : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+ legacy_request->app_info.ndp_app_info_len = aidl_request.appInfo.size();
+ if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "ndp_app_info_len too large";
+ return false;
+ }
+ memcpy(legacy_request->app_info.ndp_app_info, aidl_request.appInfo.data(),
+ legacy_request->app_info.ndp_app_info_len);
+ legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+ if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (aidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ aidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ aidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+ legacy_request->service_name_len = aidl_request.serviceNameOutOfBand.size();
+ if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: "
+ "service_name_len too large";
+ return false;
+ }
+ memcpy(legacy_request->service_name, aidl_request.serviceNameOutOfBand.data(),
+ legacy_request->service_name_len);
+ legacy_request->scid_len = aidl_request.securityConfig.scid.size();
+ if (legacy_request->scid_len > NAN_MAX_SCID_BUF_LEN) {
+ LOG(ERROR) << "convertAidlNanDataPathIndicationResponseToLegacy: scid_len too large";
+ return false;
+ }
+ 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);
+
+ return true;
+}
+
+bool convertLegacyNanResponseHeaderToAidl(const legacy_hal::NanResponseMsg& legacy_response,
+ NanStatus* nanStatus) {
+ if (!nanStatus) {
+ LOG(ERROR) << "convertLegacyNanResponseHeaderToAidl: nanStatus is null";
+ return false;
+ }
+ *nanStatus = {};
+
+ convertToNanStatus(legacy_response.status, legacy_response.nan_error,
+ sizeof(legacy_response.nan_error), nanStatus);
+ return true;
+}
+
+bool convertLegacyNanCapabilitiesResponseToAidl(const legacy_hal::NanCapabilities& legacy_response,
+ NanCapabilities* aidl_response) {
+ if (!aidl_response) {
+ LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToAidl: "
+ "aidl_response is null";
+ return false;
+ }
+ *aidl_response = {};
+
+ aidl_response->maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters;
+ aidl_response->maxPublishes = legacy_response.max_publishes;
+ aidl_response->maxSubscribes = legacy_response.max_subscribes;
+ aidl_response->maxServiceNameLen = legacy_response.max_service_name_len;
+ aidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len;
+ aidl_response->maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len;
+ aidl_response->maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len;
+ aidl_response->maxExtendedServiceSpecificInfoLen =
+ legacy_response.max_sdea_service_specific_info_len;
+ aidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces;
+ aidl_response->maxNdpSessions = legacy_response.max_ndp_sessions;
+ aidl_response->maxAppInfoLen = legacy_response.max_app_info_len;
+ aidl_response->maxQueuedTransmitFollowupMsgs =
+ legacy_response.max_queued_transmit_followup_msgs;
+ aidl_response->maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address;
+ aidl_response->supportedCipherSuites = legacy_response.cipher_suites_supported;
+ aidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported;
+ aidl_response->supports6g = legacy_response.is_6g_supported;
+ aidl_response->supportsHe = legacy_response.is_he_supported;
+ aidl_response->supportsPairing = legacy_response.is_pairing_supported;
+ aidl_response->supportsSetClusterId = legacy_response.is_set_cluster_id_supported;
+ aidl_response->supportsSuspension = legacy_response.is_suspension_supported;
+
+ return true;
+}
+
+bool convertLegacyNanMatchIndToAidl(const legacy_hal::NanMatchInd& legacy_ind,
+ NanMatchInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanMatchIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+ aidl_ind->peerId = legacy_ind.requestor_instance_id;
+ aidl_ind->addr = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.addr, legacy_ind.addr + 6, std::begin(aidl_ind->addr));
+ aidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.service_specific_info,
+ legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+ aidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.sdea_service_specific_info,
+ legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+ aidl_ind->matchFilter =
+ std::vector<uint8_t>(legacy_ind.sdf_match_filter,
+ legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len);
+ aidl_ind->matchOccurredInBeaconFlag = legacy_ind.match_occured_flag == 1; // NOTYPO
+ aidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1;
+ aidl_ind->rssiValue = legacy_ind.rssi_value;
+ aidl_ind->peerCipherType = (NanCipherSuiteType)legacy_ind.peer_cipher_type;
+ aidl_ind->peerRequiresSecurityEnabledInNdp =
+ legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+ aidl_ind->peerRequiresRanging =
+ legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE;
+ aidl_ind->rangingMeasurementInMm = legacy_ind.range_info.range_measurement_mm;
+ aidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type;
+ aidl_ind->scid = std::vector<uint8_t>(legacy_ind.scid, legacy_ind.scid + legacy_ind.scid_len);
+
+ if (!convertLegacyNiraToAidl(legacy_ind.nira, &aidl_ind->peerNira)) {
+ LOG(ERROR) << "convertLegacyNanMatchIndToAidl: invalid NIRA";
+ return false;
+ }
+ if (!convertLegacyPairingConfigToAidl(legacy_ind.peer_pairing_config,
+ &aidl_ind->peerPairingConfig)) {
+ LOG(ERROR) << "convertLegacyNanMatchIndToAidl: invalid pairing config";
+ return false;
+ }
+ return true;
+}
+
+bool convertLegacyNanFollowupIndToAidl(const legacy_hal::NanFollowupInd& legacy_ind,
+ NanFollowupReceivedInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanFollowupIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+ aidl_ind->peerId = legacy_ind.requestor_instance_id;
+ aidl_ind->addr = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.addr, legacy_ind.addr + 6, std::begin(aidl_ind->addr));
+ aidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1;
+ aidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.service_specific_info,
+ legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+ aidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+ legacy_ind.sdea_service_specific_info,
+ legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+
+ return true;
+}
+
+bool convertLegacyNanDataPathRequestIndToAidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+ NanDataPathRequestInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanDataPathRequestIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->discoverySessionId = legacy_ind.service_instance_id;
+ aidl_ind->peerDiscMacAddr = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.peer_disc_mac_addr, legacy_ind.peer_disc_mac_addr + 6,
+ std::begin(aidl_ind->peerDiscMacAddr));
+ aidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
+ aidl_ind->securityRequired =
+ legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+ aidl_ind->appInfo = std::vector<uint8_t>(
+ legacy_ind.app_info.ndp_app_info,
+ legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+
+ return true;
+}
+
+bool convertLegacyNdpChannelInfoToAidl(const legacy_hal::NanChannelInfo& legacy_struct,
+ NanDataPathChannelInfo* aidl_struct) {
+ if (!aidl_struct) {
+ LOG(ERROR) << "convertLegacyNdpChannelInfoToAidl: aidl_struct is null";
+ return false;
+ }
+ *aidl_struct = {};
+
+ aidl_struct->channelFreq = legacy_struct.channel;
+ aidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToAidl(
+ (legacy_hal::wifi_channel_width)legacy_struct.bandwidth);
+ aidl_struct->numSpatialStreams = legacy_struct.nss;
+
+ return true;
+}
+
+bool convertLegacyNanDataPathConfirmIndToAidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+ NanDataPathConfirmInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
+ aidl_ind->dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT;
+ aidl_ind->peerNdiMacAddr = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.peer_ndi_mac_addr, legacy_ind.peer_ndi_mac_addr + 6,
+ std::begin(aidl_ind->peerNdiMacAddr));
+ aidl_ind->appInfo = std::vector<uint8_t>(
+ legacy_ind.app_info.ndp_app_info,
+ legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+ aidl_ind->status.status = convertLegacyNanStatusTypeToAidl(legacy_ind.reason_code);
+ aidl_ind->status.description = "";
+
+ std::vector<NanDataPathChannelInfo> channelInfo;
+ for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
+ NanDataPathChannelInfo aidl_struct;
+ if (!convertLegacyNdpChannelInfoToAidl(legacy_ind.channel_info[i], &aidl_struct)) {
+ return false;
+ }
+ channelInfo.push_back(aidl_struct);
+ }
+ aidl_ind->channelInfo = channelInfo;
+
+ return true;
+}
+
+bool convertLegacyNanDataPathScheduleUpdateIndToAidl(
+ const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+ NanDataPathScheduleUpdateInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToAidl: "
+ "aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->peerDiscoveryAddress = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.peer_mac_addr, legacy_ind.peer_mac_addr + 6,
+ std::begin(aidl_ind->peerDiscoveryAddress));
+ std::vector<NanDataPathChannelInfo> channelInfo;
+ for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
+ NanDataPathChannelInfo aidl_struct;
+ if (!convertLegacyNdpChannelInfoToAidl(legacy_ind.channel_info[i], &aidl_struct)) {
+ return false;
+ }
+ channelInfo.push_back(aidl_struct);
+ }
+ aidl_ind->channelInfo = channelInfo;
+ std::vector<uint32_t> ndpInstanceIds;
+ for (unsigned int i = 0; i < legacy_ind.num_ndp_instances; ++i) {
+ ndpInstanceIds.push_back(legacy_ind.ndp_instance_id[i]);
+ }
+ aidl_ind->ndpInstanceIds = uintToIntVec(ndpInstanceIds);
+
+ return true;
+}
+
+legacy_hal::wifi_rtt_type convertAidlRttTypeToLegacy(RttType type) {
+ switch (type) {
+ case RttType::ONE_SIDED:
+ return legacy_hal::RTT_TYPE_1_SIDED;
+ case RttType::TWO_SIDED:
+ return legacy_hal::RTT_TYPE_2_SIDED;
+ };
+ CHECK(false);
+}
+
+RttType convertLegacyRttTypeToAidl(legacy_hal::wifi_rtt_type type) {
+ switch (type) {
+ case legacy_hal::RTT_TYPE_1_SIDED:
+ return RttType::ONE_SIDED;
+ case legacy_hal::RTT_TYPE_2_SIDED:
+ return RttType::TWO_SIDED;
+ };
+ CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::rtt_peer_type convertAidlRttPeerTypeToLegacy(RttPeerType type) {
+ switch (type) {
+ case RttPeerType::AP:
+ return legacy_hal::RTT_PEER_AP;
+ case RttPeerType::STA:
+ return legacy_hal::RTT_PEER_STA;
+ case RttPeerType::P2P_GO:
+ return legacy_hal::RTT_PEER_P2P_GO;
+ case RttPeerType::P2P_CLIENT:
+ return legacy_hal::RTT_PEER_P2P_CLIENT;
+ case RttPeerType::NAN_TYPE:
+ return legacy_hal::RTT_PEER_NAN;
+ };
+ CHECK(false);
+}
+
+legacy_hal::wifi_channel_width convertAidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) {
+ switch (type) {
+ case WifiChannelWidthInMhz::WIDTH_20:
+ return legacy_hal::WIFI_CHAN_WIDTH_20;
+ case WifiChannelWidthInMhz::WIDTH_40:
+ return legacy_hal::WIFI_CHAN_WIDTH_40;
+ case WifiChannelWidthInMhz::WIDTH_80:
+ return legacy_hal::WIFI_CHAN_WIDTH_80;
+ case WifiChannelWidthInMhz::WIDTH_160:
+ return legacy_hal::WIFI_CHAN_WIDTH_160;
+ case WifiChannelWidthInMhz::WIDTH_80P80:
+ return legacy_hal::WIFI_CHAN_WIDTH_80P80;
+ case WifiChannelWidthInMhz::WIDTH_5:
+ return legacy_hal::WIFI_CHAN_WIDTH_5;
+ case WifiChannelWidthInMhz::WIDTH_10:
+ return legacy_hal::WIFI_CHAN_WIDTH_10;
+ case WifiChannelWidthInMhz::WIDTH_320:
+ return legacy_hal::WIFI_CHAN_WIDTH_320;
+ case WifiChannelWidthInMhz::WIDTH_INVALID:
+ return legacy_hal::WIFI_CHAN_WIDTH_INVALID;
+ };
+ CHECK(false);
+}
+
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToAidl(legacy_hal::wifi_channel_width type) {
+ switch (type) {
+ case legacy_hal::WIFI_CHAN_WIDTH_20:
+ return WifiChannelWidthInMhz::WIDTH_20;
+ case legacy_hal::WIFI_CHAN_WIDTH_40:
+ return WifiChannelWidthInMhz::WIDTH_40;
+ case legacy_hal::WIFI_CHAN_WIDTH_80:
+ return WifiChannelWidthInMhz::WIDTH_80;
+ case legacy_hal::WIFI_CHAN_WIDTH_160:
+ return WifiChannelWidthInMhz::WIDTH_160;
+ case legacy_hal::WIFI_CHAN_WIDTH_80P80:
+ return WifiChannelWidthInMhz::WIDTH_80P80;
+ case legacy_hal::WIFI_CHAN_WIDTH_5:
+ return WifiChannelWidthInMhz::WIDTH_5;
+ case legacy_hal::WIFI_CHAN_WIDTH_10:
+ return WifiChannelWidthInMhz::WIDTH_10;
+ case legacy_hal::WIFI_CHAN_WIDTH_320:
+ return WifiChannelWidthInMhz::WIDTH_320;
+ default:
+ return WifiChannelWidthInMhz::WIDTH_INVALID;
+ };
+}
+
+legacy_hal::wifi_rtt_preamble convertAidlRttPreambleToLegacy(RttPreamble type) {
+ switch (type) {
+ case RttPreamble::LEGACY:
+ return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY;
+ case RttPreamble::HT:
+ return legacy_hal::WIFI_RTT_PREAMBLE_HT;
+ case RttPreamble::VHT:
+ return legacy_hal::WIFI_RTT_PREAMBLE_VHT;
+ case RttPreamble::HE:
+ return legacy_hal::WIFI_RTT_PREAMBLE_HE;
+ case RttPreamble::EHT:
+ return legacy_hal::WIFI_RTT_PREAMBLE_EHT;
+ };
+ CHECK(false);
+}
+
+RttPreamble convertLegacyRttPreambleToAidl(legacy_hal::wifi_rtt_preamble type) {
+ switch (type) {
+ case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY:
+ return RttPreamble::LEGACY;
+ case legacy_hal::WIFI_RTT_PREAMBLE_HT:
+ return RttPreamble::HT;
+ case legacy_hal::WIFI_RTT_PREAMBLE_VHT:
+ return RttPreamble::VHT;
+ case legacy_hal::WIFI_RTT_PREAMBLE_HE:
+ return RttPreamble::HE;
+ case legacy_hal::WIFI_RTT_PREAMBLE_EHT:
+ return RttPreamble::EHT;
+ };
+ CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::wifi_rtt_bw convertAidlRttBwToLegacy(RttBw type) {
+ switch (type) {
+ case RttBw::BW_5MHZ:
+ return legacy_hal::WIFI_RTT_BW_5;
+ case RttBw::BW_10MHZ:
+ return legacy_hal::WIFI_RTT_BW_10;
+ case RttBw::BW_20MHZ:
+ return legacy_hal::WIFI_RTT_BW_20;
+ case RttBw::BW_40MHZ:
+ return legacy_hal::WIFI_RTT_BW_40;
+ case RttBw::BW_80MHZ:
+ return legacy_hal::WIFI_RTT_BW_80;
+ case RttBw::BW_160MHZ:
+ return legacy_hal::WIFI_RTT_BW_160;
+ case RttBw::BW_320MHZ:
+ return legacy_hal::WIFI_RTT_BW_320;
+ case RttBw::BW_UNSPECIFIED:
+ return legacy_hal::WIFI_RTT_BW_UNSPECIFIED;
+ };
+ CHECK(false);
+}
+
+RttBw convertLegacyRttBwToAidl(legacy_hal::wifi_rtt_bw type) {
+ switch (type) {
+ case legacy_hal::WIFI_RTT_BW_5:
+ return RttBw::BW_5MHZ;
+ case legacy_hal::WIFI_RTT_BW_10:
+ return RttBw::BW_10MHZ;
+ case legacy_hal::WIFI_RTT_BW_20:
+ return RttBw::BW_20MHZ;
+ case legacy_hal::WIFI_RTT_BW_40:
+ return RttBw::BW_40MHZ;
+ case legacy_hal::WIFI_RTT_BW_80:
+ return RttBw::BW_80MHZ;
+ case legacy_hal::WIFI_RTT_BW_160:
+ return RttBw::BW_160MHZ;
+ case legacy_hal::WIFI_RTT_BW_320:
+ return RttBw::BW_320MHZ;
+ case legacy_hal::WIFI_RTT_BW_UNSPECIFIED:
+ return RttBw::BW_UNSPECIFIED;
+ };
+ CHECK(false) << "Unknown legacy type: " << type;
+}
+
+legacy_hal::wifi_motion_pattern convertAidlRttMotionPatternToLegacy(RttMotionPattern type) {
+ switch (type) {
+ case RttMotionPattern::NOT_EXPECTED:
+ return legacy_hal::WIFI_MOTION_NOT_EXPECTED;
+ case RttMotionPattern::EXPECTED:
+ return legacy_hal::WIFI_MOTION_EXPECTED;
+ case RttMotionPattern::UNKNOWN:
+ return legacy_hal::WIFI_MOTION_UNKNOWN;
+ };
+ CHECK(false);
+}
+
+WifiRatePreamble convertLegacyWifiRatePreambleToAidl(uint8_t preamble) {
+ switch (preamble) {
+ case 0:
+ return WifiRatePreamble::OFDM;
+ case 1:
+ return WifiRatePreamble::CCK;
+ case 2:
+ return WifiRatePreamble::HT;
+ case 3:
+ return WifiRatePreamble::VHT;
+ case 4:
+ return WifiRatePreamble::HE;
+ case 5:
+ return WifiRatePreamble::EHT;
+ default:
+ return WifiRatePreamble::RESERVED;
+ };
+ CHECK(false) << "Unknown legacy preamble: " << preamble;
+}
+
+WifiRateNss convertLegacyWifiRateNssToAidl(uint8_t nss) {
+ switch (nss) {
+ case 0:
+ return WifiRateNss::NSS_1x1;
+ case 1:
+ return WifiRateNss::NSS_2x2;
+ case 2:
+ return WifiRateNss::NSS_3x3;
+ case 3:
+ return WifiRateNss::NSS_4x4;
+ };
+ CHECK(false) << "Unknown legacy nss: " << nss;
+ return {};
+}
+
+RttStatus convertLegacyRttStatusToAidl(legacy_hal::wifi_rtt_status status) {
+ switch (status) {
+ case legacy_hal::RTT_STATUS_SUCCESS:
+ return RttStatus::SUCCESS;
+ case legacy_hal::RTT_STATUS_FAILURE:
+ return RttStatus::FAILURE;
+ case legacy_hal::RTT_STATUS_FAIL_NO_RSP:
+ return RttStatus::FAIL_NO_RSP;
+ case legacy_hal::RTT_STATUS_FAIL_REJECTED:
+ return RttStatus::FAIL_REJECTED;
+ case legacy_hal::RTT_STATUS_FAIL_NOT_SCHEDULED_YET:
+ return RttStatus::FAIL_NOT_SCHEDULED_YET;
+ case legacy_hal::RTT_STATUS_FAIL_TM_TIMEOUT:
+ return RttStatus::FAIL_TM_TIMEOUT;
+ case legacy_hal::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL:
+ return RttStatus::FAIL_AP_ON_DIFF_CHANNEL;
+ case legacy_hal::RTT_STATUS_FAIL_NO_CAPABILITY:
+ return RttStatus::FAIL_NO_CAPABILITY;
+ case legacy_hal::RTT_STATUS_ABORTED:
+ return RttStatus::ABORTED;
+ case legacy_hal::RTT_STATUS_FAIL_INVALID_TS:
+ return RttStatus::FAIL_INVALID_TS;
+ case legacy_hal::RTT_STATUS_FAIL_PROTOCOL:
+ return RttStatus::FAIL_PROTOCOL;
+ case legacy_hal::RTT_STATUS_FAIL_SCHEDULE:
+ return RttStatus::FAIL_SCHEDULE;
+ case legacy_hal::RTT_STATUS_FAIL_BUSY_TRY_LATER:
+ return RttStatus::FAIL_BUSY_TRY_LATER;
+ case legacy_hal::RTT_STATUS_INVALID_REQ:
+ return RttStatus::INVALID_REQ;
+ case legacy_hal::RTT_STATUS_NO_WIFI:
+ return RttStatus::NO_WIFI;
+ case legacy_hal::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE:
+ return RttStatus::FAIL_FTM_PARAM_OVERRIDE;
+ case legacy_hal::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE:
+ return RttStatus::NAN_RANGING_PROTOCOL_FAILURE;
+ case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED:
+ return RttStatus::NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
+ };
+ CHECK(false) << "Unknown legacy status: " << status;
+}
+
+bool convertAidlWifiChannelInfoToLegacy(const WifiChannelInfo& aidl_info,
+ legacy_hal::wifi_channel_info* legacy_info) {
+ if (!legacy_info) {
+ return false;
+ }
+ *legacy_info = {};
+ legacy_info->width = convertAidlWifiChannelWidthToLegacy(aidl_info.width);
+ legacy_info->center_freq = aidl_info.centerFreq;
+ legacy_info->center_freq0 = aidl_info.centerFreq0;
+ legacy_info->center_freq1 = aidl_info.centerFreq1;
+ return true;
+}
+
+bool convertLegacyWifiChannelInfoToAidl(const legacy_hal::wifi_channel_info& legacy_info,
+ WifiChannelInfo* aidl_info) {
+ if (!aidl_info) {
+ return false;
+ }
+ *aidl_info = {};
+ aidl_info->width = convertLegacyWifiChannelWidthToAidl(legacy_info.width);
+ aidl_info->centerFreq = legacy_info.center_freq;
+ aidl_info->centerFreq0 = legacy_info.center_freq0;
+ aidl_info->centerFreq1 = legacy_info.center_freq1;
+ return true;
+}
+
+bool convertAidlRttConfigToLegacy(const RttConfig& aidl_config,
+ legacy_hal::wifi_rtt_config* legacy_config) {
+ if (!legacy_config) {
+ return false;
+ }
+ *legacy_config = {};
+ CHECK(aidl_config.addr.size() == sizeof(legacy_config->addr));
+ memcpy(legacy_config->addr, aidl_config.addr.data(), aidl_config.addr.size());
+ legacy_config->type = convertAidlRttTypeToLegacy(aidl_config.type);
+ legacy_config->peer = convertAidlRttPeerTypeToLegacy(aidl_config.peer);
+ if (!convertAidlWifiChannelInfoToLegacy(aidl_config.channel, &legacy_config->channel)) {
+ return false;
+ }
+ legacy_config->burst_period = aidl_config.burstPeriod;
+ legacy_config->num_burst = aidl_config.numBurst;
+ legacy_config->num_frames_per_burst = aidl_config.numFramesPerBurst;
+ legacy_config->num_retries_per_rtt_frame = aidl_config.numRetriesPerRttFrame;
+ legacy_config->num_retries_per_ftmr = aidl_config.numRetriesPerFtmr;
+ legacy_config->LCI_request = aidl_config.mustRequestLci;
+ legacy_config->LCR_request = aidl_config.mustRequestLcr;
+ legacy_config->burst_duration = aidl_config.burstDuration;
+ legacy_config->preamble = convertAidlRttPreambleToLegacy(aidl_config.preamble);
+ legacy_config->bw = convertAidlRttBwToLegacy(aidl_config.bw);
+ return true;
+}
+
+bool convertAidlVectorOfRttConfigToLegacy(
+ const std::vector<RttConfig>& aidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
+ if (!legacy_configs) {
+ return false;
+ }
+ *legacy_configs = {};
+ for (const auto& aidl_config : aidl_configs) {
+ legacy_hal::wifi_rtt_config legacy_config;
+ if (!convertAidlRttConfigToLegacy(aidl_config, &legacy_config)) {
+ return false;
+ }
+ legacy_configs->push_back(legacy_config);
+ }
+ return true;
+}
+
+bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
+ legacy_hal::wifi_lci_information* legacy_info) {
+ if (!legacy_info) {
+ return false;
+ }
+ *legacy_info = {};
+ legacy_info->latitude = aidl_info.latitude;
+ legacy_info->longitude = aidl_info.longitude;
+ legacy_info->altitude = aidl_info.altitude;
+ legacy_info->latitude_unc = aidl_info.latitudeUnc;
+ legacy_info->longitude_unc = aidl_info.longitudeUnc;
+ legacy_info->altitude_unc = aidl_info.altitudeUnc;
+ legacy_info->motion_pattern = convertAidlRttMotionPatternToLegacy(aidl_info.motionPattern);
+ legacy_info->floor = aidl_info.floor;
+ legacy_info->height_above_floor = aidl_info.heightAboveFloor;
+ legacy_info->height_unc = aidl_info.heightUnc;
+ return true;
+}
+
+bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
+ legacy_hal::wifi_lcr_information* legacy_info) {
+ if (!legacy_info) {
+ return false;
+ }
+ *legacy_info = {};
+ CHECK(aidl_info.countryCode.size() == sizeof(legacy_info->country_code));
+ memcpy(legacy_info->country_code, aidl_info.countryCode.data(), aidl_info.countryCode.size());
+ if (aidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) {
+ return false;
+ }
+ legacy_info->length = aidl_info.civicInfo.size();
+ memcpy(legacy_info->civic_info, aidl_info.civicInfo.c_str(), aidl_info.civicInfo.size());
+ return true;
+}
+
+bool convertAidlRttResponderToLegacy(const RttResponder& aidl_responder,
+ legacy_hal::wifi_rtt_responder* legacy_responder) {
+ if (!legacy_responder) {
+ return false;
+ }
+ *legacy_responder = {};
+ if (!convertAidlWifiChannelInfoToLegacy(aidl_responder.channel, &legacy_responder->channel)) {
+ return false;
+ }
+ legacy_responder->preamble = convertAidlRttPreambleToLegacy(aidl_responder.preamble);
+ return true;
+}
+
+bool convertLegacyRttResponderToAidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+ RttResponder* aidl_responder) {
+ if (!aidl_responder) {
+ return false;
+ }
+ *aidl_responder = {};
+ if (!convertLegacyWifiChannelInfoToAidl(legacy_responder.channel, &aidl_responder->channel)) {
+ return false;
+ }
+ aidl_responder->preamble = convertLegacyRttPreambleToAidl(legacy_responder.preamble);
+ return true;
+}
+
+bool convertLegacyRttCapabilitiesToAidl(
+ const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+ RttCapabilities* aidl_capabilities) {
+ if (!aidl_capabilities) {
+ return false;
+ }
+ *aidl_capabilities = {};
+ aidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported;
+ aidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported;
+ 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->mcVersion = legacy_capabilities.mc_version;
+ return true;
+}
+
+bool convertLegacyWifiRateInfoToAidl(const legacy_hal::wifi_rate& legacy_rate,
+ WifiRateInfo* aidl_rate) {
+ if (!aidl_rate) {
+ return false;
+ }
+ *aidl_rate = {};
+ aidl_rate->preamble = convertLegacyWifiRatePreambleToAidl(legacy_rate.preamble);
+ aidl_rate->nss = convertLegacyWifiRateNssToAidl(legacy_rate.nss);
+ aidl_rate->bw = convertLegacyWifiChannelWidthToAidl(
+ static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw));
+ aidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx;
+ aidl_rate->bitRateInKbps = legacy_rate.bitrate;
+ return true;
+}
+
+bool convertLegacyRttResultToAidl(const legacy_hal::wifi_rtt_result& legacy_result,
+ RttResult* aidl_result) {
+ if (!aidl_result) {
+ return false;
+ }
+ *aidl_result = {};
+ aidl_result->addr = std::array<uint8_t, 6>();
+ CHECK(sizeof(legacy_result.addr) == aidl_result->addr.size());
+ std::copy(legacy_result.addr, legacy_result.addr + 6, std::begin(aidl_result->addr));
+ aidl_result->burstNum = legacy_result.burst_num;
+ aidl_result->measurementNumber = legacy_result.measurement_number;
+ aidl_result->successNumber = legacy_result.success_number;
+ aidl_result->numberPerBurstPeer = legacy_result.number_per_burst_peer;
+ aidl_result->status = convertLegacyRttStatusToAidl(legacy_result.status);
+ aidl_result->retryAfterDuration = legacy_result.retry_after_duration;
+ aidl_result->type = convertLegacyRttTypeToAidl(legacy_result.type);
+ aidl_result->rssi = legacy_result.rssi;
+ aidl_result->rssiSpread = legacy_result.rssi_spread;
+ if (!convertLegacyWifiRateInfoToAidl(legacy_result.tx_rate, &aidl_result->txRate)) {
+ return false;
+ }
+ if (!convertLegacyWifiRateInfoToAidl(legacy_result.rx_rate, &aidl_result->rxRate)) {
+ return false;
+ }
+ aidl_result->rtt = legacy_result.rtt;
+ aidl_result->rttSd = legacy_result.rtt_sd;
+ aidl_result->rttSpread = legacy_result.rtt_spread;
+ aidl_result->distanceInMm = legacy_result.distance_mm;
+ aidl_result->distanceSdInMm = legacy_result.distance_sd_mm;
+ aidl_result->distanceSpreadInMm = legacy_result.distance_spread_mm;
+ aidl_result->timeStampInUs = legacy_result.ts;
+ aidl_result->burstDurationInMs = legacy_result.burst_duration;
+ aidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num;
+ if (legacy_result.LCI && !convertLegacyIeToAidl(*legacy_result.LCI, &aidl_result->lci)) {
+ return false;
+ }
+ if (legacy_result.LCR && !convertLegacyIeToAidl(*legacy_result.LCR, &aidl_result->lcr)) {
+ return false;
+ }
+ return true;
+}
+
+bool convertLegacyVectorOfRttResultToAidl(
+ const std::vector<const legacy_hal::wifi_rtt_result*>& 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, &aidl_result)) {
+ return false;
+ }
+ aidl_result.channelFreqMHz = 0;
+ aidl_result.packetBw = RttBw::BW_UNSPECIFIED;
+ aidl_results->push_back(aidl_result);
+ }
+ return true;
+}
+
+bool convertLegacyVectorOfRttResultV2ToAidl(
+ const std::vector<const legacy_hal::wifi_rtt_result_v2*>& 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, &aidl_result)) {
+ return false;
+ }
+ aidl_result.channelFreqMHz =
+ legacy_result->frequency != UNSPECIFIED ? legacy_result->frequency : 0;
+ aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->packet_bw);
+ aidl_results->push_back(aidl_result);
+ }
+ return true;
+}
+
+legacy_hal::wifi_interface_type convertAidlIfaceTypeToLegacy(IfaceType aidl_interface_type) {
+ switch (aidl_interface_type) {
+ case IfaceType::STA:
+ return legacy_hal::WIFI_INTERFACE_TYPE_STA;
+ case IfaceType::AP:
+ return legacy_hal::WIFI_INTERFACE_TYPE_AP;
+ case IfaceType::P2P:
+ return legacy_hal::WIFI_INTERFACE_TYPE_P2P;
+ case IfaceType::NAN_IFACE:
+ return legacy_hal::WIFI_INTERFACE_TYPE_NAN;
+ }
+ CHECK(false);
+}
+
+legacy_hal::wifi_multi_sta_use_case convertAidlMultiStaUseCaseToLegacy(
+ IWifiChip::MultiStaUseCase use_case) {
+ switch (use_case) {
+ case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+ return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+ case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
+ return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
+ }
+ CHECK(false);
+}
+
+bool convertAidlCoexUnsafeChannelToLegacy(
+ const IWifiChip::CoexUnsafeChannel& aidl_unsafe_channel,
+ legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
+ if (!legacy_unsafe_channel) {
+ return false;
+ }
+ *legacy_unsafe_channel = {};
+ switch (aidl_unsafe_channel.band) {
+ case WifiBand::BAND_24GHZ:
+ legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
+ break;
+ case WifiBand::BAND_5GHZ:
+ legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
+ break;
+ default:
+ return false;
+ };
+ legacy_unsafe_channel->channel = aidl_unsafe_channel.channel;
+ legacy_unsafe_channel->power_cap_dbm = aidl_unsafe_channel.powerCapDbm;
+ return true;
+}
+
+bool convertAidlVectorOfCoexUnsafeChannelToLegacy(
+ const std::vector<IWifiChip::CoexUnsafeChannel>& aidl_unsafe_channels,
+ std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
+ if (!legacy_unsafe_channels) {
+ return false;
+ }
+ *legacy_unsafe_channels = {};
+ for (const auto& aidl_unsafe_channel : aidl_unsafe_channels) {
+ legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
+ if (!aidl_struct_util::convertAidlCoexUnsafeChannelToLegacy(aidl_unsafe_channel,
+ &legacy_unsafe_channel)) {
+ return false;
+ }
+ legacy_unsafe_channels->push_back(legacy_unsafe_channel);
+ }
+ return true;
+}
+
+WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg) {
+ switch (antenna_cfg) {
+ case legacy_hal::WIFI_ANTENNA_1X1:
+ return WifiAntennaMode::WIFI_ANTENNA_MODE_1X1;
+ case legacy_hal::WIFI_ANTENNA_2X2:
+ return WifiAntennaMode::WIFI_ANTENNA_MODE_2X2;
+ case legacy_hal::WIFI_ANTENNA_3X3:
+ return WifiAntennaMode::WIFI_ANTENNA_MODE_3X3;
+ case legacy_hal::WIFI_ANTENNA_4X4:
+ return WifiAntennaMode::WIFI_ANTENNA_MODE_4X4;
+ default:
+ return WifiAntennaMode::WIFI_ANTENNA_MODE_UNSPECIFIED;
+ }
+}
+
+bool convertLegacyWifiRadioConfigurationToAidl(
+ legacy_hal::wifi_radio_configuration* radio_configuration,
+ WifiRadioConfiguration* aidl_radio_configuration) {
+ if (!aidl_radio_configuration) {
+ return false;
+ }
+ *aidl_radio_configuration = {};
+ aidl_radio_configuration->bandInfo =
+ aidl_struct_util::convertLegacyMacBandToAidlWifiBand(radio_configuration->band);
+ if (aidl_radio_configuration->bandInfo == WifiBand::BAND_UNSPECIFIED) {
+ LOG(ERROR) << "Unspecified band";
+ return false;
+ }
+ aidl_radio_configuration->antennaMode =
+ aidl_struct_util::convertLegacyAntennaConfigurationToAidl(
+ radio_configuration->antenna_cfg);
+ return true;
+}
+
+bool convertLegacyRadioCombinationsMatrixToAidl(
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
+ std::vector<WifiRadioCombination>* aidl_combinations) {
+ if (!aidl_combinations || !legacy_matrix) {
+ return false;
+ }
+ *aidl_combinations = {};
+
+ int num_combinations = legacy_matrix->num_radio_combinations;
+ if (!num_combinations) {
+ LOG(ERROR) << "zero radio combinations";
+ return false;
+ }
+ wifi_radio_combination* l_radio_combinations_ptr = legacy_matrix->radio_combinations;
+ for (int i = 0; i < num_combinations; i++) {
+ int num_configurations = l_radio_combinations_ptr->num_radio_configurations;
+ WifiRadioCombination radioCombination;
+ std::vector<WifiRadioConfiguration> radio_configurations_vec;
+ if (!num_configurations) {
+ LOG(ERROR) << "zero radio configurations";
+ return false;
+ }
+ for (int j = 0; j < num_configurations; j++) {
+ WifiRadioConfiguration radioConfiguration;
+ wifi_radio_configuration* l_radio_configurations_ptr =
+ &l_radio_combinations_ptr->radio_configurations[j];
+ if (!aidl_struct_util::convertLegacyWifiRadioConfigurationToAidl(
+ l_radio_configurations_ptr, &radioConfiguration)) {
+ LOG(ERROR) << "Error converting wifi radio configuration";
+ return false;
+ }
+ radio_configurations_vec.push_back(radioConfiguration);
+ }
+ radioCombination.radioConfigurations = radio_configurations_vec;
+ aidl_combinations->push_back(radioCombination);
+ l_radio_combinations_ptr =
+ (wifi_radio_combination*)((u8*)l_radio_combinations_ptr +
+ sizeof(wifi_radio_combination) +
+ (sizeof(wifi_radio_configuration) * num_configurations));
+ }
+ return true;
+}
+
+bool convertAidlNanPairingInitiatorRequestToLegacy(const NanPairingRequest& aidl_request,
+ legacy_hal::NanPairingRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->requestor_instance_id = aidl_request.peerId;
+ memcpy(legacy_request->peer_disc_mac_addr, aidl_request.peerDiscMacAddr.data(), 6);
+ legacy_request->nan_pairing_request_type =
+ convertAidlNanPairingRequestTypeToLegacy(aidl_request.requestType);
+ legacy_request->enable_pairing_cache = aidl_request.enablePairingCache;
+
+ memcpy(legacy_request->nan_identity_key, aidl_request.pairingIdentityKey.data(),
+ NAN_IDENTITY_KEY_LEN);
+
+ legacy_request->is_opportunistic =
+ aidl_request.securityConfig.securityType == NanPairingSecurityType::OPPORTUNISTIC ? 1
+ : 0;
+ legacy_request->akm = convertAidlAkmTypeToLegacy(aidl_request.securityConfig.akm);
+ legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+ if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ aidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanPairingInitiatorRequestToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ aidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+
+ return true;
+}
+
+bool convertAidlNanPairingIndicationResponseToLegacy(
+ const NanRespondToPairingIndicationRequest& aidl_request,
+ legacy_hal::NanPairingIndicationResponse* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->pairing_instance_id = aidl_request.pairingInstanceId;
+ legacy_request->nan_pairing_request_type =
+ convertAidlNanPairingRequestTypeToLegacy(aidl_request.requestType);
+ legacy_request->enable_pairing_cache = aidl_request.enablePairingCache;
+
+ memcpy(legacy_request->nan_identity_key, aidl_request.pairingIdentityKey.data(),
+ NAN_IDENTITY_KEY_LEN);
+
+ legacy_request->is_opportunistic =
+ aidl_request.securityConfig.securityType == NanPairingSecurityType::OPPORTUNISTIC ? 1
+ : 0;
+ legacy_request->akm = convertAidlAkmTypeToLegacy(aidl_request.securityConfig.akm);
+ legacy_request->cipher_type = (unsigned int)aidl_request.securityConfig.cipherType;
+ legacy_request->rsp_code =
+ aidl_request.acceptRequest ? NAN_PAIRING_REQUEST_ACCEPT : NAN_PAIRING_REQUEST_REJECT;
+ if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PMK) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+ legacy_request->key_info.body.pmk_info.pmk_len = aidl_request.securityConfig.pmk.size();
+ if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+ LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+ "invalid pmk_len";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.pmk_info.pmk, aidl_request.securityConfig.pmk.data(),
+ legacy_request->key_info.body.pmk_info.pmk_len);
+ }
+ if (aidl_request.securityConfig.securityType == NanPairingSecurityType::PASSPHRASE) {
+ legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+ legacy_request->key_info.body.passphrase_info.passphrase_len =
+ aidl_request.securityConfig.passphrase.size();
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len <
+ NAN_SECURITY_MIN_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+ "passphrase_len too small";
+ return false;
+ }
+ if (legacy_request->key_info.body.passphrase_info.passphrase_len >
+ NAN_SECURITY_MAX_PASSPHRASE_LEN) {
+ LOG(ERROR) << "convertAidlNanPairingIndicationResponseToLegacy: "
+ "passphrase_len too large";
+ return false;
+ }
+ memcpy(legacy_request->key_info.body.passphrase_info.passphrase,
+ aidl_request.securityConfig.passphrase.data(),
+ legacy_request->key_info.body.passphrase_info.passphrase_len);
+ }
+
+ return true;
+}
+
+bool convertAidlNanBootstrappingInitiatorRequestToLegacy(
+ const NanBootstrappingRequest& aidl_request,
+ legacy_hal::NanBootstrappingRequest* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanBootstrappingInitiatorRequestToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->requestor_instance_id = aidl_request.peerId;
+ memcpy(legacy_request->peer_disc_mac_addr, aidl_request.peerDiscMacAddr.data(), 6);
+ legacy_request->request_bootstrapping_method =
+ convertAidlBootstrappingMethodToLegacy(aidl_request.requestBootstrappingMethod);
+ legacy_request->cookie_length = aidl_request.cookie.size();
+
+ memcpy(legacy_request->cookie, aidl_request.cookie.data(), legacy_request->cookie_length);
+
+ return true;
+}
+
+bool convertAidlNanBootstrappingIndicationResponseToLegacy(
+ const NanBootstrappingResponse& aidl_request,
+ legacy_hal::NanBootstrappingIndicationResponse* legacy_request) {
+ if (!legacy_request) {
+ LOG(ERROR) << "convertAidlNanBootstrappingIndicationResponseToLegacy: "
+ "legacy_request is null";
+ return false;
+ }
+ *legacy_request = {};
+
+ legacy_request->service_instance_id = aidl_request.bootstrappingInstanceId;
+ legacy_request->rsp_code = aidl_request.acceptRequest ? NAN_BOOTSTRAPPING_REQUEST_ACCEPT
+ : NAN_BOOTSTRAPPING_REQUEST_REJECT;
+
+ return true;
+}
+
+bool convertLegacyNanPairingRequestIndToAidl(const legacy_hal::NanPairingRequestInd& legacy_ind,
+ NanPairingRequestInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanPairingRequestIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+ aidl_ind->peerId = legacy_ind.requestor_instance_id;
+ aidl_ind->peerDiscMacAddr = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.peer_disc_mac_addr, legacy_ind.peer_disc_mac_addr + 6,
+ std::begin(aidl_ind->peerDiscMacAddr));
+ aidl_ind->pairingInstanceId = legacy_ind.pairing_instance_id;
+ aidl_ind->enablePairingCache = legacy_ind.enable_pairing_cache == 1;
+ aidl_ind->requestType =
+ convertLegacyNanPairingRequestTypeToAidl(legacy_ind.nan_pairing_request_type);
+ if (!convertLegacyNiraToAidl(legacy_ind.nira, &aidl_ind->peerNira)) {
+ return false;
+ }
+ return true;
+}
+
+bool convertLegacyNanPairingConfirmIndToAidl(const legacy_hal::NanPairingConfirmInd& legacy_ind,
+ NanPairingConfirmInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanPairingRequestIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->pairingInstanceId = legacy_ind.pairing_instance_id;
+ aidl_ind->enablePairingCache = legacy_ind.enable_pairing_cache == 1;
+ aidl_ind->requestType =
+ convertLegacyNanPairingRequestTypeToAidl(legacy_ind.nan_pairing_request_type);
+ aidl_ind->pairingSuccess = legacy_ind.rsp_code == NAN_PAIRING_REQUEST_ACCEPT;
+ aidl_ind->status.status = convertLegacyNanStatusTypeToAidl(legacy_ind.reason_code);
+ if (!convertLegacyNpsaToAidl(legacy_ind.npk_security_association, &aidl_ind->npksa)) {
+ return false;
+ }
+ return true;
+}
+
+bool convertLegacyNanBootstrappingRequestIndToAidl(
+ const legacy_hal::NanBootstrappingRequestInd& legacy_ind,
+ NanBootstrappingRequestInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanBootstrappingRequestIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
+ aidl_ind->peerId = legacy_ind.requestor_instance_id;
+ aidl_ind->peerDiscMacAddr = std::array<uint8_t, 6>();
+ std::copy(legacy_ind.peer_disc_mac_addr, legacy_ind.peer_disc_mac_addr + 6,
+ std::begin(aidl_ind->peerDiscMacAddr));
+ aidl_ind->bootstrappingInstanceId = legacy_ind.bootstrapping_instance_id;
+ aidl_ind->requestBootstrappingMethod =
+ convertLegacyBootstrappingMethodToAidl(legacy_ind.request_bootstrapping_method);
+ return true;
+}
+
+bool convertLegacyNanBootstrappingConfirmIndToAidl(
+ const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
+ NanBootstrappingConfirmInd* aidl_ind) {
+ if (!aidl_ind) {
+ LOG(ERROR) << "convertLegacyNanBootstrappingConfirmIndToAidl: aidl_ind is null";
+ return false;
+ }
+ *aidl_ind = {};
+
+ aidl_ind->bootstrappingInstanceId = legacy_ind.bootstrapping_instance_id;
+ aidl_ind->responseCode = static_cast<NanBootstrappingResponseCode>(legacy_ind.rsp_code);
+ aidl_ind->reasonCode.status = convertLegacyNanStatusTypeToAidl(legacy_ind.reason_code);
+ aidl_ind->comeBackDelay = legacy_ind.come_back_delay;
+ aidl_ind->cookie =
+ std::vector<uint8_t>(legacy_ind.cookie, legacy_ind.cookie + legacy_ind.cookie_length);
+ return true;
+}
+
+bool convertLegacyWifiChipCapabilitiesToAidl(
+ const legacy_hal::wifi_chip_capabilities& legacy_chip_capabilities,
+ WifiChipCapabilities& aidl_chip_capabilities) {
+ aidl_chip_capabilities.maxMloStrLinkCount = legacy_chip_capabilities.max_mlo_str_link_count;
+ aidl_chip_capabilities.maxMloAssociationLinkCount =
+ legacy_chip_capabilities.max_mlo_association_link_count;
+ aidl_chip_capabilities.maxConcurrentTdlsSessionCount =
+ legacy_chip_capabilities.max_concurrent_tdls_session_count;
+ return true;
+}
+
+uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask) {
+ uint32_t channel_category_mask = 0;
+ if (aidl_channel_category_mask &
+ static_cast<int32_t>(IWifiChip::ChannelCategoryMask::INDOOR_CHANNEL)) {
+ channel_category_mask |= legacy_hal::WIFI_INDOOR_CHANNEL;
+ }
+ if (aidl_channel_category_mask &
+ static_cast<int32_t>(IWifiChip::ChannelCategoryMask::DFS_CHANNEL)) {
+ channel_category_mask |= legacy_hal::WIFI_DFS_CHANNEL;
+ }
+ return channel_category_mask;
+}
+
+bool convertLegacyIfaceMaskToIfaceConcurrencyType(u32 mask,
+ std::vector<IfaceConcurrencyType>* types) {
+ if (!mask) return false;
+
+#ifndef BIT
+#define BIT(x) (1 << (x))
+#endif
+ if (mask & BIT(WIFI_INTERFACE_TYPE_STA)) types->push_back(IfaceConcurrencyType::STA);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_AP)) types->push_back(IfaceConcurrencyType::AP);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_AP_BRIDGED))
+ types->push_back(IfaceConcurrencyType::AP_BRIDGED);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_P2P)) types->push_back(IfaceConcurrencyType::P2P);
+ if (mask & BIT(WIFI_INTERFACE_TYPE_NAN)) types->push_back(IfaceConcurrencyType::NAN_IFACE);
+
+ return true;
+}
+
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+ legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode) {
+ if (!chip_mode) {
+ LOG(ERROR) << "chip_mode is null";
+ return false;
+ }
+ *chip_mode = {};
+
+ int num_combinations = legacy_matrix.num_iface_combinations;
+ std::vector<IWifiChip::ChipConcurrencyCombination> driver_Combinations_vec;
+ if (!num_combinations) {
+ LOG(ERROR) << "zero iface combinations";
+ return false;
+ }
+
+ for (int i = 0; i < num_combinations; i++) {
+ IWifiChip::ChipConcurrencyCombination chipComb;
+ std::vector<IWifiChip::ChipConcurrencyCombinationLimit> limits;
+ wifi_iface_combination* comb = &legacy_matrix.iface_combinations[i];
+ if (!comb->num_iface_limits) continue;
+ for (u32 j = 0; j < comb->num_iface_limits; j++) {
+ IWifiChip::ChipConcurrencyCombinationLimit chipLimit;
+ chipLimit.maxIfaces = comb->iface_limits[j].max_limit;
+ std::vector<IfaceConcurrencyType> types;
+ if (!convertLegacyIfaceMaskToIfaceConcurrencyType(comb->iface_limits[j].iface_mask,
+ &types)) {
+ LOG(ERROR) << "Failed to convert from iface_mask:"
+ << comb->iface_limits[j].iface_mask;
+ return false;
+ }
+ chipLimit.types = types;
+ limits.push_back(chipLimit);
+ }
+ chipComb.limits = limits;
+ driver_Combinations_vec.push_back(chipComb);
+ }
+
+ chip_mode->availableCombinations = driver_Combinations_vec;
+ return true;
+}
+
+} // namespace aidl_struct_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
new file mode 100644
index 0000000..e4ff963
--- /dev/null
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_STRUCT_UTIL_H_
+#define AIDL_STRUCT_UTIL_H_
+
+#include <aidl/android/hardware/wifi/IWifiChip.h>
+#include <aidl/android/hardware/wifi/IWifiChipEventCallback.h>
+#include <aidl/android/hardware/wifi/NanBandIndex.h>
+#include <aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.h>
+#include <aidl/android/hardware/wifi/StaScanDataFlagMask.h>
+#include <aidl/android/hardware/wifi/WifiDebugRingBufferFlags.h>
+#include <aidl/android/hardware/wifi/WifiIfaceMode.h>
+
+#include <vector>
+
+#include "wifi_legacy_hal.h"
+
+/**
+ * This file contains a bunch of functions to convert structs from the legacy
+ * HAL to AIDL and vice versa.
+ */
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_struct_util {
+
+// Chip conversion methods.
+bool convertLegacyChipFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set);
+bool convertLegacyDebugRingBufferStatusToAidl(
+ const legacy_hal::wifi_ring_buffer_status& legacy_status,
+ WifiDebugRingBufferStatus* aidl_status);
+bool convertLegacyVectorOfDebugRingBufferStatusToAidl(
+ const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+ std::vector<WifiDebugRingBufferStatus>* aidl_status_vec);
+bool convertLegacyWakeReasonStatsToAidl(const legacy_hal::WakeReasonStats& legacy_stats,
+ WifiDebugHostWakeReasonStats* aidl_stats);
+legacy_hal::wifi_power_scenario convertAidlTxPowerScenarioToLegacy(
+ IWifiChip::TxPowerScenario aidl_scenario);
+legacy_hal::wifi_latency_mode convertAidlLatencyModeToLegacy(
+ IWifiChip::LatencyMode aidl_latency_mode);
+bool convertLegacyWifiMacInfosToAidl(
+ const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+ std::vector<IWifiChipEventCallback::RadioModeInfo>* aidl_radio_mode_infos);
+legacy_hal::wifi_interface_type convertAidlIfaceTypeToLegacy(IfaceType aidl_interface_type);
+legacy_hal::wifi_multi_sta_use_case convertAidlMultiStaUseCaseToLegacy(
+ IWifiChip::MultiStaUseCase use_case);
+bool convertAidlCoexUnsafeChannelToLegacy(
+ const IWifiChip::CoexUnsafeChannel& aidl_unsafe_channel,
+ legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
+bool convertAidlVectorOfCoexUnsafeChannelToLegacy(
+ const std::vector<IWifiChip::CoexUnsafeChannel>& aidl_unsafe_channels,
+ std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
+bool convertLegacyRadioCombinationsMatrixToAidl(
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix,
+ std::vector<WifiRadioCombination>* aidl_combinations);
+WifiBand convertLegacyMacBandToAidlWifiBand(uint32_t band);
+WifiAntennaMode convertLegacyAntennaConfigurationToAidl(uint32_t antenna_cfg);
+bool convertLegacyIfaceCombinationsMatrixToChipMode(
+ legacy_hal::wifi_iface_concurrency_matrix& legacy_matrix, IWifiChip::ChipMode* chip_mode);
+
+// STA iface conversion methods.
+bool convertLegacyStaIfaceFeaturesToAidl(uint64_t legacy_feature_set, uint32_t* aidl_feature_set);
+bool convertLegacyApfCapabilitiesToAidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+ StaApfPacketFilterCapabilities* aidl_caps);
+bool convertLegacyGscanCapabilitiesToAidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+ StaBackgroundScanCapabilities* aidl_caps);
+legacy_hal::wifi_band convertAidlWifiBandToLegacy(WifiBand band);
+bool convertAidlGscanParamsToLegacy(const StaBackgroundScanParameters& aidl_scan_params,
+ legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
+// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
+// Information Elements (IEs)
+bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+ bool has_ie_data, StaScanResult* aidl_scan_result);
+// |cached_results| is assumed to not include IEs.
+bool convertLegacyVectorOfCachedGscanResultsToAidl(
+ const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+ std::vector<StaScanData>* aidl_scan_datas);
+bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
+ StaLinkLayerStats* aidl_stats);
+bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
+ StaLinkLayerStats* aidl_stats);
+bool convertLegacyRoamingCapabilitiesToAidl(
+ const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+ StaRoamingCapabilities* aidl_caps);
+bool convertAidlRoamingConfigToLegacy(const StaRoamingConfig& aidl_config,
+ legacy_hal::wifi_roaming_config* legacy_config);
+legacy_hal::fw_roaming_state_t convertAidlRoamingStateToLegacy(StaRoamingState state);
+bool convertLegacyVectorOfDebugTxPacketFateToAidl(
+ const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+ std::vector<WifiDebugTxPacketFateReport>* aidl_fates);
+bool convertLegacyVectorOfDebugRxPacketFateToAidl(
+ const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+ std::vector<WifiDebugRxPacketFateReport>* aidl_fates);
+
+// NAN iface conversion methods.
+void convertToNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+ NanStatus* nanStatus);
+bool convertAidlNanEnableRequestToLegacy(const NanEnableRequest& aidl_request1,
+ const NanConfigRequestSupplemental& aidl_request2,
+ legacy_hal::NanEnableRequest* legacy_request);
+bool convertAidlNanConfigRequestToLegacy(const NanConfigRequest& aidl_request1,
+ const NanConfigRequestSupplemental& aidl_request2,
+ legacy_hal::NanConfigRequest* legacy_request);
+bool convertAidlNanPublishRequestToLegacy(const NanPublishRequest& aidl_request,
+ legacy_hal::NanPublishRequest* legacy_request);
+bool convertAidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& aidl_request,
+ legacy_hal::NanSubscribeRequest* legacy_request);
+bool convertAidlNanTransmitFollowupRequestToLegacy(
+ const NanTransmitFollowupRequest& aidl_request,
+ legacy_hal::NanTransmitFollowupRequest* legacy_request);
+bool convertAidlNanDataPathInitiatorRequestToLegacy(
+ const NanInitiateDataPathRequest& aidl_request,
+ legacy_hal::NanDataPathInitiatorRequest* legacy_request);
+bool convertAidlNanDataPathIndicationResponseToLegacy(
+ const NanRespondToDataPathIndicationRequest& aidl_response,
+ legacy_hal::NanDataPathIndicationResponse* legacy_response);
+bool convertLegacyNanResponseHeaderToAidl(const legacy_hal::NanResponseMsg& legacy_response,
+ NanStatus* nanStatus);
+bool convertLegacyNanCapabilitiesResponseToAidl(const legacy_hal::NanCapabilities& legacy_response,
+ NanCapabilities* aidl_response);
+bool convertLegacyNanMatchIndToAidl(const legacy_hal::NanMatchInd& legacy_ind,
+ NanMatchInd* aidl_ind);
+bool convertLegacyNanFollowupIndToAidl(const legacy_hal::NanFollowupInd& legacy_ind,
+ NanFollowupReceivedInd* aidl_ind);
+bool convertLegacyNanDataPathRequestIndToAidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+ NanDataPathRequestInd* aidl_ind);
+bool convertLegacyNanDataPathConfirmIndToAidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+ NanDataPathConfirmInd* aidl_ind);
+bool convertLegacyNanDataPathScheduleUpdateIndToAidl(
+ const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+ NanDataPathScheduleUpdateInd* aidl_ind);
+
+// RTT controller conversion methods.
+bool convertAidlVectorOfRttConfigToLegacy(const std::vector<RttConfig>& aidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
+bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
+ legacy_hal::wifi_lci_information* legacy_info);
+bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
+ legacy_hal::wifi_lcr_information* legacy_info);
+bool convertAidlRttResponderToLegacy(const RttResponder& aidl_responder,
+ legacy_hal::wifi_rtt_responder* legacy_responder);
+bool convertAidlWifiChannelInfoToLegacy(const WifiChannelInfo& aidl_info,
+ legacy_hal::wifi_channel_info* legacy_info);
+bool convertLegacyRttResponderToAidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+ RttResponder* aidl_responder);
+bool convertLegacyRttCapabilitiesToAidl(
+ const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+ 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);
+uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand band);
+uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask);
+uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask);
+bool convertLegacyWifiUsableChannelsToAidl(
+ const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+ std::vector<WifiUsableChannel>* aidl_usable_channels);
+bool convertLegacyPeerInfoStatsToAidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+ StaPeerInfo* aidl_peer_info_stats);
+bool convertLegacyWifiRateInfoToAidl(const legacy_hal::wifi_rate& legacy_rate,
+ WifiRateInfo* aidl_rate);
+bool convertLegacyWifiChipCapabilitiesToAidl(
+ const legacy_hal::wifi_chip_capabilities& legacy_chip_capabilities,
+ WifiChipCapabilities& aidl_chip_capabilities);
+bool convertAidlNanPairingInitiatorRequestToLegacy(const NanPairingRequest& aidl_request,
+ legacy_hal::NanPairingRequest* legacy_request);
+bool convertAidlNanPairingIndicationResponseToLegacy(
+ const NanRespondToPairingIndicationRequest& aidl_response,
+ legacy_hal::NanPairingIndicationResponse* legacy_response);
+bool convertAidlNanBootstrappingInitiatorRequestToLegacy(
+ const NanBootstrappingRequest& aidl_request,
+ legacy_hal::NanBootstrappingRequest* legacy_request);
+bool convertAidlNanBootstrappingIndicationResponseToLegacy(
+ const NanBootstrappingResponse& aidl_response,
+ legacy_hal::NanBootstrappingIndicationResponse* legacy_response);
+bool convertLegacyNanPairingRequestIndToAidl(const legacy_hal::NanPairingRequestInd& legacy_ind,
+ NanPairingRequestInd* aidl_ind);
+bool convertLegacyNanPairingConfirmIndToAidl(const legacy_hal::NanPairingConfirmInd& legacy_ind,
+ NanPairingConfirmInd* aidl_ind);
+bool convertLegacyNanBootstrappingRequestIndToAidl(
+ const legacy_hal::NanBootstrappingRequestInd& legacy_ind,
+ NanBootstrappingRequestInd* aidl_ind);
+bool convertLegacyNanBootstrappingConfirmIndToAidl(
+ const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
+ NanBootstrappingConfirmInd* aidl_ind);
+uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask);
+} // namespace aidl_struct_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // AIDL_STRUCT_UTIL_H_
diff --git a/wifi/aidl/default/aidl_sync_util.cpp b/wifi/aidl/default/aidl_sync_util.cpp
new file mode 100644
index 0000000..d81eb81
--- /dev/null
+++ b/wifi/aidl/default/aidl_sync_util.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "aidl_sync_util.h"
+
+namespace {
+std::recursive_mutex g_mutex;
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_sync_util {
+
+std::unique_lock<std::recursive_mutex> acquireGlobalLock() {
+ return std::unique_lock<std::recursive_mutex>{g_mutex};
+}
+
+} // namespace aidl_sync_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/aidl_sync_util.h b/wifi/aidl/default/aidl_sync_util.h
new file mode 100644
index 0000000..a61cd3f
--- /dev/null
+++ b/wifi/aidl/default/aidl_sync_util.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AIDL_SYNC_UTIL_H_
+#define AIDL_SYNC_UTIL_H_
+
+#include <mutex>
+
+// Utility that provides a global lock to synchronize access between
+// the AIDL thread and the legacy HAL's event loop.
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace aidl_sync_util {
+std::unique_lock<std::recursive_mutex> acquireGlobalLock();
+} // namespace aidl_sync_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+#endif // AIDL_SYNC_UTIL_H_
diff --git a/wifi/aidl/default/android.hardware.wifi-service-lazy.rc b/wifi/aidl/default/android.hardware.wifi-service-lazy.rc
new file mode 100644
index 0000000..12d3ff7
--- /dev/null
+++ b/wifi/aidl/default/android.hardware.wifi-service-lazy.rc
@@ -0,0 +1,8 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi-service-lazy
+ interface aidl android.hardware.wifi.IWifi/default
+ oneshot
+ disabled
+ class hal
+ capabilities NET_ADMIN NET_RAW SYS_MODULE
+ user wifi
+ group wifi gps
diff --git a/wifi/aidl/default/android.hardware.wifi-service.rc b/wifi/aidl/default/android.hardware.wifi-service.rc
new file mode 100644
index 0000000..ec8acf5
--- /dev/null
+++ b/wifi/aidl/default/android.hardware.wifi-service.rc
@@ -0,0 +1,6 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi-service
+ interface aidl android.hardware.wifi.IWifi/default
+ class hal
+ capabilities NET_ADMIN NET_RAW SYS_MODULE
+ user wifi
+ group wifi gps
diff --git a/wifi/aidl/default/android.hardware.wifi-service.xml b/wifi/aidl/default/android.hardware.wifi-service.xml
new file mode 100644
index 0000000..5398ee7
--- /dev/null
+++ b/wifi/aidl/default/android.hardware.wifi-service.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.wifi</name>
+ <fqname>IWifi/default</fqname>
+ </hal>
+</manifest>
diff --git a/wifi/aidl/default/ringbuffer.cpp b/wifi/aidl/default/ringbuffer.cpp
new file mode 100644
index 0000000..9d08a73
--- /dev/null
+++ b/wifi/aidl/default/ringbuffer.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ringbuffer.h"
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
+
+enum Ringbuffer::AppendStatus Ringbuffer::append(const std::vector<uint8_t>& input) {
+ if (input.size() == 0) {
+ return AppendStatus::FAIL_IP_BUFFER_ZERO;
+ }
+ if (input.size() > maxSize_) {
+ LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped";
+ return AppendStatus::FAIL_IP_BUFFER_EXCEEDED_MAXSIZE;
+ }
+ data_.push_back(input);
+ size_ += input.size() * sizeof(input[0]);
+ while (size_ > maxSize_) {
+ if (data_.front().size() <= 0 || data_.front().size() > maxSize_) {
+ LOG(ERROR) << "First buffer in the ring buffer is Invalid. Size: "
+ << data_.front().size();
+ return AppendStatus::FAIL_RING_BUFFER_CORRUPTED;
+ }
+ size_ -= data_.front().size() * sizeof(data_.front()[0]);
+ data_.pop_front();
+ }
+ return AppendStatus::SUCCESS;
+}
+
+const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
+ return data_;
+}
+
+void Ringbuffer::clear() {
+ data_.clear();
+ size_ = 0;
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/ringbuffer.h b/wifi/aidl/default/ringbuffer.h
new file mode 100644
index 0000000..80c0c11
--- /dev/null
+++ b/wifi/aidl/default/ringbuffer.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#ifndef RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+#include <list>
+#include <vector>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * Ringbuffer object used to store debug data.
+ */
+class Ringbuffer {
+ public:
+ // Error codes for the append ring buffer operation
+ enum AppendStatus {
+ SUCCESS,
+ FAIL_GENERIC,
+ FAIL_IP_BUFFER_ZERO,
+ FAIL_IP_BUFFER_EXCEEDED_MAXSIZE,
+ FAIL_RING_BUFFER_CORRUPTED
+ };
+ explicit Ringbuffer(size_t maxSize);
+
+ // Appends the data buffer and deletes from the front until buffer is
+ // within |maxSize_|.
+ enum AppendStatus append(const std::vector<uint8_t>& input);
+ const std::list<std::vector<uint8_t>>& getData() const;
+ void clear();
+
+ private:
+ std::list<std::vector<uint8_t>> data_;
+ size_t size_;
+ size_t maxSize_;
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // RINGBUFFER_H_
diff --git a/wifi/aidl/default/service.cpp b/wifi/aidl/default/service.cpp
new file mode 100644
index 0000000..789a7a5
--- /dev/null
+++ b/wifi/aidl/default/service.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <signal.h>
+
+#include "wifi.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_mode_controller.h"
+
+using aidl::android::hardware::wifi::feature_flags::WifiFeatureFlags;
+using aidl::android::hardware::wifi::legacy_hal::WifiLegacyHal;
+using aidl::android::hardware::wifi::legacy_hal::WifiLegacyHalFactory;
+using aidl::android::hardware::wifi::mode_controller::WifiModeController;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main(int /*argc*/, char** argv) {
+ signal(SIGPIPE, SIG_IGN);
+ android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
+ LOG(INFO) << "Wifi Hal is booting up...";
+
+ // Prepare the RPC-serving thread pool. Allocate 1 thread in the pool,
+ // which our main thread will join below.
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+
+ const auto iface_tool = std::make_shared<::android::wifi_system::InterfaceTool>();
+ const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool);
+
+ // Setup binder service
+ std::shared_ptr<aidl::android::hardware::wifi::Wifi> service =
+ ndk::SharedRefBase::make<aidl::android::hardware::wifi::Wifi>(
+ iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(),
+ std::make_shared<WifiFeatureFlags>());
+ std::string instance =
+ std::string() + aidl::android::hardware::wifi::Wifi::descriptor + "/default";
+ if (kLazyService) {
+ auto result =
+ AServiceManager_registerLazyService(service->asBinder().get(), instance.c_str());
+ CHECK_EQ(result, STATUS_OK) << "Failed to register lazy wifi HAL";
+ } else {
+ auto result = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ CHECK_EQ(result, STATUS_OK) << "Failed to register wifi HAL";
+ }
+
+ ABinderProcess_startThreadPool();
+ LOG(INFO) << "Joining RPC thread pool";
+ ABinderProcess_joinThreadPool();
+
+ LOG(INFO) << "Wifi Hal is terminating...";
+ return 0;
+}
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
new file mode 100644
index 0000000..5c334f8
--- /dev/null
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -0,0 +1,873 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "aidl_struct_util.h"
+
+using testing::Test;
+
+namespace {
+constexpr uint32_t kMacId1 = 1;
+constexpr uint32_t kMacId2 = 2;
+constexpr uint32_t kIfaceChannel1 = 3;
+constexpr uint32_t kIfaceChannel2 = 5;
+constexpr char kIfaceName1[] = "wlan0";
+constexpr char kIfaceName2[] = "wlan1";
+constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
+byte LCI[] = {0x27, 0x1A, 0x1, 0x00, 0x8, 0x01, 0x00, 0x08, 0x00, 0x10, 0x52,
+ 0x83, 0x4d, 0x12, 0xef, 0xd2, 0xb0, 0x8b, 0x9b, 0x4b, 0xf1, 0xcc,
+ 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};
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class AidlStructUtilTest : public Test {};
+
+TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithOneMac) {
+ std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
+ legacy_hal::WifiMacInfo legacy_mac_info1 = {
+ .wlan_mac_id = kMacId1,
+ .mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
+ legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
+ legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
+ legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
+ legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
+ legacy_mac_infos.push_back(legacy_mac_info1);
+
+ std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
+ ASSERT_TRUE(aidl_struct_util::convertLegacyWifiMacInfosToAidl(legacy_mac_infos,
+ &aidl_radio_mode_infos));
+
+ ASSERT_EQ(1u, aidl_radio_mode_infos.size());
+ auto aidl_radio_mode_info1 = aidl_radio_mode_infos[0];
+ EXPECT_EQ(legacy_mac_info1.wlan_mac_id, (uint32_t)aidl_radio_mode_info1.radioId);
+ EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, aidl_radio_mode_info1.bandInfo);
+ ASSERT_EQ(2u, aidl_radio_mode_info1.ifaceInfos.size());
+ auto aidl_iface_info1 = aidl_radio_mode_info1.ifaceInfos[0];
+ EXPECT_EQ(legacy_iface_info1.name, aidl_iface_info1.name);
+ EXPECT_EQ(static_cast<int32_t>(legacy_iface_info1.channel), aidl_iface_info1.channel);
+ auto aidl_iface_info2 = aidl_radio_mode_info1.ifaceInfos[1];
+ EXPECT_EQ(legacy_iface_info2.name, aidl_iface_info2.name);
+ EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
+}
+
+TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithTwoMac) {
+ std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
+ legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1,
+ .mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
+ legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
+ legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2,
+ .mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
+ legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
+ legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
+ legacy_mac_infos.push_back(legacy_mac_info1);
+ legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
+ legacy_mac_infos.push_back(legacy_mac_info2);
+
+ std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
+ ASSERT_TRUE(aidl_struct_util::convertLegacyWifiMacInfosToAidl(legacy_mac_infos,
+ &aidl_radio_mode_infos));
+
+ ASSERT_EQ(2u, aidl_radio_mode_infos.size());
+
+ // Find mac info 1.
+ const auto aidl_radio_mode_info1 =
+ std::find_if(aidl_radio_mode_infos.begin(), aidl_radio_mode_infos.end(),
+ [&legacy_mac_info1](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return (uint32_t)x.radioId == legacy_mac_info1.wlan_mac_id;
+ });
+ ASSERT_NE(aidl_radio_mode_infos.end(), aidl_radio_mode_info1);
+ EXPECT_EQ(WifiBand::BAND_5GHZ, aidl_radio_mode_info1->bandInfo);
+ ASSERT_EQ(1u, aidl_radio_mode_info1->ifaceInfos.size());
+ auto aidl_iface_info1 = aidl_radio_mode_info1->ifaceInfos[0];
+ EXPECT_EQ(legacy_iface_info1.name, aidl_iface_info1.name);
+ EXPECT_EQ(static_cast<int32_t>(legacy_iface_info1.channel), aidl_iface_info1.channel);
+
+ // Find mac info 2.
+ const auto aidl_radio_mode_info2 =
+ std::find_if(aidl_radio_mode_infos.begin(), aidl_radio_mode_infos.end(),
+ [&legacy_mac_info2](const IWifiChipEventCallback::RadioModeInfo& x) {
+ return (uint32_t)x.radioId == legacy_mac_info2.wlan_mac_id;
+ });
+ ASSERT_NE(aidl_radio_mode_infos.end(), aidl_radio_mode_info2);
+ EXPECT_EQ(WifiBand::BAND_24GHZ, aidl_radio_mode_info2->bandInfo);
+ ASSERT_EQ(1u, aidl_radio_mode_info2->ifaceInfos.size());
+ auto aidl_iface_info2 = aidl_radio_mode_info2->ifaceInfos[0];
+ EXPECT_EQ(legacy_iface_info2.name, aidl_iface_info2.name);
+ EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
+}
+
+TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerMlStatsToAidl) {
+ legacy_hal::LinkLayerMlStats legacy_ml_stats{};
+ // Add two radio stats
+ legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ // Add two links.
+ legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
+ legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
+ // Set stats for each link.
+ for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
+ link.peers.push_back(legacy_hal::WifiPeerInfo{});
+ link.peers.push_back(legacy_hal::WifiPeerInfo{});
+ link.stat.beacon_rx = rand();
+ // MLO link id: 0 - 15
+ link.stat.link_id = rand() % 16;
+ // Maximum number of radios is limited to 3 for testing.
+ link.stat.radio = rand() % 4;
+ link.stat.frequency = rand();
+ // RSSI: 0 to -127
+ link.stat.rssi_mgmt = (rand() % 128) * -1;
+ link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
+
+ link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
+
+ link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
+
+ link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
+
+ link.stat.time_slicing_duty_cycle_percent = rand() % 101;
+ link.stat.num_peers = 2;
+
+ // Set peer stats for each of the peers.
+ for (auto& peer : link.peers) {
+ // Max station count is limited to 32 for testing.
+ peer.peer_info.bssload.sta_count = rand() % 33;
+ peer.peer_info.bssload.chan_util = rand() % 101;
+ wifi_rate_stat rate_stat1 = {
+ .rate = {3, 1, 2, 5, 0, 0},
+ .tx_mpdu = 0,
+ .rx_mpdu = 1,
+ .mpdu_lost = 2,
+ .retries = 3,
+ .retries_short = 4,
+ .retries_long = 5,
+ };
+ wifi_rate_stat rate_stat2 = {
+ .rate = {2, 2, 1, 6, 0, 1},
+ .tx_mpdu = 6,
+ .rx_mpdu = 7,
+ .mpdu_lost = 8,
+ .retries = 9,
+ .retries_short = 10,
+ .retries_long = 11,
+ };
+ peer.rate_stats.push_back(rate_stat1);
+ peer.rate_stats.push_back(rate_stat2);
+ }
+ }
+ // Set radio stats
+ for (auto& radio : legacy_ml_stats.radios) {
+ // Maximum number of radios is limited to 3 for testing.
+ radio.stats.radio = rand() % 4;
+ radio.stats.on_time = rand();
+ radio.stats.tx_time = rand();
+ radio.stats.rx_time = rand();
+ radio.stats.on_time_scan = rand();
+ radio.stats.on_time_nbd = rand();
+ radio.stats.on_time_gscan = rand();
+ radio.stats.on_time_roam_scan = rand();
+ radio.stats.on_time_pno_scan = rand();
+ radio.stats.on_time_hs20 = rand();
+ for (int i = 0; i < 4; i++) {
+ radio.tx_time_per_levels.push_back(rand());
+ }
+
+ legacy_hal::wifi_channel_stat channel_stat1 = {
+ .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+ .on_time = 0x1111,
+ .cca_busy_time = 0x55,
+ };
+ legacy_hal::wifi_channel_stat channel_stat2 = {
+ .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+ .on_time = 0x2222,
+ .cca_busy_time = 0x66,
+ };
+ radio.channel_stats.push_back(channel_stat1);
+ radio.channel_stats.push_back(channel_stat2);
+ }
+ // Convert to AIDL
+ StaLinkLayerStats converted{};
+ aidl_struct_util::convertLegacyLinkLayerMlStatsToAidl(legacy_ml_stats, &converted);
+ // Validate
+ int l = 0;
+ for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
+ EXPECT_EQ(link.stat.link_id, (uint8_t)converted.iface.links[l].linkId);
+ EXPECT_EQ(link.stat.radio, converted.iface.links[l].radioId);
+ EXPECT_EQ(link.stat.frequency, (uint32_t)converted.iface.links[l].frequencyMhz);
+ EXPECT_EQ(link.stat.beacon_rx, (uint32_t)converted.iface.links[l].beaconRx);
+ EXPECT_EQ(link.stat.rssi_mgmt, converted.iface.links[l].avgRssiMgmt);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
+ converted.iface.links[l].wmeBePktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
+ converted.iface.links[l].wmeBePktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
+ converted.iface.links[l].wmeBePktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].retries,
+ converted.iface.links[l].wmeBePktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeBeContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeBeContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeBeContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeBeContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
+ converted.iface.links[l].wmeBkPktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
+ converted.iface.links[l].wmeBkPktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
+ converted.iface.links[l].wmeBkPktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].retries,
+ converted.iface.links[l].wmeBkPktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeBkContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeBkContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeBkContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeBkContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
+ converted.iface.links[l].wmeViPktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
+ converted.iface.links[l].wmeViPktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
+ converted.iface.links[l].wmeViPktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].retries,
+ converted.iface.links[l].wmeViPktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeViContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeViContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeViContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeViContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
+ converted.iface.links[l].wmeVoPktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
+ converted.iface.links[l].wmeVoPktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
+ converted.iface.links[l].wmeVoPktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].retries,
+ converted.iface.links[l].wmeVoPktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeVoContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeVoContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeVoContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeVoContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.time_slicing_duty_cycle_percent,
+ converted.iface.links[l].timeSliceDutyCycleInPercent);
+
+ EXPECT_EQ(link.peers.size(), converted.iface.links[l].peers.size());
+ for (size_t i = 0; i < link.peers.size(); i++) {
+ EXPECT_EQ(link.peers[i].peer_info.bssload.sta_count,
+ converted.iface.links[l].peers[i].staCount);
+ EXPECT_EQ(link.peers[i].peer_info.bssload.chan_util,
+ converted.iface.links[l].peers[i].chanUtil);
+ for (size_t j = 0; j < link.peers[i].rate_stats.size(); j++) {
+ EXPECT_EQ(
+ link.peers[i].rate_stats[j].rate.preamble,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.preamble);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rate.nss,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.nss);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rate.bw,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.bw);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rate.rateMcsIdx,
+ (uint32_t)converted.iface.links[l]
+ .peers[i]
+ .rateStats[j]
+ .rateInfo.rateMcsIdx);
+ EXPECT_EQ(link.peers[i].rate_stats[j].tx_mpdu,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].txMpdu);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rx_mpdu,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rxMpdu);
+ EXPECT_EQ(link.peers[i].rate_stats[j].mpdu_lost,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].mpduLost);
+ EXPECT_EQ(link.peers[i].rate_stats[j].retries,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].retries);
+ }
+ }
+ ++l;
+ } // loop over links
+
+ EXPECT_EQ(legacy_ml_stats.radios.size(), converted.radios.size());
+ for (size_t i = 0; i < legacy_ml_stats.radios.size(); i++) {
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.radio, converted.radios[i].radioId);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time,
+ (uint32_t)converted.radios[i].onTimeInMs);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.tx_time,
+ (uint32_t)converted.radios[i].txTimeInMs);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.rx_time,
+ (uint32_t)converted.radios[i].rxTimeInMs);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].tx_time_per_levels.size(),
+ converted.radios[i].txTimeInMsPerLevel.size());
+ for (size_t j = 0; j < legacy_ml_stats.radios[i].tx_time_per_levels.size(); j++) {
+ EXPECT_EQ(legacy_ml_stats.radios[i].tx_time_per_levels[j],
+ (uint32_t)converted.radios[i].txTimeInMsPerLevel[j]);
+ }
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_nbd,
+ (uint32_t)converted.radios[i].onTimeInMsForNanScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_gscan,
+ (uint32_t)converted.radios[i].onTimeInMsForBgScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_roam_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForRoamScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_pno_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForPnoScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_hs20,
+ (uint32_t)converted.radios[i].onTimeInMsForHs20Scan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].channel_stats.size(),
+ converted.radios[i].channelStats.size());
+ for (size_t k = 0; k < legacy_ml_stats.radios[i].channel_stats.size(); k++) {
+ auto& legacy_channel_st = legacy_ml_stats.radios[i].channel_stats[k];
+ EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
+ converted.radios[i].channelStats[k].channel.width);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq,
+ converted.radios[i].channelStats[k].channel.centerFreq);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq0,
+ converted.radios[i].channelStats[k].channel.centerFreq0);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq1,
+ converted.radios[i].channelStats[k].channel.centerFreq1);
+ EXPECT_EQ(legacy_channel_st.cca_busy_time,
+ (uint32_t)converted.radios[i].channelStats[k].ccaBusyTimeInMs);
+ EXPECT_EQ(legacy_channel_st.on_time,
+ (uint32_t)converted.radios[i].channelStats[k].onTimeInMs);
+ }
+ }
+}
+
+TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerStatsToAidl) {
+ legacy_hal::LinkLayerStats legacy_stats{};
+ legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
+ legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
+ legacy_stats.iface.beacon_rx = rand();
+ // RSSI: 0 to -127
+ legacy_stats.iface.rssi_mgmt = rand() % 128;
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
+
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
+
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
+
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
+ legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
+
+ legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand() % 101;
+ legacy_stats.iface.num_peers = 1;
+
+ for (auto& radio : legacy_stats.radios) {
+ // Max number of radios limit to 3.
+ radio.stats.radio = rand() % 4;
+ radio.stats.on_time = rand();
+ radio.stats.tx_time = rand();
+ radio.stats.rx_time = rand();
+ radio.stats.on_time_scan = rand();
+ radio.stats.on_time_nbd = rand();
+ radio.stats.on_time_gscan = rand();
+ radio.stats.on_time_roam_scan = rand();
+ radio.stats.on_time_pno_scan = rand();
+ radio.stats.on_time_hs20 = rand();
+ for (int i = 0; i < 4; i++) {
+ radio.tx_time_per_levels.push_back(rand());
+ }
+
+ legacy_hal::wifi_channel_stat channel_stat1 = {
+ .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+ .on_time = 0x1111,
+ .cca_busy_time = 0x55,
+ };
+ legacy_hal::wifi_channel_stat channel_stat2 = {
+ .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+ .on_time = 0x2222,
+ .cca_busy_time = 0x66,
+ };
+ radio.channel_stats.push_back(channel_stat1);
+ radio.channel_stats.push_back(channel_stat2);
+ }
+
+ for (auto& peer : legacy_stats.peers) {
+ // Max number of stations is limited to 32 for testing.
+ peer.peer_info.bssload.sta_count = rand() % 33;
+ peer.peer_info.bssload.chan_util = rand() % 101;
+ wifi_rate_stat rate_stat1 = {
+ .rate = {3, 1, 2, 5, 0, 0},
+ .tx_mpdu = 0,
+ .rx_mpdu = 1,
+ .mpdu_lost = 2,
+ .retries = 3,
+ .retries_short = 4,
+ .retries_long = 5,
+ };
+ wifi_rate_stat rate_stat2 = {
+ .rate = {2, 2, 1, 6, 0, 1},
+ .tx_mpdu = 6,
+ .rx_mpdu = 7,
+ .mpdu_lost = 8,
+ .retries = 9,
+ .retries_short = 10,
+ .retries_long = 11,
+ };
+ peer.rate_stats.push_back(rate_stat1);
+ peer.rate_stats.push_back(rate_stat2);
+ }
+
+ StaLinkLayerStats converted{};
+ aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &converted);
+ EXPECT_EQ(0, converted.iface.links[0].linkId);
+ EXPECT_EQ(legacy_stats.iface.beacon_rx, (uint32_t)converted.iface.links[0].beaconRx);
+ EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.links[0].avgRssiMgmt);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
+ converted.iface.links[0].wmeBePktStats.rxMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
+ converted.iface.links[0].wmeBePktStats.txMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
+ converted.iface.links[0].wmeBePktStats.lostMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
+ converted.iface.links[0].wmeBePktStats.retries);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
+ converted.iface.links[0].wmeBkPktStats.rxMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
+ converted.iface.links[0].wmeBkPktStats.txMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
+ converted.iface.links[0].wmeBkPktStats.lostMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
+ converted.iface.links[0].wmeBkPktStats.retries);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
+ converted.iface.links[0].wmeViPktStats.rxMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
+ converted.iface.links[0].wmeViPktStats.txMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
+ converted.iface.links[0].wmeViPktStats.lostMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
+ converted.iface.links[0].wmeViPktStats.retries);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
+ converted.iface.links[0].wmeVoPktStats.rxMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
+ converted.iface.links[0].wmeVoPktStats.txMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
+ converted.iface.links[0].wmeVoPktStats.lostMpdu);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
+ converted.iface.links[0].wmeVoPktStats.retries);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
+ converted.iface.links[0].timeSliceDutyCycleInPercent);
+
+ EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
+ for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
+ EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId);
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time, (uint32_t)converted.radios[i].onTimeInMs);
+ EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, (uint32_t)converted.radios[i].txTimeInMs);
+ EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, (uint32_t)converted.radios[i].rxTimeInMs);
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForScan);
+ EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(),
+ converted.radios[i].txTimeInMsPerLevel.size());
+ for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) {
+ EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j],
+ (uint32_t)converted.radios[i].txTimeInMsPerLevel[j]);
+ }
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd,
+ (uint32_t)converted.radios[i].onTimeInMsForNanScan);
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan,
+ (uint32_t)converted.radios[i].onTimeInMsForBgScan);
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForRoamScan);
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForPnoScan);
+ EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20,
+ (uint32_t)converted.radios[i].onTimeInMsForHs20Scan);
+ EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(),
+ converted.radios[i].channelStats.size());
+ for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) {
+ auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k];
+ EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
+ converted.radios[i].channelStats[k].channel.width);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq,
+ converted.radios[i].channelStats[k].channel.centerFreq);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq0,
+ converted.radios[i].channelStats[k].channel.centerFreq0);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq1,
+ converted.radios[i].channelStats[k].channel.centerFreq1);
+ EXPECT_EQ(legacy_channel_st.cca_busy_time,
+ (uint32_t)converted.radios[i].channelStats[k].ccaBusyTimeInMs);
+ EXPECT_EQ(legacy_channel_st.on_time,
+ (uint32_t)converted.radios[i].channelStats[k].onTimeInMs);
+ }
+ }
+
+ EXPECT_EQ(legacy_stats.peers.size(), converted.iface.links[0].peers.size());
+ for (size_t i = 0; i < legacy_stats.peers.size(); i++) {
+ EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count,
+ converted.iface.links[0].peers[i].staCount);
+ EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util,
+ converted.iface.links[0].peers[i].chanUtil);
+ for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.preamble);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.nss);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.bw);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.rateMcsIdx);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].txMpdu);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rxMpdu);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].mpduLost);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries,
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].retries);
+ }
+ }
+}
+
+TEST_F(AidlStructUtilTest, CanConvertLegacyFeaturesToAidl) {
+ using AidlChipCaps = IWifiChip::FeatureSetMask;
+
+ uint32_t aidl_features;
+ uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
+
+ ASSERT_TRUE(
+ aidl_struct_util::convertLegacyChipFeaturesToAidl(legacy_feature_set, &aidl_features));
+
+ EXPECT_EQ((uint32_t)AidlChipCaps::D2D_RTT | (uint32_t)AidlChipCaps::SET_LATENCY_MODE,
+ aidl_features);
+}
+
+void insertRadioCombination(legacy_hal::wifi_radio_combination* dst_radio_combination_ptr,
+ int num_radio_configurations,
+ legacy_hal::wifi_radio_configuration* radio_configuration) {
+ dst_radio_combination_ptr->num_radio_configurations = num_radio_configurations;
+ memcpy(dst_radio_combination_ptr->radio_configurations, radio_configuration,
+ num_radio_configurations * sizeof(legacy_hal::wifi_radio_configuration));
+}
+
+void verifyRadioCombination(WifiRadioCombination* radioCombination, size_t num_radio_configurations,
+ legacy_hal::wifi_radio_configuration* radio_configuration) {
+ EXPECT_EQ(num_radio_configurations, radioCombination->radioConfigurations.size());
+ for (size_t i = 0; i < num_radio_configurations; i++) {
+ EXPECT_EQ(aidl_struct_util::convertLegacyMacBandToAidlWifiBand(radio_configuration->band),
+ radioCombination->radioConfigurations[i].bandInfo);
+ EXPECT_EQ(aidl_struct_util::convertLegacyAntennaConfigurationToAidl(
+ radio_configuration->antenna_cfg),
+ radioCombination->radioConfigurations[i].antennaMode);
+ radio_configuration++;
+ }
+}
+
+TEST_F(AidlStructUtilTest, canConvertLegacyRadioCombinationsMatrixToAidl) {
+ legacy_hal::wifi_radio_configuration radio_configurations_array1[] = {
+ {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
+ };
+ legacy_hal::wifi_radio_configuration radio_configurations_array2[] = {
+ {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
+ {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_3X3},
+ };
+ legacy_hal::wifi_radio_configuration radio_configurations_array3[] = {
+ {.band = legacy_hal::WLAN_MAC_2_4_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_2X2},
+ {.band = legacy_hal::WLAN_MAC_6_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_1X1},
+ {.band = legacy_hal::WLAN_MAC_5_0_BAND, .antenna_cfg = legacy_hal::WIFI_ANTENNA_4X4},
+ };
+
+ int num_radio_configs = 0;
+ int num_combinations = 0;
+ std::array<char, 256> buffer;
+ buffer.fill(0);
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix =
+ reinterpret_cast<wifi_radio_combination_matrix*>(buffer.data());
+ legacy_hal::wifi_radio_combination* radio_combinations;
+
+ // Prepare a legacy wifi_radio_combination_matrix
+ legacy_matrix->num_radio_combinations = 3;
+ // Insert first combination
+ radio_combinations =
+ (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations);
+ insertRadioCombination(
+ radio_combinations,
+ sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
+ radio_configurations_array1);
+ num_combinations++;
+ num_radio_configs +=
+ sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]);
+
+ // Insert second combination
+ radio_combinations =
+ (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
+ (num_combinations *
+ sizeof(legacy_hal::wifi_radio_combination)) +
+ (num_radio_configs *
+ sizeof(wifi_radio_configuration)));
+ insertRadioCombination(
+ radio_combinations,
+ sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
+ radio_configurations_array2);
+ num_combinations++;
+ num_radio_configs +=
+ sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]);
+
+ // Insert third combination
+ radio_combinations =
+ (legacy_hal::wifi_radio_combination*)((char*)legacy_matrix->radio_combinations +
+ (num_combinations *
+ sizeof(legacy_hal::wifi_radio_combination)) +
+ (num_radio_configs *
+ sizeof(wifi_radio_configuration)));
+ insertRadioCombination(
+ radio_combinations,
+ sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
+ radio_configurations_array3);
+
+ std::vector<WifiRadioCombination> converted_combinations;
+ aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
+ &converted_combinations);
+
+ // Verify the conversion
+ EXPECT_EQ(legacy_matrix->num_radio_combinations, converted_combinations.size());
+ verifyRadioCombination(
+ &converted_combinations[0],
+ sizeof(radio_configurations_array1) / sizeof(radio_configurations_array1[0]),
+ radio_configurations_array1);
+ verifyRadioCombination(
+ &converted_combinations[1],
+ sizeof(radio_configurations_array2) / sizeof(radio_configurations_array2[0]),
+ radio_configurations_array2);
+ verifyRadioCombination(
+ &converted_combinations[2],
+ sizeof(radio_configurations_array3) / sizeof(radio_configurations_array3[0]),
+ radio_configurations_array3);
+}
+
+void verifyRttResult(wifi_rtt_result* legacy_rtt_result_ptr, RttResult* aidl_results_ptr) {
+ EXPECT_EQ((int)legacy_rtt_result_ptr->burst_num, aidl_results_ptr->burstNum);
+ EXPECT_EQ((int)legacy_rtt_result_ptr->measurement_number, aidl_results_ptr->measurementNumber);
+ EXPECT_EQ((int)legacy_rtt_result_ptr->success_number, aidl_results_ptr->successNumber);
+ EXPECT_EQ(legacy_rtt_result_ptr->number_per_burst_peer, aidl_results_ptr->numberPerBurstPeer);
+ EXPECT_EQ(legacy_rtt_result_ptr->retry_after_duration, aidl_results_ptr->retryAfterDuration);
+ EXPECT_EQ(legacy_rtt_result_ptr->rssi, aidl_results_ptr->rssi);
+ EXPECT_EQ(legacy_rtt_result_ptr->rssi_spread, aidl_results_ptr->rssiSpread);
+ EXPECT_EQ(legacy_rtt_result_ptr->rtt, aidl_results_ptr->rtt);
+ EXPECT_EQ(legacy_rtt_result_ptr->rtt_sd, aidl_results_ptr->rttSd);
+ EXPECT_EQ(legacy_rtt_result_ptr->rtt_spread, aidl_results_ptr->rttSpread);
+ EXPECT_EQ(legacy_rtt_result_ptr->distance_mm, aidl_results_ptr->distanceInMm);
+ EXPECT_EQ(legacy_rtt_result_ptr->distance_sd_mm, aidl_results_ptr->distanceSdInMm);
+ EXPECT_EQ(legacy_rtt_result_ptr->distance_spread_mm, aidl_results_ptr->distanceSpreadInMm);
+ EXPECT_EQ(legacy_rtt_result_ptr->ts, aidl_results_ptr->timeStampInUs);
+ EXPECT_EQ(legacy_rtt_result_ptr->burst_duration, aidl_results_ptr->burstDurationInMs);
+ EXPECT_EQ(legacy_rtt_result_ptr->negotiated_burst_num, aidl_results_ptr->negotiatedBurstNum);
+ EXPECT_EQ(legacy_rtt_result_ptr->LCI->id, aidl_results_ptr->lci.id);
+ for (int i = 0; i < legacy_rtt_result_ptr->LCI->len; i++) {
+ EXPECT_EQ(legacy_rtt_result_ptr->LCI->data[i], aidl_results_ptr->lci.data[i]);
+ }
+ EXPECT_EQ(legacy_rtt_result_ptr->LCR->id, aidl_results_ptr->lcr.id);
+ for (int i = 0; i < legacy_rtt_result_ptr->LCR->len; i++) {
+ EXPECT_EQ(legacy_rtt_result_ptr->LCR->data[i], aidl_results_ptr->lcr.data[i]);
+ }
+}
+
+void fillLegacyRttResult(wifi_rtt_result* rtt_result_ptr) {
+ std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(rtt_result_ptr->addr));
+ rtt_result_ptr->burst_num = rand();
+ rtt_result_ptr->measurement_number = rand();
+ rtt_result_ptr->success_number = rand();
+ rtt_result_ptr->number_per_burst_peer = 0xF & rand();
+ rtt_result_ptr->status = RTT_STATUS_SUCCESS;
+ rtt_result_ptr->retry_after_duration = 0xF & rand();
+ rtt_result_ptr->type = RTT_TYPE_2_SIDED;
+ rtt_result_ptr->rssi = rand();
+ rtt_result_ptr->rssi_spread = rand();
+ rtt_result_ptr->rtt = rand();
+ rtt_result_ptr->rtt_sd = rand();
+ rtt_result_ptr->rtt_spread = rand();
+ rtt_result_ptr->distance_mm = rand();
+ rtt_result_ptr->distance_sd_mm = rand();
+ rtt_result_ptr->distance_spread_mm = rand();
+ rtt_result_ptr->burst_duration = rand();
+ rtt_result_ptr->negotiated_burst_num = rand();
+ rtt_result_ptr->LCI = (wifi_information_element*)LCI;
+ rtt_result_ptr->LCR = (wifi_information_element*)LCR;
+}
+
+TEST_F(AidlStructUtilTest, convertLegacyVectorOfRttResultToAidl) {
+ std::vector<const wifi_rtt_result*> rtt_results_vec;
+ wifi_rtt_result rttResults[2];
+
+ // fill legacy rtt results
+ for (int i = 0; i < 2; i++) {
+ fillLegacyRttResult(&rttResults[i]);
+ rtt_results_vec.push_back(&rttResults[i]);
+ }
+
+ std::vector<RttResult> aidl_results;
+ aidl_struct_util::convertLegacyVectorOfRttResultToAidl(rtt_results_vec, &aidl_results);
+
+ EXPECT_EQ(rtt_results_vec.size(), aidl_results.size());
+ for (size_t i = 0; i < rtt_results_vec.size(); i++) {
+ verifyRttResult(&rttResults[i], &aidl_results[i]);
+ EXPECT_EQ(aidl_results[i].channelFreqMHz, 0);
+ EXPECT_EQ(aidl_results[i].packetBw, RttBw::BW_UNSPECIFIED);
+ }
+}
+
+TEST_F(AidlStructUtilTest, convertLegacyVectorOfRttResultV2ToAidl) {
+ std::vector<const wifi_rtt_result_v2*> rtt_results_vec_v2;
+ wifi_rtt_result_v2 rttResults_v2[2];
+
+ // fill legacy rtt results v2
+ for (int i = 0; i < 2; i++) {
+ fillLegacyRttResult(&rttResults_v2[i].rtt_result);
+ rttResults_v2[i].frequency = 2412 + i * 5;
+ rttResults_v2[i].packet_bw = WIFI_RTT_BW_80;
+ rtt_results_vec_v2.push_back(&rttResults_v2[i]);
+ }
+
+ std::vector<RttResult> aidl_results;
+ aidl_struct_util::convertLegacyVectorOfRttResultV2ToAidl(rtt_results_vec_v2, &aidl_results);
+
+ EXPECT_EQ(rtt_results_vec_v2.size(), aidl_results.size());
+ for (size_t i = 0; i < rtt_results_vec_v2.size(); i++) {
+ verifyRttResult(&rttResults_v2[i].rtt_result, &aidl_results[i]);
+ EXPECT_EQ(aidl_results[i].channelFreqMHz, rttResults_v2[i].frequency);
+ EXPECT_EQ(aidl_results[i].packetBw, RttBw::BW_80MHZ);
+ }
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/main.cpp b/wifi/aidl/default/tests/main.cpp
new file mode 100644
index 0000000..767422c
--- /dev/null
+++ b/wifi/aidl/default/tests/main.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ::testing::InitGoogleMock(&argc, argv);
+ // Force ourselves to always log to stderr
+ android::base::InitLogging(argv, android::base::StderrLogger);
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/default/tests/mock_interface_tool.cpp b/wifi/aidl/default/tests/mock_interface_tool.cpp
new file mode 100644
index 0000000..79f3d1e
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_interface_tool.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "mock_interface_tool.h"
+
+namespace android {
+namespace wifi_system {
+
+MockInterfaceTool::MockInterfaceTool() {}
+
+} // namespace wifi_system
+} // namespace android
diff --git a/wifi/aidl/default/tests/mock_interface_tool.h b/wifi/aidl/default/tests/mock_interface_tool.h
new file mode 100644
index 0000000..9795de8
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_interface_tool.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef MOCK_INTERFACE_TOOL_H
+#define MOCK_INTERFACE_TOOL_H
+
+#include <gmock/gmock.h>
+#include <wifi_system/interface_tool.h>
+
+namespace android {
+namespace wifi_system {
+
+class MockInterfaceTool : public InterfaceTool {
+ public:
+ MockInterfaceTool();
+
+ MOCK_METHOD1(GetUpState, bool(const char* if_name));
+ MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
+ MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
+ MOCK_METHOD2(SetMacAddress,
+ bool(const char* if_name, const std::array<uint8_t, ETH_ALEN>& address));
+ MOCK_METHOD1(GetFactoryMacAddress, std::array<uint8_t, ETH_ALEN>(const char* if_name));
+
+}; // class MockInterfaceTool
+
+} // namespace wifi_system
+} // namespace android
+
+#endif // MOCK_INTERFACE_TOOL_H
diff --git a/wifi/aidl/default/tests/mock_wifi_feature_flags.cpp b/wifi/aidl/default/tests/mock_wifi_feature_flags.cpp
new file mode 100644
index 0000000..0c4e59d
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_feature_flags.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+#include "mock_wifi_feature_flags.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+MockWifiFeatureFlags::MockWifiFeatureFlags() {}
+
+} // namespace feature_flags
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_feature_flags.h b/wifi/aidl/default/tests/mock_wifi_feature_flags.h
new file mode 100644
index 0000000..9143d15
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_feature_flags.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#ifndef MOCK_WIFI_FEATURE_FLAGS_H_
+#define MOCK_WIFI_FEATURE_FLAGS_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_feature_flags.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+class MockWifiFeatureFlags : public WifiFeatureFlags {
+ public:
+ MockWifiFeatureFlags();
+
+ MOCK_METHOD1(getChipModes, std::vector<IWifiChip::ChipMode>(bool is_primary));
+ MOCK_METHOD0(isApMacRandomizationDisabled, bool());
+};
+
+} // namespace feature_flags
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // MOCK_WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/aidl/default/tests/mock_wifi_iface_util.cpp b/wifi/aidl/default/tests/mock_wifi_iface_util.cpp
new file mode 100644
index 0000000..0f787f2
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_iface_util.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "mock_wifi_iface_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+MockWifiIfaceUtil::MockWifiIfaceUtil(
+ const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : WifiIfaceUtil(iface_tool, legacy_hal) {}
+
+} // namespace iface_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_iface_util.h b/wifi/aidl/default/tests/mock_wifi_iface_util.h
new file mode 100644
index 0000000..49a8636
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_iface_util.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef MOCK_WIFI_IFACE_UTIL_H_
+#define MOCK_WIFI_IFACE_UTIL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_iface_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+class MockWifiIfaceUtil : public iface_util::WifiIfaceUtil {
+ public:
+ MockWifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ MOCK_METHOD1(getFactoryMacAddress, std::array<uint8_t, 6>(const std::string&));
+ MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array<uint8_t, 6>&));
+ MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
+ MOCK_METHOD2(registerIfaceEventHandlers,
+ void(const std::string&, iface_util::IfaceEventHandlers));
+ MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
+ MOCK_METHOD2(setUpState, bool(const std::string&, bool));
+ MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&));
+};
+
+} // namespace iface_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // MOCK_WIFI_IFACE_UTIL_H_
diff --git a/wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp b/wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp
new file mode 100644
index 0000000..33b2b1c
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_legacy_hal.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "mock_wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+MockWifiLegacyHal::MockWifiLegacyHal(
+ const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const wifi_hal_fn& fn, bool is_primary)
+ : WifiLegacyHal(iface_tool, fn, is_primary) {}
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_legacy_hal.h b/wifi/aidl/default/tests/mock_wifi_legacy_hal.h
new file mode 100644
index 0000000..28129a9
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_legacy_hal.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_LEGACY_HAL_H_
+#define MOCK_WIFI_LEGACY_HAL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+class MockWifiLegacyHal : public WifiLegacyHal {
+ public:
+ MockWifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const wifi_hal_fn& fn, bool is_primary);
+ MOCK_METHOD0(initialize, wifi_error());
+ MOCK_METHOD0(start, wifi_error());
+ MOCK_METHOD2(stop,
+ wifi_error(std::unique_lock<std::recursive_mutex>*, const std::function<void()>&));
+ MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
+ MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
+ wifi_error(const std::string&, const on_radio_mode_change_callback&));
+ MOCK_METHOD1(getFirmwareVersion,
+ std::pair<wifi_error, std::string>(const std::string& iface_name));
+ MOCK_METHOD1(getDriverVersion,
+ std::pair<wifi_error, std::string>(const std::string& iface_name));
+
+ MOCK_METHOD2(selectTxPowerScenario,
+ wifi_error(const std::string& iface_name, wifi_power_scenario scenario));
+ MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name));
+ MOCK_METHOD2(nanRegisterCallbackHandlers,
+ wifi_error(const std::string&, const NanCallbackHandlers&));
+ MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id));
+ MOCK_METHOD3(nanDataInterfaceDelete,
+ wifi_error(const std::string&, transaction_id, const std::string&));
+ MOCK_METHOD2(createVirtualInterface,
+ wifi_error(const std::string& ifname, wifi_interface_type iftype));
+ MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
+ MOCK_METHOD0(waitForDriverReady, wifi_error());
+ MOCK_METHOD2(getSupportedIfaceName, wifi_error(uint32_t, std::string&));
+ MOCK_METHOD1(registerSubsystemRestartCallbackHandler,
+ wifi_error(const on_subsystem_restart_callback&));
+ MOCK_METHOD1(getSupportedFeatureSet, std::pair<wifi_error, uint64_t>(const std::string&));
+};
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // MOCK_WIFI_LEGACY_HAL_H_
diff --git a/wifi/aidl/default/tests/mock_wifi_mode_controller.cpp b/wifi/aidl/default/tests/mock_wifi_mode_controller.cpp
new file mode 100644
index 0000000..f4cc4c4
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_mode_controller.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "mock_wifi_mode_controller.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+MockWifiModeController::MockWifiModeController() : WifiModeController() {}
+
+} // namespace mode_controller
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/mock_wifi_mode_controller.h b/wifi/aidl/default/tests/mock_wifi_mode_controller.h
new file mode 100644
index 0000000..f77f7d0
--- /dev/null
+++ b/wifi/aidl/default/tests/mock_wifi_mode_controller.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#ifndef MOCK_WIFI_MODE_CONTROLLER_H_
+#define MOCK_WIFI_MODE_CONTROLLER_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_mode_controller.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+class MockWifiModeController : public WifiModeController {
+ public:
+ MockWifiModeController();
+ MOCK_METHOD0(initialize, bool());
+ MOCK_METHOD1(changeFirmwareMode, bool(IfaceType));
+ MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType));
+ MOCK_METHOD0(deinitialize, bool());
+};
+} // namespace mode_controller
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // MOCK_WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/aidl/default/tests/ringbuffer_unit_tests.cpp b/wifi/aidl/default/tests/ringbuffer_unit_tests.cpp
new file mode 100644
index 0000000..c257100
--- /dev/null
+++ b/wifi/aidl/default/tests/ringbuffer_unit_tests.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+#include "ringbuffer.h"
+
+using testing::Return;
+using testing::Test;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class RingbufferTest : public Test {
+ public:
+ const uint32_t maxBufferSize_ = 10;
+ Ringbuffer buffer_{maxBufferSize_};
+};
+
+TEST_F(RingbufferTest, CreateEmptyBuffer) {
+ ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, CanUseFullBufferCapacity) {
+ const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+ const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+ buffer_.append(input);
+ buffer_.append(input2);
+ ASSERT_EQ(2u, buffer_.getData().size());
+ EXPECT_EQ(input, buffer_.getData().front());
+ EXPECT_EQ(input2, buffer_.getData().back());
+}
+
+TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) {
+ const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+ const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+ const std::vector<uint8_t> input3 = {'G'};
+ buffer_.append(input);
+ buffer_.append(input2);
+ buffer_.append(input3);
+ ASSERT_EQ(2u, buffer_.getData().size());
+ EXPECT_EQ(input2, buffer_.getData().front());
+ EXPECT_EQ(input3, buffer_.getData().back());
+}
+
+TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) {
+ const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+ const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+ const std::vector<uint8_t> input3(maxBufferSize_, '2');
+ buffer_.append(input);
+ buffer_.append(input2);
+ buffer_.append(input3);
+ ASSERT_EQ(1u, buffer_.getData().size());
+ EXPECT_EQ(input3, buffer_.getData().front());
+}
+
+TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) {
+ const std::vector<uint8_t> input = {};
+ buffer_.append(input);
+ ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, OversizedAppendIsDropped) {
+ const std::vector<uint8_t> input(maxBufferSize_ + 1, '0');
+ buffer_.append(input);
+ ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) {
+ const std::vector<uint8_t> input(maxBufferSize_, '0');
+ const std::vector<uint8_t> input2(maxBufferSize_ + 1, '1');
+ buffer_.append(input);
+ buffer_.append(input2);
+ ASSERT_EQ(1u, buffer_.getData().size());
+ EXPECT_EQ(input, buffer_.getData().front());
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/runtests.sh b/wifi/aidl/default/tests/runtests.sh
new file mode 100755
index 0000000..1f53ab8
--- /dev/null
+++ b/wifi/aidl/default/tests/runtests.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+# 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.
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+ echo "You need to source and lunch before you can use this script"
+ exit 1
+fi
+set -e
+
+$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode android.hardware.wifi-service-tests
+adb root
+adb sync data
+adb shell /data/nativetest64/vendor/android.hardware.wifi-service-tests/android.hardware.wifi-service-tests
diff --git a/wifi/aidl/default/tests/wifi_chip_unit_tests.cpp b/wifi/aidl/default/tests/wifi_chip_unit_tests.cpp
new file mode 100644
index 0000000..e66b650
--- /dev/null
+++ b/wifi/aidl/default/tests/wifi_chip_unit_tests.cpp
@@ -0,0 +1,855 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#include "wifi_chip.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+#include "mock_wifi_mode_controller.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr int kFakeChipId = 5;
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+class WifiChipTest : public Test {
+ protected:
+ void setupV1IfaceCombination() {
+ // clang-format off
+ // 1 STA + 1 P2P
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 1},
+ {{IfaceConcurrencyType::P2P}, 1}
+ }
+ }
+ };
+ // 1 AP
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsAp =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::AP}, 1}
+ }
+ }
+ };
+ const std::vector<IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
+ {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+ }
+
+ void setupV1_AwareIfaceCombination() {
+ // clang-format off
+ // 1 STA + 1 of (P2P or NAN)
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 1},
+ {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+ }
+ }
+ };
+ // 1 AP
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsAp =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::AP}, 1}
+ }
+ }
+ };
+ const std::vector<IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV1Sta, combinationsSta},
+ {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+ }
+
+ void setupV1_AwareDisabledApIfaceCombination() {
+ // clang-format off
+ // 1 STA + 1 of (P2P or NAN)
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinationsSta =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 1},
+ {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+ }
+ }
+ };
+ const std::vector<IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+ }
+
+ void setupV2_AwareIfaceCombination() {
+ // clang-format off
+ // (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 1},
+ {{IfaceConcurrencyType::AP}, 1}
+ }
+ },
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 1},
+ {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+ }
+ }
+ };
+ const std::vector<IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV3, combinations}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+ }
+
+ void setupV2_AwareDisabledApIfaceCombination() {
+ // clang-format off
+ // 1 STA + 1 of (P2P or NAN)
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 1},
+ {{IfaceConcurrencyType::P2P, IfaceConcurrencyType::NAN_IFACE}, 1}
+ }
+ }
+ };
+ const std::vector<IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV3, combinations}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+ }
+
+ void setup_MultiIfaceCombination() {
+ // clang-format off
+ // 3 STA + 1 AP
+ const std::vector<IWifiChip::ChipConcurrencyCombination> combinations =
+ {
+ {
+ {
+ {{IfaceConcurrencyType::STA}, 3},
+ {{IfaceConcurrencyType::AP}, 1}
+ }
+ }
+ };
+ const std::vector<IWifiChip::ChipMode> modes = {
+ {feature_flags::chip_mode_ids::kV3, combinations}
+ };
+ // clang-format on
+ EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
+ }
+
+ void assertNumberOfModes(uint32_t num_modes) {
+ std::vector<IWifiChip::ChipMode> modes;
+ ASSERT_TRUE(chip_->getAvailableModes(&modes).isOk());
+ // V2_Aware has 1 mode of operation.
+ ASSERT_EQ(num_modes, modes.size());
+ }
+
+ void findModeAndConfigureForIfaceType(const IfaceConcurrencyType& type) {
+ // This should be aligned with kInvalidModeId in wifi_chip.cpp
+ int32_t mode_id = INT32_MAX;
+ std::vector<IWifiChip::ChipMode> modes;
+ ASSERT_TRUE(chip_->getAvailableModes(&modes).isOk());
+
+ for (const auto& mode : modes) {
+ for (const auto& combination : mode.availableCombinations) {
+ for (const auto& limit : combination.limits) {
+ if (limit.types.end() !=
+ std::find(limit.types.begin(), limit.types.end(), type)) {
+ mode_id = mode.id;
+ }
+ }
+ }
+ }
+
+ ASSERT_NE(INT32_MAX, mode_id);
+ ASSERT_TRUE(chip_->configureChip(mode_id).isOk());
+ }
+
+ // Returns an empty string on error.
+ std::string createIface(const IfaceType& type) {
+ std::string iface_name;
+ if (type == IfaceType::AP) {
+ std::shared_ptr<IWifiApIface> iface;
+ if (!chip_->createApIface(&iface).isOk()) {
+ return "";
+ }
+ EXPECT_NE(iface.get(), nullptr);
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ } else if (type == IfaceType::NAN_IFACE) {
+ std::shared_ptr<IWifiNanIface> iface;
+ if (!chip_->createNanIface(&iface).isOk()) {
+ return "";
+ }
+ EXPECT_NE(iface.get(), nullptr);
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ } else if (type == IfaceType::P2P) {
+ std::shared_ptr<IWifiP2pIface> iface;
+ if (!chip_->createP2pIface(&iface).isOk()) {
+ return "";
+ }
+ EXPECT_NE(iface.get(), nullptr);
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ } else if (type == IfaceType::STA) {
+ std::shared_ptr<IWifiStaIface> iface;
+ if (!chip_->createStaIface(&iface).isOk()) {
+ return "";
+ }
+ EXPECT_NE(iface.get(), nullptr);
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ }
+ return iface_name;
+ }
+
+ void removeIface(const IfaceType& type, const std::string& iface_name) {
+ if (type == IfaceType::AP) {
+ ASSERT_TRUE(chip_->removeApIface(iface_name).isOk());
+ } else if (type == IfaceType::NAN_IFACE) {
+ ASSERT_TRUE(chip_->removeNanIface(iface_name).isOk());
+ } else if (type == IfaceType::P2P) {
+ ASSERT_TRUE(chip_->removeP2pIface(iface_name).isOk());
+ } else if (type == IfaceType::STA) {
+ ASSERT_TRUE(chip_->removeStaIface(iface_name).isOk());
+ }
+ }
+
+ bool createRttController() {
+ std::shared_ptr<IWifiRttController> rtt_controller;
+ auto status = chip_->createRttController(nullptr, &rtt_controller);
+ return status.isOk();
+ }
+
+ static void subsystemRestartHandler(const std::string& /*error*/) {}
+
+ std::shared_ptr<WifiChip> chip_;
+ int chip_id_ = kFakeChipId;
+ legacy_hal::wifi_hal_fn fake_func_table_;
+ std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<::android::wifi_system::MockInterfaceTool>};
+ std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+ std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{
+ new NiceMock<mode_controller::MockWifiModeController>};
+ std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
+ std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{
+ new NiceMock<feature_flags::MockWifiFeatureFlags>};
+
+ public:
+ void SetUp() override {
+ chip_ = WifiChip::create(chip_id_, true, legacy_hal_, mode_controller_, iface_util_,
+ feature_flags_, subsystemRestartHandler);
+
+ EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(*legacy_hal_, start())
+ .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
+ // Vendor HAL does not override the name by default.
+ EXPECT_CALL(*legacy_hal_, getSupportedIfaceName(testing::_, testing::_))
+ .WillRepeatedly(testing::Return(legacy_hal::WIFI_ERROR_UNKNOWN));
+ }
+
+ void TearDown() override {
+ // Restore default system iface names (This should ideally be using a
+ // mock).
+ property_set("wifi.interface", "wlan0");
+ property_set("wifi.concurrent.interface", "wlan1");
+ property_set("wifi.aware.interface", nullptr);
+ }
+};
+
+////////// V1 Iface Combinations ////////////
+// Mode 1 - STA + P2P
+// Mode 2 - AP
+class WifiChipV1IfaceCombinationTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setupV1IfaceCombination();
+ WifiChipTest::SetUp();
+ // V1 has 2 modes of operation.
+ assertNumberOfModes(2);
+ }
+};
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateNan_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+////////// V1 + Aware Iface Combinations ////////////
+// Mode 1 - STA + P2P/NAN
+// Mode 2 - AP
+class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setupV1_AwareIfaceCombination();
+ WifiChipTest::SetUp();
+ // V1_Aware has 2 modes of operation.
+ assertNumberOfModes(2u);
+ }
+};
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ std::string p2p_iface_name = createIface(IfaceType::P2P);
+ ASSERT_FALSE(p2p_iface_name.empty());
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+
+ // After removing P2P iface, NAN iface creation should succeed.
+ removeIface(IfaceType::P2P, p2p_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
+ ASSERT_FALSE(nan_iface_name.empty());
+ ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+
+ // After removing NAN iface, P2P iface creation should succeed.
+ removeIface(IfaceType::NAN_IFACE, nan_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ std::string ap_iface_name = createIface(IfaceType::AP);
+ ASSERT_FALSE(ap_iface_name.empty());
+ ASSERT_FALSE(createRttController());
+
+ removeIface(IfaceType::AP, ap_iface_name);
+
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+////////// V2 + Aware Iface Combinations ////////////
+// Mode 1 - STA + STA/AP
+// - STA + P2P/NAN
+class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setupV2_AwareIfaceCombination();
+ WifiChipTest::SetUp();
+ // V2_Aware has 1 mode of operation.
+ assertNumberOfModes(1u);
+ }
+};
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ std::string sta_iface_name = createIface(IfaceType::STA);
+ ASSERT_FALSE(sta_iface_name.empty());
+ std::string ap_iface_name = createIface(IfaceType::AP);
+ ASSERT_FALSE(ap_iface_name.empty());
+
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+
+ // After removing AP & STA iface, STA iface creation should succeed.
+ removeIface(IfaceType::STA, sta_iface_name);
+ removeIface(IfaceType::AP, ap_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ std::string p2p_iface_name = createIface(IfaceType::P2P);
+ ASSERT_FALSE(p2p_iface_name.empty());
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+
+ // After removing P2P iface, NAN iface creation should succeed.
+ removeIface(IfaceType::P2P, p2p_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
+ ASSERT_FALSE(nan_iface_name.empty());
+ ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+
+ // After removing NAN iface, P2P iface creation should succeed.
+ removeIface(IfaceType::NAN_IFACE, nan_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_FALSE(createIface(IfaceType::AP).empty());
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_FALSE(createIface(IfaceType::AP).empty());
+ ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ std::string p2p_iface_name = createIface(IfaceType::P2P);
+ ASSERT_FALSE(p2p_iface_name.empty());
+ ASSERT_TRUE(createIface(IfaceType::NAN_IFACE).empty());
+
+ // After removing P2P iface, NAN iface creation should succeed.
+ removeIface(IfaceType::P2P, p2p_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::NAN_IFACE).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ std::string nan_iface_name = createIface(IfaceType::NAN_IFACE);
+ ASSERT_FALSE(nan_iface_name.empty());
+ ASSERT_TRUE(createIface(IfaceType::P2P).empty());
+
+ // After removing NAN iface, P2P iface creation should succeed.
+ removeIface(IfaceType::NAN_IFACE, nan_iface_name);
+ ASSERT_FALSE(createIface(IfaceType::P2P).empty());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ std::string sta_iface_name = createIface(IfaceType::STA);
+ std::string ap_iface_name = createIface(IfaceType::AP);
+ ASSERT_FALSE(sta_iface_name.empty());
+ ASSERT_FALSE(ap_iface_name.empty());
+ ASSERT_NE(sta_iface_name, ap_iface_name);
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, RttControllerFlow) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::AP).empty());
+ ASSERT_TRUE(createRttController());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ ASSERT_TRUE(chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF).isOk());
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+ // Create NAN iface
+ ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "wlan0");
+
+ // We should have 1 nan iface.
+ std::vector<std::string> iface_names;
+ ASSERT_TRUE(chip_->getNanIfaceNames(&iface_names).isOk());
+ ASSERT_EQ(iface_names.size(), 1u);
+ ASSERT_EQ(iface_names[0], "wlan0");
+
+ // Retrieve the nan iface object.
+ std::shared_ptr<IWifiNanIface> nan_iface;
+ ASSERT_TRUE(chip_->getNanIface("wlan0", &nan_iface).isOk());
+ ASSERT_NE(nan_iface.get(), nullptr);
+
+ // Remove the STA iface. We should have 0 nan ifaces now.
+ removeIface(IfaceType::STA, "wlan0");
+ ASSERT_TRUE(chip_->getNanIfaceNames(&iface_names).isOk());
+ ASSERT_EQ(iface_names.size(), 0u);
+
+ // Any operation on the nan iface object should now return an error.
+ std::string name;
+ auto status = nan_iface->getName(&name);
+ ASSERT_EQ(status.getServiceSpecificError(),
+ static_cast<int32_t>(WifiStatusCode::ERROR_WIFI_IFACE_INVALID));
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+
+ // Create RTT controller
+ std::shared_ptr<IWifiRttController> rtt_controller;
+ ASSERT_TRUE(chip_->createRttController(nullptr, &rtt_controller).isOk());
+
+ // Remove the STA iface.
+ removeIface(IfaceType::STA, "wlan0");
+
+ // Any operation on the rtt controller object should now return an error.
+ std::shared_ptr<IWifiStaIface> bound_iface;
+ auto status = rtt_controller->getBoundIface(&bound_iface);
+ ASSERT_EQ(status.getServiceSpecificError(),
+ static_cast<int32_t>(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID));
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
+ property_set("wifi.aware.interface", nullptr);
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "wlan0");
+ removeIface(IfaceType::NAN_IFACE, "wlan0");
+ EXPECT_CALL(*iface_util_, setUpState(testing::_, testing::_)).Times(0);
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithDedicatedNanIface) {
+ property_set("wifi.aware.interface", "aware0");
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4));
+ EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true));
+ ASSERT_EQ(createIface(IfaceType::NAN_IFACE), "aware0");
+
+ EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true));
+ removeIface(IfaceType::NAN_IFACE, "aware0");
+}
+
+////////// V1 Iface Combinations when AP creation is disabled //////////
+class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setupV1_AwareDisabledApIfaceCombination();
+ WifiChipTest::SetUp();
+ }
+};
+
+TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+////////// V2 Iface Combinations when AP creation is disabled //////////
+class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setupV2_AwareDisabledApIfaceCombination();
+ WifiChipTest::SetUp();
+ }
+};
+
+TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_TRUE(createIface(IfaceType::AP).empty());
+}
+
+////////// Hypothetical Iface Combination with multiple ifaces //////////
+class WifiChip_MultiIfaceTest : public WifiChipTest {
+ public:
+ void SetUp() override {
+ setup_MultiIfaceCombination();
+ WifiChipTest::SetUp();
+ }
+};
+
+TEST_F(WifiChip_MultiIfaceTest, Create3Sta) {
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_TRUE(createIface(IfaceType::STA).empty());
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) {
+ property_set("wifi.interface.0", "");
+ property_set("wifi.interface.1", "");
+ property_set("wifi.interface.2", "");
+ property_set("wifi.interface", "");
+ property_set("wifi.concurrent.interface", "");
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) {
+ property_set("wifi.interface.0", "test0");
+ property_set("wifi.interface.1", "test1");
+ property_set("wifi.interface.2", "test2");
+ property_set("wifi.interface", "bad0");
+ property_set("wifi.concurrent.interface", "bad1");
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "bad0");
+ ASSERT_EQ(createIface(IfaceType::STA), "bad1");
+ ASSERT_EQ(createIface(IfaceType::STA), "test2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) {
+ property_set("wifi.interface.0", "");
+ property_set("wifi.interface.1", "");
+ property_set("wifi.interface.2", "");
+ property_set("wifi.interface", "testA0");
+ property_set("wifi.concurrent.interface", "testA1");
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "testA0");
+ ASSERT_EQ(createIface(IfaceType::STA), "testA1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+}
+
+TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) {
+ // WifiChip_MultiIfaceTest iface combo: STAx3 + APx1
+ // When the HAL support dual STAs, AP should start with idx 2.
+ findModeAndConfigureForIfaceType(IfaceConcurrencyType::STA);
+ // First AP will be slotted to wlan1.
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan2");
+ // First STA will be slotted to wlan0.
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ // All further STA will be slotted to the remaining free indices.
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp
new file mode 100644
index 0000000..e0db6fd
--- /dev/null
+++ b/wifi/aidl/default/tests/wifi_iface_util_unit_tests.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#include "wifi_iface_util.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Test;
+
+namespace {
+constexpr uint8_t kValidUnicastLocallyAssignedMacAddressMask = 0x02;
+constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
+constexpr char kIfaceName[] = "test-wlan0";
+
+bool isValidUnicastLocallyAssignedMacAddress(const std::array<uint8_t, 6>& mac_address) {
+ uint8_t first_byte = mac_address[0];
+ return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask;
+}
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+class WifiIfaceUtilTest : public Test {
+ protected:
+ std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<::android::wifi_system::MockInterfaceTool>};
+ legacy_hal::wifi_hal_fn fake_func_table_;
+ std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+ WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
+};
+
+TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
+ auto mac_address = iface_util_->getOrCreateRandomMacAddress();
+ ASSERT_TRUE(isValidUnicastLocallyAssignedMacAddress(mac_address));
+
+ // All further calls should return the same MAC address.
+ ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
+ ASSERT_EQ(mac_address, iface_util_->getOrCreateRandomMacAddress());
+}
+
+TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
+ std::array<uint8_t, 6> mac_address = {};
+ std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address));
+ EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
+ .WillRepeatedly(testing::Return(true));
+
+ // Register for iface state toggle events.
+ bool callback_invoked = false;
+ iface_util::IfaceEventHandlers event_handlers = {};
+ event_handlers.on_state_toggle_off_on =
+ [&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; };
+ iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
+ // Invoke setMacAddress and ensure that the cb is invoked.
+ ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+ ASSERT_TRUE(callback_invoked);
+
+ // Unregister for iface state toggle events.
+ callback_invoked = false;
+ iface_util_->unregisterIfaceEventHandlers(kIfaceName);
+ // Invoke setMacAddress and ensure that the cb is not invoked.
+ ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
+ ASSERT_FALSE(callback_invoked);
+}
+} // namespace iface_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
new file mode 100644
index 0000000..d58a9b0
--- /dev/null
+++ b/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#include "wifi_nan_iface.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr char kIfaceName[] = "mockWlan0";
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/,
+ iface_util::IfaceEventHandlers in_iface_event_handlers,
+ iface_util::IfaceEventHandlers* out_iface_event_handlers) {
+ *out_iface_event_handlers = in_iface_event_handlers;
+ return true;
+}
+
+class MockNanIface : public WifiNanIface {
+ public:
+ MockNanIface(const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : WifiNanIface(ifname, is_dedicated_iface, legacy_hal, iface_util) {}
+
+ static std::shared_ptr<MockNanIface> createMock(
+ const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
+ std::shared_ptr<MockNanIface> ptr = ndk::SharedRefBase::make<MockNanIface>(
+ ifname, is_dedicated_iface, legacy_hal, iface_util);
+ std::weak_ptr<MockNanIface> weak_ptr_this(ptr);
+ ptr->setWeakPtr(weak_ptr_this);
+ ptr->registerCallbackHandlers();
+ return ptr;
+ }
+
+ // Override getEventCallbacks() so that we can return a mocked callback object.
+ std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks() override {
+ return {callback_};
+ }
+
+ void setMockCallback(std::shared_ptr<IWifiNanIfaceEventCallback> cb) { callback_ = cb; }
+
+ private:
+ std::shared_ptr<IWifiNanIfaceEventCallback> callback_;
+};
+
+class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback {
+ public:
+ ndk::SpAIBinder asBinder() override { return ::ndk::SpAIBinder{}; }
+ bool isRemote() override { return false; }
+
+ ::ndk::ScopedAStatus getInterfaceVersion(int32_t* _aidl_return) override {
+ *_aidl_return = 1;
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus getInterfaceHash(std::string* _aidl_return) override {
+ *_aidl_return = "some_hash";
+ return ndk::ScopedAStatus::ok();
+ }
+
+ MOCK_METHOD3(notifyCapabilitiesResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&, const NanCapabilities&));
+ MOCK_METHOD2(notifyEnableResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyConfigResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyDisableResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD3(notifyStartPublishResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&, int8_t));
+ MOCK_METHOD2(notifyStopPublishResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD3(notifyStartSubscribeResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&, int8_t));
+ MOCK_METHOD2(notifyStopSubscribeResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyTransmitFollowupResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyCreateDataInterfaceResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyDeleteDataInterfaceResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD3(notifyInitiateDataPathResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
+ MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyTerminateDataPathResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD1(eventClusterEvent, ndk::ScopedAStatus(const NanClusterEventInd&));
+ MOCK_METHOD1(eventDisabled, ndk::ScopedAStatus(const NanStatus&));
+ MOCK_METHOD2(eventPublishTerminated, ndk::ScopedAStatus(int8_t, const NanStatus&));
+ MOCK_METHOD2(eventSubscribeTerminated, ndk::ScopedAStatus(int8_t, const NanStatus&));
+ MOCK_METHOD1(eventMatch, ndk::ScopedAStatus(const NanMatchInd&));
+ MOCK_METHOD2(eventMatchExpired, ndk::ScopedAStatus(int8_t, int32_t));
+ MOCK_METHOD1(eventFollowupReceived, ndk::ScopedAStatus(const NanFollowupReceivedInd&));
+ MOCK_METHOD2(eventTransmitFollowup, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD1(eventDataPathRequest, ndk::ScopedAStatus(const NanDataPathRequestInd&));
+ MOCK_METHOD1(eventDataPathConfirm, ndk::ScopedAStatus(const NanDataPathConfirmInd&));
+ MOCK_METHOD1(eventDataPathTerminated, ndk::ScopedAStatus(int32_t));
+ MOCK_METHOD1(eventDataPathScheduleUpdate,
+ ndk::ScopedAStatus(const NanDataPathScheduleUpdateInd&));
+ MOCK_METHOD1(eventPairingConfirm, ndk::ScopedAStatus(const NanPairingConfirmInd&));
+ MOCK_METHOD1(eventPairingRequest, ndk::ScopedAStatus(const NanPairingRequestInd&));
+ MOCK_METHOD1(eventBootstrappingConfirm, ndk::ScopedAStatus(const NanBootstrappingConfirmInd&));
+ MOCK_METHOD1(eventBootstrappingRequest, ndk::ScopedAStatus(const NanBootstrappingRequestInd&));
+ MOCK_METHOD3(notifyInitiatePairingResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
+ MOCK_METHOD2(notifyRespondToPairingIndicationResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD3(notifyInitiateBootstrappingResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&, int32_t));
+ MOCK_METHOD2(notifyRespondToBootstrappingIndicationResponse,
+ ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifySuspendResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyResumeResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD2(notifyTerminatePairingResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
+ MOCK_METHOD1(eventSuspensionModeChanged, ndk::ScopedAStatus(const NanSuspensionModeChangeInd&));
+};
+
+class WifiNanIfaceTest : public Test {
+ protected:
+ legacy_hal::wifi_hal_fn fake_func_table_;
+ std::shared_ptr<NiceMock<::android::wifi_system::MockInterfaceTool>> iface_tool_{
+ new NiceMock<::android::wifi_system::MockInterfaceTool>};
+ std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+ std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
+};
+
+TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
+ // Ensure that event handlers are registered during nan iface creation.
+ iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
+ EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_))
+ .WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1,
+ std::placeholders::_2, &captured_iface_event_handlers)));
+
+ // Create nan iface and register a callback.
+ // Note: Since we can't register a callback directly (gTest fails on
+ // AIBinder_linkToDeath), simulate the registration by overriding
+ // getEventCallbacks() to return our mock callback object.
+ std::shared_ptr<MockNanIface> mock_nan_iface =
+ MockNanIface::createMock(kIfaceName, false, legacy_hal_, iface_util_);
+ std::shared_ptr<MockNanIfaceEventCallback> mock_event_callback =
+ ndk::SharedRefBase::make<MockNanIfaceEventCallback>();
+ mock_nan_iface->setMockCallback(mock_event_callback);
+
+ // Ensure that the eventDisabled() function in the mock callback will be invoked.
+ NanStatus expected_nan_status = {NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+ EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1);
+
+ // Trigger the iface state toggle callback.
+ captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi.cpp b/wifi/aidl/default/wifi.cpp
new file mode 100644
index 0000000..e30c38a
--- /dev/null
+++ b/wifi/aidl/default/wifi.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "wifi_status_util.h"
+
+namespace {
+// Starting Chip ID, will be assigned to primary chip
+static constexpr int32_t kPrimaryChipId = 0;
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+using aidl_return_util::validateAndCallWithLock;
+
+Wifi::Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+ const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
+ : iface_tool_(iface_tool),
+ legacy_hal_factory_(legacy_hal_factory),
+ mode_controller_(mode_controller),
+ feature_flags_(feature_flags),
+ run_state_(RunState::STOPPED) {}
+
+bool Wifi::isValid() {
+ // This object is always valid.
+ return true;
+}
+
+ndk::ScopedAStatus Wifi::registerEventCallback(
+ const std::shared_ptr<IWifiEventCallback>& in_callback) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::registerEventCallbackInternal, in_callback);
+}
+
+ndk::ScopedAStatus Wifi::isStarted(bool* _aidl_return) {
+ *_aidl_return = (run_state_ != RunState::STOPPED);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Wifi::start() {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal);
+}
+
+ndk::ScopedAStatus Wifi::stop() {
+ return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal);
+}
+
+ndk::ScopedAStatus Wifi::getChipIds(std::vector<int32_t>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal,
+ _aidl_return);
+}
+
+ndk::ScopedAStatus Wifi::getChip(int32_t in_chipId, std::shared_ptr<IWifiChip>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal,
+ _aidl_return, in_chipId);
+}
+
+binder_status_t Wifi::dump(int fd, const char** args, uint32_t numArgs) {
+ LOG(INFO) << "-----------Debug was called----------------";
+ if (chips_.size() == 0) {
+ LOG(INFO) << "No chips to display.";
+ return STATUS_OK;
+ }
+
+ for (std::shared_ptr<WifiChip> chip : chips_) {
+ if (!chip.get()) continue;
+ chip->dump(fd, args, numArgs);
+ }
+ return STATUS_OK;
+}
+
+ndk::ScopedAStatus Wifi::registerEventCallbackInternal(
+ const std::shared_ptr<IWifiEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Wifi::startInternal() {
+ if (run_state_ == RunState::STARTED) {
+ return ndk::ScopedAStatus::ok();
+ } else if (run_state_ == RunState::STOPPING) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
+ }
+ ndk::ScopedAStatus wifi_status = initializeModeControllerAndLegacyHal();
+ if (wifi_status.isOk()) {
+ // Register the callback for subsystem restart
+ const auto& on_subsystem_restart_callback = [this](const std::string& error) {
+ ndk::ScopedAStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ LOG(INFO) << "Attempting to invoke onSubsystemRestart "
+ "callback";
+ WifiStatusCode errorCode =
+ static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
+ if (!callback->onSubsystemRestart(errorCode).isOk()) {
+ LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
+ } else {
+ LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
+ "callback";
+ }
+ }
+ };
+
+ // Create the chip instance once the HAL is started.
+ int32_t chipId = kPrimaryChipId;
+ for (auto& hal : legacy_hals_) {
+ chips_.push_back(
+ WifiChip::create(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
+ std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
+ feature_flags_, on_subsystem_restart_callback));
+ chipId++;
+ }
+ run_state_ = RunState::STARTED;
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onStart().isOk()) {
+ LOG(ERROR) << "Failed to invoke onStart callback";
+ };
+ }
+ LOG(INFO) << "Wifi HAL started";
+ } else {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ WifiStatusCode errorCode =
+ static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
+ if (!callback->onFailure(errorCode).isOk()) {
+ LOG(ERROR) << "Failed to invoke onFailure callback";
+ }
+ }
+ LOG(ERROR) << "Wifi HAL start failed";
+ // Clear the event callback objects since the HAL start failed.
+ event_cb_handler_.invalidate();
+ }
+ return wifi_status;
+}
+
+ndk::ScopedAStatus Wifi::stopInternal(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+ if (run_state_ == RunState::STOPPED) {
+ return ndk::ScopedAStatus::ok();
+ } else if (run_state_ == RunState::STOPPING) {
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
+ }
+ // Clear the chip object and its child objects since the HAL is now
+ // stopped.
+ for (auto& chip : chips_) {
+ if (chip.get()) {
+ chip->invalidate();
+ chip.reset();
+ }
+ }
+ chips_.clear();
+ ndk::ScopedAStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
+ if (wifi_status.isOk()) {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onStop().isOk()) {
+ LOG(ERROR) << "Failed to invoke onStop callback";
+ };
+ }
+ LOG(INFO) << "Wifi HAL stopped";
+ } else {
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ WifiStatusCode errorCode =
+ static_cast<WifiStatusCode>(wifi_status.getServiceSpecificError());
+ if (!callback->onFailure(errorCode).isOk()) {
+ LOG(ERROR) << "Failed to invoke onFailure callback";
+ }
+ }
+ LOG(ERROR) << "Wifi HAL stop failed";
+ }
+ // Clear the event callback objects since the HAL is now stopped.
+ event_cb_handler_.invalidate();
+ return wifi_status;
+}
+
+std::pair<std::vector<int32_t>, ndk::ScopedAStatus> Wifi::getChipIdsInternal() {
+ std::vector<int32_t> chip_ids;
+
+ for (auto& chip : chips_) {
+ int32_t chip_id = getChipIdFromWifiChip(chip);
+ if (chip_id != INT32_MAX) chip_ids.emplace_back(chip_id);
+ }
+ return {std::move(chip_ids), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiChip>, ndk::ScopedAStatus> Wifi::getChipInternal(int32_t chip_id) {
+ for (auto& chip : chips_) {
+ int32_t cand_id = getChipIdFromWifiChip(chip);
+ if ((cand_id != INT32_MAX) && (cand_id == chip_id)) return {chip, ndk::ScopedAStatus::ok()};
+ }
+
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+}
+
+ndk::ScopedAStatus Wifi::initializeModeControllerAndLegacyHal() {
+ if (!mode_controller_->initialize()) {
+ LOG(ERROR) << "Failed to initialize firmware mode controller";
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+
+ legacy_hals_ = legacy_hal_factory_->getHals();
+ if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ int index = 0; // for failure log
+ for (auto& hal : legacy_hals_) {
+ legacy_hal::wifi_error legacy_status = hal->initialize();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // Currently WifiLegacyHal::initialize does not allocate extra mem,
+ // only initializes the function table. If this changes, need to
+ // implement WifiLegacyHal::deinitialize and deinitalize the
+ // HALs already initialized
+ LOG(ERROR) << "Failed to initialize legacy HAL index: " << index
+ << " error: " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ index++;
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Wifi::stopLegacyHalAndDeinitializeModeController(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+ legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS;
+ int index = 0;
+
+ run_state_ = RunState::STOPPING;
+ for (auto& hal : legacy_hals_) {
+ legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {});
+ if (tmp != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to stop legacy HAL index: " << index
+ << " error: " << legacyErrorToString(legacy_status);
+ legacy_status = tmp;
+ }
+ index++;
+ }
+ run_state_ = RunState::STOPPED;
+
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "One or more legacy HALs failed to stop";
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ if (!mode_controller_->deinitialize()) {
+ LOG(ERROR) << "Failed to deinitialize firmware mode controller";
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+int32_t Wifi::getChipIdFromWifiChip(std::shared_ptr<WifiChip>& chip) {
+ int32_t chip_id = INT32_MAX;
+ if (chip.get()) {
+ ndk::ScopedAStatus status = chip->getId(&chip_id);
+ if (!status.isOk()) {
+ // Reset value if operation failed.
+ chip_id = INT32_MAX;
+ }
+ }
+ return chip_id;
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi.h b/wifi/aidl/default/wifi.h
new file mode 100644
index 0000000..9334524
--- /dev/null
+++ b/wifi/aidl/default/wifi.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_H_
+#define WIFI_H_
+
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <android-base/macros.h>
+#include <utils/Looper.h>
+
+#include <functional>
+
+#include "aidl_callback_util.h"
+#include "wifi_chip.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_factory.h"
+#include "wifi_mode_controller.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * Root AIDL interface object used to control the Wifi HAL.
+ */
+class Wifi : public BnWifi {
+ public:
+ Wifi(const std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+ const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
+
+ bool isValid();
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus registerEventCallback(
+ const std::shared_ptr<IWifiEventCallback>& in_callback) override;
+ ndk::ScopedAStatus isStarted(bool* _aidl_return) override;
+ ndk::ScopedAStatus start() override;
+ ndk::ScopedAStatus stop() override;
+ ndk::ScopedAStatus getChipIds(std::vector<int32_t>* _aidl_return) override;
+ ndk::ScopedAStatus getChip(int32_t in_chipId,
+ std::shared_ptr<IWifiChip>* _aidl_return) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ private:
+ enum class RunState { STOPPED, STARTED, STOPPING };
+
+ // Corresponding worker functions for the AIDL methods.
+ ndk::ScopedAStatus registerEventCallbackInternal(
+ const std::shared_ptr<IWifiEventCallback>& event_callback __unused);
+ ndk::ScopedAStatus startInternal();
+ ndk::ScopedAStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
+ std::pair<std::vector<int32_t>, ndk::ScopedAStatus> getChipIdsInternal();
+ std::pair<std::shared_ptr<IWifiChip>, ndk::ScopedAStatus> getChipInternal(int32_t chip_id);
+
+ ndk::ScopedAStatus initializeModeControllerAndLegacyHal();
+ ndk::ScopedAStatus stopLegacyHalAndDeinitializeModeController(
+ std::unique_lock<std::recursive_mutex>* lock);
+ int32_t getChipIdFromWifiChip(std::shared_ptr<WifiChip>& chip);
+
+ // Instance is created in this root level |IWifi| AIDL interface object
+ // and shared with all the child AIDL interface objects.
+ std::shared_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+ std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
+ std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
+ std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
+ std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
+ RunState run_state_;
+ std::vector<std::shared_ptr<WifiChip>> chips_;
+ aidl_callback_util::AidlCallbackHandler<IWifiEventCallback> event_cb_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(Wifi);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_H_
diff --git a/wifi/aidl/default/wifi_ap_iface.cpp b/wifi/aidl/default/wifi_ap_iface.cpp
new file mode 100644
index 0000000..77797502
--- /dev/null
+++ b/wifi/aidl/default/wifi_ap_iface.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_ap_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname),
+ instances_(instances),
+ legacy_hal_(legacy_hal),
+ iface_util_(iface_util),
+ is_valid_(true) {}
+
+void WifiApIface::invalidate() {
+ legacy_hal_.reset();
+ is_valid_ = false;
+}
+
+bool WifiApIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiApIface::getName() {
+ return ifname_;
+}
+
+void WifiApIface::removeInstance(std::string instance) {
+ instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
+}
+
+ndk::ScopedAStatus WifiApIface::getName(std::string* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getNameInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiApIface::setCountryCode(const std::array<uint8_t, 2>& in_code) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::setCountryCodeInternal, in_code);
+}
+
+ndk::ScopedAStatus WifiApIface::setMacAddress(const std::array<uint8_t, 6>& in_mac) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::setMacAddressInternal, in_mac);
+}
+
+ndk::ScopedAStatus WifiApIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getFactoryMacAddressInternal, _aidl_return,
+ instances_.size() > 0 ? instances_[0] : ifname_);
+}
+
+ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddress() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::resetToFactoryMacAddressInternal);
+}
+
+ndk::ScopedAStatus WifiApIface::getBridgedInstances(std::vector<std::string>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiApIface::getBridgedInstancesInternal, _aidl_return);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiApIface::getNameInternal() {
+ return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiApIface::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
+ instances_.size() > 0 ? instances_[0] : ifname_, code);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+ // Support random MAC up to 2 interfaces
+ if (instances_.size() == 2) {
+ int rbyte = 1;
+ for (auto const& intf : instances_) {
+ std::array<uint8_t, 6> rmac = mac;
+ // reverse the bits to avoid collision
+ rmac[rbyte] = 0xff - rmac[rbyte];
+ if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
+ LOG(INFO) << "Failed to set random mac address on " << intf;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ rbyte++;
+ }
+ }
+ // It also needs to set mac address for bridged interface, otherwise the mac
+ // address of bridged interface will be changed after one of instance
+ // down.
+ if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
+ LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> WifiApIface::getFactoryMacAddressInternal(
+ const std::string& ifaceName) {
+ std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
+ if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+ return {mac, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {mac, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddressInternal() {
+ std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getMacResult;
+ if (instances_.size() == 2) {
+ for (auto const& intf : instances_) {
+ getMacResult = getFactoryMacAddressInternal(intf);
+ LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
+ if (!getMacResult.second.isOk() ||
+ !iface_util_.lock()->setMacAddress(intf, getMacResult.first)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ }
+ // We need to set mac address for bridged interface, otherwise the mac
+ // address of the bridged interface will be changed after one of the
+ // instances goes down. Thus we are generating a random MAC address for
+ // the bridged interface even if we got the request to reset the Factory
+ // MAC. This is because the bridged interface is an internal interface
+ // for the operation of bpf and other networking operations.
+ if (!iface_util_.lock()->setMacAddress(ifname_,
+ iface_util_.lock()->createRandomMacAddress())) {
+ LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ } else {
+ getMacResult = getFactoryMacAddressInternal(ifname_);
+ LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
+ if (!getMacResult.second.isOk() ||
+ !iface_util_.lock()->setMacAddress(ifname_, getMacResult.first)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiApIface::getBridgedInstancesInternal() {
+ return {instances_, ndk::ScopedAStatus::ok()};
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_ap_iface.h b/wifi/aidl/default/wifi_ap_iface.h
new file mode 100644
index 0000000..7378f98
--- /dev/null
+++ b/wifi/aidl/default/wifi_ap_iface.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_AP_IFACE_H_
+#define WIFI_AP_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiApIface.h>
+#include <android-base/macros.h>
+
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control an AP Iface instance.
+ */
+class WifiApIface : public BnWifiApIface {
+ public:
+ WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::string getName();
+ void removeInstance(std::string instance);
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+ ndk::ScopedAStatus setCountryCode(const std::array<uint8_t, 2>& in_code) override;
+ ndk::ScopedAStatus setMacAddress(const std::array<uint8_t, 6>& in_mac) override;
+ ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
+ ndk::ScopedAStatus resetToFactoryMacAddress() override;
+ ndk::ScopedAStatus getBridgedInstances(std::vector<std::string>* _aidl_return) override;
+
+ private:
+ // Corresponding worker functions for the AIDL methods.
+ std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+ ndk::ScopedAStatus setCountryCodeInternal(const std::array<uint8_t, 2>& code);
+ ndk::ScopedAStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+ std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal(
+ const std::string& ifaceName);
+ ndk::ScopedAStatus resetToFactoryMacAddressInternal();
+ std::pair<std::vector<std::string>, ndk::ScopedAStatus> getBridgedInstancesInternal();
+
+ std::string ifname_;
+ std::vector<std::string> instances_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiApIface);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_AP_IFACE_H_
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
new file mode 100644
index 0000000..f9f5528
--- /dev/null
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -0,0 +1,2019 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_chip.h"
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_status_util.h"
+
+#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
+
+namespace {
+using aidl::android::hardware::wifi::IfaceType;
+using aidl::android::hardware::wifi::IWifiChip;
+using CoexRestriction = aidl::android::hardware::wifi::IWifiChip::CoexRestriction;
+using ChannelCategoryMask = aidl::android::hardware::wifi::IWifiChip::ChannelCategoryMask;
+using android::base::unique_fd;
+
+constexpr char kCpioMagic[] = "070701";
+constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
+constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
+constexpr uint32_t kMaxRingBufferFileNum = 20;
+constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
+constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
+constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
+constexpr unsigned kMaxWlanIfaces = 5;
+constexpr char kApBridgeIfacePrefix[] = "ap_br_";
+
+template <typename Iface>
+void invalidateAndClear(std::vector<std::shared_ptr<Iface>>& ifaces, std::shared_ptr<Iface> iface) {
+ iface->invalidate();
+ ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
+}
+
+template <typename Iface>
+void invalidateAndClearAll(std::vector<std::shared_ptr<Iface>>& ifaces) {
+ for (const auto& iface : ifaces) {
+ iface->invalidate();
+ }
+ ifaces.clear();
+}
+
+template <typename Iface>
+std::vector<std::string> getNames(std::vector<std::shared_ptr<Iface>>& ifaces) {
+ std::vector<std::string> names;
+ for (const auto& iface : ifaces) {
+ names.emplace_back(iface->getName());
+ }
+ return names;
+}
+
+template <typename Iface>
+std::shared_ptr<Iface> findUsingName(std::vector<std::shared_ptr<Iface>>& ifaces,
+ const std::string& name) {
+ std::vector<std::string> names;
+ for (const auto& iface : ifaces) {
+ if (name == iface->getName()) {
+ return iface;
+ }
+ }
+ return nullptr;
+}
+
+std::string getWlanIfaceName(unsigned idx) {
+ if (idx >= kMaxWlanIfaces) {
+ CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
+ return {};
+ }
+
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ if (idx == 0 || idx == 1) {
+ const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
+ auto res = property_get(altPropName, buffer.data(), nullptr);
+ if (res > 0) return buffer.data();
+ }
+ std::string propName = "wifi.interface." + std::to_string(idx);
+ auto res = property_get(propName.c_str(), buffer.data(), nullptr);
+ if (res > 0) return buffer.data();
+
+ return "wlan" + std::to_string(idx);
+}
+
+// Returns the dedicated iface name if defined.
+// Returns two ifaces in bridged mode.
+std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
+ std::vector<std::string> ifnames;
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ buffer.fill(0);
+ if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
+ return ifnames;
+ }
+ ifnames.push_back(buffer.data());
+ if (is_bridged) {
+ buffer.fill(0);
+ if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
+ return ifnames;
+ }
+ ifnames.push_back(buffer.data());
+ }
+ return ifnames;
+}
+
+std::string getPredefinedP2pIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
+ char p2pParentIfname[100];
+ std::string p2pDevIfName = "";
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ property_get("wifi.direct.interface", buffer.data(), "p2p0");
+ if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+ /* Get the p2p parent interface name from p2p device interface name set
+ * in property */
+ strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
+ strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
+ if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
+ return buffer.data();
+ }
+ /* Check if the parent interface derived from p2p device interface name
+ * is active */
+ if (strncmp(p2pParentIfname, primaryIfaceName.data(),
+ strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
+ /*
+ * Update the predefined p2p device interface parent interface name
+ * with current active wlan interface
+ */
+ p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
+ p2pDevIfName += primaryIfaceName.data();
+ LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
+ return p2pDevIfName;
+ }
+ }
+ return buffer.data();
+}
+
+// Returns the dedicated iface name if one is defined.
+std::string getPredefinedNanIfaceName() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
+ return {};
+ }
+ return buffer.data();
+}
+
+void setActiveWlanIfaceNameProperty(const std::string& ifname) {
+ auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
+ if (res != 0) {
+ PLOG(ERROR) << "Failed to set active wlan iface name property";
+ }
+}
+
+// Delete files that meet either condition:
+// 1. Older than a predefined time in the wifi tombstone dir.
+// 2. Files in excess to a predefined amount, starting from the oldest ones
+bool removeOldFilesInternal() {
+ time_t now = time(0);
+ const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
+ std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
+ if (!dir_dump) {
+ PLOG(ERROR) << "Failed to open directory";
+ return false;
+ }
+ struct dirent* dp;
+ bool success = true;
+ std::list<std::pair<const time_t, std::string>> valid_files;
+ while ((dp = readdir(dir_dump.get()))) {
+ if (dp->d_type != DT_REG) {
+ continue;
+ }
+ std::string cur_file_name(dp->d_name);
+ struct stat cur_file_stat;
+ std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+ if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
+ PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
+ success = false;
+ continue;
+ }
+ const time_t cur_file_time = cur_file_stat.st_mtime;
+ valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
+ }
+ valid_files.sort(); // sort the list of files by last modified time from
+ // small to big.
+ uint32_t cur_file_count = valid_files.size();
+ for (auto cur_file : valid_files) {
+ if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
+ if (unlink(cur_file.second.c_str()) != 0) {
+ PLOG(ERROR) << "Error deleting file";
+ success = false;
+ }
+ cur_file_count--;
+ } else {
+ break;
+ }
+ }
+ return success;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
+ const int buf_size = 32 * 1024;
+ std::array<char, buf_size> read_buf;
+ ssize_t llen = snprintf(
+ read_buf.data(), buf_size, "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
+ kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
+ static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
+ static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
+ minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
+ if (write(out_fd, read_buf.data(), llen < buf_size ? llen : buf_size - 1) == -1) {
+ PLOG(ERROR) << "Error writing cpio header to file " << file_name;
+ return false;
+ }
+ if (write(out_fd, file_name, file_name_len) == -1) {
+ PLOG(ERROR) << "Error writing filename to file " << file_name;
+ return false;
+ }
+
+ // NUL Pad header up to 4 multiple bytes.
+ llen = (llen + file_name_len) % 4;
+ if (llen != 0) {
+ const uint32_t zero = 0;
+ if (write(out_fd, &zero, 4 - llen) == -1) {
+ PLOG(ERROR) << "Error padding 0s to file " << file_name;
+ return false;
+ }
+ }
+ return true;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
+ // writing content of file
+ std::array<char, 32 * 1024> read_buf;
+ ssize_t llen = st.st_size;
+ size_t n_error = 0;
+ while (llen > 0) {
+ ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
+ if (bytes_read == -1) {
+ PLOG(ERROR) << "Error reading file";
+ return ++n_error;
+ }
+ llen -= bytes_read;
+ if (write(out_fd, read_buf.data(), bytes_read) == -1) {
+ PLOG(ERROR) << "Error writing data to file";
+ return ++n_error;
+ }
+ if (bytes_read == 0) { // this should never happen, but just in case
+ // to unstuck from while loop
+ PLOG(ERROR) << "Unexpected read result";
+ n_error++;
+ break;
+ }
+ }
+ llen = st.st_size % 4;
+ if (llen != 0) {
+ const uint32_t zero = 0;
+ if (write(out_fd, &zero, 4 - llen) == -1) {
+ PLOG(ERROR) << "Error padding 0s to file";
+ return ++n_error;
+ }
+ }
+ return n_error;
+}
+
+// Helper function for |cpioArchiveFilesInDir|
+bool cpioWriteFileTrailer(int out_fd) {
+ const int buf_size = 4096;
+ std::array<char, buf_size> read_buf;
+ read_buf.fill(0);
+ ssize_t llen = snprintf(read_buf.data(), 4096, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0);
+ if (write(out_fd, read_buf.data(), (llen < buf_size ? llen : buf_size - 1) + 4) == -1) {
+ PLOG(ERROR) << "Error writing trailing bytes";
+ return false;
+ }
+ return true;
+}
+
+// Archives all files in |input_dir| and writes result into |out_fd|
+// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
+// portion
+size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
+ struct dirent* dp;
+ size_t n_error = 0;
+ std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
+ if (!dir_dump) {
+ PLOG(ERROR) << "Failed to open directory";
+ return ++n_error;
+ }
+ while ((dp = readdir(dir_dump.get()))) {
+ if (dp->d_type != DT_REG) {
+ continue;
+ }
+ std::string cur_file_name(dp->d_name);
+ struct stat st;
+ const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+ if (stat(cur_file_path.c_str(), &st) == -1) {
+ PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
+ n_error++;
+ continue;
+ }
+ const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
+ if (fd_read == -1) {
+ PLOG(ERROR) << "Failed to open file " << cur_file_path;
+ n_error++;
+ continue;
+ }
+ std::string file_name_with_last_modified_time =
+ cur_file_name + "-" + std::to_string(st.st_mtime);
+ // string.size() does not include the null terminator. The cpio FreeBSD
+ // file header expects the null character to be included in the length.
+ const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
+ unique_fd file_auto_closer(fd_read);
+ if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
+ file_name_len)) {
+ return ++n_error;
+ }
+ size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
+ if (write_error) {
+ return n_error + write_error;
+ }
+ }
+ if (!cpioWriteFileTrailer(out_fd)) {
+ return ++n_error;
+ }
+ return n_error;
+}
+
+// Helper function to create a non-const char*.
+std::vector<char> makeCharVec(const std::string& str) {
+ std::vector<char> vec(str.size() + 1);
+ vec.assign(str.begin(), str.end());
+ vec.push_back('\0');
+ return vec;
+}
+
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+using aidl_return_util::validateAndCallWithLock;
+
+WifiChip::WifiChip(int32_t chip_id, bool is_primary,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+ const std::function<void(const std::string&)>& handler)
+ : chip_id_(chip_id),
+ legacy_hal_(legacy_hal),
+ mode_controller_(mode_controller),
+ iface_util_(iface_util),
+ is_valid_(true),
+ current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
+ modes_(feature_flags.lock()->getChipModes(is_primary)),
+ debug_ring_buffer_cb_registered_(false),
+ subsystemCallbackHandler_(handler) {
+ setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+ using_dynamic_iface_combination_ = false;
+}
+
+void WifiChip::retrieveDynamicIfaceCombination() {
+ if (using_dynamic_iface_combination_) return;
+
+ legacy_hal::wifi_iface_concurrency_matrix legacy_matrix;
+ legacy_hal::wifi_error legacy_status;
+
+ std::tie(legacy_status, legacy_matrix) =
+ legacy_hal_.lock()->getSupportedIfaceConcurrencyMatrix();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get SupportedIfaceCombinations matrix from legacy HAL: "
+ << legacyErrorToString(legacy_status);
+ return;
+ }
+
+ IWifiChip::ChipMode aidl_chip_mode;
+ if (!aidl_struct_util::convertLegacyIfaceCombinationsMatrixToChipMode(legacy_matrix,
+ &aidl_chip_mode)) {
+ LOG(ERROR) << "Failed convertLegacyIfaceCombinationsMatrixToChipMode() ";
+ return;
+ }
+
+ LOG(INFO) << "Reloading iface concurrency combination from driver";
+ aidl_chip_mode.id = feature_flags::chip_mode_ids::kV3;
+ modes_.clear();
+ modes_.push_back(aidl_chip_mode);
+ using_dynamic_iface_combination_ = true;
+}
+
+std::shared_ptr<WifiChip> WifiChip::create(
+ int32_t chip_id, bool is_primary, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+ const std::function<void(const std::string&)>& handler) {
+ std::shared_ptr<WifiChip> ptr = ndk::SharedRefBase::make<WifiChip>(
+ chip_id, is_primary, legacy_hal, mode_controller, iface_util, feature_flags, handler);
+ std::weak_ptr<WifiChip> weak_ptr_this(ptr);
+ ptr->setWeakPtr(weak_ptr_this);
+ return ptr;
+}
+
+void WifiChip::invalidate() {
+ if (!writeRingbufferFilesInternal()) {
+ LOG(ERROR) << "Error writing files to flash";
+ }
+ invalidateAndRemoveAllIfaces();
+ setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+ legacy_hal_.reset();
+ event_cb_handler_.invalidate();
+ is_valid_ = false;
+}
+
+void WifiChip::setWeakPtr(std::weak_ptr<WifiChip> ptr) {
+ weak_ptr_this_ = ptr;
+}
+
+bool WifiChip::isValid() {
+ return is_valid_;
+}
+
+std::set<std::shared_ptr<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
+ return event_cb_handler_.getCallbacks();
+}
+
+ndk::ScopedAStatus WifiChip::getId(int32_t* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
+ _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::registerEventCallback(
+ const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::registerEventCallbackInternal, event_callback);
+}
+
+ndk::ScopedAStatus WifiChip::getFeatureSet(int32_t* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getFeatureSetInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getAvailableModesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::configureChip(int32_t in_modeId) {
+ return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::configureChipInternal, in_modeId);
+}
+
+ndk::ScopedAStatus WifiChip::getMode(int32_t* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getModeInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::requestChipDebugInfoInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::requestDriverDebugDumpInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::requestFirmwareDebugDumpInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createApIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createBridgedApIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getApIfaceNames(std::vector<std::string>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getApIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getApIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiApIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getApIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeApIface(const std::string& in_ifname) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeApIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIface(
+ const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, in_brIfaceName,
+ in_ifaceInstanceName);
+}
+
+ndk::ScopedAStatus WifiChip::createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createNanIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getNanIfaceNames(std::vector<std::string>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getNanIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getNanIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiNanIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getNanIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeNanIface(const std::string& in_ifname) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeNanIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createP2pIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getP2pIfaceNames(std::vector<std::string>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getP2pIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getP2pIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiP2pIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getP2pIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeP2pIface(const std::string& in_ifname) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeP2pIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createStaIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getStaIfaceNames(std::vector<std::string>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getStaIfaceNamesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getStaIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiStaIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getStaIfaceInternal, _aidl_return, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::removeStaIface(const std::string& in_ifname) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::removeStaIfaceInternal, in_ifname);
+}
+
+ndk::ScopedAStatus WifiChip::createRttController(
+ const std::shared_ptr<IWifiStaIface>& in_boundIface,
+ std::shared_ptr<IWifiRttController>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::createRttControllerInternal, _aidl_return, in_boundIface);
+}
+
+ndk::ScopedAStatus WifiChip::getDebugRingBuffersStatus(
+ std::vector<WifiDebugRingBufferStatus>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getDebugRingBuffersStatusInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBuffer(
+ const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
+ int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::startLoggingToDebugRingBufferInternal, in_ringName,
+ in_verboseLevel, in_maxIntervalInSec, in_minDataSizeInBytes);
+}
+
+ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBuffer(const std::string& in_ringName) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::forceDumpToDebugRingBufferInternal, in_ringName);
+}
+
+ndk::ScopedAStatus WifiChip::flushRingBufferToFile() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::flushRingBufferToFileInternal);
+}
+
+ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBuffer() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::stopLoggingToDebugRingBufferInternal);
+}
+
+ndk::ScopedAStatus WifiChip::getDebugHostWakeReasonStats(
+ WifiDebugHostWakeReasonStats* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getDebugHostWakeReasonStatsInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::enableDebugErrorAlerts(bool in_enable) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::enableDebugErrorAlertsInternal, in_enable);
+}
+
+ndk::ScopedAStatus WifiChip::selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::selectTxPowerScenarioInternal, in_scenario);
+}
+
+ndk::ScopedAStatus WifiChip::resetTxPowerScenario() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::resetTxPowerScenarioInternal);
+}
+
+ndk::ScopedAStatus WifiChip::setLatencyMode(IWifiChip::LatencyMode in_mode) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setLatencyModeInternal, in_mode);
+}
+
+binder_status_t WifiChip::dump(int fd, const char**, uint32_t) {
+ {
+ std::unique_lock<std::mutex> lk(lock_t);
+ for (const auto& item : ringbuffer_map_) {
+ forceDumpToDebugRingBufferInternal(item.first);
+ }
+ // unique_lock unlocked here
+ }
+ usleep(100 * 1000); // sleep for 100 milliseconds to wait for
+ // ringbuffer updates.
+ if (!writeRingbufferFilesInternal()) {
+ LOG(ERROR) << "Error writing files to flash";
+ }
+ uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
+ if (n_error != 0) {
+ LOG(ERROR) << n_error << " errors occurred in cpio function";
+ }
+ fsync(fd);
+ return STATUS_OK;
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnection(const std::string& in_ifName) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setMultiStaPrimaryConnectionInternal, in_ifName);
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setMultiStaUseCaseInternal, in_useCase);
+}
+
+ndk::ScopedAStatus WifiChip::setCoexUnsafeChannels(
+ const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
+ int32_t in_restrictions) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setCoexUnsafeChannelsInternal, in_unsafeChannels,
+ in_restrictions);
+}
+
+ndk::ScopedAStatus WifiChip::setCountryCode(const std::array<uint8_t, 2>& in_code) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiChip::setCountryCodeInternal, in_code);
+}
+
+ndk::ScopedAStatus WifiChip::getUsableChannels(WifiBand in_band, int32_t in_ifaceModeMask,
+ int32_t in_filterMask,
+ std::vector<WifiUsableChannel>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getUsableChannelsInternal, _aidl_return, in_band,
+ in_ifaceModeMask, in_filterMask);
+}
+
+ndk::ScopedAStatus WifiChip::setAfcChannelAllowance(
+ const AfcChannelAllowance& afcChannelAllowance) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setAfcChannelAllowanceInternal, afcChannelAllowance);
+}
+
+ndk::ScopedAStatus WifiChip::triggerSubsystemRestart() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::triggerSubsystemRestartInternal);
+}
+
+ndk::ScopedAStatus WifiChip::getSupportedRadioCombinations(
+ std::vector<WifiRadioCombination>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getSupportedRadioCombinationsInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::getWifiChipCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiChip::enableStaChannelForPeerNetwork(int32_t in_channelCategoryEnableFlag) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::enableStaChannelForPeerNetworkInternal,
+ in_channelCategoryEnableFlag);
+}
+
+ndk::ScopedAStatus WifiChip::setMloMode(const ChipMloMode in_mode) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setMloModeInternal, in_mode);
+}
+
+void WifiChip::invalidateAndRemoveAllIfaces() {
+ invalidateAndClearBridgedApAll();
+ invalidateAndClearAll(ap_ifaces_);
+ invalidateAndClearAll(nan_ifaces_);
+ invalidateAndClearAll(p2p_ifaces_);
+ invalidateAndClearAll(sta_ifaces_);
+ // Since all the ifaces are invalid now, all RTT controller objects
+ // using those ifaces also need to be invalidated.
+ for (const auto& rtt : rtt_controllers_) {
+ rtt->invalidate();
+ }
+ rtt_controllers_.clear();
+}
+
+void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
+ for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
+ auto nan_iface = *it;
+ if (nan_iface->getName() == removed_iface_name) {
+ nan_iface->invalidate();
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, removed_iface_name).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ it = nan_ifaces_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+ for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
+ auto rtt = *it;
+ if (rtt->getIfaceName() == removed_iface_name) {
+ rtt->invalidate();
+ it = rtt_controllers_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getIdInternal() {
+ return {chip_id_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::registerEventCallbackInternal(
+ const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
+ if (!event_cb_handler_.addCallback(event_callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getFeatureSetInternal() {
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ uint32_t legacy_logger_feature_set;
+ const auto ifname = getFirstActiveWlanIfaceName();
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {0, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ std::tie(legacy_status, legacy_logger_feature_set) =
+ legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ // some devices don't support querying logger feature set
+ legacy_logger_feature_set = 0;
+ }
+ uint32_t aidl_feature_set;
+ if (!aidl_struct_util::convertLegacyChipFeaturesToAidl(legacy_feature_set, &aidl_feature_set)) {
+ return {0, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_feature_set, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus>
+WifiChip::getAvailableModesInternal() {
+ return {modes_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::configureChipInternal(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
+ if (!isValidModeId(mode_id)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ if (mode_id == current_mode_id_) {
+ LOG(DEBUG) << "Already in the specified mode " << mode_id;
+ return ndk::ScopedAStatus::ok();
+ }
+ ndk::ScopedAStatus status = handleChipConfiguration(lock, mode_id);
+ if (!status.isOk()) {
+ WifiStatusCode errorCode = static_cast<WifiStatusCode>(status.getServiceSpecificError());
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onChipReconfigureFailure(errorCode).isOk()) {
+ LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
+ }
+ }
+ return status;
+ }
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onChipReconfigured(mode_id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
+ }
+ }
+ current_mode_id_ = mode_id;
+ LOG(INFO) << "Configured chip in mode " << mode_id;
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+
+ legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
+
+ return status;
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getModeInternal() {
+ if (!isValidModeId(current_mode_id_)) {
+ return {current_mode_id_, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ return {current_mode_id_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> WifiChip::requestChipDebugInfoInternal() {
+ IWifiChip::ChipDebugInfo result;
+ legacy_hal::wifi_error legacy_status;
+ std::string driver_desc;
+ const auto ifname = getFirstActiveWlanIfaceName();
+ std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
+ ndk::ScopedAStatus status =
+ createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
+ return {std::move(result), std::move(status)};
+ }
+ result.driverDescription = driver_desc.c_str();
+
+ std::string firmware_desc;
+ std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
+ ndk::ScopedAStatus status =
+ createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
+ return {std::move(result), std::move(status)};
+ }
+ result.firmwareDescription = firmware_desc.c_str();
+
+ return {std::move(result), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestDriverDebugDumpInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<uint8_t> driver_dump;
+ std::tie(legacy_status, driver_dump) =
+ legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
+ return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
+ }
+ return {driver_dump, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestFirmwareDebugDumpInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<uint8_t> firmware_dump;
+ std::tie(legacy_status, firmware_dump) =
+ legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
+ return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
+ }
+ return {firmware_dump, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
+ legacy_hal::wifi_error legacy_status;
+ legacy_status = legacy_hal_.lock()->createVirtualInterface(
+ apVirtIf, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::AP));
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
+ << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
+ std::vector<std::string> ap_instances;
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ifname) {
+ ap_instances = it.second;
+ }
+ }
+ std::shared_ptr<WifiApIface> iface =
+ ndk::SharedRefBase::make<WifiApIface>(ifname, ap_instances, legacy_hal_, iface_util_);
+ ap_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return iface;
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::createApIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
+ return {std::shared_ptr<WifiApIface>(),
+ createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ std::string ifname = allocateApIfaceName();
+ ndk::ScopedAStatus status = createVirtualApInterface(ifname);
+ if (!status.isOk()) {
+ return {std::shared_ptr<WifiApIface>(), std::move(status)};
+ }
+ std::shared_ptr<WifiApIface> iface = newWifiApIface(ifname);
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
+WifiChip::createBridgedApIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
+ if (ap_instances.size() < 2) {
+ LOG(ERROR) << "Fail to allocate two instances";
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
+ for (int i = 0; i < 2; i++) {
+ ndk::ScopedAStatus status = createVirtualApInterface(ap_instances[i]);
+ if (!status.isOk()) {
+ if (i != 0) { // The failure happened when creating second virtual
+ // iface.
+ legacy_hal_.lock()->deleteVirtualInterface(
+ ap_instances.front()); // Remove the first virtual iface.
+ }
+ return {nullptr, std::move(status)};
+ }
+ }
+ br_ifaces_ap_instances_[br_ifname] = ap_instances;
+ if (!iface_util_->createBridge(br_ifname)) {
+ LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
+ invalidateAndClearBridgedAp(br_ifname);
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ for (auto const& instance : ap_instances) {
+ // Bind ap instance interface to AP bridge
+ if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
+ LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
+ invalidateAndClearBridgedAp(br_ifname);
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ }
+ std::shared_ptr<WifiApIface> iface = newWifiApIface(br_ifname);
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getApIfaceNamesInternal() {
+ if (ap_ifaces_.empty()) {
+ return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+ }
+ return {getNames(ap_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::getApIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get()) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Invalidate & remove any dependent objects first.
+ // Note: This is probably not required because we never create
+ // nan/rtt objects over AP iface. But, there is no harm to do it
+ // here and not make that assumption all over the place.
+ invalidateAndRemoveDependencies(ifname);
+ // Clear the bridge interface and the iface instance.
+ invalidateAndClearBridgedAp(ifname);
+ invalidateAndClear(ap_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
+ const std::string& ifname, const std::string& ifInstanceName) {
+ const auto iface = findUsingName(ap_ifaces_, ifname);
+ if (!iface.get() || ifInstanceName.empty()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Requires to remove one of the instance in bridge mode
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ifname) {
+ std::vector<std::string> ap_instances = it.second;
+ for (auto const& iface : ap_instances) {
+ if (iface == ifInstanceName) {
+ if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
+ LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
+ << ifname;
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to del interface: " << iface << " "
+ << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ ap_instances.erase(
+ std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
+ ap_instances.end());
+ br_ifaces_ap_instances_[ifname] = ap_instances;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ iface->removeInstance(ifInstanceName);
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::createNanIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN_IFACE)) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ bool is_dedicated_iface = true;
+ std::string ifname = getPredefinedNanIfaceName();
+ if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
+ // Use the first shared STA iface (wlan0) if a dedicated aware iface is
+ // not defined.
+ ifname = getFirstActiveWlanIfaceName();
+ is_dedicated_iface = false;
+ }
+ std::shared_ptr<WifiNanIface> iface =
+ WifiNanIface::create(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
+ nan_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::NAN_IFACE, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getNanIfaceNamesInternal() {
+ if (nan_ifaces_.empty()) {
+ return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+ }
+ return {getNames(nan_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::getNanIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(nan_ifaces_, ifname);
+ if (!iface.get()) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(nan_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ invalidateAndClear(nan_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::createP2pIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ std::string ifname = getPredefinedP2pIfaceName();
+ std::shared_ptr<WifiP2pIface> iface =
+ ndk::SharedRefBase::make<WifiP2pIface>(ifname, legacy_hal_);
+ p2p_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getP2pIfaceNamesInternal() {
+ if (p2p_ifaces_.empty()) {
+ return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+ }
+ return {getNames(p2p_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::getP2pIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(p2p_ifaces_, ifname);
+ if (!iface.get()) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(p2p_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ invalidateAndClear(p2p_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::createStaIfaceInternal() {
+ if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ std::string ifname = allocateStaIfaceName();
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
+ ifname, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::STA));
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to add interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ return {nullptr, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ std::shared_ptr<WifiStaIface> iface = WifiStaIface::create(ifname, legacy_hal_, iface_util_);
+ sta_ifaces_.push_back(iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getStaIfaceNamesInternal() {
+ if (sta_ifaces_.empty()) {
+ return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
+ }
+ return {getNames(sta_ifaces_), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::getStaIfaceInternal(
+ const std::string& ifname) {
+ const auto iface = findUsingName(sta_ifaces_, ifname);
+ if (!iface.get()) {
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {iface, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
+ const auto iface = findUsingName(sta_ifaces_, ifname);
+ if (!iface.get()) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ // Invalidate & remove any dependent objects first.
+ invalidateAndRemoveDependencies(ifname);
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to remove interface: " << ifname << " "
+ << legacyErrorToString(legacy_status);
+ }
+ invalidateAndClear(sta_ifaces_, iface);
+ for (const auto& callback : event_cb_handler_.getCallbacks()) {
+ if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
+ LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
+ }
+ }
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus>
+WifiChip::createRttControllerInternal(const std::shared_ptr<IWifiStaIface>& bound_iface) {
+ if (sta_ifaces_.size() == 0 &&
+ !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
+ LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs "
+ "(and RTT by extension)";
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+ }
+ std::shared_ptr<WifiRttController> rtt =
+ WifiRttController::create(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
+ rtt_controllers_.emplace_back(rtt);
+ return {rtt, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
+WifiChip::getDebugRingBuffersStatusInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
+ std::tie(legacy_status, legacy_ring_buffer_status_vec) =
+ legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {std::vector<WifiDebugRingBufferStatus>(),
+ createWifiStatusFromLegacyError(legacy_status)};
+ }
+ std::vector<WifiDebugRingBufferStatus> aidl_ring_buffer_status_vec;
+ if (!aidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToAidl(
+ legacy_ring_buffer_status_vec, &aidl_ring_buffer_status_vec)) {
+ return {std::vector<WifiDebugRingBufferStatus>(),
+ createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_ring_buffer_status_vec, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBufferInternal(
+ const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+ uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
+ ndk::ScopedAStatus status = registerDebugRingBufferCallback();
+ if (!status.isOk()) {
+ return status;
+ }
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
+ getFirstActiveWlanIfaceName(), ring_name,
+ static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
+ max_interval_in_sec, min_data_size_in_bytes);
+ ringbuffer_map_.insert(
+ std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
+ // if verbose logging enabled, turn up HAL daemon logging as well.
+ if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
+ ::android::base::SetMinimumLogSeverity(::android::base::DEBUG);
+ } else {
+ ::android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBufferInternal(const std::string& ring_name) {
+ ndk::ScopedAStatus status = registerDebugRingBufferCallback();
+ if (!status.isOk()) {
+ return status;
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
+
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::flushRingBufferToFileInternal() {
+ if (!writeRingbufferFilesInternal()) {
+ LOG(ERROR) << "Error writing files to flash";
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
+ if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+ debug_ring_buffer_cb_registered_ = false;
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
+WifiChip::getDebugHostWakeReasonStatsInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::WakeReasonStats legacy_stats;
+ std::tie(legacy_status, legacy_stats) =
+ legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {WifiDebugHostWakeReasonStats{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ WifiDebugHostWakeReasonStats aidl_stats;
+ if (!aidl_struct_util::convertLegacyWakeReasonStatsToAidl(legacy_stats, &aidl_stats)) {
+ return {WifiDebugHostWakeReasonStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_stats, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
+ legacy_hal::wifi_error legacy_status;
+ if (enable) {
+ std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
+ const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
+ std::vector<uint8_t> debug_data) {
+ 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->onDebugErrorAlert(error_code, debug_data).isOk()) {
+ LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
+ }
+ }
+ };
+ legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
+ getFirstActiveWlanIfaceName(), on_alert_callback);
+ } else {
+ legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
+ getFirstActiveWlanIfaceName());
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario) {
+ auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
+ getFirstActiveWlanIfaceName(),
+ aidl_struct_util::convertAidlTxPowerScenarioToLegacy(scenario));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::resetTxPowerScenarioInternal() {
+ auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setLatencyModeInternal(IWifiChip::LatencyMode mode) {
+ auto legacy_status = legacy_hal_.lock()->setLatencyMode(
+ getFirstActiveWlanIfaceName(), aidl_struct_util::convertAidlLatencyModeToLegacy(mode));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
+ auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case) {
+ auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
+ aidl_struct_util::convertAidlMultiStaUseCaseToLegacy(use_case));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setCoexUnsafeChannelsInternal(
+ std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels, int32_t aidl_restrictions) {
+ std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
+ if (!aidl_struct_util::convertAidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
+ &legacy_unsafe_channels)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ uint32_t legacy_restrictions = 0;
+ if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_DIRECT)) {
+ legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
+ }
+ if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::SOFTAP)) {
+ legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
+ }
+ if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_AWARE)) {
+ legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
+ }
+ auto legacy_status =
+ legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
+ auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> WifiChip::getUsableChannelsInternal(
+ WifiBand band, int32_t ifaceModeMask, int32_t filterMask) {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
+ std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
+ aidl_struct_util::convertAidlWifiBandToLegacyMacBand(band),
+ aidl_struct_util::convertAidlWifiIfaceModeToLegacy(ifaceModeMask),
+ aidl_struct_util::convertAidlUsableChannelFilterToLegacy(filterMask));
+
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {std::vector<WifiUsableChannel>(), createWifiStatusFromLegacyError(legacy_status)};
+ }
+ std::vector<WifiUsableChannel> aidl_usable_channels;
+ if (!aidl_struct_util::convertLegacyWifiUsableChannelsToAidl(legacy_usable_channels,
+ &aidl_usable_channels)) {
+ return {std::vector<WifiUsableChannel>(), createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_usable_channels, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::setAfcChannelAllowanceInternal(
+ const AfcChannelAllowance& afcChannelAllowance) {
+ LOG(INFO) << "setAfcChannelAllowance is not yet supported. availableAfcFrequencyInfos size="
+ << afcChannelAllowance.availableAfcFrequencyInfos.size()
+ << " availableAfcChannelInfos size="
+ << afcChannelAllowance.availableAfcChannelInfos.size()
+ << " availabilityExpireTimeMs=" << afcChannelAllowance.availabilityExpireTimeMs;
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+std::pair<std::vector<WifiRadioCombination>, ndk::ScopedAStatus>
+WifiChip::getSupportedRadioCombinationsInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
+ std::vector<WifiRadioCombination> aidl_combinations;
+
+ std::tie(legacy_status, legacy_matrix) =
+ legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
+ << legacyErrorToString(legacy_status);
+ return {aidl_combinations, createWifiStatusFromLegacyError(legacy_status)};
+ }
+
+ if (!aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
+ &aidl_combinations)) {
+ LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToAidl() ";
+ return {aidl_combinations, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {aidl_combinations, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<WifiChipCapabilities, ndk::ScopedAStatus> WifiChip::getWifiChipCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_chip_capabilities legacy_chip_capabilities;
+ std::tie(legacy_status, legacy_chip_capabilities) =
+ legacy_hal_.lock()->getWifiChipCapabilities();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to get chip capabilities from legacy HAL: "
+ << legacyErrorToString(legacy_status);
+ return {WifiChipCapabilities(), createWifiStatusFromLegacyError(legacy_status)};
+ }
+ WifiChipCapabilities aidl_chip_capabilities;
+ if (!aidl_struct_util::convertLegacyWifiChipCapabilitiesToAidl(legacy_chip_capabilities,
+ aidl_chip_capabilities)) {
+ LOG(ERROR) << "Failed convertLegacyWifiChipCapabilitiesToAidl() ";
+ return {WifiChipCapabilities(), createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+
+ return {aidl_chip_capabilities, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiChip::enableStaChannelForPeerNetworkInternal(
+ int32_t channelCategoryEnableFlag) {
+ auto legacy_status = legacy_hal_.lock()->enableStaChannelForPeerNetwork(
+ aidl_struct_util::convertAidlChannelCategoryToLegacy(channelCategoryEnableFlag));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::triggerSubsystemRestartInternal() {
+ auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::handleChipConfiguration(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
+ // If the chip is already configured in a different mode, stop
+ // the legacy HAL and then start it after firmware mode change.
+ if (isValidModeId(current_mode_id_)) {
+ LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
+ invalidateAndRemoveAllIfaces();
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ }
+ // Firmware mode change not needed for V2 devices.
+ bool success = true;
+ if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
+ success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
+ } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
+ success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
+ }
+ if (!success) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+ // Every time the HAL is restarted, we need to register the
+ // radio mode change callback.
+ ndk::ScopedAStatus status = registerRadioModeChangeCallback();
+ if (!status.isOk()) {
+ // This is probably not a critical failure?
+ LOG(ERROR) << "Failed to register radio mode change callback";
+ }
+ // Extract and save the version information into property.
+ std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> version_info;
+ version_info = WifiChip::requestChipDebugInfoInternal();
+ if (version_info.second.isOk()) {
+ property_set("vendor.wlan.firmware.version",
+ version_info.first.firmwareDescription.c_str());
+ property_set("vendor.wlan.driver.version", version_info.first.driverDescription.c_str());
+ }
+ // Get the driver supported interface combination.
+ retrieveDynamicIfaceCombination();
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiChip::registerDebugRingBufferCallback() {
+ if (debug_ring_buffer_cb_registered_) {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
+ const auto& on_ring_buffer_data_callback =
+ [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
+ const legacy_hal::wifi_ring_buffer_status& status) {
+ 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;
+ }
+ WifiDebugRingBufferStatus aidl_status;
+ Ringbuffer::AppendStatus appendstatus;
+ if (!aidl_struct_util::convertLegacyDebugRingBufferStatusToAidl(status,
+ &aidl_status)) {
+ LOG(ERROR) << "Error converting ring buffer status";
+ return;
+ }
+ {
+ std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
+ const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
+ if (target != shared_ptr_this->ringbuffer_map_.end()) {
+ Ringbuffer& cur_buffer = target->second;
+ appendstatus = cur_buffer.append(data);
+ } else {
+ LOG(ERROR) << "Ringname " << name << " not found";
+ return;
+ }
+ // unique_lock unlocked here
+ }
+ if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
+ LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
+ shared_ptr_this->writeRingbufferFilesInternal();
+ return;
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
+ getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
+
+ if (legacy_status == legacy_hal::WIFI_SUCCESS) {
+ debug_ring_buffer_cb_registered_ = true;
+ }
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiChip::registerRadioModeChangeCallback() {
+ std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
+ const auto& on_radio_mode_change_callback =
+ [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
+ 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;
+ }
+ std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
+ if (!aidl_struct_util::convertLegacyWifiMacInfosToAidl(mac_infos,
+ &aidl_radio_mode_infos)) {
+ LOG(ERROR) << "Error converting wifi mac info";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onRadioModeChange(aidl_radio_mode_infos).isOk()) {
+ LOG(ERROR) << "Failed to invoke onRadioModeChange callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
+ getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::vector<IWifiChip::ChipConcurrencyCombination>
+WifiChip::getCurrentModeConcurrencyCombinations() {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return std::vector<IWifiChip::ChipConcurrencyCombination>();
+ }
+ for (const auto& mode : modes_) {
+ if (mode.id == current_mode_id_) {
+ return mode.availableCombinations;
+ }
+ }
+ CHECK(0) << "Expected to find concurrency combinations for current mode!";
+ return std::vector<IWifiChip::ChipConcurrencyCombination>();
+}
+
+// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
+// created of the corresponding concurrency type.
+std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
+ std::map<IfaceConcurrencyType, size_t> iface_counts;
+ uint32_t num_ap = 0;
+ uint32_t num_ap_bridged = 0;
+ for (const auto& ap_iface : ap_ifaces_) {
+ std::string ap_iface_name = ap_iface->getName();
+ if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
+ br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
+ num_ap_bridged++;
+ } else {
+ num_ap++;
+ }
+ }
+ iface_counts[IfaceConcurrencyType::AP] = num_ap;
+ iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
+ iface_counts[IfaceConcurrencyType::NAN_IFACE] = nan_ifaces_.size();
+ iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
+ iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
+ return iface_counts;
+}
+
+// This expands the provided concurrency combinations to a more parseable
+// form. Returns a vector of available combinations possible with the number
+// of each concurrency type in the combination.
+// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
+std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
+ const IWifiChip::ChipConcurrencyCombination& combination) {
+ int32_t num_expanded_combos = 1;
+ for (const auto& limit : combination.limits) {
+ for (int32_t i = 0; i < limit.maxIfaces; i++) {
+ num_expanded_combos *= limit.types.size();
+ }
+ }
+
+ // Allocate the vector of expanded combos and reset all concurrency type counts to 0
+ // in each combo.
+ std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
+ expanded_combos.resize(num_expanded_combos);
+ for (auto& expanded_combo : expanded_combos) {
+ for (const auto type : {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
+ IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P,
+ IfaceConcurrencyType::STA}) {
+ expanded_combo[type] = 0;
+ }
+ }
+ int32_t span = num_expanded_combos;
+ for (const auto& limit : combination.limits) {
+ for (int32_t i = 0; i < limit.maxIfaces; i++) {
+ span /= limit.types.size();
+ for (int32_t k = 0; k < num_expanded_combos; ++k) {
+ const auto iface_type = limit.types[(k / span) % limit.types.size()];
+ expanded_combos[k][iface_type]++;
+ }
+ }
+ }
+ return expanded_combos;
+}
+
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ IfaceConcurrencyType requested_type) {
+ const auto current_combo = getCurrentConcurrencyCombination();
+
+ // Check if we have space for 1 more iface of |type| in this combo
+ for (const auto type :
+ {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
+ IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+ size_t num_ifaces_needed = current_combo.at(type);
+ if (type == requested_type) {
+ num_ifaces_needed++;
+ }
+ size_t num_ifaces_allowed = expanded_combo.at(type);
+ if (num_ifaces_needed > num_ifaces_allowed) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+// ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode
+// with the concurrency combination that is already active.
+bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
+ IfaceConcurrencyType requested_type) {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return false;
+ }
+ const auto combinations = getCurrentModeConcurrencyCombinations();
+ for (const auto& combination : combinations) {
+ const auto expanded_combos = expandConcurrencyCombinations(combination);
+ for (const auto& expanded_combo : expanded_combos) {
+ if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
+ requested_type)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Note: This does not consider concurrency types already active. It only checks if the
+// provided expanded concurrency combination can support the requested combo.
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+ // Check if we have space for 1 more |type| in this combo
+ for (const auto type :
+ {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
+ IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
+ if (req_combo.count(type) == 0) {
+ // Concurrency type not in the req_combo.
+ continue;
+ }
+ size_t num_ifaces_needed = req_combo.at(type);
+ size_t num_ifaces_allowed = expanded_combo.at(type);
+ if (num_ifaces_needed > num_ifaces_allowed) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+// ChipConcurrencyCombination.
+// b) Check if the requested concurrency combo can be added to the current mode.
+// Note: This does not consider concurrency types already active. It only checks if the
+// current mode can support the requested combo.
+bool WifiChip::canCurrentModeSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return false;
+ }
+ const auto combinations = getCurrentModeConcurrencyCombinations();
+ for (const auto& combination : combinations) {
+ const auto expanded_combos = expandConcurrencyCombinations(combination);
+ for (const auto& expanded_combo : expanded_combos) {
+ if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// This method does the following:
+// a) Enumerate all possible concurrency combos by expanding the current
+// ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode.
+bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
+ // Check if we can support at least 1 of the requested concurrency type.
+ std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+ req_iface_combo[requested_type] = 1;
+ return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+bool WifiChip::isValidModeId(int32_t mode_id) {
+ for (const auto& mode : modes_) {
+ if (mode.id == mode_id) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
+ // Check if we can support at least 1 STA & 1 AP concurrently.
+ std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+ req_iface_combo[IfaceConcurrencyType::STA] = 1;
+ req_iface_combo[IfaceConcurrencyType::AP] = 1;
+ return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
+ // Check if we can support at least 2 STA concurrently.
+ std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+ req_iface_combo[IfaceConcurrencyType::STA] = 2;
+ return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
+}
+
+std::string WifiChip::getFirstActiveWlanIfaceName() {
+ if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
+ if (ap_ifaces_.size() > 0) {
+ // If the first active wlan iface is bridged iface.
+ // Return first instance name.
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == ap_ifaces_[0]->getName()) {
+ return it.second[0];
+ }
+ }
+ return ap_ifaces_[0]->getName();
+ }
+ // This could happen if the chip call is made before any STA/AP
+ // iface is created. Default to wlan0 for such cases.
+ LOG(WARNING) << "No active wlan interfaces in use! Using default";
+ return getWlanIfaceNameWithType(IfaceType::STA, 0);
+}
+
+// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
+// not already in use.
+// Note: This doesn't check the actual presence of these interfaces.
+std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
+ for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
+ const auto ifname = getWlanIfaceNameWithType(type, idx);
+ if (findUsingNameFromBridgedApInstances(ifname)) continue;
+ if (findUsingName(ap_ifaces_, ifname)) continue;
+ if (findUsingName(sta_ifaces_, ifname)) continue;
+ return ifname;
+ }
+ // This should never happen. We screwed up somewhere if it did.
+ CHECK(false) << "All wlan interfaces in use already!";
+ return {};
+}
+
+uint32_t WifiChip::startIdxOfApIface() {
+ if (isDualStaConcurrencyAllowedInCurrentMode()) {
+ // When the HAL support dual STAs, AP should start with idx 2.
+ return 2;
+ } else if (isStaApConcurrencyAllowedInCurrentMode()) {
+ // When the HAL support STA + AP but it doesn't support dual STAs.
+ // AP should start with idx 1.
+ return 1;
+ }
+ // No concurrency support.
+ return 0;
+}
+
+// AP iface names start with idx 1 for modes supporting
+// concurrent STA and not dual AP, else start with idx 0.
+std::string WifiChip::allocateApIfaceName() {
+ // Check if we have a dedicated iface for AP.
+ std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
+ for (auto const& ifname : ifnames) {
+ if (findUsingName(ap_ifaces_, ifname)) continue;
+ return ifname;
+ }
+ return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
+}
+
+std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
+ // Check if we have a dedicated iface for AP.
+ std::vector<std::string> instances = getPredefinedApIfaceNames(true);
+ if (instances.size() == 2) {
+ return instances;
+ } else {
+ int num_ifaces_need_to_allocate = 2 - instances.size();
+ for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
+ std::string instance_name =
+ allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
+ if (!instance_name.empty()) {
+ instances.push_back(instance_name);
+ }
+ }
+ }
+ return instances;
+}
+
+// STA iface names start with idx 0.
+// Primary STA iface will always be 0.
+std::string WifiChip::allocateStaIfaceName() {
+ return allocateApOrStaIfaceName(IfaceType::STA, 0);
+}
+
+bool WifiChip::writeRingbufferFilesInternal() {
+ if (!removeOldFilesInternal()) {
+ LOG(ERROR) << "Error occurred while deleting old tombstone files";
+ return false;
+ }
+ // write ringbuffers to file
+ {
+ std::unique_lock<std::mutex> lk(lock_t);
+ for (auto& item : ringbuffer_map_) {
+ Ringbuffer& cur_buffer = item.second;
+ if (cur_buffer.getData().empty()) {
+ continue;
+ }
+ const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
+ const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
+ if (dump_fd == -1) {
+ PLOG(ERROR) << "create file failed";
+ return false;
+ }
+ unique_fd file_auto_closer(dump_fd);
+ for (const auto& cur_block : cur_buffer.getData()) {
+ if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
+ PLOG(ERROR) << "Ring buffer: " << item.first
+ << " is corrupted. Invalid block size: " << cur_block.size();
+ break;
+ }
+ if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
+ -1) {
+ PLOG(ERROR) << "Error writing to file";
+ }
+ }
+ cur_buffer.clear();
+ }
+ // unique_lock unlocked here
+ }
+ return true;
+}
+
+std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
+ std::string ifname;
+
+ // let the legacy hal override the interface name
+ legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
+ if (err == legacy_hal::WIFI_SUCCESS) return ifname;
+
+ return getWlanIfaceName(idx);
+}
+
+void WifiChip::invalidateAndClearBridgedApAll() {
+ for (auto const& it : br_ifaces_ap_instances_) {
+ for (auto const& iface : it.second) {
+ iface_util_->removeIfaceFromBridge(it.first, iface);
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ }
+ iface_util_->deleteBridge(it.first);
+ }
+ br_ifaces_ap_instances_.clear();
+}
+
+void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) {
+ if (br_name.empty()) return;
+ // delete managed interfaces
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == br_name) {
+ for (auto const& iface : it.second) {
+ iface_util_->removeIfaceFromBridge(br_name, iface);
+ legacy_hal_.lock()->deleteVirtualInterface(iface);
+ }
+ iface_util_->deleteBridge(br_name);
+ br_ifaces_ap_instances_.erase(br_name);
+ break;
+ }
+ }
+ return;
+}
+
+bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
+ for (auto const& it : br_ifaces_ap_instances_) {
+ if (it.first == name) {
+ return true;
+ }
+ for (auto const& iface : it.second) {
+ if (iface == name) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+ndk::ScopedAStatus WifiChip::setMloModeInternal(const WifiChip::ChipMloMode in_mode) {
+ legacy_hal::wifi_mlo_mode mode;
+ switch (in_mode) {
+ case WifiChip::ChipMloMode::DEFAULT:
+ mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_DEFAULT;
+ break;
+ case WifiChip::ChipMloMode::LOW_LATENCY:
+ mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_LOW_LATENCY;
+ break;
+ case WifiChip::ChipMloMode::HIGH_THROUGHPUT:
+ mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_HIGH_THROUGHPUT;
+ break;
+ case WifiChip::ChipMloMode::LOW_POWER:
+ mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_LOW_POWER;
+ break;
+ default:
+ PLOG(ERROR) << "Error: invalid mode: " << toString(in_mode);
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ return createWifiStatusFromLegacyError(legacy_hal_.lock()->setMloMode(mode));
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
new file mode 100644
index 0000000..4ddee92
--- /dev/null
+++ b/wifi/aidl/default/wifi_chip.h
@@ -0,0 +1,299 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_CHIP_H_
+#define WIFI_CHIP_H_
+
+#include <aidl/android/hardware/wifi/BnWifiChip.h>
+#include <aidl/android/hardware/wifi/IWifiRttController.h>
+#include <android-base/macros.h>
+
+#include <list>
+#include <map>
+#include <mutex>
+
+#include "aidl_callback_util.h"
+#include "ringbuffer.h"
+#include "wifi_ap_iface.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_mode_controller.h"
+#include "wifi_nan_iface.h"
+#include "wifi_p2p_iface.h"
+#include "wifi_rtt_controller.h"
+#include "wifi_sta_iface.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a Wifi HAL chip instance.
+ * Since there is only a single chip instance used today, there is no
+ * identifying handle information stored here.
+ */
+class WifiChip : public BnWifiChip {
+ public:
+ WifiChip(int32_t chip_id, bool is_primary,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+ const std::function<void(const std::string&)>& subsystemCallbackHandler);
+
+ // Factory method - use instead of default constructor.
+ static std::shared_ptr<WifiChip> create(
+ int32_t chip_id, bool is_primary,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+ const std::function<void(const std::string&)>& subsystemCallbackHandler);
+
+ // AIDL does not provide a built-in mechanism to let the server invalidate
+ // an AIDL interface object after creation. If any client process holds onto
+ // a reference to the object in their context, any method calls on that
+ // reference will continue to be directed to the server.
+ //
+ // However Wifi HAL needs to control the lifetime of these objects. So, add
+ // a public |invalidate| method to |WifiChip| and its child objects. This
+ // will be used to mark an object invalid when either:
+ // a) Wifi HAL is stopped, or
+ // b) Wifi Chip is reconfigured.
+ //
+ // All AIDL method implementations should check if the object is still
+ // marked valid before processing them.
+ void invalidate();
+ bool isValid();
+ std::set<std::shared_ptr<IWifiChipEventCallback>> getEventCallbacks();
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus registerEventCallback(
+ const std::shared_ptr<IWifiChipEventCallback>& in_callback) override;
+ ndk::ScopedAStatus getFeatureSet(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) override;
+ ndk::ScopedAStatus configureChip(int32_t in_modeId) override;
+ ndk::ScopedAStatus getMode(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) override;
+ ndk::ScopedAStatus requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) override;
+ ndk::ScopedAStatus requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) override;
+ ndk::ScopedAStatus createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) override;
+ ndk::ScopedAStatus createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) override;
+ ndk::ScopedAStatus getApIfaceNames(std::vector<std::string>* _aidl_return) override;
+ ndk::ScopedAStatus getApIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiApIface>* _aidl_return) override;
+ ndk::ScopedAStatus removeApIface(const std::string& in_ifname) override;
+ ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIface(
+ const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) override;
+ ndk::ScopedAStatus createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) override;
+ ndk::ScopedAStatus getNanIfaceNames(std::vector<std::string>* _aidl_return) override;
+ ndk::ScopedAStatus getNanIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiNanIface>* _aidl_return) override;
+ ndk::ScopedAStatus removeNanIface(const std::string& in_ifname) override;
+ ndk::ScopedAStatus createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) override;
+ ndk::ScopedAStatus getP2pIfaceNames(std::vector<std::string>* _aidl_return) override;
+ ndk::ScopedAStatus getP2pIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiP2pIface>* _aidl_return) override;
+ ndk::ScopedAStatus removeP2pIface(const std::string& in_ifname) override;
+ ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) override;
+ ndk::ScopedAStatus getStaIfaceNames(std::vector<std::string>* _aidl_return) override;
+ ndk::ScopedAStatus getStaIface(const std::string& in_ifname,
+ std::shared_ptr<IWifiStaIface>* _aidl_return) override;
+ ndk::ScopedAStatus removeStaIface(const std::string& in_ifname) override;
+ ndk::ScopedAStatus createRttController(
+ const std::shared_ptr<IWifiStaIface>& in_boundIface,
+ std::shared_ptr<IWifiRttController>* _aidl_return) override;
+ ndk::ScopedAStatus getDebugRingBuffersStatus(
+ std::vector<WifiDebugRingBufferStatus>* _aidl_return) override;
+ ndk::ScopedAStatus startLoggingToDebugRingBuffer(
+ const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
+ int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) override;
+ ndk::ScopedAStatus forceDumpToDebugRingBuffer(const std::string& in_ringName) override;
+ ndk::ScopedAStatus flushRingBufferToFile() override;
+ ndk::ScopedAStatus stopLoggingToDebugRingBuffer() override;
+ ndk::ScopedAStatus getDebugHostWakeReasonStats(
+ WifiDebugHostWakeReasonStats* _aidl_return) override;
+ ndk::ScopedAStatus enableDebugErrorAlerts(bool in_enable) override;
+ ndk::ScopedAStatus selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) override;
+ ndk::ScopedAStatus resetTxPowerScenario() override;
+ ndk::ScopedAStatus setLatencyMode(IWifiChip::LatencyMode in_mode) override;
+ ndk::ScopedAStatus setMultiStaPrimaryConnection(const std::string& in_ifName) override;
+ ndk::ScopedAStatus setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) override;
+ ndk::ScopedAStatus setCoexUnsafeChannels(
+ const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
+ int32_t in_restrictions) override;
+ ndk::ScopedAStatus setCountryCode(const std::array<uint8_t, 2>& in_code) override;
+ ndk::ScopedAStatus getUsableChannels(WifiBand in_band, int32_t in_ifaceModeMask,
+ int32_t in_filterMask,
+ std::vector<WifiUsableChannel>* _aidl_return) override;
+ ndk::ScopedAStatus setAfcChannelAllowance(
+ const AfcChannelAllowance& afcChannelAllowance) override;
+ ndk::ScopedAStatus triggerSubsystemRestart() override;
+ ndk::ScopedAStatus getSupportedRadioCombinations(
+ std::vector<WifiRadioCombination>* _aidl_return) override;
+ ndk::ScopedAStatus getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus enableStaChannelForPeerNetwork(
+ 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;
+
+ private:
+ void invalidateAndRemoveAllIfaces();
+ // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
+ // invalidated & removed.
+ void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
+
+ // Corresponding worker functions for the AIDL methods.
+ std::pair<int32_t, ndk::ScopedAStatus> getIdInternal();
+ ndk::ScopedAStatus registerEventCallbackInternal(
+ const std::shared_ptr<IWifiChipEventCallback>& event_callback);
+ std::pair<int32_t, ndk::ScopedAStatus> getFeatureSetInternal();
+ std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus> getAvailableModesInternal();
+ ndk::ScopedAStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock,
+ int32_t mode_id);
+ std::pair<int32_t, ndk::ScopedAStatus> getModeInternal();
+ std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> requestChipDebugInfoInternal();
+ std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestDriverDebugDumpInternal();
+ std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestFirmwareDebugDumpInternal();
+ std::shared_ptr<WifiApIface> newWifiApIface(std::string& ifname);
+ ndk::ScopedAStatus createVirtualApInterface(const std::string& apVirtIf);
+ std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createApIfaceInternal();
+ std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createBridgedApIfaceInternal();
+ std::pair<std::vector<std::string>, ndk::ScopedAStatus> getApIfaceNamesInternal();
+ std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> getApIfaceInternal(
+ const std::string& ifname);
+ ndk::ScopedAStatus removeApIfaceInternal(const std::string& ifname);
+ ndk::ScopedAStatus removeIfaceInstanceFromBridgedApIfaceInternal(
+ const std::string& brIfaceName, const std::string& ifInstanceName);
+ std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> createNanIfaceInternal();
+ std::pair<std::vector<std::string>, ndk::ScopedAStatus> getNanIfaceNamesInternal();
+ std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> getNanIfaceInternal(
+ const std::string& ifname);
+ ndk::ScopedAStatus removeNanIfaceInternal(const std::string& ifname);
+ std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> createP2pIfaceInternal();
+ std::pair<std::vector<std::string>, ndk::ScopedAStatus> getP2pIfaceNamesInternal();
+ std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> getP2pIfaceInternal(
+ const std::string& ifname);
+ ndk::ScopedAStatus removeP2pIfaceInternal(const std::string& ifname);
+ std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> createStaIfaceInternal();
+ std::pair<std::vector<std::string>, ndk::ScopedAStatus> getStaIfaceNamesInternal();
+ std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> getStaIfaceInternal(
+ const std::string& ifname);
+ ndk::ScopedAStatus removeStaIfaceInternal(const std::string& ifname);
+ std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus> createRttControllerInternal(
+ const std::shared_ptr<IWifiStaIface>& bound_iface);
+ std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
+ getDebugRingBuffersStatusInternal();
+ ndk::ScopedAStatus startLoggingToDebugRingBufferInternal(
+ const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+ uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes);
+ ndk::ScopedAStatus forceDumpToDebugRingBufferInternal(const std::string& ring_name);
+ ndk::ScopedAStatus flushRingBufferToFileInternal();
+ ndk::ScopedAStatus stopLoggingToDebugRingBufferInternal();
+ std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
+ getDebugHostWakeReasonStatsInternal();
+ ndk::ScopedAStatus enableDebugErrorAlertsInternal(bool enable);
+ ndk::ScopedAStatus selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario);
+ ndk::ScopedAStatus resetTxPowerScenarioInternal();
+ ndk::ScopedAStatus setLatencyModeInternal(IWifiChip::LatencyMode mode);
+ ndk::ScopedAStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
+ ndk::ScopedAStatus setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case);
+ ndk::ScopedAStatus setCoexUnsafeChannelsInternal(
+ std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels, int32_t restrictions);
+ ndk::ScopedAStatus setCountryCodeInternal(const std::array<uint8_t, 2>& in_code);
+ std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> getUsableChannelsInternal(
+ WifiBand band, int32_t ifaceModeMask, int32_t filterMask);
+ ndk::ScopedAStatus enableStaChannelForPeerNetworkInternal(int32_t channelCategoryEnableFlag);
+ ndk::ScopedAStatus setAfcChannelAllowanceInternal(
+ const AfcChannelAllowance& afcChannelAllowance);
+ ndk::ScopedAStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
+ int32_t mode_id);
+ ndk::ScopedAStatus registerDebugRingBufferCallback();
+ ndk::ScopedAStatus registerRadioModeChangeCallback();
+
+ std::vector<ChipConcurrencyCombination> getCurrentModeConcurrencyCombinations();
+ std::map<IfaceConcurrencyType, size_t> getCurrentConcurrencyCombination();
+ std::vector<std::map<IfaceConcurrencyType, size_t>> expandConcurrencyCombinations(
+ const ChipConcurrencyCombination& combination);
+ bool canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ IfaceConcurrencyType requested_type);
+ bool canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type);
+ bool canExpandedConcurrencyComboSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+ const std::map<IfaceConcurrencyType, size_t>& req_combo);
+ bool canCurrentModeSupportConcurrencyCombo(
+ const std::map<IfaceConcurrencyType, size_t>& req_combo);
+ bool canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type);
+
+ bool isValidModeId(int32_t mode_id);
+ bool isStaApConcurrencyAllowedInCurrentMode();
+ bool isDualStaConcurrencyAllowedInCurrentMode();
+ uint32_t startIdxOfApIface();
+ std::string getFirstActiveWlanIfaceName();
+ std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
+ std::string allocateApIfaceName();
+ std::vector<std::string> allocateBridgedApInstanceNames();
+ std::string allocateStaIfaceName();
+ bool writeRingbufferFilesInternal();
+ std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
+ void invalidateAndClearBridgedApAll();
+ void invalidateAndClearBridgedAp(const std::string& br_name);
+ bool findUsingNameFromBridgedApInstances(const std::string& name);
+ ndk::ScopedAStatus triggerSubsystemRestartInternal();
+ std::pair<std::vector<WifiRadioCombination>, ndk::ScopedAStatus>
+ getSupportedRadioCombinationsInternal();
+ std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
+ ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+ void retrieveDynamicIfaceCombination();
+ void setWeakPtr(std::weak_ptr<WifiChip> ptr);
+
+ int32_t chip_id_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
+ std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ std::vector<std::shared_ptr<WifiApIface>> ap_ifaces_;
+ std::vector<std::shared_ptr<WifiNanIface>> nan_ifaces_;
+ std::vector<std::shared_ptr<WifiP2pIface>> p2p_ifaces_;
+ std::vector<std::shared_ptr<WifiStaIface>> sta_ifaces_;
+ std::vector<std::shared_ptr<WifiRttController>> rtt_controllers_;
+ std::map<std::string, Ringbuffer> ringbuffer_map_;
+ bool is_valid_;
+ // Members pertaining to chip configuration.
+ int32_t current_mode_id_;
+ std::mutex lock_t;
+ std::vector<IWifiChip::ChipMode> modes_;
+ // The legacy ring buffer callback API has only a global callback
+ // registration mechanism. Use this to check if we have already
+ // registered a callback.
+ bool debug_ring_buffer_cb_registered_;
+ bool using_dynamic_iface_combination_;
+ aidl_callback_util::AidlCallbackHandler<IWifiChipEventCallback> event_cb_handler_;
+ std::weak_ptr<WifiChip> weak_ptr_this_;
+
+ const std::function<void(const std::string&)> subsystemCallbackHandler_;
+ std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
+ DISALLOW_COPY_AND_ASSIGN(WifiChip);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_CHIP_H_
diff --git a/wifi/aidl/default/wifi_feature_flags.cpp b/wifi/aidl/default/wifi_feature_flags.cpp
new file mode 100644
index 0000000..3c9f042
--- /dev/null
+++ b/wifi/aidl/default/wifi_feature_flags.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
+#include "wifi_feature_flags.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+/* The chip may either have a single mode supporting any number of combinations,
+ * or a fixed dual-mode (so it involves firmware loading to switch between
+ * modes) setting. If there is a need to support more modes, it needs to be
+ * implemented manually in WiFi HAL (see changeFirmwareMode in
+ * WifiChip::handleChipConfiguration).
+ *
+ * Supported combinations are defined in device's makefile, for example:
+ * WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
+ * WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
+ * What this means:
+ * Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
+ * operations.
+ * Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
+ *
+ * For backward compatibility, the following makefile flags can be used to
+ * generate combinations list:
+ * - WIFI_HIDL_FEATURE_DUAL_INTERFACE
+ * - WIFI_HIDL_FEATURE_DISABLE_AP
+ * - WIFI_HIDL_FEATURE_AWARE
+ * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
+ * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
+ * two concurrency combinations:
+ * Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
+ * concurrent iface operations.
+ * Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
+ * iface operations.
+ *
+ * The only dual-mode configuration supported is for alternating STA and AP
+ * mode, that may involve firmware reloading. In such case, there are 2 separate
+ * modes of operation with 1 concurrency combination each:
+ * Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
+ * concurrent iface operations.
+ * Mode 2 (AP mode): Will support 1 AP iface operation.
+ *
+ * If Aware is enabled, the concurrency combination will be modified to support either
+ * P2P or NAN in place of just P2P.
+ */
+// clang-format off
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS
+constexpr int kMainModeId = chip_mode_ids::kV3;
+#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
+// former V2 (fixed dual interface) setup expressed as V3
+constexpr int kMainModeId = chip_mode_ids::kV3;
+# ifdef WIFI_HIDL_FEATURE_DISABLE_AP
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// 1 STA + 1 of (P2P or NAN)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
+# else
+// 1 STA + 1 P2P
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
+# endif
+# else
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+ {{{STA}, 1}, {{P2P, NAN}, 1}}
+# else
+// (1 STA + 1 AP) or (1 STA + 1 P2P)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
+ {{{STA}, 1}, {{P2P}, 1}}
+# endif
+# endif
+#else
+// V1 (fixed single interface, dual-mode chip)
+constexpr int kMainModeId = chip_mode_ids::kV1Sta;
+# ifdef WIFI_HIDL_FEATURE_AWARE
+// 1 STA + 1 of (P2P or NAN)
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
+# else
+// 1 STA + 1 P2P
+# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
+# endif
+
+# ifndef WIFI_HIDL_FEATURE_DISABLE_AP
+# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
+# endif
+#endif
+// clang-format on
+
+// Convert from the legacy format (used by the WIFI_HAL_INTERFACE_COMBINATIONS
+// config variable) to a list of ChipConcurrencyCombination objects.
+std::vector<IWifiChip::ChipConcurrencyCombination> legacyToChipConcurrencyComboList(
+ std::vector<std::vector<IWifiChip::ChipConcurrencyCombinationLimit>> legacyLimits) {
+ std::vector<IWifiChip::ChipConcurrencyCombination> combos;
+ for (auto& legacyLimit : legacyLimits) {
+ IWifiChip::ChipConcurrencyCombination combo = {legacyLimit};
+ combos.push_back(combo);
+ }
+ return combos;
+}
+
+#define STA IfaceConcurrencyType::STA
+#define AP IfaceConcurrencyType::AP
+#define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
+#define P2P IfaceConcurrencyType::P2P
+#define NAN IfaceConcurrencyType::NAN_IFACE
+static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
+ {kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
+ {chip_mode_ids::kV1Ap,
+ legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
+#endif
+};
+
+static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
+#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
+ {chip_mode_ids::kV3,
+ legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
+#endif
+};
+
+constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
+ "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+// List of pre-defined concurrency combinations that can be enabled at runtime via
+// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
+// corresponding index value.
+static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
+ // Legacy combination - No STA/AP concurrencies.
+ // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
+ {"No STA/AP Concurrency",
+ {{kMainModeId,
+ legacyToChipConcurrencyComboList({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + AP concurrency
+ // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+ {"STA + AP Concurrency",
+ {{kMainModeId, legacyToChipConcurrencyComboList(
+ {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency
+ // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
+ {"Dual STA Concurrency",
+ {{kMainModeId, legacyToChipConcurrencyComboList(
+ {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+ // AP + AP + STA concurrency
+ // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
+ {"Dual AP Concurrency",
+ {{kMainModeId, legacyToChipConcurrencyComboList(
+ {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency and AP + AP + STA concurrency
+ // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
+ {"Dual STA & Dual AP Concurrency",
+ {{kMainModeId, legacyToChipConcurrencyComboList(
+ {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+ // STA + STA concurrency
+ // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
+ {"Dual STA or STA plus single other interface",
+ {{kMainModeId, legacyToChipConcurrencyComboList(
+ {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}}, {{{STA}, 2}}})}}}};
+
+#undef STA
+#undef AP
+#undef AP_BRIDGED
+#undef P2P
+#undef NAN
+
+#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+#pragma message \
+ "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
+ "'config_wifi_ap_randomization_supported' in " \
+ "frameworks/base/core/res/res/values/config.xml in the device overlay " \
+ "instead"
+#endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
+
+WifiFeatureFlags::WifiFeatureFlags() {}
+
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+ auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
+ // Debug property not set, use the device preset concurrency combination.
+ if (res <= 0) return kChipModesPrimary;
+
+ // Debug property set, use one of the debug preset concurrency combination.
+ unsigned long idx = std::stoul(buffer.data());
+ if (idx >= kDebugChipModes.size()) {
+ LOG(ERROR) << "Invalid index set in property: "
+ << kDebugPresetInterfaceCombinationIdxProperty;
+ return kChipModesPrimary;
+ }
+ std::string name;
+ std::vector<IWifiChip::ChipMode> chip_modes;
+ std::tie(name, chip_modes) = kDebugChipModes[idx];
+ LOG(INFO) << "Using debug chip mode: <" << name
+ << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
+ return chip_modes;
+}
+
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
+ return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
+}
+
+} // namespace feature_flags
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_feature_flags.h b/wifi/aidl/default/wifi_feature_flags.h
new file mode 100644
index 0000000..af1b6a6
--- /dev/null
+++ b/wifi/aidl/default/wifi_feature_flags.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_FEATURE_FLAGS_H_
+#define WIFI_FEATURE_FLAGS_H_
+
+#include <aidl/android/hardware/wifi/IWifiChip.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace feature_flags {
+
+namespace chip_mode_ids {
+// These mode ID's should be unique (even across combo versions). Refer to
+// handleChipConfiguration() for its usage.
+constexpr uint32_t kInvalid = UINT32_MAX;
+// Mode ID's for V1
+constexpr uint32_t kV1Sta = 0;
+constexpr uint32_t kV1Ap = 1;
+// Mode ID for V3
+constexpr uint32_t kV3 = 3;
+} // namespace chip_mode_ids
+
+class WifiFeatureFlags {
+ public:
+ WifiFeatureFlags();
+ virtual ~WifiFeatureFlags() = default;
+
+ virtual std::vector<IWifiChip::ChipMode> getChipModes(bool is_primary);
+
+ private:
+ std::vector<IWifiChip::ChipMode> getChipModesForPrimary();
+};
+
+} // namespace feature_flags
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/aidl/default/wifi_iface_util.cpp b/wifi/aidl/default/wifi_iface_util.cpp
new file mode 100644
index 0000000..f788217
--- /dev/null
+++ b/wifi/aidl/default/wifi_iface_util.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <net/if.h>
+#include <private/android_filesystem_config.h>
+
+#include <cstddef>
+#include <iostream>
+#include <limits>
+#include <random>
+
+#include "wifi_iface_util.h"
+
+namespace {
+// Constants to set the local bit & clear the multicast bit.
+constexpr uint8_t kMacAddressMulticastMask = 0x01;
+constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
+
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : iface_tool_(iface_tool),
+ legacy_hal_(legacy_hal),
+ random_mac_address_(nullptr),
+ event_handlers_map_() {}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) {
+ return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
+ const std::array<uint8_t, 6>& mac) {
+#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
+
+ if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
+ !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
+ LOG(ERROR) << "SetUpState(false) failed.";
+ return false;
+ }
+#endif
+ bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
+#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
+ if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
+ !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+ LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
+ // Wait for driver ready and try to set iface UP again
+ if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
+ return false;
+ }
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+ LOG(ERROR) << "SetUpState(true) failed after retry.";
+ return false;
+ }
+ }
+#endif
+ IfaceEventHandlers event_handlers = {};
+ const auto it = event_handlers_map_.find(iface_name);
+ if (it != event_handlers_map_.end()) {
+ event_handlers = it->second;
+ }
+ if (event_handlers.on_state_toggle_off_on != nullptr) {
+ event_handlers.on_state_toggle_off_on(iface_name);
+ }
+ if (!success) {
+ LOG(ERROR) << "SetMacAddress failed on " << iface_name;
+ } else {
+ LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
+ }
+ return success;
+}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
+ if (random_mac_address_) {
+ return *random_mac_address_.get();
+ }
+ random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
+ return *random_mac_address_.get();
+}
+
+void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
+ IfaceEventHandlers handlers) {
+ event_handlers_map_[iface_name] = handlers;
+}
+
+void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) {
+ event_handlers_map_.erase(iface_name);
+}
+
+std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
+ std::array<uint8_t, 6> address = {};
+ std::random_device rd;
+ std::default_random_engine engine(rd());
+ std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(),
+ std::numeric_limits<uint8_t>::max());
+ for (size_t i = 0; i < address.size(); i++) {
+ address[i] = dist(engine);
+ }
+ // Set the local bit and clear the multicast bit.
+ address[0] |= kMacAddressLocallyAssignedMask;
+ address[0] &= ~kMacAddressMulticastMask;
+ return address;
+}
+
+bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
+ LOG(ERROR) << "SetUpState to " << request_up << " failed";
+ return false;
+ }
+ return true;
+}
+
+unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) {
+ return if_nametoindex(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::createBridge(const std::string& br_name) {
+ if (!iface_tool_.lock()->createBridge(br_name)) {
+ return false;
+ }
+
+ if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) {
+ LOG(ERROR) << "bridge SetUpState(true) failed.";
+ }
+ return true;
+}
+
+bool WifiIfaceUtil::deleteBridge(const std::string& br_name) {
+ if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) {
+ LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str();
+ }
+
+ return iface_tool_.lock()->deleteBridge(br_name);
+}
+
+bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) {
+ return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
+}
+
+bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) {
+ return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
+}
+
+} // namespace iface_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_iface_util.h b/wifi/aidl/default/wifi_iface_util.h
new file mode 100644
index 0000000..a3236a5
--- /dev/null
+++ b/wifi/aidl/default/wifi_iface_util.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_IFACE_UTIL_H_
+#define WIFI_IFACE_UTIL_H_
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <wifi_system/interface_tool.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace iface_util {
+
+// Iface event handlers.
+struct IfaceEventHandlers {
+ // Callback to be invoked when the iface is set down & up for MAC address
+ // change.
+ std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
+};
+
+/**
+ * Util class for common iface operations.
+ */
+class WifiIfaceUtil {
+ public:
+ WifiIfaceUtil(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ virtual ~WifiIfaceUtil() = default;
+
+ virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name);
+ virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac);
+ // Get or create a random MAC address. The MAC address returned from
+ // this method will remain the same throughout the lifetime of the HAL
+ // daemon. (So, changes on every reboot)
+ virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
+
+ // Register for any iface event callbacks for the provided interface.
+ virtual void registerIfaceEventHandlers(const std::string& iface_name,
+ IfaceEventHandlers handlers);
+ virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+ virtual bool setUpState(const std::string& iface_name, bool request_up);
+ virtual unsigned ifNameToIndex(const std::string& iface_name);
+
+ virtual bool createBridge(const std::string& br_name);
+
+ virtual bool deleteBridge(const std::string& br_name);
+
+ virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name);
+
+ virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name);
+ // Get a random MAC address.
+ virtual std::array<uint8_t, 6> createRandomMacAddress();
+
+ private:
+ std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
+ std::map<std::string, IfaceEventHandlers> event_handlers_map_;
+};
+
+} // namespace iface_util
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_IFACE_UTIL_H_
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
new file mode 100644
index 0000000..209670b
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -0,0 +1,1943 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal.h"
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <net/if.h>
+
+#include <array>
+#include <chrono>
+
+#include "aidl_sync_util.h"
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+// Constants ported over from the legacy HAL calling code
+// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
+// away when this shim layer is replaced by the real vendor
+// implementation.
+static constexpr uint32_t kMaxVersionStringLength = 256;
+static constexpr uint32_t kMaxCachedGscanResults = 64;
+static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
+static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
+static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
+static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxWifiUsableChannels = 256;
+static constexpr uint32_t kMaxSupportedRadioCombinationsMatrixLength = 256;
+// Need a long timeout (1000ms) for chips that unload their driver.
+static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
+static constexpr char kDriverPropName[] = "wlan.driver.status";
+
+// Helper function to create a non-const char* for legacy Hal API's.
+std::vector<char> makeCharVec(const std::string& str) {
+ std::vector<char> vec(str.size() + 1);
+ vec.assign(str.begin(), str.end());
+ vec.push_back('\0');
+ return vec;
+}
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+// Legacy HAL functions accept "C" style function pointers, so use global
+// functions to pass to the legacy HAL function and store the corresponding
+// std::function methods to be invoked.
+//
+// Callback to be invoked once |stop| is complete
+std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
+void onAsyncStopComplete(wifi_handle handle) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_stop_complete_internal_callback) {
+ on_stop_complete_internal_callback(handle);
+ // Invalidate this callback since we don't want this firing again.
+ on_stop_complete_internal_callback = nullptr;
+ }
+}
+
+// Callback to be invoked for driver dump.
+std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
+void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
+ if (on_driver_memory_dump_internal_callback) {
+ on_driver_memory_dump_internal_callback(buffer, buffer_size);
+ }
+}
+
+// Callback to be invoked for firmware dump.
+std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
+void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
+ if (on_firmware_memory_dump_internal_callback) {
+ on_firmware_memory_dump_internal_callback(buffer, buffer_size);
+ }
+}
+
+// Callback to be invoked for Gscan events.
+std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback;
+void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_gscan_event_internal_callback) {
+ on_gscan_event_internal_callback(id, event);
+ }
+}
+
+// Callback to be invoked for Gscan full results.
+std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
+ on_gscan_full_result_internal_callback;
+void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_gscan_full_result_internal_callback) {
+ on_gscan_full_result_internal_callback(id, result, buckets_scanned);
+ }
+}
+
+// Callback to be invoked for link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
+ on_link_layer_stats_result_internal_callback;
+void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
+ wifi_radio_stat* radio_stat) {
+ if (on_link_layer_stats_result_internal_callback) {
+ on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat);
+ }
+}
+
+// Callback to be invoked for Multi link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_ml_stat*, int, wifi_radio_stat*))>
+ on_link_layer_ml_stats_result_internal_callback;
+void onSyncLinkLayerMlStatsResult(wifi_request_id id, wifi_iface_ml_stat* iface_ml_stat,
+ int num_radios, wifi_radio_stat* radio_stat) {
+ if (on_link_layer_ml_stats_result_internal_callback) {
+ on_link_layer_ml_stats_result_internal_callback(id, iface_ml_stat, num_radios, radio_stat);
+ }
+}
+
+// Callback to be invoked for rssi threshold breach.
+std::function<void((wifi_request_id, uint8_t*, int8_t))>
+ on_rssi_threshold_breached_internal_callback;
+void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_rssi_threshold_breached_internal_callback) {
+ on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
+ }
+}
+
+// Callback to be invoked for ring buffer data indication.
+std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
+ on_ring_buffer_data_internal_callback;
+void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
+ wifi_ring_buffer_status* status) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_ring_buffer_data_internal_callback) {
+ on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status);
+ }
+}
+
+// Callback to be invoked for error alert indication.
+std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback;
+void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_error_alert_internal_callback) {
+ on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
+ }
+}
+
+// Callback to be invoked for radio mode change indication.
+std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
+ on_radio_mode_change_internal_callback;
+void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_radio_mode_change_internal_callback) {
+ on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
+ }
+}
+
+// Callback to be invoked to report subsystem restart
+std::function<void(const char*)> on_subsystem_restart_internal_callback;
+void onAsyncSubsystemRestart(const char* error) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_subsystem_restart_internal_callback) {
+ on_subsystem_restart_internal_callback(error);
+ }
+}
+
+// Callback to be invoked for rtt results results.
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
+ 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;
+
+void invalidateRttResultsCallbacks() {
+ on_rtt_results_internal_callback = nullptr;
+ on_rtt_results_internal_callback_v2 = nullptr;
+};
+
+void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_rtt_results_internal_callback) {
+ on_rtt_results_internal_callback(id, num_results, rtt_results);
+ invalidateRttResultsCallbacks();
+ }
+}
+
+void onAsyncRttResultsV2(wifi_request_id id, unsigned num_results,
+ wifi_rtt_result_v2* rtt_results_v2[]) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_rtt_results_internal_callback_v2) {
+ on_rtt_results_internal_callback_v2(id, num_results, rtt_results_v2);
+ invalidateRttResultsCallbacks();
+ }
+}
+
+// Callbacks for the various NAN operations.
+// NOTE: These have very little conversions to perform before invoking the user
+// callbacks.
+// So, handle all of them here directly to avoid adding an unnecessary layer.
+std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
+void onAsyncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_notify_response_user_callback && msg) {
+ on_nan_notify_response_user_callback(id, *msg);
+ }
+}
+
+std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
+void onAsyncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
+ LOG(ERROR) << "onAsyncNanEventPublishReplied triggered";
+}
+
+std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
+void onAsyncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_publish_terminated_user_callback && event) {
+ on_nan_event_publish_terminated_user_callback(*event);
+ }
+}
+
+std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
+void onAsyncNanEventMatch(NanMatchInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_match_user_callback && event) {
+ on_nan_event_match_user_callback(*event);
+ }
+}
+
+std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
+void onAsyncNanEventMatchExpired(NanMatchExpiredInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_match_expired_user_callback && event) {
+ on_nan_event_match_expired_user_callback(*event);
+ }
+}
+
+std::function<void(const NanSubscribeTerminatedInd&)>
+ on_nan_event_subscribe_terminated_user_callback;
+void onAsyncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_subscribe_terminated_user_callback && event) {
+ on_nan_event_subscribe_terminated_user_callback(*event);
+ }
+}
+
+std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
+void onAsyncNanEventFollowup(NanFollowupInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_followup_user_callback && event) {
+ on_nan_event_followup_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
+void onAsyncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_disc_eng_event_user_callback && event) {
+ on_nan_event_disc_eng_event_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
+void onAsyncNanEventDisabled(NanDisabledInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_disabled_user_callback && event) {
+ on_nan_event_disabled_user_callback(*event);
+ }
+}
+
+std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
+void onAsyncNanEventTca(NanTCAInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_tca_user_callback && event) {
+ on_nan_event_tca_user_callback(*event);
+ }
+}
+
+std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
+void onAsyncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_beacon_sdf_payload_user_callback && event) {
+ on_nan_event_beacon_sdf_payload_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
+void onAsyncNanEventDataPathRequest(NanDataPathRequestInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_data_path_request_user_callback && event) {
+ on_nan_event_data_path_request_user_callback(*event);
+ }
+}
+std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
+void onAsyncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_data_path_confirm_user_callback && event) {
+ on_nan_event_data_path_confirm_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
+void onAsyncNanEventDataPathEnd(NanDataPathEndInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_data_path_end_user_callback && event) {
+ on_nan_event_data_path_end_user_callback(*event);
+ }
+}
+
+std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
+void onAsyncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_transmit_follow_up_user_callback && event) {
+ on_nan_event_transmit_follow_up_user_callback(*event);
+ }
+}
+
+std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
+void onAsyncNanEventRangeRequest(NanRangeRequestInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_range_request_user_callback && event) {
+ on_nan_event_range_request_user_callback(*event);
+ }
+}
+
+std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
+void onAsyncNanEventRangeReport(NanRangeReportInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_range_report_user_callback && event) {
+ on_nan_event_range_report_user_callback(*event);
+ }
+}
+
+std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
+void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_schedule_update_user_callback && event) {
+ on_nan_event_schedule_update_user_callback(*event);
+ }
+}
+
+std::function<void(const NanSuspensionModeChangeInd&)>
+ on_nan_event_suspension_mode_change_user_callback;
+void onAsyncNanEventSuspensionModeChange(NanSuspensionModeChangeInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_suspension_mode_change_user_callback && event) {
+ on_nan_event_suspension_mode_change_user_callback(*event);
+ }
+}
+
+std::function<void(const NanPairingRequestInd&)> on_nan_event_pairing_request_user_callback;
+void onAsyncNanEventPairingRequest(NanPairingRequestInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_pairing_request_user_callback && event) {
+ on_nan_event_pairing_request_user_callback(*event);
+ }
+}
+
+std::function<void(const NanPairingConfirmInd&)> on_nan_event_pairing_confirm_user_callback;
+void onAsyncNanEventPairingConfirm(NanPairingConfirmInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_pairing_confirm_user_callback && event) {
+ on_nan_event_pairing_confirm_user_callback(*event);
+ }
+}
+
+std::function<void(const NanBootstrappingRequestInd&)>
+ on_nan_event_bootstrapping_request_user_callback;
+void onAsyncNanEventBootstrappingRequest(NanBootstrappingRequestInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_bootstrapping_request_user_callback && event) {
+ on_nan_event_bootstrapping_request_user_callback(*event);
+ }
+}
+
+std::function<void(const NanBootstrappingConfirmInd&)>
+ on_nan_event_bootstrapping_confirm_user_callback;
+void onAsyncNanEventBootstrappingConfirm(NanBootstrappingConfirmInd* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_nan_event_bootstrapping_confirm_user_callback && event) {
+ on_nan_event_bootstrapping_confirm_user_callback(*event);
+ }
+}
+
+// Callbacks for the various TWT operations.
+std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
+void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_setup_response_callback && event) {
+ on_twt_event_setup_response_callback(*event);
+ }
+}
+
+std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
+void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_teardown_completion_callback && event) {
+ on_twt_event_teardown_completion_callback(*event);
+ }
+}
+
+std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
+void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_info_frame_received_callback && event) {
+ on_twt_event_info_frame_received_callback(*event);
+ }
+}
+
+std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
+void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_event_device_notify_callback && event) {
+ on_twt_event_device_notify_callback(*event);
+ }
+}
+
+// Callback to report current CHRE NAN state
+std::function<void(chre_nan_rtt_state)> on_chre_nan_rtt_internal_callback;
+void onAsyncChreNanRttState(chre_nan_rtt_state state) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_chre_nan_rtt_internal_callback) {
+ on_chre_nan_rtt_internal_callback(state);
+ }
+}
+
+// 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) {
+ if (on_cached_scan_results_internal_callback) {
+ on_cached_scan_results_internal_callback(cache_report);
+ }
+}
+
+// End of the free-standing "C" style callbacks.
+
+WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const wifi_hal_fn& fn, bool is_primary)
+ : global_func_table_(fn),
+ global_handle_(nullptr),
+ awaiting_event_loop_termination_(false),
+ is_started_(false),
+ iface_tool_(iface_tool),
+ is_primary_(is_primary) {}
+
+wifi_error WifiLegacyHal::initialize() {
+ LOG(DEBUG) << "Initialize legacy HAL";
+ // this now does nothing, since HAL function table is provided
+ // to the constructor
+ return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::start() {
+ // Ensure that we're starting in a good state.
+ CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
+ !awaiting_event_loop_termination_);
+ if (is_started_) {
+ LOG(DEBUG) << "Legacy HAL already started";
+ return WIFI_SUCCESS;
+ }
+ LOG(DEBUG) << "Waiting for the driver ready";
+ wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
+ if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
+ LOG(ERROR) << "Failed or timed out awaiting driver ready";
+ return status;
+ }
+
+ if (is_primary_) {
+ property_set(kDriverPropName, "ok");
+
+ if (!iface_tool_.lock()->SetWifiUpState(true)) {
+ LOG(ERROR) << "Failed to set WiFi interface up";
+ return WIFI_ERROR_UNKNOWN;
+ }
+ }
+
+ LOG(DEBUG) << "Starting legacy HAL";
+ status = global_func_table_.wifi_initialize(&global_handle_);
+ if (status != WIFI_SUCCESS || !global_handle_) {
+ LOG(ERROR) << "Failed to retrieve global handle";
+ return status;
+ }
+ std::thread(&WifiLegacyHal::runEventLoop, this).detach();
+ status = retrieveIfaceHandles();
+ if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
+ LOG(ERROR) << "Failed to retrieve wlan interface handle";
+ return status;
+ }
+ LOG(DEBUG) << "Legacy HAL start complete";
+ is_started_ = true;
+ return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::stop(
+ /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
+ const std::function<void()>& on_stop_complete_user_callback) {
+ if (!is_started_) {
+ LOG(DEBUG) << "Legacy HAL already stopped";
+ on_stop_complete_user_callback();
+ return WIFI_SUCCESS;
+ }
+ LOG(DEBUG) << "Stopping legacy HAL";
+ on_stop_complete_internal_callback = [on_stop_complete_user_callback,
+ this](wifi_handle handle) {
+ CHECK_EQ(global_handle_, handle) << "Handle mismatch";
+ LOG(INFO) << "Legacy HAL stop complete callback received";
+ // Invalidate all the internal pointers now that the HAL is
+ // stopped.
+ invalidate();
+ if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
+ on_stop_complete_user_callback();
+ is_started_ = false;
+ };
+ awaiting_event_loop_termination_ = true;
+ global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
+ const auto status =
+ stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
+ [this] { return !awaiting_event_loop_termination_; });
+ if (!status) {
+ LOG(ERROR) << "Legacy HAL stop failed or timed out";
+ return WIFI_ERROR_UNKNOWN;
+ }
+ LOG(DEBUG) << "Legacy HAL stop complete";
+ return WIFI_SUCCESS;
+}
+
+bool WifiLegacyHal::isStarted() {
+ return is_started_;
+}
+
+wifi_error WifiLegacyHal::waitForDriverReady() {
+ return global_func_table_.wifi_wait_for_driver_ready();
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
+ std::array<char, kMaxVersionStringLength> buffer;
+ buffer.fill(0);
+ wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
+ buffer.data(), buffer.size());
+ return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
+ const std::string& iface_name) {
+ std::array<char, kMaxVersionStringLength> buffer;
+ buffer.fill(0);
+ wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
+ buffer.data(), buffer.size());
+ return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
+ const std::string& iface_name) {
+ std::vector<uint8_t> driver_dump;
+ on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
+ driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+ };
+ wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
+ {onSyncDriverMemoryDump});
+ on_driver_memory_dump_internal_callback = nullptr;
+ return {status, std::move(driver_dump)};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
+ const std::string& iface_name) {
+ std::vector<uint8_t> firmware_dump;
+ on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
+ firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+ };
+ wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
+ getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
+ on_firmware_memory_dump_internal_callback = nullptr;
+ return {status, std::move(firmware_dump)};
+}
+
+std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
+ const std::string& iface_name) {
+ feature_set set = 0, chip_set = 0;
+ wifi_error status = WIFI_SUCCESS;
+
+ static_assert(sizeof(set) == sizeof(uint64_t),
+ "Some feature_flags can not be represented in output");
+ wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+ global_func_table_.wifi_get_chip_feature_set(
+ global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
+
+ if (iface_handle) {
+ status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
+ }
+ return {status, static_cast<uint64_t>(set | chip_set)};
+}
+
+std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
+ const std::string& iface_name) {
+ PacketFilterCapabilities caps;
+ wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+ getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
+ const std::vector<uint8_t>& program) {
+ return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
+ program.size());
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
+ const std::string& iface_name) {
+ PacketFilterCapabilities caps;
+ wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+ getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+ if (status != WIFI_SUCCESS) {
+ return {status, {}};
+ }
+
+ // Size the buffer to read the entire program & work memory.
+ std::vector<uint8_t> buffer(caps.max_len);
+
+ status = global_func_table_.wifi_read_packet_filter(
+ getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
+ return {status, std::move(buffer)};
+}
+
+std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
+ const std::string& iface_name) {
+ wifi_gscan_capabilities caps;
+ wifi_error status =
+ global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::startGscan(
+ const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
+ const std::function<void(wifi_request_id)>& on_failure_user_callback,
+ const on_gscan_results_callback& on_results_user_callback,
+ const on_gscan_full_result_callback& on_full_result_user_callback) {
+ // If there is already an ongoing background scan, reject new scan requests.
+ if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ // This callback will be used to either trigger |on_results_user_callback|
+ // or |on_failure_user_callback|.
+ on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
+ on_results_user_callback,
+ this](wifi_request_id id, wifi_scan_event event) {
+ switch (event) {
+ case WIFI_SCAN_RESULTS_AVAILABLE:
+ case WIFI_SCAN_THRESHOLD_NUM_SCANS:
+ case WIFI_SCAN_THRESHOLD_PERCENT: {
+ wifi_error status;
+ std::vector<wifi_cached_scan_results> cached_scan_results;
+ std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
+ if (status == WIFI_SUCCESS) {
+ on_results_user_callback(id, cached_scan_results);
+ return;
+ }
+ FALLTHROUGH_INTENDED;
+ }
+ // Fall through if failed. Failure to retrieve cached scan
+ // results should trigger a background scan failure.
+ case WIFI_SCAN_FAILED:
+ on_failure_user_callback(id);
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ return;
+ }
+ LOG(FATAL) << "Unexpected gscan event received: " << event;
+ };
+
+ on_gscan_full_result_internal_callback = [on_full_result_user_callback](
+ wifi_request_id id, wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ if (result) {
+ on_full_result_user_callback(id, result, buckets_scanned);
+ }
+ };
+
+ wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
+ wifi_error status =
+ global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
+ if (status != WIFI_SUCCESS) {
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
+ // If there is no an ongoing background scan, reject stop requests.
+ // TODO(b/32337212): This needs to be handled by the HIDL object because we
+ // need to return the NOT_STARTED error code.
+ if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
+ // If the request Id is wrong, don't stop the ongoing background scan. Any
+ // other error should be treated as the end of background scan.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ }
+ return status;
+}
+
+std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
+ const std::string& iface_name, wifi_band band) {
+ static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
+ "Wifi Channel cannot be represented in output");
+ std::vector<uint32_t> freqs;
+ freqs.resize(kMaxGscanFrequenciesForBand);
+ int32_t num_freqs = 0;
+ wifi_error status = global_func_table_.wifi_get_valid_channels(
+ getIfaceHandle(iface_name), band, freqs.size(),
+ reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
+ CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
+ freqs.resize(num_freqs);
+ return {status, std::move(freqs)};
+}
+
+wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
+ return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
+}
+
+wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
+ wifi_link_layer_params params;
+ params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
+ params.aggressive_statistics_gathering = debug;
+ return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
+}
+
+wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
+ // TODO: Do we care about these responses?
+ uint32_t clear_mask_rsp;
+ uint8_t stop_rsp;
+ return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
+ &clear_mask_rsp, 1, &stop_rsp);
+}
+
+// Copies wifi_peer_info* to vector<WifiPeerInfo> and returns poiner to next element.
+wifi_peer_info* WifiLegacyHal::copyPeerInfo(wifi_peer_info* peer_ptr,
+ std::vector<WifiPeerInfo>& peers) {
+ WifiPeerInfo peer;
+ peer.peer_info = *peer_ptr;
+ if (peer_ptr->num_rate > 0) {
+ // Copy the rate stats.
+ peer.rate_stats.assign(peer_ptr->rate_stats, peer_ptr->rate_stats + peer_ptr->num_rate);
+ }
+ peer.peer_info.num_rate = 0;
+ // Push peer info.
+ peers.push_back(peer);
+ // Return the address of next peer info.
+ return (wifi_peer_info*)((u8*)peer_ptr + sizeof(wifi_peer_info) +
+ (sizeof(wifi_rate_stat) * peer_ptr->num_rate));
+}
+// Copies wifi_link_stat* to vector<LinkStats> and returns poiner to next element.
+wifi_link_stat* WifiLegacyHal::copyLinkStat(wifi_link_stat* stat_ptr,
+ std::vector<LinkStats>& stats) {
+ LinkStats linkStat;
+ linkStat.stat = *stat_ptr;
+ wifi_peer_info* l_peer_info_stats_ptr = stat_ptr->peer_info;
+ for (uint32_t i = 0; i < linkStat.stat.num_peers; i++) {
+ l_peer_info_stats_ptr = copyPeerInfo(l_peer_info_stats_ptr, linkStat.peers);
+ }
+ // Copied all peers to linkStat.peers.
+ linkStat.stat.num_peers = 0;
+ // Push link stat.
+ stats.push_back(linkStat);
+ // Read all peers, return the address of next wifi_link_stat.
+ return (wifi_link_stat*)l_peer_info_stats_ptr;
+}
+
+wifi_error WifiLegacyHal::getLinkLayerStats(const std::string& iface_name,
+ LinkLayerStats& link_stats,
+ LinkLayerMlStats& link_ml_stats) {
+ LinkLayerStats* link_stats_ptr = &link_stats;
+ link_stats_ptr->valid = false;
+
+ on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
+ wifi_request_id /* id */,
+ wifi_iface_stat* iface_stats_ptr,
+ int num_radios,
+ wifi_radio_stat* radio_stats_ptr) {
+ wifi_radio_stat* l_radio_stats_ptr;
+ wifi_peer_info* l_peer_info_stats_ptr;
+ link_stats_ptr->valid = true;
+
+ if (iface_stats_ptr != nullptr) {
+ link_stats_ptr->iface = *iface_stats_ptr;
+ l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
+ for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
+ WifiPeerInfo peer;
+ peer.peer_info = *l_peer_info_stats_ptr;
+ if (l_peer_info_stats_ptr->num_rate > 0) {
+ /* Copy the rate stats */
+ peer.rate_stats.assign(
+ l_peer_info_stats_ptr->rate_stats,
+ l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
+ }
+ peer.peer_info.num_rate = 0;
+ link_stats_ptr->peers.push_back(peer);
+ l_peer_info_stats_ptr =
+ (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
+ (sizeof(wifi_rate_stat) *
+ l_peer_info_stats_ptr->num_rate));
+ }
+ link_stats_ptr->iface.num_peers = 0;
+ } else {
+ LOG(ERROR) << "Invalid iface stats in link layer stats";
+ }
+ if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+ LOG(ERROR) << "Invalid radio stats in link layer stats";
+ return;
+ }
+ l_radio_stats_ptr = radio_stats_ptr;
+ for (int i = 0; i < num_radios; i++) {
+ LinkLayerRadioStats radio;
+
+ radio.stats = *l_radio_stats_ptr;
+ // Copy over the tx level array to the separate vector.
+ if (l_radio_stats_ptr->num_tx_levels > 0 &&
+ l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+ radio.tx_time_per_levels.assign(
+ l_radio_stats_ptr->tx_time_per_levels,
+ l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
+ }
+ radio.stats.num_tx_levels = 0;
+ radio.stats.tx_time_per_levels = nullptr;
+ /* Copy over the channel stat to separate vector */
+ if (l_radio_stats_ptr->num_channels > 0) {
+ /* Copy the channel stats */
+ radio.channel_stats.assign(
+ l_radio_stats_ptr->channels,
+ l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+ }
+ link_stats_ptr->radios.push_back(radio);
+ l_radio_stats_ptr =
+ (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+ (sizeof(wifi_channel_stat) *
+ l_radio_stats_ptr->num_channels));
+ }
+ };
+
+ LinkLayerMlStats* link_ml_stats_ptr = &link_ml_stats;
+ link_ml_stats_ptr->valid = false;
+
+ on_link_layer_ml_stats_result_internal_callback =
+ [this, &link_ml_stats_ptr](wifi_request_id /* id */,
+ wifi_iface_ml_stat* iface_ml_stats_ptr, int num_radios,
+ wifi_radio_stat* radio_stats_ptr) {
+ wifi_radio_stat* l_radio_stats_ptr;
+ wifi_link_stat* l_link_stat_ptr;
+ link_ml_stats_ptr->valid = true;
+
+ if (iface_ml_stats_ptr != nullptr && iface_ml_stats_ptr->num_links > 0) {
+ // Copy stats from wifi_iface_ml_stat to LinkLayerMlStats,
+ // - num_links * links[] to vector of links.
+ // - num_peers * peer_info[] to vector of links[i].peers.
+ link_ml_stats_ptr->iface = *iface_ml_stats_ptr;
+ l_link_stat_ptr = iface_ml_stats_ptr->links;
+ for (int l = 0; l < iface_ml_stats_ptr->num_links; ++l) {
+ l_link_stat_ptr = copyLinkStat(l_link_stat_ptr, link_ml_stats_ptr->links);
+ }
+ } else {
+ LOG(ERROR) << "Invalid iface stats in link layer stats";
+ }
+ if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+ LOG(ERROR) << "Invalid radio stats in link layer stats";
+ return;
+ }
+ l_radio_stats_ptr = radio_stats_ptr;
+ for (int i = 0; i < num_radios; i++) {
+ LinkLayerRadioStats radio;
+
+ radio.stats = *l_radio_stats_ptr;
+ // Copy over the tx level array to the separate vector.
+ if (l_radio_stats_ptr->num_tx_levels > 0 &&
+ l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+ radio.tx_time_per_levels.assign(l_radio_stats_ptr->tx_time_per_levels,
+ l_radio_stats_ptr->tx_time_per_levels +
+ l_radio_stats_ptr->num_tx_levels);
+ }
+ radio.stats.num_tx_levels = 0;
+ radio.stats.tx_time_per_levels = nullptr;
+ /* Copy over the channel stat to separate vector */
+ if (l_radio_stats_ptr->num_channels > 0) {
+ /* Copy the channel stats */
+ radio.channel_stats.assign(
+ l_radio_stats_ptr->channels,
+ l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+ }
+ link_ml_stats_ptr->radios.push_back(radio);
+ l_radio_stats_ptr =
+ (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+ (sizeof(wifi_channel_stat) *
+ l_radio_stats_ptr->num_channels));
+ }
+ };
+
+ wifi_error status = global_func_table_.wifi_get_link_stats(
+ 0, getIfaceHandle(iface_name),
+ {onSyncLinkLayerStatsResult, onSyncLinkLayerMlStatsResult});
+ on_link_layer_stats_result_internal_callback = nullptr;
+ on_link_layer_ml_stats_result_internal_callback = nullptr;
+
+ return status;
+}
+
+wifi_error WifiLegacyHal::startRssiMonitoring(
+ const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+ const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
+ if (on_rssi_threshold_breached_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
+ wifi_request_id id, uint8_t* bssid_ptr,
+ int8_t rssi) {
+ if (!bssid_ptr) {
+ return;
+ }
+ std::array<uint8_t, ETH_ALEN> bssid_arr;
+ // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
+ // address.
+ std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
+ on_threshold_breached_user_callback(id, bssid_arr, rssi);
+ };
+ wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
+ id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
+ if (status != WIFI_SUCCESS) {
+ on_rssi_threshold_breached_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
+ if (!on_rssi_threshold_breached_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ wifi_error status =
+ global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
+ // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
+ // other error should be treated as the end of background scan.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ on_rssi_threshold_breached_internal_callback = nullptr;
+ }
+ return status;
+}
+
+std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
+ const std::string& iface_name) {
+ wifi_roaming_capabilities caps;
+ wifi_error status =
+ global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
+ return {status, caps};
+}
+
+wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
+ const wifi_roaming_config& config) {
+ wifi_roaming_config config_internal = config;
+ return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
+}
+
+wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
+ fw_roaming_state_t state) {
+ return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
+}
+
+wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
+ return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
+}
+
+wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
+ uint16_t ether_type,
+ const std::vector<uint8_t>& ip_packet_data,
+ const std::array<uint8_t, 6>& src_address,
+ const std::array<uint8_t, 6>& dst_address,
+ int32_t period_in_ms) {
+ std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
+ std::vector<uint8_t> src_address_internal(src_address.data(),
+ src_address.data() + src_address.size());
+ std::vector<uint8_t> dst_address_internal(dst_address.data(),
+ dst_address.data() + dst_address.size());
+ return global_func_table_.wifi_start_sending_offloaded_packet(
+ cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
+ ip_packet_data_internal.size(), src_address_internal.data(),
+ dst_address_internal.data(), period_in_ms);
+}
+
+wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
+ uint32_t cmd_id) {
+ return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
+ getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
+ wifi_power_scenario scenario) {
+ return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
+}
+
+wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
+ return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
+ return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
+ uint32_t completion_window) {
+ return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
+ completion_window);
+}
+
+wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+ uint32_t access_category) {
+ return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
+ access_category);
+}
+
+wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
+ return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
+}
+
+std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
+ const std::string& iface_name) {
+ uint32_t supported_feature_flags = 0;
+ wifi_error status = WIFI_SUCCESS;
+
+ wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+ if (iface_handle) {
+ status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
+ &supported_feature_flags);
+ }
+ return {status, supported_feature_flags};
+}
+
+wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
+ return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
+ const std::string& iface_name) {
+ std::vector<wifi_tx_report> tx_pkt_fates;
+ tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+ size_t num_fates = 0;
+ wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
+ getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
+ CHECK(num_fates <= MAX_FATE_LOG_LEN);
+ tx_pkt_fates.resize(num_fates);
+ return {status, std::move(tx_pkt_fates)};
+}
+
+std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
+ const std::string& iface_name) {
+ std::vector<wifi_rx_report> rx_pkt_fates;
+ rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+ size_t num_fates = 0;
+ wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
+ getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
+ CHECK(num_fates <= MAX_FATE_LOG_LEN);
+ rx_pkt_fates.resize(num_fates);
+ return {status, std::move(rx_pkt_fates)};
+}
+
+std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
+ const std::string& iface_name) {
+ WakeReasonStats stats;
+ stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+ stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+
+ // This legacy struct needs separate memory to store the variable sized wake
+ // reason types.
+ stats.wake_reason_cnt.cmd_event_wake_cnt =
+ reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
+ stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
+ stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt =
+ reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
+
+ wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
+ &stats.wake_reason_cnt);
+
+ CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
+ static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
+ kMaxWakeReasonStatsArraySize);
+ stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
+ stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
+
+ CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
+ static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
+ kMaxWakeReasonStatsArraySize);
+ stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
+ stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
+
+ return {status, stats};
+}
+
+wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
+ const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
+ if (on_ring_buffer_data_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_ring_buffer_data_internal_callback = [on_user_data_callback](
+ char* ring_name, char* buffer, int buffer_size,
+ wifi_ring_buffer_status* status) {
+ if (status && buffer) {
+ std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+ on_user_data_callback(ring_name, buffer_vector, *status);
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
+ {onAsyncRingBufferData});
+ if (status != WIFI_SUCCESS) {
+ on_ring_buffer_data_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
+ if (!on_ring_buffer_data_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_ring_buffer_data_internal_callback = nullptr;
+ return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
+ const std::string& iface_name) {
+ std::vector<wifi_ring_buffer_status> ring_buffers_status;
+ ring_buffers_status.resize(kMaxRingBuffers);
+ uint32_t num_rings = kMaxRingBuffers;
+ wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
+ getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
+ CHECK(num_rings <= kMaxRingBuffers);
+ ring_buffers_status.resize(num_rings);
+ return {status, std::move(ring_buffers_status)};
+}
+
+wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
+ const std::string& ring_name,
+ uint32_t verbose_level, uint32_t max_interval_sec,
+ uint32_t min_data_size) {
+ return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
+ max_interval_sec, min_data_size,
+ makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
+ const std::string& ring_name) {
+ return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
+ makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
+ const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
+ if (on_error_alert_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
+ int buffer_size, int err_code) {
+ if (buffer) {
+ CHECK(id == 0);
+ on_user_alert_callback(
+ err_code,
+ std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
+ reinterpret_cast<uint8_t*>(buffer) + buffer_size));
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
+ {onAsyncErrorAlert});
+ if (status != WIFI_SUCCESS) {
+ on_error_alert_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
+ if (!on_error_alert_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_error_alert_internal_callback = nullptr;
+ return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
+ const std::string& iface_name,
+ const on_radio_mode_change_callback& on_user_change_callback) {
+ if (on_radio_mode_change_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_radio_mode_change_internal_callback = [on_user_change_callback](
+ wifi_request_id /* id */, uint32_t num_macs,
+ wifi_mac_info* mac_infos_arr) {
+ if (num_macs > 0 && mac_infos_arr) {
+ std::vector<WifiMacInfo> mac_infos_vec;
+ for (uint32_t i = 0; i < num_macs; i++) {
+ WifiMacInfo mac_info;
+ mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
+ mac_info.mac_band = mac_infos_arr[i].mac_band;
+ for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
+ WifiIfaceInfo iface_info;
+ iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
+ iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
+ mac_info.iface_infos.push_back(iface_info);
+ }
+ mac_infos_vec.push_back(mac_info);
+ }
+ on_user_change_callback(mac_infos_vec);
+ }
+ };
+ wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
+ 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
+ if (status != WIFI_SUCCESS) {
+ on_radio_mode_change_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
+ const on_subsystem_restart_callback& on_restart_callback) {
+ if (on_subsystem_restart_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
+ on_restart_callback(error);
+ };
+ wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
+ global_handle_, {onAsyncSubsystemRestart});
+ if (status != WIFI_SUCCESS) {
+ on_subsystem_restart_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::startRttRangeRequest(
+ const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config>& rtt_configs,
+ const on_rtt_results_callback& on_results_user_callback,
+ const on_rtt_results_callback_v2& on_results_user_callback_v2) {
+ if (on_rtt_results_internal_callback || on_rtt_results_internal_callback_v2) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
+ unsigned num_results,
+ wifi_rtt_result* rtt_results[]) {
+ if (num_results > 0 && !rtt_results) {
+ LOG(ERROR) << "Unexpected nullptr in RTT results";
+ return;
+ }
+ std::vector<const wifi_rtt_result*> rtt_results_vec;
+ std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
+ [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
+ on_results_user_callback(id, rtt_results_vec);
+ };
+
+ on_rtt_results_internal_callback_v2 = [on_results_user_callback_v2](
+ wifi_request_id id, unsigned num_results,
+ wifi_rtt_result_v2* rtt_results_v2[]) {
+ if (num_results > 0 && !rtt_results_v2) {
+ LOG(ERROR) << "Unexpected nullptr in RTT results";
+ return;
+ }
+ std::vector<const wifi_rtt_result_v2*> rtt_results_vec_v2;
+ std::copy_if(rtt_results_v2, rtt_results_v2 + num_results,
+ back_inserter(rtt_results_vec_v2),
+ [](wifi_rtt_result_v2* rtt_result_v2) { return rtt_result_v2 != nullptr; });
+ on_results_user_callback_v2(id, rtt_results_vec_v2);
+ };
+
+ std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
+ wifi_error status = global_func_table_.wifi_rtt_range_request(
+ id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
+ {onAsyncRttResults, onAsyncRttResultsV2});
+ if (status != WIFI_SUCCESS) {
+ invalidateRttResultsCallbacks();
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::cancelRttRangeRequest(
+ const std::string& iface_name, wifi_request_id id,
+ const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs) {
+ if (!on_rtt_results_internal_callback && !on_rtt_results_internal_callback_v2) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+ static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, ETH_ALEN>),
+ "MAC address size mismatch");
+ // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
+ // addressed are cancelled).
+ std::vector<std::array<uint8_t, ETH_ALEN>> mac_addrs_internal(mac_addrs);
+ wifi_error status = global_func_table_.wifi_rtt_range_cancel(
+ id, getIfaceHandle(iface_name), mac_addrs.size(),
+ reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
+ // If the request Id is wrong, don't stop the ongoing range request. Any
+ // other error should be treated as the end of rtt ranging.
+ if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+ invalidateRttResultsCallbacks();
+ }
+ return status;
+}
+
+std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
+ const std::string& iface_name) {
+ wifi_rtt_capabilities rtt_caps;
+ wifi_error status =
+ global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
+ return {status, rtt_caps};
+}
+
+std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
+ const std::string& iface_name) {
+ wifi_rtt_responder rtt_responder;
+ wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
+ &rtt_responder);
+ return {status, rtt_responder};
+}
+
+wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
+ const wifi_channel_info& channel_hint,
+ uint32_t max_duration_secs,
+ const wifi_rtt_responder& info) {
+ wifi_rtt_responder info_internal(info);
+ return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
+ max_duration_secs, &info_internal);
+}
+
+wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
+ return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
+ const wifi_lci_information& info) {
+ wifi_lci_information info_internal(info);
+ return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
+ const wifi_lcr_information& info) {
+ wifi_lcr_information info_internal(info);
+ return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
+ const NanCallbackHandlers& user_callbacks) {
+ on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
+ on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
+ on_nan_event_match_user_callback = user_callbacks.on_event_match;
+ on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
+ on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
+ on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
+ on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
+ on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
+ on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
+ on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
+ on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
+ on_nan_event_pairing_request_user_callback = user_callbacks.on_event_pairing_request;
+ on_nan_event_pairing_confirm_user_callback = user_callbacks.on_event_pairing_confirm;
+ on_nan_event_bootstrapping_request_user_callback =
+ user_callbacks.on_event_bootstrapping_request;
+ on_nan_event_bootstrapping_confirm_user_callback =
+ user_callbacks.on_event_bootstrapping_confirm;
+ on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
+ on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
+ on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
+ on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
+ on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
+ on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
+ on_nan_event_suspension_mode_change_user_callback =
+ user_callbacks.on_event_suspension_mode_change;
+
+ return global_func_table_.wifi_nan_register_handler(getIfaceHandle(iface_name),
+ {onAsyncNanNotifyResponse,
+ onAsyncNanEventPublishReplied,
+ onAsyncNanEventPublishTerminated,
+ onAsyncNanEventMatch,
+ onAsyncNanEventMatchExpired,
+ onAsyncNanEventSubscribeTerminated,
+ onAsyncNanEventFollowup,
+ onAsyncNanEventDiscEngEvent,
+ onAsyncNanEventDisabled,
+ onAsyncNanEventTca,
+ onAsyncNanEventBeaconSdfPayload,
+ onAsyncNanEventDataPathRequest,
+ onAsyncNanEventDataPathConfirm,
+ onAsyncNanEventDataPathEnd,
+ onAsyncNanEventTransmitFollowUp,
+ onAsyncNanEventRangeRequest,
+ onAsyncNanEventRangeReport,
+ onAsyncNanEventScheduleUpdate,
+ onAsyncNanEventPairingRequest,
+ onAsyncNanEventPairingConfirm,
+ onAsyncNanEventBootstrappingRequest,
+ onAsyncNanEventBootstrappingConfirm,
+ onAsyncNanEventSuspensionModeChange});
+}
+
+wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
+ const NanEnableRequest& msg) {
+ NanEnableRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
+ return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishRequest& msg) {
+ NanPublishRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishCancelRequest& msg) {
+ NanPublishCancelRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+ const NanSubscribeRequest& msg) {
+ NanSubscribeRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
+ transaction_id id,
+ const NanSubscribeCancelRequest& msg) {
+ NanSubscribeCancelRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
+ transaction_id id,
+ const NanTransmitFollowupRequest& msg) {
+ NanTransmitFollowupRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
+ const NanStatsRequest& msg) {
+ NanStatsRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
+ const NanConfigRequest& msg) {
+ NanConfigRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
+ const NanTCARequest& msg) {
+ NanTCARequest msg_internal(msg);
+ return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
+ transaction_id id,
+ const NanBeaconSdfPayloadRequest& msg) {
+ NanBeaconSdfPayloadRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
+ NanVersion version;
+ wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
+ return {status, version};
+}
+
+wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
+ return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name) {
+ return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
+ makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name) {
+ return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
+ makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+ const NanDataPathInitiatorRequest& msg) {
+ NanDataPathInitiatorRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
+ transaction_id id,
+ const NanDataPathIndicationResponse& msg) {
+ NanDataPathIndicationResponse msg_internal(msg);
+ return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPairingRequest(const std::string& iface_name, transaction_id id,
+ const NanPairingRequest& msg) {
+ NanPairingRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_pairing_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPairingIndicationResponse(const std::string& iface_name,
+ transaction_id id,
+ const NanPairingIndicationResponse& msg) {
+ NanPairingIndicationResponse msg_internal(msg);
+ return global_func_table_.wifi_nan_pairing_indication_response(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBootstrappingRequest(const std::string& iface_name, transaction_id id,
+ const NanBootstrappingRequest& msg) {
+ NanBootstrappingRequest msg_internal(msg);
+ return global_func_table_.wifi_nan_bootstrapping_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBootstrappingIndicationResponse(
+ const std::string& iface_name, transaction_id id,
+ const NanBootstrappingIndicationResponse& msg) {
+ NanBootstrappingIndicationResponse msg_internal(msg);
+ return global_func_table_.wifi_nan_bootstrapping_indication_response(
+ id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+typedef struct {
+ u8 num_ndp_instances;
+ NanDataPathId ndp_instance_id;
+} NanDataPathEndSingleNdpIdRequest;
+
+wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
+ uint32_t ndpInstanceId) {
+ NanDataPathEndSingleNdpIdRequest msg;
+ msg.num_ndp_instances = 1;
+ msg.ndp_instance_id = ndpInstanceId;
+ wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
+ (NanDataPathEndRequest*)&msg);
+ return status;
+}
+
+wifi_error WifiLegacyHal::nanPairingEnd(const std::string& iface_name, transaction_id id,
+ uint32_t pairingId) {
+ NanPairingEndRequest msg;
+ msg.pairing_instance_id = pairingId;
+ wifi_error status =
+ global_func_table_.wifi_nan_pairing_end(id, getIfaceHandle(iface_name), &msg);
+ return status;
+}
+
+wifi_error WifiLegacyHal::nanSuspendRequest(const std::string& iface_name, transaction_id id,
+ const NanSuspendRequest& msg) {
+ NanSuspendRequest msg_internal(msg);
+ wifi_error status = global_func_table_.wifi_nan_suspend_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+ return status;
+}
+
+wifi_error WifiLegacyHal::nanResumeRequest(const std::string& iface_name, transaction_id id,
+ const NanResumeRequest& msg) {
+ NanResumeRequest msg_internal(msg);
+ wifi_error status = global_func_table_.wifi_nan_resume_request(id, getIfaceHandle(iface_name),
+ &msg_internal);
+ return status;
+}
+
+wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
+ const std::array<uint8_t, 2> code) {
+ std::string code_str(code.data(), code.data() + code.size());
+ return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
+}
+
+wifi_error WifiLegacyHal::retrieveIfaceHandles() {
+ wifi_interface_handle* iface_handles = nullptr;
+ int num_iface_handles = 0;
+ wifi_error status =
+ global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
+ if (status != WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to enumerate interface handles";
+ return status;
+ }
+ iface_name_to_handle_.clear();
+ for (int i = 0; i < num_iface_handles; ++i) {
+ std::array<char, IFNAMSIZ> iface_name_arr = {};
+ status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
+ iface_name_arr.size());
+ if (status != WIFI_SUCCESS) {
+ LOG(WARNING) << "Failed to get interface handle name";
+ continue;
+ }
+ // Assuming the interface name is null terminated since the legacy HAL
+ // API does not return a size.
+ std::string iface_name(iface_name_arr.data());
+ LOG(INFO) << "Adding interface handle for " << iface_name;
+ iface_name_to_handle_[iface_name] = iface_handles[i];
+ }
+ return WIFI_SUCCESS;
+}
+
+wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
+ const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
+ if (iface_handle_iter == iface_name_to_handle_.end()) {
+ LOG(ERROR) << "Unknown iface name: " << iface_name;
+ return nullptr;
+ }
+ return iface_handle_iter->second;
+}
+
+void WifiLegacyHal::runEventLoop() {
+ LOG(DEBUG) << "Starting legacy HAL event loop";
+ global_func_table_.wifi_event_loop(global_handle_);
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (!awaiting_event_loop_termination_) {
+ LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
+ }
+ LOG(DEBUG) << "Legacy HAL event loop terminated";
+ awaiting_event_loop_termination_ = false;
+ stop_wait_cv_.notify_one();
+}
+
+std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
+ const std::string& iface_name) {
+ std::vector<wifi_cached_scan_results> cached_scan_results;
+ cached_scan_results.resize(kMaxCachedGscanResults);
+ int32_t num_results = 0;
+ wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
+ getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
+ cached_scan_results.data(), &num_results);
+ CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
+ cached_scan_results.resize(num_results);
+ // Check for invalid IE lengths in these cached scan results and correct it.
+ for (auto& cached_scan_result : cached_scan_results) {
+ int num_scan_results = cached_scan_result.num_results;
+ for (int i = 0; i < num_scan_results; i++) {
+ auto& scan_result = cached_scan_result.results[i];
+ if (scan_result.ie_length > 0) {
+ LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
+ scan_result.ie_length = 0;
+ }
+ }
+ }
+ return {status, std::move(cached_scan_results)};
+}
+
+wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
+ wifi_interface_type iftype) {
+ // Create the interface if it doesn't exist. If interface already exist,
+ // Vendor Hal should return WIFI_SUCCESS.
+ wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
+ ifname.c_str(), iftype);
+ return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
+ // Delete the interface if it was created dynamically.
+ wifi_error status =
+ global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
+ return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+ wifi_error status) {
+ if (status == WIFI_SUCCESS) {
+ // refresh list of handlers now.
+ status = retrieveIfaceHandles();
+ } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
+ // Vendor hal does not implement this API. Such vendor implementations
+ // are expected to create / delete interface by other means.
+
+ // check if interface exists.
+ if (if_nametoindex(ifname.c_str())) {
+ status = retrieveIfaceHandles();
+ }
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
+ std::array<char, IFNAMSIZ> buffer;
+
+ wifi_error res = global_func_table_.wifi_get_supported_iface_name(
+ global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
+ if (res == WIFI_SUCCESS) ifname = buffer.data();
+
+ return res;
+}
+
+wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
+ return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
+ getIfaceHandle(ifname));
+}
+
+wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
+ return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
+}
+
+wifi_error WifiLegacyHal::setCoexUnsafeChannels(
+ std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
+ return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
+ unsafe_channels.data(), restrictions);
+}
+
+wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
+ return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
+ const TwtCallbackHandlers& user_callbacks) {
+ on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
+ on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
+ on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
+ on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
+
+ return global_func_table_.wifi_twt_register_handler(
+ getIfaceHandle(iface_name),
+ {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
+ onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
+}
+
+std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
+ const std::string& iface_name) {
+ TwtCapabilitySet capSet;
+ wifi_error status =
+ global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
+ return {status, capSet};
+}
+
+wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
+ const TwtSetupRequest& msg) {
+ TwtSetupRequest msgInternal(msg);
+ return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
+ const TwtTeardownRequest& msg) {
+ TwtTeardownRequest msgInternal(msg);
+ return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
+ const TwtInfoFrameRequest& msg) {
+ TwtInfoFrameRequest msgInternal(msg);
+ return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
+ uint8_t configId) {
+ TwtStats stats;
+ wifi_error status =
+ global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
+ return {status, stats};
+}
+
+wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
+ return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
+}
+
+wifi_error WifiLegacyHal::setScanMode(const std::string& iface_name, bool enable) {
+ return global_func_table_.wifi_set_scan_mode(iface_name.c_str(), enable);
+}
+
+wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
+ return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
+}
+
+std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
+ uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
+ std::vector<wifi_usable_channel> channels;
+ channels.resize(kMaxWifiUsableChannels);
+ uint32_t size = 0;
+ wifi_error status = global_func_table_.wifi_get_usable_channels(
+ global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
+ reinterpret_cast<wifi_usable_channel*>(channels.data()));
+ CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
+ channels.resize(size);
+ return {status, std::move(channels)};
+}
+
+wifi_error WifiLegacyHal::triggerSubsystemRestart() {
+ return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
+}
+
+wifi_error WifiLegacyHal::setIndoorState(bool isIndoor) {
+ return global_func_table_.wifi_set_indoor_state(global_handle_, isIndoor);
+}
+
+std::pair<wifi_error, wifi_radio_combination_matrix*>
+WifiLegacyHal::getSupportedRadioCombinationsMatrix() {
+ char* buffer = new char[kMaxSupportedRadioCombinationsMatrixLength];
+ std::fill(buffer, buffer + kMaxSupportedRadioCombinationsMatrixLength, 0);
+ uint32_t size = 0;
+ wifi_radio_combination_matrix* radio_combination_matrix_ptr =
+ reinterpret_cast<wifi_radio_combination_matrix*>(buffer);
+ wifi_error status = global_func_table_.wifi_get_supported_radio_combinations_matrix(
+ global_handle_, kMaxSupportedRadioCombinationsMatrixLength, &size,
+ radio_combination_matrix_ptr);
+ CHECK(size >= 0 && size <= kMaxSupportedRadioCombinationsMatrixLength);
+ return {status, radio_combination_matrix_ptr};
+}
+
+wifi_error WifiLegacyHal::chreNanRttRequest(const std::string& iface_name, bool enable) {
+ if (enable)
+ return global_func_table_.wifi_nan_rtt_chre_enable_request(0, getIfaceHandle(iface_name),
+ NULL);
+ else
+ return global_func_table_.wifi_nan_rtt_chre_disable_request(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::chreRegisterHandler(const std::string& iface_name,
+ const ChreCallbackHandlers& handler) {
+ if (on_chre_nan_rtt_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_chre_nan_rtt_internal_callback = handler.on_wifi_chre_nan_rtt_state;
+
+ wifi_error status = global_func_table_.wifi_chre_register_handler(getIfaceHandle(iface_name),
+ {onAsyncChreNanRttState});
+ if (status != WIFI_SUCCESS) {
+ on_chre_nan_rtt_internal_callback = nullptr;
+ }
+ return status;
+}
+
+wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name, bool enable) {
+ 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 status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
+ {onSyncCachedScanResults});
+
+ on_cached_scan_results_internal_callback = nullptr;
+ return status;
+}
+
+std::pair<wifi_error, wifi_chip_capabilities> WifiLegacyHal::getWifiChipCapabilities() {
+ wifi_chip_capabilities chip_capabilities;
+ wifi_error status =
+ global_func_table_.wifi_get_chip_capabilities(global_handle_, &chip_capabilities);
+ return {status, chip_capabilities};
+}
+
+wifi_error WifiLegacyHal::enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag) {
+ return global_func_table_.wifi_enable_sta_channel_for_peer_network(global_handle_,
+ channelCategoryEnableFlag);
+}
+
+wifi_error WifiLegacyHal::setMloMode(wifi_mlo_mode mode) {
+ return global_func_table_.wifi_set_mlo_mode(global_handle_, mode);
+}
+
+std::pair<wifi_error, wifi_iface_concurrency_matrix>
+WifiLegacyHal::getSupportedIfaceConcurrencyMatrix() {
+ wifi_iface_concurrency_matrix iface_concurrency_matrix;
+ wifi_error status = global_func_table_.wifi_get_supported_iface_concurrency_matrix(
+ global_handle_, &iface_concurrency_matrix);
+ return {status, iface_concurrency_matrix};
+}
+
+void WifiLegacyHal::invalidate() {
+ global_handle_ = nullptr;
+ iface_name_to_handle_.clear();
+ on_driver_memory_dump_internal_callback = nullptr;
+ on_firmware_memory_dump_internal_callback = nullptr;
+ on_gscan_event_internal_callback = nullptr;
+ on_gscan_full_result_internal_callback = nullptr;
+ on_link_layer_stats_result_internal_callback = nullptr;
+ on_link_layer_ml_stats_result_internal_callback = nullptr;
+ on_rssi_threshold_breached_internal_callback = nullptr;
+ on_ring_buffer_data_internal_callback = nullptr;
+ on_error_alert_internal_callback = nullptr;
+ on_radio_mode_change_internal_callback = nullptr;
+ on_subsystem_restart_internal_callback = nullptr;
+ invalidateRttResultsCallbacks();
+ on_nan_notify_response_user_callback = nullptr;
+ on_nan_event_publish_terminated_user_callback = nullptr;
+ on_nan_event_match_user_callback = nullptr;
+ on_nan_event_match_expired_user_callback = nullptr;
+ on_nan_event_subscribe_terminated_user_callback = nullptr;
+ on_nan_event_followup_user_callback = nullptr;
+ on_nan_event_disc_eng_event_user_callback = nullptr;
+ on_nan_event_disabled_user_callback = nullptr;
+ on_nan_event_tca_user_callback = nullptr;
+ on_nan_event_beacon_sdf_payload_user_callback = nullptr;
+ on_nan_event_data_path_request_user_callback = nullptr;
+ on_nan_event_pairing_request_user_callback = nullptr;
+ on_nan_event_pairing_confirm_user_callback = nullptr;
+ on_nan_event_bootstrapping_request_user_callback = nullptr;
+ on_nan_event_bootstrapping_confirm_user_callback = nullptr;
+ on_nan_event_data_path_confirm_user_callback = nullptr;
+ on_nan_event_data_path_end_user_callback = nullptr;
+ on_nan_event_transmit_follow_up_user_callback = nullptr;
+ on_nan_event_range_request_user_callback = nullptr;
+ on_nan_event_range_report_user_callback = nullptr;
+ on_nan_event_schedule_update_user_callback = nullptr;
+ on_twt_event_setup_response_callback = nullptr;
+ on_twt_event_teardown_completion_callback = nullptr;
+ on_twt_event_info_frame_received_callback = nullptr;
+ on_twt_event_device_notify_callback = nullptr;
+ on_chre_nan_rtt_internal_callback = nullptr;
+}
+
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
new file mode 100644
index 0000000..5168a8b
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -0,0 +1,828 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_LEGACY_HAL_H_
+#define WIFI_LEGACY_HAL_H_
+
+#include <hardware_legacy/wifi_hal.h>
+#include <wifi_system/interface_tool.h>
+
+#include <condition_variable>
+#include <functional>
+#include <map>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+// This is in a separate namespace to prevent typename conflicts between
+// the legacy HAL types and the AIDL interface types.
+namespace legacy_hal {
+// Import all the types defined inside the legacy HAL header files into this
+// namespace.
+using ::chre_nan_rtt_state;
+using ::frame_info;
+using ::frame_type;
+using ::FRAME_TYPE_80211_MGMT;
+using ::FRAME_TYPE_ETHERNET_II;
+using ::FRAME_TYPE_UNKNOWN;
+using ::fw_roaming_state_t;
+using ::mac_addr;
+using ::NAN_BOOTSTRAPPING_INITIATOR_RESPONSE;
+using ::NAN_BOOTSTRAPPING_RESPONDER_RESPONSE;
+using ::NAN_CHANNEL_24G_BAND;
+using ::NAN_CHANNEL_5G_BAND_HIGH;
+using ::NAN_CHANNEL_5G_BAND_LOW;
+using ::NAN_DISABLE_RANGE_REPORT;
+using ::NAN_DO_NOT_USE_SRF;
+using ::NAN_DP_CHANNEL_NOT_REQUESTED;
+using ::NAN_DP_CONFIG_NO_SECURITY;
+using ::NAN_DP_CONFIG_SECURITY;
+using ::NAN_DP_END;
+using ::NAN_DP_FORCE_CHANNEL_SETUP;
+using ::NAN_DP_INITIATOR_RESPONSE;
+using ::NAN_DP_INTERFACE_CREATE;
+using ::NAN_DP_INTERFACE_DELETE;
+using ::NAN_DP_REQUEST_ACCEPT;
+using ::NAN_DP_REQUEST_CHANNEL_SETUP;
+using ::NAN_DP_REQUEST_REJECT;
+using ::NAN_DP_RESPONDER_RESPONSE;
+using ::NAN_GET_CAPABILITIES;
+using ::NAN_MATCH_ALG_MATCH_CONTINUOUS;
+using ::NAN_MATCH_ALG_MATCH_NEVER;
+using ::NAN_MATCH_ALG_MATCH_ONCE;
+using ::NAN_PAIRING_END;
+using ::NAN_PAIRING_INITIATOR_RESPONSE;
+using ::NAN_PAIRING_RESPONDER_RESPONSE;
+using ::NAN_PAIRING_SETUP;
+using ::NAN_PAIRING_VERIFICATION;
+using ::NAN_PUBLISH_TYPE_SOLICITED;
+using ::NAN_PUBLISH_TYPE_UNSOLICITED;
+using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED;
+using ::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+using ::NAN_RANGING_AUTO_RESPONSE_ENABLE;
+using ::NAN_RANGING_DISABLE;
+using ::NAN_RANGING_ENABLE;
+using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD;
+using ::NAN_RESPONSE_CONFIG;
+using ::NAN_RESPONSE_DISABLED;
+using ::NAN_RESPONSE_ENABLED;
+using ::NAN_RESPONSE_ERROR;
+using ::NAN_RESPONSE_PUBLISH;
+using ::NAN_RESPONSE_PUBLISH_CANCEL;
+using ::NAN_RESPONSE_STATS;
+using ::NAN_RESPONSE_SUBSCRIBE;
+using ::NAN_RESPONSE_SUBSCRIBE_CANCEL;
+using ::NAN_RESPONSE_TCA;
+using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
+using ::NAN_RESUME_REQUEST_RESPONSE;
+using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+using ::NAN_SECURITY_KEY_INPUT_PMK;
+using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
+using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
+using ::NAN_SRF_ATTR_BLOOM_FILTER;
+using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR;
+using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+using ::NAN_SRF_INCLUDE_RESPOND;
+using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+using ::NAN_SSI_REQUIRED_IN_MATCH_IND;
+using ::NAN_STATUS_ALREADY_ENABLED;
+using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL;
+using ::NAN_STATUS_INTERNAL_FAILURE;
+using ::NAN_STATUS_INVALID_BOOTSTRAPPING_ID;
+using ::NAN_STATUS_INVALID_NDP_ID;
+using ::NAN_STATUS_INVALID_PAIRING_ID;
+using ::NAN_STATUS_INVALID_PARAM;
+using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID;
+using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID;
+using ::NAN_STATUS_NAN_NOT_ALLOWED;
+using ::NAN_STATUS_NO_CONNECTION;
+using ::NAN_STATUS_NO_OTA_ACK;
+using ::NAN_STATUS_NO_RESOURCE_AVAILABLE;
+using ::NAN_STATUS_NOT_SUPPORTED;
+using ::NAN_STATUS_PROTOCOL_FAILURE;
+using ::NAN_STATUS_REDUNDANT_REQUEST;
+using ::NAN_STATUS_SUCCESS;
+using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED;
+using ::NAN_SUBSCRIBE_TYPE_ACTIVE;
+using ::NAN_SUBSCRIBE_TYPE_PASSIVE;
+using ::NAN_SUSPEND_REQUEST_RESPONSE;
+using ::NAN_TRANSMIT_IN_DW;
+using ::NAN_TRANSMIT_IN_FAW;
+using ::NAN_TX_PRIORITY_HIGH;
+using ::NAN_TX_PRIORITY_NORMAL;
+using ::NAN_TX_TYPE_BROADCAST;
+using ::NAN_TX_TYPE_UNICAST;
+using ::NAN_USE_SRF;
+using ::NanAkm;
+using ::NanBeaconSdfPayloadInd;
+using ::NanBootstrappingConfirmInd;
+using ::NanBootstrappingIndicationResponse;
+using ::NanBootstrappingRequest;
+using ::NanBootstrappingRequestInd;
+using ::NanBootstrappingRequestResponse;
+using ::NanBootstrappingResponseCode;
+using ::NanCapabilities;
+using ::NanChannelInfo;
+using ::NanConfigRequest;
+using ::NanDataPathChannelCfg;
+using ::NanDataPathConfirmInd;
+using ::NanDataPathEndInd;
+using ::NanDataPathIndicationResponse;
+using ::NanDataPathInitiatorRequest;
+using ::NanDataPathRequestInd;
+using ::NanDataPathScheduleUpdateInd;
+using ::NanDisabledInd;
+using ::NanDiscEngEventInd;
+using ::NanEnableRequest;
+using ::NanFollowupInd;
+using ::NanIdentityResolutionAttribute;
+using ::NanMatchAlg;
+using ::NanMatchExpiredInd;
+using ::NanMatchInd;
+using ::NanPairingConfig;
+using ::NanPairingConfirmInd;
+using ::NanPairingEndRequest;
+using ::NanPairingIndicationResponse;
+using ::NanPairingRequest;
+using ::NanPairingRequestInd;
+using ::NanPairingRequestResponse;
+using ::NanPairingRequestType;
+using ::NanPairingResponseCode;
+using ::NanPublishCancelRequest;
+using ::NanPublishRequest;
+using ::NanPublishTerminatedInd;
+using ::NanPublishType;
+using ::NanRangeReportInd;
+using ::NanRangeRequestInd;
+using ::NanResponseMsg;
+using ::NanResumeRequest;
+using ::NanSRFType;
+using ::NanStatusType;
+using ::NanSubscribeCancelRequest;
+using ::NanSubscribeRequest;
+using ::NanSubscribeTerminatedInd;
+using ::NanSubscribeType;
+using ::NanSuspendRequest;
+using ::NanSuspensionModeChangeInd;
+using ::NanTransmitFollowupInd;
+using ::NanTransmitFollowupRequest;
+using ::NanTxType;
+using ::NpkSecurityAssociation;
+using ::PASN;
+using ::ROAMING_DISABLE;
+using ::ROAMING_ENABLE;
+using ::RTT_PEER_AP;
+using ::RTT_PEER_NAN;
+using ::RTT_PEER_P2P_CLIENT;
+using ::RTT_PEER_P2P_GO;
+using ::RTT_PEER_STA;
+using ::rtt_peer_type;
+using ::RTT_STATUS_ABORTED;
+using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
+using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
+using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
+using ::RTT_STATUS_FAIL_INVALID_TS;
+using ::RTT_STATUS_FAIL_NO_CAPABILITY;
+using ::RTT_STATUS_FAIL_NO_RSP;
+using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
+using ::RTT_STATUS_FAIL_PROTOCOL;
+using ::RTT_STATUS_FAIL_REJECTED;
+using ::RTT_STATUS_FAIL_SCHEDULE;
+using ::RTT_STATUS_FAIL_TM_TIMEOUT;
+using ::RTT_STATUS_FAILURE;
+using ::RTT_STATUS_INVALID_REQ;
+using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
+using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
+using ::RTT_STATUS_NO_WIFI;
+using ::RTT_STATUS_SUCCESS;
+using ::RTT_TYPE_1_SIDED;
+using ::RTT_TYPE_2_SIDED;
+using ::RX_PKT_FATE_DRV_DROP_FILTER;
+using ::RX_PKT_FATE_DRV_DROP_INVALID;
+using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
+using ::RX_PKT_FATE_DRV_DROP_OTHER;
+using ::RX_PKT_FATE_DRV_QUEUED;
+using ::RX_PKT_FATE_FW_DROP_FILTER;
+using ::RX_PKT_FATE_FW_DROP_INVALID;
+using ::RX_PKT_FATE_FW_DROP_NOBUFS;
+using ::RX_PKT_FATE_FW_DROP_OTHER;
+using ::RX_PKT_FATE_FW_QUEUED;
+using ::RX_PKT_FATE_SUCCESS;
+using ::SAE;
+using ::ssid_t;
+using ::transaction_id;
+using ::TX_PKT_FATE_ACKED;
+using ::TX_PKT_FATE_DRV_DROP_INVALID;
+using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
+using ::TX_PKT_FATE_DRV_DROP_OTHER;
+using ::TX_PKT_FATE_DRV_QUEUED;
+using ::TX_PKT_FATE_FW_DROP_INVALID;
+using ::TX_PKT_FATE_FW_DROP_NOBUFS;
+using ::TX_PKT_FATE_FW_DROP_OTHER;
+using ::TX_PKT_FATE_FW_QUEUED;
+using ::TX_PKT_FATE_SENT;
+using ::WIFI_AC_BE;
+using ::WIFI_AC_BK;
+using ::WIFI_AC_VI;
+using ::WIFI_AC_VO;
+using ::WIFI_ANTENNA_1X1;
+using ::WIFI_ANTENNA_2X2;
+using ::WIFI_ANTENNA_3X3;
+using ::WIFI_ANTENNA_4X4;
+using ::WIFI_ANTENNA_UNSPECIFIED;
+using ::wifi_band;
+using ::WIFI_BAND_A;
+using ::WIFI_BAND_A_DFS;
+using ::WIFI_BAND_A_WITH_DFS;
+using ::WIFI_BAND_ABG;
+using ::WIFI_BAND_ABG_WITH_DFS;
+using ::WIFI_BAND_BG;
+using ::WIFI_BAND_UNSPECIFIED;
+using ::wifi_cached_scan_report;
+using ::wifi_cached_scan_results;
+using ::WIFI_CHAN_WIDTH_10;
+using ::WIFI_CHAN_WIDTH_160;
+using ::WIFI_CHAN_WIDTH_20;
+using ::WIFI_CHAN_WIDTH_320;
+using ::WIFI_CHAN_WIDTH_40;
+using ::WIFI_CHAN_WIDTH_5;
+using ::WIFI_CHAN_WIDTH_80;
+using ::WIFI_CHAN_WIDTH_80P80;
+using ::WIFI_CHAN_WIDTH_INVALID;
+using ::wifi_channel_category;
+using ::wifi_channel_info;
+using ::wifi_channel_stat;
+using ::wifi_channel_width;
+using ::wifi_chip_capabilities;
+using ::wifi_coex_restriction;
+using ::wifi_coex_unsafe_channel;
+using ::WIFI_DFS_CHANNEL;
+using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
+using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+using ::wifi_error;
+using ::WIFI_ERROR_BUSY;
+using ::WIFI_ERROR_INVALID_ARGS;
+using ::WIFI_ERROR_INVALID_REQUEST_ID;
+using ::WIFI_ERROR_NONE;
+using ::WIFI_ERROR_NOT_AVAILABLE;
+using ::WIFI_ERROR_NOT_SUPPORTED;
+using ::WIFI_ERROR_OUT_OF_MEMORY;
+using ::WIFI_ERROR_TIMED_OUT;
+using ::WIFI_ERROR_TOO_MANY_REQUESTS;
+using ::WIFI_ERROR_UNINITIALIZED;
+using ::WIFI_ERROR_UNKNOWN;
+using ::wifi_gscan_capabilities;
+using ::wifi_hal_fn;
+using ::wifi_iface_concurrency_matrix;
+using ::WIFI_INDOOR_CHANNEL;
+using ::wifi_information_element;
+using ::WIFI_INTERFACE_IBSS;
+using ::WIFI_INTERFACE_MESH;
+using ::wifi_interface_mode;
+using ::WIFI_INTERFACE_NAN;
+using ::WIFI_INTERFACE_P2P_CLIENT;
+using ::WIFI_INTERFACE_P2P_GO;
+using ::WIFI_INTERFACE_SOFTAP;
+using ::WIFI_INTERFACE_STA;
+using ::WIFI_INTERFACE_TDLS;
+using ::wifi_interface_type;
+using ::WIFI_INTERFACE_TYPE_AP;
+using ::WIFI_INTERFACE_TYPE_NAN;
+using ::WIFI_INTERFACE_TYPE_P2P;
+using ::WIFI_INTERFACE_TYPE_STA;
+using ::WIFI_INTERFACE_UNKNOWN;
+using ::wifi_latency_mode;
+using ::WIFI_LATENCY_MODE_LOW;
+using ::WIFI_LATENCY_MODE_NORMAL;
+using ::wifi_lci_information;
+using ::wifi_lcr_information;
+using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
+using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
+using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
+using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED;
+using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED;
+using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
+using ::wifi_mlo_mode;
+using ::WIFI_MOTION_EXPECTED;
+using ::WIFI_MOTION_NOT_EXPECTED;
+using ::wifi_motion_pattern;
+using ::WIFI_MOTION_UNKNOWN;
+using ::wifi_multi_sta_use_case;
+using ::wifi_power_scenario;
+using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
+using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
+using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
+using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
+using ::WIFI_POWER_SCENARIO_VOICE_CALL;
+using ::wifi_radio_combination;
+using ::wifi_radio_combination_matrix;
+using ::wifi_radio_configuration;
+using ::wifi_rate;
+using ::wifi_request_id;
+using ::wifi_ring_buffer_status;
+using ::wifi_roaming_capabilities;
+using ::wifi_roaming_config;
+using ::wifi_rtt_bw;
+using ::WIFI_RTT_BW_10;
+using ::WIFI_RTT_BW_160;
+using ::WIFI_RTT_BW_20;
+using ::WIFI_RTT_BW_320;
+using ::WIFI_RTT_BW_40;
+using ::WIFI_RTT_BW_5;
+using ::WIFI_RTT_BW_80;
+using ::WIFI_RTT_BW_UNSPECIFIED;
+using ::wifi_rtt_capabilities;
+using ::wifi_rtt_config;
+using ::wifi_rtt_preamble;
+using ::WIFI_RTT_PREAMBLE_EHT;
+using ::WIFI_RTT_PREAMBLE_HE;
+using ::WIFI_RTT_PREAMBLE_HT;
+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_status;
+using ::wifi_rtt_type;
+using ::wifi_rx_packet_fate;
+using ::wifi_rx_report;
+using ::wifi_scan_bucket_spec;
+using ::wifi_scan_cmd_params;
+using ::WIFI_SCAN_FLAG_INTERRUPTED;
+using ::wifi_scan_result;
+using ::WIFI_SUCCESS;
+using ::wifi_tx_packet_fate;
+using ::wifi_tx_report;
+using ::wifi_usable_channel;
+using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+using ::WLAN_MAC_2_4_BAND;
+using ::WLAN_MAC_5_0_BAND;
+using ::WLAN_MAC_60_0_BAND;
+using ::WLAN_MAC_6_0_BAND;
+
+// APF capabilities supported by the iface.
+struct PacketFilterCapabilities {
+ uint32_t version;
+ uint32_t max_len;
+};
+
+// WARNING: We don't care about the variable sized members of either
+// |wifi_iface_stat|, |wifi_radio_stat| structures. So, using the pragma
+// to escape the compiler warnings regarding this.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wgnu-variable-sized-type-not-at-end"
+// The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in
+// |wifi_radio_stat| structure in the legacy HAL API. Separate that out
+// into a separate return element to avoid passing pointers around.
+struct LinkLayerRadioStats {
+ wifi_radio_stat stats;
+ std::vector<uint32_t> tx_time_per_levels;
+ std::vector<wifi_channel_stat> channel_stats;
+};
+
+struct WifiPeerInfo {
+ wifi_peer_info peer_info;
+ std::vector<wifi_rate_stat> rate_stats;
+};
+
+struct LinkLayerStats {
+ wifi_iface_stat iface;
+ std::vector<LinkLayerRadioStats> radios;
+ std::vector<WifiPeerInfo> peers;
+ bool valid;
+};
+
+struct LinkStats {
+ wifi_link_stat stat;
+ std::vector<WifiPeerInfo> peers;
+};
+
+struct LinkLayerMlStats {
+ wifi_iface_ml_stat iface;
+ std::vector<LinkStats> links;
+ std::vector<LinkLayerRadioStats> radios;
+ bool valid;
+};
+
+#pragma GCC diagnostic pop
+
+// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
+// |WLAN_DRIVER_WAKE_REASON_CNT.driver_fw_local_wake_cnt| stats is provided
+// as a pointer in |WLAN_DRIVER_WAKE_REASON_CNT| structure in the legacy HAL
+// API. Separate that out into a separate return elements to avoid passing
+// pointers around.
+struct WakeReasonStats {
+ WLAN_DRIVER_WAKE_REASON_CNT wake_reason_cnt;
+ std::vector<uint32_t> cmd_event_wake_cnt;
+ std::vector<uint32_t> driver_fw_local_wake_cnt;
+};
+
+// NAN response and event callbacks struct.
+struct NanCallbackHandlers {
+ // NotifyResponse invoked to notify the status of the Request.
+ std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response;
+ // Various event callbacks.
+ std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated;
+ std::function<void(const NanMatchInd&)> on_event_match;
+ std::function<void(const NanMatchExpiredInd&)> on_event_match_expired;
+ std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated;
+ std::function<void(const NanFollowupInd&)> on_event_followup;
+ std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event;
+ std::function<void(const NanDisabledInd&)> on_event_disabled;
+ std::function<void(const NanTCAInd&)> on_event_tca;
+ std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload;
+ std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request;
+ std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm;
+ std::function<void(const NanDataPathEndInd&)> on_event_data_path_end;
+ std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up;
+ std::function<void(const NanRangeRequestInd&)> on_event_range_request;
+ std::function<void(const NanRangeReportInd&)> on_event_range_report;
+ std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update;
+ std::function<void(const NanPairingRequestInd&)> on_event_pairing_request;
+ std::function<void(const NanPairingConfirmInd&)> on_event_pairing_confirm;
+ std::function<void(const NanBootstrappingRequestInd&)> on_event_bootstrapping_request;
+ std::function<void(const NanBootstrappingConfirmInd&)> on_event_bootstrapping_confirm;
+ std::function<void(const NanSuspensionModeChangeInd&)> on_event_suspension_mode_change;
+};
+
+// Full scan results contain IE info and are hence passed by reference, to
+// preserve the variable length array member |ie_data|. Callee must not retain
+// the pointer.
+using on_gscan_full_result_callback =
+ std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
+// These scan results don't contain any IE info, so no need to pass by
+// reference.
+using on_gscan_results_callback =
+ std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
+
+// Invoked when the rssi value breaches the thresholds set.
+using on_rssi_threshold_breached_callback =
+ std::function<void(wifi_request_id, std::array<uint8_t, ETH_ALEN>, int8_t)>;
+
+// Callback for RTT range request results.
+// Rtt results contain IE info and are hence passed by reference, to
+// preserve the |LCI| and |LCR| pointers. Callee must not retain
+// the pointer.
+using on_rtt_results_callback =
+ 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*>&)>;
+
+// Callback for ring buffer data.
+using on_ring_buffer_data_callback = std::function<void(
+ const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>;
+
+// Callback for alerts.
+using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>;
+
+// Callback for subsystem restart
+using on_subsystem_restart_callback = std::function<void(const std::string&)>;
+
+// Struct for the mac info from the legacy HAL. This is a cleaner version
+// of the |wifi_mac_info| & |wifi_iface_info|.
+typedef struct {
+ std::string name;
+ wifi_channel channel;
+} WifiIfaceInfo;
+
+typedef struct {
+ uint32_t wlan_mac_id;
+ /* BIT MASK of BIT(WLAN_MAC*) as represented by wlan_mac_band */
+ uint32_t mac_band;
+ /* Represents the connected Wi-Fi interfaces associated with each MAC */
+ std::vector<WifiIfaceInfo> iface_infos;
+} WifiMacInfo;
+
+// Callback for radio mode change
+using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>;
+
+// TWT response and event callbacks struct.
+struct TwtCallbackHandlers {
+ // Callback for TWT setup response
+ std::function<void(const TwtSetupResponse&)> on_setup_response;
+ // Callback for TWT teardown completion
+ std::function<void(const TwtTeardownCompletion&)> on_teardown_completion;
+ // Callback for TWT info frame received event
+ std::function<void(const TwtInfoFrameReceived&)> on_info_frame_received;
+ // Callback for TWT notification from the device
+ std::function<void(const TwtDeviceNotify&)> on_device_notify;
+};
+
+// CHRE response and event callbacks struct.
+struct ChreCallbackHandlers {
+ // Callback for CHRE NAN RTT
+ std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
+};
+
+// Cached Scan Results response and event callbacks struct.
+struct CachedScanResultsCallbackHandlers {
+ // Callback for Cached Scan Results
+ std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
+};
+
+/**
+ * Class that encapsulates all legacy HAL interactions.
+ * This class manages the lifetime of the event loop thread used by legacy HAL.
+ *
+ * Note: There will only be a single instance of this class created in the Wifi
+ * object and will be valid for the lifetime of the process.
+ */
+class WifiLegacyHal {
+ public:
+ WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
+ const wifi_hal_fn& fn, bool is_primary);
+ virtual ~WifiLegacyHal() = default;
+
+ // Initialize the legacy HAL function table.
+ virtual wifi_error initialize();
+ // Start the legacy HAL and the event looper thread.
+ virtual wifi_error start();
+ // Deinitialize the legacy HAL and wait for the event loop thread to exit
+ // using a predefined timeout.
+ virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
+ const std::function<void()>& on_complete_callback);
+ virtual wifi_error waitForDriverReady();
+ // Checks if legacy HAL has successfully started
+ bool isStarted();
+ // Wrappers for all the functions in the legacy HAL function table.
+ virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name);
+ virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name);
+ std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump(
+ const std::string& iface_name);
+ std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump(
+ const std::string& iface_name);
+ virtual std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name);
+ // APF functions.
+ std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities(
+ const std::string& iface_name);
+ wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program);
+ std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData(
+ const std::string& iface_name);
+ // Gscan functions.
+ std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities(
+ const std::string& iface_name);
+ // These API's provides a simplified interface over the legacy Gscan API's:
+ // a) All scan events from the legacy HAL API other than the
+ // |WIFI_SCAN_FAILED| are treated as notification of results.
+ // This method then retrieves the cached scan results from the legacy
+ // HAL API and triggers the externally provided
+ // |on_results_user_callback| on success.
+ // b) |WIFI_SCAN_FAILED| scan event or failure to retrieve cached scan
+ // results
+ // Triggers the externally provided |on_failure_user_callback|.
+ // c) Full scan result event triggers the externally provided
+ // |on_full_result_user_callback|.
+ wifi_error startGscan(const std::string& iface_name, wifi_request_id id,
+ const wifi_scan_cmd_params& params,
+ const std::function<void(wifi_request_id)>& on_failure_callback,
+ const on_gscan_results_callback& on_results_callback,
+ const on_gscan_full_result_callback& on_full_result_callback);
+ wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
+ std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
+ const std::string& iface_name, wifi_band band);
+ virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
+ // Link layer stats functions.
+ wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
+ wifi_error disableLinkLayerStats(const std::string& iface_name);
+ wifi_error getLinkLayerStats(const std::string& iface_name,
+ legacy_hal::LinkLayerStats& legacy_stats,
+ legacy_hal::LinkLayerMlStats& legacy_ml_stats);
+ // RSSI monitor functions.
+ wifi_error startRssiMonitoring(
+ const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+ const on_rssi_threshold_breached_callback& on_threshold_breached_callback);
+ wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id);
+ std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities(
+ const std::string& iface_name);
+ wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config);
+ wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state);
+ wifi_error configureNdOffload(const std::string& iface_name, bool enable);
+ wifi_error startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
+ uint16_t ether_type,
+ const std::vector<uint8_t>& ip_packet_data,
+ const std::array<uint8_t, 6>& src_address,
+ const std::array<uint8_t, 6>& dst_address,
+ int32_t period_in_ms);
+ wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id);
+ virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
+ wifi_power_scenario scenario);
+ virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
+ wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode);
+ wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window);
+ wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+ uint32_t access_category);
+ wifi_error resetDscpToAccessCategoryMapping();
+ // Logger/debug functions.
+ std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name);
+ wifi_error startPktFateMonitoring(const std::string& iface_name);
+ std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name);
+ std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name);
+ std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name);
+ wifi_error registerRingBufferCallbackHandler(
+ const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback);
+ wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name);
+ virtual wifi_error registerSubsystemRestartCallbackHandler(
+ const on_subsystem_restart_callback& on_restart_callback);
+ std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus(
+ const std::string& iface_name);
+ wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name,
+ uint32_t verbose_level, uint32_t max_interval_sec,
+ uint32_t min_data_size);
+ wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name);
+ wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name,
+ const on_error_alert_callback& on_alert_callback);
+ wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name);
+ // Radio mode functions.
+ virtual wifi_error registerRadioModeChangeCallbackHandler(
+ const std::string& iface_name,
+ const on_radio_mode_change_callback& on_user_change_callback);
+ // RTT functions.
+ wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+ 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 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_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,
+ const wifi_rtt_responder& info);
+ wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id);
+ wifi_error setRttLci(const std::string& iface_name, wifi_request_id id,
+ const wifi_lci_information& info);
+ wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
+ const wifi_lcr_information& info);
+ // NAN functions.
+ virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name,
+ const NanCallbackHandlers& callbacks);
+ wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id,
+ const NanEnableRequest& msg);
+ virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id);
+ wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishRequest& msg);
+ wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+ const NanPublishCancelRequest& msg);
+ wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+ const NanSubscribeRequest& msg);
+ wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id,
+ const NanSubscribeCancelRequest& msg);
+ wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id,
+ const NanTransmitFollowupRequest& msg);
+ wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id,
+ const NanStatsRequest& msg);
+ wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id,
+ const NanConfigRequest& msg);
+ wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id,
+ const NanTCARequest& msg);
+ wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id,
+ const NanBeaconSdfPayloadRequest& msg);
+ std::pair<wifi_error, NanVersion> nanGetVersion();
+ wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id);
+ wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name);
+ virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+ const std::string& data_iface_name);
+ wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+ const NanDataPathInitiatorRequest& msg);
+ wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id,
+ const NanDataPathIndicationResponse& msg);
+ wifi_error nanPairingRequest(const std::string& iface_name, transaction_id id,
+ const NanPairingRequest& msg);
+ wifi_error nanPairingIndicationResponse(const std::string& iface_name, transaction_id id,
+ const NanPairingIndicationResponse& msg);
+ wifi_error nanBootstrappingRequest(const std::string& iface_name, transaction_id id,
+ const NanBootstrappingRequest& msg);
+ wifi_error nanBootstrappingIndicationResponse(const std::string& iface_name, transaction_id id,
+ const NanBootstrappingIndicationResponse& msg);
+ wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId);
+ wifi_error nanPairingEnd(const std::string& iface_name, transaction_id id, uint32_t pairingId);
+ wifi_error nanSuspendRequest(const std::string& iface_name, transaction_id id,
+ const NanSuspendRequest& msg);
+ wifi_error nanResumeRequest(const std::string& iface_name, transaction_id id,
+ const NanResumeRequest& msg);
+ // AP functions.
+ wifi_error setCountryCode(const std::string& iface_name, const std::array<uint8_t, 2> code);
+
+ // Interface functions.
+ virtual wifi_error createVirtualInterface(const std::string& ifname,
+ wifi_interface_type iftype);
+ virtual wifi_error deleteVirtualInterface(const std::string& ifname);
+ virtual wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname);
+
+ // STA + STA functions
+ virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
+ virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
+
+ // Coex functions.
+ virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels,
+ uint32_t restrictions);
+
+ wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
+
+ wifi_error twtRegisterHandler(const std::string& iface_name,
+ const TwtCallbackHandlers& handler);
+
+ std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
+
+ wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
+
+ wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
+
+ wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
+
+ std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
+
+ wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
+
+ wifi_error setScanMode(const std::string& iface_name, bool enable);
+
+ wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier);
+
+ // Retrieve the list of usable channels in the requested bands
+ // for the requested modes
+ std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
+ uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
+
+ wifi_error triggerSubsystemRestart();
+
+ wifi_error setIndoorState(bool isIndoor);
+
+ std::pair<wifi_error, wifi_radio_combination_matrix*> getSupportedRadioCombinationsMatrix();
+
+ // CHRE NAN RTT function
+ wifi_error chreNanRttRequest(const std::string& iface_name, bool enable);
+
+ wifi_error chreRegisterHandler(const std::string& iface_name,
+ const ChreCallbackHandlers& handler);
+
+ wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
+ wifi_error getWifiCachedScanResults(const std::string& iface_name,
+ const CachedScanResultsCallbackHandlers& handler);
+ std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
+ wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
+ wifi_error setMloMode(wifi_mlo_mode mode);
+ std::pair<wifi_error, wifi_iface_concurrency_matrix> getSupportedIfaceConcurrencyMatrix();
+
+ private:
+ // Retrieve interface handles for all the available interfaces.
+ wifi_error retrieveIfaceHandles();
+ wifi_interface_handle getIfaceHandle(const std::string& iface_name);
+ // Run the legacy HAL event loop thread.
+ void runEventLoop();
+ // Retrieve the cached gscan results to pass the results back to the
+ // external callbacks.
+ std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults(
+ const std::string& iface_name);
+ void invalidate();
+ // Handles wifi (error) status of Virtual interface create/delete
+ wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+ wifi_error status);
+ wifi_link_stat* copyLinkStat(wifi_link_stat* stat_ptr, std::vector<LinkStats>& stats);
+ wifi_peer_info* copyPeerInfo(wifi_peer_info* peer_ptr, std::vector<WifiPeerInfo>& peers);
+
+ // Global function table of legacy HAL.
+ wifi_hal_fn global_func_table_;
+ // Opaque handle to be used for all global operations.
+ wifi_handle global_handle_;
+ // Map of interface name to handle that is to be used for all interface
+ // specific operations.
+ std::map<std::string, wifi_interface_handle> iface_name_to_handle_;
+ // Flag to indicate if we have initiated the cleanup of legacy HAL.
+ std::atomic<bool> awaiting_event_loop_termination_;
+ std::condition_variable_any stop_wait_cv_;
+ // Flag to indicate if the legacy HAL has been started.
+ bool is_started_;
+ std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+ // Flag to indicate if this HAL is for the primary chip. This is used
+ // in order to avoid some hard-coded behavior used with older HALs,
+ // such as bring wlan0 interface up/down on start/stop HAL.
+ // it may be removed once vendor HALs are updated.
+ bool is_primary_;
+};
+
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_LEGACY_HAL_H_
diff --git a/wifi/aidl/default/wifi_legacy_hal_factory.cpp b/wifi/aidl/default/wifi_legacy_hal_factory.cpp
new file mode 100644
index 0000000..0359d6f
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_factory.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal_factory.h"
+
+#include <android-base/logging.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals";
+static constexpr char kVendorHalsDescExt[] = ".xml";
+static constexpr uint32_t kVendorHalsDescVersion = 1;
+
+bool isDirectory(struct dirent* entryPtr) {
+ bool isDir = false;
+ if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) {
+ isDir = (entryPtr->d_type == DT_DIR);
+ } else {
+ struct stat entryStat;
+ stat(entryPtr->d_name, &entryStat);
+ isDir = S_ISDIR(entryStat.st_mode);
+ }
+ return isDir;
+}
+
+bool isFileExtension(const char* name, const char* ext) {
+ if (name == NULL) return false;
+ if (ext == NULL) return false;
+
+ size_t extLen = strlen(ext);
+ size_t nameLen = strlen(name);
+
+ if (extLen > nameLen) return false;
+
+ if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false;
+
+ return true;
+}
+}; // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+WifiLegacyHalFactory::WifiLegacyHalFactory(
+ const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool)
+ : iface_tool_(iface_tool) {}
+
+std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
+ if (legacy_hals_.empty()) {
+ if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
+ for (auto& desc : descs_) {
+ std::shared_ptr<WifiLegacyHal> hal =
+ std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
+ legacy_hals_.push_back(hal);
+ }
+ }
+
+ return legacy_hals_;
+}
+
+bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() {
+ wifi_hal_lib_desc desc;
+
+ if (!initLinkedHalFunctionTable(&desc.fn)) return false;
+
+ desc.primary = true;
+ desc.handle = NULL;
+ descs_.push_back(desc);
+ return true;
+}
+
+bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) {
+ init_wifi_vendor_hal_func_table_t initfn;
+
+ initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT,
+ "init_wifi_vendor_hal_func_table");
+ if (!initfn) {
+ LOG(INFO) << "no vendor HAL library linked, will try dynamic load";
+ return false;
+ }
+
+ if (!initHalFuncTableWithStubs(hal_fn)) {
+ LOG(ERROR) << "Can not initialize the basic function pointer table";
+ return false;
+ }
+
+ if (initfn(hal_fn) != WIFI_SUCCESS) {
+ LOG(ERROR) << "Can not initialize the vendor function pointer table";
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Overall structure of the HAL descriptor XML schema
+ *
+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <WifiVendorHal version="1">
+ * <path>/vendor/lib64/libwifi-hal-qcom.so</path>
+ * <primary>1</primary>
+ * </WifiVendorHal>
+ */
+void WifiLegacyHalFactory::initVendorHalsDescriptorList() {
+ xmlDocPtr xml;
+ xmlNodePtr node, cnode;
+ char* version = NULL;
+ std::string path;
+ xmlChar* value;
+ wifi_hal_lib_desc desc;
+
+ LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath;
+ DIR* dirPtr = ::opendir(kVendorHalsDescPath);
+ if (dirPtr == NULL) {
+ LOG(ERROR) << "failed to open " << kVendorHalsDescPath;
+ return;
+ }
+ for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL;
+ entryPtr = ::readdir(dirPtr)) {
+ if (isDirectory(entryPtr)) continue;
+
+ if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt))
+ continue; // only process .xml files
+
+ LOG(INFO) << "processing config file: " << entryPtr->d_name;
+
+ std::string fullPath(kVendorHalsDescPath);
+ fullPath.append("/");
+ fullPath.append(entryPtr->d_name);
+ xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER);
+ if (!xml) {
+ LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping...";
+ continue;
+ }
+ node = xmlDocGetRootElement(xml);
+ if (!node) {
+ LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping...";
+ goto skip;
+ }
+ if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) {
+ LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name
+ << " skipping...";
+ goto skip;
+ }
+ version = (char*)xmlGetProp(node, BAD_CAST "version");
+ if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) {
+ LOG(ERROR) << "conf file: " << entryPtr->d_name
+ << "must have version: " << kVendorHalsDescVersion << ", skipping...";
+ goto skip;
+ }
+ cnode = node->children;
+ path.clear();
+ desc.primary = false;
+ while (cnode) {
+ if (!xmlStrcmp(cnode->name, BAD_CAST "path")) {
+ value = xmlNodeListGetString(xml, cnode->children, 1);
+ if (value) path = (char*)value;
+ xmlFree(value);
+ } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) {
+ value = xmlNodeListGetString(xml, cnode->children, 1);
+ desc.primary = !xmlStrcmp(value, BAD_CAST "1");
+ xmlFree(value);
+ }
+ cnode = cnode->next;
+ }
+ if (path.empty()) {
+ LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name
+ << ", skipping...";
+ goto skip;
+ }
+ if (loadVendorHalLib(path, desc)) {
+ if (desc.primary)
+ descs_.insert(descs_.begin(), desc);
+ else
+ descs_.push_back(desc);
+ }
+ skip:
+ xmlFreeDoc(xml);
+ if (version) {
+ xmlFree(version);
+ version = NULL;
+ }
+ }
+ ::closedir(dirPtr);
+}
+
+bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) {
+ void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
+ init_wifi_vendor_hal_func_table_t initfn;
+ wifi_error res;
+
+ if (!h) {
+ LOG(ERROR) << "failed to open vendor hal library: " << path;
+ return false;
+ }
+ initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table");
+ if (!initfn) {
+ LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path;
+ goto out_err;
+ }
+
+ if (!initHalFuncTableWithStubs(&desc.fn)) {
+ LOG(ERROR) << "Can not initialize the basic function pointer table";
+ goto out_err;
+ }
+ res = initfn(&desc.fn);
+ if (res != WIFI_SUCCESS) {
+ LOG(ERROR) << "failed to initialize the vendor func table in: " << path
+ << " error: " << res;
+ goto out_err;
+ }
+
+ res = desc.fn.wifi_early_initialize();
+ // vendor HALs which do not implement early_initialize will return
+ // WIFI_ERROR_NOT_SUPPORTED, treat this as success.
+ if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) {
+ LOG(ERROR) << "early initialization failed in: " << path << " error: " << res;
+ goto out_err;
+ }
+
+ desc.handle = h;
+ return true;
+out_err:
+ dlclose(h);
+ return false;
+}
+
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_legacy_hal_factory.h b/wifi/aidl/default/wifi_legacy_hal_factory.h
new file mode 100644
index 0000000..e7b287a
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_factory.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_LEGACY_HAL_FACTORY_H_
+#define WIFI_LEGACY_HAL_FACTORY_H_
+
+#include <wifi_system/interface_tool.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+// This is in a separate namespace to prevent typename conflicts between
+// the legacy HAL types and the AIDL interface types.
+namespace legacy_hal {
+/**
+ * Class that creates WifiLegacyHal objects for vendor HALs in the system.
+ */
+class WifiLegacyHalFactory {
+ public:
+ WifiLegacyHalFactory(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool);
+ virtual ~WifiLegacyHalFactory() = default;
+
+ std::vector<std::shared_ptr<WifiLegacyHal>> getHals();
+
+ private:
+ typedef struct {
+ wifi_hal_fn fn;
+ bool primary;
+ void* handle;
+ } wifi_hal_lib_desc;
+
+ bool initVendorHalDescriptorFromLinked();
+ void initVendorHalsDescriptorList();
+ bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn);
+ bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc);
+
+ std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool_;
+ std::vector<wifi_hal_lib_desc> descs_;
+ std::vector<std::shared_ptr<WifiLegacyHal>> legacy_hals_;
+};
+
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_LEGACY_HAL_FACTORY_H_
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
new file mode 100644
index 0000000..b5196c9
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_legacy_hal_stubs.h"
+
+// TODO: Remove these stubs from HalTool in libwifi-system.
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+template <typename>
+struct stubFunction;
+
+template <typename R, typename... Args>
+struct stubFunction<R (*)(Args...)> {
+ static constexpr R invoke(Args...) { return WIFI_ERROR_NOT_SUPPORTED; }
+};
+template <typename... Args>
+struct stubFunction<void (*)(Args...)> {
+ static constexpr void invoke(Args...) {}
+};
+
+template <typename T>
+void populateStubFor(T* val) {
+ *val = &stubFunction<T>::invoke;
+}
+
+bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
+ if (hal_fn == nullptr) {
+ return false;
+ }
+ populateStubFor(&hal_fn->wifi_initialize);
+ populateStubFor(&hal_fn->wifi_wait_for_driver_ready);
+ populateStubFor(&hal_fn->wifi_cleanup);
+ populateStubFor(&hal_fn->wifi_event_loop);
+ populateStubFor(&hal_fn->wifi_get_error_info);
+ populateStubFor(&hal_fn->wifi_get_supported_feature_set);
+ populateStubFor(&hal_fn->wifi_get_concurrency_matrix);
+ populateStubFor(&hal_fn->wifi_set_scanning_mac_oui);
+ populateStubFor(&hal_fn->wifi_get_supported_channels);
+ populateStubFor(&hal_fn->wifi_is_epr_supported);
+ populateStubFor(&hal_fn->wifi_get_ifaces);
+ populateStubFor(&hal_fn->wifi_get_iface_name);
+ populateStubFor(&hal_fn->wifi_set_iface_event_handler);
+ populateStubFor(&hal_fn->wifi_reset_iface_event_handler);
+ populateStubFor(&hal_fn->wifi_start_gscan);
+ populateStubFor(&hal_fn->wifi_stop_gscan);
+ populateStubFor(&hal_fn->wifi_get_cached_gscan_results);
+ populateStubFor(&hal_fn->wifi_set_bssid_hotlist);
+ populateStubFor(&hal_fn->wifi_reset_bssid_hotlist);
+ populateStubFor(&hal_fn->wifi_set_significant_change_handler);
+ populateStubFor(&hal_fn->wifi_reset_significant_change_handler);
+ populateStubFor(&hal_fn->wifi_get_gscan_capabilities);
+ populateStubFor(&hal_fn->wifi_set_link_stats);
+ populateStubFor(&hal_fn->wifi_get_link_stats);
+ populateStubFor(&hal_fn->wifi_clear_link_stats);
+ populateStubFor(&hal_fn->wifi_get_valid_channels);
+ populateStubFor(&hal_fn->wifi_rtt_range_request);
+ populateStubFor(&hal_fn->wifi_rtt_range_cancel);
+ populateStubFor(&hal_fn->wifi_get_rtt_capabilities);
+ populateStubFor(&hal_fn->wifi_rtt_get_responder_info);
+ populateStubFor(&hal_fn->wifi_enable_responder);
+ populateStubFor(&hal_fn->wifi_disable_responder);
+ populateStubFor(&hal_fn->wifi_set_nodfs_flag);
+ populateStubFor(&hal_fn->wifi_start_logging);
+ populateStubFor(&hal_fn->wifi_set_epno_list);
+ populateStubFor(&hal_fn->wifi_reset_epno_list);
+ populateStubFor(&hal_fn->wifi_set_country_code);
+ populateStubFor(&hal_fn->wifi_get_firmware_memory_dump);
+ populateStubFor(&hal_fn->wifi_set_log_handler);
+ populateStubFor(&hal_fn->wifi_reset_log_handler);
+ populateStubFor(&hal_fn->wifi_set_alert_handler);
+ populateStubFor(&hal_fn->wifi_reset_alert_handler);
+ populateStubFor(&hal_fn->wifi_get_firmware_version);
+ populateStubFor(&hal_fn->wifi_get_ring_buffers_status);
+ populateStubFor(&hal_fn->wifi_get_logger_supported_feature_set);
+ populateStubFor(&hal_fn->wifi_get_ring_data);
+ populateStubFor(&hal_fn->wifi_enable_tdls);
+ populateStubFor(&hal_fn->wifi_disable_tdls);
+ populateStubFor(&hal_fn->wifi_get_tdls_status);
+ populateStubFor(&hal_fn->wifi_get_tdls_capabilities);
+ populateStubFor(&hal_fn->wifi_get_driver_version);
+ populateStubFor(&hal_fn->wifi_set_passpoint_list);
+ populateStubFor(&hal_fn->wifi_reset_passpoint_list);
+ populateStubFor(&hal_fn->wifi_set_lci);
+ populateStubFor(&hal_fn->wifi_set_lcr);
+ populateStubFor(&hal_fn->wifi_start_sending_offloaded_packet);
+ populateStubFor(&hal_fn->wifi_stop_sending_offloaded_packet);
+ populateStubFor(&hal_fn->wifi_start_rssi_monitoring);
+ populateStubFor(&hal_fn->wifi_stop_rssi_monitoring);
+ populateStubFor(&hal_fn->wifi_get_wake_reason_stats);
+ populateStubFor(&hal_fn->wifi_configure_nd_offload);
+ populateStubFor(&hal_fn->wifi_get_driver_memory_dump);
+ populateStubFor(&hal_fn->wifi_start_pkt_fate_monitoring);
+ populateStubFor(&hal_fn->wifi_get_tx_pkt_fates);
+ populateStubFor(&hal_fn->wifi_get_rx_pkt_fates);
+ populateStubFor(&hal_fn->wifi_nan_enable_request);
+ populateStubFor(&hal_fn->wifi_nan_disable_request);
+ populateStubFor(&hal_fn->wifi_nan_publish_request);
+ populateStubFor(&hal_fn->wifi_nan_publish_cancel_request);
+ populateStubFor(&hal_fn->wifi_nan_subscribe_request);
+ populateStubFor(&hal_fn->wifi_nan_subscribe_cancel_request);
+ populateStubFor(&hal_fn->wifi_nan_transmit_followup_request);
+ populateStubFor(&hal_fn->wifi_nan_stats_request);
+ populateStubFor(&hal_fn->wifi_nan_config_request);
+ populateStubFor(&hal_fn->wifi_nan_tca_request);
+ populateStubFor(&hal_fn->wifi_nan_beacon_sdf_payload_request);
+ populateStubFor(&hal_fn->wifi_nan_register_handler);
+ populateStubFor(&hal_fn->wifi_nan_get_version);
+ populateStubFor(&hal_fn->wifi_nan_get_capabilities);
+ populateStubFor(&hal_fn->wifi_nan_data_interface_create);
+ populateStubFor(&hal_fn->wifi_nan_data_interface_delete);
+ populateStubFor(&hal_fn->wifi_nan_data_request_initiator);
+ populateStubFor(&hal_fn->wifi_nan_data_indication_response);
+ populateStubFor(&hal_fn->wifi_nan_pairing_request);
+ populateStubFor(&hal_fn->wifi_nan_pairing_indication_response);
+ populateStubFor(&hal_fn->wifi_nan_bootstrapping_request);
+ populateStubFor(&hal_fn->wifi_nan_bootstrapping_indication_response);
+ populateStubFor(&hal_fn->wifi_nan_data_end);
+ populateStubFor(&hal_fn->wifi_nan_pairing_end);
+ populateStubFor(&hal_fn->wifi_get_packet_filter_capabilities);
+ populateStubFor(&hal_fn->wifi_set_packet_filter);
+ populateStubFor(&hal_fn->wifi_read_packet_filter);
+ populateStubFor(&hal_fn->wifi_get_roaming_capabilities);
+ populateStubFor(&hal_fn->wifi_enable_firmware_roaming);
+ populateStubFor(&hal_fn->wifi_configure_roaming);
+ populateStubFor(&hal_fn->wifi_select_tx_power_scenario);
+ populateStubFor(&hal_fn->wifi_reset_tx_power_scenario);
+ populateStubFor(&hal_fn->wifi_set_radio_mode_change_handler);
+ populateStubFor(&hal_fn->wifi_set_latency_mode);
+ populateStubFor(&hal_fn->wifi_set_thermal_mitigation_mode);
+ populateStubFor(&hal_fn->wifi_virtual_interface_create);
+ populateStubFor(&hal_fn->wifi_virtual_interface_delete);
+ populateStubFor(&hal_fn->wifi_map_dscp_access_category);
+ populateStubFor(&hal_fn->wifi_reset_dscp_mapping);
+ populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler);
+ populateStubFor(&hal_fn->wifi_get_supported_iface_name);
+ populateStubFor(&hal_fn->wifi_early_initialize);
+ populateStubFor(&hal_fn->wifi_get_chip_feature_set);
+ populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
+ populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
+ populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels);
+ populateStubFor(&hal_fn->wifi_set_voip_mode);
+ populateStubFor(&hal_fn->wifi_twt_register_handler);
+ populateStubFor(&hal_fn->wifi_twt_get_capability);
+ populateStubFor(&hal_fn->wifi_twt_setup_request);
+ populateStubFor(&hal_fn->wifi_twt_teardown_request);
+ populateStubFor(&hal_fn->wifi_twt_info_frame_request);
+ populateStubFor(&hal_fn->wifi_twt_get_stats);
+ populateStubFor(&hal_fn->wifi_twt_clear_stats);
+ populateStubFor(&hal_fn->wifi_set_dtim_config);
+ populateStubFor(&hal_fn->wifi_get_usable_channels);
+ populateStubFor(&hal_fn->wifi_trigger_subsystem_restart);
+ populateStubFor(&hal_fn->wifi_set_indoor_state);
+ populateStubFor(&hal_fn->wifi_get_supported_radio_combinations_matrix);
+ populateStubFor(&hal_fn->wifi_nan_rtt_chre_enable_request);
+ populateStubFor(&hal_fn->wifi_nan_rtt_chre_disable_request);
+ populateStubFor(&hal_fn->wifi_chre_register_handler);
+ populateStubFor(&hal_fn->wifi_enable_tx_power_limits);
+ populateStubFor(&hal_fn->wifi_get_cached_scan_results);
+ populateStubFor(&hal_fn->wifi_get_chip_capabilities);
+ populateStubFor(&hal_fn->wifi_enable_sta_channel_for_peer_network);
+ populateStubFor(&hal_fn->wifi_nan_suspend_request);
+ populateStubFor(&hal_fn->wifi_nan_resume_request);
+ populateStubFor(&hal_fn->wifi_set_scan_mode);
+ populateStubFor(&hal_fn->wifi_set_mlo_mode);
+ populateStubFor(&hal_fn->wifi_get_supported_iface_concurrency_matrix);
+ return true;
+}
+
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.h b/wifi/aidl/default/wifi_legacy_hal_stubs.h
new file mode 100644
index 0000000..603ecf2
--- /dev/null
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_LEGACY_HAL_STUBS_H_
+#define WIFI_LEGACY_HAL_STUBS_H_
+
+#include <hardware_legacy/wifi_hal.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace legacy_hal {
+
+bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
+} // namespace legacy_hal
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_LEGACY_HAL_STUBS_H_
diff --git a/wifi/aidl/default/wifi_mode_controller.cpp b/wifi/aidl/default/wifi_mode_controller.cpp
new file mode 100644
index 0000000..07cb072
--- /dev/null
+++ b/wifi/aidl/default/wifi_mode_controller.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_mode_controller.h"
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <private/android_filesystem_config.h>
+
+namespace {
+using aidl::android::hardware::wifi::IfaceType;
+using android::wifi_hal::DriverTool;
+
+int convertIfaceTypeToFirmwareMode(IfaceType type) {
+ int mode;
+ switch (type) {
+ case IfaceType::AP:
+ mode = DriverTool::kFirmwareModeAp;
+ break;
+ case IfaceType::P2P:
+ mode = DriverTool::kFirmwareModeP2p;
+ break;
+ case IfaceType::NAN_IFACE:
+ // NAN is exposed in STA mode currently.
+ mode = DriverTool::kFirmwareModeSta;
+ break;
+ case IfaceType::STA:
+ mode = DriverTool::kFirmwareModeSta;
+ break;
+ }
+ return mode;
+}
+} // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
+
+bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) {
+ return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type));
+}
+
+bool WifiModeController::initialize() {
+ if (!driver_tool_->LoadDriver()) {
+ LOG(ERROR) << "Failed to load WiFi driver";
+ return false;
+ }
+ return true;
+}
+
+bool WifiModeController::changeFirmwareMode(IfaceType type) {
+ if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
+ LOG(ERROR) << "Failed to change firmware mode";
+ return false;
+ }
+ return true;
+}
+
+bool WifiModeController::deinitialize() {
+ if (!driver_tool_->UnloadDriver()) {
+ LOG(ERROR) << "Failed to unload WiFi driver";
+ return false;
+ }
+ return true;
+}
+
+} // namespace mode_controller
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_mode_controller.h b/wifi/aidl/default/wifi_mode_controller.h
new file mode 100644
index 0000000..1a9fb1a
--- /dev/null
+++ b/wifi/aidl/default/wifi_mode_controller.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_MODE_CONTROLLER_H_
+#define WIFI_MODE_CONTROLLER_H_
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <wifi_hal/driver_tool.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace mode_controller {
+
+/**
+ * Class that encapsulates all firmware mode configuration.
+ * This class will perform the necessary firmware reloads to put the chip in the
+ * required state (essentially a wrapper over DriverTool).
+ */
+class WifiModeController {
+ public:
+ WifiModeController();
+ virtual ~WifiModeController() = default;
+
+ // Checks if a firmware mode change is necessary to support the specified
+ // iface type operations.
+ virtual bool isFirmwareModeChangeNeeded(IfaceType type);
+ virtual bool initialize();
+ // Change the firmware mode to support the specified iface type operations.
+ virtual bool changeFirmwareMode(IfaceType type);
+ // Unload the driver. This should be invoked whenever |IWifi.stop()| is
+ // invoked.
+ virtual bool deinitialize();
+
+ private:
+ std::unique_ptr<::android::wifi_hal::DriverTool> driver_tool_;
+};
+
+} // namespace mode_controller
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/aidl/default/wifi_nan_iface.cpp b/wifi/aidl/default/wifi_nan_iface.cpp
new file mode 100644
index 0000000..cefe7f7
--- /dev/null
+++ b/wifi/aidl/default/wifi_nan_iface.cpp
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_nan_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname),
+ is_dedicated_iface_(is_dedicated_iface),
+ legacy_hal_(legacy_hal),
+ iface_util_(iface_util),
+ is_valid_(true) {}
+
+std::shared_ptr<WifiNanIface> WifiNanIface::create(
+ const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
+ std::shared_ptr<WifiNanIface> ptr = ndk::SharedRefBase::make<WifiNanIface>(
+ ifname, is_dedicated_iface, legacy_hal, iface_util);
+ if (is_dedicated_iface) {
+ // If using a dedicated iface, set the iface up first.
+ if (!iface_util.lock()->setUpState(ifname, true)) {
+ // Fatal failure, invalidate the iface object.
+ ptr->invalidate();
+ return nullptr;
+ }
+ }
+ std::weak_ptr<WifiNanIface> weak_ptr_this(ptr);
+ ptr->setWeakPtr(weak_ptr_this);
+ ptr->registerCallbackHandlers();
+ return ptr;
+}
+
+void WifiNanIface::registerCallbackHandlers() {
+ // Register all the callbacks here. These should be valid for the lifetime
+ // of the object. Whenever the mode changes legacy HAL will remove
+ // all of these callbacks.
+ legacy_hal::NanCallbackHandlers callback_handlers;
+ std::weak_ptr<WifiNanIface> weak_ptr_this = weak_ptr_this_;
+
+ // Callback for response.
+ callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id,
+ const legacy_hal::NanResponseMsg& msg) {
+ 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;
+ }
+ NanStatus nanStatus;
+ if (!aidl_struct_util::convertLegacyNanResponseHeaderToAidl(msg, &nanStatus)) {
+ LOG(ERROR) << "Failed to convert nan response header";
+ return;
+ }
+
+ switch (msg.response_type) {
+ case legacy_hal::NAN_RESPONSE_ENABLED: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyEnableResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_DISABLED: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyDisableResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_PUBLISH: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStartPublishResponse(id, nanStatus,
+ msg.body.publish_response.publish_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStopPublishResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyTransmitFollowupResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStartSubscribeResponse(
+ id, nanStatus, msg.body.subscribe_response.subscribe_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyStopSubscribeResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_CONFIG: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyConfigResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_GET_CAPABILITIES: {
+ NanCapabilities aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanCapabilitiesResponseToAidl(
+ msg.body.nan_capabilities, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyCapabilitiesResponse(id, nanStatus, aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_INTERFACE_CREATE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyCreateDataInterfaceResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_INTERFACE_DELETE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyDeleteDataInterfaceResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyInitiateDataPathResponse(
+ id, nanStatus,
+ msg.body.data_request_response.ndp_instance_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyRespondToDataPathIndicationResponse(id, nanStatus)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_DP_END: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyTerminateDataPathResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_PAIRING_INITIATOR_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyInitiatePairingResponse(
+ id, nanStatus,
+ msg.body.pairing_request_response.paring_instance_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_PAIRING_RESPONDER_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyRespondToPairingIndicationResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_PAIRING_END: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyTerminatePairingResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_BOOTSTRAPPING_INITIATOR_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyInitiateBootstrappingResponse(
+ id, nanStatus,
+ msg.body.bootstrapping_request_response
+ .bootstrapping_instance_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_BOOTSTRAPPING_RESPONDER_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyRespondToBootstrappingIndicationResponse(id, nanStatus)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_SUSPEND_REQUEST_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifySuspendResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESUME_REQUEST_RESPONSE: {
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->notifyResumeResponse(id, nanStatus).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ break;
+ }
+ case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
+ /* fall through */
+ case legacy_hal::NAN_RESPONSE_TCA:
+ /* fall through */
+ case legacy_hal::NAN_RESPONSE_STATS:
+ /* fall through */
+ case legacy_hal::NAN_RESPONSE_ERROR:
+ /* fall through */
+ default:
+ LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type;
+ return;
+ }
+ };
+
+ callback_handlers.on_event_disc_eng_event = [weak_ptr_this](
+ const legacy_hal::NanDiscEngEventInd& msg) {
+ 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;
+ }
+ NanClusterEventInd aidl_struct;
+ // event types defined identically - hence can be cast
+ aidl_struct.eventType = (NanClusterEventType)msg.event_type;
+ aidl_struct.addr = std::array<uint8_t, 6>();
+ std::copy(msg.data.mac_addr.addr, msg.data.mac_addr.addr + 6, std::begin(aidl_struct.addr));
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventClusterEvent(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
+ 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;
+ }
+ NanStatus status;
+ aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+ &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDisabled(status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_publish_terminated =
+ [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
+ 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;
+ }
+ NanStatus status;
+ aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
+ sizeof(msg.nan_reason), &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_subscribe_terminated =
+ [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
+ 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;
+ }
+ NanStatus status;
+ aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
+ sizeof(msg.nan_reason), &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
+ 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;
+ }
+ NanMatchInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanMatchIndToAidl(msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventMatch(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_match_expired = [weak_ptr_this](
+ const legacy_hal::NanMatchExpiredInd& msg) {
+ 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->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
+ 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;
+ }
+ NanFollowupReceivedInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanFollowupIndToAidl(msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventFollowupReceived(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_transmit_follow_up =
+ [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
+ 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;
+ }
+ NanStatus status;
+ aidl_struct_util::convertToNanStatus(msg.reason, msg.nan_reason,
+ sizeof(msg.nan_reason), &status);
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_data_path_request =
+ [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
+ 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;
+ }
+ NanDataPathRequestInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanDataPathRequestIndToAidl(msg,
+ &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDataPathRequest(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_data_path_confirm =
+ [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
+ 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;
+ }
+ NanDataPathConfirmInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanDataPathConfirmIndToAidl(msg,
+ &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDataPathConfirm(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_data_path_end =
+ [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
+ 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()) {
+ for (int i = 0; i < msg.num_ndp_instances; ++i) {
+ if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ }
+ };
+
+ callback_handlers.on_event_pairing_request =
+ [weak_ptr_this](const legacy_hal::NanPairingRequestInd& msg) {
+ 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;
+ }
+ NanPairingRequestInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanPairingRequestIndToAidl(msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventPairingRequest(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+ callback_handlers.on_event_pairing_confirm =
+ [weak_ptr_this](const legacy_hal::NanPairingConfirmInd& msg) {
+ 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;
+ }
+ NanPairingConfirmInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanPairingConfirmIndToAidl(msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventPairingConfirm(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+ callback_handlers.on_event_bootstrapping_request =
+ [weak_ptr_this](const legacy_hal::NanBootstrappingRequestInd& msg) {
+ 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;
+ }
+ NanBootstrappingRequestInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanBootstrappingRequestIndToAidl(
+ msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventBootstrappingRequest(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+ callback_handlers.on_event_bootstrapping_confirm =
+ [weak_ptr_this](const legacy_hal::NanBootstrappingConfirmInd& msg) {
+ 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;
+ }
+ NanBootstrappingConfirmInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanBootstrappingConfirmIndToAidl(
+ msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventBootstrappingConfirm(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ callback_handlers.on_event_beacon_sdf_payload =
+ [](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
+ LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
+ };
+
+ callback_handlers.on_event_range_request = [](const legacy_hal::NanRangeRequestInd& /* msg */) {
+ LOG(ERROR) << "on_event_range_request - should not be called";
+ };
+
+ callback_handlers.on_event_range_report = [](const legacy_hal::NanRangeReportInd& /* msg */) {
+ LOG(ERROR) << "on_event_range_report - should not be called";
+ };
+
+ callback_handlers.on_event_schedule_update =
+ [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) {
+ 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;
+ }
+ NanDataPathScheduleUpdateInd aidl_struct;
+ if (!aidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToAidl(
+ msg, &aidl_struct)) {
+ LOG(ERROR) << "Failed to convert nan capabilities response";
+ return;
+ }
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDataPathScheduleUpdate(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+ callback_handlers.on_event_suspension_mode_change =
+ [weak_ptr_this](const legacy_hal::NanSuspensionModeChangeInd& msg) {
+ 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;
+ }
+ NanSuspensionModeChangeInd aidl_struct;
+ aidl_struct.isSuspended = msg.is_suspended;
+
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventSuspensionModeChanged(aidl_struct).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
+ invalidate();
+ }
+
+ // Register for iface state toggle events.
+ iface_util::IfaceEventHandlers event_handlers = {};
+#ifndef WIFI_SKIP_STATE_TOGGLE_OFF_ON_FOR_NAN
+ event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
+ 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;
+ }
+ // Tell framework that NAN has been disabled.
+ NanStatus status = {NanStatusCode::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->eventDisabled(status).isOk()) {
+ LOG(ERROR) << "Failed to invoke the callback";
+ }
+ }
+ };
+#endif
+ iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
+}
+
+void WifiNanIface::setWeakPtr(std::weak_ptr<WifiNanIface> ptr) {
+ weak_ptr_this_ = ptr;
+}
+
+void WifiNanIface::invalidate() {
+ if (!isValid()) {
+ return;
+ }
+ // send commands to HAL to actually disable and destroy interfaces
+ legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
+ legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
+ legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
+ iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
+ legacy_hal_.reset();
+ event_cb_handler_.invalidate();
+ is_valid_ = false;
+ if (is_dedicated_iface_) {
+ // If using a dedicated iface, set the iface down.
+ iface_util_.lock()->setUpState(ifname_, false);
+ }
+}
+
+bool WifiNanIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiNanIface::getName() {
+ return ifname_;
+}
+
+std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
+ LOG(ERROR) << "Using original getEventCallbacks";
+ return event_cb_handler_.getCallbacks();
+}
+
+ndk::ScopedAStatus WifiNanIface::getName(std::string* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getNameInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiNanIface::registerEventCallback(
+ const std::shared_ptr<IWifiNanIfaceEventCallback>& callback) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::registerEventCallbackInternal, callback);
+}
+
+ndk::ScopedAStatus WifiNanIface::getCapabilitiesRequest(char16_t in_cmdId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::getCapabilitiesRequestInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiNanIface::enableRequest(char16_t in_cmdId, const NanEnableRequest& in_msg1,
+ const NanConfigRequestSupplemental& in_msg2) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::enableRequestInternal, in_cmdId, in_msg1, in_msg2);
+}
+
+ndk::ScopedAStatus WifiNanIface::configRequest(char16_t in_cmdId, const NanConfigRequest& in_msg1,
+ const NanConfigRequestSupplemental& in_msg2) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::configRequestInternal, in_cmdId, in_msg1, in_msg2);
+}
+
+ndk::ScopedAStatus WifiNanIface::disableRequest(char16_t in_cmdId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::disableRequestInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiNanIface::startPublishRequest(char16_t in_cmdId,
+ const NanPublishRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::startPublishRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopPublishRequest(char16_t in_cmdId, int8_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::stopPublishRequestInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiNanIface::startSubscribeRequest(char16_t in_cmdId,
+ const NanSubscribeRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::startSubscribeRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopSubscribeRequest(char16_t in_cmdId, int8_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::stopSubscribeRequestInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiNanIface::transmitFollowupRequest(char16_t in_cmdId,
+ const NanTransmitFollowupRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::transmitFollowupRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::createDataInterfaceRequest(char16_t in_cmdId,
+ const std::string& in_ifaceName) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::createDataInterfaceRequestInternal, in_cmdId,
+ in_ifaceName);
+}
+
+ndk::ScopedAStatus WifiNanIface::deleteDataInterfaceRequest(char16_t in_cmdId,
+ const std::string& in_ifaceName) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::deleteDataInterfaceRequestInternal, in_cmdId,
+ in_ifaceName);
+}
+
+ndk::ScopedAStatus WifiNanIface::initiateDataPathRequest(char16_t in_cmdId,
+ const NanInitiateDataPathRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::initiateDataPathRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::respondToDataPathIndicationRequest(
+ char16_t in_cmdId, const NanRespondToDataPathIndicationRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::respondToDataPathIndicationRequestInternal, in_cmdId,
+ in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::terminateDataPathRequest(char16_t in_cmdId,
+ int32_t in_ndpInstanceId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::terminateDataPathRequestInternal, in_cmdId,
+ in_ndpInstanceId);
+}
+
+ndk::ScopedAStatus WifiNanIface::initiatePairingRequest(char16_t in_cmdId,
+ const NanPairingRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::initiatePairingRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::respondToPairingIndicationRequest(
+ char16_t in_cmdId, const NanRespondToPairingIndicationRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::respondToPairingIndicationRequestInternal, in_cmdId,
+ in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::terminatePairingRequest(char16_t in_cmdId,
+ int32_t in_ndpInstanceId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::terminatePairingRequestInternal, in_cmdId,
+ in_ndpInstanceId);
+}
+
+ndk::ScopedAStatus WifiNanIface::initiateBootstrappingRequest(
+ char16_t in_cmdId, const NanBootstrappingRequest& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::initiateBootstrappingRequestInternal, in_cmdId, in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::respondToBootstrappingIndicationRequest(
+ char16_t in_cmdId, const NanBootstrappingResponse& in_msg) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::respondToBootstrappingIndicationRequestInternal, in_cmdId,
+ in_msg);
+}
+
+ndk::ScopedAStatus WifiNanIface::suspendRequest(char16_t in_cmdId, int8_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::suspendRequestInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiNanIface::resumeRequest(char16_t in_cmdId, int8_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiNanIface::resumeRequestInternal, in_cmdId, in_sessionId);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiNanIface::getNameInternal() {
+ return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiNanIface::registerEventCallbackInternal(
+ const std::shared_ptr<IWifiNanIfaceEventCallback>& callback) {
+ if (!event_cb_handler_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiNanIface::getCapabilitiesRequestInternal(char16_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::enableRequestInternal(char16_t cmd_id,
+ const NanEnableRequest& msg1,
+ const NanConfigRequestSupplemental& msg2) {
+ legacy_hal::NanEnableRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanEnableRequestToLegacy(msg1, msg2, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::configRequestInternal(char16_t cmd_id,
+ const NanConfigRequest& msg1,
+ const NanConfigRequestSupplemental& msg2) {
+ legacy_hal::NanConfigRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanConfigRequestToLegacy(msg1, msg2, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::disableRequestInternal(char16_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::startPublishRequestInternal(char16_t cmd_id,
+ const NanPublishRequest& msg) {
+ legacy_hal::NanPublishRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanPublishRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopPublishRequestInternal(char16_t cmd_id, int8_t sessionId) {
+ legacy_hal::NanPublishCancelRequest legacy_msg;
+ legacy_msg.publish_id = sessionId;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::startSubscribeRequestInternal(char16_t cmd_id,
+ const NanSubscribeRequest& msg) {
+ legacy_hal::NanSubscribeRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::stopSubscribeRequestInternal(char16_t cmd_id, int8_t sessionId) {
+ legacy_hal::NanSubscribeCancelRequest legacy_msg;
+ legacy_msg.subscribe_id = sessionId;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::transmitFollowupRequestInternal(
+ char16_t cmd_id, const NanTransmitFollowupRequest& msg) {
+ legacy_hal::NanTransmitFollowupRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiNanIface::createDataInterfaceRequestInternal(char16_t cmd_id,
+ const std::string& iface_name) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::deleteDataInterfaceRequestInternal(char16_t cmd_id,
+ const std::string& iface_name) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::initiateDataPathRequestInternal(
+ char16_t cmd_id, const NanInitiateDataPathRequest& msg) {
+ legacy_hal::NanDataPathInitiatorRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
+ char16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) {
+ legacy_hal::NanDataPathIndicationResponse legacy_msg;
+ if (!aidl_struct_util::convertAidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::terminateDataPathRequestInternal(char16_t cmd_id,
+ int32_t ndpInstanceId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::initiatePairingRequestInternal(char16_t cmd_id,
+ const NanPairingRequest& msg) {
+ legacy_hal::NanPairingRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanPairingInitiatorRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPairingRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::respondToPairingIndicationRequestInternal(
+ char16_t cmd_id, const NanRespondToPairingIndicationRequest& msg) {
+ legacy_hal::NanPairingIndicationResponse legacy_msg;
+ if (!aidl_struct_util::convertAidlNanPairingIndicationResponseToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPairingIndicationResponse(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::terminatePairingRequestInternal(char16_t cmd_id,
+ int32_t ndpInstanceId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanPairingEnd(ifname_, cmd_id, ndpInstanceId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::initiateBootstrappingRequestInternal(
+ char16_t cmd_id, const NanBootstrappingRequest& msg) {
+ legacy_hal::NanBootstrappingRequest legacy_msg;
+ if (!aidl_struct_util::convertAidlNanBootstrappingInitiatorRequestToLegacy(msg, &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanBootstrappingRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::respondToBootstrappingIndicationRequestInternal(
+ char16_t cmd_id, const NanBootstrappingResponse& msg) {
+ legacy_hal::NanBootstrappingIndicationResponse legacy_msg;
+ if (!aidl_struct_util::convertAidlNanBootstrappingIndicationResponseToLegacy(msg,
+ &legacy_msg)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanBootstrappingIndicationResponse(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::suspendRequestInternal(char16_t cmd_id, int8_t sessionId) {
+ legacy_hal::NanSuspendRequest legacy_msg;
+ legacy_msg.publish_subscribe_id = sessionId;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanSuspendRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+ndk::ScopedAStatus WifiNanIface::resumeRequestInternal(char16_t cmd_id, int8_t sessionId) {
+ legacy_hal::NanResumeRequest legacy_msg;
+ legacy_msg.publish_subscribe_id = sessionId;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->nanResumeRequest(ifname_, cmd_id, legacy_msg);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_nan_iface.h b/wifi/aidl/default/wifi_nan_iface.h
new file mode 100644
index 0000000..a49ae8c
--- /dev/null
+++ b/wifi/aidl/default/wifi_nan_iface.h
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_NAN_IFACE_H_
+#define WIFI_NAN_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiNanIface.h>
+#include <aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.h>
+#include <android-base/macros.h>
+
+#include "aidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a NAN Iface instance.
+ */
+class WifiNanIface : public BnWifiNanIface {
+ public:
+ WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+ // Factory method - use instead of default constructor.
+ static std::shared_ptr<WifiNanIface> create(
+ const std::string& ifname, bool is_dedicated_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::string getName();
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+ ndk::ScopedAStatus registerEventCallback(
+ const std::shared_ptr<IWifiNanIfaceEventCallback>& in_callback) override;
+ ndk::ScopedAStatus getCapabilitiesRequest(char16_t in_cmdId) override;
+ ndk::ScopedAStatus enableRequest(char16_t in_cmdId, const NanEnableRequest& in_msg1,
+ const NanConfigRequestSupplemental& in_msg2) override;
+ ndk::ScopedAStatus configRequest(char16_t in_cmdId, const NanConfigRequest& in_msg1,
+ const NanConfigRequestSupplemental& in_msg2) override;
+ ndk::ScopedAStatus disableRequest(char16_t in_cmdId) override;
+ ndk::ScopedAStatus startPublishRequest(char16_t in_cmdId,
+ const NanPublishRequest& in_msg) override;
+ ndk::ScopedAStatus stopPublishRequest(char16_t in_cmdId, int8_t in_sessionId) override;
+ ndk::ScopedAStatus startSubscribeRequest(char16_t in_cmdId,
+ const NanSubscribeRequest& in_msg) override;
+ ndk::ScopedAStatus stopSubscribeRequest(char16_t in_cmdId, int8_t in_sessionId) override;
+ ndk::ScopedAStatus transmitFollowupRequest(char16_t in_cmdId,
+ const NanTransmitFollowupRequest& in_msg) override;
+ ndk::ScopedAStatus createDataInterfaceRequest(char16_t in_cmdId,
+ const std::string& in_ifaceName) override;
+ ndk::ScopedAStatus deleteDataInterfaceRequest(char16_t in_cmdId,
+ const std::string& in_ifaceName) override;
+ ndk::ScopedAStatus initiateDataPathRequest(char16_t in_cmdId,
+ const NanInitiateDataPathRequest& in_msg) override;
+ ndk::ScopedAStatus respondToDataPathIndicationRequest(
+ char16_t in_cmdId, const NanRespondToDataPathIndicationRequest& in_msg) override;
+ ndk::ScopedAStatus terminateDataPathRequest(char16_t in_cmdId,
+ int32_t in_ndpInstanceId) override;
+ ndk::ScopedAStatus initiatePairingRequest(char16_t in_cmdId,
+ const NanPairingRequest& in_msg) override;
+ ndk::ScopedAStatus respondToPairingIndicationRequest(
+ char16_t in_cmdId, const NanRespondToPairingIndicationRequest& in_msg) override;
+ ndk::ScopedAStatus terminatePairingRequest(char16_t in_cmdId, int32_t in_pairingId) override;
+ ndk::ScopedAStatus initiateBootstrappingRequest(char16_t in_cmdId,
+ const NanBootstrappingRequest& in_msg) override;
+ ndk::ScopedAStatus respondToBootstrappingIndicationRequest(
+ char16_t in_cmdId, const NanBootstrappingResponse& in_msg) override;
+ ndk::ScopedAStatus suspendRequest(char16_t in_cmdId, int8_t sessionId) override;
+ ndk::ScopedAStatus resumeRequest(char16_t in_cmdId, int8_t sessionId) override;
+
+ protected:
+ // Accessible to child class in the gTest suite.
+ void setWeakPtr(std::weak_ptr<WifiNanIface> ptr);
+ void registerCallbackHandlers();
+
+ private:
+ // Corresponding worker functions for the AIDL methods.
+ std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+ ndk::ScopedAStatus registerEventCallbackInternal(
+ const std::shared_ptr<IWifiNanIfaceEventCallback>& callback);
+ ndk::ScopedAStatus getCapabilitiesRequestInternal(char16_t cmd_id);
+ ndk::ScopedAStatus enableRequestInternal(char16_t cmd_id, const NanEnableRequest& msg1,
+ const NanConfigRequestSupplemental& msg2);
+ ndk::ScopedAStatus configRequestInternal(char16_t cmd_id, const NanConfigRequest& msg1,
+ const NanConfigRequestSupplemental& msg2);
+ ndk::ScopedAStatus disableRequestInternal(char16_t cmd_id);
+ ndk::ScopedAStatus startPublishRequestInternal(char16_t cmd_id, const NanPublishRequest& msg);
+ ndk::ScopedAStatus stopPublishRequestInternal(char16_t cmd_id, int8_t sessionId);
+ ndk::ScopedAStatus startSubscribeRequestInternal(char16_t cmd_id,
+ const NanSubscribeRequest& msg);
+ ndk::ScopedAStatus stopSubscribeRequestInternal(char16_t cmd_id, int8_t sessionId);
+ ndk::ScopedAStatus transmitFollowupRequestInternal(char16_t cmd_id,
+ const NanTransmitFollowupRequest& msg);
+ ndk::ScopedAStatus createDataInterfaceRequestInternal(char16_t cmd_id,
+ const std::string& iface_name);
+ ndk::ScopedAStatus deleteDataInterfaceRequestInternal(char16_t cmd_id,
+ const std::string& iface_name);
+ ndk::ScopedAStatus initiateDataPathRequestInternal(char16_t cmd_id,
+ const NanInitiateDataPathRequest& msg);
+ ndk::ScopedAStatus respondToDataPathIndicationRequestInternal(
+ char16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg);
+ ndk::ScopedAStatus terminateDataPathRequestInternal(char16_t cmd_id, int32_t ndpInstanceId);
+ ndk::ScopedAStatus initiatePairingRequestInternal(char16_t cmd_id,
+ const NanPairingRequest& msg);
+ ndk::ScopedAStatus respondToPairingIndicationRequestInternal(
+ char16_t cmd_id, const NanRespondToPairingIndicationRequest& msg);
+ ndk::ScopedAStatus terminatePairingRequestInternal(char16_t cmd_id, int32_t pairingId);
+ ndk::ScopedAStatus initiateBootstrappingRequestInternal(char16_t cmd_id,
+ const NanBootstrappingRequest& msg);
+ ndk::ScopedAStatus respondToBootstrappingIndicationRequestInternal(
+ char16_t cmd_id, const NanBootstrappingResponse& msg);
+ ndk::ScopedAStatus suspendRequestInternal(char16_t in_cmdId, int8_t sessionId);
+ ndk::ScopedAStatus resumeRequestInternal(char16_t in_cmdId, int8_t sessionId);
+
+ // Overridden in the gTest suite.
+ virtual std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks();
+
+ std::string ifname_;
+ bool is_dedicated_iface_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ bool is_valid_;
+ std::weak_ptr<WifiNanIface> weak_ptr_this_;
+ aidl_callback_util::AidlCallbackHandler<IWifiNanIfaceEventCallback> event_cb_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_NAN_IFACE_H_
diff --git a/wifi/aidl/default/wifi_p2p_iface.cpp b/wifi/aidl/default/wifi_p2p_iface.cpp
new file mode 100644
index 0000000..48ec6d6
--- /dev/null
+++ b/wifi/aidl/default/wifi_p2p_iface.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_p2p_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiP2pIface::WifiP2pIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+void WifiP2pIface::invalidate() {
+ legacy_hal_.reset();
+ is_valid_ = false;
+}
+
+bool WifiP2pIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiP2pIface::getName() {
+ return ifname_;
+}
+
+ndk::ScopedAStatus WifiP2pIface::getName(std::string* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiP2pIface::getNameInternal, _aidl_return);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiP2pIface::getNameInternal() {
+ return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_p2p_iface.h b/wifi/aidl/default/wifi_p2p_iface.h
new file mode 100644
index 0000000..d17470e
--- /dev/null
+++ b/wifi/aidl/default/wifi_p2p_iface.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_P2P_IFACE_H_
+#define WIFI_P2P_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiP2pIface.h>
+#include <android-base/macros.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a P2P Iface instance.
+ */
+class WifiP2pIface : public BnWifiP2pIface {
+ public:
+ WifiP2pIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::string getName();
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+
+ private:
+ // Corresponding worker functions for the AIDL methods.
+ std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+
+ std::string ifname_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiP2pIface);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_P2P_IFACE_H_
diff --git a/wifi/aidl/default/wifi_rtt_controller.cpp b/wifi/aidl/default/wifi_rtt_controller.cpp
new file mode 100644
index 0000000..a5f6768
--- /dev/null
+++ b/wifi/aidl/default/wifi_rtt_controller.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_rtt_controller.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiRttController::WifiRttController(const std::string& iface_name,
+ const std::shared_ptr<IWifiStaIface>& bound_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+std::shared_ptr<WifiRttController> WifiRttController::create(
+ const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) {
+ std::shared_ptr<WifiRttController> ptr =
+ ndk::SharedRefBase::make<WifiRttController>(iface_name, bound_iface, legacy_hal);
+ std::weak_ptr<WifiRttController> weak_ptr_this(ptr);
+ ptr->setWeakPtr(weak_ptr_this);
+ return ptr;
+}
+
+void WifiRttController::invalidate() {
+ legacy_hal_.reset();
+ event_callbacks_.clear();
+ is_valid_ = false;
+};
+
+bool WifiRttController::isValid() {
+ return is_valid_;
+}
+
+void WifiRttController::setWeakPtr(std::weak_ptr<WifiRttController> ptr) {
+ weak_ptr_this_ = ptr;
+}
+
+std::vector<std::shared_ptr<IWifiRttControllerEventCallback>>
+WifiRttController::getEventCallbacks() {
+ return event_callbacks_;
+}
+
+std::string WifiRttController::getIfaceName() {
+ return ifname_;
+}
+
+ndk::ScopedAStatus WifiRttController::getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getBoundIfaceInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiRttController::registerEventCallback(
+ const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::registerEventCallbackInternal, callback);
+}
+
+ndk::ScopedAStatus WifiRttController::rangeRequest(int32_t in_cmdId,
+ const std::vector<RttConfig>& in_rttConfigs) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::rangeRequestInternal, in_cmdId, in_rttConfigs);
+}
+
+ndk::ScopedAStatus WifiRttController::rangeCancel(int32_t in_cmdId,
+ const std::vector<MacAddress>& in_addrs) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::rangeCancelInternal, in_cmdId, in_addrs);
+}
+
+ndk::ScopedAStatus WifiRttController::getCapabilities(RttCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiRttController::setLci(int32_t in_cmdId, const RttLciInformation& in_lci) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::setLciInternal, in_cmdId, in_lci);
+}
+
+ndk::ScopedAStatus WifiRttController::setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::setLcrInternal, in_cmdId, in_lcr);
+}
+
+ndk::ScopedAStatus WifiRttController::getResponderInfo(RttResponder* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::getResponderInfoInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiRttController::enableResponder(int32_t in_cmdId,
+ const WifiChannelInfo& in_channelHint,
+ int32_t in_maxDurationInSeconds,
+ const RttResponder& in_info) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::enableResponderInternal, in_cmdId, in_channelHint,
+ in_maxDurationInSeconds, in_info);
+}
+
+ndk::ScopedAStatus WifiRttController::disableResponder(int32_t in_cmdId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+ &WifiRttController::disableResponderInternal, in_cmdId);
+}
+
+std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus>
+WifiRttController::getBoundIfaceInternal() {
+ return {bound_iface_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiRttController::registerEventCallbackInternal(
+ const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
+ event_callbacks_.emplace_back(callback);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WifiRttController::rangeRequestInternal(
+ int32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
+ 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) {
+ 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;
+ }
+ std::vector<RttResult> aidl_results;
+ if (!aidl_struct_util::convertLegacyVectorOfRttResultToAidl(results,
+ &aidl_results)) {
+ LOG(ERROR) << "Failed to convert rtt results 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 callback";
+ }
+ }
+ };
+ const auto& on_results_callback_v2 =
+ [weak_ptr_this](legacy_hal::wifi_request_id id,
+ const std::vector<const legacy_hal::wifi_rtt_result_v2*>& results) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "v2 Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<RttResult> aidl_results;
+ if (!aidl_struct_util::convertLegacyVectorOfRttResultV2ToAidl(results,
+ &aidl_results)) {
+ LOG(ERROR) << "Failed to convert rtt results v2 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 v2 callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
+ ifname_, cmd_id, legacy_configs, on_results_callback, on_results_callback_v2);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiRttController::rangeCancelInternal(int32_t cmd_id,
+ const std::vector<MacAddress>& addrs) {
+ std::vector<std::array<uint8_t, ETH_ALEN>> legacy_addrs;
+ for (const auto& addr : addrs) {
+ std::array<uint8_t, ETH_ALEN> addr_array;
+ std::copy_n(addr.data.begin(), ETH_ALEN, addr_array.begin());
+ legacy_addrs.push_back(addr_array);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+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_);
+ 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()};
+}
+
+ndk::ScopedAStatus WifiRttController::setLciInternal(int32_t cmd_id, const RttLciInformation& lci) {
+ legacy_hal::wifi_lci_information legacy_lci;
+ if (!aidl_struct_util::convertAidlRttLciInformationToLegacy(lci, &legacy_lci)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiRttController::setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr) {
+ legacy_hal::wifi_lcr_information legacy_lcr;
+ if (!aidl_struct_util::convertAidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<RttResponder, ndk::ScopedAStatus> WifiRttController::getResponderInfoInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_rtt_responder legacy_responder;
+ std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {RttResponder{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ RttResponder aidl_responder;
+ if (!aidl_struct_util::convertLegacyRttResponderToAidl(legacy_responder, &aidl_responder)) {
+ return {RttResponder{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_responder, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiRttController::enableResponderInternal(int32_t cmd_id,
+ const WifiChannelInfo& channel_hint,
+ int32_t max_duration_seconds,
+ const RttResponder& info) {
+ legacy_hal::wifi_channel_info legacy_channel_info;
+ if (!aidl_struct_util::convertAidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_rtt_responder legacy_responder;
+ if (!aidl_struct_util::convertAidlRttResponderToLegacy(info, &legacy_responder)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
+ ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiRttController::disableResponderInternal(int32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_rtt_controller.h b/wifi/aidl/default/wifi_rtt_controller.h
new file mode 100644
index 0000000..db690c3
--- /dev/null
+++ b/wifi/aidl/default/wifi_rtt_controller.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_RTT_CONTROLLER_H_
+#define WIFI_RTT_CONTROLLER_H_
+
+#include <aidl/android/hardware/wifi/BnWifiRttController.h>
+#include <aidl/android/hardware/wifi/IWifiRttControllerEventCallback.h>
+#include <aidl/android/hardware/wifi/IWifiStaIface.h>
+#include <android-base/macros.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control all RTT operations.
+ */
+class WifiRttController : public BnWifiRttController {
+ public:
+ WifiRttController(const std::string& iface_name,
+ const std::shared_ptr<IWifiStaIface>& bound_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+ // Factory method - use instead of default constructor.
+ static std::shared_ptr<WifiRttController> create(
+ const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::vector<std::shared_ptr<IWifiRttControllerEventCallback>> getEventCallbacks();
+ std::string getIfaceName();
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) override;
+ ndk::ScopedAStatus registerEventCallback(
+ const std::shared_ptr<IWifiRttControllerEventCallback>& callback) override;
+ ndk::ScopedAStatus rangeRequest(int32_t in_cmdId,
+ const std::vector<RttConfig>& in_rttConfigs) override;
+ ndk::ScopedAStatus rangeCancel(int32_t in_cmdId,
+ const std::vector<MacAddress>& in_addrs) override;
+ ndk::ScopedAStatus getCapabilities(RttCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus setLci(int32_t in_cmdId, const RttLciInformation& in_lci) override;
+ ndk::ScopedAStatus setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) override;
+ ndk::ScopedAStatus getResponderInfo(RttResponder* _aidl_return) override;
+ ndk::ScopedAStatus enableResponder(int32_t in_cmdId, const WifiChannelInfo& in_channelHint,
+ int32_t in_maxDurationInSeconds,
+ const RttResponder& in_info) override;
+ ndk::ScopedAStatus disableResponder(int32_t in_cmdId) override;
+
+ private:
+ // Corresponding worker functions for the AIDL methods.
+ std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> getBoundIfaceInternal();
+ ndk::ScopedAStatus registerEventCallbackInternal(
+ const std::shared_ptr<IWifiRttControllerEventCallback>& callback);
+ ndk::ScopedAStatus rangeRequestInternal(int32_t cmd_id,
+ const std::vector<RttConfig>& rtt_configs);
+ ndk::ScopedAStatus rangeCancelInternal(int32_t cmd_id, const std::vector<MacAddress>& addrs);
+ std::pair<RttCapabilities, ndk::ScopedAStatus> getCapabilitiesInternal();
+ ndk::ScopedAStatus setLciInternal(int32_t cmd_id, const RttLciInformation& lci);
+ ndk::ScopedAStatus setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr);
+ std::pair<RttResponder, ndk::ScopedAStatus> getResponderInfoInternal();
+ ndk::ScopedAStatus enableResponderInternal(int32_t cmd_id, const WifiChannelInfo& channel_hint,
+ int32_t max_duration_seconds,
+ const RttResponder& info);
+ ndk::ScopedAStatus disableResponderInternal(int32_t cmd_id);
+
+ void setWeakPtr(std::weak_ptr<WifiRttController> ptr);
+
+ std::string ifname_;
+ std::shared_ptr<IWifiStaIface> bound_iface_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::vector<std::shared_ptr<IWifiRttControllerEventCallback>> event_callbacks_;
+ std::weak_ptr<WifiRttController> weak_ptr_this_;
+ bool is_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiRttController);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_RTT_CONTROLLER_H_
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
new file mode 100644
index 0000000..800813f
--- /dev/null
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_sta_iface.h"
+
+#include <android-base/logging.h>
+
+#include "aidl_return_util.h"
+#include "aidl_struct_util.h"
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using aidl_return_util::validateAndCall;
+
+WifiStaIface::WifiStaIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+ : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
+ // Turn on DFS channel usage for STA iface.
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable.";
+ }
+}
+
+std::shared_ptr<WifiStaIface> WifiStaIface::create(
+ const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util) {
+ std::shared_ptr<WifiStaIface> ptr =
+ ndk::SharedRefBase::make<WifiStaIface>(ifname, legacy_hal, iface_util);
+ std::weak_ptr<WifiStaIface> weak_ptr_this(ptr);
+ ptr->setWeakPtr(weak_ptr_this);
+ return ptr;
+}
+
+void WifiStaIface::invalidate() {
+ legacy_hal_.reset();
+ event_cb_handler_.invalidate();
+ is_valid_ = false;
+}
+
+void WifiStaIface::setWeakPtr(std::weak_ptr<WifiStaIface> ptr) {
+ weak_ptr_this_ = ptr;
+}
+
+bool WifiStaIface::isValid() {
+ return is_valid_;
+}
+
+std::string WifiStaIface::getName() {
+ return ifname_;
+}
+
+std::set<std::shared_ptr<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
+ return event_cb_handler_.getCallbacks();
+}
+
+ndk::ScopedAStatus WifiStaIface::getName(std::string* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getNameInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::registerEventCallback(
+ const std::shared_ptr<IWifiStaIfaceEventCallback>& in_callback) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::registerEventCallbackInternal, in_callback);
+}
+
+ndk::ScopedAStatus WifiStaIface::getFeatureSet(int32_t* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getFeatureSetInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::getApfPacketFilterCapabilities(
+ StaApfPacketFilterCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getApfPacketFilterCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::installApfPacketFilter(const std::vector<uint8_t>& in_program) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::installApfPacketFilterInternal, in_program);
+}
+
+ndk::ScopedAStatus WifiStaIface::readApfPacketFilterData(std::vector<uint8_t>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::readApfPacketFilterDataInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::getBackgroundScanCapabilities(
+ StaBackgroundScanCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getBackgroundScanCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::startBackgroundScan(int32_t in_cmdId,
+ const StaBackgroundScanParameters& in_params) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startBackgroundScanInternal, in_cmdId, in_params);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopBackgroundScan(int32_t in_cmdId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::stopBackgroundScanInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableLinkLayerStatsCollection(bool in_debug) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::enableLinkLayerStatsCollectionInternal, in_debug);
+}
+
+ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollection() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::disableLinkLayerStatsCollectionInternal);
+}
+
+ndk::ScopedAStatus WifiStaIface::getLinkLayerStats(StaLinkLayerStats* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getLinkLayerStatsInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::startRssiMonitoring(int32_t in_cmdId, int32_t in_maxRssi,
+ int32_t in_minRssi) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startRssiMonitoringInternal, in_cmdId, in_maxRssi,
+ in_minRssi);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopRssiMonitoring(int32_t in_cmdId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::stopRssiMonitoringInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiStaIface::getRoamingCapabilities(StaRoamingCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getRoamingCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::configureRoaming(const StaRoamingConfig& in_config) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::configureRoamingInternal, in_config);
+}
+
+ndk::ScopedAStatus WifiStaIface::setRoamingState(StaRoamingState in_state) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setRoamingStateInternal, in_state);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableNdOffload(bool in_enable) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::enableNdOffloadInternal, in_enable);
+}
+
+ndk::ScopedAStatus WifiStaIface::startSendingKeepAlivePackets(
+ int32_t in_cmdId, const std::vector<uint8_t>& in_ipPacketData, char16_t in_etherType,
+ const std::array<uint8_t, 6>& in_srcAddress, const std::array<uint8_t, 6>& in_dstAddress,
+ int32_t in_periodInMs) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startSendingKeepAlivePacketsInternal, in_cmdId,
+ in_ipPacketData, in_etherType, in_srcAddress, in_dstAddress,
+ in_periodInMs);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopSendingKeepAlivePackets(int32_t in_cmdId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::stopSendingKeepAlivePacketsInternal, in_cmdId);
+}
+
+ndk::ScopedAStatus WifiStaIface::startDebugPacketFateMonitoring() {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::startDebugPacketFateMonitoringInternal);
+}
+
+ndk::ScopedAStatus WifiStaIface::getDebugTxPacketFates(
+ std::vector<WifiDebugTxPacketFateReport>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getDebugTxPacketFatesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::getDebugRxPacketFates(
+ std::vector<WifiDebugRxPacketFateReport>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getDebugRxPacketFatesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::setMacAddress(const std::array<uint8_t, 6>& in_mac) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setMacAddressInternal, in_mac);
+}
+
+ndk::ScopedAStatus WifiStaIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getFactoryMacAddressInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::setScanMode(bool in_enable) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setScanModeInternal, in_enable);
+}
+
+ndk::ScopedAStatus WifiStaIface::setDtimMultiplier(int32_t in_multiplier) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::setDtimMultiplierInternal, in_multiplier);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
+ return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::registerEventCallbackInternal(
+ const std::shared_ptr<IWifiStaIfaceEventCallback>& callback) {
+ if (!event_cb_handler_.addCallback(callback)) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<int32_t, ndk::ScopedAStatus> WifiStaIface::getFeatureSetInternal() {
+ legacy_hal::wifi_error legacy_status;
+ uint64_t legacy_feature_set;
+ std::tie(legacy_status, legacy_feature_set) =
+ legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {0, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ uint32_t aidl_feature_set;
+ if (!aidl_struct_util::convertLegacyStaIfaceFeaturesToAidl(legacy_feature_set,
+ &aidl_feature_set)) {
+ return {0, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_feature_set, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<StaApfPacketFilterCapabilities, ndk::ScopedAStatus>
+WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::PacketFilterCapabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {StaApfPacketFilterCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ StaApfPacketFilterCapabilities aidl_caps;
+ if (!aidl_struct_util::convertLegacyApfCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ return {StaApfPacketFilterCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::installApfPacketFilterInternal(
+ const std::vector<uint8_t>& program) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+WifiStaIface::readApfPacketFilterDataInternal() {
+ const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data =
+ legacy_hal_.lock()->readApfPacketFilterData(ifname_);
+ return {std::move(legacy_status_and_data.second),
+ createWifiStatusFromLegacyError(legacy_status_and_data.first)};
+}
+
+std::pair<StaBackgroundScanCapabilities, ndk::ScopedAStatus>
+WifiStaIface::getBackgroundScanCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_gscan_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {StaBackgroundScanCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ StaBackgroundScanCapabilities aidl_caps;
+ if (!aidl_struct_util::convertLegacyGscanCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ return {StaBackgroundScanCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::startBackgroundScanInternal(
+ int32_t cmd_id, const StaBackgroundScanParameters& params) {
+ legacy_hal::wifi_scan_cmd_params legacy_params;
+ if (!aidl_struct_util::convertAidlGscanParamsToLegacy(params, &legacy_params)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+ const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id 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->onBackgroundScanFailure(id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback";
+ }
+ }
+ };
+ const auto& on_results_callback =
+ [weak_ptr_this](legacy_hal::wifi_request_id id,
+ const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
+ 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;
+ }
+ std::vector<StaScanData> aidl_scan_datas;
+ if (!aidl_struct_util::convertLegacyVectorOfCachedGscanResultsToAidl(
+ results, &aidl_scan_datas)) {
+ LOG(ERROR) << "Failed to convert scan results to AIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onBackgroundScanResults(id, aidl_scan_datas).isOk()) {
+ LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback";
+ }
+ }
+ };
+ const auto& on_full_result_callback = [weak_ptr_this](
+ legacy_hal::wifi_request_id id,
+ const legacy_hal::wifi_scan_result* result,
+ uint32_t buckets_scanned) {
+ 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;
+ }
+ StaScanResult aidl_scan_result;
+ if (!aidl_struct_util::convertLegacyGscanResultToAidl(*result, true, &aidl_scan_result)) {
+ LOG(ERROR) << "Failed to convert full scan results to AIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onBackgroundFullScanResult(id, buckets_scanned, aidl_scan_result)
+ .isOk()) {
+ LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback,
+ on_results_callback, on_full_result_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopBackgroundScanInternal(int32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<StaLinkLayerStats, ndk::ScopedAStatus> WifiStaIface::getLinkLayerStatsInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::LinkLayerStats legacy_stats{};
+ legacy_hal::LinkLayerMlStats legacy_ml_stats{};
+ legacy_status = legacy_hal_.lock()->getLinkLayerStats(ifname_, legacy_stats, legacy_ml_stats);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {StaLinkLayerStats{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ StaLinkLayerStats aidl_stats;
+ if (legacy_stats.valid) {
+ if (!aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &aidl_stats)) {
+ return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ } else if (legacy_ml_stats.valid) {
+ if (!aidl_struct_util::convertLegacyLinkLayerMlStatsToAidl(legacy_ml_stats, &aidl_stats)) {
+ return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ } else {
+ return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_stats, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::startRssiMonitoringInternal(int32_t cmd_id, int32_t max_rssi,
+ int32_t min_rssi) {
+ std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+ const auto& on_threshold_breached_callback =
+ [weak_ptr_this](legacy_hal::wifi_request_id id, std::array<uint8_t, ETH_ALEN> bssid,
+ int8_t rssi) {
+ 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->onRssiThresholdBreached(id, bssid, rssi).isOk()) {
+ LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring(
+ ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopRssiMonitoringInternal(int32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<StaRoamingCapabilities, ndk::ScopedAStatus>
+WifiStaIface::getRoamingCapabilitiesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ legacy_hal::wifi_roaming_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {StaRoamingCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ StaRoamingCapabilities aidl_caps;
+ if (!aidl_struct_util::convertLegacyRoamingCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ return {StaRoamingCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_caps, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) {
+ legacy_hal::wifi_roaming_config legacy_config;
+ if (!aidl_struct_util::convertAidlRoamingConfigToLegacy(config, &legacy_config)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming(
+ ifname_, aidl_struct_util::convertAidlRoamingStateToLegacy(state));
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
+ int32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, char16_t ether_type,
+ const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
+ int32_t period_in_ms) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket(
+ ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(int32_t cmd_id) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<std::vector<WifiDebugTxPacketFateReport>, ndk::ScopedAStatus>
+WifiStaIface::getDebugTxPacketFatesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_tx_report> legacy_fates;
+ std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {std::vector<WifiDebugTxPacketFateReport>(),
+ createWifiStatusFromLegacyError(legacy_status)};
+ }
+ std::vector<WifiDebugTxPacketFateReport> aidl_fates;
+ if (!aidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToAidl(legacy_fates,
+ &aidl_fates)) {
+ return {std::vector<WifiDebugTxPacketFateReport>(),
+ createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_fates, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<WifiDebugRxPacketFateReport>, ndk::ScopedAStatus>
+WifiStaIface::getDebugRxPacketFatesInternal() {
+ legacy_hal::wifi_error legacy_status;
+ std::vector<legacy_hal::wifi_rx_report> legacy_fates;
+ std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {std::vector<WifiDebugRxPacketFateReport>(),
+ createWifiStatusFromLegacyError(legacy_status)};
+ }
+ std::vector<WifiDebugRxPacketFateReport> aidl_fates;
+ if (!aidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToAidl(legacy_fates,
+ &aidl_fates)) {
+ return {std::vector<WifiDebugRxPacketFateReport>(),
+ createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_fates, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+ bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
+ if (!status) {
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> WifiStaIface::getFactoryMacAddressInternal() {
+ std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_);
+ if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+ return {mac, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {mac, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::setScanModeInternal(bool enable) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setScanMode(ifname_, enable);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::setDtimMultiplierInternal(const int multiplier) {
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDtimConfig(ifname_, multiplier);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_sta_iface.h b/wifi/aidl/default/wifi_sta_iface.h
new file mode 100644
index 0000000..3d7ec4d
--- /dev/null
+++ b/wifi/aidl/default/wifi_sta_iface.h
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_STA_IFACE_H_
+#define WIFI_STA_IFACE_H_
+
+#include <aidl/android/hardware/wifi/BnWifiStaIface.h>
+#include <aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.h>
+#include <android-base/macros.h>
+
+#include "aidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+/**
+ * AIDL interface object used to control a STA Iface instance.
+ */
+class WifiStaIface : public BnWifiStaIface {
+ public:
+ WifiStaIface(const std::string& ifname,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+ // Factory method - use instead of default constructor.
+ static std::shared_ptr<WifiStaIface> create(
+ const std::string& ifname, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+ const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+
+ // Refer to |WifiChip::invalidate()|.
+ void invalidate();
+ bool isValid();
+ std::set<std::shared_ptr<IWifiStaIfaceEventCallback>> getEventCallbacks();
+ std::string getName();
+
+ // AIDL methods exposed.
+ ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+ ndk::ScopedAStatus registerEventCallback(
+ const std::shared_ptr<IWifiStaIfaceEventCallback>& in_callback) override;
+ ndk::ScopedAStatus getFeatureSet(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getApfPacketFilterCapabilities(
+ StaApfPacketFilterCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus installApfPacketFilter(const std::vector<uint8_t>& in_program) override;
+ ndk::ScopedAStatus readApfPacketFilterData(std::vector<uint8_t>* _aidl_return) override;
+ ndk::ScopedAStatus getBackgroundScanCapabilities(
+ StaBackgroundScanCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus startBackgroundScan(int32_t in_cmdId,
+ const StaBackgroundScanParameters& in_params) override;
+ ndk::ScopedAStatus stopBackgroundScan(int32_t in_cmdId) override;
+ ndk::ScopedAStatus enableLinkLayerStatsCollection(bool in_debug) override;
+ ndk::ScopedAStatus disableLinkLayerStatsCollection() override;
+ ndk::ScopedAStatus getLinkLayerStats(StaLinkLayerStats* _aidl_return) override;
+ ndk::ScopedAStatus startRssiMonitoring(int32_t in_cmdId, int32_t in_maxRssi,
+ int32_t in_minRssi) override;
+ ndk::ScopedAStatus stopRssiMonitoring(int32_t in_cmdId) override;
+ ndk::ScopedAStatus getRoamingCapabilities(StaRoamingCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus configureRoaming(const StaRoamingConfig& in_config) override;
+ ndk::ScopedAStatus setRoamingState(StaRoamingState in_state) override;
+ ndk::ScopedAStatus enableNdOffload(bool in_enable) override;
+ ndk::ScopedAStatus startSendingKeepAlivePackets(int32_t in_cmdId,
+ const std::vector<uint8_t>& in_ipPacketData,
+ char16_t in_etherType,
+ const std::array<uint8_t, 6>& in_srcAddress,
+ const std::array<uint8_t, 6>& in_dstAddress,
+ int32_t in_periodInMs) override;
+ ndk::ScopedAStatus stopSendingKeepAlivePackets(int32_t in_cmdId) override;
+ ndk::ScopedAStatus startDebugPacketFateMonitoring() override;
+ ndk::ScopedAStatus getDebugTxPacketFates(
+ std::vector<WifiDebugTxPacketFateReport>* _aidl_return) override;
+ ndk::ScopedAStatus getDebugRxPacketFates(
+ std::vector<WifiDebugRxPacketFateReport>* _aidl_return) override;
+ ndk::ScopedAStatus setMacAddress(const std::array<uint8_t, 6>& in_mac) override;
+ 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;
+
+ private:
+ // Corresponding worker functions for the AIDL methods.
+ std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+ ndk::ScopedAStatus registerEventCallbackInternal(
+ const std::shared_ptr<IWifiStaIfaceEventCallback>& callback);
+ std::pair<int32_t, ndk::ScopedAStatus> getFeatureSetInternal();
+ std::pair<StaApfPacketFilterCapabilities, ndk::ScopedAStatus>
+ getApfPacketFilterCapabilitiesInternal();
+ ndk::ScopedAStatus installApfPacketFilterInternal(const std::vector<uint8_t>& program);
+ std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> readApfPacketFilterDataInternal();
+ std::pair<StaBackgroundScanCapabilities, ndk::ScopedAStatus>
+ getBackgroundScanCapabilitiesInternal();
+ ndk::ScopedAStatus startBackgroundScanInternal(int32_t cmd_id,
+ const StaBackgroundScanParameters& params);
+ ndk::ScopedAStatus stopBackgroundScanInternal(int32_t cmd_id);
+ ndk::ScopedAStatus enableLinkLayerStatsCollectionInternal(bool debug);
+ ndk::ScopedAStatus disableLinkLayerStatsCollectionInternal();
+ std::pair<StaLinkLayerStats, ndk::ScopedAStatus> getLinkLayerStatsInternal();
+ ndk::ScopedAStatus startRssiMonitoringInternal(int32_t cmd_id, int32_t max_rssi,
+ int32_t min_rssi);
+ ndk::ScopedAStatus stopRssiMonitoringInternal(int32_t cmd_id);
+ std::pair<StaRoamingCapabilities, ndk::ScopedAStatus> getRoamingCapabilitiesInternal();
+ ndk::ScopedAStatus configureRoamingInternal(const StaRoamingConfig& config);
+ ndk::ScopedAStatus setRoamingStateInternal(StaRoamingState state);
+ ndk::ScopedAStatus enableNdOffloadInternal(bool enable);
+ ndk::ScopedAStatus startSendingKeepAlivePacketsInternal(
+ int32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, char16_t ether_type,
+ const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
+ int32_t period_in_ms);
+ ndk::ScopedAStatus stopSendingKeepAlivePacketsInternal(int32_t cmd_id);
+ ndk::ScopedAStatus startDebugPacketFateMonitoringInternal();
+ std::pair<std::vector<WifiDebugTxPacketFateReport>, ndk::ScopedAStatus>
+ getDebugTxPacketFatesInternal();
+ std::pair<std::vector<WifiDebugRxPacketFateReport>, ndk::ScopedAStatus>
+ getDebugRxPacketFatesInternal();
+ ndk::ScopedAStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+ std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
+ ndk::ScopedAStatus setScanModeInternal(bool enable);
+ ndk::ScopedAStatus setDtimMultiplierInternal(const int multiplier);
+
+ void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);
+
+ std::string ifname_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+ std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ std::weak_ptr<WifiStaIface> weak_ptr_this_;
+ bool is_valid_;
+ aidl_callback_util::AidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
+};
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_STA_IFACE_H_
diff --git a/wifi/aidl/default/wifi_status_util.cpp b/wifi/aidl/default/wifi_status_util.cpp
new file mode 100644
index 0000000..25ecd71
--- /dev/null
+++ b/wifi/aidl/default/wifi_status_util.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_status_util.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+
+std::string legacyErrorToString(legacy_hal::wifi_error error) {
+ switch (error) {
+ case legacy_hal::WIFI_SUCCESS:
+ return "SUCCESS";
+ case legacy_hal::WIFI_ERROR_UNINITIALIZED:
+ return "UNINITIALIZED";
+ case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
+ return "NOT_AVAILABLE";
+ case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
+ return "NOT_SUPPORTED";
+ case legacy_hal::WIFI_ERROR_INVALID_ARGS:
+ return "INVALID_ARGS";
+ case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
+ return "INVALID_REQUEST_ID";
+ case legacy_hal::WIFI_ERROR_TIMED_OUT:
+ return "TIMED_OUT";
+ case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
+ return "TOO_MANY_REQUESTS";
+ case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case legacy_hal::WIFI_ERROR_BUSY:
+ return "BUSY";
+ case legacy_hal::WIFI_ERROR_UNKNOWN:
+ return "UNKNOWN";
+ default:
+ return "UNKNOWN ERROR";
+ }
+}
+
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code, const std::string& description) {
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(static_cast<int32_t>(code),
+ description.c_str());
+}
+
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(code));
+}
+
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
+ const std::string& desc) {
+ switch (error) {
+ case legacy_hal::WIFI_ERROR_NONE:
+ return ndk::ScopedAStatus::ok();
+
+ case legacy_hal::WIFI_ERROR_UNINITIALIZED:
+ case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, desc);
+
+ case legacy_hal::WIFI_ERROR_NOT_SUPPORTED:
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED, desc);
+
+ case legacy_hal::WIFI_ERROR_INVALID_ARGS:
+ case legacy_hal::WIFI_ERROR_INVALID_REQUEST_ID:
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc);
+
+ case legacy_hal::WIFI_ERROR_TIMED_OUT:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out");
+
+ case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests");
+
+ case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory");
+
+ case legacy_hal::WIFI_ERROR_BUSY:
+ return createWifiStatus(WifiStatusCode::ERROR_BUSY);
+
+ case legacy_hal::WIFI_ERROR_UNKNOWN:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
+
+ default:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error");
+ }
+}
+
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) {
+ return createWifiStatusFromLegacyError(error, "");
+}
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/wifi/aidl/default/wifi_status_util.h b/wifi/aidl/default/wifi_status_util.h
new file mode 100644
index 0000000..633811d
--- /dev/null
+++ b/wifi/aidl/default/wifi_status_util.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFI_STATUS_UTIL_H_
+#define WIFI_STATUS_UTIL_H_
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+using ::aidl::android::hardware::wifi::WifiStatusCode;
+
+std::string legacyErrorToString(legacy_hal::wifi_error error);
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code, const std::string& description);
+ndk::ScopedAStatus createWifiStatus(WifiStatusCode code);
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
+ const std::string& description);
+ndk::ScopedAStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
+
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // WIFI_STATUS_UTIL_H_
diff --git a/wifi/aidl/vts/functional/Android.bp b/wifi/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..1277182
--- /dev/null
+++ b/wifi/aidl/vts/functional/Android.bp
@@ -0,0 +1,169 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalWifiChipTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "wifi_chip_aidl_test.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "VtsHalWifiTargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_test {
+ name: "VtsHalWifiStaIfaceTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "wifi_sta_iface_aidl_test.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "VtsHalWifiTargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_test {
+ name: "VtsHalWifiApIfaceTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "wifi_ap_iface_aidl_test.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "VtsHalWifiTargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_test {
+ name: "VtsHalWifiNanIfaceTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "wifi_nan_iface_aidl_test.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "VtsHalWifiTargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_test {
+ name: "VtsHalWifiRttControllerTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "wifi_rtt_controller_aidl_test.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "VtsHalWifiTargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
+
+cc_library_static {
+ name: "VtsHalWifiTargetTestUtil",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "wifi_aidl_test_utils.cpp",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbinder_ndk",
+ "libnativehelper",
+ ],
+ static_libs: [
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ ],
+}
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
new file mode 100644
index 0000000..ca3c4b7
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_aidl_test_utils.h"
+
+using ::android::wifi_system::InterfaceTool;
+
+namespace {
+bool findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,
+ const std::vector<IWifiChip::ChipMode>& modes,
+ int* mode_id) {
+ for (const auto& mode : modes) {
+ for (const auto& combination : mode.availableCombinations) {
+ for (const auto& iface_limit : combination.limits) {
+ const auto& iface_types = iface_limit.types;
+ if (std::find(iface_types.begin(), iface_types.end(), desired_type) !=
+ iface_types.end()) {
+ *mode_id = mode.id;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
+ IfaceConcurrencyType type,
+ int* configured_mode_id) {
+ if (!configured_mode_id) {
+ return false;
+ }
+ std::vector<IWifiChip::ChipMode> chip_modes;
+ auto status = wifi_chip->getAvailableModes(&chip_modes);
+ if (!status.isOk()) {
+ return false;
+ }
+ if (!findAnyModeSupportingConcurrencyType(type, chip_modes, configured_mode_id)) {
+ return false;
+ }
+ if (!wifi_chip->configureChip(*configured_mode_id).isOk()) {
+ return false;
+ }
+ return true;
+}
+
+bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
+ IfaceConcurrencyType type) {
+ int mode_id;
+ return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, &mode_id);
+}
+} // namespace
+
+bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code) {
+ if (status == nullptr) {
+ return false;
+ }
+ return status->getServiceSpecificError() == static_cast<int32_t>(expected_code);
+}
+
+std::shared_ptr<IWifi> getWifi(const char* instance_name) {
+ return IWifi::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(instance_name)));
+}
+
+std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name) {
+ std::shared_ptr<IWifi> wifi = getWifi(instance_name);
+ if (!wifi.get()) {
+ return nullptr;
+ }
+
+ const int retry_interval_ms = 2;
+ const int max_retries = 5;
+ int retry_count = 0;
+ auto status = wifi->start();
+ while (retry_count < max_retries && !status.isOk()) {
+ retry_count++;
+ usleep(retry_interval_ms * 1000);
+ status = wifi->start();
+ }
+ if (!status.isOk()) {
+ return nullptr;
+ }
+
+ std::vector<int> chip_ids = {};
+ status = wifi->getChipIds(&chip_ids);
+ if (!status.isOk() || chip_ids.size() == 0) {
+ return nullptr;
+ }
+ std::shared_ptr<IWifiChip> chip;
+ status = wifi->getChip(chip_ids[0], &chip);
+ if (!status.isOk()) {
+ return nullptr;
+ }
+ return chip;
+}
+
+void setupStaIface(const std::shared_ptr<IWifiStaIface>& iface) {
+ std::string iface_name;
+ auto status = iface->getName(&iface_name);
+ if (status.isOk()) {
+ InterfaceTool iface_tool;
+ iface_tool.SetUpState(iface_name.c_str(), true);
+ }
+}
+
+void setupNanIface(const std::shared_ptr<IWifiNanIface>& iface) {
+ std::string iface_name;
+ auto status = iface->getName(&iface_name);
+ if (status.isOk()) {
+ InterfaceTool iface_tool;
+ iface_tool.SetUpState(iface_name.c_str(), true);
+ }
+}
+
+std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::STA)) {
+ return nullptr;
+ }
+ std::shared_ptr<IWifiStaIface> iface;
+ auto status = wifi_chip->createStaIface(&iface);
+ if (!status.isOk()) {
+ return nullptr;
+ }
+ setupStaIface(iface);
+ return iface;
+}
+
+std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip,
+ IfaceConcurrencyType::NAN_IFACE)) {
+ return nullptr;
+ }
+ std::shared_ptr<IWifiNanIface> iface;
+ auto status = wifi_chip->createNanIface(&iface);
+ if (!status.isOk()) {
+ return nullptr;
+ }
+ setupNanIface(iface);
+ return iface;
+}
+
+std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP)) {
+ return nullptr;
+ }
+ std::shared_ptr<IWifiApIface> iface;
+ auto status = wifi_chip->createApIface(&iface);
+ if (!status.isOk()) {
+ return nullptr;
+ }
+ return iface;
+}
+
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
+ if (!wifi_chip.get()) {
+ return nullptr;
+ }
+ int mode_id;
+ std::shared_ptr<IWifiApIface> iface;
+ configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP, &mode_id);
+ auto status = wifi_chip->createBridgedApIface(&iface);
+ if (!status.isOk()) {
+ return nullptr;
+ }
+ return iface;
+}
+
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+ return getBridgedWifiApIface(wifi_chip);
+}
+
+bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
+ IfaceConcurrencyType type, int* configured_mode_id) {
+ return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, configured_mode_id);
+}
+
+void stopWifiService(const char* instance_name) {
+ std::shared_ptr<IWifi> wifi = getWifi(instance_name);
+ if (wifi != nullptr) {
+ wifi->stop();
+ }
+}
+
+int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip) {
+ int32_t features = 0;
+ if (wifi_chip->getFeatureSet(&features).isOk()) {
+ return features;
+ }
+ return 0;
+}
+
+bool isAidlServiceAvailable(const char* instance_name) {
+ return AServiceManager_isDeclared(instance_name);
+}
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.h b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
new file mode 100644
index 0000000..0d70c3b
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VtsCoreUtil.h>
+
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <aidl/android/hardware/wifi/IWifiChip.h>
+#include <android/binder_manager.h>
+#include <wifi_system/interface_tool.h>
+
+using aidl::android::hardware::wifi::IfaceConcurrencyType;
+using aidl::android::hardware::wifi::IWifi;
+using aidl::android::hardware::wifi::IWifiApIface;
+using aidl::android::hardware::wifi::IWifiChip;
+using aidl::android::hardware::wifi::IWifiNanIface;
+using aidl::android::hardware::wifi::IWifiStaIface;
+using aidl::android::hardware::wifi::WifiStatusCode;
+
+// Helper functions to obtain references to the various AIDL interface objects.
+std::shared_ptr<IWifi> getWifi(const char* instance_name);
+std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name);
+std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name);
+std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
+// Configure the chip in a mode to support the creation of the provided iface type.
+bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
+ IfaceConcurrencyType type, int* configured_mode_id);
+// Used to trigger IWifi.stop() at the end of every test.
+void stopWifiService(const char* instance_name);
+int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip);
+bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code);
+bool isAidlServiceAvailable(const char* instance_name);
diff --git a/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
new file mode 100644
index 0000000..d39cfb4
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::IWifiApIface;
+using aidl::android::hardware::wifi::WifiBand;
+
+class WifiApIfaceAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ isBridgedSupport_ = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
+ stopWifiService(getInstanceName());
+ }
+
+ void TearDown() override { stopWifiService(getInstanceName()); }
+
+ protected:
+ bool isBridgedSupport_ = false;
+ const char* getInstanceName() { return GetParam().c_str(); }
+};
+
+/*
+ * SetMacAddress
+ */
+TEST_P(WifiApIfaceAidlTest, SetMacAddress) {
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+ std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x44};
+ EXPECT_TRUE(wifi_ap_iface->setMacAddress(mac).isOk());
+}
+
+/*
+ * SetCountryCode
+ */
+TEST_P(WifiApIfaceAidlTest, SetCountryCode) {
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ const std::array<uint8_t, 2> country_code = {0x55, 0x53};
+ EXPECT_TRUE(wifi_ap_iface->setCountryCode(country_code).isOk());
+}
+
+/*
+ * GetFactoryMacAddress
+ */
+TEST_P(WifiApIfaceAidlTest, GetFactoryMacAddress) {
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ std::array<uint8_t, 6> mac;
+ EXPECT_TRUE(wifi_ap_iface->getFactoryMacAddress(&mac).isOk());
+ std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
+ EXPECT_NE(mac, all_zero_mac);
+}
+
+/**
+ * GetBridgedInstances - non-bridged mode
+ */
+TEST_P(WifiApIfaceAidlTest, GetBridgedInstances) {
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ std::vector<std::string> instances;
+ EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+ EXPECT_EQ(instances.size(), 0);
+}
+
+/**
+ * GetBridgedInstances - bridged AP mode.
+ */
+TEST_P(WifiApIfaceAidlTest, GetBridgedInstances_Bridged) {
+ if (!isBridgedSupport_) {
+ GTEST_SKIP() << "Missing Bridged AP support";
+ }
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ std::vector<std::string> instances;
+ EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+ EXPECT_EQ(instances.size(), 2);
+}
+
+/**
+ * ResetToFactoryMacAddress - non-bridged mode
+ */
+TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress) {
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+ EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
+}
+
+/**
+ * ResetToFactoryMacAddress - bridged AP mode
+ */
+TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress_Bridged) {
+ if (!isBridgedSupport_) {
+ GTEST_SKIP() << "Missing Bridged AP support";
+ }
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+ EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiApIfaceAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ android::ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
new file mode 100644
index 0000000..ca88d8e
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
@@ -0,0 +1,857 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <numeric>
+#include <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiChipEventCallback.h>
+#include <aidl/android/hardware/wifi/WifiIfaceMode.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::BnWifiChipEventCallback;
+using aidl::android::hardware::wifi::IfaceType;
+using aidl::android::hardware::wifi::IWifiApIface;
+using aidl::android::hardware::wifi::IWifiChip;
+using aidl::android::hardware::wifi::IWifiNanIface;
+using aidl::android::hardware::wifi::IWifiP2pIface;
+using aidl::android::hardware::wifi::IWifiRttController;
+using aidl::android::hardware::wifi::WifiBand;
+using aidl::android::hardware::wifi::WifiDebugHostWakeReasonStats;
+using aidl::android::hardware::wifi::WifiDebugRingBufferStatus;
+using aidl::android::hardware::wifi::WifiDebugRingBufferVerboseLevel;
+using aidl::android::hardware::wifi::WifiIfaceMode;
+using aidl::android::hardware::wifi::WifiRadioCombination;
+using aidl::android::hardware::wifi::WifiStatusCode;
+using aidl::android::hardware::wifi::WifiUsableChannel;
+
+class WifiChipAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ stopWifiService(getInstanceName());
+ wifi_chip_ = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip_.get());
+ }
+
+ void TearDown() override { stopWifiService(getInstanceName()); }
+
+ protected:
+ int configureChipForConcurrencyType(IfaceConcurrencyType type) {
+ int mode_id;
+ EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip_, type, &mode_id));
+ return mode_id;
+ }
+
+ std::shared_ptr<IWifiStaIface> configureChipForStaAndGetIface() {
+ std::shared_ptr<IWifiStaIface> iface;
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ EXPECT_TRUE(wifi_chip_->createStaIface(&iface).isOk());
+ EXPECT_NE(nullptr, iface.get());
+ return iface;
+ }
+
+ std::shared_ptr<IWifiP2pIface> configureChipForP2pAndGetIface() {
+ std::shared_ptr<IWifiP2pIface> iface;
+ configureChipForConcurrencyType(IfaceConcurrencyType::P2P);
+ EXPECT_TRUE(wifi_chip_->createP2pIface(&iface).isOk());
+ EXPECT_NE(nullptr, iface.get());
+ return iface;
+ }
+
+ std::shared_ptr<IWifiApIface> configureChipForApAndGetIface() {
+ std::shared_ptr<IWifiApIface> iface;
+ configureChipForConcurrencyType(IfaceConcurrencyType::AP);
+ EXPECT_TRUE(wifi_chip_->createApIface(&iface).isOk());
+ EXPECT_NE(nullptr, iface.get());
+ return iface;
+ }
+
+ std::shared_ptr<IWifiNanIface> configureChipForNanAndGetIface() {
+ std::shared_ptr<IWifiNanIface> iface;
+ configureChipForConcurrencyType(IfaceConcurrencyType::NAN_IFACE);
+ EXPECT_TRUE(wifi_chip_->createNanIface(&iface).isOk());
+ EXPECT_NE(nullptr, iface.get());
+ return iface;
+ }
+
+ std::string getStaIfaceName(const std::shared_ptr<IWifiStaIface>& iface) {
+ std::string iface_name;
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ return iface_name;
+ }
+
+ std::string getP2pIfaceName(const std::shared_ptr<IWifiP2pIface>& iface) {
+ std::string iface_name;
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ return iface_name;
+ }
+
+ std::string getApIfaceName(const std::shared_ptr<IWifiApIface>& iface) {
+ std::string iface_name;
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ return iface_name;
+ }
+
+ std::string getNanIfaceName(const std::shared_ptr<IWifiNanIface>& iface) {
+ std::string iface_name;
+ EXPECT_TRUE(iface->getName(&iface_name).isOk());
+ return iface_name;
+ }
+
+ std::vector<std::shared_ptr<IWifiStaIface>> create2StaIfacesIfPossible() {
+ std::shared_ptr<IWifiStaIface> iface1 = configureChipForStaAndGetIface();
+
+ // Try create a create second iface.
+ std::shared_ptr<IWifiStaIface> iface2;
+ bool add_second_success = wifi_chip_->createStaIface(&iface2).isOk();
+ if (!add_second_success) {
+ return {iface1};
+ }
+ EXPECT_NE(nullptr, iface2.get());
+ return {iface1, iface2};
+ }
+
+ const char* getInstanceName() { return GetParam().c_str(); }
+
+ std::shared_ptr<IWifiChip> wifi_chip_;
+};
+
+class WifiChipEventCallback : public BnWifiChipEventCallback {
+ public:
+ WifiChipEventCallback() = default;
+
+ ::ndk::ScopedAStatus onChipReconfigureFailure(WifiStatusCode /* status */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onChipReconfigured(int /* modeId */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onDebugErrorAlert(int /* errorCode */,
+ const std::vector<uint8_t>& /* debugData */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onDebugRingBufferDataAvailable(
+ const WifiDebugRingBufferStatus& /* status */,
+ const std::vector<uint8_t>& /* data */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onIfaceAdded(IfaceType /* type */,
+ const std::string& /* name */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onIfaceRemoved(IfaceType /* type */,
+ const std::string& /* name */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onRadioModeChange(
+ const std::vector<RadioModeInfo>& /* radioModeInfos */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+/*
+ * RegisterEventCallback
+ *
+ * Note: it is not feasible to test the invocation of the callback function,
+ * since events are triggered internally in the HAL implementation and cannot be
+ * triggered from the test case.
+ */
+TEST_P(WifiChipAidlTest, RegisterEventCallback) {
+ std::shared_ptr<WifiChipEventCallback> callback =
+ ndk::SharedRefBase::make<WifiChipEventCallback>();
+ ASSERT_NE(nullptr, callback.get());
+ EXPECT_TRUE(wifi_chip_->registerEventCallback(callback).isOk());
+}
+
+/*
+ * GetFeatureSet
+ */
+TEST_P(WifiChipAidlTest, GetFeatureSet) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ EXPECT_NE(features, 0);
+}
+
+/*
+ * GetId
+ */
+TEST_P(WifiChipAidlTest, GetId) {
+ int id;
+ EXPECT_TRUE(wifi_chip_->getId(&id).isOk());
+}
+
+/*
+ * GetAvailableModes
+ */
+TEST_P(WifiChipAidlTest, GetAvailableModes) {
+ std::vector<IWifiChip::ChipMode> modes;
+ EXPECT_TRUE(wifi_chip_->getAvailableModes(&modes).isOk());
+ EXPECT_NE(modes.size(), 0);
+}
+
+/*
+ * GetMode
+ */
+TEST_P(WifiChipAidlTest, GetMode) {
+ int expected_mode = configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int retrieved_mode;
+ EXPECT_TRUE(wifi_chip_->getMode(&retrieved_mode).isOk());
+ EXPECT_EQ(retrieved_mode, expected_mode);
+}
+
+/*
+ * GetUsableChannels
+ */
+TEST_P(WifiChipAidlTest, GetUsableChannels) {
+ WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
+ uint32_t ifaceModeMask = static_cast<uint32_t>(WifiIfaceMode::IFACE_MODE_P2P_CLIENT) |
+ static_cast<uint32_t>(WifiIfaceMode::IFACE_MODE_P2P_GO);
+ uint32_t filterMask =
+ static_cast<uint32_t>(IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) |
+ static_cast<uint32_t>(IWifiChip::UsableChannelFilter::CONCURRENCY);
+
+ std::vector<WifiUsableChannel> channels;
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ auto status = wifi_chip_->getUsableChannels(band, ifaceModeMask, filterMask, &channels);
+ if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ GTEST_SKIP() << "getUsableChannels() is not supported by vendor.";
+ }
+ EXPECT_TRUE(status.isOk());
+}
+
+/*
+ * GetSupportedRadioCombinations
+ */
+TEST_P(WifiChipAidlTest, GetSupportedRadioCombinations) {
+ std::vector<WifiRadioCombination> combinations;
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ auto status = wifi_chip_->getSupportedRadioCombinations(&combinations);
+ if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ GTEST_SKIP() << "Skipping this test since getSupportedRadioCombinations() "
+ "is not supported by vendor.";
+ }
+ EXPECT_TRUE(status.isOk());
+}
+
+/*
+ * SetCountryCode
+ */
+TEST_P(WifiChipAidlTest, SetCountryCode) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ std::array<uint8_t, 2> country_code = {0x55, 0x53};
+ EXPECT_TRUE(wifi_chip_->setCountryCode(country_code).isOk());
+}
+
+/*
+ * SetLatencyMode_normal
+ * Tests the setLatencyMode() API with Latency mode NORMAL.
+ */
+TEST_P(WifiChipAidlTest, SetLatencyMode_normal) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ auto status = wifi_chip_->setLatencyMode(IWifiChip::LatencyMode::NORMAL);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_LATENCY_MODE)) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * SetLatencyMode_low
+ * Tests the setLatencyMode() API with Latency mode LOW.
+ */
+TEST_P(WifiChipAidlTest, SetLatencyMode_low) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ auto status = wifi_chip_->setLatencyMode(IWifiChip::LatencyMode::LOW);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_LATENCY_MODE)) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * SetMultiStaPrimaryConnection
+ *
+ * Only runs if the device supports 2 STA ifaces.
+ */
+TEST_P(WifiChipAidlTest, SetMultiStaPrimaryConnection) {
+ auto ifaces = create2StaIfacesIfPossible();
+ if (ifaces.size() < 2) {
+ GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
+ }
+
+ auto status = wifi_chip_->setMultiStaPrimaryConnection(getStaIfaceName(ifaces[0]));
+ if (!status.isOk()) {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * SetMultiStaUseCase
+ *
+ * Only runs if the device supports 2 STA ifaces.
+ */
+TEST_P(WifiChipAidlTest, setMultiStaUseCase) {
+ auto ifaces = create2StaIfacesIfPossible();
+ if (ifaces.size() < 2) {
+ GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
+ }
+
+ auto status = wifi_chip_->setMultiStaUseCase(
+ IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY);
+ if (!status.isOk()) {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * SetCoexUnsafeChannels
+ */
+TEST_P(WifiChipAidlTest, SetCoexUnsafeChannels) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+
+ // Test with an empty vector of CoexUnsafeChannels.
+ std::vector<IWifiChip::CoexUnsafeChannel> vec;
+ int restrictions = 0;
+ auto status = wifi_chip_->setCoexUnsafeChannels(vec, restrictions);
+ if (!status.isOk()) {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+
+ // Test with a non-empty vector of CoexUnsafeChannels.
+ IWifiChip::CoexUnsafeChannel unsafeChannel24Ghz;
+ unsafeChannel24Ghz.band = WifiBand::BAND_24GHZ;
+ unsafeChannel24Ghz.channel = 6;
+ vec.push_back(unsafeChannel24Ghz);
+ IWifiChip::CoexUnsafeChannel unsafeChannel5Ghz;
+ unsafeChannel5Ghz.band = WifiBand::BAND_5GHZ;
+ unsafeChannel5Ghz.channel = 36;
+ vec.push_back(unsafeChannel5Ghz);
+ restrictions = static_cast<int32_t>(IWifiChip::CoexRestriction::WIFI_AWARE) |
+ static_cast<int32_t>(IWifiChip::CoexRestriction::SOFTAP) |
+ static_cast<int32_t>(IWifiChip::CoexRestriction::WIFI_DIRECT);
+
+ status = wifi_chip_->setCoexUnsafeChannels(vec, restrictions);
+ if (!status.isOk()) {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * SelectTxPowerScenario - Body
+ */
+TEST_P(WifiChipAidlTest, SelectTxPowerScenario_body) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ int32_t expected_features =
+ static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT) |
+ static_cast<int32_t>(IWifiChip::FeatureSetMask::USE_BODY_HEAD_SAR);
+ auto status = wifi_chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::ON_BODY_CELL_OFF);
+ if (features & expected_features) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * SelectTxPowerScenario - Voice Call
+ */
+TEST_P(WifiChipAidlTest, SelectTxPowerScenario_voiceCall) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ auto status = wifi_chip_->selectTxPowerScenario(IWifiChip::TxPowerScenario::VOICE_CALL);
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT)) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * ResetTxPowerScenario
+ */
+TEST_P(WifiChipAidlTest, ResetTxPowerScenario) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ int32_t features = getChipFeatureSet(wifi_chip_);
+ auto status = wifi_chip_->resetTxPowerScenario();
+ if (features & static_cast<int32_t>(IWifiChip::FeatureSetMask::SET_TX_POWER_LIMIT)) {
+ EXPECT_TRUE(status.isOk());
+ } else {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/*
+ * ConfigureChip
+ */
+TEST_P(WifiChipAidlTest, ConfigureChip) {
+ std::vector<IWifiChip::ChipMode> modes;
+ EXPECT_TRUE(wifi_chip_->getAvailableModes(&modes).isOk());
+ EXPECT_NE(modes.size(), 0);
+ for (const auto& mode : modes) {
+ // configureChip() requires a fresh IWifiChip object.
+ wifi_chip_ = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip_.get());
+ EXPECT_TRUE(wifi_chip_->configureChip(mode.id).isOk());
+ stopWifiService(getInstanceName());
+ // Sleep for 5 milliseconds between each wifi state toggle.
+ usleep(5000);
+ }
+}
+
+/*
+ * RequestChipDebugInfo
+ */
+TEST_P(WifiChipAidlTest, RequestChipDebugInfo) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ IWifiChip::ChipDebugInfo debug_info = {};
+ EXPECT_TRUE(wifi_chip_->requestChipDebugInfo(&debug_info).isOk());
+ EXPECT_NE(debug_info.driverDescription.size(), 0);
+ EXPECT_NE(debug_info.firmwareDescription.size(), 0);
+}
+
+/*
+ * RequestFirmwareDebugDump
+ */
+TEST_P(WifiChipAidlTest, RequestFirmwareDebugDump) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ std::vector<uint8_t> debug_dump;
+ auto status = wifi_chip_->requestFirmwareDebugDump(&debug_dump);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * RequestDriverDebugDump
+ */
+TEST_P(WifiChipAidlTest, RequestDriverDebugDump) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ std::vector<uint8_t> debug_dump;
+ auto status = wifi_chip_->requestDriverDebugDump(&debug_dump);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * GetDebugRingBuffersStatus
+ */
+TEST_P(WifiChipAidlTest, GetDebugRingBuffersStatus) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
+ auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ if (status.isOk()) {
+ ASSERT_NE(ring_buffer_status.size(), 0);
+ for (const auto& ring_buffer : ring_buffer_status) {
+ EXPECT_NE(ring_buffer.ringName.size(), 0);
+ }
+ }
+}
+
+/*
+ * GetDebugHostWakeReasonStats
+ */
+TEST_P(WifiChipAidlTest, GetDebugHostWakeReasonStats) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ WifiDebugHostWakeReasonStats wake_reason_stats = {};
+ auto status = wifi_chip_->getDebugHostWakeReasonStats(&wake_reason_stats);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * StartLoggingToDebugRingBuffer
+ */
+TEST_P(WifiChipAidlTest, StartLoggingToDebugRingBuffer) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ std::string ring_name;
+ std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
+
+ auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ if (status.isOk()) {
+ ASSERT_NE(ring_buffer_status.size(), 0);
+ ring_name = ring_buffer_status[0].ringName;
+ }
+
+ status = wifi_chip_->startLoggingToDebugRingBuffer(
+ ring_name, WifiDebugRingBufferVerboseLevel::VERBOSE, 5, 1024);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * ForceDumpToDebugRingBuffer
+ */
+TEST_P(WifiChipAidlTest, ForceDumpToDebugRingBuffer) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+ std::string ring_name;
+ std::vector<WifiDebugRingBufferStatus> ring_buffer_status;
+
+ auto status = wifi_chip_->getDebugRingBuffersStatus(&ring_buffer_status);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ if (status.isOk()) {
+ ASSERT_NE(ring_buffer_status.size(), 0);
+ ring_name = ring_buffer_status[0].ringName;
+ }
+
+ status = wifi_chip_->forceDumpToDebugRingBuffer(ring_name);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * CreateStaIface
+ * Configures the chip in STA mode and creates an iface.
+ */
+TEST_P(WifiChipAidlTest, CreateStaIface) {
+ configureChipForStaAndGetIface();
+}
+
+/*
+ * CreateApIface
+ */
+TEST_P(WifiChipAidlTest, CreateApIface) {
+ configureChipForApAndGetIface();
+}
+
+/*
+ * CreateNanIface
+ */
+TEST_P(WifiChipAidlTest, CreateNanIface) {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+ GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+ }
+ configureChipForNanAndGetIface();
+}
+
+/*
+ * CreateP2pIface
+ */
+TEST_P(WifiChipAidlTest, CreateP2pIface) {
+ configureChipForP2pAndGetIface();
+}
+
+/*
+ * GetStaIfaceNames
+ * Configures the chip in STA mode and ensures that the iface name list is
+ * empty before creating the iface. Then create the iface and ensure that
+ * iface name is returned in the iface name list.
+ */
+TEST_P(WifiChipAidlTest, GetStaIfaceNames) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::STA);
+
+ std::vector<std::string> iface_names;
+ EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+
+ std::shared_ptr<IWifiStaIface> iface;
+ EXPECT_TRUE(wifi_chip_->createStaIface(&iface).isOk());
+ ASSERT_NE(nullptr, iface.get());
+
+ std::string iface_name = getStaIfaceName(iface);
+ EXPECT_TRUE(wifi_chip_->getStaIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 1);
+ EXPECT_EQ(iface_name, iface_names[0]);
+
+ EXPECT_TRUE(wifi_chip_->removeStaIface(iface_name).isOk());
+ EXPECT_TRUE(wifi_chip_->getStaIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetP2pIfaceNames
+ */
+TEST_P(WifiChipAidlTest, GetP2pIfaceNames) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::P2P);
+
+ std::vector<std::string> iface_names;
+ EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+
+ std::shared_ptr<IWifiP2pIface> iface;
+ EXPECT_TRUE(wifi_chip_->createP2pIface(&iface).isOk());
+ ASSERT_NE(nullptr, iface.get());
+
+ std::string iface_name = getP2pIfaceName(iface);
+ EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 1);
+ EXPECT_EQ(iface_name, iface_names[0]);
+
+ EXPECT_TRUE(wifi_chip_->removeP2pIface(iface_name).isOk());
+ EXPECT_TRUE(wifi_chip_->getP2pIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetApIfaceNames
+ */
+TEST_P(WifiChipAidlTest, GetApIfaceNames) {
+ configureChipForConcurrencyType(IfaceConcurrencyType::AP);
+
+ std::vector<std::string> iface_names;
+ EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+
+ std::shared_ptr<IWifiApIface> iface;
+ EXPECT_TRUE(wifi_chip_->createApIface(&iface).isOk());
+ ASSERT_NE(nullptr, iface.get());
+
+ std::string iface_name = getApIfaceName(iface);
+ EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 1);
+ EXPECT_EQ(iface_name, iface_names[0]);
+
+ EXPECT_TRUE(wifi_chip_->removeApIface(iface_name).isOk());
+ EXPECT_TRUE(wifi_chip_->getApIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetNanIfaceNames
+ */
+TEST_P(WifiChipAidlTest, GetNanIfaceNames) {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+ GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+ }
+ configureChipForConcurrencyType(IfaceConcurrencyType::NAN_IFACE);
+
+ std::vector<std::string> iface_names;
+ EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+
+ std::shared_ptr<IWifiNanIface> iface;
+ EXPECT_TRUE(wifi_chip_->createNanIface(&iface).isOk());
+ ASSERT_NE(nullptr, iface.get());
+
+ std::string iface_name = getNanIfaceName(iface);
+ EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 1);
+ EXPECT_EQ(iface_name, iface_names[0]);
+
+ EXPECT_TRUE(wifi_chip_->removeNanIface(iface_name).isOk());
+ EXPECT_TRUE(wifi_chip_->getNanIfaceNames(&iface_names).isOk());
+ EXPECT_EQ(iface_names.size(), 0);
+}
+
+/*
+ * GetStaIface
+ * Configures the chip in STA mode and creates an iface. Then retrieves
+ * the iface object using its name and ensures that any other name
+ * doesn't retrieve a valid iface object.
+ */
+TEST_P(WifiChipAidlTest, GetStaIface) {
+ std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
+ std::string iface_name = getStaIfaceName(iface);
+
+ std::shared_ptr<IWifiStaIface> retrieved_iface;
+ EXPECT_TRUE(wifi_chip_->getStaIface(iface_name, &retrieved_iface).isOk());
+ EXPECT_NE(nullptr, retrieved_iface.get());
+
+ std::string invalid_name = iface_name + "0";
+ std::shared_ptr<IWifiStaIface> invalid_iface;
+ auto status = wifi_chip_->getStaIface(invalid_name, &invalid_iface);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * GetP2pIface
+ */
+TEST_P(WifiChipAidlTest, GetP2pIface) {
+ std::shared_ptr<IWifiP2pIface> iface = configureChipForP2pAndGetIface();
+ std::string iface_name = getP2pIfaceName(iface);
+
+ std::shared_ptr<IWifiP2pIface> retrieved_iface;
+ EXPECT_TRUE(wifi_chip_->getP2pIface(iface_name, &retrieved_iface).isOk());
+ EXPECT_NE(nullptr, retrieved_iface.get());
+
+ std::string invalid_name = iface_name + "0";
+ std::shared_ptr<IWifiP2pIface> invalid_iface;
+ auto status = wifi_chip_->getP2pIface(invalid_name, &invalid_iface);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * GetApIface
+ */
+TEST_P(WifiChipAidlTest, GetApIface) {
+ std::shared_ptr<IWifiApIface> iface = configureChipForApAndGetIface();
+ std::string iface_name = getApIfaceName(iface);
+
+ std::shared_ptr<IWifiApIface> retrieved_iface;
+ EXPECT_TRUE(wifi_chip_->getApIface(iface_name, &retrieved_iface).isOk());
+ EXPECT_NE(nullptr, retrieved_iface.get());
+
+ std::string invalid_name = iface_name + "0";
+ std::shared_ptr<IWifiApIface> invalid_iface;
+ auto status = wifi_chip_->getApIface(invalid_name, &invalid_iface);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * GetNanIface
+ */
+TEST_P(WifiChipAidlTest, GetNanIface) {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+ GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+ }
+ std::shared_ptr<IWifiNanIface> iface = configureChipForNanAndGetIface();
+ std::string iface_name = getNanIfaceName(iface);
+
+ std::shared_ptr<IWifiNanIface> retrieved_iface;
+ EXPECT_TRUE(wifi_chip_->getNanIface(iface_name, &retrieved_iface).isOk());
+ EXPECT_NE(nullptr, retrieved_iface.get());
+
+ std::string invalid_name = iface_name + "0";
+ std::shared_ptr<IWifiNanIface> invalid_iface;
+ auto status = wifi_chip_->getNanIface(invalid_name, &invalid_iface);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_EQ(nullptr, invalid_iface.get());
+}
+
+/*
+ * RemoveStaIface
+ * Configures the chip in STA mode and creates an iface. Then removes
+ * the iface object using the correct name and ensures that any other
+ * name doesn't remove the iface.
+ */
+TEST_P(WifiChipAidlTest, RemoveStaIface) {
+ std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
+ std::string iface_name = getStaIfaceName(iface);
+
+ std::string invalid_name = iface_name + "0";
+ auto status = wifi_chip_->removeStaIface(invalid_name);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_TRUE(wifi_chip_->removeStaIface(iface_name).isOk());
+
+ // No such iface exists now, so this should return failure.
+ EXPECT_FALSE(wifi_chip_->removeStaIface(iface_name).isOk());
+}
+
+/*
+ * RemoveP2pIface
+ */
+TEST_P(WifiChipAidlTest, RemoveP2pIface) {
+ std::shared_ptr<IWifiP2pIface> iface = configureChipForP2pAndGetIface();
+ std::string iface_name = getP2pIfaceName(iface);
+
+ std::string invalid_name = iface_name + "0";
+ auto status = wifi_chip_->removeP2pIface(invalid_name);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_TRUE(wifi_chip_->removeP2pIface(iface_name).isOk());
+
+ // No such iface exists now, so this should return failure.
+ EXPECT_FALSE(wifi_chip_->removeP2pIface(iface_name).isOk());
+}
+
+/*
+ * RemoveApIface
+ */
+TEST_P(WifiChipAidlTest, RemoveApIface) {
+ std::shared_ptr<IWifiApIface> iface = configureChipForApAndGetIface();
+ std::string iface_name = getApIfaceName(iface);
+
+ std::string invalid_name = iface_name + "0";
+ auto status = wifi_chip_->removeApIface(invalid_name);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_TRUE(wifi_chip_->removeApIface(iface_name).isOk());
+
+ // No such iface exists now, so this should return failure.
+ EXPECT_FALSE(wifi_chip_->removeApIface(iface_name).isOk());
+}
+
+/*
+ * RemoveNanIface
+ */
+TEST_P(WifiChipAidlTest, RemoveNanIface) {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) {
+ GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+ }
+ std::shared_ptr<IWifiNanIface> iface = configureChipForNanAndGetIface();
+ std::string iface_name = getNanIfaceName(iface);
+
+ std::string invalid_name = iface_name + "0";
+ auto status = wifi_chip_->removeNanIface(invalid_name);
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ EXPECT_TRUE(wifi_chip_->removeNanIface(iface_name).isOk());
+
+ // No such iface exists now, so this should return failure.
+ EXPECT_FALSE(wifi_chip_->removeNanIface(iface_name).isOk());
+}
+
+/*
+ * CreateRttController
+ */
+TEST_P(WifiChipAidlTest, CreateRttController) {
+ std::shared_ptr<IWifiStaIface> iface = configureChipForStaAndGetIface();
+ std::shared_ptr<IWifiRttController> rtt_controller;
+ auto status = wifi_chip_->createRttController(iface, &rtt_controller);
+ if (status.isOk()) {
+ EXPECT_NE(nullptr, rtt_controller.get());
+ } else {
+ EXPECT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+ }
+}
+
+/**
+ * CreateBridgedApIface & RemoveIfaceInstanceFromBridgedApIface
+ */
+TEST_P(WifiChipAidlTest, CreateBridgedApIfaceAndremoveIfaceInstanceFromBridgedApIfaceTest) {
+ bool isBridgedSupport = testing::checkSubstringInCommandOutput(
+ "/system/bin/cmd wifi get-softap-supported-features",
+ "wifi_softap_bridged_ap_supported");
+ if (!isBridgedSupport) {
+ GTEST_SKIP() << "Missing Bridged AP support";
+ }
+
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip.get());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(wifi_chip);
+ ASSERT_NE(nullptr, wifi_ap_iface.get());
+
+ std::string br_name;
+ std::vector<std::string> instances;
+ EXPECT_TRUE(wifi_ap_iface->getName(&br_name).isOk());
+ EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances).isOk());
+ EXPECT_EQ(instances.size(), 2);
+
+ std::vector<std::string> instances_after_remove;
+ EXPECT_TRUE(wifi_chip->removeIfaceInstanceFromBridgedApIface(br_name, instances[0]).isOk());
+ EXPECT_TRUE(wifi_ap_iface->getBridgedInstances(&instances_after_remove).isOk());
+ EXPECT_EQ(instances_after_remove.size(), 1);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiChipAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ android::ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
new file mode 100644
index 0000000..bebad7c
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
@@ -0,0 +1,740 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiNanIfaceEventCallback.h>
+#include <aidl/android/hardware/wifi/NanBandIndex.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::BnWifiNanIfaceEventCallback;
+using aidl::android::hardware::wifi::IWifiNanIface;
+using aidl::android::hardware::wifi::NanBandIndex;
+using aidl::android::hardware::wifi::NanBandSpecificConfig;
+using aidl::android::hardware::wifi::NanBootstrappingConfirmInd;
+using aidl::android::hardware::wifi::NanBootstrappingRequestInd;
+using aidl::android::hardware::wifi::NanCapabilities;
+using aidl::android::hardware::wifi::NanClusterEventInd;
+using aidl::android::hardware::wifi::NanConfigRequest;
+using aidl::android::hardware::wifi::NanConfigRequestSupplemental;
+using aidl::android::hardware::wifi::NanDataPathConfirmInd;
+using aidl::android::hardware::wifi::NanDataPathRequestInd;
+using aidl::android::hardware::wifi::NanDataPathScheduleUpdateInd;
+using aidl::android::hardware::wifi::NanDataPathSecurityType;
+using aidl::android::hardware::wifi::NanEnableRequest;
+using aidl::android::hardware::wifi::NanFollowupReceivedInd;
+using aidl::android::hardware::wifi::NanInitiateDataPathRequest;
+using aidl::android::hardware::wifi::NanMatchAlg;
+using aidl::android::hardware::wifi::NanMatchInd;
+using aidl::android::hardware::wifi::NanPairingConfirmInd;
+using aidl::android::hardware::wifi::NanPairingRequestInd;
+using aidl::android::hardware::wifi::NanPublishRequest;
+using aidl::android::hardware::wifi::NanPublishType;
+using aidl::android::hardware::wifi::NanRespondToDataPathIndicationRequest;
+using aidl::android::hardware::wifi::NanStatus;
+using aidl::android::hardware::wifi::NanStatusCode;
+using aidl::android::hardware::wifi::NanSuspensionModeChangeInd;
+using aidl::android::hardware::wifi::NanTxType;
+
+#define TIMEOUT_PERIOD 10
+
+class WifiNanIfaceAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware"))
+ GTEST_SKIP() << "Skipping this test since NAN is not supported.";
+ stopWifiService(getInstanceName());
+
+ wifi_nan_iface_ = getWifiNanIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_nan_iface_.get());
+ std::shared_ptr<WifiNanIfaceEventCallback> callback =
+ ndk::SharedRefBase::make<WifiNanIfaceEventCallback>(*this);
+ EXPECT_TRUE(wifi_nan_iface_->registerEventCallback(callback).isOk());
+ }
+
+ void TearDown() override { stopWifiService(getInstanceName()); }
+
+ // Used as a mechanism to inform the test about data/event callbacks.
+ inline void notify() {
+ std::unique_lock<std::mutex> lock(mtx_);
+ count_++;
+ cv_.notify_one();
+ }
+
+ enum CallbackType {
+ INVALID = -2,
+ ANY_CALLBACK = -1,
+
+ NOTIFY_CAPABILITIES_RESPONSE = 0,
+ NOTIFY_ENABLE_RESPONSE,
+ NOTIFY_CONFIG_RESPONSE,
+ NOTIFY_DISABLE_RESPONSE,
+ NOTIFY_START_PUBLISH_RESPONSE,
+ NOTIFY_STOP_PUBLISH_RESPONSE,
+ NOTIFY_START_SUBSCRIBE_RESPONSE,
+ NOTIFY_STOP_SUBSCRIBE_RESPONSE,
+ NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE,
+ NOTIFY_CREATE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_DELETE_DATA_INTERFACE_RESPONSE,
+ NOTIFY_INITIATE_DATA_PATH_RESPONSE,
+ NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE,
+ NOTIFY_TERMINATE_DATA_PATH_RESPONSE,
+ NOTIFY_INITIATE_PAIRING_RESPONSE,
+ NOTIFY_RESPOND_TO_PAIRING_INDICATION_RESPONSE,
+ NOTIFY_INITIATE_BOOTSTRAPPING_RESPONSE,
+ NOTIFY_RESPOND_TO_BOOTSTRAPPING_INDICATION_RESPONSE,
+ NOTIFY_SUSPEND_RESPONSE,
+ NOTIFY_RESUME_RESPONSE,
+ NOTIFY_TERMINATE_PAIRING_RESPONSE,
+
+ EVENT_CLUSTER_EVENT,
+ EVENT_DISABLED,
+ EVENT_PUBLISH_TERMINATED,
+ EVENT_SUBSCRIBE_TERMINATED,
+ EVENT_MATCH,
+ EVENT_MATCH_EXPIRED,
+ EVENT_FOLLOWUP_RECEIVED,
+ EVENT_TRANSMIT_FOLLOWUP,
+ EVENT_DATA_PATH_REQUEST,
+ EVENT_DATA_PATH_CONFIRM,
+ EVENT_DATA_PATH_TERMINATED,
+ EVENT_DATA_PATH_SCHEDULE_UPDATE,
+ EVENT_PAIRING_REQUEST,
+ EVENT_PAIRING_CONFIRM,
+ EVENT_BOOTSTRAPPING_REQUEST,
+ EVENT_BOOTSTRAPPING_CONFIRM,
+ EVENT_SUSPENSION_MODE_CHANGE,
+ };
+
+ // Test code calls this function to wait for data/event callback.
+ // Must set callbackType = INVALID before calling this function.
+ inline std::cv_status wait(CallbackType waitForCallbackType) {
+ std::unique_lock<std::mutex> lock(mtx_);
+ EXPECT_NE(INVALID, waitForCallbackType);
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) return status;
+ if (waitForCallbackType != ANY_CALLBACK && callback_type_ != INVALID &&
+ callback_type_ != waitForCallbackType) {
+ count_--;
+ }
+ }
+ count_--;
+ return status;
+ }
+
+ class WifiNanIfaceEventCallback : public BnWifiNanIfaceEventCallback {
+ public:
+ WifiNanIfaceEventCallback(WifiNanIfaceAidlTest& parent) : parent_(parent){};
+
+ ::ndk::ScopedAStatus eventClusterEvent(const NanClusterEventInd& event) override {
+ parent_.callback_type_ = EVENT_CLUSTER_EVENT;
+ parent_.nan_cluster_event_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventDataPathConfirm(const NanDataPathConfirmInd& event) override {
+ parent_.callback_type_ = EVENT_DATA_PATH_CONFIRM;
+ parent_.nan_data_path_confirm_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventDataPathRequest(const NanDataPathRequestInd& event) override {
+ parent_.callback_type_ = EVENT_DATA_PATH_REQUEST;
+ parent_.nan_data_path_request_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventDataPathScheduleUpdate(
+ const NanDataPathScheduleUpdateInd& event) override {
+ parent_.callback_type_ = EVENT_DATA_PATH_SCHEDULE_UPDATE;
+ parent_.nan_data_path_schedule_update_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventDataPathTerminated(int32_t ndpInstanceId) override {
+ parent_.callback_type_ = EVENT_DATA_PATH_TERMINATED;
+ parent_.ndp_instance_id_ = ndpInstanceId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventDisabled(const NanStatus& status) override {
+ parent_.callback_type_ = EVENT_DISABLED;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventFollowupReceived(const NanFollowupReceivedInd& event) override {
+ parent_.callback_type_ = EVENT_FOLLOWUP_RECEIVED;
+ parent_.nan_followup_received_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventMatch(const NanMatchInd& event) override {
+ parent_.callback_type_ = EVENT_MATCH;
+ parent_.nan_match_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventMatchExpired(int8_t discoverySessionId, int32_t peerId) override {
+ parent_.callback_type_ = EVENT_MATCH_EXPIRED;
+ parent_.session_id_ = discoverySessionId;
+ parent_.peer_id_ = peerId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventPublishTerminated(int8_t sessionId,
+ const NanStatus& status) override {
+ parent_.callback_type_ = EVENT_PUBLISH_TERMINATED;
+ parent_.session_id_ = sessionId;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventSubscribeTerminated(int8_t sessionId,
+ const NanStatus& status) override {
+ parent_.callback_type_ = EVENT_SUBSCRIBE_TERMINATED;
+ parent_.session_id_ = sessionId;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventTransmitFollowup(char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = EVENT_TRANSMIT_FOLLOWUP;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventPairingConfirm(const NanPairingConfirmInd& event) override {
+ parent_.callback_type_ = EVENT_PAIRING_CONFIRM;
+ parent_.nan_pairing_confirm_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventPairingRequest(const NanPairingRequestInd& event) override {
+ parent_.callback_type_ = EVENT_PAIRING_REQUEST;
+ parent_.nan_pairing_request_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventBootstrappingConfirm(
+ const NanBootstrappingConfirmInd& event) override {
+ parent_.callback_type_ = EVENT_BOOTSTRAPPING_CONFIRM;
+ parent_.nan_bootstrapping_confirm_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventBootstrappingRequest(
+ const NanBootstrappingRequestInd& event) override {
+ parent_.callback_type_ = EVENT_BOOTSTRAPPING_REQUEST;
+ parent_.nan_bootstrapping_request_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus eventSuspensionModeChanged(
+ const NanSuspensionModeChangeInd& event) override {
+ parent_.callback_type_ = EVENT_SUSPENSION_MODE_CHANGE;
+ parent_.nan_suspension_mode_change_ind_ = event;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyCapabilitiesResponse(
+ char16_t id, const NanStatus& status,
+ const NanCapabilities& capabilities) override {
+ parent_.callback_type_ = NOTIFY_CAPABILITIES_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.capabilities_ = capabilities;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyConfigResponse(char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_CONFIG_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyCreateDataInterfaceResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyDeleteDataInterfaceResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyDisableResponse(char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_DISABLE_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyEnableResponse(char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_ENABLE_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyInitiateDataPathResponse(char16_t id, const NanStatus& status,
+ int32_t ndpInstanceId) override {
+ parent_.callback_type_ = NOTIFY_INITIATE_DATA_PATH_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.ndp_instance_id_ = ndpInstanceId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyRespondToDataPathIndicationResponse(
+ char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyStartPublishResponse(char16_t id, const NanStatus& status,
+ int8_t sessionId) override {
+ parent_.callback_type_ = NOTIFY_START_PUBLISH_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.session_id_ = sessionId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyStartSubscribeResponse(char16_t id, const NanStatus& status,
+ int8_t sessionId) override {
+ parent_.callback_type_ = NOTIFY_START_SUBSCRIBE_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.session_id_ = sessionId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyStopPublishResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_STOP_PUBLISH_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyStopSubscribeResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_STOP_SUBSCRIBE_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyTerminateDataPathResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_TERMINATE_DATA_PATH_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifySuspendResponse(char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_SUSPEND_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyResumeResponse(char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_RESUME_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyTransmitFollowupResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyInitiatePairingResponse(char16_t id, const NanStatus& status,
+ int32_t pairingInstanceId) override {
+ parent_.callback_type_ = NOTIFY_INITIATE_PAIRING_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.pairing_instance_id_ = pairingInstanceId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyRespondToPairingIndicationResponse(
+ char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_RESPOND_TO_PAIRING_INDICATION_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyInitiateBootstrappingResponse(
+ char16_t id, const NanStatus& status, int32_t bootstrapppingInstanceId) override {
+ parent_.callback_type_ = NOTIFY_INITIATE_BOOTSTRAPPING_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.bootstrappping_instance_id_ = bootstrapppingInstanceId;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyRespondToBootstrappingIndicationResponse(
+ char16_t id, const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_RESPOND_TO_BOOTSTRAPPING_INDICATION_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus notifyTerminatePairingResponse(char16_t id,
+ const NanStatus& status) override {
+ parent_.callback_type_ = NOTIFY_TERMINATE_PAIRING_RESPONSE;
+ parent_.id_ = id;
+ parent_.status_ = status;
+ parent_.notify();
+ return ndk::ScopedAStatus::ok();
+ }
+
+ private:
+ WifiNanIfaceAidlTest& parent_;
+ };
+
+ protected:
+ std::shared_ptr<IWifiNanIface> wifi_nan_iface_;
+ CallbackType callback_type_;
+ uint16_t id_;
+ uint8_t session_id_;
+ uint32_t ndp_instance_id_;
+ uint32_t pairing_instance_id_;
+ uint32_t bootstrappping_instance_id_;
+ uint32_t peer_id_;
+ NanCapabilities capabilities_;
+ NanClusterEventInd nan_cluster_event_ind_;
+ NanDataPathConfirmInd nan_data_path_confirm_ind_;
+ NanDataPathRequestInd nan_data_path_request_ind_;
+ NanDataPathScheduleUpdateInd nan_data_path_schedule_update_ind_;
+ NanFollowupReceivedInd nan_followup_received_ind_;
+ NanMatchInd nan_match_ind_;
+ NanStatus status_;
+ NanPairingRequestInd nan_pairing_request_ind_;
+ NanPairingConfirmInd nan_pairing_confirm_ind_;
+ NanBootstrappingRequestInd nan_bootstrapping_request_ind_;
+ NanBootstrappingConfirmInd nan_bootstrapping_confirm_ind_;
+ NanSuspensionModeChangeInd nan_suspension_mode_change_ind_;
+
+ const char* getInstanceName() { return GetParam().c_str(); }
+
+ private:
+ // synchronization objects
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_ = 0;
+};
+
+/*
+ * FailOnIfaceInvalid
+ * Ensure that API calls to an interface fail with code ERROR_WIFI_IFACE_INVALID
+ * after wifi is disabled.
+ */
+TEST_P(WifiNanIfaceAidlTest, FailOnIfaceInvalid) {
+ stopWifiService(getInstanceName());
+ sleep(5); // Ensure that all chips/interfaces are invalidated.
+ auto status = wifi_nan_iface_->getCapabilitiesRequest(0);
+ ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_WIFI_IFACE_INVALID));
+}
+
+/*
+ * EnableRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callback_type_ = INVALID;
+ NanEnableRequest nanEnableRequest = {};
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ auto status =
+ wifi_nan_iface_->enableRequest(inputCmdId, nanEnableRequest, nanConfigRequestSupp);
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_TRUE(status.isOk());
+
+ // Wait for a callback.
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+ ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callback_type_);
+ ASSERT_EQ(id_, inputCmdId);
+ ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
+ }
+}
+
+/*
+ * ConfigRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callback_type_ = INVALID;
+ NanConfigRequest nanConfigRequest = {};
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ auto status =
+ wifi_nan_iface_->configRequest(inputCmdId, nanConfigRequest, nanConfigRequestSupp);
+
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_TRUE(status.isOk());
+
+ // Wait for a callback.
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE));
+ ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callback_type_);
+ ASSERT_EQ(id_, inputCmdId);
+ ASSERT_EQ(status_.status, NanStatusCode::INVALID_ARGS);
+ }
+}
+
+/*
+ * EnableRequest - Invalid Args in Shim Conversion
+ */
+TEST_P(WifiNanIfaceAidlTest, EnableRequest_InvalidShimArgs) {
+ uint16_t inputCmdId = 10;
+ NanEnableRequest nanEnableRequest = {};
+ nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = -15; // must be > 0
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ auto status =
+ wifi_nan_iface_->enableRequest(inputCmdId, nanEnableRequest, nanConfigRequestSupp);
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ }
+}
+
+/*
+ * ConfigRequest - Invalid Args in Shim Conversion
+ */
+TEST_P(WifiNanIfaceAidlTest, ConfigRequest_InvalidShimArgs) {
+ uint16_t inputCmdId = 10;
+ NanConfigRequest nanConfigRequest = {};
+ nanConfigRequest.numberOfPublishServiceIdsInBeacon = -15; // must be > 0
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ auto status =
+ wifi_nan_iface_->configRequest(inputCmdId, nanConfigRequest, nanConfigRequestSupp);
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_TRUE(checkStatusCode(&status, WifiStatusCode::ERROR_INVALID_ARGS));
+ }
+}
+
+/*
+ * NotifyCapabilitiesResponse
+ */
+TEST_P(WifiNanIfaceAidlTest, NotifyCapabilitiesResponse) {
+ uint16_t inputCmdId = 10;
+ callback_type_ = INVALID;
+ EXPECT_TRUE(wifi_nan_iface_->getCapabilitiesRequest(inputCmdId).isOk());
+
+ // Wait for a callback.
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CAPABILITIES_RESPONSE));
+ ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE, callback_type_);
+ ASSERT_EQ(id_, inputCmdId);
+ ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
+
+ // Check for reasonable capability values.
+ EXPECT_GT(capabilities_.maxConcurrentClusters, 0);
+ EXPECT_GT(capabilities_.maxPublishes, 0);
+ EXPECT_GT(capabilities_.maxSubscribes, 0);
+ EXPECT_EQ(capabilities_.maxServiceNameLen, 255);
+ EXPECT_EQ(capabilities_.maxMatchFilterLen, 255);
+ EXPECT_GT(capabilities_.maxTotalMatchFilterLen, 255);
+ EXPECT_EQ(capabilities_.maxServiceSpecificInfoLen, 255);
+ EXPECT_GE(capabilities_.maxExtendedServiceSpecificInfoLen, 255);
+ EXPECT_GT(capabilities_.maxNdiInterfaces, 0);
+ EXPECT_GT(capabilities_.maxNdpSessions, 0);
+ EXPECT_GT(capabilities_.maxAppInfoLen, 0);
+ EXPECT_GT(capabilities_.maxQueuedTransmitFollowupMsgs, 0);
+ EXPECT_GT(capabilities_.maxSubscribeInterfaceAddresses, 0);
+ EXPECT_NE(static_cast<int32_t>(capabilities_.supportedCipherSuites), 0);
+}
+
+/*
+ * StartPublishRequest
+ */
+TEST_P(WifiNanIfaceAidlTest, StartPublishRequest) {
+ uint16_t inputCmdId = 10;
+ NanBandSpecificConfig config24 = {};
+ config24.rssiClose = 60;
+ config24.rssiMiddle = 70;
+ config24.rssiCloseProximity = 60;
+ config24.dwellTimeMs = 200;
+ config24.scanPeriodSec = 20;
+ config24.validDiscoveryWindowIntervalVal = false;
+ config24.discoveryWindowIntervalVal = 0;
+
+ NanBandSpecificConfig config5 = {};
+ config5.rssiClose = 60;
+ config5.rssiMiddle = 75;
+ config5.rssiCloseProximity = 60;
+ config5.dwellTimeMs = 200;
+ config5.scanPeriodSec = 20;
+ config5.validDiscoveryWindowIntervalVal = false;
+ config5.discoveryWindowIntervalVal = 0;
+
+ NanEnableRequest req = {};
+ req.operateInBand[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
+ req.operateInBand[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = false;
+ req.hopCountMax = 2;
+ req.configParams.masterPref = 0;
+ req.configParams.disableDiscoveryAddressChangeIndication = true;
+ req.configParams.disableStartedClusterIndication = true;
+ req.configParams.disableJoinedClusterIndication = true;
+ req.configParams.includePublishServiceIdsInBeacon = true;
+ req.configParams.numberOfPublishServiceIdsInBeacon = 0;
+ req.configParams.includeSubscribeServiceIdsInBeacon = true;
+ req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
+ req.configParams.rssiWindowSize = 8;
+ req.configParams.macAddressRandomizationIntervalSec = 1800;
+ req.configParams.bandSpecificConfig[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] =
+ config24;
+ req.configParams.bandSpecificConfig[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] =
+ config5;
+
+ req.debugConfigs.validClusterIdVals = true;
+ req.debugConfigs.clusterIdTopRangeVal = 65535;
+ req.debugConfigs.clusterIdBottomRangeVal = 0;
+ req.debugConfigs.validIntfAddrVal = false;
+ req.debugConfigs.validOuiVal = false;
+ req.debugConfigs.ouiVal = 0;
+ req.debugConfigs.validRandomFactorForceVal = false;
+ req.debugConfigs.randomFactorForceVal = 0;
+ req.debugConfigs.validHopCountForceVal = false;
+ req.debugConfigs.hopCountForceVal = 0;
+ req.debugConfigs.validDiscoveryChannelVal = false;
+ req.debugConfigs.discoveryChannelMhzVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = 0;
+ req.debugConfigs.discoveryChannelMhzVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = 0;
+ req.debugConfigs.validUseBeaconsInBandVal = false;
+ req.debugConfigs.useBeaconsInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
+ req.debugConfigs.useBeaconsInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = true;
+ req.debugConfigs.validUseSdfInBandVal = false;
+ req.debugConfigs.useSdfInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_24GHZ)] = true;
+ req.debugConfigs.useSdfInBandVal[static_cast<int32_t>(NanBandIndex::NAN_BAND_5GHZ)] = true;
+
+ NanConfigRequestSupplemental nanConfigRequestSupp = {};
+ nanConfigRequestSupp.discoveryBeaconIntervalMs = 20;
+ nanConfigRequestSupp.numberOfSpatialStreamsInDiscovery = 0;
+ nanConfigRequestSupp.enableDiscoveryWindowEarlyTermination = false;
+
+ callback_type_ = INVALID;
+ auto status = wifi_nan_iface_->enableRequest(inputCmdId, req, nanConfigRequestSupp);
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_TRUE(status.isOk());
+
+ // Wait for a callback.
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE));
+ ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callback_type_);
+ ASSERT_EQ(id_, inputCmdId);
+ ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
+ }
+
+ NanPublishRequest nanPublishRequest = {};
+ nanPublishRequest.baseConfigs.sessionId = 0;
+ nanPublishRequest.baseConfigs.ttlSec = 0;
+ nanPublishRequest.baseConfigs.discoveryWindowPeriod = 1;
+ nanPublishRequest.baseConfigs.discoveryCount = 0;
+ nanPublishRequest.baseConfigs.serviceName = {97};
+ nanPublishRequest.baseConfigs.discoveryMatchIndicator = NanMatchAlg::MATCH_NEVER;
+ nanPublishRequest.baseConfigs.useRssiThreshold = false;
+ nanPublishRequest.baseConfigs.disableDiscoveryTerminationIndication = false;
+ nanPublishRequest.baseConfigs.disableMatchExpirationIndication = true;
+ nanPublishRequest.baseConfigs.disableFollowupReceivedIndication = false;
+ nanPublishRequest.baseConfigs.securityConfig.securityType = NanDataPathSecurityType::OPEN;
+ nanPublishRequest.autoAcceptDataPathRequests = false;
+ nanPublishRequest.publishType = NanPublishType::UNSOLICITED;
+ nanPublishRequest.txType = NanTxType::BROADCAST;
+
+ status = wifi_nan_iface_->startPublishRequest(inputCmdId + 1, nanPublishRequest);
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_TRUE(status.isOk());
+
+ // Wait for a callback.
+ ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_START_PUBLISH_RESPONSE));
+ ASSERT_EQ(NOTIFY_START_PUBLISH_RESPONSE, callback_type_);
+ ASSERT_EQ(id_, inputCmdId + 1);
+ ASSERT_EQ(status_.status, NanStatusCode::SUCCESS);
+ }
+}
+
+/*
+ * RespondToDataPathIndicationRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, RespondToDataPathIndicationRequest_InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callback_type_ = INVALID;
+ NanRespondToDataPathIndicationRequest nanRespondToDataPathIndicationRequest = {};
+ nanRespondToDataPathIndicationRequest.ifaceName = "AwareInterfaceNameTooLong";
+ auto status = wifi_nan_iface_->respondToDataPathIndicationRequest(
+ inputCmdId, nanRespondToDataPathIndicationRequest);
+
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_EQ(status.getServiceSpecificError(),
+ static_cast<int32_t>(WifiStatusCode::ERROR_INVALID_ARGS));
+ }
+}
+
+/*
+ * InitiateDataPathRequest - Invalid Args
+ */
+TEST_P(WifiNanIfaceAidlTest, InitiateDataPathRequest_InvalidArgs) {
+ uint16_t inputCmdId = 10;
+ callback_type_ = INVALID;
+ NanInitiateDataPathRequest nanInitiateDataPathRequest = {};
+ nanInitiateDataPathRequest.ifaceName = "AwareInterfaceNameTooLong";
+ auto status = wifi_nan_iface_->initiateDataPathRequest(inputCmdId, nanInitiateDataPathRequest);
+
+ if (!checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ ASSERT_EQ(status.getServiceSpecificError(),
+ static_cast<int32_t>(WifiStatusCode::ERROR_INVALID_ARGS));
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiNanIfaceAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ android::ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp
new file mode 100644
index 0000000..d763fe6
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_rtt_controller_aidl_test.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiRttControllerEventCallback.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::BnWifiRttControllerEventCallback;
+using aidl::android::hardware::wifi::IWifiRttController;
+using aidl::android::hardware::wifi::RttBw;
+using aidl::android::hardware::wifi::RttCapabilities;
+using aidl::android::hardware::wifi::RttConfig;
+using aidl::android::hardware::wifi::RttPeerType;
+using aidl::android::hardware::wifi::RttPreamble;
+using aidl::android::hardware::wifi::RttResponder;
+using aidl::android::hardware::wifi::RttResult;
+using aidl::android::hardware::wifi::RttType;
+using aidl::android::hardware::wifi::WifiChannelInfo;
+using aidl::android::hardware::wifi::WifiChannelWidthInMhz;
+using aidl::android::hardware::wifi::WifiStatusCode;
+
+class WifiRttControllerAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ if (!::testing::deviceSupportsFeature("android.hardware.wifi.rtt"))
+ GTEST_SKIP() << "Skipping this test since RTT is not supported.";
+ stopWifiService(getInstanceName());
+ wifi_rtt_controller_ = getWifiRttController();
+ ASSERT_NE(nullptr, wifi_rtt_controller_.get());
+
+ // Check RTT support before we run the test.
+ RttCapabilities caps = {};
+ auto status = wifi_rtt_controller_->getCapabilities(&caps);
+ if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+ GTEST_SKIP() << "Skipping this test since RTT is not supported.";
+ }
+ }
+
+ void TearDown() override { stopWifiService(getInstanceName()); }
+
+ protected:
+ std::shared_ptr<IWifiRttController> getWifiRttController() {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+ EXPECT_NE(nullptr, wifi_chip.get());
+
+ std::shared_ptr<IWifiStaIface> wifi_sta_iface = getWifiStaIface(getInstanceName());
+ EXPECT_NE(nullptr, wifi_sta_iface.get());
+
+ std::shared_ptr<IWifiRttController> rtt_controller;
+ EXPECT_TRUE(wifi_chip->createRttController(wifi_sta_iface, &rtt_controller).isOk());
+ EXPECT_NE(nullptr, rtt_controller.get());
+ return rtt_controller;
+ }
+
+ std::shared_ptr<IWifiRttController> wifi_rtt_controller_;
+
+ private:
+ const char* getInstanceName() { return GetParam().c_str(); }
+};
+
+class WifiRttControllerEventCallback : public BnWifiRttControllerEventCallback {
+ public:
+ WifiRttControllerEventCallback() = default;
+
+ ::ndk::ScopedAStatus onResults(int /* cmdId */,
+ const std::vector<RttResult>& /* results */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+/*
+ * RegisterEventCallback
+ *
+ * Note: it is not feasible to test the invocation of the callback function,
+ * since events are triggered internally in the HAL implementation and cannot be
+ * triggered from the test case.
+ */
+TEST_P(WifiRttControllerAidlTest, RegisterEventCallback) {
+ std::shared_ptr<WifiRttControllerEventCallback> callback =
+ ndk::SharedRefBase::make<WifiRttControllerEventCallback>();
+ ASSERT_NE(nullptr, callback.get());
+ EXPECT_TRUE(wifi_rtt_controller_->registerEventCallback(callback).isOk());
+}
+
+/*
+ * GetCapabilities
+ */
+TEST_P(WifiRttControllerAidlTest, GetCapabilities) {
+ RttCapabilities caps = {};
+ EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
+}
+
+/*
+ * GetResponderInfo
+ */
+TEST_P(WifiRttControllerAidlTest, GetResponderInfo) {
+ RttResponder responder = {};
+ EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk());
+}
+
+/*
+ * EnableResponder
+ */
+TEST_P(WifiRttControllerAidlTest, EnableResponder) {
+ int cmdId = 55;
+ WifiChannelInfo channelInfo;
+ channelInfo.width = WifiChannelWidthInMhz::WIDTH_80;
+ channelInfo.centerFreq = 5660;
+ channelInfo.centerFreq0 = 5660;
+ channelInfo.centerFreq1 = 0;
+
+ RttResponder responder = {};
+ EXPECT_TRUE(wifi_rtt_controller_->getResponderInfo(&responder).isOk());
+ EXPECT_TRUE(wifi_rtt_controller_->enableResponder(cmdId, channelInfo, 10, responder).isOk());
+}
+
+/*
+ * Request2SidedRangeMeasurement
+ * Tests the two sided ranging - 802.11mc FTM protocol.
+ */
+TEST_P(WifiRttControllerAidlTest, Request2SidedRangeMeasurement) {
+ RttCapabilities caps = {};
+ EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
+ if (!caps.rttFtmSupported) {
+ GTEST_SKIP() << "Skipping two sided RTT since driver/fw does not support";
+ }
+
+ RttConfig config;
+ config.addr = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
+ config.type = RttType::TWO_SIDED;
+ config.peer = RttPeerType::AP;
+ config.channel.width = WifiChannelWidthInMhz::WIDTH_80;
+ config.channel.centerFreq = 5180;
+ config.channel.centerFreq0 = 5210;
+ config.channel.centerFreq1 = 0;
+ config.bw = RttBw::BW_20MHZ;
+ config.preamble = RttPreamble::HT;
+ config.mustRequestLci = false;
+ config.mustRequestLcr = false;
+ config.burstPeriod = 0;
+ config.numBurst = 0;
+ config.numFramesPerBurst = 8;
+ config.numRetriesPerRttFrame = 0;
+ config.numRetriesPerFtmr = 0;
+ config.burstDuration = 9;
+
+ int cmdId = 55;
+ std::vector<RttConfig> configs = {config};
+ EXPECT_TRUE(wifi_rtt_controller_->rangeRequest(cmdId, configs).isOk());
+
+ // Sleep for 2 seconds to wait for driver/firmware to complete RTT.
+ sleep(2);
+}
+
+/*
+ * RangeRequest
+ */
+TEST_P(WifiRttControllerAidlTest, RangeRequest) {
+ RttCapabilities caps = {};
+ EXPECT_TRUE(wifi_rtt_controller_->getCapabilities(&caps).isOk());
+ if (!caps.rttOneSidedSupported) {
+ GTEST_SKIP() << "Skipping one sided RTT since driver/fw does not support";
+ }
+
+ // Get the highest supported preamble.
+ int preamble = 1;
+ int caps_preamble_support = static_cast<int>(caps.preambleSupport);
+ caps_preamble_support >>= 1;
+ while (caps_preamble_support != 0) {
+ caps_preamble_support >>= 1;
+ preamble <<= 1;
+ }
+
+ RttConfig config;
+ config.addr = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}};
+ config.type = RttType::ONE_SIDED;
+ config.peer = RttPeerType::AP;
+ config.channel.width = WifiChannelWidthInMhz::WIDTH_80;
+ config.channel.centerFreq = 5765;
+ config.channel.centerFreq0 = 5775;
+ config.channel.centerFreq1 = 0;
+ config.bw = RttBw::BW_80MHZ;
+ config.preamble = static_cast<RttPreamble>(preamble);
+ config.mustRequestLci = false;
+ config.mustRequestLcr = false;
+ config.burstPeriod = 0;
+ config.numBurst = 0;
+ config.numFramesPerBurst = 8;
+ config.numRetriesPerRttFrame = 3;
+ config.numRetriesPerFtmr = 3;
+ config.burstDuration = 9;
+
+ int cmdId = 55;
+ std::vector<RttConfig> configs = {config};
+ EXPECT_TRUE(wifi_rtt_controller_->rangeRequest(cmdId, configs).isOk());
+
+ // Sleep for 2 seconds to wait for driver/firmware to complete RTT.
+ sleep(2);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiRttControllerAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiRttControllerAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ android::ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
new file mode 100644
index 0000000..adc9b73
--- /dev/null
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <vector>
+
+#include <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/BnWifi.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using aidl::android::hardware::wifi::IWifi;
+using aidl::android::hardware::wifi::IWifiStaIface;
+using aidl::android::hardware::wifi::MacAddress;
+using aidl::android::hardware::wifi::Ssid;
+using aidl::android::hardware::wifi::StaApfPacketFilterCapabilities;
+using aidl::android::hardware::wifi::StaBackgroundScanCapabilities;
+using aidl::android::hardware::wifi::StaLinkLayerStats;
+using aidl::android::hardware::wifi::StaRoamingCapabilities;
+using aidl::android::hardware::wifi::StaRoamingConfig;
+using aidl::android::hardware::wifi::StaRoamingState;
+using aidl::android::hardware::wifi::WifiBand;
+using aidl::android::hardware::wifi::WifiDebugRxPacketFateReport;
+using aidl::android::hardware::wifi::WifiDebugTxPacketFateReport;
+using aidl::android::hardware::wifi::WifiStatusCode;
+
+class WifiStaIfaceAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ stopWifiService(getInstanceName());
+ wifi_sta_iface_ = getWifiStaIface(getInstanceName());
+ ASSERT_NE(nullptr, wifi_sta_iface_.get());
+ }
+
+ void TearDown() override { stopWifiService(getInstanceName()); }
+
+ protected:
+ bool isFeatureSupported(IWifiStaIface::FeatureSetMask expected) {
+ int32_t features = 0;
+ EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
+ return features & static_cast<int32_t>(expected);
+ }
+
+ ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* sta_iface) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
+ EXPECT_NE(nullptr, wifi_chip.get());
+ return wifi_chip->createStaIface(sta_iface);
+ }
+
+ std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
+
+ private:
+ const char* getInstanceName() { return GetParam().c_str(); }
+};
+
+/*
+ * GetFactoryMacAddress
+ * Ensures that calls to getFactoryMacAddress will retrieve a non-zero MAC.
+ */
+TEST_P(WifiStaIfaceAidlTest, GetFactoryMacAddress) {
+ std::array<uint8_t, 6> mac;
+ EXPECT_TRUE(wifi_sta_iface_->getFactoryMacAddress(&mac).isOk());
+ std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
+ EXPECT_NE(mac, all_zero_mac);
+}
+
+/*
+ * GetFeatureSet
+ */
+TEST_P(WifiStaIfaceAidlTest, GetFeatureSet) {
+ int32_t features = 0;
+ EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
+ EXPECT_NE(features, 0);
+}
+
+/*
+ * CheckApfIsSupported:
+ * Ensures the APF packet filter is fully supported as required in VSR 14:
+ * https://docs.partner.android.com/gms/policies/vsr/vsr-14
+ */
+TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
+ // It is not required to check the vendor API level is at least U here
+ // because the Wi-Fi AIDL interface is launched with Android U(VSR-14).
+ // TODO: Add wavier list to the chipsets that doesn't support APF.
+ EXPECT_TRUE(isFeatureSupported(IWifiStaIface::FeatureSetMask::APF));
+ StaApfPacketFilterCapabilities apf_caps = {};
+ EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
+ // The APF version must be 4 and the usable memory must be at least
+ // 1024 bytes.
+ EXPECT_EQ(apf_caps.version, 4);
+ EXPECT_GE(apf_caps.maxLength, 1024);
+}
+
+/*
+ * GetBackgroundScanCapabilities
+ */
+TEST_P(WifiStaIfaceAidlTest, GetBackgroundScanCapabilities) {
+ if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN)) {
+ GTEST_SKIP() << "Background scan capabilities are not supported.";
+ }
+ StaBackgroundScanCapabilities caps = {};
+ EXPECT_TRUE(wifi_sta_iface_->getBackgroundScanCapabilities(&caps).isOk());
+}
+
+/*
+ * GetLinkLayerStats
+ * Ensures that calls to getLinkLayerStats will retrieve a non-empty
+ * StaLinkLayerStats after link layer stats collection is enabled.
+ */
+TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) {
+ if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
+ GTEST_SKIP() << "Skipping this test since link layer stats are not supported.";
+ }
+
+ // Enable link layer stats collection.
+ EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
+
+ // Retrieve link layer stats.
+ StaLinkLayerStats link_layer_stats = {};
+ EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
+ EXPECT_GT(link_layer_stats.timeStampInMs, 0);
+
+ // Try to create a 2nd iface. If successful, it should fill the duty cycle field.
+ std::shared_ptr<IWifiStaIface> iface;
+ auto status = createStaIface(&iface);
+ if (status.isOk()) {
+ EXPECT_GT(link_layer_stats.iface.links[0].timeSliceDutyCycleInPercent, 0);
+ }
+
+ // Disable link layer stats collection.
+ EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
+}
+
+/*
+ * SetMacAddress
+ * Ensures that calls to setMacAddress will return successfully.
+ */
+TEST_P(WifiStaIfaceAidlTest, SetMacAddress) {
+ std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x41};
+ EXPECT_TRUE(wifi_sta_iface_->setMacAddress(mac).isOk());
+}
+
+/*
+ * SetScanMode
+ */
+TEST_P(WifiStaIfaceAidlTest, SetScanMode) {
+ auto status = wifi_sta_iface_->setScanMode(true);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+
+ status = wifi_sta_iface_->setScanMode(false);
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+}
+
+/*
+ * LinkLayerStatsCollection
+ */
+TEST_P(WifiStaIfaceAidlTest, LinkLayerStatsCollection) {
+ if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
+ GTEST_SKIP() << "Link layer stats collection is not supported.";
+ }
+
+ // Enable link layer stats collection.
+ EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
+
+ // Retrieve link layer stats.
+ StaLinkLayerStats link_layer_stats = {};
+ EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
+
+ // Disable link layer stats collection.
+ EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
+}
+
+/*
+ * RSSIMonitoring
+ * Ensures that calls to startRssiMonitoring and stopRssiMonitoring will fail
+ * if the device is not connected to an AP.
+ */
+TEST_P(WifiStaIfaceAidlTest, RSSIMonitoring) {
+ if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::RSSI_MONITOR)) {
+ GTEST_SKIP() << "RSSI monitoring is not supported.";
+ }
+
+ const int cmd = 1;
+ const int maxRssi = -50;
+ const int minRssi = -90;
+ // Expected to fail because device is not connected to an AP.
+ EXPECT_FALSE(wifi_sta_iface_->startRssiMonitoring(cmd, maxRssi, minRssi).isOk());
+ EXPECT_FALSE(wifi_sta_iface_->stopRssiMonitoring(cmd).isOk());
+}
+
+/*
+ * RoamingControl
+ */
+TEST_P(WifiStaIfaceAidlTest, RoamingControl) {
+ if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::CONTROL_ROAMING)) {
+ GTEST_SKIP() << "Roaming control is not supported.";
+ }
+
+ // Retrieve roaming capabilities.
+ StaRoamingCapabilities caps = {};
+ EXPECT_TRUE(wifi_sta_iface_->getRoamingCapabilities(&caps).isOk());
+
+ // Set up roaming configuration based on roaming capabilities.
+ StaRoamingConfig roaming_config = {};
+ if (caps.maxBlocklistSize > 0) {
+ MacAddress block_list_entry;
+ block_list_entry.data = std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
+ roaming_config.bssidBlocklist = {block_list_entry};
+ }
+ if (caps.maxAllowlistSize > 0) {
+ Ssid allow_list_entry = {};
+ allow_list_entry.data = std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}};
+ roaming_config.ssidAllowlist = {allow_list_entry};
+ }
+
+ // Configure roaming.
+ EXPECT_TRUE(wifi_sta_iface_->configureRoaming(roaming_config).isOk());
+
+ // Enable roaming.
+ EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::ENABLED).isOk());
+}
+
+/*
+ * EnableNDOffload
+ */
+TEST_P(WifiStaIfaceAidlTest, EnableNDOffload) {
+ if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::ND_OFFLOAD)) {
+ GTEST_SKIP() << "ND offload is not supported.";
+ }
+ EXPECT_TRUE(wifi_sta_iface_->enableNdOffload(true).isOk());
+}
+
+/*
+ * PacketFateMonitoring
+ */
+TEST_P(WifiStaIfaceAidlTest, PacketFateMonitoring) {
+ // Start packet fate monitoring.
+ auto status = wifi_sta_iface_->startDebugPacketFateMonitoring();
+ EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
+
+ // Retrieve packets.
+ if (status.isOk()) {
+ std::vector<WifiDebugRxPacketFateReport> rx_reports;
+ std::vector<WifiDebugTxPacketFateReport> tx_reports;
+ EXPECT_TRUE(wifi_sta_iface_->getDebugRxPacketFates(&rx_reports).isOk());
+ EXPECT_TRUE(wifi_sta_iface_->getDebugTxPacketFates(&tx_reports).isOk());
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceAidlTest);
+INSTANTIATE_TEST_SUITE_P(WifiTest, WifiStaIfaceAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ android::ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/wifi/apex/Android.bp b/wifi/apex/Android.bp
index 45f17a6..f8ba5c4 100644
--- a/wifi/apex/Android.bp
+++ b/wifi/apex/Android.bp
@@ -15,7 +15,7 @@
genrule {
name: "gen-android.hardware.wifi.rc",
- srcs: [":[email protected]"],
+ srcs: [":default-android.hardware.wifi-service.rc"],
out: ["com.android.hardware.wifi-service.rc"],
cmd: "sed -e 's@/vendor/bin/@/apex/com.android.hardware.wifi/bin/@' $(in) > $(out)",
}
@@ -28,7 +28,7 @@
prebuilt_etc {
name: "com.android.hardware.wifi.xml",
- src: ":[email protected]",
+ src: ":default-android.hardware.wifi-service.xml",
installable: false,
sub_dir: "vintf",
}
@@ -43,13 +43,13 @@
updatable: false,
soc_specific: true,
binaries: [
- "[email protected]",
+ "android.hardware.wifi-service",
],
prebuilts: [
"com.android.hardware.wifi.rc",
"com.android.hardware.wifi.xml",
],
overrides: [
- "[email protected]",
+ "android.hardware.wifi-service",
],
}
diff --git a/wifi/apex/file_contexts b/wifi/apex/file_contexts
index 04e8a62..d932fac 100644
--- a/wifi/apex/file_contexts
+++ b/wifi/apex/file_contexts
@@ -1,3 +1,3 @@
(/.*)? u:object_r:vendor_file:s0
/etc(/.*)? u:object_r:vendor_configs_file:s0
-/bin/hw/android\.hardware\[email protected] u:object_r:hal_wifi_default_exec:s0
+/bin/hw/android\.hardware\.wifi-service u:object_r:hal_wifi_default_exec:s0
diff --git a/wifi/hostapd/aidl/lint-baseline.xml b/wifi/hostapd/aidl/lint-baseline.xml
new file mode 100644
index 0000000..657622e
--- /dev/null
+++ b/wifi/hostapd/aidl/lint-baseline.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
+ line="55"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V1-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
+ line="46"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"
+ line="117"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V2-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"
+ line="62"
+ column="12"/>
+ </issue>
+
+</issues>
\ No newline at end of file
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index e61d397..1942db1 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -34,6 +34,9 @@
"[email protected]",
"[email protected]",
"[email protected]",
+ "android.hardware.wifi-V1-ndk",
+ "libwifi-system-iface",
+ "VtsHalWifiTargetTestUtil",
],
test_suites: [
"general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index bd2649f..69f1b76 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <aidl/android/hardware/wifi/IWifi.h>
#include <android/hardware/wifi/1.0/IWifi.h>
#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
@@ -30,6 +31,8 @@
#include <wifi_hidl_test_utils.h>
#include <wifi_hidl_test_utils_1_5.h>
+#include "wifi_aidl_test_utils.h"
+
using aidl::android::hardware::wifi::hostapd::BandMask;
using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
using aidl::android::hardware::wifi::hostapd::ChannelBandwidth;
@@ -54,6 +57,8 @@
const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
const Ieee80211ReasonCode kTestDisconnectReasonCode =
Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
+const std::string kWifiAidlInstanceNameStr = std::string() + IWifi::descriptor + "/default";
+const char* kWifiAidlInstanceName = kWifiAidlInstanceNameStr.c_str();
inline BandMask operator|(BandMask a, BandMask b) {
return static_cast<BandMask>(static_cast<int32_t>(a) |
@@ -77,33 +82,70 @@
isBridgedSupport = testing::checkSubstringInCommandOutput(
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_bridged_ap_supported");
- const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
- ::android::hardware::wifi::V1_0::IWifi::descriptor);
- EXPECT_NE(0, instances.size());
- wifiInstanceName = instances[0];
+ if (!isAidlServiceAvailable(kWifiAidlInstanceName)) {
+ const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_0::IWifi::descriptor);
+ EXPECT_NE(0, instances.size());
+ wifiHidlInstanceName = instances[0];
+ }
}
virtual void TearDown() override {
- if (getWifi(wifiInstanceName) != nullptr) {
- stopWifi(wifiInstanceName);
- }
+ stopVendorHal();
hostapd->terminate();
// Wait 3 seconds to allow terminate to complete
sleep(3);
}
std::shared_ptr<IHostapd> hostapd;
- std::string wifiInstanceName;
+ std::string wifiHidlInstanceName;
bool isAcsSupport;
bool isWpa3SaeSupport;
bool isBridgedSupport;
+ void stopVendorHal() {
+ if (isAidlServiceAvailable(kWifiAidlInstanceName)) {
+ // HIDL and AIDL versions of getWifi() take different arguments
+ // i.e. const char* vs string
+ if (getWifi(kWifiAidlInstanceName) != nullptr) {
+ stopWifiService(kWifiAidlInstanceName);
+ }
+ } else {
+ if (getWifi(wifiHidlInstanceName) != nullptr) {
+ stopWifi(wifiHidlInstanceName);
+ }
+ }
+ }
+
std::string setupApIfaceAndGetName(bool isBridged) {
+ if (isAidlServiceAvailable(kWifiAidlInstanceName)) {
+ return setupApIfaceAndGetNameAidl(isBridged);
+ } else {
+ return setupApIfaceAndGetNameHidl(isBridged);
+ }
+ }
+
+ std::string setupApIfaceAndGetNameAidl(bool isBridged) {
+ std::shared_ptr<IWifiApIface> wifi_ap_iface;
+ if (isBridged) {
+ wifi_ap_iface = getBridgedWifiApIface(kWifiAidlInstanceName);
+ } else {
+ wifi_ap_iface = getWifiApIface(kWifiAidlInstanceName);
+ }
+ EXPECT_NE(nullptr, wifi_ap_iface.get());
+
+ std::string ap_iface_name;
+ auto status = wifi_ap_iface->getName(&ap_iface_name);
+ EXPECT_TRUE(status.isOk());
+ return ap_iface_name;
+ }
+
+ std::string setupApIfaceAndGetNameHidl(bool isBridged) {
android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
if (isBridged) {
- wifi_ap_iface = getBridgedWifiApIface_1_5(wifiInstanceName);
+ wifi_ap_iface = getBridgedWifiApIface_1_5(wifiHidlInstanceName);
} else {
- wifi_ap_iface = getWifiApIface_1_5(wifiInstanceName);
+ wifi_ap_iface = getWifiApIface_1_5(wifiHidlInstanceName);
}
EXPECT_NE(nullptr, wifi_ap_iface.get());
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
index ded9122..e84a5cf 100644
--- a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
@@ -28,7 +28,7 @@
using namespace std::chrono_literals;
static constexpr std::chrono::milliseconds kPollTimeout = 300ms;
-static constexpr bool kSuperVerbose = true;
+static constexpr bool kSuperVerbose = false;
InterceptorRelay::InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
const std::string& clientName)
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
index ac8653e..32e5a6e 100644
--- a/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
+++ b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
@@ -117,14 +117,13 @@
int clientSocketFd, const char* clientName,
struct android_nlinterceptor_InterceptedSocket* interceptedSocket);
-void android_nlinterceptor_closeSocket(
- const struct android_nlinterceptor_InterceptedSocket* sock);
+void android_nlinterceptor_closeSocket(struct android_nlinterceptor_InterceptedSocket sock);
-bool android_nlinterceptor_subscribe(
- const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+bool android_nlinterceptor_subscribe(struct android_nlinterceptor_InterceptedSocket sock,
+ uint32_t group);
-bool android_nlinterceptor_unsubscribe(
- const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+bool android_nlinterceptor_unsubscribe(struct android_nlinterceptor_InterceptedSocket sock,
+ uint32_t group);
#ifdef __cplusplus
}
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
index 575f900..aae7a3a 100644
--- a/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
+++ b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
@@ -150,25 +150,18 @@
return true;
}
-extern "C" void android_nlinterceptor_closeSocket(
- const android_nlinterceptor_InterceptedSocket* sock) {
- if (!sock) {
- LOG(ERROR) << "Can't close socket identified by a null pointer!";
- return;
- }
- closeSocket({sock->nlFamily, sock->portId});
+extern "C" void android_nlinterceptor_closeSocket(android_nlinterceptor_InterceptedSocket sock) {
+ closeSocket({sock.nlFamily, sock.portId});
}
-extern "C" bool android_nlinterceptor_subscribe(
- const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
- if (!sock) return false;
- return subscribe({sock->nlFamily, sock->portId}, group);
+extern "C" bool android_nlinterceptor_subscribe(android_nlinterceptor_InterceptedSocket sock,
+ uint32_t group) {
+ return subscribe({sock.nlFamily, sock.portId}, group);
}
-extern "C" bool android_nlinterceptor_unsubscribe(
- const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
- if (!sock) return false;
- return unsubscribe({sock->nlFamily, sock->portId}, group);
+extern "C" bool android_nlinterceptor_unsubscribe(android_nlinterceptor_InterceptedSocket sock,
+ uint32_t group) {
+ return unsubscribe({sock.nlFamily, sock.portId}, group);
}
} // namespace android::nlinterceptor
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index 9cb4e51..c4d3767 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -36,6 +36,11 @@
"com.android.wifi",
],
min_sdk_version: "30",
+ lint: {
+ // Disable linter to avoid error about fixed size arrays.
+ // Interface will only be accessed on devices >= T.
+ enabled: false,
+ },
},
ndk: {
gen_trace: true,
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 433b3d80..553cbc8 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
@@ -39,4 +39,5 @@
int maxNumberTxSpatialStreams;
int maxNumberRxSpatialStreams;
android.hardware.wifi.supplicant.LegacyMode legacyMode;
+ boolean apTidToLinkMapNegotiationSupported;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppConfigurationData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppConfigurationData.aidl
new file mode 100644
index 0000000..2225330
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppConfigurationData.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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 DppConfigurationData {
+ byte[] ssid;
+ String password;
+ byte[] psk;
+ android.hardware.wifi.supplicant.DppAkm securityAkm;
+ android.hardware.wifi.supplicant.DppConnectionKeys dppConnectionKeys;
+ boolean connStatusRequested;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
new file mode 100644
index 0000000..d72633b
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum DppStatusErrorCode {
+ UNKNOWN = -1,
+ SUCCESS = 0,
+ NOT_COMPATIBLE = 1,
+ AUTH_FAILURE = 2,
+ UNWRAP_FAILURE = 3,
+ BAD_GROUP = 4,
+ CONFIGURE_FAILURE = 5,
+ RESPONSE_PENDING = 6,
+ INVALID_CONNECTOR = 7,
+ NO_MATCH = 8,
+ CONFIG_REJECTED = 9,
+ NO_AP = 10,
+ CONFIGURE_PENDING = 11,
+ CSR_NEEDED = 12,
+ CSR_BAD = 13,
+ NEW_KEY_NEEDED = 14,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
new file mode 100644
index 0000000..bcf0ea8
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+interface INonStandardCertCallback {
+ byte[] getBlob(in String alias);
+ String[] listAliases(in String prefix);
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
index 4b26ac3..dd62167 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -47,5 +47,6 @@
void setConcurrencyPriority(in android.hardware.wifi.supplicant.IfaceType type);
void setDebugParams(in android.hardware.wifi.supplicant.DebugLevel level, in boolean showTimestamp, in boolean showKeys);
oneway void terminate();
+ void registerNonStandardCertCallback(in android.hardware.wifi.supplicant.INonStandardCertCallback callback);
const int EXT_RADIO_WORK_TIMEOUT_IN_SECS = 10;
}
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 e204184..19e6728 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
@@ -96,4 +96,5 @@
void findOnSocialChannels(in int timeoutInSec);
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);
}
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 8d9f498..da3ca52 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
@@ -52,4 +52,5 @@
oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
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);
}
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 53d5770..1616b26 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
@@ -95,4 +95,8 @@
void stopDppInitiator();
void stopDppResponder(in int ownBootstrapId);
void stopRxFilter();
+ 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);
+ 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/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 25a09b4..1c23223 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -44,6 +44,9 @@
oneway void onDppFailure(in android.hardware.wifi.supplicant.DppFailureCode code, in String ssid, in String channelList, in char[] bandList);
oneway void onDppProgress(in android.hardware.wifi.supplicant.DppProgressCode code);
oneway void onDppSuccess(in android.hardware.wifi.supplicant.DppEventType event);
+ /**
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onDppConfigReceived.
+ */
oneway void onDppSuccessConfigReceived(in byte[] ssid, in String password, in byte[] psk, in android.hardware.wifi.supplicant.DppAkm securityAkm, in android.hardware.wifi.supplicant.DppConnectionKeys dppConnectionKeys);
oneway void onDppSuccessConfigSent();
oneway void onEapFailure(in byte[] bssid, in int errorCode);
@@ -56,11 +59,29 @@
oneway void onNetworkAdded(in int id);
oneway void onNetworkNotFound(in byte[] ssid);
oneway void onNetworkRemoved(in int id);
+ /**
+ * @deprecated use onPmkSaCacheAdded() instead.
+ */
oneway void onPmkCacheAdded(in long expirationTimeInSec, in byte[] serializedEntry);
+ /**
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onSupplicantStateChanged()
+ */
oneway void onStateChanged(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent);
oneway void onWpsEventFail(in byte[] bssid, in android.hardware.wifi.supplicant.WpsConfigError configError, in android.hardware.wifi.supplicant.WpsErrorIndication errorInd);
oneway void onWpsEventPbcOverlap();
oneway void onWpsEventSuccess();
oneway void onQosPolicyReset();
oneway void onQosPolicyRequest(in int qosPolicyRequestId, in android.hardware.wifi.supplicant.QosPolicyData[] qosPolicyData);
+ oneway void onMloLinksInfoChanged(in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback.MloLinkInfoChangeReason reason);
+ oneway void onDppConfigReceived(in android.hardware.wifi.supplicant.DppConfigurationData configData);
+ oneway void onDppConnectionStatusResultSent(in android.hardware.wifi.supplicant.DppStatusErrorCode code);
+ oneway void onBssFrequencyChanged(in int frequencyMhz);
+ oneway void onSupplicantStateChanged(in android.hardware.wifi.supplicant.SupplicantStateChangeData stateChangeData);
+ oneway void onQosPolicyResponseForScs(in android.hardware.wifi.supplicant.QosPolicyScsResponseStatus[] qosPolicyScsResponseStatus);
+ oneway void onPmkSaCacheAdded(in android.hardware.wifi.supplicant.PmkSaCacheData pmkSaData);
+ @Backing(type="int") @VintfStability
+ enum MloLinkInfoChangeReason {
+ TID_TO_LINK_MAP = 0,
+ MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+ }
}
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 0b3cb81..bfc05a4 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
@@ -127,6 +127,8 @@
void setWepKey(in int keyIdx, in byte[] wepKey);
void setWepTxKeyIdx(in int keyIdx);
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+ void setMinimumTlsVersionEapPhase1Param(android.hardware.wifi.supplicant.TlsVersion tlsVersion);
+ void setStrictConservativePeerMode(in boolean enable);
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/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index 6276a35..f9a078b 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -39,4 +39,5 @@
oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params);
oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind);
oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+ oneway void onPermanentIdReqDenied();
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
index 5e2c47b..8bda324 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
@@ -36,4 +36,8 @@
parcelable MloLink {
byte linkId;
byte[] staLinkMacAddress;
+ byte tidsUplinkMap;
+ byte tidsDownlinkMap;
+ @nullable byte[6] apLinkMacAddress;
+ int frequencyMHz;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl
index 14fcb91..3dac2d6 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLinksInfo.aidl
@@ -35,4 +35,6 @@
@VintfStability
parcelable MloLinksInfo {
android.hardware.wifi.supplicant.MloLink[] links;
+ int apMloLinkId;
+ @nullable byte[6] apMldMacAddress;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
new file mode 100644
index 0000000..db31ca1
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.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;
+@VintfStability
+parcelable P2pClientEapolIpAddressInfo {
+ int ipAddressClient;
+ int ipAddressMask;
+ int ipAddressGo;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
new file mode 100644
index 0000000..5465a86
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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 P2pGroupStartedEventParams {
+ String groupInterfaceName;
+ boolean isGroupOwner;
+ byte[] ssid;
+ int frequencyMHz;
+ byte[] psk;
+ String passphrase;
+ boolean isPersistent;
+ byte[6] goDeviceAddress;
+ byte[6] goInterfaceAddress;
+ boolean isP2pClientEapolIpAddressInfoPresent;
+ android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo p2pClientIpInfo;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
new file mode 100644
index 0000000..c31b167
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.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;
+@VintfStability
+parcelable PmkSaCacheData {
+ byte[6] bssid;
+ long expirationTimeInSec;
+ byte[] serializedEntry;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
index 8bf5fd8..156d57a 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
@@ -43,4 +43,5 @@
android.hardware.wifi.supplicant.ProtocolNextHeader protocolNextHdr;
byte[] flowLabelIpv6;
String domainName;
+ byte dscp;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
index 280ddbe..9c0c0b6 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
@@ -41,4 +41,5 @@
PROTOCOL_NEXT_HEADER = 16,
FLOW_LABEL = 32,
DOMAIN_NAME = 64,
+ DSCP = 128,
}
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
new file mode 100644
index 0000000..4e5e8ae
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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 QosPolicyScsData {
+ byte policyId;
+ byte userPriority;
+ android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
new file mode 100644
index 0000000..d5573af
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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 QosPolicyScsRequestStatus {
+ byte policyId;
+ android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode qosPolicyScsRequestStatusCode;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
new file mode 100644
index 0000000..4d81566
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
@@ -0,0 +1,26 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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 QosPolicyScsRequestStatusCode {
+ SENT = 0,
+ ALREADY_ACTIVE = 1,
+ NOT_EXIST = 2,
+ INVALID = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
new file mode 100644
index 0000000..2737f1a
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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 QosPolicyScsResponseStatus {
+ byte policyId;
+ android.hardware.wifi.supplicant.QosPolicyScsResponseStatusCode qosPolicyScsResponseStatusCode;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
new file mode 100644
index 0000000..693d3e0
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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 QosPolicyScsResponseStatusCode {
+ SUCCESS = 0,
+ TCLAS_REQUEST_DECLINED = 1,
+ TCLAS_NOT_SUPPORTED_BY_AP = 2,
+ TCLAS_INSUFFICIENT_RESOURCES = 3,
+ TCLAS_RESOURCES_EXHAUSTED = 4,
+ TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS = 5,
+ TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT = 6,
+ TCLAS_PROCESSING_TERMINATED = 7,
+ TIMEOUT = 8,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..52d3f24
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable SignalPollResult {
+ int linkId;
+ int currentRssiDbm;
+ int txBitrateMbps;
+ int rxBitrateMbps;
+ int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..1d37635
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable SupplicantStateChangeData {
+ android.hardware.wifi.supplicant.StaIfaceCallbackState newState;
+ int id;
+ byte[] ssid;
+ byte[6] bssid;
+ android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask;
+ int frequencyMhz;
+ boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index 32d71a3..d84ff95 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -45,4 +45,5 @@
FAILURE_NETWORK_INVALID = 8,
FAILURE_NETWORK_UNKNOWN = 9,
FAILURE_UNSUPPORTED = 10,
+ FAILURE_ONGOING_REQUEST = 11,
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..22a374f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum TlsVersion {
+ TLS_V1_0 = 0,
+ TLS_V1_1 = 1,
+ TLS_V1_2 = 2,
+ TLS_V1_3 = 3,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 9a0a924..32e1510 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -39,4 +39,6 @@
SAE_PK = 4,
WFD_R2 = 8,
TRUST_ON_FIRST_USE = 16,
+ SET_TLS_MINIMUM_VERSION = 32,
+ TLS_V1_3 = 64,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 1718413..4921a67 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -44,4 +44,8 @@
* detailed network mode for legacy network
*/
LegacyMode legacyMode;
+ /**
+ * Indicates the AP support for TID-to-link mapping negotiation.
+ */
+ boolean apTidToLinkMapNegotiationSupported;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppConfigurationData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppConfigurationData.aidl
new file mode 100644
index 0000000..b25bc40
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppConfigurationData.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.DppAkm;
+import android.hardware.wifi.supplicant.DppConnectionKeys;
+
+/**
+ * DPP configuration related information.
+ */
+@VintfStability
+parcelable DppConfigurationData {
+ /*
+ * SSID of the network.
+ */
+ byte[] ssid;
+ /*
+ * WPA2 or SAE passphrase.
+ */
+ String password;
+ /*
+ * Pre-shared key encoded in hex.
+ */
+ byte[] psk;
+ /*
+ * AKM that can be provisioned using DPP.
+ */
+ DppAkm securityAkm;
+ /*
+ * Connection keys that are used for DPP network connection.
+ */
+ DppConnectionKeys dppConnectionKeys;
+ /*
+ * Optional flag to indicate that the configurator requested connection status
+ * result.
+ * This flag is set to true if the enrollee receives the configuration response
+ * frame with sendConnStatus attribute.
+ */
+ boolean connStatusRequested;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppStatusErrorCode.aidl
new file mode 100644
index 0000000..30965d6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppStatusErrorCode.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * DppStatusErrorCode: The possible values for the DPP status and error codes
+ * in the DPP protocol.
+ * See Easy Connect specification V2.0 section 8.3.4 for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum DppStatusErrorCode {
+ UNKNOWN = -1,
+ SUCCESS = 0,
+ NOT_COMPATIBLE = 1,
+ AUTH_FAILURE = 2,
+ UNWRAP_FAILURE = 3,
+ BAD_GROUP = 4,
+ CONFIGURE_FAILURE = 5,
+ RESPONSE_PENDING = 6,
+ INVALID_CONNECTOR = 7,
+ NO_MATCH = 8,
+ CONFIG_REJECTED = 9,
+ NO_AP = 10,
+ CONFIGURE_PENDING = 11,
+ CSR_NEEDED = 12,
+ CSR_BAD = 13,
+ NEW_KEY_NEEDED = 14,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
new file mode 100644
index 0000000..2e11c76
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/INonStandardCertCallback.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Callback to allow supplicant to retrieve non-standard certificate types
+ * from the framework. Certificates can be stored in the framework using
+ * the WifiKeystore#put system API.
+ *
+ * Must be registered by the client at initialization, so that
+ * supplicant can call into the client to retrieve any values.
+ */
+@VintfStability
+interface INonStandardCertCallback {
+ /**
+ * Requests a binary blob from the certificate key-value store.
+ *
+ * @param alias Key into the key-value mapping.
+ * @return Value associated with |alias| in the certificate store.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ byte[] getBlob(in String alias);
+
+ /**
+ * List the aliases currently stored in the database.
+ *
+ * @param prefix Prefix to filter the aliases by.
+ * @return List of alias strings in the certificate store.
+ The resulting strings will each exclude the prefix.
+ */
+ String[] listAliases(in String prefix);
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
index c17289d..b187c2f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -17,6 +17,7 @@
package android.hardware.wifi.supplicant;
import android.hardware.wifi.supplicant.DebugLevel;
+import android.hardware.wifi.supplicant.INonStandardCertCallback;
import android.hardware.wifi.supplicant.ISupplicantCallback;
import android.hardware.wifi.supplicant.ISupplicantP2pIface;
import android.hardware.wifi.supplicant.ISupplicantStaIface;
@@ -158,4 +159,14 @@
* wait to be restarted.
*/
oneway void terminate();
+
+ /**
+ * Register a Non-Standard Certificate callback with supplicant.
+ *
+ * @param callback An instance of the |INonStandardCertCallback| AIDL interface
+ * object.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ void registerNonStandardCertCallback(in INonStandardCertCallback callback);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 313ee8b..e58422c 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -827,4 +827,22 @@
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
void setVendorElements(in P2pFrameTypeMask frameTypeMask, in byte[] vendorElemBytes);
+
+ /**
+ * Configure the IP addresses in supplicant for P2P GO to provide the IP address to
+ * client in EAPOL handshake. Refer Wi-Fi P2P Technical Specification v1.7 - Section 4.2.8
+ * "IP Address Allocation in EAPOL-Key Frames (4-Way Handshake)" for more details.
+ * The IP addresses are IPV4 addresses and higher-order address bytes are in the lower-order
+ * int bytes (e.g. 1.2.3.4 is represented as 0x04030201)
+ *
+ * @param ipAddressGo The P2P Group Owner IP address.
+ * @param ipAddressMask The P2P Group owner subnet mask.
+ * @param ipAddressStart The starting address in the IP address pool.
+ * @param ipAddressEnd The ending address in the IP address pool.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ void configureEapolIpAddressAllocationParams(
+ in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 7c8c1f2..9d6fa67 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -17,6 +17,7 @@
package android.hardware.wifi.supplicant;
import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
+import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
import android.hardware.wifi.supplicant.P2pStatusCode;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -243,4 +244,11 @@
in byte[] primaryDeviceType, in String deviceName, in WpsConfigMethods configMethods,
in byte deviceCapabilities, in P2pGroupCapabilityMask groupCapabilities,
in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
+
+ /**
+ * Used to indicate the start of a P2P group, with some parameters describing the group.
+ *
+ * @param groupStartedEventParams Parameters describing the P2P group.
+ */
+ void onGroupStartedWithParams(in P2pGroupStartedEventParams groupStartedEventParams);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 9edf210..06ab8fb 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -29,8 +29,11 @@
import android.hardware.wifi.supplicant.IfaceType;
import android.hardware.wifi.supplicant.KeyMgmtMask;
import android.hardware.wifi.supplicant.MloLinksInfo;
+import android.hardware.wifi.supplicant.QosPolicyScsData;
+import android.hardware.wifi.supplicant.QosPolicyScsRequestStatus;
import android.hardware.wifi.supplicant.QosPolicyStatus;
import android.hardware.wifi.supplicant.RxFilterType;
+import android.hardware.wifi.supplicant.SignalPollResult;
import android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -781,4 +784,70 @@
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
void stopRxFilter();
+
+ /**
+ * This method returns the signal poll results. Results will be for each
+ * link in case of Multiple Link Operation (MLO).
+ *
+ * @return Signal Poll Results per link.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ * |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+ */
+ SignalPollResult[] getSignalPollResults();
+
+ /**
+ * Maximum number of policies that can be included in a QoS SCS add/remove request.
+ */
+ const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
+
+ /**
+ * Send a set of QoS SCS policy add requests to the AP.
+ *
+ * This is a request to the AP (if it supports the feature) to apply the QoS policies
+ * on traffic in the downlink.
+ *
+ * Synchronous response will indicate which policies were sent to the AP, and which
+ * were rejected immediately by supplicant. Caller will also receive an asynchronous
+ * response in |ISupplicantStaIfaceCallback.onQosPolicyResponseForScs| indicating
+ * the response from the AP for each policy that was sent.
+ *
+ * @param qosPolicyScsData QoS policies info provided by STA.
+ * @return QosPolicyScsRequestStatus[] synchronously corresponding to all
+ * the scs policies. Size of the result array will be the same as
+ * the size of the input array.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN| if the number of policies in the
+ * request is greater than |MAX_POLICIES_PER_QOS_SCS_REQUEST|
+ *
+ * |SupplicantStatusCode.FAILURE_UNSUPPORTED| if the AP does not support
+ * the feature.
+ *
+ * |SupplicantStatusCode.FAILURE_ONGOING_REQUEST| if a request is currently
+ * being processed. Supplicant will only handle one request at a time.
+ */
+ QosPolicyScsRequestStatus[] addQosPolicyRequestForScs(in QosPolicyScsData[] qosPolicyData);
+
+ /**
+ * Request the removal of specific QoS policies for SCS configured by the STA.
+ *
+ * Synchronous response will indicate which policies were sent to the AP, and which
+ * were rejected immediately by supplicant. Caller will also receive an asynchronous
+ * response in |ISupplicantStaIfaceCallback.onQosPolicyResponseForScs| indicating
+ * the response from the AP for each policy that was sent.
+ *
+ * @param scsPolicyIds policy id's to be removed.
+ * @return QosPolicyScsRequestStatus[] synchronously corresponding to all
+ * the scs policies.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN| if the number of policies in the
+ * request is greater than |MAX_POLICIES_PER_QOS_SCS_REQUEST|
+ *
+ * |SupplicantStatusCode.FAILURE_UNSUPPORTED| if the AP does not support
+ * the feature.
+ *
+ * |SupplicantStatusCode.FAILURE_ONGOING_REQUEST| if a request is currently
+ * being processed. Supplicant will only handle one request at a time.
+ */
+ QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 0730a8c..17a220d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -22,15 +22,20 @@
import android.hardware.wifi.supplicant.BssTmData;
import android.hardware.wifi.supplicant.BssidChangeReason;
import android.hardware.wifi.supplicant.DppAkm;
+import android.hardware.wifi.supplicant.DppConfigurationData;
import android.hardware.wifi.supplicant.DppConnectionKeys;
import android.hardware.wifi.supplicant.DppEventType;
import android.hardware.wifi.supplicant.DppFailureCode;
import android.hardware.wifi.supplicant.DppProgressCode;
+import android.hardware.wifi.supplicant.DppStatusErrorCode;
import android.hardware.wifi.supplicant.Hs20AnqpData;
import android.hardware.wifi.supplicant.OsuMethod;
+import android.hardware.wifi.supplicant.PmkSaCacheData;
import android.hardware.wifi.supplicant.QosPolicyData;
+import android.hardware.wifi.supplicant.QosPolicyScsResponseStatus;
import android.hardware.wifi.supplicant.StaIfaceCallbackState;
import android.hardware.wifi.supplicant.StaIfaceReasonCode;
+import android.hardware.wifi.supplicant.SupplicantStateChangeData;
import android.hardware.wifi.supplicant.WpsConfigError;
import android.hardware.wifi.supplicant.WpsErrorIndication;
@@ -143,6 +148,9 @@
* Indicates DPP configuration received success event in Enrolee mode.
* This is also triggered when Configurator generates credentials for itself
* using generateSelfDppConfiguration() API
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+ * onDppConfigReceived.
*/
void onDppSuccessConfigReceived(in byte[] ssid, in String password, in byte[] psk,
in DppAkm securityAkm, in DppConnectionKeys dppConnectionKeys);
@@ -241,6 +249,8 @@
/**
* Indicates pairwise master key (PMK) cache added event.
*
+ * @deprecated use onPmkSaCacheAdded() instead.
+ *
* @param expirationTimeInSec expiration time in seconds
* @param serializedEntry is serialized PMK cache entry, the content is
* opaque for the framework and depends on the native implementation.
@@ -252,6 +262,9 @@
* event is triggered by a particular network, the |SupplicantNetworkId|,
* |ssid|, |bssid| parameters must indicate the parameters of the network/AP
* which caused this state transition.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+ * onSupplicantStateChanged()
*
* @param newState New State of the interface. This must be one of the |State|
* values above.
@@ -303,4 +316,91 @@
* @param qosPolicyData QoS policies info requested by the AP.
*/
void onQosPolicyRequest(in int qosPolicyRequestId, in QosPolicyData[] qosPolicyData);
+
+ /**
+ * Reason codes to be used with the callback |ISupplicantStaIfaceCallback.onMloLinksInfoChanged|
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum MloLinkInfoChangeReason {
+ /**
+ * TID-to-link mapping has changed. Updated mappings will be set in
+ * |MloLinksInfo.MloLink[].tids_downlink_map| and
+ * |MloLinksInfo.MloLink[].tids_uplink_map| for each of the links.
+ *
+ * STA MLD will operate in default mode if a TID-to-link mapping is not
+ * indicated by the callback. In default mode, all TIDs are mapped to
+ * all setup links in downlink and uplink directions.
+ */
+ TID_TO_LINK_MAP = 0,
+ /**
+ * Multi-link reconfiguration - AP removal as described in
+ * IEEE 802.11be spec, section 35.3.6. This is a mandatory feature for
+ * station.
+ *
+ * Removed link will not be present in |ISupplicantStaIface.getConnectionMloLinksInfo|.
+ */
+ MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+ }
+
+ /**
+ * Used to indicate that Multi Link status has changed due to the provided
+ * reason. Upadted MLO link status can be fetched using
+ * |ISupplicantStaIface.getConnectionMloLinksInfo|
+ *
+ * |MloLink.linkId| and |MloLink.staLinkMacAddress| are not expected
+ * to change.
+ *
+ * @param reason Reason as given in MloLinkInfoChangeReason.
+ */
+ void onMloLinksInfoChanged(in MloLinkInfoChangeReason reason);
+
+ /**
+ * Indicates DPP configuration received success event in Enrollee mode.
+ * This is also triggered when Configurator generates credentials for itself
+ * using generateSelfDppConfiguration() API
+ */
+ void onDppConfigReceived(in DppConfigurationData configData);
+
+ /**
+ * Indicates that DPP connection status result frame is sent.
+ */
+ void onDppConnectionStatusResultSent(in DppStatusErrorCode code);
+
+ /**
+ * Used to indicate that the operating frequency has changed for this BSS.
+ * This event is triggered when STA switches the channel due to channel
+ * switch announcement from the connected access point.
+ *
+ * @param frequencyMhz New operating frequency in MHz.
+ */
+ void onBssFrequencyChanged(in int frequencyMhz);
+
+ /**
+ * Used to indicate a state change event on this particular iface.
+ *
+ * @param stateChangeData Supplicant state change related information.
+ */
+ void onSupplicantStateChanged(in SupplicantStateChangeData stateChangeData);
+
+ /**
+ * Indicates an SCS response from the AP.
+ *
+ * If the AP does not send a response within the timeout period (1 sec),
+ * supplicant will call this API with the TIMEOUT status for each policy.
+ *
+ * The AP can trigger an unsolicited scs response to indicate the removal of
+ * previously requested policies.
+ *
+ * @param qosPolicyScsResponseStatus[] status for each SCS id.
+ */
+ void onQosPolicyResponseForScs(in QosPolicyScsResponseStatus[] qosPolicyScsResponseStatus);
+
+ /**
+ * Indicates pairwise master key (PMK) cache added event.
+ *
+ * @param pmkSaData PMKSA cache entry added details.
+ *
+ */
+ void onPmkSaCacheAdded(in PmkSaCacheData pmkSaData);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 267f1e8..750cf72 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -31,6 +31,7 @@
import android.hardware.wifi.supplicant.PairwiseCipherMask;
import android.hardware.wifi.supplicant.ProtoMask;
import android.hardware.wifi.supplicant.SaeH2eMode;
+import android.hardware.wifi.supplicant.TlsVersion;
/**
* Interface exposed by the supplicant for each station mode network
@@ -1118,4 +1119,26 @@
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
+
+ /**
+ * Set the minimum TLS version for EAP phase1 param.
+ *
+ * @param tlsVersion the TLS version
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void setMinimumTlsVersionEapPhase1Param(TlsVersion tlsVersion);
+
+ /**
+ * Enable the strict conservative peer mode for EAP-SIM/AKA/AKA'
+ *
+ * @param enable true to enable, false to disable.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void setStrictConservativePeerMode(in boolean enable);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index de7b675..4f892be 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -71,4 +71,11 @@
*/
void onServerCertificateAvailable(
in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
+
+ /**
+ * Used to notify the AT_PERMANENT_ID_REQ denied event.
+ *
+ * In strict conservative mode, AT_PERMANENT_ID_REQ is denied from eap_peer side.
+ */
+ void onPermanentIdReqDenied();
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
index 0e23728..0b4d66e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
@@ -30,4 +30,40 @@
* STA Link MAC Address
*/
byte[/* 6 */] staLinkMacAddress;
+ /**
+ * Bitset where each bit indicates TID mapped to this link in uplink and
+ * downlink direction.
+ *
+ * Traffic Identifier (TID) is an identifier used to classify a packet. It
+ * is represented as a four bit number identifying the QoS traffic within
+ * MAC data service. There are 16 possible values for TID, out of only 8 are
+ * practically used to identify differentiated services.
+ *
+ * A TID-to-link mapping indicates links on which frames belonging to each
+ * TID can be exchanged. IEEE 802.11be draft 2.0 defines the mapping for TID
+ * values between 0 to 7 only. Once associated, an MLO link state is
+ * considered as active if at least one TID is mapped to the link. Link
+ * state is considered as idle if no TID is mapped to the link.
+ *
+ * TIDs can be mapped to uplink, downlink or both directions.
+ * e.g.
+ * - TID 4 is mapped to this link in uplink direction, if bit 4 in
+ * MloLink#tids_uplink_map is set.
+ * - TID 2 is mapped to both directions for this link, if bit 2 of both
+ * MloLink#tids_uplink_map and MloLink#tids_downlink_map are set.
+ *
+ * In case of default link mapping, tids_uplink_map and tids_downlink_map
+ * is set to 0xFF for all the links.
+ *
+ */
+ byte tidsUplinkMap;
+ byte tidsDownlinkMap;
+ /**
+ * AP Link MAC Address
+ */
+ @nullable byte[6] apLinkMacAddress;
+ /**
+ * Frequency on which the link operates in MHz.
+ */
+ int frequencyMHz;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl
index 2f14717..3b81df8 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLinksInfo.aidl
@@ -28,4 +28,12 @@
* List of MLO links
*/
MloLink[] links;
+ /**
+ * The MLO link-id for the access point. It is the link-id used for association.
+ */
+ int apMloLinkId;
+ /**
+ * AP MLD MAC address.
+ */
+ @nullable byte[6] apMldMacAddress;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
new file mode 100644
index 0000000..148e4a4
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pClientEapolIpAddressInfo.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * P2P Client IPV4 address allocated via EAPOL exchange.
+ * The IP addresses are IPV4 addresses and higher-order address bytes are in the lower-order
+ * int bytes (e.g. 1.2.3.4 is represented as 0x04030201)
+ */
+@VintfStability
+parcelable P2pClientEapolIpAddressInfo {
+ /**
+ * The P2P Client IP address.
+ */
+ int ipAddressClient;
+ /**
+ * The subnet that the P2P Group Owner is using.
+ */
+ int ipAddressMask;
+ /**
+ * The P2P Group Owner IP address.
+ */
+ int ipAddressGo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
new file mode 100644
index 0000000..96f1e16
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo;
+
+/**
+ * Parameters passed as part of Wifi P2P group start event.
+ */
+@VintfStability
+parcelable P2pGroupStartedEventParams {
+ /** Interface name of the group (For ex: p2p-p2p0-1). */
+ String groupInterfaceName;
+
+ /** Whether this device is owner of the group. */
+ boolean isGroupOwner;
+
+ /** SSID of the group. */
+ byte[] ssid;
+
+ /** Frequency in MHz on which this group is created. */
+ int frequencyMHz;
+
+ /** PSK used to secure the group. */
+ byte[] psk;
+
+ /** PSK passphrase used to secure the group. */
+ String passphrase;
+
+ /** Whether this group is persisted or not. */
+ boolean isPersistent;
+
+ /** MAC Address of the owner of this group. */
+ byte[6] goDeviceAddress;
+
+ /** MAC Address of the P2P interface of the owner of this group. */
+ byte[6] goInterfaceAddress;
+
+ /**
+ * Flag to indicate that the P2P Client IP address is allocated via EAPOL exchange.
+ */
+ boolean isP2pClientEapolIpAddressInfoPresent;
+
+ /**
+ * The P2P Client IP Address allocated by the P2P Group Owner in EAPOL
+ * key exchange.
+ * Refer Wi-Fi P2P Technical Specification v1.7 - Section 4.2.8
+ * "IP Address Allocation in EAPOL-Key Frames (4-Way Handshake)" for more details.
+ * The value is undefined if isP2pClientEapolIpAddressInfoPresent is false.
+ */
+ P2pClientEapolIpAddressInfo p2pClientIpInfo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
new file mode 100644
index 0000000..e0f1d31
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.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;
+
+/**
+ * Details of the PMKSA cache entry that was added in supplicant.
+ */
+@VintfStability
+parcelable PmkSaCacheData {
+ /**
+ * BSSID of the access point to which the station is associated.
+ */
+ byte[6] bssid;
+ /**
+ * PMK expiration time in seconds.
+ */
+ long expirationTimeInSec;
+ /**
+ * Serialized PMK cache entry.
+ * The content is opaque for the framework and depends on the native implementation.
+ */
+ byte[] serializedEntry;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
index d95d18d..478b09d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParams.aidl
@@ -62,4 +62,10 @@
* "reg-name" in RFC 3986.
*/
String domainName;
+
+ /**
+ * Differentiated Services Code Point (DSCP) value.
+ * Used by AP for mapping the data streams to apply the user priority.
+ */
+ byte dscp;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
index 51bc14c..c15fec0 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyClassifierParamsMask.aidl
@@ -29,4 +29,5 @@
PROTOCOL_NEXT_HEADER = 1 << 4,
FLOW_LABEL = 1 << 5,
DOMAIN_NAME = 1 << 6,
+ DSCP = 1 << 7,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
new file mode 100644
index 0000000..86a4dac
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -0,0 +1,24 @@
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
+
+/**
+ * QoS policy information in SCS request.
+ * TCLAS Processing element is always set to 0.
+ */
+@VintfStability
+parcelable QosPolicyScsData {
+ /** SCS QoS Policy identifier. */
+ byte policyId;
+
+ /**
+ * User Priority (UP) which the AP should apply to streams that match
+ * the classifier parameters.
+ */
+ byte userPriority;
+
+ /**
+ * QoS policy SCS classifier type information.
+ */
+ QosPolicyClassifierParams classifierParams;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
new file mode 100644
index 0000000..e233f32
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatus.aidl
@@ -0,0 +1,13 @@
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode;
+
+/**
+ * QoS policy status info per scsId. Returned immediately by supplicant
+ * upon SCS request.
+ */
+@VintfStability
+parcelable QosPolicyScsRequestStatus {
+ byte policyId;
+ QosPolicyScsRequestStatusCode qosPolicyScsRequestStatusCode;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
new file mode 100644
index 0000000..daf1578
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsRequestStatusCode.aidl
@@ -0,0 +1,25 @@
+package android.hardware.wifi.supplicant;
+
+/**
+ * Enum values for QoS policy request status.
+ */
+@VintfStability
+@Backing(type="int")
+enum QosPolicyScsRequestStatusCode {
+ /**
+ * SCS request was sent to the AP.
+ */
+ SENT,
+ /**
+ * Add request conflicts with an existing policy ID.
+ */
+ ALREADY_ACTIVE,
+ /**
+ * Remove request is for a policy ID that does not exist.
+ */
+ NOT_EXIST,
+ /**
+ * QoS policy params are invalid.
+ */
+ INVALID,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
new file mode 100644
index 0000000..846a0e2
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatus.aidl
@@ -0,0 +1,13 @@
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.QosPolicyScsResponseStatusCode;
+
+/**
+ * QoS policy status info per scsId. Returned in a callback once replies are
+ * received from the AP.
+ */
+@VintfStability
+parcelable QosPolicyScsResponseStatus {
+ byte policyId;
+ QosPolicyScsResponseStatusCode qosPolicyScsResponseStatusCode;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
new file mode 100644
index 0000000..f4ecd2a
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsResponseStatusCode.aidl
@@ -0,0 +1,46 @@
+package android.hardware.wifi.supplicant;
+
+/**
+ * Enum values for QoS policy response status.
+ */
+@VintfStability
+@Backing(type="int")
+enum QosPolicyScsResponseStatusCode {
+ SUCCESS,
+ /**
+ * Network policy does not permit the stream to be assigned the requested
+ * user priority (UP), but the AP might accept another request from the STA
+ * with the same TCLAS classifier(s) but a different user priority (UP).
+ */
+ TCLAS_REQUEST_DECLINED,
+ /**
+ * Requested TCLAS processing is not supported by the AP.
+ */
+ TCLAS_NOT_SUPPORTED_BY_AP,
+ /**
+ * The AP has insufficient TCLAS processing resources to satisfy the request
+ * (i.e. to classify and process the traffic).
+ */
+ TCLAS_INSUFFICIENT_RESOURCES,
+ /**
+ * Sufficient TCLAS processing resources were available when the SCS
+ * stream was created, but are no longer available.
+ */
+ TCLAS_RESOURCES_EXHAUSTED,
+ /**
+ * Insufficient capacity to sustain the current QoS treatment.
+ */
+ TCLAS_PROCESSING_TERMINATED_INSUFFICIENT_QOS,
+ /**
+ * Conflict with a (new or dynamic) network policy.
+ */
+ TCLAS_PROCESSING_TERMINATED_POLICY_CONFLICT,
+ /**
+ * Other reason for decline.
+ */
+ TCLAS_PROCESSING_TERMINATED,
+ /**
+ * AP did not send a response within the timeout period (1 sec).
+ */
+ TIMEOUT,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl
new file mode 100644
index 0000000..a3b11a0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SignalPollResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Signal polling results.
+ */
+@VintfStability
+parcelable SignalPollResult {
+ /**
+ * Link identifier.
+ */
+ int linkId;
+ /**
+ * RSSI value in dBM.
+ */
+ int currentRssiDbm;
+ /**
+ * Last transmitted packet bit rate in Mbps.
+ */
+ int txBitrateMbps;
+ /**
+ * Last received packet bit rate in Mbps.
+ */
+ int rxBitrateMbps;
+ /**
+ * Frequency in MHz.
+ */
+ int frequencyMhz;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
new file mode 100644
index 0000000..f7c66e0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStateChangeData.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.hardware.wifi.supplicant.StaIfaceCallbackState;
+
+/**
+ * Supplicant state change related information.
+ */
+@VintfStability
+parcelable SupplicantStateChangeData {
+ /**
+ * New State of the interface. This must be one of the
+ * |StaIfaceCallbackState| values.
+ */
+ StaIfaceCallbackState newState;
+ /**
+ * ID of the corresponding network which caused this
+ * state change event. This must be invalid (-1) if this
+ * event is not specific to a particular network.
+ */
+ int id;
+ /**
+ * SSID of the corresponding network which caused this state
+ * change event. This must be empty if this event is not specific
+ * to a particular network.
+ */
+ byte[] ssid;
+ /**
+ * BSSID of the corresponding AP which caused this state
+ * change event. This must be zero'ed if this event is not
+ * specific to a particular network.
+ */
+ byte[6] bssid;
+
+ /**
+ * Currently used key mgmt mask.
+ */
+ KeyMgmtMask keyMgmtMask;
+ /*
+ * Frequency of the connected channel in MHz. This must be zero if this
+ * event is not specific to a particular network.
+ */
+ int frequencyMhz;
+ /*
+ * Flag to indicate that FILS HLP IEs were included in this association.
+ * This flag is valid only for WPA_COMPLETED state change.
+ */
+ boolean filsHlpSent;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index c7b7ffd..e97d6ee 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -63,4 +63,8 @@
*/
FAILURE_NETWORK_UNKNOWN,
FAILURE_UNSUPPORTED,
+ /**
+ * A different request is currently being processed.
+ */
+ FAILURE_ONGOING_REQUEST,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl
new file mode 100644
index 0000000..316e881
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TlsVersion.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * TlsVersion: TLS version.
+ */
+@VintfStability
+@Backing(type="int")
+enum TlsVersion {
+ TLS_V1_0,
+ TLS_V1_1,
+ TLS_V1_2,
+ TLS_V1_3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 08006cf..a9434c4 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -42,4 +42,12 @@
* Trust On First Use
*/
TRUST_ON_FIRST_USE = 1 << 4,
+ /**
+ * TLS minimum version
+ */
+ SET_TLS_MINIMUM_VERSION = 1 << 5,
+ /**
+ * TLS V1.3
+ */
+ TLS_V1_3 = 1 << 6,
}
diff --git a/wifi/supplicant/aidl/lint-baseline.xml b/wifi/supplicant/aidl/lint-baseline.xml
new file mode 100644
index 0000000..0631223
--- /dev/null
+++ b/wifi/supplicant/aidl/lint-baseline.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.0.0-dev" type="baseline" dependencies="true" variant="all" version="8.0.0-dev">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicant.java"
+ line="84"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantCallback.java"
+ line="43"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIface.java"
+ line="237"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.java"
+ line="91"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.java"
+ line="76"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIface.java"
+ line="235"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.java"
+ line="124"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetwork.java"
+ line="354"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V1-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.java"
+ line="52"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/INonStandardCertCallback.java"
+ line="67"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicant.java"
+ line="200"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantCallback.java"
+ line="60"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIface.java"
+ line="928"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.java"
+ line="265"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.java"
+ line="164"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIface.java"
+ line="939"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.java"
+ line="390"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetwork.java"
+ line="1239"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+ errorLine1=" this.markVintfStability();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="out/.intermediates/hardware/interfaces/wifi/supplicant/aidl/android.hardware.wifi.supplicant-V2-java-source/gen/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.java"
+ line="97"
+ column="12"/>
+ </issue>
+
+</issues>
\ No newline at end of file
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 8e142ec..f7c619a 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -44,12 +44,14 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
"libwifi-system",
"libwifi-system-iface",
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "VtsHalWifiTargetTestUtil",
],
test_suites: [
"general-tests",
@@ -78,12 +80,14 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
"libwifi-system",
"libwifi-system-iface",
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "VtsHalWifiTargetTestUtil",
],
test_suites: [
"general-tests",
@@ -112,12 +116,14 @@
"[email protected]",
"[email protected]",
"[email protected]",
- "android.hardware.wifi.supplicant-V1-ndk",
+ "android.hardware.wifi.supplicant-V2-ndk",
"libwifi-system",
"libwifi-system-iface",
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiSupplicantV1_0TargetTestUtil",
+ "android.hardware.wifi-V1-ndk",
+ "VtsHalWifiTargetTestUtil",
],
test_suites: [
"general-tests",
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_aidl_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_aidl_test_utils.h
new file mode 100644
index 0000000..a850e50
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_aidl_test_utils.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VtsCoreUtil.h>
+#include <aidl/android/hardware/wifi/IWifi.h>
+#include <android-base/logging.h>
+#include <wifi_system/supplicant_manager.h>
+
+#include "wifi_aidl_test_utils.h"
+
+using android::wifi_system::SupplicantManager;
+
+// Helper methods to interact with wifi_aidl_test_utils
+namespace SupplicantAidlTestUtils {
+const std::string kWifiInstanceNameStr = std::string() + IWifi::descriptor + "/default";
+const char* kWifiInstanceName = kWifiInstanceNameStr.c_str();
+
+// Initialize the driver and firmware to STA mode using the vendor HAL.
+void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ // Skip if wifi instance is not set.
+ if (wifi_instance_name == "") {
+ return;
+ }
+ if (getWifi(wifi_instance_name.c_str()) != nullptr) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name.c_str());
+ int mode_id;
+ EXPECT_TRUE(configureChipToSupportConcurrencyType(wifi_chip, IfaceConcurrencyType::STA,
+ &mode_id));
+ } else {
+ LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+ }
+}
+
+// Deinitialize the driver and firmware using the vendor HAL.
+void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
+ // Skip if wifi instance is not set.
+ if (wifi_instance_name == "") {
+ return;
+ }
+ if (getWifi(wifi_instance_name.c_str()) != nullptr) {
+ stopWifiService(wifi_instance_name.c_str());
+ } else {
+ LOG(WARNING) << __func__ << ": Vendor HAL not supported";
+ }
+}
+
+bool waitForSupplicantState(bool is_running) {
+ SupplicantManager supplicant_manager;
+ int count = 50; /* wait at most 5 seconds for completion */
+ while (count-- > 0) {
+ if (supplicant_manager.IsSupplicantRunning() == is_running) {
+ return true;
+ }
+ usleep(100000);
+ }
+ LOG(ERROR) << "Unable to " << (is_running ? "start" : "stop") << " supplicant";
+ return false;
+}
+
+bool waitForSupplicantStart() {
+ return waitForSupplicantState(true);
+}
+
+bool waitForSupplicantStop() {
+ return waitForSupplicantState(false);
+}
+
+bool waitForWifiHalStop(const std::string& wifi_instance_name) {
+ std::shared_ptr<IWifi> wifi = getWifi(wifi_instance_name.c_str());
+ int count = 50; /* wait at most 5 seconds for completion */
+ while (count-- > 0) {
+ if (wifi != nullptr) {
+ bool started = false;
+ auto status = wifi->isStarted(&started);
+ if (status.isOk() && !started) {
+ return true;
+ }
+ }
+ usleep(100000);
+ wifi = getWifi(wifi_instance_name.c_str());
+ }
+ LOG(ERROR) << "Wifi HAL was not stopped";
+ return false;
+}
+
+bool waitForFrameworkReady() {
+ int waitCount = 15;
+ do {
+ // Check whether package service is ready or not.
+ if (!testing::checkSubstringInCommandOutput("/system/bin/service check package",
+ ": not found")) {
+ return true;
+ }
+ LOG(INFO) << "Framework is not ready";
+ sleep(1);
+ } while (waitCount-- > 0);
+ return false;
+}
+
+bool useAidlService() {
+ return isAidlServiceAvailable(kWifiInstanceName);
+}
+
+void startSupplicant() {
+ initializeDriverAndFirmware(kWifiInstanceName);
+ SupplicantManager supplicant_manager;
+ ASSERT_TRUE(supplicant_manager.StartSupplicant());
+ ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
+}
+
+void stopSupplicantService() {
+ SupplicantManager supplicant_manager;
+ ASSERT_TRUE(supplicant_manager.StopSupplicant());
+ deInitializeDriverAndFirmware(kWifiInstanceName);
+ ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
+}
+
+bool stopWifiFramework(const std::string& wifi_instance_name) {
+ std::system("svc wifi disable");
+ std::system("cmd wifi set-scan-always-available disabled");
+ return waitForSupplicantStop() && waitForWifiHalStop(wifi_instance_name);
+}
+
+void initializeService() {
+ ASSERT_TRUE(stopWifiFramework(kWifiInstanceName));
+ std::system("/system/bin/start");
+ ASSERT_TRUE(waitForFrameworkReady());
+ stopSupplicantService();
+ startSupplicant();
+}
+} // namespace SupplicantAidlTestUtils
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_legacy_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_legacy_test_utils.h
new file mode 100644
index 0000000..a20a458
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_legacy_test_utils.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <VtsCoreUtil.h>
+#include <android-base/logging.h>
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <hidl/ServiceManagement.h>
+#include <supplicant_hidl_test_utils.h>
+#include <wifi_system/supplicant_manager.h>
+
+using android::wifi_system::SupplicantManager;
+
+// Helper methods to interact with supplicant_hidl_test_utils
+namespace SupplicantLegacyTestUtils {
+std::string getWifiInstanceName() {
+ const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
+ ::android::hardware::wifi::V1_0::IWifi::descriptor);
+ EXPECT_NE(0, instances.size());
+ return instances.size() != 0 ? instances[0] : "";
+}
+
+void stopSupplicantService() {
+ stopSupplicant(getWifiInstanceName());
+}
+
+void startSupplicant() {
+ initializeDriverAndFirmware(getWifiInstanceName());
+ SupplicantManager supplicant_manager;
+ ASSERT_TRUE(supplicant_manager.StartSupplicant());
+ ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
+}
+
+void initializeService() {
+ ASSERT_TRUE(stopWifiFramework(getWifiInstanceName()));
+ std::system("/system/bin/start");
+ ASSERT_TRUE(waitForFrameworkReady());
+ stopSupplicantService();
+ startSupplicant();
+}
+} // namespace SupplicantLegacyTestUtils
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 d95bd03..a260408 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
@@ -19,6 +19,7 @@
#include <aidl/Vintf.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <binder/IServiceManager.h>
@@ -36,8 +37,10 @@
using aidl::android::hardware::wifi::supplicant::MiracastMode;
using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
+using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
using aidl::android::hardware::wifi::supplicant::P2pStatusCode;
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
using aidl::android::hardware::wifi::supplicant::WpsDevPasswordId;
using aidl::android::hardware::wifi::supplicant::WpsProvisionMethod;
@@ -175,6 +178,10 @@
const std::vector<uint8_t>& /* vendorElemBytes */) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onGroupStartedWithParams(
+ const P2pGroupStartedEventParams& /* groupStartedEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
};
class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {
@@ -413,7 +420,12 @@
*/
TEST_P(SupplicantP2pIfaceAidlTest, EnableMacRandomization) {
// Enable twice
- EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
+ auto status = p2p_iface_->setMacRandomization(true);
+ if (!status.isOk() && status.getServiceSpecificError() ==
+ static_cast<int32_t>(SupplicantStatusCode::FAILURE_UNSUPPORTED)) {
+ GTEST_SKIP() << "Mac randomization is not supported.";
+ }
+ EXPECT_TRUE(status.isOk());
EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
// Disable twice
@@ -524,16 +536,11 @@
* Connect
*/
TEST_P(SupplicantP2pIfaceAidlTest, Connect) {
- /*
- * Auto-join is not enabled before R. After enabling auto-join,
- * this should always succeed.
- */
std::string pin;
EXPECT_TRUE(p2p_iface_
- ->connect(kTestMacAddr, WpsProvisionMethod::PBC,
- kTestConnectPin, false, false,
- kTestConnectGoIntent, &pin)
- .isOk());
+ ->connect(kTestMacAddr, WpsProvisionMethod::PBC, kTestConnectPin, true,
+ false, kTestConnectGoIntent, &pin)
+ .isOk());
}
/*
@@ -542,10 +549,9 @@
TEST_P(SupplicantP2pIfaceAidlTest, CancelConnect) {
std::string pin;
EXPECT_TRUE(p2p_iface_
- ->connect(kTestMacAddr, WpsProvisionMethod::PBC,
- kTestConnectPin, false, false,
- kTestConnectGoIntent, &pin)
- .isOk());
+ ->connect(kTestMacAddr, WpsProvisionMethod::PBC, kTestConnectPin, true,
+ false, kTestConnectGoIntent, &pin)
+ .isOk());
EXPECT_TRUE(p2p_iface_->cancelConnect().isOk());
}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index 272a427..5d00485 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -206,6 +206,39 @@
QosPolicyData /* qosPolicyData */>&) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onSupplicantStateChanged(
+ const ::aidl::android::hardware::wifi::supplicant::
+ SupplicantStateChangeData& /* stateChangeData */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onMloLinksInfoChanged(
+ ::aidl::android::hardware::wifi::supplicant::ISupplicantStaIfaceCallback::
+ MloLinkInfoChangeReason /* reason */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onDppConfigReceived(
+ const ::aidl::android::hardware::wifi::supplicant::
+ DppConfigurationData& /* configData */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onDppConnectionStatusResultSent(
+ ::aidl::android::hardware::wifi::supplicant::DppStatusErrorCode /* code */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onBssFrequencyChanged(int32_t /* frequencyMhz */) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onQosPolicyResponseForScs(
+ const std::vector<::aidl::android::hardware::wifi::supplicant::
+ QosPolicyScsResponseStatus>& /* qosPolicyScsResponseStatus */)
+ override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onPmkSaCacheAdded(
+ const ::aidl::android::hardware::wifi::supplicant::PmkSaCacheData& /* pmkSaData */)
+ override {
+ return ndk::ScopedAStatus::ok();
+ }
};
class SupplicantStaIfaceAidlTest : 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 b3f70da..0e2b72c 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
@@ -19,6 +19,7 @@
#include <aidl/Vintf.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaNetworkCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/TlsVersion.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <binder/IServiceManager.h>
@@ -51,6 +52,7 @@
using aidl::android::hardware::wifi::supplicant::PairwiseCipherMask;
using aidl::android::hardware::wifi::supplicant::ProtoMask;
using aidl::android::hardware::wifi::supplicant::SaeH2eMode;
+using aidl::android::hardware::wifi::supplicant::TlsVersion;
using aidl::android::hardware::wifi::supplicant::TransitionDisableIndication;
using aidl::android::hardware::wifi::supplicant::WpaDriverCapabilitiesMask;
using android::ProcessState;
@@ -98,6 +100,7 @@
const std::vector<uint8_t>& /* certBlob */) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onPermanentIdReqDenied() override { return ndk::ScopedAStatus::ok(); }
};
class SupplicantStaNetworkAidlTest
@@ -648,6 +651,14 @@
}
/*
+ * SetStrictConservativePeerMode
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetStrictConversativePeerMode) {
+ EXPECT_TRUE(sta_network_->setStrictConservativePeerMode(true).isOk());
+ EXPECT_TRUE(sta_network_->setStrictConservativePeerMode(false).isOk());
+}
+
+/*
* SendNetworkEapIdentityResponse
*/
TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapIdentityResponse) {
@@ -791,6 +802,21 @@
EXPECT_TRUE(sta_network_->setRoamingConsortiumSelection(testSelection).isOk());
}
+/*
+ * SetMinimumTlsVersionEapPhase1Param
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetMinimumTlsVersionEapPhase1Param) {
+ WpaDriverCapabilitiesMask caps;
+ EXPECT_TRUE(sta_iface_->getWpaDriverCapabilities(&caps).isOk());
+ const bool tlsV13Supported = !!(static_cast<uint32_t>(caps) &
+ static_cast<uint32_t>(WpaDriverCapabilitiesMask::TLS_V1_3));
+ LOG(INFO) << "TLS_V1_3 Supported: " << tlsV13Supported;
+
+ // Operation will succeed if TLS_V1_3 is supported, or fail otherwise.
+ EXPECT_EQ(sta_network_->setMinimumTlsVersionEapPhase1Param(TlsVersion::TLS_V1_3).isOk(),
+ tlsV13Supported);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index 31042a2..7eeab68 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -14,22 +14,16 @@
* limitations under the License.
*/
-#ifndef SUPPLICANT_TEST_UTILS_H
-#define SUPPLICANT_TEST_UTILS_H
+#pragma once
-#include <VtsCoreUtil.h>
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.0/IWifi.h>
-#include <hidl/ServiceManagement.h>
-#include <supplicant_hidl_test_utils.h>
-#include <wifi_system/supplicant_manager.h>
+#include "supplicant_aidl_test_utils.h"
+#include "supplicant_legacy_test_utils.h"
using aidl::android::hardware::wifi::supplicant::IfaceInfo;
using aidl::android::hardware::wifi::supplicant::ISupplicant;
using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
-using android::wifi_system::SupplicantManager;
std::string getStaIfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
@@ -43,16 +37,7 @@
return std::string(buffer.data());
}
-std::string getWifiInstanceName() {
- const std::vector<std::string> instances =
- android::hardware::getAllHalInstanceNames(
- ::android::hardware::wifi::V1_0::IWifi::descriptor);
- EXPECT_NE(0, instances.size());
- return instances.size() != 0 ? instances[0] : "";
-}
-
-bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface,
- KeyMgmtMask expected) {
+bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface, KeyMgmtMask expected) {
KeyMgmtMask caps;
if (!iface->getKeyMgmtCapabilities(&caps).isOk()) {
return false;
@@ -67,22 +52,22 @@
return keyMgmtSupported(iface, filsMask);
}
-void startSupplicant() {
- initializeDriverAndFirmware(getWifiInstanceName());
- SupplicantManager supplicant_manager;
- ASSERT_TRUE(supplicant_manager.StartSupplicant());
- ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
+void stopSupplicantService() {
+ // Select method based on whether the HIDL or AIDL
+ // Vendor HAL is available.
+ if (SupplicantAidlTestUtils::useAidlService()) {
+ SupplicantAidlTestUtils::stopSupplicantService();
+ } else {
+ SupplicantLegacyTestUtils::stopSupplicantService();
+ }
}
-// Wrapper around the implementation in supplicant_hidl_test_util.
-void stopSupplicantService() { stopSupplicant(getWifiInstanceName()); }
-
void initializeService() {
- ASSERT_TRUE(stopWifiFramework(getWifiInstanceName()));
- std::system("/system/bin/start");
- ASSERT_TRUE(waitForFrameworkReady());
- stopSupplicantService();
- startSupplicant();
+ if (SupplicantAidlTestUtils::useAidlService()) {
+ SupplicantAidlTestUtils::stopSupplicantService();
+ } else {
+ SupplicantLegacyTestUtils::stopSupplicantService();
+ }
}
void addStaIface(const std::shared_ptr<ISupplicant> supplicant) {
@@ -106,5 +91,3 @@
}
return supplicant;
}
-
-#endif // SUPPLICANT_TEST_UTILS_H
\ No newline at end of file