Merge "Add AIDL PixelFormat::R_8"
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index 0d4775c6a..1bd6abe 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -7,17 +7,40 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+soong_config_module_type {
+ name: "android_hardware_audio_config_default",
+ module_type: "cc_defaults",
+ config_namespace: "android_hardware_audio",
+ bool_variables: [
+ "run_64bit",
+ ],
+ properties: ["compile_multilib"],
+}
+
+android_hardware_audio_config_default {
+ name: "android_hardware_audio_config_defaults",
+
+ soong_config_variables: {
+ run_64bit: {
+ conditions_default: {
+ // Prefer 32 bit as the binary must always be installed at the same
+ // location for init to start it and the build system does not support
+ // having two binaries installable to the same location even if they are
+ // not installed in the same build.
+ compile_multilib: "prefer32",
+ },
+ compile_multilib: "64",
+ },
+ },
+}
+
cc_binary {
name: "android.hardware.audio.service",
init_rc: ["android.hardware.audio.service.rc"],
relative_install_path: "hw",
vendor: true,
- // Prefer 32 bit as the binary must always be installed at the same
- // location for init to start it and the build system does not support
- // having two binaries installable to the same location even if they are
- // not installed in the same build.
- compile_multilib: "prefer32",
+
srcs: ["service.cpp"],
cflags: [
@@ -34,6 +57,10 @@
"libutils",
"libhardware",
],
+
+ defaults: [
+ "android_hardware_audio_config_defaults",
+ ],
}
// Legacy service name, use android.hardware.audio.service instead
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
index 6b4dbc1..e3b98c9 100644
--- a/audio/core/all-versions/vts/functional/6.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -36,9 +36,14 @@
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+ auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
for (const auto& ioProfile : module->getOutputProfiles()) {
+ if (getCachedPolicyConfig()
+ .getAttachedSinkDeviceForMixPort(moduleName, ioProfile->getName())
+ .empty()) {
+ continue; // no attached device
+ }
for (const auto& profile : ioProfile->getAudioProfiles()) {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
@@ -94,9 +99,14 @@
std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+ auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
for (const auto& ioProfile : module->getInputProfiles()) {
+ if (getCachedPolicyConfig()
+ .getAttachedSourceDeviceForMixPort(moduleName, ioProfile->getName())
+ .empty()) {
+ continue; // no attached device
+ }
for (const auto& profile : ioProfile->getAudioProfiles()) {
const auto& channels = profile->getChannels();
const auto& sampleRates = profile->getSampleRates();
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 0cc6a5b..2759801 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -499,18 +499,10 @@
return xsd::isLinearPcm(std::get<PARAM_CONFIG>(cfg).base.format)
// MMAP NOIRQ and HW A/V Sync profiles use special writing protocols.
&&
- std::find_if(flags.begin(), flags.end(),
- [](const auto& flag) {
- return flag == toString(xsd::AudioInOutFlag::
- AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) ||
- flag == toString(xsd::AudioInOutFlag::
- AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
- }) == flags.end() &&
- !getCachedPolicyConfig()
- .getAttachedSinkDeviceForMixPort(
- std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(cfg)),
- std::get<PARAM_PORT_NAME>(cfg))
- .empty();
+ std::find_if(flags.begin(), flags.end(), [](const auto& flag) {
+ return flag == toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) ||
+ flag == toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
+ }) == flags.end();
});
return pcmParams;
}();
@@ -677,20 +669,13 @@
// reading h/w hotword might require Soundtrigger to be active.
&&
std::find_if(
- flags.begin(), flags.end(),
- [](const auto& flag) {
+ flags.begin(), flags.end(), [](const auto& flag) {
return flag == toString(
xsd::AudioInOutFlag::
AUDIO_INPUT_FLAG_MMAP_NOIRQ) ||
flag == toString(xsd::AudioInOutFlag::
AUDIO_INPUT_FLAG_HW_HOTWORD);
- }) == flags.end() &&
- !getCachedPolicyConfig()
- .getAttachedSourceDeviceForMixPort(
- std::get<PARAM_DEVICE_NAME>(
- std::get<PARAM_DEVICE>(cfg)),
- std::get<PARAM_PORT_NAME>(cfg))
- .empty();
+ }) == flags.end();
});
return pcmParams;
}();
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
index 8c92cbd..42bf1d3 100644
--- a/audio/core/all-versions/vts/functional/7.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -95,11 +95,16 @@
std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+ auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
+ if (getCachedPolicyConfig()
+ .getAttachedSinkDeviceForMixPort(moduleName, mixPort.getName())
+ .empty()) {
+ continue; // no attached device
+ }
auto [flags, isOffload] = generateOutFlags(mixPort);
for (const auto& profile : mixPort.getProfile()) {
if (!profile.hasFormat() || !profile.hasSamplingRates() ||
@@ -223,11 +228,16 @@
std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
std::vector<DeviceConfigParameter> result;
for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ const std::string moduleName = std::get<PARAM_DEVICE_NAME>(device);
+ auto module = getCachedPolicyConfig().getModuleFromName(moduleName);
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
+ if (getCachedPolicyConfig()
+ .getAttachedSourceDeviceForMixPort(moduleName, mixPort.getName())
+ .empty()) {
+ continue; // no attached device
+ }
std::vector<AudioInOutFlag> flags;
if (mixPort.hasFlags()) {
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index b99ed43..b280d7c 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -217,6 +217,7 @@
data: [
"tests/apm_config_no_vx.xml",
"tests/apm_config_with_vx.xml",
+ "tests/apm_config_b_205808571_6_0.xml",
],
test_config: "tests/HalAudioV6_0GeneratorTest.xml",
}
@@ -246,6 +247,7 @@
"tests/apm_config_no_vx_7_0.xml",
"tests/apm_config_with_vx_7_0.xml",
"tests/apm_config_b_204314749_7_0.xml",
+ "tests/apm_config_b_205808571_7_0.xml",
],
test_config: "tests/HalAudioV7_0GeneratorTest.xml",
}
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
index a94041c..171d03f 100644
--- a/audio/core/all-versions/vts/functional/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -76,6 +76,16 @@
const std::set<std::string>& getModulesWithDevicesNames() const {
return mModulesWithDevicesNames;
}
+ std::string getAttachedSinkDeviceForMixPort(const std::string& moduleName,
+ const std::string& mixPortName) const {
+ return findAttachedDevice(getAttachedDevices(moduleName),
+ getSinkDevicesForMixPort(moduleName, mixPortName));
+ }
+ std::string getAttachedSourceDeviceForMixPort(const std::string& moduleName,
+ const std::string& mixPortName) const {
+ return findAttachedDevice(getAttachedDevices(moduleName),
+ getSourceDevicesForMixPort(moduleName, mixPortName));
+ }
bool haveInputProfilesInModule(const std::string& name) const {
auto module = getModuleFromName(name);
return module && !module->getInputProfiles().empty();
@@ -92,6 +102,8 @@
for (const auto& module : hwModules) {
if (module->getDeclaredDevices().indexOf(device) >= 0) {
mModulesWithDevicesNames.insert(module->getName());
+ mAttachedDevicesPerModule[module->getName()].push_back(
+ device->getTagName());
break;
}
}
@@ -100,16 +112,64 @@
for (const auto& module : hwModules) {
if (module->getDeclaredDevices().indexOf(device) >= 0) {
mModulesWithDevicesNames.insert(module->getName());
+ mAttachedDevicesPerModule[module->getName()].push_back(
+ device->getTagName());
break;
}
}
}
}
}
+ std::string findAttachedDevice(const std::vector<std::string>& attachedDevices,
+ const std::set<std::string>& possibleDevices) const {
+ for (const auto& device : attachedDevices) {
+ if (possibleDevices.count(device)) return device;
+ }
+ return {};
+ }
+ std::vector<std::string> getAttachedDevices(const std::string& moduleName) const {
+ if (auto iter = mAttachedDevicesPerModule.find(moduleName);
+ iter != mAttachedDevicesPerModule.end()) {
+ return iter->second;
+ }
+ return {};
+ }
+ std::set<std::string> getSinkDevicesForMixPort(const std::string& moduleName,
+ const std::string& mixPortName) const {
+ std::set<std::string> result;
+ auto module = getModuleFromName(moduleName);
+ if (module != nullptr) {
+ for (const auto& route : module->getRoutes()) {
+ for (const auto& source : route->getSources()) {
+ if (source->getTagName() == mixPortName) {
+ result.insert(route->getSink()->getTagName());
+ }
+ }
+ }
+ }
+ return result;
+ }
+ std::set<std::string> getSourceDevicesForMixPort(const std::string& moduleName,
+ const std::string& mixPortName) const {
+ std::set<std::string> result;
+ auto module = getModuleFromName(moduleName);
+ if (module != nullptr) {
+ for (const auto& route : module->getRoutes()) {
+ if (route->getSink()->getTagName() == mixPortName) {
+ const auto& sources = route->getSources();
+ std::transform(sources.begin(), sources.end(),
+ std::inserter(result, result.end()),
+ [](const auto& source) { return source->getTagName(); });
+ }
+ }
+ }
+ return result;
+ }
const std::string mConfigFileName;
status_t mStatus = android::NO_INIT;
std::string mFilePath;
sp<const android::HwModule> mPrimaryModule = nullptr;
std::set<std::string> mModulesWithDevicesNames;
+ std::map<std::string, std::vector<std::string>> mAttachedDevicesPerModule;
};
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
index 0c85a05..0230447 100644
--- a/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
@@ -24,6 +24,7 @@
<option name="cleanup" value="true" />
<option name="push" value="apm_config_no_vx.xml->/data/local/tmp/apm_config_no_vx.xml" />
<option name="push" value="apm_config_with_vx.xml->/data/local/tmp/apm_config_with_vx.xml" />
+ <option name="push" value="apm_config_b_205808571_6_0.xml->/data/local/tmp/apm_config_b_205808571_6_0.xml" />
<option name="push" value="HalAudioV6_0GeneratorTest->/data/local/tmp/HalAudioV6_0GeneratorTest" />
</target_preparer>
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
index 3dc5b33..0d8abd3 100644
--- a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
@@ -25,6 +25,7 @@
<option name="push" value="apm_config_no_vx_7_0.xml->/data/local/tmp/apm_config_no_vx.xml" />
<option name="push" value="apm_config_with_vx_7_0.xml->/data/local/tmp/apm_config_with_vx.xml" />
<option name="push" value="apm_config_b_204314749_7_0.xml->/data/local/tmp/apm_config_b_204314749_7_0.xml" />
+ <option name="push" value="apm_config_b_205808571_7_0.xml->/data/local/tmp/apm_config_b_205808571_7_0.xml" />
<option name="push" value="HalAudioV7_0GeneratorTest->/data/local/tmp/HalAudioV7_0GeneratorTest" />
</target_preparer>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_6_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_6_0.xml
new file mode 100644
index 0000000..0f7bf7f
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_6_0.xml
@@ -0,0 +1,451 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (c) 2016-2021, The Linux Foundation. All rights reserved
+ Not a Contribution.
+-->
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <!-- version section contains a “version” tag in the form “major.minor” e.g. version=”1.0” -->
+
+ <!-- Global configuration Decalaration -->
+ <globalConfiguration speaker_drc_enabled="true" call_screen_mode_supported="true"/>
+
+
+ <!-- Modules section:
+ There is one section per audio HW module present on the platform.
+ Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+ The module names are the same as in current .conf file:
+ “primary”, “A2DP”, “remote_submix”, “USB”
+ Each module will contain the following sections:
+ “devicePorts”: a list of device descriptors for all input and output devices accessible via this
+ module.
+ This contains both permanently attached devices and removable devices.
+ “mixPorts”: listing all output and input streams exposed by the audio HAL
+ “routes”: list of possible connections between input and output devices or between stream and
+ devices.
+ "route": is defined by an attribute:
+ -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
+ -"sink": the sink involved in this route
+ -"sources": all the sources than can be connected to the sink via vis route
+ “attachedDevices”: permanently attached devices.
+ The attachedDevices section is a list of devices names. The names correspond to device names
+ defined in <devicePorts> section.
+ “defaultOutputDevice”: device to be used by default when no policy rule applies
+ -->
+ <modules>
+ <!-- Primary Audio HAL -->
+ <module name="primary" halVersion="2.0">
+ <attachedDevices>
+ <item>Earpiece</item>
+ <item>Speaker</item>
+ <item>Telephony Tx</item>
+ <item>Built-In Mic</item>
+ <item>Built-In Back Mic</item>
+ <item>FM Tuner</item>
+ <item>Telephony Rx</item>
+ </attachedDevices>
+ <defaultOutputDevice>Speaker</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="raw" role="source"
+ flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="haptics output" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+ </mixPort>
+ <mixPort name="deep_buffer" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="hifi_playback" role="source" />
+ <mixPort name="compress_passthrough" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+ </mixPort>
+ <mixPort name="direct_pcm" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ </mixPort>
+ <mixPort name="compressed_offload" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+ <profile name="" format="AUDIO_FORMAT_MP3"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_FLAC"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_ALAC"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_APE"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_LC"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_HE_V1"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_HE_V2"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_DTS"
+ samplingRates="32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_DTS_HD"
+ samplingRates="32000,44100,48000,64000,88200,96000,128000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_WMA"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_WMA_PRO"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_VORBIS"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_ADTS_LC"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V1"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V2"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+ </mixPort>
+ <mixPort name="voice_tx" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="voip_rx" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="incall_music_uplink" role="source"
+ flags="AUDIO_OUTPUT_FLAG_INCALL_MUSIC">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+
+ <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ <mixPort name="fast input" role="sink"
+ flags="AUDIO_INPUT_FLAG_FAST">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ <mixPort name="quad mic" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+ </mixPort>
+ <mixPort name="voip_tx" role="sink"
+ flags="AUDIO_INPUT_FLAG_VOIP_TX">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </mixPort>
+ <mixPort name="usb_surround_sound" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
+ channelMasks="AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
+ </mixPort>
+ <mixPort name="record_24" role="sink" maxOpenCount="2" maxActiveCount="2">
+ <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
+ </mixPort>
+ <mixPort name="voice_rx" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ <mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3"/>
+ </mixPort>
+ <mixPort name="hifi_input" role="sink" />
+ </mixPorts>
+
+ <devicePorts>
+ <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
+ <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </devicePort>
+ <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Line" type="AUDIO_DEVICE_OUT_LINE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+ </devicePort>
+ <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+ </devicePort>
+ <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+ </devicePort>
+ <devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000"/>
+ </devicePort>
+ <devicePort tagName="Proxy" type="AUDIO_DEVICE_OUT_PROXY" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000"/>
+ </devicePort>
+ <devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
+ encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
+ encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
+ encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000,64000,88200,96000,128000,176400,192000"/>
+ </devicePort>
+ <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000,64000,88200,96000,128000,176400,192000"/>
+ </devicePort>
+
+ <!-- Input devices declaration, i.e. Source DEVICE PORT -->
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </devicePort>
+ <devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </devicePort>
+ <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
+ </devicePort>
+ <devicePort tagName="USB Headset In" type="AUDIO_DEVICE_IN_USB_HEADSET" role="source">
+ </devicePort>
+ <devicePort tagName="A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source"
+ encodedFormats="VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+
+ </devicePorts>
+ <!-- route declaration, i.e. list all available sources for a given sink -->
+ <routes>
+ <route type="mix" sink="Earpiece"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Speaker"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Wired Headset"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Wired Headphones"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Line"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="HDMI"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,compress_passthrough,voip_rx,haptics output"/>
+ <route type="mix" sink="Proxy"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,haptics output"/>
+ <route type="mix" sink="FM"
+ sources="primary output"/>
+ <route type="mix" sink="BT SCO"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT SCO Headset"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT SCO Car Kit"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="USB Device Out"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+ <route type="mix" sink="USB Headset Out"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+ <route type="mix" sink="Telephony Tx"
+ sources="voice_tx,incall_music_uplink"/>
+ <route type="mix" sink="voice_rx"
+ sources="Telephony Rx"/>
+ <route type="mix" sink="primary input"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx,A2DP In"/>
+ <route type="mix" sink="usb_surround_sound"
+ sources="USB Device In,USB Headset In"/>
+ <route type="mix" sink="fast input"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+ <route type="mix" sink="quad mic"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+ <route type="mix" sink="voip_tx"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+ <route type="mix" sink="record_24"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,A2DP In"/>
+ <route type="mix" sink="mmap_no_irq_in"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,USB Device In,USB Headset In"/>
+ <route type="mix" sink="BT A2DP Out"
+ sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT A2DP Headphones"
+ sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT A2DP Speaker"
+ sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="hifi_input" sources="USB Device In,USB Headset In" />
+ </routes>
+
+ </module>
+
+ <!-- A2DP Audio HAL -->
+ <module name="a2dp" halVersion="2.0">
+ <mixPorts>
+ <mixPort name="a2dp input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ </mixPorts>
+
+ <devicePorts>
+ <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ </devicePorts>
+
+ <routes>
+ <route type="mix" sink="a2dp input"
+ sources="BT A2DP In"/>
+ </routes>
+ </module>
+
+ <!-- Usb Audio HAL -->
+ <module name="usb" halVersion="2.0">
+ <mixPorts>
+ <mixPort name="usb_accessory output" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="USB Host Out"
+ sources="usb_accessory output"/>
+ </routes>
+ </module>
+
+ <!-- Remote Submix Audio HAL -->
+ <!-- <xi:include href="/vendor/etc/r_submix_audio_policy_configuration.xml"/> -->
+
+ <!-- Bluetooth Audio HAL for hearing aid -->
+ <!-- <xi:include href="/vendor/etc/bluetooth_qti_hearing_aid_audio_policy_configuration.xml"/> -->
+
+ </modules>
+ <!-- End of Modules section -->
+
+ <!-- Volume section -->
+
+ <!-- <xi:include href="/vendor/etc/audio_policy_volumes.xml"/> -->
+ <!-- <xi:include href="/vendor/etc/default_volume_tables.xml"/> -->
+
+ <!-- End of Volume section -->
+
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_7_0.xml
new file mode 100644
index 0000000..16427b6
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_b_205808571_7_0.xml
@@ -0,0 +1,446 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (c) 2016-2021, The Linux Foundation. All rights reserved
+ Not a Contribution.
+-->
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <!-- version section contains a “version” tag in the form “major.minor” e.g. version=”1.0” -->
+
+ <!-- Global configuration Decalaration -->
+ <globalConfiguration speaker_drc_enabled="true" call_screen_mode_supported="true"/>
+
+
+ <!-- Modules section:
+ There is one section per audio HW module present on the platform.
+ Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
+ The module names are the same as in current .conf file:
+ “primary”, “A2DP”, “remote_submix”, “USB”
+ Each module will contain the following sections:
+ “devicePorts”: a list of device descriptors for all input and output devices accessible via this
+ module.
+ This contains both permanently attached devices and removable devices.
+ “mixPorts”: listing all output and input streams exposed by the audio HAL
+ “routes”: list of possible connections between input and output devices or between stream and
+ devices.
+ "route": is defined by an attribute:
+ -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
+ -"sink": the sink involved in this route
+ -"sources": all the sources than can be connected to the sink via vis route
+ “attachedDevices”: permanently attached devices.
+ The attachedDevices section is a list of devices names. The names correspond to device names
+ defined in <devicePorts> section.
+ “defaultOutputDevice”: device to be used by default when no policy rule applies
+ -->
+ <modules>
+ <!-- Primary Audio HAL -->
+ <module name="primary" halVersion="2.0">
+ <attachedDevices>
+ <item>Earpiece</item>
+ <item>Speaker</item>
+ <item>Telephony Tx</item>
+ <item>Built-In Mic</item>
+ <item>Built-In Back Mic</item>
+ <item>FM Tuner</item>
+ <item>Telephony Rx</item>
+ </attachedDevices>
+ <defaultOutputDevice>Speaker</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="raw" role="source"
+ flags="AUDIO_OUTPUT_FLAG_FAST AUDIO_OUTPUT_FLAG_RAW">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="haptics output" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
+ </mixPort>
+ <mixPort name="deep_buffer" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="hifi_playback" role="source" />
+ <mixPort name="compress_passthrough" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+ </mixPort>
+ <mixPort name="direct_pcm" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ </mixPort>
+ <mixPort name="compressed_offload" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+ <profile name="" format="AUDIO_FORMAT_MP3"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_FLAC"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_ALAC"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_APE"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_LC"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_HE_V1"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_HE_V2"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_DTS"
+ samplingRates="32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_DTS_HD"
+ samplingRates="32000 44100 48000 64000 88200 96000 128000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_WMA"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_WMA_PRO"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_VORBIS"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_ADTS_LC"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V1"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ <profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V2"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
+ </mixPort>
+ <mixPort name="voice_tx" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="voip_rx" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_VOIP_RX">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="incall_music_uplink" role="source"
+ flags="AUDIO_OUTPUT_FLAG_INCALL_MUSIC">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 48000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+
+ <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ <mixPort name="fast input" role="sink"
+ flags="AUDIO_INPUT_FLAG_FAST">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ <mixPort name="quad mic" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+ </mixPort>
+ <mixPort name="voip_tx" role="sink"
+ flags="AUDIO_INPUT_FLAG_VOIP_TX">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </mixPort>
+ <mixPort name="usb_surround_sound" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4 AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
+ channelMasks="AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6"/>
+ </mixPort>
+ <mixPort name="record_24" role="sink" maxOpenCount="2" maxActiveCount="2">
+ <profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
+ <profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
+ </mixPort>
+ <mixPort name="voice_rx" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ <mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3"/>
+ </mixPort>
+ <mixPort name="hifi_input" role="sink" />
+ </mixPorts>
+
+ <devicePorts>
+ <!-- Output devices declaration, i.e. Sink DEVICE PORT -->
+ <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </devicePort>
+ <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Line" type="AUDIO_DEVICE_OUT_LINE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+ </devicePort>
+ <devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+ </devicePort>
+ <devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
+ </devicePort>
+ <devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 16000 22050 32000 44100 48000 64000 88200 96000 128000 176400 192000"/>
+ </devicePort>
+ <devicePort tagName="Proxy" type="AUDIO_DEVICE_OUT_PROXY" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 16000 22050 32000 44100 48000 64000 88200 96000 128000 176400 192000"/>
+ </devicePort>
+ <devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
+ encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
+ encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
+ encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/>
+ </devicePort>
+ <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/>
+ </devicePort>
+
+ <!-- Input devices declaration, i.e. Source DEVICE PORT -->
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </devicePort>
+ <devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+ </devicePort>
+ <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
+ </devicePort>
+ <devicePort tagName="USB Headset In" type="AUDIO_DEVICE_IN_USB_HEADSET" role="source">
+ </devicePort>
+ <devicePort tagName="A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source"
+ encodedFormats="VX_AUDIO_FORMAT_LC3">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+
+ </devicePorts>
+ <!-- route declaration, i.e. list all available sources for a given sink -->
+ <routes>
+ <route type="mix" sink="Earpiece"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Speaker"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Wired Headset"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Wired Headphones"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="Line"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,haptics output"/>
+ <route type="mix" sink="HDMI"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,compress_passthrough,voip_rx,haptics output"/>
+ <route type="mix" sink="Proxy"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,haptics output"/>
+ <route type="mix" sink="FM"
+ sources="primary output"/>
+ <route type="mix" sink="BT SCO"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT SCO Headset"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT SCO Car Kit"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="USB Device Out"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+ <route type="mix" sink="USB Headset Out"
+ sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,haptics output"/>
+ <route type="mix" sink="Telephony Tx"
+ sources="voice_tx,incall_music_uplink"/>
+ <route type="mix" sink="voice_rx"
+ sources="Telephony Rx"/>
+ <route type="mix" sink="primary input"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx,A2DP In"/>
+ <route type="mix" sink="usb_surround_sound"
+ sources="USB Device In,USB Headset In"/>
+ <route type="mix" sink="fast input"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+ <route type="mix" sink="quad mic"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
+ <route type="mix" sink="voip_tx"
+ sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+ <route type="mix" sink="record_24"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,A2DP In"/>
+ <route type="mix" sink="mmap_no_irq_in"
+ sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,USB Device In,USB Headset In"/>
+ <route type="mix" sink="BT A2DP Out"
+ sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT A2DP Headphones"
+ sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="BT A2DP Speaker"
+ sources="primary output,deep_buffer,direct_pcm,compressed_offload,voip_rx,haptics output"/>
+ <route type="mix" sink="hifi_input" sources="USB Device In,USB Headset In" />
+ </routes>
+
+ </module>
+
+ <!-- A2DP Audio HAL -->
+ <module name="a2dp" halVersion="2.0">
+ <mixPorts>
+ <mixPort name="a2dp input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ </mixPorts>
+
+ <devicePorts>
+ <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ </devicePorts>
+
+ <routes>
+ <route type="mix" sink="a2dp input"
+ sources="BT A2DP In"/>
+ </routes>
+ </module>
+
+ <!-- Usb Audio HAL -->
+ <module name="usb" halVersion="2.0">
+ <mixPorts>
+ <mixPort name="usb_accessory output" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="USB Host Out"
+ sources="usb_accessory output"/>
+ </routes>
+ </module>
+
+ <!-- Remote Submix Audio HAL -->
+
+ <!-- Bluetooth Audio HAL for hearing aid -->
+
+ </modules>
+ <!-- End of Modules section -->
+
+ <!-- Volume section -->
+
+ <!-- End of Volume section -->
+
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
index 7caa712..3fdd8e6 100644
--- a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -131,8 +131,43 @@
// clang-format off
INSTANTIATE_TEST_SUITE_P(Generators, GeneratorsTest,
::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"
-#if MAJOR_VERSION == 7
+#if MAJOR_VERSION == 6
+ , "apm_config_b_205808571_6_0.xml"
+#elif MAJOR_VERSION == 7
, "apm_config_b_204314749_7_0.xml"
+ , "apm_config_b_205808571_7_0.xml"
#endif
));
// clang-format on
+
+TEST(GeneratorsDeviceTest, AttachedDevicesOnly) {
+ static const std::string kTestFile =
+ "apm_config_b_205808571_" STRINGIFY(MAJOR_VERSION) "_0.xml";
+ ASSERT_TRUE(PolicyConfigManager::getInstance().init(kDataDir, kTestFile));
+ EXPECT_NE(nullptr, getCachedPolicyConfig().getPrimaryModule());
+ const auto allInConfigs = generateInputDeviceConfigParameters(false /*oneProfilePerDevice*/);
+ EXPECT_FALSE(allInConfigs.empty());
+ for (const auto& configParam : allInConfigs) {
+ const AudioConfig& config = std::get<PARAM_CONFIG>(configParam);
+ // The config contains multichannel masks for mixPort connected to
+ // input devicePorts that are not attached. These multichannel masks must
+ // not appear among generated masks.
+ const uint32_t channelCount =
+#if MAJOR_VERSION == 6
+ audio_channel_count_from_in_mask(
+ static_cast<audio_channel_mask_t>(config.channelMask));
+#elif MAJOR_VERSION == 7
+ xsd::getChannelCount(config.base.channelMask);
+#endif
+ EXPECT_TRUE(channelCount <= 4) << "Unexpected channel count: " << channelCount << " " <<
+#if MAJOR_VERSION == 6
+ ::testing::PrintToString(config.format) << ", "
+ << ::testing::PrintToString(config.sampleRateHz) << ", "
+ << ::testing::PrintToString(config.channelMask);
+#elif MAJOR_VERSION == 7
+ ::testing::PrintToString(config.base.format) << ", "
+ << ::testing::PrintToString(config.base.sampleRateHz) << ", "
+ << ::testing::PrintToString(config.base.channelMask);
+#endif
+ }
+}
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 3696351..ff6f3be 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -20,6 +20,9 @@
},
{
"name": "FakeUserHalTest"
+ },
+ {
+ "name": "DefaultVehicleHalTest"
}
]
}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
index 54c65ba..22c690c 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable CreateUserRequest {
int requestId;
android.hardware.automotive.vehicle.UserInfo newUserInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
index 6126f99..7d0196b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable CreateUserResponse {
int requestId;
android.hardware.automotive.vehicle.CreateUserStatus status = android.hardware.automotive.vehicle.CreateUserStatus.SUCCESS;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
index 177966b..d88cd8b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable GetValueRequest {
long requestId;
android.hardware.automotive.vehicle.VehiclePropValue prop;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
index 5ecf4dd..a7df2ff 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable GetValueRequests {
android.hardware.automotive.vehicle.GetValueRequest[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
index 60c46e4..25f3575 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable GetValueResult {
long requestId;
android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
index 778ba8e..4c365b1 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable GetValueResults {
android.hardware.automotive.vehicle.GetValueResult[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
index c2c2500..a4c048a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable InitialUserInfoRequest {
int requestId;
android.hardware.automotive.vehicle.InitialUserInfoRequestType requestType = android.hardware.automotive.vehicle.InitialUserInfoRequestType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
index ffb1781..f0e1612 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable InitialUserInfoResponse {
int requestId;
android.hardware.automotive.vehicle.InitialUserInfoResponseAction action = android.hardware.automotive.vehicle.InitialUserInfoResponseAction.DEFAULT;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
index e553d60..e7b0a13 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable RawPropValues {
int[] int32Values = {};
float[] floatValues;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
index 6861309..74457b9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable RemoveUserRequest {
int requestId;
android.hardware.automotive.vehicle.UserInfo removedUserInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
index d6cddb6..6a65307 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SetValueRequest {
long requestId;
android.hardware.automotive.vehicle.VehiclePropValue value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
index ea9ac9a..15fd7ea 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SetValueRequests {
android.hardware.automotive.vehicle.SetValueRequest[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
index 6c25bc8..ec5fabb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SetValueResult {
long requestId;
android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
index 65ff8f0..47f1656 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SetValueResults {
android.hardware.automotive.vehicle.SetValueResult[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index dcefd09..91e7c14 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SubscribeOptions {
int propId;
int[] areaIds;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
index bb18e02..3012b7a 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SwitchUserRequest {
int requestId;
android.hardware.automotive.vehicle.SwitchUserMessageType messageType = android.hardware.automotive.vehicle.SwitchUserMessageType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
index efc1911..8915d1b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable SwitchUserResponse {
int requestId;
android.hardware.automotive.vehicle.SwitchUserMessageType messageType = android.hardware.automotive.vehicle.SwitchUserMessageType.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
index a0f9879..a540f8e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UserIdentificationAssociation {
android.hardware.automotive.vehicle.UserIdentificationAssociationType type = android.hardware.automotive.vehicle.UserIdentificationAssociationType.INVALID;
android.hardware.automotive.vehicle.UserIdentificationAssociationValue value = android.hardware.automotive.vehicle.UserIdentificationAssociationValue.UNKNOWN;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
index 744030e..fe7fd6f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UserIdentificationGetRequest {
int requestId;
android.hardware.automotive.vehicle.UserInfo userInfo;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
index b47b003..3e2a257 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UserIdentificationResponse {
int requestId;
int numberAssociation;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
index 5297349..57840fb 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UserIdentificationSetAssociation {
android.hardware.automotive.vehicle.UserIdentificationAssociationType type = android.hardware.automotive.vehicle.UserIdentificationAssociationType.INVALID;
android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue value = android.hardware.automotive.vehicle.UserIdentificationAssociationSetValue.INVALID;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
index 725040d..db01b51 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UserIdentificationSetRequest {
int requestId;
android.hardware.automotive.vehicle.UserInfo userInfo;
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
index b99272b..f47d5e7 100644
--- 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
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UserInfo {
int userId = 0;
int flags;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
index 7234316..edcef2e 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable UsersInfo {
android.hardware.automotive.vehicle.UserInfo currentUser;
int numberUsers;
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 7a42ec8..b93a11b 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
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehicleAreaConfig {
int areaId;
int minInt32Value;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 16ba6db..8602d2d 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropConfig {
int prop;
android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
index e5d146d..04c8006 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropConfigs {
android.hardware.automotive.vehicle.VehiclePropConfig[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 8b2e104..9835295 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropError {
int propId;
int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
index 6303d3a..9dcb10b 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropErrors {
android.hardware.automotive.vehicle.VehiclePropError[] payloads;
@nullable ParcelFileDescriptor sharedMemoryFd;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index fc1ae53..c87379f 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropValue {
long timestamp;
int areaId;
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
index da8c60b..e09a6b9 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -32,7 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.automotive.vehicle;
-@VintfStability
+@JavaDerive(equals=true, toString=true) @VintfStability
parcelable VehiclePropValues {
android.hardware.automotive.vehicle.VehiclePropValue[] payloads;
long sharedMemoryId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
index 1f7c9cc..624e5a6 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserRequest.aidl
@@ -26,6 +26,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable CreateUserRequest {
/**
* Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
index d011366..29db442 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/CreateUserResponse.aidl
@@ -25,6 +25,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable CreateUserResponse {
/**
* Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
index 43a89d0..e5b3929 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequest.aidl
@@ -19,6 +19,7 @@
import android.hardware.automotive.vehicle.VehiclePropValue;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable GetValueRequest {
// A unique request ID. For every client, the request ID must start with 1
// and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
index 6601233..3bbb88c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueRequests.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable GetValueRequests {
// A list of GetValueRequest to get if they fit the binder memory
// limitation.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
index b099a85..24c5757 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResult.aidl
@@ -20,6 +20,7 @@
import android.hardware.automotive.vehicle.VehiclePropValue;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable GetValueResult {
// The ID for the request this response is for.
long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
index 919e644..a8bfb2c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GetValueResults.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable GetValueResults {
// The list of responses if they fit the binder memory limitation.
GetValueResult[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
index 7879d44..c7ba836 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoRequest.aidl
@@ -26,6 +26,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable InitialUserInfoRequest {
/**
* Arbitrary id used to map the HAL response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
index 8be0c69..4c46fcb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/InitialUserInfoResponse.aidl
@@ -26,6 +26,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable InitialUserInfoResponse {
/**
* Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
index 5d8febd..9c6875b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RawPropValues.aidl
@@ -17,6 +17,7 @@
package android.hardware.automotive.vehicle;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable RawPropValues {
/**
* This is used for properties of types VehiclePropertyType#INT
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
index 1a3d4dd..cb61da8 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/RemoveUserRequest.aidl
@@ -26,6 +26,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable RemoveUserRequest {
/**
* Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
index f2b0e27..625f901 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequest.aidl
@@ -19,6 +19,7 @@
import android.hardware.automotive.vehicle.VehiclePropValue;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SetValueRequest {
// A unique request ID. For every client, the request ID must start with 1
// and monotonically increase for every SetValueRequest. If it hits
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
index 5d6ad85..a690fa2 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueRequests.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SetValueRequests {
// The list of request if they fit the binder memory limitation.
SetValueRequest[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
index a468f3b..b3feeaa 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResult.aidl
@@ -19,6 +19,7 @@
import android.hardware.automotive.vehicle.StatusCode;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SetValueResult {
// The ID for the request this response is for.
long requestId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
index 6df9de0..9b0e505 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SetValueResults.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SetValueResults {
// The list of responses if they fit the binder memory limitation.
SetValueResult[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index bc7d84a..e68f7e3 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -20,6 +20,7 @@
* Encapsulates information about subscription to vehicle property events.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SubscribeOptions {
/** Property to subscribe */
int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
index 10858a4..320632c 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserRequest.aidl
@@ -27,6 +27,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SwitchUserRequest {
/**
* Arbitrary id used to map the response to the request.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
index d5d44e5..106386d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SwitchUserResponse.aidl
@@ -26,6 +26,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable SwitchUserResponse {
/**
* Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
index cdd11bf..4af5f72 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationAssociation.aidl
@@ -23,6 +23,7 @@
* Helper struct used when getting a user/identification association type.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UserIdentificationAssociation {
UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
UserIdentificationAssociationValue value = UserIdentificationAssociationValue.UNKNOWN;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
index 58620ef..82580d7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationGetRequest.aidl
@@ -26,6 +26,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UserIdentificationGetRequest {
/**
* Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
index 06341c7..1487a70 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationResponse.aidl
@@ -25,6 +25,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UserIdentificationResponse {
/**
* Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
index fe5017f..bfb9544 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetAssociation.aidl
@@ -23,6 +23,7 @@
* Helper struct used when setting a user/identification association type.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UserIdentificationSetAssociation {
UserIdentificationAssociationType type = UserIdentificationAssociationType.INVALID;
UserIdentificationAssociationSetValue value = UserIdentificationAssociationSetValue.INVALID;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
index 13f3677..223ff08 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserIdentificationSetRequest.aidl
@@ -25,6 +25,7 @@
* VehiclePropValue.RawValue through libraries provided by the default Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UserIdentificationSetRequest {
/**
* Id of the request being responded.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
index e4ecc4b..20c72bd 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UserInfo.aidl
@@ -20,6 +20,7 @@
* Information about a specific Android user.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UserInfo {
/**
* System user.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
index 77468b1..ede36f7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/UsersInfo.aidl
@@ -26,6 +26,7 @@
* Vehicle HAL implementation.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable UsersInfo {
/**
* The current foreground user.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
index 82f98d8..1031ebb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.aidl
@@ -23,6 +23,7 @@
* This requests Android to enter its normal operating state.
* This may be sent after the AP has reported
* VehicleApPowerStateReport#DEEP_SLEEP_EXIT,
+ * VehicleApPowerStateReport#HIBERNATION_EXIT,
* VehicleApPowerStateReport#SHUTDOWN_CANCELLED, or
* VehicleApPowerStateReport#WAIT_FOR_VHAL.
*/
@@ -31,6 +32,7 @@
* The power controller issues this request to shutdown the system.
* This may be sent after the AP has reported
* VehicleApPowerStateReport#DEEP_SLEEP_EXIT,
+ * VehicleApPowerStateReport#HIBERNATION_EXIT,
* VehicleApPowerStateReport#ON,
* VehicleApPowerStateReport#SHUTDOWN_CANCELLED,
* VehicleApPowerStateReport#SHUTDOWN_POSTPONE,
@@ -59,6 +61,7 @@
* Completes the shutdown process.
* This may be sent after the AP has reported
* VehicleApPowerStateReport#DEEP_SLEEP_ENTRY or
+ * VehicleApPowerStateReport#HIBERNATION_ENTRY or
* VehicleApPowerStateReport#SHUTDOWN_START. The AP will not report new
* state information after receiving this request.
*/
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index b33dcbc..b44996d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -17,6 +17,7 @@
package android.hardware.automotive.vehicle;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehicleAreaConfig {
/**
* Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 5e0dbec..1b48f0b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -21,6 +21,7 @@
import android.hardware.automotive.vehicle.VehiclePropertyChangeMode;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehiclePropConfig {
/** Property identifier */
int prop;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
index 98abdef..9c2d5f7 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehiclePropConfigs {
// The list of vehicle property configs if they fit the binder memory
// limitation.
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
index 1608977..2c31c72 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropError.aidl
@@ -19,6 +19,7 @@
import android.hardware.automotive.vehicle.StatusCode;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehiclePropError {
// Property ID.
int propId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
index 6a77d35..10a164d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropErrors.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehiclePropErrors {
// List of property set errors if they fit binder memory limitation.
VehiclePropError[] payloads;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
index 37dac59..289f270 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValue.aidl
@@ -25,6 +25,7 @@
* events.
*/
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehiclePropValue {
/** Time is elapsed nanoseconds since boot */
long timestamp;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
index 1944f8e..df44fdb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropValues.aidl
@@ -20,6 +20,7 @@
import android.os.ParcelFileDescriptor;
@VintfStability
+@JavaDerive(equals=true, toString=true)
parcelable VehiclePropValues {
// The list of vehicle properties if they fit the binder memory limitation.
VehiclePropValue[] payloads;
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
index dfc2efc..dcd9208 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
@@ -22,10 +22,17 @@
name: "FakeVehicleHardware",
vendor: true,
srcs: ["src/*.cpp"],
- cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
- defaults: ["VehicleHalDefaults"],
+ defaults: [
+ "VehicleHalDefaults",
+ "FakeVehicleHardwareDefaults",
+ ],
+}
+
+cc_defaults {
+ name: "FakeVehicleHardwareDefaults",
+ cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
header_libs: [
"IVehicleHardware",
"VehicleHalDefaultConfig",
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 104147a..5b2003e 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -62,27 +62,6 @@
const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override";
-template <class T>
-StatusCode getErrorCode(const Result<T>& result) {
- if (result.ok()) {
- return StatusCode::OK;
- }
- return static_cast<StatusCode>(result.error().code());
-}
-
-template <class T>
-int getIntErrorCode(const Result<T>& result) {
- return toInt(getErrorCode(result));
-}
-
-template <class T>
-std::string getErrorMsg(const Result<T>& result) {
- if (result.ok()) {
- return "";
- }
- return result.error().message();
-}
-
} // namespace
void FakeVehicleHardware::storePropInitialValue(const defaultconfig::ConfigDeclaration& config) {
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index 2b36c72..013d177 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -25,6 +25,7 @@
#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/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -34,6 +35,7 @@
#include <aidl/android/hardware/automotive/vehicle/PortLocationType.h>
#include <aidl/android/hardware/automotive/vehicle/SetValueRequest.h>
#include <aidl/android/hardware/automotive/vehicle/SetValueResult.h>
+#include <aidl/android/hardware/automotive/vehicle/SetValueResults.h>
#include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
index 95e58c6..63eb747 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
@@ -18,6 +18,9 @@
#define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleUtils_H_
#include <VehicleHalTypes.h>
+
+#include <android-base/format.h>
+#include <android-base/result.h>
#include <utils/Log.h>
namespace android {
@@ -183,6 +186,60 @@
return size;
}
+template <class T>
+::aidl::android::hardware::automotive::vehicle::StatusCode getErrorCode(
+ const ::android::base::Result<T>& result) {
+ if (result.ok()) {
+ return ::aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+ }
+ return static_cast<::aidl::android::hardware::automotive::vehicle::StatusCode>(
+ result.error().code());
+}
+
+template <class T>
+int getIntErrorCode(const ::android::base::Result<T>& result) {
+ return toInt(getErrorCode(result));
+}
+
+template <class T>
+std::string getErrorMsg(const ::android::base::Result<T>& result) {
+ if (result.ok()) {
+ return "";
+ }
+ return result.error().message();
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(
+ const ::android::base::Result<T>& result,
+ ::aidl::android::hardware::automotive::vehicle::StatusCode status,
+ std::string additionalErrorMsg) {
+ if (result.ok()) {
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(status),
+ fmt::format("{}, error: {}", additionalErrorMsg, getErrorMsg(result)).c_str());
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(
+ const ::android::base::Result<T>& result,
+ ::aidl::android::hardware::automotive::vehicle::StatusCode status) {
+ return toScopedAStatus(result, status, "");
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result) {
+ return toScopedAStatus(result, getErrorCode(result));
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result,
+ std::string additionalErrorMsg) {
+ return toScopedAStatus(result, getErrorCode(result), additionalErrorMsg);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 0704107..79d3ebd 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -1,37 +1,68 @@
-// 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.
+/*
+ * 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 {
- // 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"],
+ default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_binary {
name: "android.hardware.automotive.vehicle-aidl-default-service",
- defaults: ["VehicleHalDefaults"],
- local_include_dirs: ["include"],
+ vendor: true,
+ defaults: [
+ "FakeVehicleHardwareDefaults",
+ "VehicleHalDefaults",
+ "android-automotive-large-parcelable-defaults",
+ ],
vintf_fragments: ["vhal-default-service.xml"],
init_rc: ["vhal-default-service.rc"],
- vendor: true,
relative_install_path: "hw",
- srcs: ["src/*.cpp"],
+ srcs: ["src/VehicleService.cpp"],
+ static_libs: [
+ "DefaultVehicleHal",
+ "FakeVehicleHardware",
+ "VehicleHalUtils",
+ "android-automotive-large-parcelable-vendor-lib",
+ ],
+ header_libs: [
+ "IVehicleHardware",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+}
+
+cc_library {
+ name: "DefaultVehicleHal",
+ vendor: true,
+ defaults: [
+ "VehicleHalDefaults",
+ "android-automotive-large-parcelable-defaults",
+ ],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+ srcs: [
+ "src/ConnectedClient.cpp",
+ "src/DefaultVehicleHal.cpp",
+ ],
static_libs: [
"VehicleHalUtils",
+ "android-automotive-large-parcelable-vendor-lib",
+ ],
+ header_libs: [
+ "IVehicleHardware",
],
shared_libs: [
"libbinder_ndk",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h b/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
new file mode 100644
index 0000000..43a9603
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
+
+#include <VehicleHalTypes.h>
+
+#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
+#include <android-base/result.h>
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// A class to represent a binder client with a callback interface. Each callback function, e.g.
+// GetValues or SetValues for a specific binder client is a separate {@code ConnectedClient}.
+// For one {@code ConnectedClient}, we use one pending request pool to manage all pending requests,
+// so the request IDs must be unique for one client. We also manage a set of callback functions
+// for one client, e.g. timeoutCallback which could be passed to hardware.
+// This class is thread-safe.
+class ConnectedClient {
+ public:
+ ConnectedClient(
+ std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
+ callback);
+
+ virtual ~ConnectedClient() = default;
+
+ protected:
+ const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
+ mCallback;
+};
+
+// A class to represent a client that calls {@code IVehicle.setValues} or {@code
+// IVehicle.getValues}.
+template <class ResultType, class ResultsType>
+class GetSetValuesClient final : public ConnectedClient {
+ public:
+ GetSetValuesClient(
+ std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>
+ callback);
+
+ // Sends the results to this client.
+ void sendResults(const std::vector<ResultType>& results);
+
+ // Sends each result separately to this client. Each result would be sent through one callback
+ // invocation.
+ void sendResultsSeparately(const std::vector<ResultType>& results);
+
+ // Gets the callback to be called when the request for this client has finished.
+ std::shared_ptr<const std::function<void(std::vector<ResultType>)>> getResultCallback();
+
+ private:
+ // The following members are only initialized during construction.
+ std::shared_ptr<const std::function<void(std::vector<ResultType>)>> mResultCallback;
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_ConnectedClient_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 49c501e..43bdca2 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -17,14 +17,68 @@
#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
+#include <IVehicleHardware.h>
+#include <LargeParcelableBase.h>
+#include <VehicleUtils.h>
#include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
+#include <android/binder_auto_utils.h>
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
+// private namespace
+namespace defaultvehiclehal_impl {
+
+constexpr int INVALID_MEMORY_FD = -1;
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(
+ const ::android::base::Result<T>& result,
+ ::aidl::android::hardware::automotive::vehicle::StatusCode status) {
+ if (result.ok()) {
+ return ::ndk::ScopedAStatus::ok();
+ }
+ return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(toInt(status),
+ getErrorMsg(result).c_str());
+}
+
+template <class T>
+::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result) {
+ return toScopedAStatus(result, getErrorCode(result));
+}
+
+template <class T1, class T2>
+::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>& values, T2* output) {
+ auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
+ parcelableVectorToStableLargeParcelable(values);
+ if (!result.ok()) {
+ return toScopedAStatus(
+ result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
+ }
+ auto& fd = result.value();
+ if (fd == nullptr) {
+ output->payloads = values;
+ } else {
+ // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
+ // 'sharedMemoryFd' field.
+ output->sharedMemoryFd.set(fd->get());
+ *(fd->getR()) = INVALID_MEMORY_FD;
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace defaultvehiclehal_impl
+
class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::vehicle::BnVehicle {
+ public:
+ explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
+
::ndk::ScopedAStatus getAllPropConfigs(
::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
override;
@@ -56,6 +110,14 @@
const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
callback,
int64_t sharedMemoryId) override;
+
+ IVehicleHardware* getHardware();
+
+ private:
+ const std::unique_ptr<IVehicleHardware> mVehicleHardware;
+ std::unordered_map<int32_t, ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
+ mConfigsByPropId;
+ std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile;
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
new file mode 100644
index 0000000..dcb15b9
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
@@ -0,0 +1,89 @@
+/*
+ * 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_vhal_include_ParcelableUtils_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_ParcelableUtils_H_
+
+#include <LargeParcelableBase.h>
+#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+template <class T1, class T2>
+::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>&& values, T2* output) {
+ auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
+ parcelableVectorToStableLargeParcelable(values);
+ if (!result.ok()) {
+ return toScopedAStatus(
+ result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
+ }
+ auto& fd = result.value();
+ if (fd == nullptr) {
+ // If we no longer needs values, move it inside the payloads to avoid copying.
+ output->payloads = std::move(values);
+ } else {
+ // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
+ // 'sharedMemoryFd' field.
+ output->sharedMemoryFd = std::move(*fd);
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+template <class T1, class T2>
+::ndk::ScopedAStatus vectorToStableLargeParcelable(const std::vector<T1>& values, T2* output) {
+ // Because 'values' is passed in as const reference, we have to do a copy here.
+ std::vector<T1> valuesCopy = values;
+
+ return vectorToStableLargeParcelable(std::move(valuesCopy), output);
+}
+
+template <class T1, class T2>
+::android::base::expected<std::vector<T1>, ::ndk::ScopedAStatus> stableLargeParcelableToVector(
+ const T2& largeParcelable) {
+ ::android::base::Result<std::optional<std::vector<T1>>> result =
+ ::android::automotive::car_binder_lib::LargeParcelableBase::
+ stableLargeParcelableToParcelableVector<T1>(largeParcelable.sharedMemoryFd);
+
+ if (!result.ok()) {
+ return ::android::base::unexpected(toScopedAStatus(
+ result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INVALID_ARG,
+ "failed to parse large parcelable"));
+ }
+
+ if (!result.value().has_value()) {
+ return ::android::base::unexpected(
+ ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(::aidl::android::hardware::automotive::vehicle::StatusCode::
+ INVALID_ARG),
+ "empty request"));
+ }
+
+ return std::move(result.value().value());
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_ParcelableUtils_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
new file mode 100644
index 0000000..656dfaf
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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 "ConnectedClient.h"
+#include "ParcelableUtils.h"
+
+#include <VehicleHalTypes.h>
+
+#include <utils/Log.h>
+
+#include <inttypes.h>
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::android::base::Result;
+using ::ndk::ScopedAStatus;
+
+// A function to call the specific callback based on results type.
+template <class T>
+ScopedAStatus callCallback(std::shared_ptr<IVehicleCallback> callback, const T& results);
+
+template <>
+ScopedAStatus callCallback<GetValueResults>(std::shared_ptr<IVehicleCallback> callback,
+ const GetValueResults& results) {
+ return callback->onGetValues(results);
+}
+
+template <>
+ScopedAStatus callCallback<SetValueResults>(std::shared_ptr<IVehicleCallback> callback,
+ const SetValueResults& results) {
+ return callback->onSetValues(results);
+}
+
+// Send a single GetValue/SetValue result through the callback.
+template <class ResultType, class ResultsType>
+void sendGetOrSetValueResult(std::shared_ptr<IVehicleCallback> callback, const ResultType& result) {
+ ResultsType parcelableResults;
+ parcelableResults.payloads.resize(1);
+ parcelableResults.payloads[0] = result;
+ if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults);
+ !callbackStatus.isOk()) {
+ ALOGE("failed to call callback, error: %s, code: %d", callbackStatus.getMessage(),
+ callbackStatus.getServiceSpecificError());
+ }
+}
+
+// Send all the GetValue/SetValue results through callback, one result in each callback invocation.
+template <class ResultType, class ResultsType>
+void sendGetOrSetValueResultsSeparately(std::shared_ptr<IVehicleCallback> callback,
+ const std::vector<ResultType>& results) {
+ for (const auto& result : results) {
+ sendGetOrSetValueResult<ResultType, ResultsType>(callback, result);
+ }
+}
+
+// Send all the GetValue/SetValue results through callback in a single callback invocation.
+template <class ResultType, class ResultsType>
+void sendGetOrSetValueResults(std::shared_ptr<IVehicleCallback> callback,
+ const std::vector<ResultType>& results) {
+ ResultsType parcelableResults;
+ ScopedAStatus status = vectorToStableLargeParcelable(results, &parcelableResults);
+ if (status.isOk()) {
+ if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults);
+ !callbackStatus.isOk()) {
+ ALOGE("failed to call callback, error: %s, code: %d", status.getMessage(),
+ status.getServiceSpecificError());
+ }
+ return;
+ }
+ int statusCode = status.getServiceSpecificError();
+ ALOGE("failed to marshal result into large parcelable, error: "
+ "%s, code: %d",
+ status.getMessage(), statusCode);
+ sendGetOrSetValueResultsSeparately<ResultType, ResultsType>(callback, results);
+}
+
+// Specify the functions for GetValues and SetValues types.
+template void sendGetOrSetValueResult<GetValueResult, GetValueResults>(
+ std::shared_ptr<IVehicleCallback> callback, const GetValueResult& result);
+template void sendGetOrSetValueResult<SetValueResult, SetValueResults>(
+ std::shared_ptr<IVehicleCallback> callback, const SetValueResult& result);
+
+template void sendGetOrSetValueResults<GetValueResult, GetValueResults>(
+ std::shared_ptr<IVehicleCallback> callback, const std::vector<GetValueResult>& results);
+template void sendGetOrSetValueResults<SetValueResult, SetValueResults>(
+ std::shared_ptr<IVehicleCallback> callback, const std::vector<SetValueResult>& results);
+
+template void sendGetOrSetValueResultsSeparately<GetValueResult, GetValueResults>(
+ std::shared_ptr<IVehicleCallback> callback, const std::vector<GetValueResult>& results);
+template void sendGetOrSetValueResultsSeparately<SetValueResult, SetValueResults>(
+ std::shared_ptr<IVehicleCallback> callback, const std::vector<SetValueResult>& results);
+
+} // namespace
+
+ConnectedClient::ConnectedClient(std::shared_ptr<IVehicleCallback> callback)
+ : mCallback(callback) {}
+
+template <class ResultType, class ResultsType>
+GetSetValuesClient<ResultType, ResultsType>::GetSetValuesClient(
+ std::shared_ptr<IVehicleCallback> callback)
+ : ConnectedClient(callback) {
+ mResultCallback = std::make_shared<const std::function<void(std::vector<ResultType>)>>(
+ [callback](std::vector<ResultType> results) {
+ return sendGetOrSetValueResults<ResultType, ResultsType>(callback, results);
+ });
+}
+
+template <class ResultType, class ResultsType>
+std::shared_ptr<const std::function<void(std::vector<ResultType>)>>
+GetSetValuesClient<ResultType, ResultsType>::getResultCallback() {
+ return mResultCallback;
+}
+
+template <class ResultType, class ResultsType>
+void GetSetValuesClient<ResultType, ResultsType>::sendResults(
+ const std::vector<ResultType>& results) {
+ return sendGetOrSetValueResults<ResultType, ResultsType>(mCallback, results);
+}
+
+template <class ResultType, class ResultsType>
+void GetSetValuesClient<ResultType, ResultsType>::sendResultsSeparately(
+ const std::vector<ResultType>& results) {
+ return sendGetOrSetValueResultsSeparately<ResultType, ResultsType>(mCallback, results);
+}
+
+template class GetSetValuesClient<GetValueResult, GetValueResults>;
+template class GetSetValuesClient<SetValueResult, SetValueResults>;
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 5a31643..fd9e331 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -18,7 +18,11 @@
#include <DefaultVehicleHal.h>
+#include <LargeParcelableBase.h>
#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+#include <android-base/result.h>
+#include <utils/Log.h>
namespace android {
namespace hardware {
@@ -28,12 +32,41 @@
using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::android::automotive::car_binder_lib::LargeParcelableBase;
+using ::android::base::Result;
using ::ndk::ScopedAStatus;
-ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs*) {
- // TODO(b/200737967): implement this.
+DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware)
+ : mVehicleHardware(std::move(hardware)) {
+ auto configs = mVehicleHardware->getAllPropertyConfigs();
+ for (auto& config : configs) {
+ mConfigsByPropId[config.prop] = config;
+ }
+ auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(configs);
+ if (!result.ok()) {
+ ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
+ getErrorMsg(result).c_str(), getIntErrorCode(result));
+ return;
+ }
+
+ if (result.value() != nullptr) {
+ mConfigFile = std::move(result.value());
+ }
+}
+
+ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
+ if (mConfigFile != nullptr) {
+ output->sharedMemoryFd.set(dup(mConfigFile->get()));
+ return ScopedAStatus::ok();
+ }
+ output->payloads.reserve(mConfigsByPropId.size());
+ for (const auto& [_, config] : mConfigsByPropId) {
+ output->payloads.push_back(config);
+ }
return ScopedAStatus::ok();
}
@@ -49,9 +82,15 @@
return ScopedAStatus::ok();
}
-ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>&, VehiclePropConfigs*) {
- // TODO(b/200737967): implement this.
- return ScopedAStatus::ok();
+ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
+ VehiclePropConfigs* output) {
+ std::vector<VehiclePropConfig> configs;
+ for (int32_t prop : props) {
+ if (mConfigsByPropId.find(prop) != mConfigsByPropId.end()) {
+ configs.push_back(mConfigsByPropId[prop]);
+ }
+ }
+ return defaultvehiclehal_impl::vectorToStableLargeParcelable(configs, output);
}
ScopedAStatus DefaultVehicleHal::subscribe(const std::shared_ptr<IVehicleCallback>&,
@@ -72,6 +111,10 @@
return ScopedAStatus::ok();
}
+IVehicleHardware* DefaultVehicleHal::getHardware() {
+ return mVehicleHardware.get();
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
index 7c623ea..14224a5 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
@@ -17,15 +17,19 @@
#define LOG_TAG "VehicleService"
#include <DefaultVehicleHal.h>
+#include <FakeVehicleHardware.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <utils/Log.h>
using ::android::hardware::automotive::vehicle::DefaultVehicleHal;
+using ::android::hardware::automotive::vehicle::fake::FakeVehicleHardware;
int main(int /* argc */, char* /* argv */[]) {
- std::shared_ptr<DefaultVehicleHal> vhal = ndk::SharedRefBase::make<DefaultVehicleHal>();
+ std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
+ std::shared_ptr<DefaultVehicleHal> vhal =
+ ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
ALOGI("Registering as service...");
binder_exception_t err = AServiceManager_addService(vhal->asBinder().get(),
diff --git a/automotive/vehicle/aidl/impl/vhal/test/Android.bp b/automotive/vehicle/aidl/impl/vhal/test/Android.bp
new file mode 100644
index 0000000..bf16475
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/Android.bp
@@ -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.
+ */
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "DefaultVehicleHalTest",
+ vendor: true,
+ srcs: ["*.cpp"],
+ static_libs: [
+ "DefaultVehicleHal",
+ "VehicleHalUtils",
+ "android-automotive-large-parcelable-vendor-lib",
+ "libgtest",
+ "libgmock",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ ],
+ header_libs: [
+ "IVehicleHardware",
+ ],
+ defaults: [
+ "VehicleHalDefaults",
+ "android-automotive-large-parcelable-defaults",
+ ],
+ test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp
new file mode 100644
index 0000000..ddd0c65
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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 "ConnectedClient.h"
+#include "MockVehicleCallback.h"
+
+#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+class ConnectedClientTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
+ mCallbackClient = IVehicleCallback::fromBinder(mCallback->asBinder());
+ }
+
+ std::shared_ptr<IVehicleCallback> getCallbackClient() { return mCallbackClient; }
+
+ MockVehicleCallback* getCallback() { return mCallback.get(); }
+
+ protected:
+ using GetValuesClient = GetSetValuesClient<GetValueResult, GetValueResults>;
+ using SetValuesClient = GetSetValuesClient<SetValueResult, SetValueResults>;
+
+ private:
+ std::shared_ptr<MockVehicleCallback> mCallback;
+ std::shared_ptr<IVehicleCallback> mCallbackClient;
+};
+
+TEST_F(ConnectedClientTest, testSendGetValueResults) {
+ std::vector<GetValueResult> results = {{
+ .requestId = 0,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = 0,
+ },
+ },
+ {
+ .requestId = 1,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = 1,
+ },
+ }};
+
+ GetValuesClient client(getCallbackClient());
+
+ client.sendResults(results);
+
+ auto maybeGetValueResults = getCallback()->nextGetValueResults();
+ ASSERT_TRUE(maybeGetValueResults.has_value());
+ ASSERT_EQ(maybeGetValueResults.value().payloads, results);
+}
+
+TEST_F(ConnectedClientTest, testSendGetValueResultsSeparately) {
+ std::vector<GetValueResult> results = {{
+ .requestId = 0,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = 0,
+ },
+ },
+ {
+ .requestId = 1,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = 1,
+ },
+ }};
+
+ GetValuesClient client(getCallbackClient());
+
+ client.sendResultsSeparately(results);
+
+ for (auto& result : results) {
+ auto maybeGetValueResults = getCallback()->nextGetValueResults();
+ EXPECT_TRUE(maybeGetValueResults.has_value());
+ if (!maybeGetValueResults.has_value()) {
+ continue;
+ }
+ EXPECT_EQ(maybeGetValueResults.value().payloads, std::vector<GetValueResult>({result}));
+ }
+}
+
+TEST_F(ConnectedClientTest, testGetValuesGnResultCallback) {
+ std::vector<GetValueResult> results = {{
+ .requestId = 0,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = 0,
+ },
+ },
+ {
+ .requestId = 1,
+ .status = StatusCode::OK,
+ .prop =
+ VehiclePropValue{
+ .prop = 1,
+ },
+ }};
+
+ GetValuesClient client(getCallbackClient());
+
+ (*(client.getResultCallback()))(results);
+
+ auto maybeGetValueResults = getCallback()->nextGetValueResults();
+ ASSERT_TRUE(maybeGetValueResults.has_value());
+ ASSERT_EQ(maybeGetValueResults.value().payloads, results);
+}
+
+TEST_F(ConnectedClientTest, testSendSetValueResults) {
+ std::vector<SetValueResult> results = {{
+ .requestId = 0,
+ .status = StatusCode::OK,
+ },
+ {
+ .requestId = 1,
+ .status = StatusCode::OK,
+ }};
+
+ SetValuesClient client(getCallbackClient());
+
+ client.sendResults(results);
+
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value());
+ ASSERT_EQ(maybeSetValueResults.value().payloads, results);
+}
+
+TEST_F(ConnectedClientTest, testSendSetValueResultsSeparately) {
+ std::vector<SetValueResult> results = {{
+ .requestId = 0,
+ .status = StatusCode::OK,
+ },
+ {
+ .requestId = 1,
+ .status = StatusCode::OK,
+ }};
+
+ SetValuesClient client(getCallbackClient());
+
+ client.sendResultsSeparately(results);
+
+ for (auto& result : results) {
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ EXPECT_TRUE(maybeSetValueResults.has_value());
+ if (!maybeSetValueResults.has_value()) {
+ continue;
+ }
+ EXPECT_EQ(maybeSetValueResults.value().payloads, std::vector<SetValueResult>({result}));
+ }
+}
+
+TEST_F(ConnectedClientTest, testSetValuesGetResultCallback) {
+ std::vector<SetValueResult> results = {{
+ .requestId = 0,
+ .status = StatusCode::OK,
+ },
+ {
+ .requestId = 1,
+ .status = StatusCode::OK,
+ }};
+
+ SetValuesClient client(getCallbackClient());
+
+ (*(client.getResultCallback()))(results);
+
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value());
+ ASSERT_EQ(maybeSetValueResults.value().payloads, results);
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
new file mode 100644
index 0000000..62a7098
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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 "DefaultVehicleHal.h"
+
+#include <IVehicleHardware.h>
+#include <LargeParcelableBase.h>
+#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <optional>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::IVehicle;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+
+using ::android::automotive::car_binder_lib::LargeParcelableBase;
+using ::android::base::Result;
+
+using ::testing::Eq;
+using ::testing::WhenSortedBy;
+
+class MockVehicleHardware final : public IVehicleHardware {
+ public:
+ std::vector<VehiclePropConfig> getAllPropertyConfigs() const override {
+ return mPropertyConfigs;
+ }
+
+ StatusCode setValues(std::function<void(const std::vector<SetValueResult>&)>&&,
+ const std::vector<SetValueRequest>&) override {
+ // TODO(b/200737967): mock this.
+ return StatusCode::OK;
+ }
+
+ StatusCode getValues(std::function<void(const std::vector<GetValueResult>&)>&&,
+ const std::vector<GetValueRequest>&) const override {
+ // TODO(b/200737967): mock this.
+ return StatusCode::OK;
+ }
+
+ DumpResult dump(const std::vector<std::string>&) override {
+ // TODO(b/200737967): mock this.
+ return DumpResult{};
+ }
+
+ StatusCode checkHealth() override {
+ // TODO(b/200737967): mock this.
+ return StatusCode::OK;
+ }
+
+ void registerOnPropertyChangeEvent(
+ std::function<void(const std::vector<VehiclePropValue>&)>&&) override {
+ // TODO(b/200737967): mock this.
+ }
+
+ void registerOnPropertySetErrorEvent(
+ std::function<void(const std::vector<SetValueErrorEvent>&)>&&) override {
+ // TODO(b/200737967): mock this.
+ }
+
+ // Test functions.
+ void setPropertyConfigs(const std::vector<VehiclePropConfig>& configs) {
+ mPropertyConfigs = configs;
+ }
+
+ private:
+ std::vector<VehiclePropConfig> mPropertyConfigs;
+};
+
+struct PropConfigCmp {
+ bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {
+ return (a.prop < b.prop);
+ }
+} propConfigCmp;
+
+} // namespace
+
+TEST(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
+ auto testConfigs = std::vector<VehiclePropConfig>({
+ VehiclePropConfig{
+ .prop = 1,
+ },
+ VehiclePropConfig{
+ .prop = 2,
+ },
+ });
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ hardware->setPropertyConfigs(testConfigs);
+ auto vhal = ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+ VehiclePropConfigs output;
+ auto status = client->getAllPropConfigs(&output);
+
+ ASSERT_TRUE(status.isOk());
+ ASSERT_THAT(output.payloads, WhenSortedBy(propConfigCmp, Eq(testConfigs)));
+}
+
+TEST(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
+ std::vector<VehiclePropConfig> testConfigs;
+ // 10000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
+ for (size_t i = 0; i < 10000; i++) {
+ testConfigs.push_back(VehiclePropConfig{
+ .prop = static_cast<int32_t>(i),
+ });
+ }
+
+ auto hardware = std::make_unique<MockVehicleHardware>();
+ hardware->setPropertyConfigs(testConfigs);
+ auto vhal = ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+ std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+ VehiclePropConfigs output;
+ auto status = client->getAllPropConfigs(&output);
+
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(output.payloads.empty());
+ Result<std::optional<std::vector<VehiclePropConfig>>> result =
+ LargeParcelableBase::stableLargeParcelableToParcelableVector<VehiclePropConfig>(
+ output.sharedMemoryFd);
+ ASSERT_TRUE(result.ok());
+ ASSERT_TRUE(result.value().has_value());
+ ASSERT_EQ(result.value().value(), testConfigs);
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
new file mode 100644
index 0000000..ca366cd
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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 "MockVehicleCallback.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
+
+template <class T>
+std::optional<T> pop(std::list<T>& items) {
+ if (items.size() > 0) {
+ auto item = std::move(items.front());
+ items.pop_front();
+ return item;
+ }
+ return std::nullopt;
+}
+
+template <class T>
+static ScopedAStatus storeResults(const T& results, std::list<T>* storedResults) {
+ T resultsCopy{
+ .payloads = results.payloads,
+ };
+ int fd = results.sharedMemoryFd.get();
+ if (fd != -1) {
+ resultsCopy.sharedMemoryFd = ScopedFileDescriptor(dup(fd));
+ }
+ storedResults->push_back(std::move(resultsCopy));
+ return ScopedAStatus::ok();
+}
+
+} // namespace
+
+ScopedAStatus MockVehicleCallback::onGetValues(const GetValueResults& results) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return storeResults(results, &mGetValueResults);
+}
+
+ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return storeResults(results, &mSetValueResults);
+}
+
+ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues&, int32_t) {
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors&) {
+ return ScopedAStatus::ok();
+}
+
+std::optional<GetValueResults> MockVehicleCallback::nextGetValueResults() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return pop(mGetValueResults);
+}
+
+std::optional<SetValueResults> MockVehicleCallback::nextSetValueResults() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return pop(mSetValueResults);
+}
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
new file mode 100644
index 0000000..916575a
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
+
+#include <VehicleHalTypes.h>
+
+#include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h>
+#include <android-base/thread_annotations.h>
+
+#include <list>
+#include <mutex>
+#include <optional>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// MockVehicleCallback is a mock VehicleCallback implementation that simply stores the results.
+class MockVehicleCallback final
+ : public ::aidl::android::hardware::automotive::vehicle::BnVehicleCallback {
+ public:
+ ::ndk::ScopedAStatus onGetValues(
+ const ::aidl::android::hardware::automotive::vehicle::GetValueResults& results)
+ override;
+ ::ndk::ScopedAStatus onSetValues(
+ const ::aidl::android::hardware::automotive::vehicle::SetValueResults& results)
+ override;
+ ::ndk::ScopedAStatus onPropertyEvent(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropValues&,
+ int32_t) override;
+ ::ndk::ScopedAStatus onPropertySetError(
+ const ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors&) override;
+
+ // Test functions
+ std::optional<::aidl::android::hardware::automotive::vehicle::GetValueResults>
+ nextGetValueResults();
+ std::optional<::aidl::android::hardware::automotive::vehicle::SetValueResults>
+ nextSetValueResults();
+
+ private:
+ std::mutex mLock;
+ std::list<::aidl::android::hardware::automotive::vehicle::GetValueResults> mGetValueResults
+ GUARDED_BY(mLock);
+ std::list<::aidl::android::hardware::automotive::vehicle::SetValueResults> mSetValueResults
+ GUARDED_BY(mLock);
+};
+
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
new file mode 100644
index 0000000..60da877
--- /dev/null
+++ b/bluetooth/audio/aidl/Android.bp
@@ -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.
+
+aidl_interface {
+ name: "android.hardware.bluetooth.audio",
+ vendor_available: true,
+ srcs: ["android/hardware/bluetooth/audio/*.aidl"],
+ stability: "vintf",
+ imports: [
+ "android.hardware.common-V2",
+ "android.hardware.common.fmq-V1",
+ "android.hardware.audio.common",
+ ],
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ enabled: false,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
new file mode 100644
index 0000000..ad44c26
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable AacCapabilities {
+ android.hardware.bluetooth.audio.AacObjectType objectType;
+ int[] sampleRateHz;
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ boolean variableBitRateSupported;
+ byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
new file mode 100644
index 0000000..6adef6d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable AacConfiguration {
+ android.hardware.bluetooth.audio.AacObjectType objectType;
+ int sampleRateHz;
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ boolean variableBitRateEnabled;
+ byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
new file mode 100644
index 0000000..c129c66
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum AacObjectType {
+ MPEG2_LC = 1,
+ MPEG4_LC = 2,
+ MPEG4_LTP = 4,
+ MPEG4_SCALABLE = 8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
new file mode 100644
index 0000000..4767b69
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable AptxCapabilities {
+ int[] sampleRateHz;
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
new file mode 100644
index 0000000..91e88b3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable AptxConfiguration {
+ int sampleRateHz;
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
new file mode 100644
index 0000000..20a7731
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+union AudioCapabilities {
+ android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities;
+ android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities;
+ android.hardware.bluetooth.audio.LeAudioCapabilities leAudioCapabilities;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
new file mode 100644
index 0000000..34f7837
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+union AudioConfiguration {
+ android.hardware.bluetooth.audio.PcmConfiguration pcmConfig;
+ android.hardware.bluetooth.audio.CodecConfiguration codecConfig;
+ android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
new file mode 100644
index 0000000..319a5e2
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum AudioLocation {
+ UNKNOWN = 1,
+ FRONT_LEFT = 2,
+ FRONT_RIGHT = 4,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
new file mode 100644
index 0000000..b3aa709
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable BroadcastConfiguration {
+ android.hardware.bluetooth.audio.BroadcastConfiguration.BroadcastStreamMap[] streamMap;
+ @VintfStability
+ parcelable BroadcastStreamMap {
+ char streamHandle;
+ int audioChannelAllocation;
+ android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCondecConfig;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
new file mode 100644
index 0000000..3ca93c3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum ChannelMode {
+ UNKNOWN = 1,
+ MONO = 2,
+ STEREO = 4,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
new file mode 100644
index 0000000..b451880
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable CodecCapabilities {
+ android.hardware.bluetooth.audio.CodecType codecType;
+ android.hardware.bluetooth.audio.CodecCapabilities.Capabilities capabilities;
+ @VintfStability
+ union Capabilities {
+ android.hardware.bluetooth.audio.SbcCapabilities sbcCapabilities;
+ android.hardware.bluetooth.audio.AacCapabilities aacCapabilities;
+ android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities;
+ android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
new file mode 100644
index 0000000..863aee2
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable CodecConfiguration {
+ android.hardware.bluetooth.audio.CodecType codecType;
+ int encodedAudioBitrate;
+ int peerMtu;
+ boolean isScmstEnabled;
+ android.hardware.bluetooth.audio.CodecConfiguration.CodecSpecific config;
+ @VintfStability
+ union CodecSpecific {
+ android.hardware.bluetooth.audio.SbcConfiguration sbcConfig;
+ android.hardware.bluetooth.audio.AacConfiguration aacConfig;
+ android.hardware.bluetooth.audio.LdacConfiguration ldacConfig;
+ android.hardware.bluetooth.audio.AptxConfiguration aptxConfig;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
new file mode 100644
index 0000000..44b434b
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum CodecType {
+ UNKNOWN = 0,
+ SBC = 1,
+ AAC = 2,
+ APTX = 3,
+ APTX_HD = 4,
+ LDAC = 5,
+ LC3 = 6,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
new file mode 100644
index 0000000..e389ef3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioPort {
+ android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition();
+ void startStream();
+ void stopStream();
+ void suspendStream();
+ void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
new file mode 100644
index 0000000..84bcc0c
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioProvider {
+ void endSession();
+ android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.UnsynchronizedWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+ void streamStarted(in boolean status);
+ void streamSuspended(in boolean status);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
new file mode 100644
index 0000000..5e33deb
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioProviderFactory {
+ android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
+ android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
new file mode 100644
index 0000000..3c650da
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable Lc3Capabilities {
+ byte[] pcmBitDepth;
+ int[] samplingFrequencyHz;
+ int[] frameDurationUs;
+ int[] octetsPerFrame;
+ byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
new file mode 100644
index 0000000..ef77da7
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable Lc3Configuration {
+ byte pcmBitDepth;
+ int samplingFrequencyHz;
+ int frameDurationUs;
+ int octetsPerFrame;
+ byte blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
new file mode 100644
index 0000000..19e041a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable LdacCapabilities {
+ int[] sampleRateHz;
+ android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+ android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+ byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
new file mode 100644
index 0000000..a9d6c5e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacChannelMode {
+ UNKNOWN = 1,
+ STEREO = 2,
+ DUAL = 4,
+ MONO = 8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
new file mode 100644
index 0000000..8a37638
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable LdacConfiguration {
+ int sampleRateHz;
+ android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+ android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+ byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
new file mode 100644
index 0000000..bc0d97b
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacQualityIndex {
+ QUALITY_HIGH = 1,
+ QUALITY_MID = 2,
+ QUALITY_LOW = 4,
+ QUALITY_ABR = 8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
new file mode 100644
index 0000000..9efafca
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioCapabilities {
+ android.hardware.bluetooth.audio.LeAudioMode mode;
+ android.hardware.bluetooth.audio.CodecType codecType;
+ android.hardware.bluetooth.audio.AudioLocation supportedChannel;
+ int supportedChannelCount;
+ android.hardware.bluetooth.audio.LeAudioCapabilities.LeaudioCodecCapabilities leaudioCodecCapabilities;
+ @VintfStability
+ parcelable VendorCapabilities {
+ ParcelableHolder extension;
+ }
+ @VintfStability
+ union LeaudioCodecCapabilities {
+ android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
+ android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
new file mode 100644
index 0000000..bb3d7e4
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+union LeAudioCodecConfiguration {
+ android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
+ android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+ @VintfStability
+ parcelable VendorConfiguration {
+ ParcelableHolder extension;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
new file mode 100644
index 0000000..c6cb5cb
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioConfiguration {
+ android.hardware.bluetooth.audio.LeAudioMode mode;
+ android.hardware.bluetooth.audio.LeAudioConfiguration.LeAuioModeConfig modeConfig;
+ android.hardware.bluetooth.audio.CodecType codecType;
+ @VintfStability
+ union LeAuioModeConfig {
+ android.hardware.bluetooth.audio.UnicastConfiguration unicastConfig;
+ android.hardware.bluetooth.audio.BroadcastConfiguration broadcastConfig;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
new file mode 100644
index 0000000..766f637
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LeAudioMode {
+ UNKNOWN = 0,
+ UNICAST = 1,
+ BROADCAST = 2,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
new file mode 100644
index 0000000..0c2f87d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable PcmCapabilities {
+ int[] sampleRateHz;
+ android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+ byte[] bitsPerSample;
+ int[] dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
new file mode 100644
index 0000000..93d7805
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable PcmConfiguration {
+ int sampleRateHz;
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ byte bitsPerSample;
+ int dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
new file mode 100644
index 0000000..810a9a1
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.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.bluetooth.audio;
+@VintfStability
+parcelable PresentationPosition {
+ long remoteDeviceAudioDelayNanos;
+ long transmittedOctets;
+ android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimeStamp;
+ @VintfStability
+ parcelable TimeSpec {
+ long tvSec;
+ long tvNSec;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
new file mode 100644
index 0000000..5170f16
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcAllocMethod {
+ ALLOC_MD_S = 1,
+ ALLOC_MD_L = 2,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
new file mode 100644
index 0000000..ec3aa0f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable SbcCapabilities {
+ int[] sampleRateHz;
+ android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+ byte[] blockLength;
+ byte[] numSubbands;
+ android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+ byte[] bitsPerSample;
+ int minBitpool;
+ int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
new file mode 100644
index 0000000..88fca4a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcChannelMode {
+ UNKNOWN = 1,
+ JOINT_STEREO = 2,
+ STEREO = 4,
+ DUAL = 8,
+ MONO = 16,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
new file mode 100644
index 0000000..8eab9c3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable SbcConfiguration {
+ int sampleRateHz;
+ android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+ byte blockLength;
+ byte numSubbands;
+ android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+ byte bitsPerSample;
+ int minBitpool;
+ int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
new file mode 100644
index 0000000..900ab31
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SessionType {
+ UNKNOWN = 0,
+ A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
+ A2DP_HARDWARE_OFFLOAD_DATAPATH = 2,
+ HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
+ LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
new file mode 100644
index 0000000..b385763
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.bluetooth.audio;
+@VintfStability
+parcelable UnicastConfiguration {
+ android.hardware.bluetooth.audio.UnicastConfiguration.UnicastStreamMap[] streamMap;
+ int peerDelay;
+ android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+ @VintfStability
+ parcelable UnicastStreamMap {
+ char streamHandle;
+ int audioChannelAllocation;
+ }
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
new file mode 100644
index 0000000..4303883
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacObjectType;
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AAC codec capabilities
+ */
+@VintfStability
+parcelable AacCapabilities {
+ /* bitfield */
+ AacObjectType objectType;
+ int[] sampleRateHz;
+ /* bitfield */
+ ChannelMode channelMode;
+ boolean variableBitRateSupported;
+ byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
new file mode 100644
index 0000000..30338e7
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacObjectType;
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AAC codec configuration
+ */
+@VintfStability
+parcelable AacConfiguration {
+ AacObjectType objectType;
+ int sampleRateHz;
+ ChannelMode channelMode;
+ boolean variableBitRateEnabled;
+ byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
new file mode 100644
index 0000000..480e422
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum AacObjectType {
+ /**
+ * MPEG-2 Low Complexity. Support is Mandatory.
+ */
+ MPEG2_LC = 1,
+ /**
+ * MPEG-4 Low Complexity. Support is Optional.
+ */
+ MPEG4_LC = 1 << 1,
+ /**
+ * MPEG-4 Long Term Prediction. Support is Optional.
+ */
+ MPEG4_LTP = 1 << 2,
+ /**
+ * MPEG-4 Scalable. Support is Optional.
+ */
+ MPEG4_SCALABLE = 1 << 3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
new file mode 100644
index 0000000..6a37fc6
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AptX and AptX-HD codec capabilities
+ */
+@VintfStability
+parcelable AptxCapabilities {
+ int[] sampleRateHz;
+ /* bitfield */
+ ChannelMode channelMode;
+ byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
new file mode 100644
index 0000000..83b7b0c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AptX and AptX-HD codec configuration
+ */
+@VintfStability
+parcelable AptxConfiguration {
+ int sampleRateHz;
+ ChannelMode channelMode;
+ byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
new file mode 100644
index 0000000..6ed4472
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecCapabilities;
+import android.hardware.bluetooth.audio.LeAudioCapabilities;
+import android.hardware.bluetooth.audio.PcmCapabilities;
+
+/**
+ * Used to specify the capabilities of the different session types
+ */
+@VintfStability
+union AudioCapabilities {
+ PcmCapabilities pcmCapabilities;
+ CodecCapabilities codecCapabilities;
+ LeAudioCapabilities leAudioCapabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
new file mode 100644
index 0000000..ce515b5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.LeAudioConfiguration;
+import android.hardware.bluetooth.audio.PcmConfiguration;
+
+/**
+ * Used to configure either a Hardware or Software Encoding session based on session type
+ */
+@VintfStability
+union AudioConfiguration {
+ PcmConfiguration pcmConfig;
+ CodecConfiguration codecConfig;
+ LeAudioConfiguration leAudioConfig;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
new file mode 100644
index 0000000..dedfbf9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="int")
+enum AudioLocation {
+ UNKNOWN = 1,
+ FRONT_LEFT = 1 << 1,
+ FRONT_RIGHT = 1 << 2,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
new file mode 100644
index 0000000..07d05f1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.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.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
+
+@VintfStability
+parcelable BroadcastConfiguration {
+ @VintfStability
+ parcelable BroadcastStreamMap {
+ /*
+ * The connection handle used for a unicast or a broadcast group.
+ * Range: 0x0000 to 0xEFFF
+ */
+ char streamHandle;
+ /*
+ * Audio channel allocation is a bit field, each enabled bit means that given audio
+ * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+ * least significant bit to the most significant bit.
+ */
+ int audioChannelAllocation;
+ LeAudioCodecConfiguration leAudioCondecConfig;
+ }
+ BroadcastStreamMap[] streamMap;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
new file mode 100644
index 0000000..2df879d
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum ChannelMode {
+ UNKNOWN = 1,
+ MONO = 1 << 1,
+ STEREO = 1 << 2,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
new file mode 100644
index 0000000..0eee8cb
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacCapabilities;
+import android.hardware.bluetooth.audio.AptxCapabilities;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LdacCapabilities;
+import android.hardware.bluetooth.audio.SbcCapabilities;
+
+/**
+ * Used to specify the capabilities of the codecs supported by Hardware Encoding.
+ * AptX and AptX-HD both use the AptxCapabilities field.
+ */
+@VintfStability
+parcelable CodecCapabilities {
+ @VintfStability
+ union Capabilities {
+ SbcCapabilities sbcCapabilities;
+ AacCapabilities aacCapabilities;
+ LdacCapabilities ldacCapabilities;
+ AptxCapabilities aptxCapabilities;
+ }
+ CodecType codecType;
+ Capabilities capabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
new file mode 100644
index 0000000..fac90f0
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacConfiguration;
+import android.hardware.bluetooth.audio.AptxConfiguration;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LdacConfiguration;
+import android.hardware.bluetooth.audio.SbcConfiguration;
+
+/**
+ * Used to configure a Hardware Encoding session.
+ * AptX and AptX-HD both use the AptxConfiguration field.
+ */
+@VintfStability
+parcelable CodecConfiguration {
+ @VintfStability
+ union CodecSpecific {
+ SbcConfiguration sbcConfig;
+ AacConfiguration aacConfig;
+ LdacConfiguration ldacConfig;
+ AptxConfiguration aptxConfig;
+ }
+ CodecType codecType;
+ /**
+ * The encoded audio bitrate in bits / second.
+ * 0x00000000 - The audio bitrate is not specified / unused
+ * 0x00000001 - 0x00FFFFFF - Encoded audio bitrate in bits/second
+ * 0x01000000 - 0xFFFFFFFF - Reserved
+ *
+ * The HAL needs to support all legal bitrates for the selected codec.
+ */
+ int encodedAudioBitrate;
+ /**
+ * Peer MTU (in two-octets)
+ */
+ int peerMtu;
+ /**
+ * Content protection by SCMS-T
+ */
+ boolean isScmstEnabled;
+ CodecSpecific config;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
new file mode 100644
index 0000000..68c60f5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="int")
+enum CodecType {
+ UNKNOWN,
+ SBC,
+ AAC,
+ APTX,
+ APTX_HD,
+ LDAC,
+ LC3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
new file mode 100644
index 0000000..50e3197
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -0,0 +1,73 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.audio.common.SourceMetadata;
+import android.hardware.bluetooth.audio.PresentationPosition;
+
+/**
+ * HAL interface from the Audio HAL to the Bluetooth stack
+ *
+ * The Audio HAL calls methods in this interface to start, suspend, and stop
+ * an audio stream. These calls return immediately and the results, if any,
+ * are sent over the IBluetoothAudioProvider interface.
+ *
+ * Moreover, the Audio HAL can also get the presentation position of the stream
+ * and provide stream metadata.
+ *
+ */
+@VintfStability
+interface IBluetoothAudioPort {
+ /**
+ * Get the audio presentation position.
+ *
+ * @return the audio presentation position
+ *
+ */
+ PresentationPosition getPresentationPosition();
+
+ /**
+ * This indicates that the caller of this method has opened the data path
+ * and wants to start an audio stream. The caller must wait for a
+ * IBluetoothAudioProvider.streamStarted(Status) call.
+ */
+ void startStream();
+
+ /**
+ * This indicates that the caller of this method wants to stop the audio
+ * stream. The data path will be closed after this call. There is no
+ * callback from the IBluetoothAudioProvider interface even though the
+ * teardown is asynchronous.
+ */
+ void stopStream();
+
+ /**
+ * This indicates that the caller of this method wants to suspend the audio
+ * stream. The caller must wait for the Bluetooth process to call
+ * IBluetoothAudioProvider.streamSuspended(Status). The caller still keeps
+ * the data path open.
+ */
+ void suspendStream();
+
+ /**
+ * Called when the metadata of the stream's source has been changed.
+ *
+ * @param sourceMetadata Description of the audio that is played by the
+ * clients.
+ */
+ void updateMetadata(in SourceMetadata sourceMetadata);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
new file mode 100644
index 0000000..cebd808
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -0,0 +1,74 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioConfiguration;
+import android.hardware.bluetooth.audio.IBluetoothAudioPort;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.UnsynchronizedWrite;
+
+/**
+ * HAL interface from the Bluetooth stack to the Audio HAL
+ *
+ * The Bluetooth stack calls methods in this interface to start and end audio
+ * sessions and sends callback events to the Audio HAL.
+ *
+ */
+@VintfStability
+interface IBluetoothAudioProvider {
+ /**
+ * Ends the current session and unregisters the IBluetoothAudioPort
+ * interface.
+ */
+ void endSession();
+
+ /**
+ * This method indicates that the Bluetooth stack is ready to stream audio.
+ * It registers an instance of IBluetoothAudioPort with and provides the
+ * current negotiated codec to the Audio HAL. After this method is called,
+ * the Audio HAL can invoke IBluetoothAudioPort.startStream().
+ *
+ * Note: endSession() must be called to unregister this IBluetoothAudioPort
+ *
+ * @param hostIf An instance of IBluetoothAudioPort for stream control
+ * @param audioConfig The audio configuration negotiated with the remote
+ * device. The PCM parameters are set if software based encoding,
+ * otherwise the correct codec configuration is used for hardware
+ * encoding.
+ *
+ * @return The fast message queue for audio data from/to this
+ * provider. Audio data will be in PCM format as specified by the
+ * audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
+ * from/to hardware or on failure
+ */
+ MQDescriptor<int, UnsynchronizedWrite> startSession(
+ in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig);
+
+ /**
+ * Callback for IBluetoothAudioPort.startStream()
+ *
+ * @param status true for SUCCESS or false for FAILURE
+ */
+ void streamStarted(in boolean status);
+
+ /**
+ * Callback for IBluetoothAudioPort.suspendStream()
+ *
+ * @param status true for SUCCESS or false for FAILURE
+ */
+ void streamSuspended(in boolean status);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
new file mode 100644
index 0000000..3cde22c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioCapabilities;
+import android.hardware.bluetooth.audio.IBluetoothAudioProvider;
+import android.hardware.bluetooth.audio.SessionType;
+/**
+ * This factory allows a HAL implementation to be split into multiple
+ * independent providers.
+ *
+ * When the Bluetooth stack is ready to create an audio session, it must first
+ * obtain the IBluetoothAudioProvider for that session type by calling
+ * openProvider().
+ *
+ */
+
+@VintfStability
+interface IBluetoothAudioProviderFactory {
+ /**
+ * Gets a list of audio capabilities for a session type.
+ *
+ * For software encoding, the PCM capabilities are returned.
+ * For hardware encoding, the supported codecs and their capabilities are
+ * returned.
+ *
+ * @param sessionType The session type (e.g.
+ * A2DP_SOFTWARE_ENCODING_DATAPATH).
+ * @return A list containing all the capabilities
+ * supported by the sesson type. The capabilities is a list of
+ * available options when configuring the codec for the session.
+ * For software encoding it is the PCM data rate.
+ * For hardware encoding it is the list of supported codecs and their
+ * capabilities.
+ * If a provider isn't supported, an empty list should be returned.
+ * Note: Only one entry should exist per codec when using hardware
+ * encoding.
+ */
+ AudioCapabilities[] getProviderCapabilities(in SessionType sessionType);
+
+ /**
+ * Opens an audio provider for a session type. To close the provider, it is
+ * necessary to release references to the returned provider object.
+ *
+ * @param sessionType The session type (e.g.
+ * LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
+ *
+ * @return provider The provider of the specified session type
+ */
+ IBluetoothAudioProvider openProvider(in SessionType sessionType);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
new file mode 100644
index 0000000..1aedefd
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding LC3 codec capabilities.
+ */
+@VintfStability
+parcelable Lc3Capabilities {
+ /*
+ * PCM is Input for encoder, Output for decoder
+ */
+ byte[] pcmBitDepth;
+ /*
+ * codec-specific parameters
+ */
+ int[] samplingFrequencyHz;
+ /*
+ * FrameDuration based on microseconds.
+ */
+ int[] frameDurationUs;
+ /*
+ * length in octets of a codec frame
+ */
+ int[] octetsPerFrame;
+ /*
+ * Number of blocks of codec frames per single SDU (Service Data Unit)
+ */
+ byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
new file mode 100644
index 0000000..77c04c1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding LC3 codec configuration.
+ */
+@VintfStability
+parcelable Lc3Configuration {
+ /*
+ * PCM is Input for encoder, Output for decoder
+ */
+ byte pcmBitDepth;
+ /*
+ * codec-specific parameters
+ */
+ int samplingFrequencyHz;
+ /*
+ * FrameDuration based on microseconds.
+ */
+ int frameDurationUs;
+ /*
+ * length in octets of a codec frame
+ */
+ int octetsPerFrame;
+ /*
+ * Number of blocks of codec frames per single SDU (Service Data Unit)
+ */
+ byte blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
new file mode 100644
index 0000000..44cca7e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LdacChannelMode;
+import android.hardware.bluetooth.audio.LdacQualityIndex;
+
+/**
+ * Used for Hardware Encoding LDAC codec capabilities
+ * all qualities must be supported.
+ */
+@VintfStability
+parcelable LdacCapabilities {
+ int[] sampleRateHz;
+ /* bitfiled */
+ LdacChannelMode channelMode;
+ /* bitfiled */
+ LdacQualityIndex qualityIndex;
+ byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
new file mode 100644
index 0000000..3acca32
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.bluetooth.audio;
+
+/**
+ * Channel Mode: 3 bits
+ */
+@VintfStability
+@Backing(type="byte")
+enum LdacChannelMode {
+ UNKNOWN = 1,
+ STEREO = 1 << 1,
+ DUAL = 1 << 2,
+ MONO = 1 << 3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl
new file mode 100644
index 0000000..cc03dd0
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LdacChannelMode;
+import android.hardware.bluetooth.audio.LdacQualityIndex;
+
+/**
+ * Used for Hardware Encoding LDAC codec configuration
+ * Only used when configuring the codec.
+ */
+@VintfStability
+parcelable LdacConfiguration {
+ int sampleRateHz;
+ LdacChannelMode channelMode;
+ LdacQualityIndex qualityIndex;
+ byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
new file mode 100644
index 0000000..fc532f4
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum LdacQualityIndex {
+ /**
+ * 990kbps
+ */
+ QUALITY_HIGH = 1,
+ /**
+ * 660kbps
+ */
+ QUALITY_MID = 1 << 1,
+ /**
+ * 330kbps
+ */
+ QUALITY_LOW = 1 << 2,
+ /**
+ * Adaptive Bit Rate mode
+ */
+ QUALITY_ABR = 1 << 3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
new file mode 100644
index 0000000..ea05820
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioLocation;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.LeAudioMode;
+
+/**
+ * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding.
+ */
+@VintfStability
+parcelable LeAudioCapabilities {
+ @VintfStability
+ parcelable VendorCapabilities {
+ ParcelableHolder extension;
+ }
+ @VintfStability
+ union LeaudioCodecCapabilities {
+ Lc3Capabilities lc3Capabilities;
+ VendorCapabilities vendorCapabillities;
+ }
+ LeAudioMode mode;
+ CodecType codecType;
+ /*
+ * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time.
+ * Example: 0x27 = 0b00100111: One, two, three or six channels supported.
+ */
+ AudioLocation supportedChannel;
+ int supportedChannelCount;
+ LeaudioCodecCapabilities leaudioCodecCapabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
new file mode 100644
index 0000000..421eeb2
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.Lc3Configuration;
+
+@VintfStability
+union LeAudioCodecConfiguration {
+ @VintfStability
+ parcelable VendorConfiguration {
+ ParcelableHolder extension;
+ }
+ Lc3Configuration lc3Config;
+ VendorConfiguration vendorConfig;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
new file mode 100644
index 0000000..a212c96
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.BroadcastConfiguration;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LeAudioMode;
+import android.hardware.bluetooth.audio.UnicastConfiguration;
+
+@VintfStability
+parcelable LeAudioConfiguration {
+ @VintfStability
+ union LeAuioModeConfig {
+ UnicastConfiguration unicastConfig;
+ BroadcastConfiguration broadcastConfig;
+ }
+ /*
+ * The mode of the LE audio
+ */
+ LeAudioMode mode;
+ LeAuioModeConfig modeConfig;
+ CodecType codecType;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
new file mode 100644
index 0000000..2cf019e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum LeAudioMode {
+ UNKNOWN,
+ UNICAST,
+ BROADCAST,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
new file mode 100644
index 0000000..776b777
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Software Encoding audio feed capabilities
+ */
+@VintfStability
+parcelable PcmCapabilities {
+ int[] sampleRateHz;
+ ChannelMode[] channelMode;
+ byte[] bitsPerSample;
+ /**
+ * Data interval for data transfer
+ */
+ int[] dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
new file mode 100644
index 0000000..03aa27b
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Software Encoding audio feed configuration
+ */
+@VintfStability
+parcelable PcmConfiguration {
+ int sampleRateHz;
+ ChannelMode channelMode;
+ byte bitsPerSample;
+ /**
+ * Data interval for data transfer
+ */
+ int dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
new file mode 100644
index 0000000..17e746f
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+parcelable PresentationPosition {
+ @VintfStability
+ parcelable TimeSpec {
+ /**
+ * seconds
+ */
+ long tvSec;
+ /**
+ * nanoseconds
+ */
+ long tvNSec;
+ }
+ /*
+ * remoteDeviceAudioDelayNanos the audio delay from when the remote
+ * device (e.g. headset) receives audio data to when the device plays the
+ * sound. If the delay is unknown, the value is set to zero.
+ */
+ long remoteDeviceAudioDelayNanos;
+ /*
+ * transmittedOctets the number of audio data octets that were sent
+ * to a remote device. This excludes octets that have been written to the
+ * data path but have not been sent to the remote device. The count is
+ * not reset until stopStream() is called. If the software data path is
+ * unused (e.g. Hardware Offload), the value is set to 0.
+ */
+ long transmittedOctets;
+ /*
+ * transmittedOctetsTimeStamp the value of CLOCK_MONOTONIC
+ * corresponding to transmittedOctets. If the software data path is
+ * unused (e.g., for Hardware Offload), the value is set to zero.
+ */
+ TimeSpec transmittedOctetsTimeStamp;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
new file mode 100644
index 0000000..7047e34
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SbcAllocMethod {
+ /**
+ * SNR
+ */
+ ALLOC_MD_S = 1,
+ /**
+ * Loudness
+ */
+ ALLOC_MD_L = 1 << 1,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
new file mode 100644
index 0000000..cf62ed4
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.SbcAllocMethod;
+import android.hardware.bluetooth.audio.SbcChannelMode;
+
+/**
+ * Used for Hardware Encoding SBC codec capabilities.
+ */
+@VintfStability
+parcelable SbcCapabilities {
+ int[] sampleRateHz;
+ /* bitfield */
+ SbcChannelMode channelMode;
+ byte[] blockLength;
+ byte[] numSubbands;
+ /* bitfield */
+ SbcAllocMethod allocMethod;
+ byte[] bitsPerSample;
+ /*
+ * range from 2 to 250.
+ */
+ int minBitpool;
+ /*
+ * range from 2 to 250.
+ */
+ int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
new file mode 100644
index 0000000..7eb38cd
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SbcChannelMode {
+ UNKNOWN = 1,
+ JOINT_STEREO = 1 << 1,
+ STEREO = 1 << 2,
+ DUAL = 1 << 3,
+ MONO = 1 << 4,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl
new file mode 100644
index 0000000..054d03e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.SbcAllocMethod;
+import android.hardware.bluetooth.audio.SbcChannelMode;
+
+/**
+ * Used for Hardware Encoding SBC codec configuration.
+ */
+@VintfStability
+parcelable SbcConfiguration {
+ int sampleRateHz;
+ SbcChannelMode channelMode;
+ byte blockLength;
+ byte numSubbands;
+ SbcAllocMethod allocMethod;
+ byte bitsPerSample;
+ /*
+ * range from 2 to 250.
+ */
+ int minBitpool;
+ /*
+ * range from 2 to 250.
+ */
+ int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
new file mode 100644
index 0000000..b588869
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SessionType {
+ UNKNOWN,
+ /**
+ * A2DP legacy that AVDTP media is encoded by Bluetooth Stack
+ */
+ A2DP_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * The encoding of AVDTP media is done by HW and there is control only
+ */
+ A2DP_HARDWARE_OFFLOAD_DATAPATH,
+ /**
+ * Used when encoded by Bluetooth Stack and streaming to Hearing Aid
+ */
+ HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * Used when encoded by Bluetooth Stack and streaming to LE Audio device
+ */
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * Used when decoded by Bluetooth Stack and streaming to audio framework
+ */
+ LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ /**
+ * Encoding is done by HW an there is control only
+ */
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ /**
+ * Decoding is done by HW an there is control only
+ */
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
new file mode 100644
index 0000000..7be2c5b
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
+
+@VintfStability
+parcelable UnicastConfiguration {
+ @VintfStability
+ parcelable UnicastStreamMap {
+ /*
+ * The connection handle used for a unicast or a broadcast group.
+ * Range: 0x0000 to 0xEFFF
+ */
+ char streamHandle;
+ /*
+ * Audio channel allocation is a bit field, each enabled bit means that given audio
+ * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+ * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
+ * Audio Location assigned number.
+ */
+ int audioChannelAllocation;
+ }
+ UnicastStreamMap[] streamMap;
+ int peerDelay;
+ LeAudioCodecConfiguration leAudioCodecConfig;
+}
diff --git a/camera/device/3.8/Android.bp b/camera/device/3.8/Android.bp
new file mode 100644
index 0000000..2a1f215
--- /dev/null
+++ b/camera/device/3.8/Android.bp
@@ -0,0 +1,38 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+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"],
+}
+
+
+hidl_interface {
+ name: "android.hardware.camera.device@3.8",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "ICameraDevice.hal",
+ "ICameraDeviceCallback.hal",
+ ],
+ interfaces: [
+ "android.hardware.camera.common@1.0",
+ "android.hardware.camera.device@3.2",
+ "android.hardware.camera.device@3.3",
+ "android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.5",
+ "android.hardware.camera.device@3.6",
+ "android.hardware.camera.device@3.7",
+ "android.hardware.camera.metadata@3.2",
+ "android.hardware.camera.metadata@3.3",
+ "android.hardware.camera.metadata@3.4",
+ "android.hardware.camera.metadata@3.5",
+ "android.hardware.camera.metadata@3.6",
+ "android.hardware.graphics.common@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal
new file mode 100644
index 0000000..448f176
--- /dev/null
+++ b/camera/device/3.8/ICameraDevice.hal
@@ -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.camera.device@3.8;
+
+import @3.7::ICameraDevice;
+
+/**
+ * Camera device interface
+ *
+ * Supports the android.hardware.Camera API, and the android.hardware.camera2
+ * API at LIMITED or better hardware level.
+ *
+ * ICameraDevice.open() must return @3.2::ICameraDeviceSession,
+ * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or
+ * @3.7::ICameraDeviceSession.
+ */
+interface ICameraDevice extends @3.7::ICameraDevice {
+};
diff --git a/camera/device/3.8/ICameraDeviceCallback.hal b/camera/device/3.8/ICameraDeviceCallback.hal
new file mode 100644
index 0000000..de0775d
--- /dev/null
+++ b/camera/device/3.8/ICameraDeviceCallback.hal
@@ -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.camera.device@3.8;
+
+import @3.5::ICameraDeviceCallback;
+
+/**
+ * Callback methods for the HAL to call into the framework.
+ */
+interface ICameraDeviceCallback extends @3.5::ICameraDeviceCallback {
+ /**
+ * Identical to @3.5::ICameraDeviceCallback.notify, except that it takes a
+ * list of @3.8::NotifyMsg which contain readout timestamp in addition
+ * to exposure start timestamp for shutter.
+ *
+ * The readout timestamp is used for the framework to re-time the viewfinder
+ * frames targeted for SurfaceView so that preview jitter can be reduced.
+ */
+ notify_3_8(vec<NotifyMsg> msgs);
+};
diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal
new file mode 100644
index 0000000..843d050
--- /dev/null
+++ b/camera/device/3.8/types.hal
@@ -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.
+ */
+
+package android.hardware.camera.device@3.8;
+
+import @3.2::ErrorMsg;
+import @3.2::MsgType;
+import @3.2::ShutterMsg;
+
+/**
+ * ShutterMsg:
+ *
+ * Message contents for MsgType::SHUTTER
+ *
+ * This version extends the @3.2 ShutterMsg with the readout timestamp.
+ */
+struct ShutterMsg {
+ /**
+ * The definition of ShutterMsg from prior version.
+ */
+ @3.2::ShutterMsg v3_2;
+
+ /**
+ * Timestamp for the capture readout. This must be in the same time domain
+ * as v3_2.timestamp, and for a rolling shutter sensor, the value must be
+ * v3_2.timestamp + exposureTime + t_crop_top where t_crop_top is the exposure time
+ * skew of the cropped lines on the top.
+ */
+ uint64_t readoutTimestamp;
+};
+
+/**
+ * NotifyMsg:
+ *
+ * The message structure sent to ICameraDevice3Callback::notify()
+ *
+ * This version extends the @3.2 NotifyMsg with the @3.8 version of ShutterMsg.
+ */
+struct NotifyMsg {
+ /**
+ * The message type.
+ */
+ @3.2::MsgType type;
+
+ union Message {
+ /**
+ * Error message contents. Valid if type is MsgType::ERROR
+ */
+ @3.2::ErrorMsg error;
+
+ /**
+ * Shutter message contents. Valid if type is MsgType::SHUTTER
+ */
+ ShutterMsg shutter;
+ } msg;
+};
diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal
index b20af18..11360da 100644
--- a/camera/metadata/3.8/types.hal
+++ b/camera/metadata/3.8/types.hal
@@ -47,7 +47,7 @@
/** android.flash.info.strengthDefaultLevel [static, int32, public]
*
* <p>Default flashlight brightness level to be set via
- * {android.hardware.camera2.CameraManager#setTorchStrengthLevel}.</p>
+ * {android.hardware.camera2.CameraManager#turnOnTorchWithStrengthLevel}.</p>
*/
ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 64a51f6..4fc7437 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -65,10 +65,10 @@
} // anonymous namespace
-ExternalCameraProviderImpl_2_4::ExternalCameraProviderImpl_2_4() :
- mCfg(ExternalCameraConfig::loadFromCfg()),
- mHotPlugThread(this) {
- mHotPlugThread.run("ExtCamHotPlug", PRIORITY_BACKGROUND);
+ExternalCameraProviderImpl_2_4::ExternalCameraProviderImpl_2_4()
+ : mCfg(ExternalCameraConfig::loadFromCfg()) {
+ mHotPlugThread = sp<HotplugThread>::make(this);
+ mHotPlugThread->run("ExtCamHotPlug", PRIORITY_BACKGROUND);
mPreferredHal3MinorVersion =
property_get_int32("ro.vendor.camera.external.hal3TrebleMinorVersion", 4);
@@ -88,7 +88,7 @@
}
ExternalCameraProviderImpl_2_4::~ExternalCameraProviderImpl_2_4() {
- mHotPlugThread.requestExit();
+ mHotPlugThread->requestExit();
}
diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
index 8c79f68..f1d8003 100644
--- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
@@ -102,7 +102,7 @@
sp<ICameraProviderCallback> mCallbacks = nullptr;
std::unordered_map<std::string, CameraDeviceStatus> mCameraStatusMap; // camera id -> status
const ExternalCameraConfig mCfg;
- HotplugThread mHotPlugThread;
+ sp<HotplugThread> mHotPlugThread;
int mPreferredHal3MinorVersion;
};
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 8886ee1..2c141ee 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -49,6 +49,7 @@
"android.hardware.camera.device@3.5",
"android.hardware.camera.device@3.6",
"android.hardware.camera.device@3.7",
+ "android.hardware.camera.device@3.8",
"android.hardware.camera.metadata@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index d02547c..77974fc 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -43,6 +43,7 @@
#include <android/hardware/camera/device/3.7/ICameraDevice.h>
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
+#include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
#include <android/hardware/camera/metadata/3.4/types.h>
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
@@ -194,6 +195,7 @@
namespace {
// "device@<version>/legacy/<id>"
const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+ const int CAMERA_DEVICE_API_VERSION_3_8 = 0x308;
const int CAMERA_DEVICE_API_VERSION_3_7 = 0x307;
const int CAMERA_DEVICE_API_VERSION_3_6 = 0x306;
const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
@@ -201,6 +203,7 @@
const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+ const char *kHAL3_8 = "3.8";
const char *kHAL3_7 = "3.7";
const char *kHAL3_6 = "3.6";
const char *kHAL3_5 = "3.5";
@@ -238,7 +241,9 @@
return -1;
}
- if (version.compare(kHAL3_7) == 0) {
+ if (version.compare(kHAL3_8) == 0) {
+ return CAMERA_DEVICE_API_VERSION_3_8;
+ } else if (version.compare(kHAL3_7) == 0) {
return CAMERA_DEVICE_API_VERSION_3_7;
} else if (version.compare(kHAL3_6) == 0) {
return CAMERA_DEVICE_API_VERSION_3_6;
@@ -638,7 +643,7 @@
}
};
- struct DeviceCb : public V3_5::ICameraDeviceCallback {
+ struct DeviceCb : public V3_8::ICameraDeviceCallback {
DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
mParent(parent), mDeviceVersion(deviceVersion) {
mStaticMetadata = staticMeta;
@@ -648,6 +653,7 @@
const hidl_vec<V3_4::CaptureResult>& results) override;
Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
+ Return<void> notify_3_8(const hidl_vec<V3_8::NotifyMsg>& msgs) override;
Return<void> requestStreamBuffers(
const hidl_vec<V3_5::BufferRequest>& bufReqs,
@@ -663,6 +669,8 @@
private:
bool processCaptureResultLocked(const CaptureResult& results,
hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata);
+ Return<void> notifyHelper(const hidl_vec<NotifyMsg>& msgs,
+ const std::vector<std::pair<bool, nsecs_t>>& readoutTimestamps);
CameraHidlTest *mParent; // Parent object
int mDeviceVersion;
@@ -956,6 +964,9 @@
// Set by notify() SHUTTER call.
nsecs_t shutterTimestamp;
+ bool shutterReadoutTimestampValid;
+ nsecs_t shutterReadoutTimestamp;
+
bool errorCodeValid;
ErrorCode errorCode;
@@ -1001,6 +1012,8 @@
InFlightRequest() :
shutterTimestamp(0),
+ shutterReadoutTimestampValid(false),
+ shutterReadoutTimestamp(0),
errorCodeValid(false),
errorCode(ErrorCode::ERROR_BUFFER),
usePartialResult(false),
@@ -1018,6 +1031,8 @@
bool partialResults, uint32_t partialCount,
std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
shutterTimestamp(0),
+ shutterReadoutTimestampValid(false),
+ shutterReadoutTimestamp(0),
errorCodeValid(false),
errorCode(ErrorCode::ERROR_BUFFER),
usePartialResult(partialResults),
@@ -1036,6 +1051,8 @@
const std::unordered_set<std::string>& extraPhysicalResult,
std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
shutterTimestamp(0),
+ shutterReadoutTimestampValid(false),
+ shutterReadoutTimestamp(0),
errorCodeValid(false),
errorCode(ErrorCode::ERROR_BUFFER),
usePartialResult(partialResults),
@@ -1462,8 +1479,46 @@
}
}
+Return<void> CameraHidlTest::DeviceCb::notify_3_8(
+ const hidl_vec<V3_8::NotifyMsg>& msgs) {
+ hidl_vec<NotifyMsg> msgs3_2;
+ std::vector<std::pair<bool, nsecs_t>> readoutTimestamps;
+
+ nsecs_t count = msgs.size();
+ msgs3_2.resize(count);
+ readoutTimestamps.resize(count);
+
+ for (size_t i = 0; i < count; i++) {
+ msgs3_2[i].type = msgs[i].type;
+ switch (msgs[i].type) {
+ case MsgType::ERROR:
+ msgs3_2[i].msg.error = msgs[i].msg.error;
+ readoutTimestamps[i] = {false, 0};
+ break;
+ case MsgType::SHUTTER:
+ msgs3_2[i].msg.shutter = msgs[i].msg.shutter.v3_2;
+ readoutTimestamps[i] = {true, msgs[i].msg.shutter.readoutTimestamp};
+ break;
+ }
+ }
+
+ return notifyHelper(msgs3_2, readoutTimestamps);
+}
+
Return<void> CameraHidlTest::DeviceCb::notify(
const hidl_vec<NotifyMsg>& messages) {
+ std::vector<std::pair<bool, nsecs_t>> readoutTimestamps;
+ readoutTimestamps.resize(messages.size());
+ for (size_t i = 0; i < messages.size(); i++) {
+ readoutTimestamps[i] = {false, 0};
+ }
+
+ return notifyHelper(messages, readoutTimestamps);
+}
+
+Return<void> CameraHidlTest::DeviceCb::notifyHelper(
+ const hidl_vec<NotifyMsg>& messages,
+ const std::vector<std::pair<bool, nsecs_t>>& readoutTimestamps) {
std::lock_guard<std::mutex> l(mParent->mLock);
for (size_t i = 0; i < messages.size(); i++) {
@@ -1526,6 +1581,8 @@
}
InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
r->shutterTimestamp = messages[i].msg.shutter.timestamp;
+ r->shutterReadoutTimestampValid = readoutTimestamps[i].first;
+ r->shutterReadoutTimestamp = readoutTimestamps[i].second;
}
break;
default:
@@ -1940,6 +1997,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -1984,6 +2042,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -2725,6 +2784,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -2812,6 +2872,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -2893,6 +2954,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -3021,6 +3083,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -3088,6 +3151,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -3124,7 +3188,7 @@
castSession(session, deviceVersion, &sessionV3_3,
&sessionV3_4, &sessionV3_5, &sessionV3_6,
&sessionV3_7);
- if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) {
+ if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) {
ASSERT_TRUE(sessionV3_7.get() != nullptr);
} else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
ASSERT_TRUE(sessionV3_6.get() != nullptr);
@@ -3190,6 +3254,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -4730,6 +4795,28 @@
ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
+ // For camera device 3.8 or newer, shutterReadoutTimestamp must be
+ // available, and it must be >= shutterTimestamp + exposureTime, and
+ // < shutterTimestamp + exposureTime + rollingShutterSkew / 2.
+ if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) {
+ ASSERT_TRUE(inflightReq.shutterReadoutTimestampValid);
+ ASSERT_FALSE(inflightReq.collectedResult.isEmpty());
+ if (inflightReq.collectedResult.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
+ camera_metadata_entry_t exposureTimeResult = inflightReq.collectedResult.find(
+ ANDROID_SENSOR_EXPOSURE_TIME);
+ nsecs_t exposureToReadout =
+ inflightReq.shutterReadoutTimestamp - inflightReq.shutterTimestamp;
+ ASSERT_GE(exposureToReadout, exposureTimeResult.data.i64[0]);
+ if (inflightReq.collectedResult.exists(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW)) {
+ camera_metadata_entry_t rollingShutterSkew =
+ inflightReq.collectedResult.find(
+ ANDROID_SENSOR_ROLLING_SHUTTER_SKEW);
+ ASSERT_LT(exposureToReadout, exposureTimeResult.data.i64[0] +
+ rollingShutterSkew.data.i64[0] / 2);
+ }
+ }
+ }
+
request.frameNumber++;
// Empty settings should be supported after the first call
// for repeating requests.
@@ -6222,6 +6309,7 @@
std::string cameraId;
int deviceVersion = getCameraDeviceVersionAndId(name, mProviderType, &cameraId);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
@@ -7651,6 +7739,7 @@
ASSERT_NE(nullptr, device3_7);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7: {
auto castResult = device::V3_7::ICameraDevice::castFrom(device);
ASSERT_TRUE(castResult.isOk());
@@ -7707,6 +7796,7 @@
ASSERT_NE(nullptr, session3_7);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_8:
case CAMERA_DEVICE_API_VERSION_3_7: {
auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session);
ASSERT_TRUE(castResult.isOk());
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index a59be21..193fd2b 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -81,5 +81,6 @@
],
kernel_configs: [
"kernel_config_current_5.10",
+ "kernel_config_current_5.15",
],
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5d92304..a781b35 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -147,6 +147,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.bluetooth.audio</name>
+ <interface>
+ <name>IBluetoothAudioProviderFactory</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.boot</name>
<version>1.2</version>
@@ -222,9 +229,8 @@
<regex-instance>.*</regex-instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="aidl" optional="true">
<name>android.hardware.dumpstate</name>
- <version>1.1</version>
<interface>
<name>IDumpstateDevice</name>
<instance>default</instance>
@@ -429,7 +435,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.neuralnetworks</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>IDevice</name>
<regex-instance>.*</regex-instance>
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
new file mode 100644
index 0000000..e7dcbc7
--- /dev/null
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.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.contexthub;
+@VintfStability
+parcelable HostEndpointInfo {
+ char hostEndpointId;
+ android.hardware.contexthub.HostEndpointInfo.Type type;
+ @nullable String packageName;
+ @nullable String attributionTag;
+ @Backing(type="int") @VintfStability
+ enum Type {
+ TYPE_FRAMEWORK = 1,
+ TYPE_APP = 2,
+ }
+}
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 cb31c84..facce4b 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
@@ -43,4 +43,6 @@
boolean queryNanoapps(in int contextHubId);
boolean registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb);
boolean sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
+ void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo);
+ void onHostEndpointDisconnected(char hostEndpointId);
}
diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
new file mode 100644
index 0000000..40a231d
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.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.
+ */
+
+package android.hardware.contexthub;
+
+/**
+ * Stores metadata regarding a host endpoint that may communicate with the Context Hub.
+ */
+@VintfStability
+parcelable HostEndpointInfo {
+ /** The ID of the host endpoint asscociated with this host. */
+ char hostEndpointId;
+
+ /** The type of endpoint. */
+ Type type;
+
+ /** The (optional) package name of the host. */
+ @nullable String packageName;
+
+ /** The (optional) attribution tag associated with this host. */
+ @nullable String attributionTag;
+
+ @VintfStability
+ @Backing(type="int")
+ enum Type {
+ /**
+ This endpoint is from the Android framework, where packageName and attributionTag may be
+ empty.
+ */
+ TYPE_FRAMEWORK = 1,
+
+ /** This endpoint is an Android app. */
+ TYPE_APP = 2,
+ }
+}
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index e820cbf..33d241a 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -18,6 +18,7 @@
import android.hardware.contexthub.ContextHubInfo;
import android.hardware.contexthub.ContextHubMessage;
+import android.hardware.contexthub.HostEndpointInfo;
import android.hardware.contexthub.IContextHubCallback;
import android.hardware.contexthub.NanoappBinary;
import android.hardware.contexthub.Setting;
@@ -151,4 +152,29 @@
* @return true on success
*/
boolean sendMessageToHub(in int contextHubId, in ContextHubMessage message);
+
+ /**
+ * Invoked when a host endpoint has connected with the ContextHubService.
+ *
+ * The host associated with this invocation may initiate a communication channel with
+ * the Context Hub using sendMessageToHub.
+ *
+ * @param hostEndpointInfo Metadata associated with this host endpoint.
+ */
+ void onHostEndpointConnected(in HostEndpointInfo hostEndpointInfo);
+
+ /**
+ * Invoked when a host endpoint has disconnected from the framework. This could be as a result
+ * of an explicit connection closure, or unexpected restarts.
+ *
+ * Note that hostEndpointId is the same as the value in HostEndpointInfo. When this function is
+ * called, the HAL is expected to clean up any resources attached to the messaging channel
+ * associated with this host endpoint ID.
+ *
+ * @param hostEndPointId The ID of the host that has disconnected.
+ *
+ * @return Status::ok on success
+ * EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host.
+ */
+ void onHostEndpointDisconnected(char hostEndpointId);
}
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 1fbccc5..6da690d 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -111,6 +111,21 @@
return ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
+ mConnectedHostEndpoints.insert(in_info.hostEndpointId);
+
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
+ if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
+ mConnectedHostEndpoints.erase(in_hostEndpointId);
+ return ndk::ScopedAStatus::ok();
+ } else {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
+ }
+}
+
} // namespace contexthub
} // namespace hardware
} // namespace android
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index 0dbb61b..dd739e6 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -18,6 +18,8 @@
#include <aidl/android/hardware/contexthub/BnContextHub.h>
+#include <unordered_set>
+
namespace aidl {
namespace android {
namespace hardware {
@@ -41,10 +43,15 @@
::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId,
const ContextHubMessage& in_message,
bool* _aidl_return) override;
+ ::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override;
+
+ ::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
private:
static constexpr uint32_t kMockHubId = 0;
std::shared_ptr<IContextHubCallback> mCallback;
+
+ std::unordered_set<char16_t> mConnectedHostEndpoints;
};
} // namespace contexthub
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index 4b0d60f..1b2dc29 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -36,6 +36,7 @@
using ::android::hardware::contexthub::AsyncEventType;
using ::android::hardware::contexthub::ContextHubInfo;
using ::android::hardware::contexthub::ContextHubMessage;
+using ::android::hardware::contexthub::HostEndpointInfo;
using ::android::hardware::contexthub::IContextHub;
using ::android::hardware::contexthub::IContextHubCallbackDefault;
using ::android::hardware::contexthub::NanoappBinary;
@@ -330,6 +331,22 @@
return tuples;
}
+TEST_P(ContextHubAidl, TestHostConnection) {
+ constexpr char16_t kHostEndpointId = 1;
+ HostEndpointInfo hostEndpointInfo;
+ hostEndpointInfo.hostEndpointId = kHostEndpointId;
+
+ ASSERT_TRUE(contextHub->onHostEndpointConnected(hostEndpointInfo).isOk());
+ ASSERT_TRUE(contextHub->onHostEndpointDisconnected(kHostEndpointId).isOk());
+}
+
+TEST_P(ContextHubAidl, TestInvalidHostConnection) {
+ constexpr char16_t kHostEndpointId = 1;
+
+ Status status = contextHub->onHostEndpointDisconnected(kHostEndpointId);
+ ASSERT_EQ(status.exceptionCode(), android::binder::Status::EX_ILLEGAL_ARGUMENT);
+}
+
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/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
new file mode 100644
index 0000000..e18eade
--- /dev/null
+++ b/dumpstate/aidl/Android.bp
@@ -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 {
+ // 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.dumpstate",
+ vendor_available: true,
+ srcs: ["android/hardware/dumpstate/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ separate_platform_variant: false,
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/dumpstate/aidl/aidl_api/android.hardware.dumpstate/current/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/aidl_api/android.hardware.dumpstate/current/android/hardware/dumpstate/IDumpstateDevice.aidl
new file mode 100644
index 0000000..4d78a4c
--- /dev/null
+++ b/dumpstate/aidl/aidl_api/android.hardware.dumpstate/current/android/hardware/dumpstate/IDumpstateDevice.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.dumpstate;
+@VintfStability
+interface IDumpstateDevice {
+ void dumpstateBoard(in ParcelFileDescriptor[] fd, in android.hardware.dumpstate.IDumpstateDevice.DumpstateMode mode, in long timeoutMillis);
+ boolean getVerboseLoggingEnabled();
+ void setVerboseLoggingEnabled(in boolean enable);
+ const int ERROR_UNSUPPORTED_MODE = 1;
+ const int ERROR_DEVICE_LOGGING_NOT_ENABLED = 2;
+ @Backing(type="int") @VintfStability
+ enum DumpstateMode {
+ FULL = 0,
+ INTERACTIVE = 1,
+ REMOTE = 2,
+ WEAR = 3,
+ CONNECTIVITY = 4,
+ WIFI = 5,
+ DEFAULT = 6,
+ PROTO = 7,
+ }
+}
diff --git a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
new file mode 100644
index 0000000..3b42546
--- /dev/null
+++ b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
@@ -0,0 +1,137 @@
+/*
+ * 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.dumpstate;
+
+import android.os.ParcelFileDescriptor;
+
+@VintfStability
+interface IDumpstateDevice {
+ /**
+ * Constants that define the type of bug report being taken to restrict content appropriately.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum DumpstateMode {
+ /**
+ * Takes a bug report without user interference.
+ */
+ FULL = 0,
+ /**
+ * Interactive bug report, i.e. triggered by the user.
+ */
+ INTERACTIVE = 1,
+ /**
+ * Remote bug report triggered by DevicePolicyManager, for example.
+ */
+ REMOTE = 2,
+ /**
+ * Bug report triggered on a wear device.
+ */
+ WEAR = 3,
+ /**
+ * Bug report limited to only connectivity info (cellular, wifi, and networking). Sometimes
+ * called "telephony" in legacy contexts.
+ *
+ * All reported information MUST directly relate to connectivity debugging or customer
+ * support and MUST NOT contain unrelated private information. This information MUST NOT
+ * identify user-installed packages (UIDs are OK, package names are not), and MUST NOT
+ * contain logs of user application traffic.
+ */
+ CONNECTIVITY = 4,
+ /**
+ * Bug report limited to only wifi info.
+ */
+ WIFI = 5,
+ /**
+ * Default mode, This mode MUST be supported if the
+ * dumpstate HAL is implemented.
+ */
+ DEFAULT = 6,
+ /**
+ * Takes a report in protobuf.
+ *
+ * The content, if implemented, must be a binary protobuf message written to the first file
+ * descriptor of the native handle. The protobuf schema shall be defined by the vendor.
+ */
+ PROTO = 7,
+ }
+
+ /**
+ * Returned for cases where the device doesn't support the given DumpstateMode (e.g. a phone
+ * trying to use DumpstateMode::WEAR).
+ */
+ const int ERROR_UNSUPPORTED_MODE = 1;
+ /**
+ * Returned when device logging is not enabled.
+ */
+ const int ERROR_DEVICE_LOGGING_NOT_ENABLED = 2;
+
+ /**
+ * Dump device-specific state into the given file descriptors.
+ *
+ * One file descriptor must be passed to this method but two may be passed:
+ * the first descriptor must be used to dump device-specific state in text
+ * format, the second descriptor is optional and may be used to dump
+ * device-specific state in binary format.
+ *
+ * DumpstateMode can be used to limit the information that is output.
+ * For an example of when this is relevant, consider a bug report being generated with
+ * DumpstateMode::CONNECTIVITY - there is no reason to include camera or USB logs in this type
+ * of report.
+ *
+ * When verbose logging is disabled, getVerboseLoggingEnabled returns false, and this
+ * API is called, it may still output essential information but must not include
+ * information that identifies the user.
+ *
+ * @param fd array of file descriptors, with one or two valid file descriptors. The first FD is
+ * for text output, the second (if present) is for binary output.
+ * @param mode A mode value to restrict dumped content.
+ * @param timeoutMillis An approximate "budget" for how much time this call has been allotted.
+ * If execution runs longer than this, the IDumpstateDevice service may be killed and only
+ * partial information will be included in the report.
+ * @return If error, return service specific error with code
+ * ERROR_UNSUPPORTED_MODE or ERROR_DEVICE_LOGGING_NOT_ENABLED
+ */
+ void dumpstateBoard(in ParcelFileDescriptor[] fd, in DumpstateMode mode, in long timeoutMillis);
+
+ /**
+ * Queries the current state of verbose device logging. Primarily for UI and informative
+ * purposes.
+ *
+ * Even if verbose logging has been disabled, dumpstateBoard may still be called by the
+ * dumpstate routine, and essential information that does not identify the user may be included.
+ *
+ * @return Whether or not verbose vendor logging is currently enabled.
+ */
+ boolean getVerboseLoggingEnabled();
+
+ /**
+ * Turns verbose device vendor logging on or off.
+ *
+ * The setting should be persistent across reboots. Underlying implementations may need to start
+ * vendor logging daemons, set system properties, or change logging masks, for example. Given
+ * that many vendor logs contain significant amounts of private information and may come with
+ * memory/storage/battery impacts, calling this method on a user build should only be done after
+ * user consent has been obtained, e.g. from a toggle in developer settings.
+ *
+ * Even if verbose logging has been disabled, dumpstateBoard may still be called by the
+ * dumpstate routine, and essential information that does not identify the user may be included.
+ *
+ * @param enable Whether to enable or disable verbose vendor logging.
+ */
+ void setVerboseLoggingEnabled(in boolean enable);
+}
diff --git a/dumpstate/aidl/default/Android.bp b/dumpstate/aidl/default/Android.bp
new file mode 100644
index 0000000..45fdc17
--- /dev/null
+++ b/dumpstate/aidl/default/Android.bp
@@ -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.
+
+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.dumpstate-service.example",
+ relative_install_path: "hw",
+ init_rc: ["dumpstate-default.rc"],
+ vintf_fragments: ["dumpstate-default.xml"],
+ vendor: true,
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "libdumpstateutil",
+ "liblog",
+ "libutils",
+ "android.hardware.dumpstate-V1-ndk",
+ ],
+ srcs: [
+ "main.cpp",
+ "Dumpstate.cpp",
+ ],
+ cflags: [
+ "-DLOG_TAG=\"android.hardware.dumpstate-service.example\"",
+ ],
+}
diff --git a/dumpstate/aidl/default/Dumpstate.cpp b/dumpstate/aidl/default/Dumpstate.cpp
new file mode 100644
index 0000000..a0730fb
--- /dev/null
+++ b/dumpstate/aidl/default/Dumpstate.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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 <android-base/properties.h>
+#include <log/log.h>
+#include "DumpstateUtil.h"
+
+#include "Dumpstate.h"
+
+using android::os::dumpstate::DumpFileToFd;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace dumpstate {
+
+const char kVerboseLoggingProperty[] = "persist.dumpstate.verbose_logging.enabled";
+
+ndk::ScopedAStatus Dumpstate::dumpstateBoard(const std::vector<::ndk::ScopedFileDescriptor>& in_fds,
+ IDumpstateDevice::DumpstateMode in_mode,
+ int64_t in_timeoutMillis) {
+ (void)in_timeoutMillis;
+
+ if (in_fds.size() < 1) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "No file descriptor");
+ }
+
+ int fd = in_fds[0].get();
+ if (fd < 0) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid file descriptor");
+ }
+
+ switch (in_mode) {
+ case IDumpstateDevice::DumpstateMode::FULL:
+ return dumpstateBoardImpl(fd, true);
+
+ case IDumpstateDevice::DumpstateMode::DEFAULT:
+ return dumpstateBoardImpl(fd, false);
+
+ case IDumpstateDevice::DumpstateMode::INTERACTIVE:
+ case IDumpstateDevice::DumpstateMode::REMOTE:
+ case IDumpstateDevice::DumpstateMode::WEAR:
+ case IDumpstateDevice::DumpstateMode::CONNECTIVITY:
+ case IDumpstateDevice::DumpstateMode::WIFI:
+ case IDumpstateDevice::DumpstateMode::PROTO:
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(ERROR_UNSUPPORTED_MODE,
+ "Unsupported mode");
+
+ default:
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid mode");
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Dumpstate::getVerboseLoggingEnabled(bool* _aidl_return) {
+ *_aidl_return = getVerboseLoggingEnabledImpl();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Dumpstate::setVerboseLoggingEnabled(bool in_enable) {
+ ::android::base::SetProperty(kVerboseLoggingProperty, in_enable ? "true" : "false");
+ return ndk::ScopedAStatus::ok();
+}
+
+bool Dumpstate::getVerboseLoggingEnabledImpl() {
+ return ::android::base::GetBoolProperty(kVerboseLoggingProperty, false);
+}
+
+ndk::ScopedAStatus Dumpstate::dumpstateBoardImpl(const int fd, const bool full) {
+ ALOGD("DumpstateDevice::dumpstateBoard() FD: %d\n", fd);
+
+ dprintf(fd, "verbose logging: %s\n", getVerboseLoggingEnabledImpl() ? "enabled" : "disabled");
+ dprintf(fd, "[%s] %s\n", (full ? "full" : "default"), "Hello, world!");
+
+ // Shows an example on how to use the libdumpstateutil API.
+ DumpFileToFd(fd, "cmdline", "/proc/self/cmdline");
+
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace dumpstate
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/dumpstate/aidl/default/Dumpstate.h b/dumpstate/aidl/default/Dumpstate.h
new file mode 100644
index 0000000..0629831
--- /dev/null
+++ b/dumpstate/aidl/default/Dumpstate.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/dumpstate/BnDumpstateDevice.h>
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android/binder_status.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace dumpstate {
+
+class Dumpstate : public BnDumpstateDevice {
+ private:
+ bool getVerboseLoggingEnabledImpl();
+ ::ndk::ScopedAStatus dumpstateBoardImpl(const int fd, const bool full);
+
+ public:
+ ::ndk::ScopedAStatus dumpstateBoard(const std::vector<::ndk::ScopedFileDescriptor>& in_fds,
+ IDumpstateDevice::DumpstateMode in_mode,
+ int64_t in_timeoutMillis) override;
+
+ ::ndk::ScopedAStatus getVerboseLoggingEnabled(bool* _aidl_return) override;
+
+ ::ndk::ScopedAStatus setVerboseLoggingEnabled(bool in_enable) override;
+};
+
+} // namespace dumpstate
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/dumpstate/aidl/default/dumpstate-default.rc b/dumpstate/aidl/default/dumpstate-default.rc
new file mode 100644
index 0000000..4d011dd
--- /dev/null
+++ b/dumpstate/aidl/default/dumpstate-default.rc
@@ -0,0 +1,7 @@
+service vendor.dumpstate-default /vendor/bin/hw/android.hardware.dumpstate-service.example
+ class hal
+ user nobody
+ group nobody
+ interface aidl android.hardware.dumpstate.IDumpstateDevice/default
+ oneshot
+ disabled
diff --git a/dumpstate/aidl/default/dumpstate-default.xml b/dumpstate/aidl/default/dumpstate-default.xml
new file mode 100644
index 0000000..877aeed
--- /dev/null
+++ b/dumpstate/aidl/default/dumpstate-default.xml
@@ -0,0 +1,8 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.dumpstate</name>
+ <version>1</version>
+ <fqname>IDumpstateDevice/default</fqname>
+ </hal>
+</manifest>
+
diff --git a/dumpstate/aidl/default/main.cpp b/dumpstate/aidl/default/main.cpp
new file mode 100644
index 0000000..2451752
--- /dev/null
+++ b/dumpstate/aidl/default/main.cpp
@@ -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.
+ */
+
+#include "Dumpstate.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::dumpstate::Dumpstate;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr<Dumpstate> dumpstate = ndk::SharedRefBase::make<Dumpstate>();
+
+ const std::string instance = std::string() + Dumpstate::descriptor + "/default";
+ binder_status_t status =
+ AServiceManager_registerLazyService(dumpstate->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // Unreachable
+}
diff --git a/dumpstate/aidl/vts/functional/Android.bp b/dumpstate/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..5e516cf
--- /dev/null
+++ b/dumpstate/aidl/vts/functional/Android.bp
@@ -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 {
+ // 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: "VtsHalDumpstateTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalDumpstateTargetTest.cpp"],
+ shared_libs: [
+ "libbinder_ndk",
+ "libvintf",
+ ],
+ static_libs: [
+ "android.hardware.dumpstate-V1-ndk",
+ ],
+ test_suites: [
+ "vts",
+ ],
+}
diff --git a/dumpstate/aidl/vts/functional/VtsHalDumpstateTargetTest.cpp b/dumpstate/aidl/vts/functional/VtsHalDumpstateTargetTest.cpp
new file mode 100644
index 0000000..442b0b0
--- /dev/null
+++ b/dumpstate/aidl/vts/functional/VtsHalDumpstateTargetTest.cpp
@@ -0,0 +1,295 @@
+/*
+ * 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 <fcntl.h>
+#include <unistd.h>
+
+#include <functional>
+#include <tuple>
+#include <vector>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::dumpstate::IDumpstateDevice;
+
+// Base class common to all dumpstate HAL AIDL tests.
+template <typename T>
+class DumpstateAidlTestBase : public ::testing::TestWithParam<T> {
+ protected:
+ bool CheckStatus(const ndk::ScopedAStatus& status, const binder_exception_t expected_ex_code,
+ const int32_t expected_service_specific) {
+ binder_exception_t ex_code = status.getExceptionCode();
+ if (ex_code != expected_ex_code) {
+ return false;
+ }
+ if (ex_code == EX_SERVICE_SPECIFIC) {
+ int32_t service_specific = status.getServiceSpecificError();
+ if (service_specific != expected_service_specific) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public:
+ virtual void SetUp() override { GetService(); }
+
+ virtual std::string GetInstanceName() = 0;
+
+ void GetService() {
+ const std::string instance_name = GetInstanceName();
+
+ ASSERT_TRUE(AServiceManager_isDeclared(instance_name.c_str()));
+ auto dumpstateBinder =
+ ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str()));
+ dumpstate = IDumpstateDevice::fromBinder(dumpstateBinder);
+ ASSERT_NE(dumpstate, nullptr) << "Could not get AIDL instance " << instance_name;
+ }
+
+ void ToggleVerboseLogging(bool enable) {
+ ndk::ScopedAStatus status;
+ bool logging_enabled = false;
+
+ status = dumpstate->setVerboseLoggingEnabled(enable);
+ ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.getDescription();
+
+ status = dumpstate->getVerboseLoggingEnabled(&logging_enabled);
+ ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.getDescription();
+ ASSERT_EQ(logging_enabled, enable)
+ << "Verbose logging should now be " << (enable ? "enabled" : "disabled");
+ }
+
+ void EnableVerboseLogging() { ToggleVerboseLogging(true); }
+
+ void DisableVerboseLogging() { ToggleVerboseLogging(false); }
+
+ std::shared_ptr<IDumpstateDevice> dumpstate;
+};
+
+// Tests that don't need to iterate every single DumpstateMode value for dumpstateBoard_1_1.
+class DumpstateAidlGeneralTest : public DumpstateAidlTestBase<std::string> {
+ protected:
+ virtual std::string GetInstanceName() override { return GetParam(); }
+};
+
+// Tests that iterate every single DumpstateMode value for dumpstateBoard_1_1.
+class DumpstateAidlPerModeTest
+ : public DumpstateAidlTestBase<std::tuple<std::string, IDumpstateDevice::DumpstateMode>> {
+ protected:
+ virtual std::string GetInstanceName() override { return std::get<0>(GetParam()); }
+
+ IDumpstateDevice::DumpstateMode GetMode() { return std::get<1>(GetParam()); }
+
+ // Will only execute additional_assertions when status == expected.
+ void AssertStatusForMode(const ::ndk::ScopedAStatus& status,
+ binder_exception_t expected_ex_code, int32_t expected_service_specific,
+ std::function<void()> additional_assertions = nullptr) {
+ if (GetMode() == IDumpstateDevice::DumpstateMode::DEFAULT) {
+ ASSERT_TRUE(CheckStatus(status, expected_ex_code, expected_ex_code));
+ } else {
+ // The rest of the modes are optional to support, but they MUST return either the
+ // expected value or UNSUPPORTED_MODE.
+ ASSERT_TRUE(CheckStatus(status, expected_ex_code, expected_service_specific) ||
+ CheckStatus(status, EX_SERVICE_SPECIFIC,
+ IDumpstateDevice::ERROR_UNSUPPORTED_MODE));
+ }
+ if (CheckStatus(status, expected_ex_code, expected_service_specific) &&
+ additional_assertions != nullptr) {
+ additional_assertions();
+ }
+ }
+};
+
+constexpr uint64_t kDefaultTimeoutMillis = 30 * 1000; // 30 seconds
+
+// Negative test: make sure dumpstateBoard() doesn't crash when passed a empty file descriptor
+// array.
+TEST_P(DumpstateAidlPerModeTest, TestNullHandle) {
+ EnableVerboseLogging();
+
+ std::vector<::ndk::ScopedFileDescriptor> dumpstateFds; // empty file descriptor vector
+
+ auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+ AssertStatusForMode(status, EX_ILLEGAL_ARGUMENT, 0);
+}
+
+// Positive test: make sure dumpstateBoard() writes something to the FD.
+TEST_P(DumpstateAidlPerModeTest, TestOk) {
+ EnableVerboseLogging();
+
+ // Index 0 corresponds to the read end of the pipe; 1 to the write end.
+ int fds[2];
+ ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+ std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+ dumpstateFds.emplace_back(fds[1]);
+
+ auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+
+ AssertStatusForMode(status, EX_NONE, 0, [&fds]() {
+ // Check that at least one byte was written.
+ char buff;
+ ASSERT_EQ(1, read(fds[0], &buff, 1)) << "Dumped nothing";
+ });
+
+ close(fds[1]);
+ close(fds[0]);
+}
+
+// Positive test: make sure dumpstateBoard() doesn't crash with two FDs.
+TEST_P(DumpstateAidlPerModeTest, TestHandleWithTwoFds) {
+ EnableVerboseLogging();
+
+ int fds1[2];
+ int fds2[2];
+ ASSERT_EQ(0, pipe2(fds1, O_NONBLOCK)) << errno;
+ ASSERT_EQ(0, pipe2(fds2, O_NONBLOCK)) << errno;
+
+ std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+ dumpstateFds.emplace_back(fds1[1]);
+ dumpstateFds.emplace_back(fds2[1]);
+
+ auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+
+ AssertStatusForMode(status, EX_NONE, 0, [&fds1, &fds2]() {
+ // Check that at least one byte was written to one of the FDs.
+ char buff;
+ size_t read1 = read(fds1[0], &buff, 1);
+ size_t read2 = read(fds2[0], &buff, 1);
+ // Sometimes read returns -1, so we can't just add them together and expect >= 1.
+ ASSERT_TRUE(read1 == 1 || read2 == 1) << "Dumped nothing";
+ });
+
+ close(fds1[1]);
+ close(fds1[0]);
+ close(fds2[1]);
+ close(fds2[0]);
+}
+
+// Make sure dumpstateBoard actually validates its arguments.
+TEST_P(DumpstateAidlGeneralTest, TestInvalidModeArgument_Negative) {
+ EnableVerboseLogging();
+
+ int fds[2];
+ ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+ std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+ dumpstateFds.emplace_back(fds[1]);
+
+ auto status = dumpstate->dumpstateBoard(dumpstateFds,
+ static_cast<IDumpstateDevice::DumpstateMode>(-100),
+ kDefaultTimeoutMillis);
+ ASSERT_TRUE(CheckStatus(status, EX_ILLEGAL_ARGUMENT, 0));
+
+ close(fds[1]);
+ close(fds[0]);
+}
+
+TEST_P(DumpstateAidlGeneralTest, TestInvalidModeArgument_Undefined) {
+ EnableVerboseLogging();
+
+ int fds[2];
+ ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+ std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+ dumpstateFds.emplace_back(fds[1]);
+
+ auto status = dumpstate->dumpstateBoard(dumpstateFds,
+ static_cast<IDumpstateDevice::DumpstateMode>(9001),
+ kDefaultTimeoutMillis);
+ ASSERT_TRUE(CheckStatus(status, EX_ILLEGAL_ARGUMENT, 0));
+
+ close(fds[1]);
+ close(fds[0]);
+}
+
+// Make sure disabling verbose logging behaves correctly. Some info is still allowed to be emitted,
+// but it can't have privacy/storage/battery impacts.
+TEST_P(DumpstateAidlPerModeTest, TestDeviceLoggingDisabled) {
+ DisableVerboseLogging();
+
+ // Index 0 corresponds to the read end of the pipe; 1 to the write end.
+ int fds[2];
+ ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
+
+ std::vector<::ndk::ScopedFileDescriptor> dumpstateFds;
+ dumpstateFds.emplace_back(fds[1]);
+
+ auto status = dumpstate->dumpstateBoard(dumpstateFds, GetMode(), kDefaultTimeoutMillis);
+
+ // We don't include additional assertions here about the file passed in. If verbose logging is
+ // disabled, the OEM may choose to include nothing at all, but it is allowed to include some
+ // essential information based on the mode as long as it isn't private user information.
+ AssertStatusForMode(status, EX_NONE, 0);
+
+ close(fds[1]);
+ close(fds[0]);
+}
+
+// Double-enable is perfectly valid, but the second call shouldn't do anything.
+TEST_P(DumpstateAidlGeneralTest, TestRepeatedEnable) {
+ EnableVerboseLogging();
+ EnableVerboseLogging();
+}
+
+// Double-disable is perfectly valid, but the second call shouldn't do anything.
+TEST_P(DumpstateAidlGeneralTest, TestRepeatedDisable) {
+ DisableVerboseLogging();
+ DisableVerboseLogging();
+}
+
+// Toggling in short order is perfectly valid.
+TEST_P(DumpstateAidlGeneralTest, TestRepeatedToggle) {
+ EnableVerboseLogging();
+ DisableVerboseLogging();
+ EnableVerboseLogging();
+ DisableVerboseLogging();
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DumpstateAidlGeneralTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, DumpstateAidlGeneralTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IDumpstateDevice::descriptor)),
+ android::PrintInstanceNameToString);
+
+// Includes the mode's name as part of the description string.
+static inline std::string PrintInstanceNameToStringWithMode(
+ const testing::TestParamInfo<std::tuple<std::string, IDumpstateDevice::DumpstateMode>>&
+ info) {
+ return android::PrintInstanceNameToString(
+ testing::TestParamInfo(std::get<0>(info.param), info.index)) +
+ "_" + toString(std::get<1>(info.param));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DumpstateAidlPerModeTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstanceAndMode, DumpstateAidlPerModeTest,
+ testing::Combine(
+ testing::ValuesIn(android::getAidlHalInstanceNames(IDumpstateDevice::descriptor)),
+ testing::ValuesIn(ndk::internal::enum_values<IDumpstateDevice::DumpstateMode>)),
+ PrintInstanceNameToStringWithMode);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 52276b4..9bd04a0 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -41,6 +41,8 @@
android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
@nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
+ @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
+ @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
const int ERROR_INVALID_ARGUMENT = 1;
const int ERROR_ALREADY_INIT = 2;
const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl
new file mode 100644
index 0000000..50da5bf
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.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.gnss;
+@VintfStability
+interface IGnssGeofence {
+ void setCallback(in android.hardware.gnss.IGnssGeofenceCallback callback);
+ void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees, in double radiusMeters, in int lastTransition, in int monitorTransitions, in int notificationResponsivenessMs, in int unknownTimerMs);
+ void pauseGeofence(in int geofenceId);
+ void resumeGeofence(in int geofenceId, in int monitorTransitions);
+ void removeGeofence(in int geofenceId);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl
new file mode 100644
index 0000000..26482ea
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssGeofenceCallback {
+ void gnssGeofenceTransitionCb(in int geofenceId, in android.hardware.gnss.GnssLocation location, in int transition, in long timestampMillis);
+ void gnssGeofenceStatusCb(in int availability, in android.hardware.gnss.GnssLocation lastLocation);
+ void gnssGeofenceAddCb(in int geofenceId, in int status);
+ void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+ void gnssGeofencePauseCb(in int geofenceId, in int status);
+ void gnssGeofenceResumeCb(in int geofenceId, in int status);
+ const int ENTERED = 1;
+ const int EXITED = 2;
+ const int UNCERTAIN = 4;
+ const int UNAVAILABLE = 1;
+ const int AVAILABLE = 2;
+ const int OPERATION_SUCCESS = 0;
+ const int ERROR_TOO_MANY_GEOFENCES = -100;
+ const int ERROR_ID_EXISTS = -101;
+ const int ERROR_ID_UNKNOWN = -102;
+ const int ERROR_INVALID_TRANSITION = -103;
+ const int ERROR_GENERIC = -149;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
new file mode 100644
index 0000000..d513c15
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -0,0 +1,68 @@
+/*
+ * 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.gnss;
+@VintfStability
+interface IGnssNavigationMessageCallback {
+ void gnssNavigationMessageCb(in android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage message);
+ @VintfStability
+ parcelable GnssNavigationMessage {
+ int svid;
+ android.hardware.gnss.IGnssNavigationMessageCallback.GnssNavigationMessage.GnssNavigationMessageType type;
+ int status;
+ int messageId;
+ int submessageId;
+ byte[] data;
+ const int STATUS_PARITY_PASSED = 1;
+ const int STATUS_PARITY_REBUILT = 2;
+ const int STATUS_UNKNOWN = 0;
+ @Backing(type="int") @VintfStability
+ enum GnssNavigationMessageType {
+ UNKNOWN = 0,
+ GPS_L1CA = 257,
+ GPS_L2CNAV = 258,
+ GPS_L5CNAV = 259,
+ SBS = 513,
+ GPS_CNAV2 = 260,
+ GLO_L1CA = 769,
+ QZS_L1CA = 1025,
+ BDS_D1 = 1281,
+ BDS_D2 = 1282,
+ BDS_CNAV1 = 1283,
+ BDS_CNAV2 = 1284,
+ GAL_I = 1537,
+ GAL_F = 1538,
+ IRN_L5CA = 1793,
+ }
+ }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
new file mode 100644
index 0000000..196e9b9
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssNavigationMessageInterface.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.gnss;
+@VintfStability
+interface IGnssNavigationMessageInterface {
+ void setCallback(in android.hardware.gnss.IGnssNavigationMessageCallback callback);
+ void close();
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index b12fb82..42cc496 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -19,7 +19,9 @@
import android.hardware.gnss.IGnssBatching;
import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssConfiguration;
+import android.hardware.gnss.IGnssGeofence;
import android.hardware.gnss.IGnssMeasurementInterface;
+import android.hardware.gnss.IGnssNavigationMessageInterface;
import android.hardware.gnss.IGnssPowerIndication;
import android.hardware.gnss.IGnssPsds;
@@ -110,4 +112,18 @@
* @return Handle to the IGnssBatching interface.
*/
@nullable IGnssBatching getExtensionGnssBatching();
+
+ /**
+ * This method returns the IGnssGeofence interface.
+ *
+ * @return Handle to the IGnssGeofence interface.
+ */
+ @nullable IGnssGeofence getExtensionGnssGeofence();
+
+ /**
+ * This method returns the IGnssNavigationMessageInterface.
+ *
+ * @return Handle to the IGnssNavigationMessageInterface.
+ */
+ @nullable IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl b/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl
new file mode 100644
index 0000000..bb4ff93
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssGeofence.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.gnss;
+
+import android.hardware.gnss.IGnssGeofenceCallback;
+
+/** Extended interface for GNSS Geofence support. */
+@VintfStability
+interface IGnssGeofence {
+ /**
+ * Opens the geofence interface and provides the callback routines to the HAL.
+ *
+ * @param callback Handle to the IGnssGeofenceCallback interface.
+ */
+ void setCallback(in IGnssGeofenceCallback callback);
+
+ /**
+ * Add a geofence area. This api currently supports circular geofences.
+ *
+ * @param geofenceId The id for the geofence. If a geofence with this id already exists, an
+ * error value (ERROR_ID_EXISTS) must be returned.
+ * @param latitudeDegrees The latitude(in degrees) for the geofence lastTransition.
+ * @param longitudeDegrees The longitude(in degrees) for the geofence lastTransition.
+ * @param radiusMeters The radius(in meters) for the geofence lastTransition.
+ * @param lastTransition The current state of the geofence. It can be one of the transition
+ * states (ENTERED, EXITED, UNCERTAIN) as defined in IGnssGeofenceCallback. For example, if
+ * the system already knows that the user is inside the geofence, this will be set to ENTERED.
+ * In most cases, it will be UNCERTAIN.
+ * @param monitorTransitions A bitfield of ENTERED, EXITED and UNCERTAIN. It represents which
+ * transitions to monitor.
+ * @param notificationResponsivenessMs - Defines the best-effort description of how soon must
+ * the callback be called when the transition associated with the Geofence is triggered. For
+ * instance, if set to 1000 milliseconds with ENTERED, the callback must be called 1000
+ * milliseconds within entering the geofence. This parameter is defined in milliseconds.
+ * NOTE: This is not to be confused with the rate that the GNSS is polled at. It is acceptable
+ * to dynamically vary the rate of sampling the GNSS for power-saving reasons; thus the rate of
+ * sampling may be faster or slower than this.
+ * @param unknownTimerMs - The time limit in millisecondsafter which the UNCERTAIN transition
+ * must be triggered.
+ */
+ void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees,
+ in double radiusMeters, in int lastTransition, in int monitorTransitions,
+ in int notificationResponsivenessMs, in int unknownTimerMs);
+
+ /**
+ * Pause monitoring a particular geofence.
+ *
+ * @param geofenceId The id for the geofence.
+ */
+ void pauseGeofence(in int geofenceId);
+
+ /**
+ * Resume monitoring a particular geofence.
+ *
+ * @param geofenceId - The id for the geofence.
+ * @param monitorTransitions Specifies which transitions to monitor. It can be a bitwise OR of
+ * ENTERED, EXITED and UNCERTAIN. This supersedes the value associated provided in the
+ * addGeofence call.
+ */
+ void resumeGeofence(in int geofenceId, in int monitorTransitions);
+
+ /**
+ * Remove a geofence area. After the function returns, no notifications must be sent.
+ *
+ * @param geofenceId The id of the geofence.
+ */
+ void removeGeofence(in int geofenceId);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl
new file mode 100644
index 0000000..c176965
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl
@@ -0,0 +1,184 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.GnssLocation;
+
+/**
+ * The callback interface to report GNSS geofence events from the HAL.
+ *
+ * There are 3 states associated with a Geofence: Inside, Outside, Unknown.
+ * There are 3 transitions: ENTERED, EXITED, UNCERTAIN.
+ *
+ * An example state diagram with confidence level: 95% and Unknown time limit
+ * set as 30 secs is shown below. (confidence level and Unknown time limit are
+ * explained latter).
+ * ____________________________
+ * | Unknown (30 secs) |
+ * """"""""""""""""""""""""""""
+ * ^ | | ^
+ * UNCERTAIN| |ENTERED EXITED| |UNCERTAIN
+ * | v v |
+ * ________ EXITED _________
+ * | Inside | -----------> | Outside |
+ * | | <----------- | |
+ * """""""" ENTERED """""""""
+ *
+ * Inside state: We are 95% confident that the user is inside the geofence.
+ * Outside state: We are 95% confident that the user is outside the geofence
+ * Unknown state: Rest of the time.
+ *
+ * The Unknown state is better explained with an example:
+ *
+ * __________
+ * | c|
+ * | ___ | _______
+ * | |a| | | b |
+ * | """ | """""""
+ * | |
+ * """"""""""
+ * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy
+ * circle reported by the GNSS subsystem. Now with regard to "b", the system is
+ * confident that the user is outside. But with regard to "a" is not confident
+ * whether it is inside or outside the geofence. If the accuracy remains the
+ * same for a sufficient period of time, the UNCERTAIN transition must be
+ * triggered with the state set to Unknown. If the accuracy improves later, an
+ * appropriate transition must be triggered. This "sufficient period of time"
+ * is defined by the parameter in the addGeofenceArea API.
+ * In other words, Unknown state can be interpreted as a state in which the
+ * GNSS subsystem isn't confident enough that the user is either inside or
+ * outside the Geofence. It moves to Unknown state only after the expiry of the
+ * timeout.
+ *
+ * The geofence callback needs to be triggered for the ENTERED and EXITED
+ * transitions, when the GNSS system is confident that the user has entered
+ * (Inside state) or exited (Outside state) the Geofence. An implementation
+ * which uses a value of 95% as the confidence is recommended. The callback
+ * must be triggered only for the transitions requested by the
+ * addGeofenceArea method.
+ *
+ * Even though the diagram and explanation talks about states and transitions,
+ * the callee is only interested in the transitions. The states are mentioned
+ * here for illustrative purposes.
+ *
+ * Startup Scenario: When the device boots up, if an application adds geofences,
+ * and then we get an accurate GNSS location fix, it needs to trigger the
+ * appropriate (ENTERED or EXITED) transition for every Geofence it knows about.
+ * By default, all the Geofences will be in the Unknown state.
+ *
+ * When the GNSS system is unavailable, gnssGeofenceStatusCb must be
+ * called to inform the upper layers of the same. Similarly, when it becomes
+ * available the callback must be called. This is a global state while the
+ * UNKNOWN transition described above is per geofence.
+ *
+ * An important aspect to note is that users of this API (framework), will use
+ * other subsystems like wifi, sensors, cell to handle Unknown case and
+ * hopefully provide a definitive state transition to the third party
+ * application. GNSS Geofence will just be a signal indicating what the GNSS
+ * subsystem knows about the Geofence.
+ */
+@VintfStability
+interface IGnssGeofenceCallback {
+ // Geofence transition status
+ const int ENTERED = 1 << 0;
+ const int EXITED = 1 << 1;
+ const int UNCERTAIN = 1 << 2;
+
+ // Geofence availability status
+ const int UNAVAILABLE = 1 << 0;
+ const int AVAILABLE = 1 << 1;
+
+ // Geofence operation status
+ const int OPERATION_SUCCESS = 0;
+ const int ERROR_TOO_MANY_GEOFENCES = -100;
+ const int ERROR_ID_EXISTS = -101;
+ const int ERROR_ID_UNKNOWN = -102;
+ const int ERROR_INVALID_TRANSITION = -103;
+ const int ERROR_GENERIC = -149;
+
+ /**
+ * The callback associated with the geofence transition.
+ *
+ * The callback must only be called when the caller is interested in that particular transition.
+ * For instance, if the caller is interested only in ENTERED transition, then the callback must
+ * not be called with the EXITED transition.
+ *
+ * IMPORTANT: If a transition is triggered resulting in this callback, the GNSS subsystem will
+ * wake up the application processor, if it is in suspend state.
+ *
+ * @param geofenceId The id associated with the addGeofenceArea.
+ * @param location The current GNSS location.
+ * @param transition Can be one of ENTERED, EXITED or UNCERTAIN.
+ * @param timestamp Timestamp (in UTC milliseconds) when the transition was detected.
+ */
+ void gnssGeofenceTransitionCb(in int geofenceId, in GnssLocation location, in int transition,
+ in long timestampMillis);
+
+ /**
+ * The callback associated with the availability of the GNSS system for geofencing monitoring.
+ * If the GNSS system determines that it cannot monitor geofences because of lack of reliability
+ * or unavailability of the GNSS signals, it will call this callback with UNAVAILABLE parameter.
+ *
+ * @param status - UNAVAILABLE or AVAILABLE.
+ * @param lastLocation - Last known location.
+ */
+ void gnssGeofenceStatusCb(in int availability, in GnssLocation lastLocation);
+
+ /**
+ * The callback associated with the addGeofence call.
+ *
+ * @param geofenceId Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if the geofence add was successful,
+ * returns ERROR_TOO_MANY_GEOFENCES if the geofence limit has been reached,
+ * returns ERROR_ID_EXISTS if geofence with id already exists,
+ * returns ERROR_INVALID_TRANSITION if the monitorTransition contains an invalid
+ * transition, and
+ * returns ERROR_GENERIC for other errors.
+ */
+ void gnssGeofenceAddCb(in int geofenceId, in int status);
+
+ /**
+ * The callback associated with the removeGeofence call.
+ *
+ * @param geofenceId Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if successful,
+ * returns ERROR_ID_UNKNOWN for invalid id and
+ * returns ERROR_GENERIC for others.
+ */
+ void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+
+ /**
+ * The callback associated with the pauseGeofence call.
+ *
+ * @param geofenceId Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if success,
+ * returns ERROR_ID_UNKNOWN for invalid id,
+ * returns ERROR_INVALID_TRANSITION when monitorTransitions is invalid, and
+ * returns ERROR_GENERIC for other err errors.
+ */
+ void gnssGeofencePauseCb(in int geofenceId, in int status);
+
+ /**
+ * The callback associated with the resumeGeofence call.
+ *
+ * @param geofenceId - Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if successful,
+ * returns ERROR_ID_UNKNOWN for invalid id, and
+ * returns ERROR_GENERIC for others.
+ */
+ void gnssGeofenceResumeCb(in int geofenceId, in int status);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
new file mode 100644
index 0000000..0fdfaf8
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageCallback.aidl
@@ -0,0 +1,240 @@
+/*
+ * 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.gnss;
+
+/** Represents a GNSS navigation message (or a fragment of it). */
+@VintfStability
+interface IGnssNavigationMessageCallback {
+ /**
+ * Represents a reading of GNSS measurements. For devices launched in Android Q or newer, it is
+ * mandatory that these be provided, on request, when the GNSS receiver is searching/tracking
+ * signals.
+ *
+ * - Reporting of GNSS constellation measurements is mandatory.
+ * - Reporting of all tracked constellations are encouraged.
+ */
+ @VintfStability
+ parcelable GnssNavigationMessage {
+ /**
+ * Status of Navigation Message
+ *
+ * When a message is received properly without any parity error in its
+ * navigation words, the status must be set to PARITY_PASSED.
+ *
+ * If a message is received with words that failed a parity check, but the GNSS
+ * receiver has corrected those words, the status must be set to PARITY_REBUILT.
+ *
+ * Do not send any navigation message that contains words with parity errors
+ * that cannot be corrected.
+ */
+ const int STATUS_PARITY_PASSED = (1 << 0);
+ const int STATUS_PARITY_REBUILT = (1 << 1);
+ const int STATUS_UNKNOWN = 0;
+
+ /**
+ * Enumeration of available values to indicate the GNSS Navigation message
+ * types.
+ *
+ * For convenience, first byte is the GnssConstellationType on which that signal
+ * is typically transmitted.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum GnssNavigationMessageType {
+ UNKNOWN = 0,
+
+ /** GPS L1 C/A message contained in the structure. */
+ GPS_L1CA = 0x0101,
+
+ /** GPS L2-CNAV message contained in the structure. */
+ GPS_L2CNAV = 0x0102,
+
+ /** GPS L5-CNAV message contained in the structure. */
+ GPS_L5CNAV = 0x0103,
+
+ /* SBAS message contained in the structure. */
+ SBS = 0x0201,
+
+ /** GPS CNAV-2 message contained in the structure. */
+ GPS_CNAV2 = 0x0104,
+
+ /** Glonass L1 CA message contained in the structure. */
+ GLO_L1CA = 0x0301,
+
+ /** QZSS L1 C/A message contained in the structure. */
+ QZS_L1CA = 0x0401,
+
+ /** Beidou D1 message contained in the structure. */
+ BDS_D1 = 0x0501,
+
+ /** Beidou D2 message contained in the structure. */
+ BDS_D2 = 0x0502,
+
+ /** Beidou CNAV1 message contained in the structure. */
+ BDS_CNAV1 = 0x0503,
+
+ /** Beidou CNAV2 message contained in the structure. */
+ BDS_CNAV2 = 0x0504,
+
+ /** Galileo I/NAV message contained in the structure. */
+ GAL_I = 0x0601,
+
+ /** Galileo F/NAV message contained in the structure. */
+ GAL_F = 0x0602,
+
+ /** IRNSS L5 C/A message contained in the structure. */
+ IRN_L5CA = 0x0701,
+ }
+
+ /**
+ * Satellite vehicle ID number, as defined in GnssSvInfo::svid
+ *
+ * This is a mandatory value.
+ */
+ int svid;
+
+ /**
+ * The type of message contained in the structure.
+ *
+ * This is a mandatory value.
+ */
+ GnssNavigationMessageType type;
+
+ /**
+ * The status of the received navigation message.
+ *
+ * It is a bitfield of constants with prefix "STATUS_" defined in this structure.
+ *
+ * No need to send any navigation message that contains words with parity
+ * errors that cannot be corrected.
+ */
+ int status;
+
+ /**
+ * Message identifier. It provides an index so the complete Navigation
+ * Message can be assembled.
+ *
+ * - For GNSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame
+ * id' of the navigation message, in the range of 1-25 (Subframe 1, 2, 3
+ * does not contain a 'frame id' and this value can be set to -1.)
+ *
+ * - For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.
+ *
+ * - For BeiDou D1, this refers to the frame number in the range of 1-24
+ *
+ * - For Beidou D2, this refers to the frame number, in the range of 1-120
+ *
+ * - For Galileo F/NAV nominal frame structure, this refers to the subframe
+ * number, in the range of 1-12
+ *
+ * - For Galileo I/NAV nominal frame structure, this refers to the subframe
+ * number in the range of 1-24
+ *
+ * - For SBAS and Beidou CNAV2, this is unused and can be set to -1.
+ *
+ * - For QZSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+ * navigation message, in the range of 1-25. (Subframe 1, 2, 3 does not contain a 'frame
+ * id' and this value can be set to -1.)
+ *
+ * - For Beidou CNAV1 this refers to the page type number in the range of 1-63.
+ *
+ * - For IRNSS L5 C/A subframe 3 and 4, this value corresponds to the Message Id of the
+ * navigation message, in the range of 1-63. (Subframe 1 and 2 does not contain a message
+ * type id and this value can be set to -1.)
+ */
+ int messageId;
+
+ /**
+ * Sub-message identifier. If required by the message 'type', this value contains a
+ * sub-index within the current message (or frame) that is being transmitted.
+ *
+ * - For GNSS L1 C/A, BeiDou D1 & BeiDou D2, the submessage id corresponds to the subframe
+ * number of the navigation message, in the range of 1-5.
+ *
+ * - For Glonass L1 C/A, this refers to the String number, in the range from 1-15.
+ *
+ * - For Galileo F/NAV, this refers to the page type in the range 1-6.
+ *
+ * - For Galileo I/NAV, this refers to the word type in the range 0-10+. A value of 0 is
+ * only allowed if the Satellite is transmiting a Spare Word.
+ *
+ * - For Galileo in particular, the type information embedded within the data bits may be
+ * even more useful in interpretation, than the nominal page and word types provided in
+ * this field.
+ *
+ * - For SBAS, the submessage id corresponds to the message type, in the range 1-63.
+ *
+ * - For Beidou CNAV1, the submessage id corresponds to the subframe number of the
+ * navigation message, in the range of 1-3.
+ *
+ * - For Beidou CNAV2, the submessage id corresponds to the message type, in the range 1-63.
+ *
+ * - For IRNSS L5 C/A, the submessage id corresponds to the subframe number of the
+ * navigation message, in the range of 1-4.
+ */
+ int submessageId;
+
+ /**
+ * The data of the reported GNSS message. The bytes (or words) are specified
+ * using big endian format (MSB first).
+ *
+ * - For GNSS L1 C/A, Beidou D1 & Beidou D2, each subframe contains 10 30-bit
+ * words. Each word (30 bits) must fit into the last 30 bits in a
+ * 4-byte word (skip B31 and B32), with MSB first, for a total of 40
+ * bytes, covering a time period of 6, 6, and 0.6 seconds, respectively.
+ * The standard followed is 1995 SPS Signal specification.
+ *
+ * - For Glonass L1 C/A, each string contains 85 data bits, including the
+ * checksum. These bits must fit into 11 bytes, with MSB first (skip
+ * B86-B88), covering a time period of 2 seconds.
+ * The standard followed is Glonass Interface Control Document Edition 5.1.
+ *
+ * - For Galileo F/NAV, each word consists of 238-bit (sync & tail symbols
+ * excluded). Each word must fit into 30-bytes, with MSB first (skip
+ * B239, B240), covering a time period of 10 seconds. The standard
+ * followed is European GNSS(Galileo) Signal in Space Interface
+ * Control Document Issue 1.2.
+ *
+ * - For Galileo I/NAV, each page contains 2 page parts, even and odd, with
+ * a total of 2x114 = 228 bits, (sync & tail excluded) that must fit
+ * into 29 bytes, with MSB first (skip B229-B232). The standard followed
+ * is same as above.
+ *
+ * - For SBAS, each block consists of 250 data bits, that should be fit into 32 bytes. MSB
+ * first (skip B251-B256).
+ *
+ * - For Beidou CNAV1, subframe #1 consists of 14 data bits, that should be fit into 2
+ * bytes. MSB first (skip B15-B16). subframe #2 consists of 600 bits that should be fit
+ * into 75 bytes. subframe #3 consists of 264 data bits that should be fit into 33 bytes.
+ *
+ * - For Beidou CNAV2, each subframe consists of 288 data bits, that should be fit into 36
+ * bytes.
+ *
+ * The data reported here must be the raw data as demodulated by the GNSS receiver, not data
+ * received from an external source (i.e. not from a server download.)
+ */
+ byte[] data;
+ }
+
+ /**
+ * The callback to report an available fragment of a GNSS navigation messages
+ * from the HAL.
+ *
+ * @param message - The GNSS navigation submessage/subframe representation.
+ */
+ void gnssNavigationMessageCb(in GnssNavigationMessage message);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.aidl
new file mode 100644
index 0000000..e2f57c3
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssNavigationMessageInterface.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.
+ */
+
+package android.hardware.gnss;
+
+import android.hardware.gnss.IGnssNavigationMessageCallback;
+
+/**
+ * Extended interface for GNSS navigation message reporting support.
+ */
+@VintfStability
+interface IGnssNavigationMessageInterface {
+ /**
+ * Initializes the interface and registers the callback routines with the HAL.
+ *
+ * After a successful call to 'setCallback' the HAL must begin to provide updates as
+ * they become available.
+ *
+ * @param callback handle to IGnssNavigationMessageCallack interface.
+ */
+ void setCallback(in IGnssNavigationMessageCallback callback);
+
+ /**
+ * Stops updates from the HAL, and unregisters the callback routines.
+ *
+ * After a call to close(), the previously registered callbacks must be
+ * considered invalid by the HAL.
+ *
+ * If close() is invoked without a previous setCallback, this function must perform
+ * no work.
+ */
+ void close();
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 892ad15..b6df895 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -57,7 +57,9 @@
srcs: [
"Gnss.cpp",
"GnssBatching.cpp",
+ "GnssGeofence.cpp",
"GnssHidlHal.cpp",
+ "GnssNavigationMessageInterface.cpp",
"GnssPowerIndication.cpp",
"GnssPsds.cpp",
"GnssConfiguration.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index fbfa2bb..8d58a20 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -20,7 +20,9 @@
#include <log/log.h>
#include "GnssBatching.h"
#include "GnssConfiguration.h"
+#include "GnssGeofence.h"
#include "GnssMeasurementInterface.h"
+#include "GnssNavigationMessageInterface.h"
#include "GnssPsds.h"
namespace aidl::android::hardware::gnss {
@@ -96,4 +98,19 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
+ ALOGD("Gnss::getExtensionGnssGeofence");
+
+ *iGnssGeofence = SharedRefBase::make<GnssGeofence>();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
+ std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
+ ALOGD("Gnss::getExtensionGnssNavigationMessage");
+
+ *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 3959ef8..128a6c1 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -40,6 +40,10 @@
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
ndk::ScopedAStatus getExtensionGnssBatching(
std::shared_ptr<IGnssBatching>* iGnssBatching) override;
+ ndk::ScopedAStatus getExtensionGnssGeofence(
+ std::shared_ptr<IGnssGeofence>* iGnssGeofence) override;
+ ndk::ScopedAStatus getExtensionGnssNavigationMessage(
+ std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssGeofence.cpp b/gnss/aidl/default/GnssGeofence.cpp
new file mode 100644
index 0000000..eda33cc
--- /dev/null
+++ b/gnss/aidl/default/GnssGeofence.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GnssGeofenceAidl"
+
+#include "GnssGeofence.h"
+#include <aidl/android/hardware/gnss/BnGnssGeofence.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IGnssGeofenceCallback> GnssGeofence::sCallback = nullptr;
+
+ndk::ScopedAStatus GnssGeofence::setCallback(
+ const std::shared_ptr<IGnssGeofenceCallback>& callback) {
+ ALOGD("setCallback");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::addGeofence(int geofenceId, double latitudeDegrees,
+ double longitudeDegrees, double radiusMeters,
+ int lastTransition, int monitorTransitions,
+ int notificationResponsivenessMs, int unknownTimerMs) {
+ ALOGD("addGeofence. geofenceId=%d, lat=%lf, lng=%lf, rad=%lf, lastTransition=%d, "
+ "monitorTransitions=%d, notificationResponsivenessMs=%d, unknownTimerMs=%d",
+ geofenceId, latitudeDegrees, longitudeDegrees, radiusMeters, lastTransition,
+ monitorTransitions, notificationResponsivenessMs, unknownTimerMs);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::pauseGeofence(int geofenceId) {
+ ALOGD("pauseGeofence. id=%d", geofenceId);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::resumeGeofence(int geofenceId, int monitorTransitions) {
+ ALOGD("resumeGeofence. id=%d, monitorTransitions=%d", geofenceId, monitorTransitions);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::removeGeofence(int geofenceId) {
+ ALOGD("removeGeofence. id=%d", geofenceId);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssGeofence.h b/gnss/aidl/default/GnssGeofence.h
new file mode 100644
index 0000000..313e832
--- /dev/null
+++ b/gnss/aidl/default/GnssGeofence.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssGeofence.h>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssGeofence : public BnGnssGeofence {
+ public:
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssGeofenceCallback>& callback) override;
+ ndk::ScopedAStatus addGeofence(int geofenceId, double latitudeDegrees, double longitudeDegrees,
+ double radiusMeters, int lastTransition, int monitorTransitions,
+ int notificationResponsivenessMs, int unknownTimerMs) override;
+ ndk::ScopedAStatus pauseGeofence(int geofenceId) override;
+ ndk::ScopedAStatus resumeGeofence(int geofenceId, int monitorTransitions) override;
+ ndk::ScopedAStatus removeGeofence(int geofenceId) override;
+
+ private:
+ // Guarded by mMutex
+ static std::shared_ptr<IGnssGeofenceCallback> sCallback;
+
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.cpp b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
new file mode 100644
index 0000000..4bc859d
--- /dev/null
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GnssNavigationMessageAidl"
+
+#include "GnssNavigationMessageInterface.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+using GnssNavigationMessage = IGnssNavigationMessageCallback::GnssNavigationMessage;
+using GnssNavigationMessageType = GnssNavigationMessage::GnssNavigationMessageType;
+
+std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::sCallback = nullptr;
+
+GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {}
+
+GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
+ stop();
+}
+
+ndk::ScopedAStatus GnssNavigationMessageInterface::setCallback(
+ const std::shared_ptr<IGnssNavigationMessageCallback>& callback) {
+ ALOGD("setCallback");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ start();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssNavigationMessageInterface::close() {
+ ALOGD("close");
+ stop();
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = nullptr;
+ return ndk::ScopedAStatus::ok();
+}
+
+void GnssNavigationMessageInterface::start() {
+ ALOGD("start");
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ GnssNavigationMessage message = {
+ .svid = 19,
+ .type = GnssNavigationMessageType::GPS_L1CA,
+ .status = GnssNavigationMessage::STATUS_PARITY_PASSED,
+ .messageId = 2,
+ .submessageId = 3,
+ .data = std::vector<uint8_t>(40, 0xF9),
+ };
+ this->reportMessage(message);
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
+ }
+ });
+ mThread.detach();
+}
+
+void GnssNavigationMessageInterface::stop() {
+ ALOGD("stop");
+ mIsActive = false;
+}
+
+void GnssNavigationMessageInterface::reportMessage(const GnssNavigationMessage& message) {
+ ALOGD("reportMessage()");
+ std::shared_ptr<IGnssNavigationMessageCallback> callbackCopy;
+ {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sCallback == nullptr) {
+ ALOGE("%s: GnssNavigationMessageInterface::sCallback is null.", __func__);
+ return;
+ }
+ callbackCopy = sCallback;
+ }
+ callbackCopy->gnssNavigationMessageCb(message);
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.h b/gnss/aidl/default/GnssNavigationMessageInterface.h
new file mode 100644
index 0000000..600b23a
--- /dev/null
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssNavigationMessageInterface.h>
+#include <atomic>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssNavigationMessageInterface : public BnGnssNavigationMessageInterface {
+ public:
+ GnssNavigationMessageInterface();
+ ~GnssNavigationMessageInterface();
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IGnssNavigationMessageCallback>& callback) override;
+ ndk::ScopedAStatus close() override;
+
+ private:
+ void start();
+ void stop();
+ void reportMessage(const IGnssNavigationMessageCallback::GnssNavigationMessage& message);
+
+ std::atomic<long> mMinIntervalMillis;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+
+ // Guarded by mMutex
+ static std::shared_ptr<IGnssNavigationMessageCallback> sCallback;
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 6096d4d..4d81519 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -32,7 +32,9 @@
"gnss_hal_test_cases.cpp",
"GnssBatchingCallback.cpp",
"GnssCallbackAidl.cpp",
+ "GnssGeofenceCallback.cpp",
"GnssMeasurementCallbackAidl.cpp",
+ "GnssNavigationMessageCallback.cpp",
"GnssPowerIndicationCallback.cpp",
"VtsHalGnssTargetTest.cpp",
],
diff --git a/gnss/aidl/vts/GnssGeofenceCallback.cpp b/gnss/aidl/vts/GnssGeofenceCallback.cpp
new file mode 100644
index 0000000..b841cb9
--- /dev/null
+++ b/gnss/aidl/vts/GnssGeofenceCallback.cpp
@@ -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.
+ */
+
+#include "GnssGeofenceCallback.h"
+#include <log/log.h>
+
+using android::binder::Status;
+using android::hardware::gnss::GnssLocation;
+
+Status GnssGeofenceCallback::gnssGeofenceTransitionCb(int, const GnssLocation&, int, int64_t) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceStatusCb(int, const GnssLocation&) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceAddCb(int, int) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceRemoveCb(int, int) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofencePauseCb(int, int) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceResumeCb(int, int) {
+ // To implement
+ return Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssGeofenceCallback.h b/gnss/aidl/vts/GnssGeofenceCallback.h
new file mode 100644
index 0000000..b105518
--- /dev/null
+++ b/gnss/aidl/vts/GnssGeofenceCallback.h
@@ -0,0 +1,38 @@
+/*
+ * 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/hardware/gnss/BnGnssGeofenceCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssGeofenceCallback. */
+class GnssGeofenceCallback : public android::hardware::gnss::BnGnssGeofenceCallback {
+ public:
+ GnssGeofenceCallback() {}
+ ~GnssGeofenceCallback() {}
+
+ android::binder::Status gnssGeofenceTransitionCb(
+ int geofenceId, const android::hardware::gnss::GnssLocation& location, int transition,
+ int64_t timestampMillis) override;
+ android::binder::Status gnssGeofenceStatusCb(
+ int availability, const android::hardware::gnss::GnssLocation& lastLocation) override;
+ android::binder::Status gnssGeofenceAddCb(int geofenceId, int status) override;
+ android::binder::Status gnssGeofenceRemoveCb(int geofenceId, int status) override;
+ android::binder::Status gnssGeofencePauseCb(int geofenceId, int status) override;
+ android::binder::Status gnssGeofenceResumeCb(int geofenceId, int status) override;
+};
diff --git a/gnss/aidl/vts/GnssNavigationMessageCallback.cpp b/gnss/aidl/vts/GnssNavigationMessageCallback.cpp
new file mode 100644
index 0000000..cf4a6eb
--- /dev/null
+++ b/gnss/aidl/vts/GnssNavigationMessageCallback.cpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "GnssNavMsgCallback"
+
+#include "GnssNavigationMessageCallback.h"
+#include <log/log.h>
+
+android::binder::Status GnssNavigationMessageCallback::gnssNavigationMessageCb(
+ const android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage& msg) {
+ ALOGD("gnssNavigationMessageCb. svid=%d, type=%d, status=%d, msgId=%d, subMsgId=%d, "
+ "data.size=%d",
+ msg.svid, (int)msg.type, (int)msg.status, msg.messageId, msg.submessageId,
+ (int)msg.data.size());
+ return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssNavigationMessageCallback.h b/gnss/aidl/vts/GnssNavigationMessageCallback.h
new file mode 100644
index 0000000..55114ca
--- /dev/null
+++ b/gnss/aidl/vts/GnssNavigationMessageCallback.h
@@ -0,0 +1,31 @@
+/*
+ * 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/hardware/gnss/BnGnssNavigationMessageCallback.h>
+
+/** Implementation for IGnssNavigationMessageCallback. */
+class GnssNavigationMessageCallback
+ : public android::hardware::gnss::BnGnssNavigationMessageCallback {
+ public:
+ GnssNavigationMessageCallback() {}
+ ~GnssNavigationMessageCallback() {}
+
+ android::binder::Status gnssNavigationMessageCb(
+ const android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage&
+ message) override;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 86140cc..830922c 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -23,7 +23,9 @@
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
#include "GnssBatchingCallback.h"
+#include "GnssGeofenceCallback.h"
#include "GnssMeasurementCallbackAidl.h"
+#include "GnssNavigationMessageCallback.h"
#include "GnssPowerIndicationCallback.h"
#include "gnss_hal_test.h"
@@ -38,8 +40,11 @@
using android::hardware::gnss::IGnssBatching;
using android::hardware::gnss::IGnssBatchingCallback;
using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssGeofence;
+using android::hardware::gnss::IGnssGeofenceCallback;
using android::hardware::gnss::IGnssMeasurementCallback;
using android::hardware::gnss::IGnssMeasurementInterface;
+using android::hardware::gnss::IGnssNavigationMessageInterface;
using android::hardware::gnss::IGnssPowerIndication;
using android::hardware::gnss::IGnssPsds;
using android::hardware::gnss::PsdsType;
@@ -755,23 +760,36 @@
}
/*
- * TestGnssBatchingExtension:
- * 1. Gets the IGnssBatching extension.
- * 2. Initializes the interface with an IGnssBatchingCallback.
- * 3. Clean up.
+ * TestAllExtensions.
*/
-TEST_P(GnssHalTest, TestGnssBatchingExtension) {
+TEST_P(GnssHalTest, TestAllExtensions) {
sp<IGnssBatching> iGnssBatching;
auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
- if (!status.isOk() || iGnssBatching == nullptr) {
- // Device doesn't support batching. Skip the test.
- return;
+ if (status.isOk() && iGnssBatching != nullptr) {
+ auto gnssBatchingCallback = sp<GnssBatchingCallback>::make();
+ status = iGnssBatching->init(gnssBatchingCallback);
+ ASSERT_TRUE(status.isOk());
+
+ status = iGnssBatching->cleanup();
+ ASSERT_TRUE(status.isOk());
}
- sp<IGnssBatchingCallback> iGnssBatchingCallback;
- status = iGnssBatching->init(iGnssBatchingCallback);
- ASSERT_TRUE(status.isOk());
+ sp<IGnssGeofence> iGnssGeofence;
+ status = aidl_gnss_hal_->getExtensionGnssGeofence(&iGnssGeofence);
+ if (status.isOk() && iGnssGeofence != nullptr) {
+ auto gnssGeofenceCallback = sp<GnssGeofenceCallback>::make();
+ status = iGnssGeofence->setCallback(gnssGeofenceCallback);
+ ASSERT_TRUE(status.isOk());
+ }
- status = iGnssBatching->cleanup();
- ASSERT_TRUE(status.isOk());
+ sp<IGnssNavigationMessageInterface> iGnssNavMsgIface;
+ status = aidl_gnss_hal_->getExtensionGnssNavigationMessage(&iGnssNavMsgIface);
+ if (status.isOk() && iGnssNavMsgIface != nullptr) {
+ auto gnssNavMsgCallback = sp<GnssNavigationMessageCallback>::make();
+ status = iGnssNavMsgIface->setCallback(gnssNavMsgCallback);
+ ASSERT_TRUE(status.isOk());
+
+ status = iGnssNavMsgIface->close();
+ ASSERT_TRUE(status.isOk());
+ }
}
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 19b1b45..c5a186b 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -523,7 +523,7 @@
using Capabilities = V2_1::IGnssCallback::Capabilities;
const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST |
- Capabilities::ANTENNA_INFO;
+ Capabilities::ANTENNA_INFO | Capabilities::NAV_MESSAGES;
auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_1(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 51295a6..4faf84b 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -43,6 +43,7 @@
"libmath",
"libnativewindow",
"librenderengine",
+ "libshaders",
"libtonemap",
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.mapper@3.0-vts",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 79ed368..1e0a329 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -67,6 +67,7 @@
"android.hardware.graphics.mapper@4.0-vts",
"libgtest",
"librenderengine",
+ "libshaders",
"libtonemap",
],
header_libs: [
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index c011f73..9bf8609 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -19,7 +19,7 @@
// 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
+ // SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["hardware_interfaces_license"],
}
@@ -28,20 +28,29 @@
defaults: [
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
+ // Needed for librenderengine
+ "skia_deps",
],
srcs: [
"VtsHalGraphicsComposer3_TargetTest.cpp",
+ "VtsHalGraphicsComposer3_ReadbackTest.cpp",
"composer-vts/GraphicsComposerCallback.cpp",
"composer-vts/TestCommandReader.cpp",
],
shared_libs: [
+ "libEGL",
+ "libGLESv1_CM",
+ "libGLESv2",
"libbinder_ndk",
"libbinder",
"libfmq",
"libbase",
"libsync",
"libui",
+ "libgui",
+ "libhidlbase",
+ "libprocessgroup",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.1",
"android.hardware.graphics.mapper@3.0",
@@ -69,6 +78,10 @@
"android.hardware.graphics.mapper@3.0-vts",
"android.hardware.graphics.mapper@4.0-vts",
"libaidlcommonsupport",
+ "libgtest",
+ "librenderengine",
+ "libshaders",
+ "libtonemap",
],
cflags: [
"-Wconversion",
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
new file mode 100644
index 0000000..4008cb4
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -0,0 +1,1316 @@
+/**
+ * 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.
+ */
+
+#define LOG_TAG "graphics_composer_aidl_hal_readback_tests@3"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <android/binder_manager.h>
+#include <composer-vts/include/ReadbackVts.h>
+#include <composer-vts/include/RenderEngineVts.h>
+#include <gtest/gtest.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include "composer-vts/include/GraphicsComposerCallback.h"
+#include "composer-vts/include/TestCommandReader.h"
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+namespace {
+
+using ::android::Rect;
+using common::Dataspace;
+using common::PixelFormat;
+
+class GraphicsCompositionTestBase : public ::testing::Test {
+ protected:
+ void SetUpBase(const std::string& name) {
+ ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
+ ASSERT_NE(binder, nullptr);
+ ASSERT_NO_FATAL_FAILURE(mComposer = IComposer::fromBinder(binder));
+ ASSERT_NE(mComposer, nullptr);
+ ASSERT_NO_FATAL_FAILURE(mComposer->createClient(&mComposerClient));
+ mComposerCallback = ::ndk::SharedRefBase::make<GraphicsComposerCallback>();
+ mComposerClient->registerCallback(mComposerCallback);
+
+ // assume the first display is primary and is never removed
+ mPrimaryDisplay = waitForFirstDisplay();
+
+ ASSERT_NO_FATAL_FAILURE(mInvalidDisplayId = GetInvalidDisplayId());
+
+ int32_t activeConfig;
+ EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+ DisplayAttribute::WIDTH, &mDisplayWidth)
+ .isOk());
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+ DisplayAttribute::HEIGHT, &mDisplayHeight)
+ .isOk());
+
+ setTestColorModes();
+
+ // explicitly disable vsync
+ EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
+ mComposerCallback->setVsyncAllowed(false);
+
+ // set up command writer/reader and gralloc
+ mWriter = std::make_shared<CommandWriterBase>(1024);
+ mReader = std::make_unique<TestCommandReader>();
+ mGraphicBuffer = allocate();
+
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
+
+ ASSERT_NO_FATAL_FAILURE(
+ mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
+ ::android::renderengine::RenderEngineCreationArgs::Builder()
+ .setPixelFormat(static_cast<int>(common::PixelFormat::RGBA_8888))
+ .setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers)
+ .setUseColorManagerment(true)
+ .setEnableProtectedContext(false)
+ .setPrecacheToneMapperShaderOnly(false)
+ .setContextPriority(::android::renderengine::RenderEngine::
+ ContextPriority::HIGH)
+ .build())));
+
+ ::android::renderengine::DisplaySettings clientCompositionDisplay;
+ clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight);
+ clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
+
+ mTestRenderEngine->initGraphicBuffer(
+ static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1,
+ static_cast<uint64_t>(
+ static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::GPU_RENDER_TARGET)));
+ mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
+ EXPECT_EQ(0, mReader->mErrors.size());
+ EXPECT_EQ(0, mReader->mCompositionChanges.size());
+ if (mComposerCallback != nullptr) {
+ EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
+ EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
+ EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
+ }
+ }
+
+ ::android::sp<::android::GraphicBuffer> allocate() {
+ return ::android::sp<::android::GraphicBuffer>::make(
+ mDisplayWidth, mDisplayHeight, ::android::PIXEL_FORMAT_RGBA_8888,
+ /*layerCount*/ 1,
+ static_cast<uint64_t>(static_cast<int>(common::BufferUsage::CPU_WRITE_OFTEN) |
+ static_cast<int>(common::BufferUsage::CPU_READ_OFTEN)),
+ "VtsHalGraphicsComposer3_ReadbackTest");
+ }
+
+ void clearCommandReaderState() {
+ mReader->mCompositionChanges.clear();
+ mReader->mErrors.clear();
+ }
+
+ void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
+ for (auto layer : layers) {
+ layer->write(mWriter);
+ }
+ execute();
+ }
+
+ void execute() {
+ TestCommandReader* reader = mReader.get();
+ CommandWriterBase* writer = mWriter.get();
+ bool queueChanged = false;
+ int32_t commandLength = 0;
+ std::vector<NativeHandle> commandHandles;
+ ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+ if (queueChanged) {
+ auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ ExecuteCommandsStatus commandStatus;
+ EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
+ .isOk());
+
+ if (commandStatus.queueChanged) {
+ MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
+ ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
+ reader->setMQDescriptor(outputCommandQueue);
+ }
+ ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
+ reader->parse();
+ reader->reset();
+ writer->reset();
+ }
+
+ bool getHasReadbackBuffer() {
+ ReadbackBufferAttributes readBackBufferAttributes;
+ const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+ &readBackBufferAttributes);
+ mPixelFormat = readBackBufferAttributes.format;
+ mDataspace = readBackBufferAttributes.dataspace;
+ return error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
+ }
+
+ std::shared_ptr<IComposer> mComposer;
+ std::shared_ptr<IComposerClient> mComposerClient;
+
+ std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
+ // the first display and is assumed never to be removed
+ int64_t mPrimaryDisplay;
+ int64_t mInvalidDisplayId;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+ std::vector<ColorMode> mTestColorModes;
+ std::shared_ptr<CommandWriterBase> mWriter;
+ std::unique_ptr<TestCommandReader> mReader;
+ ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+ std::unique_ptr<TestRenderEngine> mTestRenderEngine;
+
+ common::PixelFormat mPixelFormat;
+ common::Dataspace mDataspace;
+
+ static constexpr uint32_t kClientTargetSlotCount = 64;
+
+ private:
+ int64_t waitForFirstDisplay() {
+ while (true) {
+ std::vector<int64_t> displays = mComposerCallback->getDisplays();
+ if (displays.empty()) {
+ usleep(5 * 1000);
+ continue;
+ }
+ return displays[0];
+ }
+ }
+
+ void setTestColorModes() {
+ mTestColorModes.clear();
+ std::vector<ColorMode> modes;
+ EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+
+ for (ColorMode mode : modes) {
+ if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
+ mode) != ReadbackHelper::colorModes.end()) {
+ mTestColorModes.push_back(mode);
+ }
+ }
+ }
+
+ // returns an invalid display id (one that has not been registered to a
+ // display. Currently assuming that a device will never have close to
+ // std::numeric_limit<uint64_t>::max() displays registered while running tests
+ int64_t GetInvalidDisplayId() {
+ int64_t id = std::numeric_limits<int64_t>::max();
+ std::vector<int64_t> displays = mComposerCallback->getDisplays();
+ while (id > 0) {
+ if (std::none_of(displays.begin(), displays.end(),
+ [&](const auto& display) { return id == display; })) {
+ return id;
+ }
+ id--;
+ }
+
+ // Although 0 could be an invalid display, a return value of 0
+ // from GetInvalidDisplayId means all other ids are in use, a condition which
+ // we are assuming a device will never have
+ EXPECT_NE(0, id);
+ return id;
+ }
+};
+
+class GraphicsCompositionTest : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::string> {
+ public:
+ void SetUp() override { SetUpBase(GetParam()); }
+};
+
+TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ common::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setColor(BLUE);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ // expected color for each pixel
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ // if hwc cannot handle and asks for composition change,
+ // just succeed the test
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
+ GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+ BLUE);
+
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+ mDisplayHeight, common::PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ common::Rect coloredSquare({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setColor(BLUE);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+ layer->write(mWriter);
+
+ // This following buffer call should have no effect
+ uint64_t usage =
+ static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN));
+
+ mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
+ static_cast<uint32_t>(mDisplayHeight), 1,
+ static_cast<uint32_t>(common::PixelFormat::RGBA_8888), usage);
+ mWriter->setLayerBuffer(0, mGraphicBuffer->handle, -1);
+
+ // expected color for each pixel
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, coloredSquare, BLUE);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ mWriter->validateDisplay();
+ execute();
+
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, mDisplayWidth,
+ mDisplayHeight, mPixelFormat, mDataspace);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadDisplay) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ ASSERT_NE(nullptr, mGraphicBuffer);
+ ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+ aidl::android::hardware::common::NativeHandle bufferHandle =
+ ::android::dupToAidl(mGraphicBuffer->handle);
+ ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
+
+ const auto error = mComposerClient->setReadbackBuffer(mInvalidDisplayId, bufferHandle, fence);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadParameter) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ aidl::android::hardware::common::NativeHandle bufferHandle = ::android::dupToAidl(nullptr);
+ ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
+ const auto error =
+ mComposerClient->setReadbackBuffer(mPrimaryDisplay, bufferHandle, releaseFence);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ ndk::ScopedFileDescriptor releaseFence;
+ const auto error = mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &releaseFence);
+
+ EXPECT_TRUE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, ClientComposition) {
+ EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount)
+ .isOk());
+
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ EXPECT_TRUE(mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight / 2},
+ GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+ BLUE);
+
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+ mDisplayHeight, PixelFormat::RGBA_FP16);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+
+ if (!mReader->mCompositionChanges.empty()) {
+ ASSERT_EQ(1, mReader->mCompositionChanges.size());
+ ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+
+ PixelFormat clientFormat = PixelFormat::RGBA_8888;
+ auto clientUsage = static_cast<uint32_t>(
+ static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+ static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
+ Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
+ common::Rect damage{0, 0, mDisplayWidth, mDisplayHeight};
+
+ // create client target buffer
+ mGraphicBuffer->reallocate(layer->getWidth(), layer->getHeight(),
+ static_cast<int32_t>(common::PixelFormat::RGBA_8888),
+ layer->getLayerCount(), clientUsage);
+
+ ASSERT_NE(nullptr, mGraphicBuffer->handle);
+
+ void* clientBufData;
+ mGraphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
+
+ ASSERT_NO_FATAL_FAILURE(
+ ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(),
+ static_cast<uint32_t>(mGraphicBuffer->stride),
+ clientBufData, clientFormat, expectedColors));
+ EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+
+ ndk::ScopedFileDescriptor fenceHandle;
+ EXPECT_TRUE(
+ mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
+
+ layer->setToClientComposition(mWriter);
+ mWriter->acceptDisplayChanges();
+ mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
+ std::vector<common::Rect>(1, damage));
+ execute();
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
+
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 2}, GREEN);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, RED);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ auto deviceLayer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+ mDisplayHeight / 2, PixelFormat::RGBA_8888);
+ std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
+ ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
+ {0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
+ static_cast<int32_t>(deviceLayer->getHeight())},
+ GREEN);
+ 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);
+ ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
+ deviceLayer->write(mWriter);
+
+ PixelFormat clientFormat = PixelFormat::RGBA_8888;
+ auto clientUsage = static_cast<uint32_t>(
+ static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+ static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
+ Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
+ int32_t clientWidth = mDisplayWidth;
+ int32_t clientHeight = mDisplayHeight / 2;
+
+ auto clientLayer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, clientWidth,
+ clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
+ common::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight};
+ clientLayer->setDisplayFrame(clientFrame);
+ clientLayer->setZOrder(0);
+ clientLayer->write(mWriter);
+ mWriter->validateDisplay();
+ execute();
+
+ if (mReader->mCompositionChanges.size() != 1) {
+ mReader->mCompositionChanges.clear();
+ continue;
+ }
+ // create client target buffer
+ ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+ mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
+ static_cast<uint32_t>(mDisplayHeight),
+ static_cast<int32_t>(common::PixelFormat::RGBA_8888),
+ clientLayer->getLayerCount(), clientUsage);
+ ASSERT_NE(nullptr, mGraphicBuffer->handle);
+
+ void* clientBufData;
+ mGraphicBuffer->lock(clientUsage, {0, 0, mDisplayWidth, mDisplayHeight}, &clientBufData);
+
+ std::vector<Color> clientColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(clientColors, mDisplayWidth, clientFrame, RED);
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
+ static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight),
+ mGraphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
+ EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+
+ ndk::ScopedFileDescriptor fenceHandle;
+ EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
+
+ clientLayer->setToClientComposition(mWriter);
+ mWriter->acceptDisplayChanges();
+ mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
+ std::vector<common::Rect>(1, clientFrame));
+ execute();
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerDamage) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ common::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+ mDisplayHeight, PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+ // update surface damage and recheck
+ redRect = {mDisplayWidth / 4, mDisplayHeight / 4, mDisplayWidth / 2, mDisplayHeight / 2};
+ ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+ ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
+ layer->setSurfaceDamage(
+ std::vector<common::Rect>(1, {0, 0, mDisplayWidth / 2, mDisplayWidth / 2}));
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ auto layer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ layer->setColor(RED);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setAlpha(0);
+ layer->setBlendMode(BlendMode::PREMULTIPLIED);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight},
+ BLUE);
+
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+ mDisplayHeight, PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+ layer->setSourceCrop({0, static_cast<float>(mDisplayHeight / 2),
+ static_cast<float>(mDisplayWidth),
+ static_cast<float>(mDisplayHeight)});
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ // update expected colors to match crop
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight}, BLUE);
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ common::Rect redRect = {0, 0, mDisplayWidth, mDisplayHeight / 2};
+ common::Rect blueRect = {0, mDisplayHeight / 4, mDisplayWidth, mDisplayHeight};
+ auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ redLayer->setColor(RED);
+ redLayer->setDisplayFrame(redRect);
+
+ auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ blueLayer->setColor(BLUE);
+ blueLayer->setDisplayFrame(blueRect);
+ blueLayer->setZOrder(5);
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+ // red in front of blue
+ redLayer->setZOrder(10);
+
+ // fill blue first so that red will overwrite on overlap
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+
+ redLayer->setZOrder(1);
+ ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, blueRect, BLUE);
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+class GraphicsBlendModeCompositionTest
+ : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::tuple<std::string, std::string>> {
+ public:
+ void SetUp() override {
+ SetUpBase(std::get<0>(GetParam()));
+ mBackgroundColor = BLACK;
+ mTopLayerColor = RED;
+ }
+
+ void setBackgroundColor(Color color) { mBackgroundColor = color; }
+
+ void setTopLayerColor(Color color) { mTopLayerColor = color; }
+
+ void setUpLayers(BlendMode blendMode) {
+ mLayers.clear();
+ std::vector<Color> topLayerPixelColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(topLayerPixelColors, mDisplayWidth,
+ {0, 0, mDisplayWidth, mDisplayHeight}, mTopLayerColor);
+
+ auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ backgroundLayer->setZOrder(0);
+ backgroundLayer->setColor(mBackgroundColor);
+
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, mGraphicBuffer, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth,
+ mDisplayHeight, PixelFormat::RGBA_8888);
+ layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ layer->setZOrder(10);
+ layer->setDataspace(Dataspace::UNKNOWN, mWriter);
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
+
+ layer->setBlendMode(blendMode);
+ layer->setAlpha(std::stof(std::get<1>(GetParam())));
+
+ mLayers.push_back(backgroundLayer);
+ mLayers.push_back(layer);
+ }
+
+ void setExpectedColors(std::vector<Color>& expectedColors) {
+ ASSERT_EQ(2, mLayers.size());
+ ReadbackHelper::clearColors(expectedColors, mDisplayWidth, mDisplayHeight, mDisplayWidth);
+
+ auto layer = mLayers[1];
+ BlendMode blendMode = layer->getBlendMode();
+ float alpha = mTopLayerColor.a / 255.0f * layer->getAlpha();
+ if (blendMode == BlendMode::NONE) {
+ for (auto& expectedColor : expectedColors) {
+ expectedColor.r = mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha());
+ expectedColor.g = mTopLayerColor.g * static_cast<int8_t>(layer->getAlpha());
+ expectedColor.b = mTopLayerColor.b * static_cast<int8_t>(layer->getAlpha());
+ expectedColor.a = static_cast<int8_t>(alpha * 255.0);
+ }
+ } else if (blendMode == BlendMode::PREMULTIPLIED) {
+ for (auto& expectedColor : expectedColors) {
+ expectedColor.r = static_cast<int8_t>(
+ mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha()) +
+ mBackgroundColor.r * (1.0 - alpha));
+ expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * layer->getAlpha() +
+ mBackgroundColor.g * (1.0 - alpha));
+ expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * layer->getAlpha() +
+ mBackgroundColor.b * (1.0 - alpha));
+ expectedColor.a = static_cast<int8_t>(alpha + mBackgroundColor.a * (1.0 - alpha));
+ }
+ } else if (blendMode == BlendMode::COVERAGE) {
+ for (auto& expectedColor : expectedColors) {
+ expectedColor.r = static_cast<int8_t>(mTopLayerColor.r * alpha +
+ mBackgroundColor.r * (1.0 - alpha));
+ expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * alpha +
+ mBackgroundColor.g * (1.0 - alpha));
+ expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * alpha +
+ mBackgroundColor.b * (1.0 - alpha));
+ expectedColor.a = static_cast<int8_t>(mTopLayerColor.a * alpha +
+ mBackgroundColor.a * (1.0 - alpha));
+ }
+ }
+ }
+
+ protected:
+ std::vector<std::shared_ptr<TestLayer>> mLayers;
+ Color mBackgroundColor;
+ Color mTopLayerColor;
+};
+
+TEST_P(GraphicsBlendModeCompositionTest, None) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+ setBackgroundColor(BLACK);
+ setTopLayerColor(TRANSLUCENT_RED);
+ setUpLayers(BlendMode::NONE);
+ setExpectedColors(expectedColors);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(mLayers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(mLayers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+ setBackgroundColor(BLACK);
+ setTopLayerColor(TRANSLUCENT_RED);
+
+ setUpLayers(BlendMode::COVERAGE);
+ setExpectedColors(expectedColors);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(mLayers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+ mWriter->selectDisplay(mPrimaryDisplay);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+
+ setBackgroundColor(BLACK);
+ setTopLayerColor(TRANSLUCENT_RED);
+ setUpLayers(BlendMode::PREMULTIPLIED);
+ setExpectedColors(expectedColors);
+
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ writeLayers(mLayers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(mLayers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+class GraphicsTransformCompositionTest : public GraphicsCompositionTest {
+ protected:
+ void SetUp() override {
+ GraphicsCompositionTest::SetUp();
+ mWriter->selectDisplay(mPrimaryDisplay);
+ auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
+ backgroundLayer->setColor({0, 0, 0, 0});
+ backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
+ backgroundLayer->setZOrder(0);
+
+ mSideLength = mDisplayWidth < mDisplayHeight ? mDisplayWidth : mDisplayHeight;
+ common::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
+ common::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength};
+
+ mLayer = std::make_shared<TestBufferLayer>(mComposerClient, mGraphicBuffer,
+ *mTestRenderEngine, mPrimaryDisplay, mSideLength,
+ mSideLength, PixelFormat::RGBA_8888);
+ mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
+ mLayer->setZOrder(10);
+
+ std::vector<Color> baseColors(static_cast<size_t>(mSideLength * mSideLength));
+ ReadbackHelper::fillColorsArea(baseColors, mSideLength, redRect, RED);
+ ReadbackHelper::fillColorsArea(baseColors, mSideLength, blueRect, BLUE);
+ ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
+ mLayers = {backgroundLayer, mLayer};
+ }
+
+ protected:
+ std::shared_ptr<TestBufferLayer> mLayer;
+ std::vector<std::shared_ptr<TestLayer>> mLayers;
+ int mSideLength;
+};
+
+TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
+ for (ColorMode mode : mTestColorModes) {
+ ASSERT_NE(nullptr, mWriter);
+ mWriter->selectDisplay(mPrimaryDisplay);
+ auto error =
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC);
+ if (!error.isOk() &&
+ (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
+ error.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
+ SUCCEED() << "ColorMode not supported, skip test";
+ return;
+ }
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ mLayer->setTransform(Transform::FLIP_H);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
+
+ writeLayers(mLayers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(mLayers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ mLayer->setTransform(Transform::FLIP_V);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
+
+ writeLayers(mLayers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(mLayers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+TEST_P(GraphicsTransformCompositionTest, ROT_180) {
+ for (ColorMode mode : mTestColorModes) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ ASSERT_NO_FATAL_FAILURE(
+ mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
+
+ if (!getHasReadbackBuffer()) {
+ GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+ ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
+ mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ mLayer->setTransform(Transform::ROT_180);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
+
+ std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength},
+ RED);
+ ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
+ {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
+
+ writeLayers(mLayers);
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->validateDisplay();
+ execute();
+ if (!mReader->mCompositionChanges.empty()) {
+ clearCommandReaderState();
+ GTEST_SUCCEED();
+ return;
+ }
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(mLayers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsCompositionTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsCompositionTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsBlendModeCompositionTest);
+INSTANTIATE_TEST_SUITE_P(BlendMode, GraphicsBlendModeCompositionTest,
+ testing::Combine(testing::ValuesIn(::android::getAidlHalInstanceNames(
+ IComposer::descriptor)),
+ testing::Values("0.2", "1.0")));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsTransformCompositionTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsTransformCompositionTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+} // namespace
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index 9ea837e..b9460c8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -40,6 +40,9 @@
using namespace std::chrono_literals;
+using ::android::GraphicBuffer;
+using ::android::sp;
+
class VtsDisplay {
public:
VtsDisplay(int64_t displayId, int32_t displayWidth, int32_t displayHeight)
@@ -73,38 +76,117 @@
ASSERT_NO_FATAL_FAILURE(mComposer = IComposer::fromBinder(binder));
ASSERT_NE(mComposer, nullptr);
ASSERT_NO_FATAL_FAILURE(mComposer->createClient(&mComposerClient));
- mInvalidDisplayId = GetInvalidDisplayId();
mComposerCallback = ::ndk::SharedRefBase::make<GraphicsComposerCallback>();
EXPECT_TRUE(mComposerClient->registerCallback(mComposerCallback).isOk());
// assume the first displays are built-in and are never removed
mDisplays = waitForDisplays();
+ mPrimaryDisplay = mDisplays[0].get();
+ ASSERT_NO_FATAL_FAILURE(mInvalidDisplayId = GetInvalidDisplayId());
+
+ int32_t activeConfig;
+ EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+ DisplayAttribute::WIDTH, &mDisplayWidth)
+ .isOk());
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+ DisplayAttribute::HEIGHT, &mDisplayHeight)
+ .isOk());
// explicitly disable vsync
for (const auto& display : mDisplays) {
EXPECT_TRUE(mComposerClient->setVsyncEnabled(display.get(), false).isOk());
}
mComposerCallback->setVsyncAllowed(false);
-
- mWriter = std::make_unique<CommandWriterBase>(1024);
- mReader = std::make_unique<TestCommandReader>();
}
void TearDown() override {
- ASSERT_EQ(0, mReader->mErrors.size());
- ASSERT_EQ(0, mReader->mCompositionChanges.size());
-
+ destroyAllLayers();
if (mComposerCallback != nullptr) {
EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
- EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
EXPECT_EQ(0, mComposerCallback->getInvalidVsyncPeriodChangeCount());
EXPECT_EQ(0, mComposerCallback->getInvalidSeamlessPossibleCount());
}
}
+ void Test_setContentTypeForDisplay(const int64_t& display,
+ const std::vector<ContentType>& capabilities,
+ const ContentType& contentType, const char* contentTypeStr) {
+ const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(),
+ contentType) != capabilities.end();
+
+ if (!contentTypeSupport) {
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED,
+ mComposerClient->setContentType(display, contentType)
+ .getServiceSpecificError());
+ GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
+ << std::to_string(display) << ", skipping test";
+ return;
+ }
+
+ EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
+ EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
+ }
+
+ void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) {
+ for (const auto& display : mDisplays) {
+ std::vector<ContentType> supportedContentTypes;
+ const auto error = mComposerClient->getSupportedContentTypes(display.get(),
+ &supportedContentTypes);
+ EXPECT_TRUE(error.isOk());
+
+ Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
+ contentTypeStr);
+ }
+ }
+
+ int64_t createLayer(const VtsDisplay& display) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(display.get(), kBufferSlotCount, &layer).isOk());
+
+ auto resourceIt = mDisplayResources.find(display.get());
+ if (resourceIt == mDisplayResources.end()) {
+ resourceIt = mDisplayResources.insert({display.get(), DisplayResource(false)}).first;
+ }
+
+ EXPECT_TRUE(resourceIt->second.layers.insert(layer).second)
+ << "duplicated layer id " << layer;
+
+ return layer;
+ }
+
+ void destroyAllLayers() {
+ for (const auto& it : mDisplayResources) {
+ auto display = it.first;
+ const DisplayResource& resource = it.second;
+
+ for (auto layer : resource.layers) {
+ const auto error = mComposerClient->destroyLayer(display, layer);
+ EXPECT_TRUE(error.isOk());
+ }
+
+ if (resource.isVirtual) {
+ const auto error = mComposerClient->destroyVirtualDisplay(display);
+ EXPECT_TRUE(error.isOk());
+ }
+ }
+ mDisplayResources.clear();
+ }
+
+ void destroyLayer(const VtsDisplay& display, int64_t layer) {
+ auto const error = mComposerClient->destroyLayer(display.get(), layer);
+ ASSERT_TRUE(error.isOk()) << "failed to destroy layer " << layer;
+
+ auto resourceIt = mDisplayResources.find(display.get());
+ ASSERT_NE(mDisplayResources.end(), resourceIt);
+ resourceIt->second.layers.erase(layer);
+ }
+
// returns an invalid display id (one that has not been registered to a
// display. Currently assuming that a device will never have close to
// std::numeric_limit<uint64_t>::max() displays registered while running tests
@@ -118,7 +200,11 @@
id--;
}
- return 0;
+ // Although 0 could be an invalid display, a return value of 0
+ // from GetInvalidDisplayId means all other ids are in use, a condition which
+ // we are assuming a device will never have
+ EXPECT_NE(0, id);
+ return id;
}
std::vector<VtsDisplay> waitForDisplays() {
@@ -177,320 +263,11 @@
return error;
}
- void Test_setContentTypeForDisplay(const int64_t& display,
- const std::vector<ContentType>& capabilities,
- const ContentType& contentType, const char* contentTypeStr) {
- const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(),
- contentType) != capabilities.end();
-
- if (!contentTypeSupport) {
- EXPECT_EQ(IComposerClient::EX_UNSUPPORTED,
- mComposerClient->setContentType(display, contentType)
- .getServiceSpecificError());
- GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
- << std::to_string(display) << ", skipping test";
- return;
- }
-
- EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
- EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
- }
-
- void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) {
- for (const auto& display : mDisplays) {
- std::vector<ContentType> supportedContentTypes;
- const auto error = mComposerClient->getSupportedContentTypes(display.get(),
- &supportedContentTypes);
- EXPECT_TRUE(error.isOk());
-
- Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
- contentTypeStr);
- }
- }
-
- void execute() {
- TestCommandReader* reader = mReader.get();
- CommandWriterBase* writer = mWriter.get();
- bool queueChanged = false;
- int32_t commandLength = 0;
- std::vector<NativeHandle> commandHandles;
- ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
- if (queueChanged) {
- auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
- ASSERT_TRUE(ret.isOk());
- }
-
- ExecuteCommandsStatus commandStatus;
- EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
- .isOk());
-
- if (commandStatus.queueChanged) {
- MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
- ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
- reader->setMQDescriptor(outputCommandQueue);
- }
- ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
- reader->parse();
- reader->reset();
- writer->reset();
- }
-
- ::android::sp<::android::GraphicBuffer> allocate(uint32_t width, uint32_t height) {
- ::android::sp<::android::GraphicBuffer> buffer =
- ::android::sp<::android::GraphicBuffer>::make(
- width, height, ::android::PIXEL_FORMAT_RGBA_8888,
- /*layerCount*/ 1,
- static_cast<uint64_t>(
- static_cast<int>(common::BufferUsage::CPU_WRITE_OFTEN) |
- static_cast<int>(common::BufferUsage::CPU_READ_OFTEN)),
- "VtsHalGraphicsComposer3_TargetTest");
-
- return buffer;
- }
-
struct TestParameters {
nsecs_t delayForChange;
bool refreshMiss;
};
- static inline auto toTimePoint(nsecs_t time) {
- return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
- }
-
- int64_t createLayer(const VtsDisplay& display) {
- int64_t layer;
- EXPECT_TRUE(mComposerClient->createLayer(display.get(), kBufferSlotCount, &layer).isOk());
-
- auto resourceIt = mDisplayResources.find(display.get());
- if (resourceIt == mDisplayResources.end()) {
- resourceIt = mDisplayResources.insert({display.get(), DisplayResource(false)}).first;
- }
-
- EXPECT_TRUE(resourceIt->second.layers.insert(layer).second)
- << "duplicated layer id " << layer;
-
- return layer;
- }
-
- void destroyLayer(const VtsDisplay& display, int64_t layer) {
- auto const error = mComposerClient->destroyLayer(display.get(), layer);
- ASSERT_TRUE(error.isOk()) << "failed to destroy layer " << layer;
-
- auto resourceIt = mDisplayResources.find(display.get());
- ASSERT_NE(mDisplayResources.end(), resourceIt);
- resourceIt->second.layers.erase(layer);
- }
-
- void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
- std::vector<int32_t> displayConfigs;
- EXPECT_TRUE(mComposerClient->getDisplayConfigs(display, &displayConfigs).isOk());
- for (const int32_t config1 : displayConfigs) {
- for (const int32_t config2 : displayConfigs) {
- if (config1 != config2) {
- func(config1, config2);
- }
- }
- }
- }
-
- void setActiveConfig(VtsDisplay& display, int32_t config) {
- EXPECT_TRUE(mComposerClient->setActiveConfig(display.get(), config).isOk());
- int32_t displayWidth;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH,
- &displayWidth)
- .isOk());
- int32_t displayHeight;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT,
- &displayHeight)
- .isOk());
- display.setDimensions(displayWidth, displayHeight);
- }
-
- void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
- if (timeline != nullptr) {
- // Refresh time should be before newVsyncAppliedTimeNanos
- EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
-
- std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
- }
-
- mWriter->selectDisplay(display.get());
- setPowerMode(display.get(), PowerMode::ON);
- EXPECT_TRUE(
- mComposerClient
- ->setColorMode(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC)
- .isOk());
-
- FRect displayCrop = display.getCrop();
- auto displayWidth = static_cast<uint32_t>(std::ceilf(displayCrop.right - displayCrop.left));
- auto displayHeight =
- static_cast<uint32_t>(std::ceilf(displayCrop.bottom - displayCrop.top));
- int64_t layer = 0;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer(display));
- {
- auto buffer = allocate(displayWidth, displayHeight);
- ASSERT_NE(nullptr, buffer);
- ASSERT_EQ(::android::OK, buffer->initCheck());
- ASSERT_NE(nullptr, buffer->handle);
-
- mWriter->selectLayer(layer);
- mWriter->setLayerCompositionType(Composition::DEVICE);
- mWriter->setLayerDisplayFrame(display.getFrameRect());
- mWriter->setLayerPlaneAlpha(1);
- mWriter->setLayerSourceCrop(display.getCrop());
- mWriter->setLayerTransform(static_cast<Transform>(0));
- mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
- mWriter->setLayerZOrder(10);
- mWriter->setLayerBlendMode(BlendMode::NONE);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
- mWriter->setLayerBuffer(0, buffer->handle, -1);
- mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
-
- mWriter->validateDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- mReader->mCompositionChanges.clear();
-
- mWriter->presentDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- }
-
- {
- auto buffer = allocate(displayWidth, displayHeight);
- ASSERT_NE(nullptr, buffer->handle);
-
- mWriter->selectLayer(layer);
- mWriter->setLayerBuffer(0, buffer->handle, -1);
- mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
- mWriter->validateDisplay();
- execute();
- ASSERT_EQ(0, mReader->mErrors.size());
- mReader->mCompositionChanges.clear();
-
- mWriter->presentDisplay();
- execute();
- }
-
- ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
- }
-
- void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
- int64_t desiredTimeNanos, int64_t oldPeriodNanos,
- int64_t newPeriodNanos) {
- const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
- while (std::chrono::steady_clock::now() <= kChangeDeadline) {
- int32_t vsyncPeriodNanos;
- EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos).isOk());
- if (systemTime() <= desiredTimeNanos) {
- EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
- } else if (vsyncPeriodNanos == newPeriodNanos) {
- break;
- }
- std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
- }
- }
-
- void Test_setActiveConfigWithConstraints(const TestParameters& params) {
- for (VtsDisplay& display : mDisplays) {
- forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
- setActiveConfig(display, config1);
- sendRefreshFrame(display, nullptr);
-
- int32_t vsyncPeriod1;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config1,
- DisplayAttribute::VSYNC_PERIOD,
- &vsyncPeriod1)
- .isOk());
- int32_t configGroup1;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config1,
- DisplayAttribute::CONFIG_GROUP,
- &configGroup1)
- .isOk());
- int32_t vsyncPeriod2;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config2,
- DisplayAttribute::VSYNC_PERIOD,
- &vsyncPeriod2)
- .isOk());
- int32_t configGroup2;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config2,
- DisplayAttribute::CONFIG_GROUP,
- &configGroup2)
- .isOk());
-
- if (vsyncPeriod1 == vsyncPeriod2) {
- return; // continue
- }
-
- // We don't allow delayed change when changing config groups
- if (params.delayForChange > 0 && configGroup1 != configGroup2) {
- return; // continue
- }
-
- VsyncPeriodChangeTimeline timeline;
- VsyncPeriodChangeConstraints constraints = {
- .desiredTimeNanos = systemTime() + params.delayForChange,
- .seamlessRequired = false};
- EXPECT_TRUE(setActiveConfigWithConstraints(display, config2, constraints, &timeline)
- .isOk());
-
- EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
- // Refresh rate should change within a reasonable time
- constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s; // 1 second
- EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
- kReasonableTimeForChange.count());
-
- if (timeline.refreshRequired) {
- if (params.refreshMiss) {
- // Miss the refresh frame on purpose to make sure the implementation sends a
- // callback
- std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
- 100ms);
- }
- sendRefreshFrame(display, &timeline);
- }
- waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
- vsyncPeriod1, vsyncPeriod2);
-
- // At this point the refresh rate should have changed already, however in rare
- // cases the implementation might have missed the deadline. In this case a new
- // timeline should have been provided.
- auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
- if (timeline.refreshRequired && params.refreshMiss) {
- EXPECT_TRUE(newTimeline.has_value());
- }
-
- if (newTimeline.has_value()) {
- if (newTimeline->refreshRequired) {
- sendRefreshFrame(display, &newTimeline.value());
- }
- waitForVsyncPeriodChange(display.get(), newTimeline.value(),
- constraints.desiredTimeNanos, vsyncPeriod1,
- vsyncPeriod2);
- }
-
- int32_t vsyncPeriodNanos;
- EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
- .isOk());
- EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
- });
- }
- }
-
- void setPowerMode(int64_t display, PowerMode powerMode) {
- ::ndk::ScopedAStatus error = mComposerClient->setPowerMode(display, powerMode);
- ASSERT_TRUE(error.isOk() ||
- IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
- << "failed to set power mode";
- }
-
// Keep track of all virtual displays and layers. When a test fails with
// ASSERT_*, the destructor will clean up the resources for the test.
struct DisplayResource {
@@ -506,11 +283,11 @@
int64_t mPrimaryDisplay;
std::vector<VtsDisplay> mDisplays;
std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
- std::unique_ptr<CommandWriterBase> mWriter;
- std::unique_ptr<TestCommandReader> mReader;
// use the slot count usually set by SF
static constexpr uint32_t kBufferSlotCount = 64;
std::unordered_map<int64_t, DisplayResource> mDisplayResources;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
};
TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBadDisplay) {
@@ -529,94 +306,19 @@
}
}
-TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod) {
- for (VtsDisplay& display : mDisplays) {
- std::vector<int32_t> configs;
- EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
- for (int32_t config : configs) {
- int32_t expectedVsyncPeriodNanos = -1;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config,
- DisplayAttribute::VSYNC_PERIOD,
- &expectedVsyncPeriodNanos)
- .isOk());
-
- VsyncPeriodChangeTimeline timeline;
- VsyncPeriodChangeConstraints constraints;
-
- constraints.desiredTimeNanos = systemTime();
- constraints.seamlessRequired = false;
- EXPECT_TRUE(mComposerClient
- ->setActiveConfigWithConstraints(display.get(), config, constraints,
- &timeline)
- .isOk());
-
- if (timeline.refreshRequired) {
- sendRefreshFrame(display, &timeline);
- }
- waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
- expectedVsyncPeriodNanos);
-
- int32_t vsyncPeriodNanos;
- int retryCount = 100;
- do {
- std::this_thread::sleep_for(10ms);
- vsyncPeriodNanos = 0;
- EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
- .isOk());
- --retryCount;
- } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
-
- EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
-
- // Make sure that the vsync period stays the same if the active config is not
- // changed.
- auto timeout = 1ms;
- for (int i = 0; i < 10; i++) {
- std::this_thread::sleep_for(timeout);
- timeout *= 2;
- vsyncPeriodNanos = 0;
- EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
- .isOk());
- EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
- }
- }
- }
+TEST_P(GraphicsComposerAidlTest, DumpDebugInfo) {
+ std::string debugInfo;
+ EXPECT_TRUE(mComposer->dumpDebugInfo(&debugInfo).isOk());
}
-TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
- VsyncPeriodChangeTimeline timeline;
- VsyncPeriodChangeConstraints constraints;
+TEST_P(GraphicsComposerAidlTest, CreateClientSingleton) {
+ std::shared_ptr<IComposerClient> composerClient;
+ const auto error = mComposer->createClient(&composerClient);
- constraints.seamlessRequired = true;
- constraints.desiredTimeNanos = systemTime();
-
- for (VtsDisplay& display : mDisplays) {
- forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
- int32_t configGroup1;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config1,
- DisplayAttribute::CONFIG_GROUP, &configGroup1)
- .isOk());
- int32_t configGroup2;
- EXPECT_TRUE(mComposerClient
- ->getDisplayAttribute(display.get(), config2,
- DisplayAttribute::CONFIG_GROUP, &configGroup2)
- .isOk());
- if (configGroup1 != configGroup2) {
- setActiveConfig(display, config1);
- sendRefreshFrame(display, nullptr);
- EXPECT_EQ(IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
- setActiveConfigWithConstraints(display, config2, constraints, &timeline)
- .getServiceSpecificError());
- }
- });
- }
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_NO_RESOURCES, error.getServiceSpecificError());
}
-TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints) {
- Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
-}
TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
DisplayIdentification displayIdentification0;
@@ -766,11 +468,19 @@
}
TEST_P(GraphicsComposerAidlTest, SetColorModeBadDisplay) {
- auto const error = mComposerClient->setColorMode(mInvalidDisplayId, ColorMode::NATIVE,
- RenderIntent::COLORIMETRIC);
+ std::vector<ColorMode> colorModes;
+ EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+ for (auto mode : colorModes) {
+ std::vector<RenderIntent> intents;
+ EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk())
+ << "failed to get render intents";
+ for (auto intent : intents) {
+ auto const error = mComposerClient->setColorMode(mInvalidDisplayId, mode, intent);
- EXPECT_FALSE(error.isOk());
- ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+ }
+ }
}
TEST_P(GraphicsComposerAidlTest, SetColorModeBadParameter) {
@@ -826,17 +536,19 @@
displayContentSamplingAttributes.format = static_cast<common::PixelFormat>(invalid);
displayContentSamplingAttributes.dataspace = static_cast<common::Dataspace>(invalid);
displayContentSamplingAttributes.componentMask = static_cast<FormatColorComponent>(invalid);
- EXPECT_TRUE(mComposerClient
- ->getDisplayedContentSamplingAttributes(mPrimaryDisplay,
- &displayContentSamplingAttributes)
- .isOk());
+ auto error = mComposerClient->getDisplayedContentSamplingAttributes(
+ mPrimaryDisplay, &displayContentSamplingAttributes);
+ if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ SUCCEED() << "Sampling attributes aren't supported on this device, test skipped";
+ return;
+ }
int64_t maxFrames = 10;
int64_t timestamp = 0;
int64_t frameCount = 0;
DisplayContentSample displayContentSample;
- auto error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
- &displayContentSample);
+ error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
+ &displayContentSample);
if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
SUCCEED() << "Device does not support optional extension. Test skipped";
return;
@@ -1190,14 +902,160 @@
EXPECT_TRUE(mComposerClient->destroyVirtualDisplay(virtualDisplay.display).isOk());
}
+TEST_P(GraphicsComposerAidlTest, DestroyVirtualDisplayBadDisplay) {
+ int32_t maxDisplayCount = 0;
+ EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&maxDisplayCount).isOk());
+ if (maxDisplayCount == 0) {
+ GTEST_SUCCEED() << "no virtual display support";
+ return;
+ }
+ const auto error = mComposerClient->destroyVirtualDisplay(mInvalidDisplayId);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, CreateLayer) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, CreateLayerBadDisplay) {
+ int64_t layer;
+ const auto error = mComposerClient->createLayer(mInvalidDisplayId, kBufferSlotCount, &layer);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, DestroyLayerBadDisplay) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ const auto error = mComposerClient->destroyLayer(mInvalidDisplayId, layer);
+
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+ EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, DestroyLayerBadLayerError) {
+ // We haven't created any layers yet, so any id should be invalid
+ const auto error = mComposerClient->destroyLayer(mPrimaryDisplay, 1);
+
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_LAYER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetActiveConfigBadDisplay) {
+ int32_t config;
+ const auto error = mComposerClient->getActiveConfig(mInvalidDisplayId, &config);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayConfig) {
+ std::vector<int32_t> configs;
+ EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayConfigBadDisplay) {
+ std::vector<int32_t> configs;
+ const auto error = mComposerClient->getDisplayConfigs(mInvalidDisplayId, &configs);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayName) {
+ std::string displayName;
+ EXPECT_TRUE(mComposerClient->getDisplayName(mPrimaryDisplay, &displayName).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) {
+ EXPECT_TRUE(
+ mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetActiveConfig) {
+ std::vector<int32_t> configs;
+ EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+ for (auto config : configs) {
+ EXPECT_TRUE(mComposerClient->setActiveConfig(mPrimaryDisplay, config).isOk());
+ int32_t config1;
+ EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &config1).isOk());
+ EXPECT_EQ(config, config1);
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetActiveConfigPowerCycle) {
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk());
+
+ std::vector<int32_t> configs;
+ EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+ for (auto config : configs) {
+ EXPECT_TRUE(mComposerClient->setActiveConfig(mPrimaryDisplay, config).isOk());
+ int32_t config1;
+ EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &config1).isOk());
+ EXPECT_EQ(config, config1);
+
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk());
+ EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &config1).isOk());
+ EXPECT_EQ(config, config1);
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDozeSupportBadDisplay) {
+ bool isDozeSupport;
+ const auto error = mComposerClient->getDozeSupport(mInvalidDisplayId, &isDozeSupport);
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
+ bool isDozeSupported;
+ mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk();
+ if (!isDozeSupported) {
+ auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+
+ error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE_SUSPEND);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, SetVsyncEnabled) {
+ mComposerCallback->setVsyncAllowed(true);
+
+ EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, true).isOk());
+ usleep(60 * 1000);
+ EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
+
+ mComposerCallback->setVsyncAllowed(false);
+}
+
TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
std::vector<PowerMode> modes;
modes.push_back(PowerMode::OFF);
modes.push_back(PowerMode::ON_SUSPEND);
modes.push_back(PowerMode::ON);
+ bool isDozeSupported;
+ EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+ if (isDozeSupported) {
+ modes.push_back(PowerMode::DOZE);
+ modes.push_back(PowerMode::DOZE_SUSPEND);
+ }
+
for (auto mode : modes) {
- setPowerMode(mPrimaryDisplay, mode);
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
}
}
@@ -1205,49 +1063,48 @@
std::vector<PowerMode> modes;
modes.push_back(PowerMode::OFF);
+ modes.push_back(PowerMode::ON);
modes.push_back(PowerMode::OFF);
-
for (auto mode : modes) {
- setPowerMode(mPrimaryDisplay, mode);
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
}
+ modes.clear();
+ modes.push_back(PowerMode::OFF);
+ modes.push_back(PowerMode::OFF);
+ for (auto mode : modes) {
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+ }
modes.clear();
modes.push_back(PowerMode::ON);
modes.push_back(PowerMode::ON);
-
for (auto mode : modes) {
- setPowerMode(mPrimaryDisplay, mode);
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
}
-
modes.clear();
modes.push_back(PowerMode::ON_SUSPEND);
modes.push_back(PowerMode::ON_SUSPEND);
-
for (auto mode : modes) {
- setPowerMode(mPrimaryDisplay, mode);
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
}
+ modes.clear();
bool isDozeSupported = false;
ASSERT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
if (isDozeSupported) {
- modes.clear();
-
modes.push_back(PowerMode::DOZE);
modes.push_back(PowerMode::DOZE);
-
for (auto mode : modes) {
- setPowerMode(mPrimaryDisplay, mode);
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
}
-
modes.clear();
modes.push_back(PowerMode::DOZE_SUSPEND);
modes.push_back(PowerMode::DOZE_SUSPEND);
-
for (auto mode : modes) {
- setPowerMode(mPrimaryDisplay, mode);
+ EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
}
}
}
@@ -1266,25 +1123,12 @@
ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
}
-TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
- bool isDozeSupported = false;
- EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
- if (!isDozeSupported) {
- auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
- EXPECT_FALSE(error.isOk());
- EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
-
- error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE_SUSPEND);
- EXPECT_FALSE(error.isOk());
- EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
- }
-}
-
TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix) {
std::vector<float> matrix;
EXPECT_TRUE(
mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::SRGB_LINEAR, &matrix)
.isOk());
+
// the last row is known
ASSERT_EQ(0.0f, matrix[12]);
ASSERT_EQ(0.0f, matrix[13]);
@@ -1301,6 +1145,774 @@
EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
}
+// Tests for Command.
+class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
+ protected:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::SetUp());
+
+ mWriter = std::make_unique<CommandWriterBase>(1024);
+ mReader = std::make_unique<TestCommandReader>();
+ }
+
+ void TearDown() override {
+ ASSERT_EQ(0, mReader->mErrors.size());
+ ASSERT_EQ(0, mReader->mCompositionChanges.size());
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
+ }
+
+ void execute() {
+ TestCommandReader* reader = mReader.get();
+ CommandWriterBase* writer = mWriter.get();
+ bool queueChanged = false;
+ int32_t commandLength = 0;
+ std::vector<NativeHandle> commandHandles;
+ ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+ if (queueChanged) {
+ auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
+ ASSERT_TRUE(ret.isOk());
+ }
+
+ ExecuteCommandsStatus commandStatus;
+ EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
+ .isOk());
+
+ if (commandStatus.queueChanged) {
+ MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
+ ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
+ reader->setMQDescriptor(outputCommandQueue);
+ }
+ ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
+ reader->parse();
+ reader->reset();
+ writer->reset();
+ }
+
+ static inline auto toTimePoint(nsecs_t time) {
+ return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
+ }
+
+ void setActiveConfig(VtsDisplay& display, int32_t config) {
+ EXPECT_TRUE(mComposerClient->setActiveConfig(display.get(), config).isOk());
+ int32_t displayWidth;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH,
+ &displayWidth)
+ .isOk());
+ int32_t displayHeight;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT,
+ &displayHeight)
+ .isOk());
+ display.setDimensions(displayWidth, displayHeight);
+ }
+
+ void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
+ std::vector<int32_t> displayConfigs;
+ EXPECT_TRUE(mComposerClient->getDisplayConfigs(display, &displayConfigs).isOk());
+ for (const int32_t config1 : displayConfigs) {
+ for (const int32_t config2 : displayConfigs) {
+ if (config1 != config2) {
+ func(config1, config2);
+ }
+ }
+ }
+ }
+
+ void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
+ int64_t desiredTimeNanos, int64_t oldPeriodNanos,
+ int64_t newPeriodNanos) {
+ const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
+ while (std::chrono::steady_clock::now() <= kChangeDeadline) {
+ int32_t vsyncPeriodNanos;
+ EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos).isOk());
+ if (systemTime() <= desiredTimeNanos) {
+ EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
+ } else if (vsyncPeriodNanos == newPeriodNanos) {
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
+ }
+ }
+
+ sp<GraphicBuffer> allocate() {
+ return sp<GraphicBuffer>::make(
+ static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight),
+ ::android::PIXEL_FORMAT_RGBA_8888,
+ /*layerCount*/ 1,
+ (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");
+ }
+
+ void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
+ if (timeline != nullptr) {
+ // Refresh time should be before newVsyncAppliedTimeNanos
+ EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
+
+ std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
+ }
+
+ mWriter->selectDisplay(display.get());
+ EXPECT_TRUE(mComposerClient->setPowerMode(display.get(), PowerMode::ON).isOk());
+ EXPECT_TRUE(
+ mComposerClient
+ ->setColorMode(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ int64_t layer = 0;
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer(display));
+ {
+ auto buffer = allocate();
+ ASSERT_NE(nullptr, buffer);
+ ASSERT_EQ(::android::OK, buffer->initCheck());
+ ASSERT_NE(nullptr, buffer->handle);
+
+ mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(Composition::DEVICE);
+ mWriter->setLayerDisplayFrame(display.getFrameRect());
+ mWriter->setLayerPlaneAlpha(1);
+ mWriter->setLayerSourceCrop(display.getCrop());
+ mWriter->setLayerTransform(static_cast<Transform>(0));
+ mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
+ mWriter->setLayerZOrder(10);
+ mWriter->setLayerBlendMode(BlendMode::NONE);
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
+ mWriter->setLayerBuffer(0, buffer->handle, -1);
+ mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
+
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mReader->mCompositionChanges.clear();
+
+ mWriter->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ }
+
+ {
+ auto buffer = allocate();
+ ASSERT_NE(nullptr, buffer->handle);
+
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBuffer(0, buffer->handle, -1);
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
+ mWriter->validateDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+ mReader->mCompositionChanges.clear();
+
+ mWriter->presentDisplay();
+ execute();
+ }
+
+ ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
+ }
+
+ void Test_setActiveConfigWithConstraints(const TestParameters& params) {
+ for (VtsDisplay& display : mDisplays) {
+ forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+ setActiveConfig(display, config1);
+ sendRefreshFrame(display, nullptr);
+
+ int32_t vsyncPeriod1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config1,
+ DisplayAttribute::VSYNC_PERIOD,
+ &vsyncPeriod1)
+ .isOk());
+ int32_t configGroup1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config1,
+ DisplayAttribute::CONFIG_GROUP,
+ &configGroup1)
+ .isOk());
+ int32_t vsyncPeriod2;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config2,
+ DisplayAttribute::VSYNC_PERIOD,
+ &vsyncPeriod2)
+ .isOk());
+ int32_t configGroup2;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config2,
+ DisplayAttribute::CONFIG_GROUP,
+ &configGroup2)
+ .isOk());
+
+ if (vsyncPeriod1 == vsyncPeriod2) {
+ return; // continue
+ }
+
+ // We don't allow delayed change when changing config groups
+ if (params.delayForChange > 0 && configGroup1 != configGroup2) {
+ return; // continue
+ }
+
+ VsyncPeriodChangeTimeline timeline;
+ VsyncPeriodChangeConstraints constraints = {
+ .desiredTimeNanos = systemTime() + params.delayForChange,
+ .seamlessRequired = false};
+ EXPECT_TRUE(setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+ .isOk());
+
+ EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
+ // Refresh rate should change within a reasonable time
+ constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s; // 1 second
+ EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
+ kReasonableTimeForChange.count());
+
+ if (timeline.refreshRequired) {
+ if (params.refreshMiss) {
+ // Miss the refresh frame on purpose to make sure the implementation sends a
+ // callback
+ std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
+ 100ms);
+ }
+ sendRefreshFrame(display, &timeline);
+ }
+ waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
+ vsyncPeriod1, vsyncPeriod2);
+
+ // At this point the refresh rate should have changed already, however in rare
+ // cases the implementation might have missed the deadline. In this case a new
+ // timeline should have been provided.
+ auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
+ if (timeline.refreshRequired && params.refreshMiss) {
+ EXPECT_TRUE(newTimeline.has_value());
+ }
+
+ if (newTimeline.has_value()) {
+ if (newTimeline->refreshRequired) {
+ sendRefreshFrame(display, &newTimeline.value());
+ }
+ waitForVsyncPeriodChange(display.get(), newTimeline.value(),
+ constraints.desiredTimeNanos, vsyncPeriod1,
+ vsyncPeriod2);
+ }
+
+ int32_t vsyncPeriodNanos;
+ EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+ .isOk());
+ EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
+ });
+ }
+ }
+
+ // clang-format off
+ const std::array<float, 16> kIdentity = {{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f,
+ }};
+ // clang-format on
+
+ std::unique_ptr<CommandWriterBase> mWriter;
+ std::unique_ptr<TestCommandReader> mReader;
+};
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->setColorTransform(kIdentity.data(), ColorTransform::IDENTITY);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerColorTransform(kIdentity.data());
+ execute();
+
+ if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "setLayerColorTransform is not supported";
+ return;
+ }
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_CLIENT_TARGET) {
+ EXPECT_TRUE(
+ mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN, std::vector<Rect>());
+
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_OUTPUT_BUFFER) {
+ int32_t virtualDisplayCount;
+ EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&virtualDisplayCount).isOk());
+ if (virtualDisplayCount == 0) {
+ GTEST_SUCCEED() << "no virtual display support";
+ return;
+ }
+
+ VirtualDisplay display;
+ EXPECT_TRUE(mComposerClient
+ ->createVirtualDisplay(64, 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
+ kBufferSlotCount, &display)
+ .isOk());
+
+ mWriter->selectDisplay(display.display);
+ auto handle = allocate()->handle;
+ mWriter->setOutputBuffer(0, handle, -1);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, VALIDATE_DISPLAY) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->validateDisplay();
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->validateDisplay();
+ mWriter->acceptDisplayChanges();
+ execute();
+}
+
+// TODO(b/208441745) fix the test failure
+TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) {
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->validateDisplay();
+ mWriter->presentDisplay();
+ execute();
+}
+
+/**
+ * Test IComposerClient::Command::PRESENT_DISPLAY
+ *
+ * Test that IComposerClient::Command::PRESENT_DISPLAY works without
+ * additional call to validateDisplay when only the layer buffer handle and
+ * surface damage have been set
+ */
+// TODO(b/208441745) fix the test failure
+TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) {
+ std::vector<Capability> capabilities;
+ EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk());
+ if (none_of(capabilities.begin(), capabilities.end(),
+ [&](auto item) { return item == Capability::SKIP_VALIDATE; })) {
+ GTEST_SUCCEED() << "Device does not have skip validate capability, skipping";
+ return;
+ }
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
+
+ std::vector<RenderIntent> renderIntents;
+ mComposerClient->getRenderIntents(mPrimaryDisplay, ColorMode::NATIVE, &renderIntents);
+ for (auto intent : renderIntents) {
+ mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE, intent);
+
+ auto handle = allocate()->handle;
+ ASSERT_NE(nullptr, handle);
+
+ Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+ mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(Composition::DEVICE);
+ mWriter->setLayerDisplayFrame(displayFrame);
+ mWriter->setLayerPlaneAlpha(1);
+ mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+ mWriter->setLayerTransform(static_cast<Transform>(0));
+ mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
+ mWriter->setLayerZOrder(10);
+ mWriter->setLayerBlendMode(BlendMode::NONE);
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
+ mWriter->setLayerBuffer(0, handle, -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->presentDisplay();
+ execute();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->selectLayer(layer);
+ auto handle2 = allocate()->handle;
+ ASSERT_NE(nullptr, handle2);
+ mWriter->setLayerBuffer(0, handle2, -1);
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
+ mWriter->presentDisplay();
+ execute();
+ }
+}
+
+// TODO(b/208441745) fix the test failure
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_CURSOR_POSITION) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ auto handle = allocate()->handle;
+ ASSERT_NE(nullptr, handle);
+ Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBuffer(0, handle, -1);
+ mWriter->setLayerCompositionType(Composition::CURSOR);
+ mWriter->setLayerDisplayFrame(displayFrame);
+ mWriter->setLayerPlaneAlpha(1);
+ mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+ mWriter->setLayerTransform(static_cast<Transform>(0));
+ mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
+ mWriter->setLayerZOrder(10);
+ mWriter->setLayerBlendMode(BlendMode::NONE);
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
+ mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ mWriter->validateDisplay();
+
+ execute();
+ if (mReader->mCompositionChanges.size() != 0) {
+ GTEST_SUCCEED() << "Composition change requested, skipping test";
+ return;
+ }
+ mWriter->presentDisplay();
+ ASSERT_EQ(0, mReader->mErrors.size());
+
+ mWriter->setLayerCursorPosition(1, 1);
+ mWriter->setLayerCursorPosition(0, 0);
+ mWriter->validateDisplay();
+ mWriter->presentDisplay();
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BUFFER) {
+ auto handle = allocate()->handle;
+ ASSERT_NE(nullptr, handle);
+
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBuffer(0, handle, -1);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SURFACE_DAMAGE) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ Rect empty{0, 0, 0, 0};
+ Rect unit{0, 0, 1, 1};
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, empty));
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, unit));
+ mWriter->setLayerSurfaceDamage(std::vector<Rect>());
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerBlendMode(BlendMode::NONE);
+ mWriter->setLayerBlendMode(BlendMode::PREMULTIPLIED);
+ mWriter->setLayerBlendMode(BlendMode::COVERAGE);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerColor(Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+ static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
+ mWriter->setLayerColor(Color{0, 0, 0, 0});
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerCompositionType(Composition::CLIENT);
+ mWriter->setLayerCompositionType(Composition::DEVICE);
+ mWriter->setLayerCompositionType(Composition::SOLID_COLOR);
+ mWriter->setLayerCompositionType(Composition::CURSOR);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DATASPACE) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DISPLAY_FRAME) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerDisplayFrame(Rect{0, 0, 1, 1});
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PLANE_ALPHA) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerPlaneAlpha(0.0f);
+ mWriter->setLayerPlaneAlpha(1.0f);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
+ std::vector<Capability> capabilities;
+ EXPECT_TRUE(mComposer->getCapabilities(&capabilities).isOk());
+ if (none_of(capabilities.begin(), capabilities.end(),
+ [&](auto& item) { return item == Capability::SIDEBAND_STREAM; })) {
+ GTEST_SUCCEED() << "no sideband stream support";
+ return;
+ }
+
+ auto handle = allocate()->handle;
+ ASSERT_NE(nullptr, handle);
+
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerSidebandStream(handle);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SOURCE_CROP) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerSourceCrop(FRect{0.0f, 0.0f, 1.0f, 1.0f});
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_TRANSFORM) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerTransform(static_cast<Transform>(0));
+ mWriter->setLayerTransform(Transform::FLIP_H);
+ mWriter->setLayerTransform(Transform::FLIP_V);
+ mWriter->setLayerTransform(Transform::ROT_90);
+ mWriter->setLayerTransform(Transform::ROT_180);
+ mWriter->setLayerTransform(Transform::ROT_270);
+ mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+ static_cast<int>(Transform::ROT_90)));
+ mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+ static_cast<int>(Transform::ROT_90)));
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_VISIBLE_REGION) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ Rect empty{0, 0, 0, 0};
+ Rect unit{0, 0, 1, 1};
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerVisibleRegion(std::vector<Rect>(1, empty));
+ mWriter->setLayerVisibleRegion(std::vector<Rect>(1, unit));
+ mWriter->setLayerVisibleRegion(std::vector<Rect>());
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_Z_ORDER) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+ mWriter->setLayerZOrder(10);
+ mWriter->setLayerZOrder(0);
+ execute();
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
+ int64_t layer;
+ EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+ mWriter->selectDisplay(mPrimaryDisplay);
+ mWriter->selectLayer(layer);
+
+ /**
+ * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
+ * the D65 white point and the SRGB transfer functions.
+ * Rendering Intent: Colorimetric
+ * Primaries:
+ * x y
+ * green 0.265 0.690
+ * blue 0.150 0.060
+ * red 0.680 0.320
+ * white (D65) 0.3127 0.3290
+ */
+
+ std::vector<PerFrameMetadata> aidlMetadata;
+ aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
+ aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
+ aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265f});
+ aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690f});
+ aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150f});
+ aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060f});
+ aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_X, 0.3127f});
+ aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_Y, 0.3290f});
+ aidlMetadata.push_back({PerFrameMetadataKey::MAX_LUMINANCE, 100.0f});
+ 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(aidlMetadata);
+ execute();
+
+ if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
+ mReader->mErrors.clear();
+ GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
+ EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+ return;
+ }
+
+ EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints) {
+ Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints_Delayed) {
+ Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
+ .refreshMiss = false});
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints_MissRefresh) {
+ Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, getDisplayVsyncPeriod) {
+ for (VtsDisplay& display : mDisplays) {
+ std::vector<int32_t> configs;
+ EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+ for (int32_t config : configs) {
+ int32_t expectedVsyncPeriodNanos = -1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config,
+ DisplayAttribute::VSYNC_PERIOD,
+ &expectedVsyncPeriodNanos)
+ .isOk());
+
+ VsyncPeriodChangeTimeline timeline;
+ VsyncPeriodChangeConstraints constraints;
+
+ constraints.desiredTimeNanos = systemTime();
+ constraints.seamlessRequired = false;
+ EXPECT_TRUE(mComposerClient
+ ->setActiveConfigWithConstraints(display.get(), config, constraints,
+ &timeline)
+ .isOk());
+
+ if (timeline.refreshRequired) {
+ sendRefreshFrame(display, &timeline);
+ }
+ waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
+ expectedVsyncPeriodNanos);
+
+ int32_t vsyncPeriodNanos;
+ int retryCount = 100;
+ do {
+ std::this_thread::sleep_for(10ms);
+ vsyncPeriodNanos = 0;
+ EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+ .isOk());
+ --retryCount;
+ } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
+
+ EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+
+ // Make sure that the vsync period stays the same if the active config is not
+ // changed.
+ auto timeout = 1ms;
+ for (int i = 0; i < 10; i++) {
+ std::this_thread::sleep_for(timeout);
+ timeout *= 2;
+ vsyncPeriodNanos = 0;
+ EXPECT_TRUE(mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)
+ .isOk());
+ EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+ }
+ }
+ }
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
+ VsyncPeriodChangeTimeline timeline;
+ VsyncPeriodChangeConstraints constraints;
+
+ constraints.seamlessRequired = true;
+ constraints.desiredTimeNanos = systemTime();
+
+ for (VtsDisplay& display : mDisplays) {
+ forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
+ int32_t configGroup1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config1,
+ DisplayAttribute::CONFIG_GROUP, &configGroup1)
+ .isOk());
+ int32_t configGroup2;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config2,
+ DisplayAttribute::CONFIG_GROUP, &configGroup2)
+ .isOk());
+ if (configGroup1 != configGroup2) {
+ setActiveConfig(display, config1);
+ sendRefreshFrame(display, nullptr);
+ EXPECT_EQ(IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
+ setActiveConfigWithConstraints(display, config2, constraints, &timeline)
+ .getServiceSpecificError());
+ }
+ });
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerAidlCommandTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+ ::android::PrintInstanceNameToString);
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsComposerAidlTest,
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index 00ea4f3..2b058c7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -29,6 +29,8 @@
srcs: [
"GraphicsComposerCallback.cpp",
"TestCommandReader.cpp",
+ "ReadbackVts.cpp",
+ "RenderEngineVts.cpp",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
@@ -38,20 +40,32 @@
"android.hardware.graphics.common-V3-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
+ "libarect",
"libgtest",
"libbase",
"libfmq",
"libsync",
+ "libmath",
"libaidlcommonsupport",
+ "libnativewindow",
+ "librenderengine",
+ "libshaders",
+ "libtonemap",
"android.hardware.graphics.mapper@2.0-vts",
+ "android.hardware.graphics.mapper@2.1-vts",
"android.hardware.graphics.mapper@3.0-vts",
"android.hardware.graphics.mapper@4.0-vts",
],
shared_libs: [
"libbinder_ndk",
"libhidlbase",
+ "libui",
"android.hardware.graphics.composer3-V1-ndk",
],
+ export_static_lib_headers: [
+ "android.hardware.graphics.mapper@2.1-vts",
+ "librenderengine",
+ ],
cflags: [
"-O0",
"-g",
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp
index daf9924..307fe15 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/GraphicsComposerCallback.cpp
@@ -125,12 +125,4 @@
return ::ndk::ScopedAStatus::ok();
}
-::ndk::SpAIBinder GraphicsComposerCallback::asBinder() {
- return nullptr;
-}
-
-bool GraphicsComposerCallback::isRemote() {
- return true;
-}
-
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
new file mode 100644
index 0000000..b612309
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
@@ -0,0 +1,360 @@
+/**
+ * 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.
+ */
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include "include/ReadbackVts.h"
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include "include/RenderEngineVts.h"
+#include "renderengine/ExternalTexture.h"
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
+const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
+ common::Dataspace::DISPLAY_P3};
+
+void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+ writer->selectLayer(mLayer);
+ writer->setLayerDisplayFrame(mDisplayFrame);
+ writer->setLayerSourceCrop(mSourceCrop);
+ writer->setLayerZOrder(mZOrder);
+ writer->setLayerSurfaceDamage(mSurfaceDamage);
+ writer->setLayerTransform(mTransform);
+ writer->setLayerPlaneAlpha(mAlpha);
+ writer->setLayerBlendMode(mBlendMode);
+}
+
+std::string ReadbackHelper::getColorModeString(ColorMode mode) {
+ switch (mode) {
+ case ColorMode::SRGB:
+ return {"SRGB"};
+ case ColorMode::DISPLAY_P3:
+ return {"DISPLAY_P3"};
+ default:
+ return {"Unsupported color mode for readback"};
+ }
+}
+
+std::string ReadbackHelper::getDataspaceString(common::Dataspace dataspace) {
+ switch (dataspace) {
+ case common::Dataspace::SRGB:
+ return {"SRGB"};
+ case common::Dataspace::DISPLAY_P3:
+ return {"DISPLAY_P3"};
+ case common::Dataspace::UNKNOWN:
+ return {"UNKNOWN"};
+ default:
+ return {"Unsupported dataspace for readback"};
+ }
+}
+
+Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
+ switch (mode) {
+ case ColorMode::DISPLAY_P3:
+ return Dataspace::DISPLAY_P3;
+ case ColorMode::SRGB:
+ default:
+ return common::Dataspace::UNKNOWN;
+ }
+}
+
+LayerSettings TestLayer::toRenderEngineLayerSettings() {
+ LayerSettings layerSettings;
+
+ layerSettings.alpha = ::android::half(mAlpha);
+ layerSettings.disableBlending = mBlendMode == BlendMode::NONE;
+ layerSettings.geometry.boundaries = ::android::FloatRect(
+ static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
+ static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
+
+ const ::android::mat4 translation = ::android::mat4::translate(::android::vec4(
+ (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H)
+ ? static_cast<float>(-mDisplayFrame.right)
+ : 0.0f),
+ (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V)
+ ? static_cast<float>(-mDisplayFrame.bottom)
+ : 0.0f),
+ 0.0f, 1.0f));
+
+ const ::android::mat4 scale = ::android::mat4::scale(::android::vec4(
+ static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H) ? -1.0f
+ : 1.0f,
+ static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V) ? -1.0f
+ : 1.0f,
+ 1.0f, 1.0f));
+
+ layerSettings.geometry.positionTransform = scale * translation;
+
+ return layerSettings;
+}
+
+int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
+ switch (pixelFormat) {
+ case common::PixelFormat::RGBA_8888:
+ return 4;
+ case common::PixelFormat::RGB_888:
+ return 3;
+ default:
+ return -1;
+ }
+}
+
+void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
+ common::PixelFormat pixelFormat,
+ std::vector<Color> desiredPixelColors) {
+ ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
+ pixelFormat == common::PixelFormat::RGBA_8888);
+ int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+ ASSERT_NE(-1, bytesPerPixel);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ auto pixel = row * static_cast<int32_t>(width) + col;
+ Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
+
+ int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
+ uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+ pixelColor[0] = static_cast<uint8_t>(srcColor.r);
+ pixelColor[1] = static_cast<uint8_t>(srcColor.g);
+ pixelColor[2] = static_cast<uint8_t>(srcColor.b);
+
+ if (bytesPerPixel == 4) {
+ pixelColor[3] = static_cast<uint8_t>(srcColor.a);
+ }
+ }
+ }
+}
+
+void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
+ int32_t displayWidth) {
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ int pixel = row * displayWidth + col;
+ expectedColors[static_cast<size_t>(pixel)] = BLACK;
+ }
+ }
+}
+
+void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
+ Color color) {
+ for (int row = area.top; row < area.bottom; row++) {
+ for (int col = area.left; col < area.right; col++) {
+ int pixel = row * stride + col;
+ expectedColors[static_cast<size_t>(pixel)] = color;
+ }
+ }
+}
+
+bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
+ const common::Dataspace& dataspace) {
+ if (pixelFormat != common::PixelFormat::RGB_888 &&
+ pixelFormat != common::PixelFormat::RGBA_8888) {
+ return false;
+ }
+ if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
+ return false;
+ }
+ return true;
+}
+
+void ReadbackHelper::compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData,
+ const int32_t stride, const uint32_t width,
+ const uint32_t height, common::PixelFormat pixelFormat) {
+ const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
+ ASSERT_NE(-1, bytesPerPixel);
+ for (int row = 0; row < height; row++) {
+ for (int col = 0; col < width; col++) {
+ auto pixel = row * static_cast<int32_t>(width) + col;
+ int offset = (row * stride + col) * bytesPerPixel;
+ uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+
+ ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].r),
+ pixelColor[0]);
+ ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].g),
+ pixelColor[1]);
+ ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].b),
+ pixelColor[2]);
+ }
+ }
+}
+
+ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client,
+ const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
+ int32_t width, int32_t height, common::PixelFormat pixelFormat,
+ common::Dataspace dataspace) {
+ mDisplay = display;
+
+ mComposerClient = client;
+ mGraphicBuffer = graphicBuffer;
+
+ mPixelFormat = pixelFormat;
+ mDataspace = dataspace;
+
+ mWidth = static_cast<uint32_t>(width);
+ mHeight = static_cast<uint32_t>(height);
+ mLayerCount = 1;
+ mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
+
+ mAccessRegion.top = 0;
+ mAccessRegion.left = 0;
+ mAccessRegion.right = static_cast<int32_t>(width);
+ mAccessRegion.bottom = static_cast<int32_t>(height);
+}
+
+::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocate() {
+ return ::android::sp<::android::GraphicBuffer>::make(
+ mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
+ "ReadbackVts");
+}
+
+void ReadbackBuffer::setReadbackBuffer() {
+ mGraphicBuffer = allocate();
+ ASSERT_NE(nullptr, mGraphicBuffer);
+ ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+ aidl::android::hardware::common::NativeHandle bufferHandle =
+ ::android::dupToAidl(mGraphicBuffer->handle);
+ ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
+ EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
+}
+
+void ReadbackBuffer::checkReadbackBuffer(std::vector<Color> expectedColors) {
+ // lock buffer for reading
+ ndk::ScopedFileDescriptor fenceHandle;
+ EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle).isOk());
+
+ int outBytesPerPixel;
+ int outBytesPerStride;
+ auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, nullptr, fenceHandle.get(),
+ &outBytesPerPixel, &outBytesPerStride);
+ EXPECT_EQ(::android::OK, status);
+ ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+ ReadbackHelper::compareColorBuffers(expectedColors, mGraphicBuffer.get(),
+ static_cast<int32_t>(mStride), mWidth, mHeight,
+ mPixelFormat);
+ status = mGraphicBuffer->unlock();
+ EXPECT_EQ(::android::OK, status);
+}
+
+void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+ TestLayer::write(writer);
+ writer->setLayerCompositionType(Composition::SOLID_COLOR);
+ writer->setLayerColor(mColor);
+}
+
+LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
+ LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
+
+ layerSettings.source.solidColor =
+ ::android::half3(static_cast<::android::half>(mColor.r) / 255.0,
+ static_cast<::android::half>(mColor.g) / 255.0,
+ static_cast<::android::half>(mColor.b) / 255.0);
+ layerSettings.alpha =
+ mAlpha * static_cast<float>((static_cast<::android::half>(mColor.a) / 255.0));
+ return layerSettings;
+}
+
+TestBufferLayer::TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
+ const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
+ TestRenderEngine& renderEngine, int64_t display, uint32_t width,
+ uint32_t height, common::PixelFormat format,
+ Composition composition)
+ : TestLayer{client, display}, mRenderEngine(renderEngine) {
+ mGraphicBuffer = graphicBuffer;
+ mComposition = composition;
+ mWidth = width;
+ mHeight = height;
+ mLayerCount = 1;
+ mPixelFormat = format;
+ mUsage = (static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+ static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY) |
+ static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
+
+ mAccessRegion.top = 0;
+ mAccessRegion.left = 0;
+ mAccessRegion.right = static_cast<int32_t>(width);
+ mAccessRegion.bottom = static_cast<int32_t>(height);
+
+ setSourceCrop({0, 0, (float)width, (float)height});
+}
+
+void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+ TestLayer::write(writer);
+ writer->setLayerCompositionType(mComposition);
+ writer->setLayerVisibleRegion(std::vector<Rect>(1, mDisplayFrame));
+ if (mGraphicBuffer->handle != nullptr)
+ writer->setLayerBuffer(0, mGraphicBuffer->handle, mFillFence);
+}
+
+LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
+ LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
+ layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::ExternalTexture>(
+ ::android::sp<::android::GraphicBuffer>::make(
+ mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
+ static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride),
+ mRenderEngine.getInternalRenderEngine(),
+ ::android::renderengine::ExternalTexture::Usage::READABLE);
+
+ layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
+
+ const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (static_cast<float>(mWidth));
+ const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (static_cast<float>(mHeight));
+ const float translateX = mSourceCrop.left / (static_cast<float>(mWidth));
+ const float translateY = mSourceCrop.top / (static_cast<float>(mHeight));
+
+ layerSettings.source.buffer.textureTransform =
+ ::android::mat4::translate(::android::vec4(translateX, translateY, 0, 1)) *
+ ::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0, 1.0));
+
+ return layerSettings;
+}
+
+void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) {
+ void* bufData;
+ auto status = mGraphicBuffer->lock(mUsage, &bufData);
+ EXPECT_EQ(::android::OK, status);
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData,
+ mPixelFormat, expectedColors));
+ EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+}
+
+void TestBufferLayer::setBuffer(std::vector<Color> colors) {
+ mGraphicBuffer->reallocate(mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat),
+ mLayerCount, mUsage);
+ ASSERT_NE(nullptr, mGraphicBuffer);
+ ASSERT_NE(nullptr, mGraphicBuffer->handle);
+ ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+ ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+}
+
+void TestBufferLayer::setDataspace(common::Dataspace dataspace,
+ const std::shared_ptr<CommandWriterBase>& writer) {
+ writer->selectLayer(mLayer);
+ writer->setLayerDataspace(dataspace);
+}
+
+void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
+ writer->selectLayer(mLayer);
+ writer->setLayerCompositionType(Composition::CLIENT);
+}
+
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
new file mode 100644
index 0000000..e83750e
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
@@ -0,0 +1,89 @@
+/**
+ * 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 "include/RenderEngineVts.h"
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using ::android::hardware::graphics::mapper::V2_1::IMapper;
+using ::android::renderengine::DisplaySettings;
+using ::android::renderengine::LayerSettings;
+using ::android::renderengine::RenderEngineCreationArgs;
+
+TestRenderEngine::TestRenderEngine(const RenderEngineCreationArgs& args) {
+ mFormat = static_cast<common::PixelFormat>(args.pixelFormat);
+ mRenderEngine = ::android::renderengine::RenderEngine::create(args);
+}
+
+TestRenderEngine::~TestRenderEngine() {
+ mRenderEngine.release();
+}
+
+void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
+ sort(layers.begin(), layers.end(),
+ [](const std::shared_ptr<TestLayer>& lhs, const std::shared_ptr<TestLayer>& rhs) -> bool {
+ return lhs->getZOrder() < rhs->getZOrder();
+ });
+
+ if (!mCompositionLayers.empty()) {
+ mCompositionLayers.clear();
+ }
+ for (auto& layer : layers) {
+ LayerSettings settings = layer->toRenderEngineLayerSettings();
+ mCompositionLayers.push_back(settings);
+ }
+}
+
+void TestRenderEngine::initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
+ uint64_t usage) {
+ mGraphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
+ width, height, static_cast<int32_t>(mFormat), layerCount, usage);
+}
+
+void TestRenderEngine::drawLayers() {
+ ::android::base::unique_fd bufferFence;
+
+ std::vector<::android::renderengine::LayerSettings> compositionLayers;
+ compositionLayers.reserve(mCompositionLayers.size());
+ std::transform(mCompositionLayers.begin(), mCompositionLayers.end(),
+ std::back_insert_iterator(compositionLayers),
+ [](::android::renderengine::LayerSettings& settings)
+ -> ::android::renderengine::LayerSettings { return settings; });
+ auto texture = std::make_shared<::android::renderengine::ExternalTexture>(
+ mGraphicBuffer, *mRenderEngine,
+ ::android::renderengine::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));
+ }
+}
+
+void TestRenderEngine::checkColorBuffer(std::vector<Color>& expectedColors) {
+ void* bufferData;
+ ASSERT_EQ(0,
+ mGraphicBuffer->lock(static_cast<uint32_t>(mGraphicBuffer->getUsage()), &bufferData));
+ ReadbackHelper::compareColorBuffers(
+ expectedColors, bufferData, static_cast<int32_t>(mGraphicBuffer->getStride()),
+ mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(), mFormat);
+ ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
+}
+
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
index 0346686..a5a84d9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
@@ -37,15 +37,15 @@
auto command = static_cast<Command>(commandRaw);
switch (command) {
- case Command::SET_CLIENT_TARGET_PROPERTY:
+ case Command::SET_CLIENT_TARGET_PROPERTY: {
ASSERT_EQ(2, length);
read();
close(readFence());
- break;
- case Command::SELECT_DISPLAY:
+ } break;
+ case Command::SELECT_DISPLAY: {
ASSERT_EQ(2, length);
read64(); // display
- break;
+ } break;
case Command::SET_ERROR: {
ASSERT_EQ(2, length);
auto loc = read();
@@ -53,7 +53,7 @@
std::pair<uint32_t, uint32_t> error(loc, err);
mErrors.push_back(error);
} break;
- case Command::SET_CHANGED_COMPOSITION_TYPES:
+ case Command::SET_CHANGED_COMPOSITION_TYPES: {
ASSERT_EQ(0, length % 3);
for (uint16_t count = 0; count < length / 3; ++count) {
uint64_t layerId = read64();
@@ -62,8 +62,8 @@
std::pair<uint64_t, uint32_t> compositionChange(layerId, composition);
mCompositionChanges.push_back(compositionChange);
}
- break;
- case Command::SET_DISPLAY_REQUESTS:
+ } break;
+ case Command::SET_DISPLAY_REQUESTS: {
ASSERT_EQ(1, length % 3);
read(); // displayRequests, ignored for now
for (uint16_t count = 0; count < (length - 1) / 3; ++count) {
@@ -72,18 +72,18 @@
// client composition anyway
ASSERT_EQ(1u, read());
}
- break;
- case Command::SET_PRESENT_FENCE:
+ } break;
+ case Command::SET_PRESENT_FENCE: {
ASSERT_EQ(1, length);
close(readFence());
- break;
- case Command::SET_RELEASE_FENCES:
+ } break;
+ case Command::SET_RELEASE_FENCES: {
ASSERT_EQ(0, length % 3);
for (uint16_t count = 0; count < length / 3; ++count) {
read64();
close(readFence());
}
- break;
+ } break;
default:
GTEST_FAIL() << "unexpected return command " << std::hex << static_cast<int>(command);
break;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
index 02e5151..c359d5e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
@@ -19,7 +19,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
-#include <aidl/android/hardware/graphics/composer3/IComposerCallback.h>
+#include <aidl/android/hardware/graphics/composer3/BnComposerCallback.h>
#include <android-base/thread_annotations.h>
#include <mutex>
#include <unordered_set>
@@ -29,8 +29,7 @@
namespace aidl::android::hardware::graphics::composer3::vts {
-// IComposerCallback to be installed with IComposerClient::registerCallback.
-class GraphicsComposerCallback : public IComposerCallback {
+class GraphicsComposerCallback : public BnComposerCallback {
public:
void setVsyncAllowed(bool allowed);
@@ -59,9 +58,6 @@
const ::aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline&
in_updatedTimeline) override;
- ::ndk::SpAIBinder asBinder() override;
- bool isRemote() override;
-
mutable std::mutex mMutex;
// the set of all currently connected displays
std::unordered_set<int64_t> mDisplays GUARDED_BY(mMutex);
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
new file mode 100644
index 0000000..85b4fdc
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -0,0 +1,214 @@
+/**
+ * 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
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <GraphicsComposerCallback.h>
+#include <TestCommandReader.h>
+#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
+#include <android-base/unique_fd.h>
+#include <android/hardware/graphics/composer3/command-buffer.h>
+#include <mapper-vts/2.1/MapperVts.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
+
+#include <memory>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using ::android::renderengine::LayerSettings;
+using common::Dataspace;
+using common::PixelFormat;
+using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
+
+static const Color BLACK = {0, 0, 0, static_cast<int8_t>(0xff)};
+static const Color RED = {static_cast<int8_t>(0xff), 0, 0, static_cast<int8_t>(0xff)};
+static const Color TRANSLUCENT_RED = {static_cast<int8_t>(0xff), 0, 0, 0x33};
+static const Color GREEN = {0, static_cast<int8_t>(0xff), 0, static_cast<int8_t>(0xff)};
+static const Color BLUE = {0, 0, static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
+static const Color WHITE = {static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+ static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
+
+class TestRenderEngine;
+
+class TestLayer {
+ public:
+ TestLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
+ : mComposerClient(client) {
+ client->createLayer(display, kBufferSlotCount, &mLayer);
+ }
+
+ // ComposerClient will take care of destroying layers, no need to explicitly
+ // call destroyLayers here
+ virtual ~TestLayer(){};
+
+ virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
+ virtual LayerSettings toRenderEngineLayerSettings();
+
+ void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
+ void setSourceCrop(FRect crop) { mSourceCrop = crop; }
+ void setZOrder(uint32_t z) { mZOrder = z; }
+
+ void setSurfaceDamage(std::vector<Rect> surfaceDamage) {
+ mSurfaceDamage = std::move(surfaceDamage);
+ }
+
+ void setTransform(Transform transform) { mTransform = transform; }
+ void setAlpha(float alpha) { mAlpha = alpha; }
+ void setBlendMode(BlendMode blendMode) { mBlendMode = blendMode; }
+
+ BlendMode getBlendMode() const { return mBlendMode; }
+
+ uint32_t getZOrder() const { return mZOrder; }
+
+ float getAlpha() const { return mAlpha; }
+
+ protected:
+ int64_t mLayer;
+ Rect mDisplayFrame = {0, 0, 0, 0};
+ std::vector<Rect> mSurfaceDamage;
+ Transform mTransform = static_cast<Transform>(0);
+ FRect mSourceCrop = {0, 0, 0, 0};
+ static constexpr uint32_t kBufferSlotCount = 64;
+ float mAlpha = 1.0;
+ BlendMode mBlendMode = BlendMode::NONE;
+ uint32_t mZOrder = 0;
+
+ private:
+ std::shared_ptr<IComposerClient> const mComposerClient;
+};
+
+class TestColorLayer : public TestLayer {
+ public:
+ TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
+ : TestLayer{client, display} {}
+
+ void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+
+ LayerSettings toRenderEngineLayerSettings() override;
+
+ void setColor(Color color) { mColor = color; }
+
+ private:
+ Color mColor = WHITE;
+};
+
+class TestBufferLayer : public TestLayer {
+ public:
+ TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
+ const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
+ TestRenderEngine& renderEngine, int64_t display, uint32_t width,
+ uint32_t height, common::PixelFormat format,
+ Composition composition = Composition::DEVICE);
+
+ void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+
+ LayerSettings toRenderEngineLayerSettings() override;
+
+ void fillBuffer(std::vector<Color>& expectedColors);
+
+ void setBuffer(std::vector<Color> colors);
+
+ void setDataspace(Dataspace dataspace, const std::shared_ptr<CommandWriterBase>& writer);
+
+ void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer);
+
+ uint32_t getWidth() const { return mWidth; }
+
+ uint32_t getHeight() const { return mHeight; }
+
+ ::android::Rect getAccessRegion() const { return mAccessRegion; }
+
+ uint32_t getLayerCount() const { return mLayerCount; }
+
+ protected:
+ Composition mComposition;
+ ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+ TestRenderEngine& mRenderEngine;
+ int32_t mFillFence;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mLayerCount;
+ PixelFormat mPixelFormat;
+ uint32_t mUsage;
+ uint32_t mStride;
+ ::android::Rect mAccessRegion;
+};
+
+class ReadbackHelper {
+ public:
+ static std::string getColorModeString(ColorMode mode);
+
+ static std::string getDataspaceString(Dataspace dataspace);
+
+ static Dataspace getDataspaceForColorMode(ColorMode mode);
+
+ static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
+
+ static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
+ PixelFormat pixelFormat, std::vector<Color> desiredPixelColors);
+
+ static void clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
+ int32_t displayWidth);
+
+ static void fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
+ Color color);
+
+ static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace);
+
+ static const std::vector<ColorMode> colorModes;
+ static const std::vector<Dataspace> dataspaces;
+
+ static void compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData,
+ const int32_t stride, const uint32_t width,
+ const uint32_t height, PixelFormat pixelFormat);
+};
+
+class ReadbackBuffer {
+ public:
+ ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client,
+ const ::android::sp<::android::GraphicBuffer>& graphicBuffer, int32_t width,
+ int32_t height, common::PixelFormat pixelFormat, common::Dataspace dataspace);
+
+ void setReadbackBuffer();
+
+ void checkReadbackBuffer(std::vector<Color> expectedColors);
+
+ ::android::sp<::android::GraphicBuffer> allocate();
+
+ protected:
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mLayerCount;
+ uint32_t mUsage;
+ uint32_t mStride;
+ PixelFormat mPixelFormat;
+ Dataspace mDataspace;
+ int64_t mDisplay;
+ ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+ std::shared_ptr<IComposerClient> mComposerClient;
+ ::android::Rect mAccessRegion;
+ native_handle_t mBufferHandle;
+};
+
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
new file mode 100644
index 0000000..eaff6d7
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
@@ -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.
+ */
+#pragma once
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <ReadbackVts.h>
+#include <mapper-vts/2.1/MapperVts.h>
+#include <math/half.h>
+#include <math/vec3.h>
+#include <renderengine/ExternalTexture.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using ::android::hardware::graphics::mapper::V2_1::IMapper;
+using ::android::renderengine::DisplaySettings;
+using ::android::renderengine::ExternalTexture;
+using ::android::renderengine::RenderEngineCreationArgs;
+
+class TestRenderEngine {
+ public:
+ static constexpr uint32_t sMaxFrameBufferAcquireBuffers = 2;
+
+ TestRenderEngine(const RenderEngineCreationArgs& args);
+ ~TestRenderEngine();
+
+ void setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers);
+ void initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint64_t usage);
+ void setDisplaySettings(DisplaySettings& displaySettings) {
+ mDisplaySettings = displaySettings;
+ };
+ void drawLayers();
+ void checkColorBuffer(std::vector<Color>& expectedColors);
+
+ ::android::renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; }
+
+ private:
+ common::PixelFormat mFormat;
+ std::vector<::android::renderengine::LayerSettings> mCompositionLayers;
+ std::unique_ptr<::android::renderengine::RenderEngine> mRenderEngine;
+ std::vector<::android::renderengine::LayerSettings> mRenderLayers;
+ ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
+
+ DisplaySettings mDisplaySettings;
+};
+
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/health/aidl/README.md b/health/aidl/README.md
index 53a4f91..a64fe93 100644
--- a/health/aidl/README.md
+++ b/health/aidl/README.md
@@ -63,8 +63,7 @@
* You may ignore the `service` line. The name of the service does not matter.
* If your service belongs to additional classes beside `charger`, you need a
custom health AIDL service.
-* You may ignore the `seclabel` line. When the health AIDL service runs in
- charger mode, its original SELinux domain is kept.
+* Modify the `seclabel` line. Replace `charger` with `charger_vendor`.
* If your service has a different `user` (not `system`), you need a custom
health AIDL service.
* If your service belongs to additional `group`s beside
@@ -80,7 +79,9 @@
for your device, install it with
```mk
-PRODUCT_PACKAGES += android.hardware.health-service.example
+PRODUCT_PACKAGES += \
+ android.hardware.health-service.example \
+ android.hardware.health-service.example_recovery \
```
Then, delete any existing `service` with `class charger` in your device-specific
@@ -156,15 +157,42 @@
for charger (`ro.charger.no_ui=true`), skip the invocation of
`ChargerModeMain()` in `main()`.
+### Build system changes
+
+Install both the platform and recovery variant of the service. For example:
+
+```mk
+PRODUCT_PACKAGES += \
+ android.hardware.health-service.cuttlefish \
+ android.hardware.health-service.cuttlefish_recovery \
+```
+
### SELinux rules
Add device specific permissions to the domain where the health HAL
process is executed, especially if a device-specific `libhealthd` is used
and/or device-specific storage related APIs are implemented.
+Example (assuming that your health AIDL service runs in domain
+`hal_health_tuna`:
+
+```text
+type hal_health_tuna, domain;
+hal_server_domain(hal_health_tuna, hal_health)
+type hal_health_tuna_exec, exec_type, vendor_file_type, file_type;
+
+# allow hal_health_tuna ...;
+```
+
If you did not define a separate domain, the domain is likely
`hal_health_default`. The device-specific rules for it is likely at
`device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te`.
+In this case, the aforementioned SELinux rules and types has already been
+defined. You only need to add device-specific permissions.
+
+```text
+# allow hal_health_default ...;
+```
### Implementing charger {#charger}
@@ -211,6 +239,8 @@
```text
service vendor.charger-tuna /vendor/bin/hw/android.hardware.health-service-tuna --charger
+ class charger
+ seclabel u:r:charger_vendor:s0
# ...
```
@@ -286,8 +316,5 @@
`hal_health_tuna`:
```text
-type hal_health_tuna, charger_type, domain;
-hal_server_domain(hal_health_default, hal_health)
+domain_trans(init, hal_health_tuna_exec, charger_vendor)
```
-
-[comment: TODO(b/170338625): explain recovery]: #
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index a13c677..8aa7638 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -23,8 +23,6 @@
cc_defaults {
name: "libhealth_aidl_common_defaults",
- recovery_available: true,
- vendor: true,
shared_libs: [
"libbase",
"libbinder_ndk",
@@ -100,6 +98,8 @@
"libhealth_aidl_common_defaults",
"libhealth_aidl_charger_defaults",
],
+ vendor: true,
+ recovery_available: true,
export_include_dirs: ["include"],
export_static_lib_headers: [
"libbatterymonitor",
@@ -122,10 +122,9 @@
// AIDL version of android.hardware.health@2.1-service.
// Default binder service of the health HAL.
-cc_binary {
- name: "android.hardware.health-service.example",
+cc_defaults {
+ name: "android.hardware.health-service.example-defaults",
relative_install_path: "hw",
- init_rc: ["android.hardware.health-service.example.rc"],
vintf_fragments: ["android.hardware.health-service.example.xml"],
defaults: [
"libhealth_aidl_common_defaults",
@@ -135,7 +134,20 @@
"libhealth_aidl_impl",
],
srcs: ["main.cpp"],
- overrides: [
- "charger",
- ],
+}
+
+cc_binary {
+ name: "android.hardware.health-service.example",
+ vendor: true,
+ defaults: ["android.hardware.health-service.example-defaults"],
+ init_rc: ["android.hardware.health-service.example.rc"],
+ overrides: ["charger"],
+}
+
+cc_binary {
+ name: "android.hardware.health-service.example_recovery",
+ recovery: true,
+ defaults: ["android.hardware.health-service.example-defaults"],
+ init_rc: ["android.hardware.health-service.example_recovery.rc"],
+ overrides: ["charger.recovery"],
}
diff --git a/health/aidl/default/android.hardware.health-service.example.rc b/health/aidl/default/android.hardware.health-service.example.rc
index dee3d11..4258890 100644
--- a/health/aidl/default/android.hardware.health-service.example.rc
+++ b/health/aidl/default/android.hardware.health-service.example.rc
@@ -7,6 +7,7 @@
service vendor.charger-default /vendor/bin/hw/android.hardware.health-service.example --charger
class charger
+ seclabel u:r:charger_vendor:s0
user system
group system wakelock input
capabilities SYS_BOOT
diff --git a/health/aidl/default/android.hardware.health-service.example_recovery.rc b/health/aidl/default/android.hardware.health-service.example_recovery.rc
new file mode 100644
index 0000000..0001170
--- /dev/null
+++ b/health/aidl/default/android.hardware.health-service.example_recovery.rc
@@ -0,0 +1,7 @@
+service vendor.health-default /system/bin/hw/android.hardware.health-service.example_recovery
+ class hal
+ seclabel u:r:hal_health_default:s0
+ user system
+ group system
+ capabilities WAKE_ALARM BLOCK_SUSPEND
+ file /dev/kmsg w
diff --git a/health/aidl/default/main.cpp b/health/aidl/default/main.cpp
index 76c6ba0..03b2ecb 100644
--- a/health/aidl/default/main.cpp
+++ b/health/aidl/default/main.cpp
@@ -39,14 +39,16 @@
static constexpr std::string_view gChargerArg{"--charger"};
int main(int argc, char** argv) {
+#ifdef __ANDROID_RECOVERY__
+ android::base::InitLogging(argv, android::base::KernelLogger);
+#endif
+
// make a default health service
auto config = std::make_unique<healthd_config>();
::android::hardware::health::InitHealthdConfig(config.get());
auto binder = ndk::SharedRefBase::make<Health>(gInstanceName, std::move(config));
if (argc >= 2 && argv[1] == gChargerArg) {
- android::base::InitLogging(argv, &android::base::KernelLogger);
-
#if !CHARGER_FORCE_NO_UI
// If charger shouldn't have UI for your device, simply drop the line below
// for your service implementation. This corresponds to
diff --git a/health/storage/aidl/default/main.cpp b/health/storage/aidl/default/main.cpp
index 186b64c..74e266f 100644
--- a/health/storage/aidl/default/main.cpp
+++ b/health/storage/aidl/default/main.cpp
@@ -24,14 +24,19 @@
using std::string_literals::operator""s;
int main() {
+ LOG(INFO) << "Health storage AIDL HAL starting...";
ABinderProcess_setThreadPoolMaxThreadCount(0);
// make a default storage service
auto storage = ndk::SharedRefBase::make<Storage>();
const std::string name = Storage::descriptor + "/default"s;
+ LOG(INFO) << "Health storage AIDL HAL registering...";
CHECK_EQ(STATUS_OK,
AServiceManager_registerLazyService(storage->asBinder().get(), name.c_str()));
+ LOG(INFO) << "Health storage AIDL HAL joining...";
ABinderProcess_joinThreadPool();
+
+ LOG(ERROR) << "Health storage AIDL HAL join thread ends, exiting...";
return EXIT_FAILURE; // should not reach
}
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index a7be660..8e5a0ff 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -41,6 +41,10 @@
"general-tests",
"vts",
],
+ sanitize: {
+ cfi: false,
+ },
+
}
cc_test_library {
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 2c15823..7676147 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -81,6 +81,12 @@
namespace test {
namespace {
+// The maximum number of times we'll attempt to verify that corruption
+// of an encrypted blob results in an error. Retries are necessary as there
+// is a small (roughly 1/256) chance that corrupting ciphertext still results
+// in valid PKCS7 padding.
+constexpr size_t kMaxPaddingCorruptionRetries = 8;
+
template <TagType tag_type, Tag tag, typename ValueT>
bool contains(hidl_vec<KeyParameter>& set, TypedTag<tag_type, tag> ttag, ValueT expected_value) {
size_t count = std::count_if(set.begin(), set.end(), [&](const KeyParameter& param) {
@@ -2853,11 +2859,22 @@
string ciphertext = EncryptMessage(message, params);
EXPECT_EQ(16U, ciphertext.size());
EXPECT_NE(ciphertext, message);
- ++ciphertext[ciphertext.size() / 2];
- EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
- string plaintext;
- EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &plaintext));
+ for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+ ++ciphertext[ciphertext.size() / 2];
+
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+ string plaintext;
+ ErrorCode error = Finish(message, &plaintext);
+ if (error == ErrorCode::INVALID_INPUT_LENGTH) {
+ // This is the expected error, we can exit the test now.
+ return;
+ } else {
+ // Very small chance we got valid decryption, so try again.
+ ASSERT_EQ(error, ErrorCode::OK);
+ }
+ }
+ FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
}
HidlBuf CopyIv(const AuthorizationSet& set) {
@@ -3923,17 +3940,30 @@
string ciphertext = EncryptMessage(message, BlockMode::ECB, PaddingMode::PKCS7);
EXPECT_EQ(8U, ciphertext.size());
EXPECT_NE(ciphertext, message);
- ++ciphertext[ciphertext.size() / 2];
AuthorizationSetBuilder begin_params;
begin_params.push_back(TAG_BLOCK_MODE, BlockMode::ECB);
begin_params.push_back(TAG_PADDING, PaddingMode::PKCS7);
- EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
- string plaintext;
- size_t input_consumed;
- EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
- EXPECT_EQ(ciphertext.size(), input_consumed);
- EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
+
+ for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+ ++ciphertext[ciphertext.size() / 2];
+
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+ string plaintext;
+
+ size_t input_consumed;
+ EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
+ EXPECT_EQ(ciphertext.size(), input_consumed);
+ ErrorCode error = Finish(&plaintext);
+ if (error == ErrorCode::INVALID_ARGUMENT) {
+ // This is the expected error, we can exit the test now.
+ return;
+ } else {
+ // Very small chance we got valid decryption, so try again.
+ ASSERT_EQ(error, ErrorCode::OK);
+ }
+ }
+ FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
}
struct TripleDesTestVector {
@@ -4234,18 +4264,28 @@
string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv);
EXPECT_EQ(8U, ciphertext.size());
EXPECT_NE(ciphertext, message);
- ++ciphertext[ciphertext.size() / 2];
auto begin_params = AuthorizationSetBuilder()
.BlockMode(BlockMode::CBC)
.Padding(PaddingMode::PKCS7)
.Authorization(TAG_NONCE, iv);
- EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
- string plaintext;
- size_t input_consumed;
- EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
- EXPECT_EQ(ciphertext.size(), input_consumed);
- EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
+ for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+ ++ciphertext[ciphertext.size() / 2];
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+ string plaintext;
+ size_t input_consumed;
+ EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
+ EXPECT_EQ(ciphertext.size(), input_consumed);
+ ErrorCode error = Finish(&plaintext);
+ if (error == ErrorCode::INVALID_ARGUMENT) {
+ // This is the expected error, we can exit the test now.
+ return;
+ } else {
+ // Very small chance we got valid decryption, so try again.
+ ASSERT_EQ(error, ErrorCode::OK);
+ }
+ }
+ FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
}
/*
diff --git a/media/omx/1.0/vts/OWNERS b/media/omx/1.0/vts/OWNERS
index e0e0dd1..9e390c2 100644
--- a/media/omx/1.0/vts/OWNERS
+++ b/media/omx/1.0/vts/OWNERS
@@ -1,7 +1,5 @@
+# Bug component: 25690
# Media team
-pawin@google.com
+taklee@google.com
+wonsik@google.com
lajos@google.com
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
\ No newline at end of file
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h
index 1ab9dcb..244001f 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h
@@ -41,7 +41,7 @@
// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
// function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_OC_MR1. On failure, this function returns with the appropriate
+// nn::kVersionFeatureLevel1. On failure, this function returns with the appropriate
// nn::GeneralError.
nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
ErrorStatus status, const sp<IPreparedModel>& preparedModel);
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
index 5c1480e..7710a7e 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h
@@ -28,7 +28,7 @@
namespace android::hardware::neuralnetworks::V1_0::utils {
-constexpr auto kVersion = nn::Version::ANDROID_OC_MR1;
+constexpr auto kVersion = nn::kVersionFeatureLevel1;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -51,7 +51,7 @@
template <typename Type>
nn::Result<void> compliantVersion(const Type& canonical) {
const auto version = NN_TRY(nn::validate(canonical));
- if (version > kVersion) {
+ if (!nn::isCompliantVersion(version, kVersion)) {
return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return {};
diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp
index 49913a2..b0c236e 100644
--- a/neuralnetworks/1.0/utils/src/Device.cpp
+++ b/neuralnetworks/1.0/utils/src/Device.cpp
@@ -99,7 +99,7 @@
}
nn::Version Device::getFeatureLevel() const {
- return nn::Version::ANDROID_OC_MR1;
+ return kVersion;
}
nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.0/utils/test/DeviceTest.cpp b/neuralnetworks/1.0/utils/test/DeviceTest.cpp
index e881da2..83e555f 100644
--- a/neuralnetworks/1.0/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.0/utils/test/DeviceTest.cpp
@@ -233,7 +233,7 @@
const auto featureLevel = device->getFeatureLevel();
// verify result
- EXPECT_EQ(featureLevel, nn::Version::ANDROID_OC_MR1);
+ EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel1);
}
TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
index 4660ff7..ff06739 100644
--- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h
@@ -30,7 +30,7 @@
namespace android::hardware::neuralnetworks::V1_1::utils {
constexpr auto kDefaultExecutionPreference = ExecutionPreference::FAST_SINGLE_ANSWER;
-constexpr auto kVersion = nn::Version::ANDROID_P;
+constexpr auto kVersion = nn::kVersionFeatureLevel2;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -53,7 +53,7 @@
template <typename Type>
nn::Result<void> compliantVersion(const Type& canonical) {
const auto version = NN_TRY(nn::validate(canonical));
- if (version > kVersion) {
+ if (!nn::isCompliantVersion(version, kVersion)) {
return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return {};
diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp
index 7d54cab..3effa84 100644
--- a/neuralnetworks/1.1/utils/src/Device.cpp
+++ b/neuralnetworks/1.1/utils/src/Device.cpp
@@ -99,7 +99,7 @@
}
nn::Version Device::getFeatureLevel() const {
- return nn::Version::ANDROID_P;
+ return kVersion;
}
nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.1/utils/test/DeviceTest.cpp b/neuralnetworks/1.1/utils/test/DeviceTest.cpp
index 41e0e30..2248da6 100644
--- a/neuralnetworks/1.1/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.1/utils/test/DeviceTest.cpp
@@ -243,7 +243,7 @@
const auto featureLevel = device->getFeatureLevel();
// verify result
- EXPECT_EQ(featureLevel, nn::Version::ANDROID_P);
+ EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel2);
}
TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h
index 6dd8138..fc04303 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h
@@ -38,7 +38,8 @@
// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
// function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_Q. On failure, this function returns with the appropriate nn::GeneralError.
+// nn::kVersionFeatureLevel3. On failure, this function returns with the appropriate
+// nn::GeneralError.
nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
V1_0::ErrorStatus status, const sp<IPreparedModel>& preparedModel);
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
index 23e336a..a06f2ac 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h
@@ -39,7 +39,7 @@
constexpr auto kDefaultMesaureTiming = MeasureTiming::NO;
constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits<uint64_t>::max(),
.timeInDriver = std::numeric_limits<uint64_t>::max()};
-constexpr auto kVersion = nn::Version::ANDROID_Q;
+constexpr auto kVersion = nn::kVersionFeatureLevel3;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -62,7 +62,7 @@
template <typename Type>
nn::Result<void> compliantVersion(const Type& canonical) {
const auto version = NN_TRY(nn::validate(canonical));
- if (version > kVersion) {
+ if (!nn::isCompliantVersion(version, kVersion)) {
return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return {};
diff --git a/neuralnetworks/1.2/utils/src/Burst.cpp b/neuralnetworks/1.2/utils/src/Burst.cpp
index e0a23f1..911fbfa 100644
--- a/neuralnetworks/1.2/utils/src/Burst.cpp
+++ b/neuralnetworks/1.2/utils/src/Burst.cpp
@@ -315,7 +315,7 @@
// if the request is valid but of a higher version than what's supported in burst execution,
// fall back to another execution path
- if (const auto version = NN_TRY(nn::validate(request)); version > nn::Version::ANDROID_Q) {
+ if (!compliantVersion(request).ok()) {
// fallback to another execution path if the packet could not be sent
return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration);
}
@@ -359,7 +359,7 @@
// if the request is valid but of a higher version than what's supported in burst execution,
// fall back to another execution path
- if (const auto version = NN_TRY(nn::validate(request)); version > nn::Version::ANDROID_Q) {
+ if (!compliantVersion(request).ok()) {
// fallback to another execution path if the packet could not be sent
return kPreparedModel->createReusableExecution(request, measure, loopTimeoutDuration);
}
diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp
index f12669a..e7acecd 100644
--- a/neuralnetworks/1.2/utils/src/Device.cpp
+++ b/neuralnetworks/1.2/utils/src/Device.cpp
@@ -192,7 +192,7 @@
}
nn::Version Device::getFeatureLevel() const {
- return nn::Version::ANDROID_Q;
+ return kVersion;
}
nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.2/utils/test/DeviceTest.cpp b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
index 215d44c..1dc6285 100644
--- a/neuralnetworks/1.2/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.2/utils/test/DeviceTest.cpp
@@ -483,7 +483,7 @@
const auto featureLevel = device->getFeatureLevel();
// verify result
- EXPECT_EQ(featureLevel, nn::Version::ANDROID_Q);
+ EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel3);
}
TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h
index 4b8ddc1..10892bc 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h
@@ -47,7 +47,8 @@
// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
// function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_R. On failure, this function returns with the appropriate nn::GeneralError.
+// nn::kVersionFeatureLevel4. On failure, this function returns with the appropriate
+// nn::GeneralError.
nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
ErrorStatus status, const sp<IPreparedModel>& preparedModel);
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
index 2812db2..594d727 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h
@@ -39,7 +39,7 @@
using V1_2::utils::kNoTiming;
constexpr auto kDefaultPriority = Priority::MEDIUM;
-constexpr auto kVersion = nn::Version::ANDROID_R;
+constexpr auto kVersion = nn::kVersionFeatureLevel4;
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -62,7 +62,7 @@
template <typename Type>
nn::Result<void> compliantVersion(const Type& canonical) {
const auto version = NN_TRY(nn::validate(canonical));
- if (version > kVersion) {
+ if (!nn::isCompliantVersion(version, kVersion)) {
return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return {};
diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp
index a73ce82..9517fda 100644
--- a/neuralnetworks/1.3/utils/src/Device.cpp
+++ b/neuralnetworks/1.3/utils/src/Device.cpp
@@ -143,7 +143,7 @@
}
nn::Version Device::getFeatureLevel() const {
- return nn::Version::ANDROID_R;
+ return kVersion;
}
nn::DeviceType Device::getType() const {
diff --git a/neuralnetworks/1.3/utils/test/DeviceTest.cpp b/neuralnetworks/1.3/utils/test/DeviceTest.cpp
index 2d1b2f2..7eba4bc 100644
--- a/neuralnetworks/1.3/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/1.3/utils/test/DeviceTest.cpp
@@ -505,7 +505,7 @@
const auto featureLevel = device->getFeatureLevel();
// verify result
- EXPECT_EQ(featureLevel, nn::Version::ANDROID_R);
+ EXPECT_EQ(featureLevel, nn::kVersionFeatureLevel4);
}
TEST(DeviceTest, getCachedData) {
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
index 2eff11b..34506c8 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
@@ -138,4 +138,6 @@
RANK = 101,
BATCH_MATMUL = 102,
PACK = 103,
+ MIRROR_PAD = 104,
+ REVERSE = 105,
}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index 2ec91ac..aebe8d9 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -4318,6 +4318,8 @@
* Supported tensor {@link OperandType}:
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM} (since NNAPI feature level 7)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since NNAPI feature level 7)
*
* Supported tensor rank: from 1.
*
@@ -4326,6 +4328,9 @@
*
* Outputs:
* * 0: The output tensor of same shape as input0.
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint can be different from inputs' scale and zeroPoint.
*/
RSQRT = 83,
@@ -5322,4 +5327,68 @@
* * 0: The packed tensor.
*/
PACK = 103,
+
+ /**
+ * Pads a tensor with mirrored values.
+ *
+ * Supported tensor {@link OperandType}:
+ * * {@link OperandType::TENSOR_FLOAT16}
+ * * {@link OperandType::TENSOR_FLOAT32}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+ * * {@link OperandType::TENSOR_INT32}
+ *
+ * Supported tensor rank: from 1.
+ *
+ * Inputs:
+ * * 0: An n-D tensor, specifying the tensor to be padded.
+ * * 1: A 2-D tensor of {@link OperandType::TENSOR_INT32}, the paddings
+ * for each spatial dimension of the input tensor. The shape of the
+ * tensor must be {rank(input0), 2}.
+ * padding[i, 0] specifies the number of elements to be padded in the
+ * front of dimension i.
+ * padding[i, 1] specifies the number of elements to be padded after the
+ * end of dimension i.
+ * * 2: An {@link OperandType::INT32} scalar, specifying the mode.
+ * Options are 0:REFLECT and 1:SYMMETRIC.
+ *
+ * Outputs:
+ * * 0: A tensor of the same {@link OperandType} as input0. The
+ * output tensor has the same rank as input0, and each
+ * dimension of the output tensor has the same size as the
+ * corresponding dimension of the input tensor plus the size
+ * of the padding:
+ * output0.dimension[i] =
+ * padding[i, 0] + input0.dimension[i] + padding[i, 1]
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint must be the same as input0.
+ */
+ MIRROR_PAD = 104,
+
+ /**
+ * Reverses a specified dimension of a tensor.
+ *
+ * Supported tensor {@link OperandType}:
+ * * {@link OperandType::TENSOR_FLOAT16}
+ * * {@link OperandType::TENSOR_FLOAT32}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+ * * {@link OperandType::TENSOR_INT32}
+ *
+ * Supported tensor rank: up to 8.
+ *
+ * Inputs:
+ * * 0: Input tensor of rank n.
+ * * 1: Axis tensor of type {@link OperandType::TENSOR_INT32} and shape [1],
+ * specifying which dimension of the input tensor is to be reversed. The dimension
+ * must be in the range [0, n).
+ *
+ * Outputs:
+ * * 0: The reversed tensor.
+ * For {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors,
+ * the scales and zeroPoint must be the same as input0.
+ */
+ REVERSE = 105,
}
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 1a4cd9a..e356104 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -56,13 +56,21 @@
}
cc_library_static {
- name: "neuralnetworks_utils_hal_aidl",
+ name: "neuralnetworks_utils_hal_aidl_v2",
defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
shared_libs: [
"android.hardware.neuralnetworks-V2-ndk",
],
}
+cc_library_static {
+ name: "neuralnetworks_utils_hal_aidl",
+ defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
+ shared_libs: [
+ "android.hardware.neuralnetworks-V3-ndk",
+ ],
+}
+
// A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries
// that are commonly used together. Modules that always depend on the latest non-experimental
// AIDL features can include this cc_defaults to avoid managing dependency versions explicitly.
@@ -71,7 +79,7 @@
static_libs: [
"android.hardware.common-V2-ndk",
"android.hardware.graphics.common-V3-ndk",
- "android.hardware.neuralnetworks-V2-ndk",
+ "android.hardware.neuralnetworks-V3-ndk",
"neuralnetworks_utils_hal_aidl",
],
}
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
index f2ab479..a27487e 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
@@ -19,6 +19,7 @@
#include "nnapi/hal/aidl/Conversions.h"
+#include <aidl/android/hardware/neuralnetworks/IDevice.h>
#include <android-base/logging.h>
#include <nnapi/Result.h>
#include <nnapi/TypeUtils.h>
@@ -28,7 +29,21 @@
namespace aidl::android::hardware::neuralnetworks::utils {
constexpr auto kDefaultPriority = Priority::MEDIUM;
-constexpr auto kVersion = nn::Version::FEATURE_LEVEL_6;
+
+constexpr std::optional<nn::Version> aidlVersionToCanonicalVersion(int aidlVersion) {
+ switch (aidlVersion) {
+ case 1:
+ return nn::kVersionFeatureLevel5;
+ case 2:
+ return nn::kVersionFeatureLevel6;
+ case 3:
+ return nn::kVersionFeatureLevel7;
+ default:
+ return std::nullopt;
+ }
+}
+
+constexpr auto kVersion = aidlVersionToCanonicalVersion(IDevice::version).value();
template <typename Type>
nn::Result<void> validate(const Type& halObject) {
@@ -51,7 +66,7 @@
template <typename Type>
nn::Result<void> compliantVersion(const Type& canonical) {
const auto version = NN_TRY(nn::validate(canonical));
- if (version > kVersion) {
+ if (!nn::isCompliantVersion(version, kVersion)) {
return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
}
return {};
diff --git a/neuralnetworks/aidl/utils/src/Callbacks.cpp b/neuralnetworks/aidl/utils/src/Callbacks.cpp
index a321477..8084970 100644
--- a/neuralnetworks/aidl/utils/src/Callbacks.cpp
+++ b/neuralnetworks/aidl/utils/src/Callbacks.cpp
@@ -35,7 +35,8 @@
// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this
// function returns with a non-null nn::SharedPreparedModel with a feature level of
-// nn::Version::ANDROID_S. On failure, this function returns with the appropriate nn::GeneralError.
+// nn::kVersionFeatureLevel5. On failure, this function returns with the appropriate
+// nn::GeneralError.
nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) {
HANDLE_STATUS_AIDL(status) << "model preparation failed with " << toString(status);
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index 01772ee..e48593c 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -46,13 +46,11 @@
aidlVersion = std::min(aidlVersion, IDevice::version);
// Map stable AIDL versions to canonical versions.
- switch (aidlVersion) {
- case 1:
- return nn::Version::ANDROID_S;
- case 2:
- return nn::Version::FEATURE_LEVEL_6;
+ auto version = aidlVersionToCanonicalVersion(aidlVersion);
+ if (!version.has_value()) {
+ return NN_ERROR() << "Unknown AIDL service version: " << aidlVersion;
}
- return NN_ERROR() << "Unknown AIDL service version: " << aidlVersion;
+ return version.value();
}
} // namespace
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index 79abe1b..0366e7d 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -152,13 +152,17 @@
};
std::string printDeviceTest(const testing::TestParamInfo<nn::Version>& info) {
- switch (info.param) {
- case nn::Version::ANDROID_S:
+ const nn::Version version = info.param;
+ CHECK(!version.runtimeOnlyFeatures);
+ switch (version.level) {
+ case nn::Version::Level::FEATURE_LEVEL_5:
return "v1";
- case nn::Version::FEATURE_LEVEL_6:
+ case nn::Version::Level::FEATURE_LEVEL_6:
return "v2";
+ case nn::Version::Level::FEATURE_LEVEL_7:
+ return "v3";
default:
- LOG(FATAL) << "Invalid AIDL version: " << info.param;
+ LOG(FATAL) << "Invalid AIDL version: " << version;
return "invalid";
}
}
@@ -891,7 +895,8 @@
}
INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest,
- ::testing::Values(nn::Version::ANDROID_S, nn::Version::FEATURE_LEVEL_6),
+ ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6,
+ nn::kVersionFeatureLevel7),
printDeviceTest);
} // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp
index a102fe0..1ed15b8 100644
--- a/neuralnetworks/aidl/vts/functional/Android.bp
+++ b/neuralnetworks/aidl/vts/functional/Android.bp
@@ -60,6 +60,7 @@
"libsync",
],
whole_static_libs: [
+ "neuralnetworks_generated_AIDL_V3_example",
"neuralnetworks_generated_AIDL_V2_example",
"neuralnetworks_generated_V1_0_example",
"neuralnetworks_generated_V1_1_example",
diff --git a/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp b/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp
index 3abd724..0488b63 100644
--- a/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp
+++ b/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp
@@ -28,7 +28,6 @@
namespace {
using ::testing::_;
-using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using SharedMockDevice = std::shared_ptr<const nn::MockDevice>;
@@ -54,7 +53,7 @@
// Setup default actions for each relevant call.
constexpr auto getName_ret = []() -> const std::string& { return kName; };
constexpr auto getVersionString_ret = []() -> const std::string& { return kVersionString; };
- constexpr auto kFeatureLevel = nn::Version::ANDROID_OC_MR1;
+ constexpr auto kFeatureLevel = nn::kVersionFeatureLevel1;
constexpr auto kDeviceType = nn::DeviceType::ACCELERATOR;
constexpr auto getSupportedExtensions_ret = []() -> const std::vector<nn::Extension>& {
return kExtensions;
@@ -142,7 +141,7 @@
TEST(ResilientDeviceTest, getFeatureLevel) {
// setup call
const auto [mockDevice, mockDeviceFactory, device] = setup();
- constexpr auto kFeatureLevel = nn::Version::ANDROID_OC_MR1;
+ constexpr auto kFeatureLevel = nn::kVersionFeatureLevel1;
EXPECT_CALL(*mockDevice, getFeatureLevel()).Times(1).WillOnce(Return(kFeatureLevel));
// run test
@@ -592,7 +591,7 @@
const auto recoveredMockDevice = createConfiguredMockDevice();
EXPECT_CALL(*recoveredMockDevice, getFeatureLevel())
.Times(1)
- .WillOnce(Return(nn::Version::ANDROID_P));
+ .WillOnce(Return(nn::kVersionFeatureLevel2));
EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice));
// run test
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index c167a6d..9f530b3 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -645,6 +645,10 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+ return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
@@ -699,6 +703,10 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+ return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
@@ -752,6 +760,10 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+ return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
}
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 60eabc7..bc7f63c 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
@@ -34,7 +34,6 @@
package android.hardware.radio.config;
@VintfStability
parcelable SimSlotStatus {
- boolean cardActive;
int cardState;
String atr;
String eid;
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 cfcd42c..9df687c 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
@@ -52,6 +52,7 @@
int mtuV6;
boolean preferred;
boolean persistent;
+ boolean alwaysOn;
const int ID_DEFAULT = 0;
const int ID_TETHERED = 1;
const int ID_IMS = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
index 4cac560..68c82fa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
@@ -53,6 +53,7 @@
oneway void hangup(in int serial, in int gsmIndex);
oneway void hangupForegroundResumeBackground(in int serial);
oneway void hangupWaitingOrBackground(in int serial);
+ oneway void isVoNrEnabled(in int serial);
oneway void rejectCall(in int serial);
oneway void responseAcknowledgement();
oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off);
@@ -66,6 +67,7 @@
oneway void setPreferredVoicePrivacy(in int serial, in boolean enable);
oneway void setResponseFunctions(in android.hardware.radio.voice.IRadioVoiceResponse radioVoiceResponse, in android.hardware.radio.voice.IRadioVoiceIndication radioVoiceIndication);
oneway void setTtyMode(in int serial, in android.hardware.radio.voice.TtyMode mode);
+ oneway void setVoNrEnabled(in int serial, in boolean enable);
oneway void startDtmf(in int serial, in String s);
oneway void stopDtmf(in int serial);
oneway void switchWaitingOrHoldingAndActive(in int serial);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index 9f490a8..a3b5e58 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -54,6 +54,7 @@
oneway void hangupConnectionResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void hangupForegroundResumeBackgroundResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void hangupWaitingOrBackgroundResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void isVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable);
oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info);
@@ -65,6 +66,7 @@
oneway void setMuteResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setTtyModeResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void setVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void startDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void stopDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void switchWaitingOrHoldingAndActiveResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 4ab955a..a1c3c27 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -20,7 +20,6 @@
@VintfStability
parcelable SimSlotStatus {
- boolean cardActive;
/**
* Card state in the physical slot. Values are CardStatus.[STATE_ABSENT, STATE_PRESENT,
* STATE_ERROR, STATE_RESTRICTED].
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 7657fc9..a14963f 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -115,4 +115,11 @@
* If the same data profile exists, this data profile must overwrite it.
*/
boolean persistent;
+ /**
+ * Indicates the PDU session brought up by this data profile should be always-on.
+ * An always-on PDU Session is a PDU Session for which User Plane resources have to be
+ * activated during every transition from CM-IDLE mode to CM-CONNECTED state.
+ * See 3GPP TS 23.501 section 5.6.13 for the details.
+ */
+ boolean alwaysOn;
}
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index 1e60de5..a012be4 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -267,6 +267,15 @@
void hangupWaitingOrBackground(in int serial);
/**
+ * Query current Voice NR enable state
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioVoiceResponse.isVoNrEnabledResponse()
+ */
+ void isVoNrEnabled(in int serial);
+
+ /**
* Send UDUB (user determined user busy) to ringing or waiting call answer)
*
* @param serial Serial number of request.
@@ -404,6 +413,16 @@
void setTtyMode(in int serial, in TtyMode mode);
/**
+ * Set Voice NR enable state
+ *
+ * @param serial Serial number of request.
+ * @param enable true for "enable vonr" and false for "disable vonr"
+ *
+ * Response function is IRadioVoiceResponse.setVoNrEnabledResponse()
+ */
+ void setVoNrEnabled(in int serial, in boolean enable);
+
+ /**
* Start playing a DTMF tone. Continue playing DTMF tone until stopDtmf is received. If a
* startDtmf() is received while a tone is currently playing, it must cancel the previous tone
* and play the new one.
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index f3cf5fb..d126fc1 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -468,6 +468,20 @@
/**
* @param info Response info struct containing response type, serial no. and error
+ * @param enable true for "vonr enabled" and false for "vonr disabled"
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ void isVoNrEnabledResponse(in RadioResponseInfo info, in boolean enable);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
* RadioError:NONE
@@ -694,6 +708,20 @@
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_ARGUMENTS
+ * RadioError:MODEM_ERR
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_MEMORY
+ * RadioError:REQUEST_NOT_SUPPORTED
+ */
+ void setVoNrEnabledResponse(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_ARGUMENTS
* RadioError:NO_RESOURCES
* RadioError:NO_MEMORY
* RadioError:SYSTEM_ERR
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
new file mode 100644
index 0000000..43d9378
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -0,0 +1,93 @@
+// 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 {
+ // 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 {
+ name: "android.hardware.radio-library.compat",
+ relative_install_path: "hw",
+ vendor: true,
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ //"-Wold-style-cast", // TODO(b/203699028) enable after aosp/1900880 gets merged
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+ ],
+ shared_libs: [
+ "android.hardware.radio.config-V1-ndk",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ "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.sim-V1-ndk",
+ "android.hardware.radio.voice-V1-ndk",
+ "android.hardware.radio@1.0",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.2",
+ "android.hardware.radio@1.3",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.5",
+ "android.hardware.radio@1.6",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ ],
+ srcs: [
+ "RadioCompatBase.cpp",
+ "RadioResponse.cpp",
+ "commonStructs.cpp",
+ "config/RadioConfig.cpp",
+ "config/RadioConfigIndication.cpp",
+ "config/RadioConfigResponse.cpp",
+ "config/structs.cpp",
+ "data/RadioIndication-data.cpp",
+ "data/RadioResponse-data.cpp",
+ "data/RadioData.cpp",
+ "data/structs.cpp",
+ "messaging/RadioIndication-messaging.cpp",
+ "messaging/RadioMessaging.cpp",
+ "messaging/RadioResponse-messaging.cpp",
+ "messaging/structs.cpp",
+ "modem/RadioIndication-modem.cpp",
+ "modem/RadioResponse-modem.cpp",
+ "modem/RadioModem.cpp",
+ "modem/structs.cpp",
+ "network/RadioIndication-network.cpp",
+ "network/RadioNetwork.cpp",
+ "network/RadioResponse-network.cpp",
+ "network/structs.cpp",
+ "network/utils.cpp",
+ "sim/RadioIndication-sim.cpp",
+ "sim/RadioResponse-sim.cpp",
+ "sim/RadioSim.cpp",
+ "sim/structs.cpp",
+ "voice/RadioIndication-voice.cpp",
+ "voice/RadioResponse-voice.cpp",
+ "voice/RadioVoice.cpp",
+ "voice/structs.cpp",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
new file mode 100644
index 0000000..a9eac68
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 <libradiocompat/RadioCompatBase.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+RadioCompatBase::RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
+ sp<RadioIndication> radioIndication)
+ : mHal1_5(hidlHal),
+ mHal1_6(V1_6::IRadio::castFrom(hidlHal)),
+ mRadioResponse(radioResponse),
+ mRadioIndication(radioIndication) {}
+
+V1_6::IRadioResponse& RadioCompatBase::respond() {
+ CHECK(mRadioResponse) << "This shouldn't happen (response functions are passed in constructor)";
+ return *mRadioResponse;
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
new file mode 100644
index 0000000..35b0ac1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.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 <libradiocompat/RadioResponse.h>
+
+#include "debug.h"
+
+#define RADIO_MODULE "Common"
+
+namespace android::hardware::radio::compat {
+
+Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
+ LOG_CALL << serial;
+ // TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
+ if (mDataCb) mDataCb->acknowledgeRequest(serial);
+ if (mMessagingCb) mMessagingCb->acknowledgeRequest(serial);
+ if (mModemCb) mModemCb->acknowledgeRequest(serial);
+ if (mNetworkCb) mNetworkCb->acknowledgeRequest(serial);
+ if (mSimCb) mSimCb->acknowledgeRequest(serial);
+ if (mVoiceCb) mVoiceCb->acknowledgeRequest(serial);
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/collections.h b/radio/aidl/compat/libradiocompat/collections.h
new file mode 100644
index 0000000..082ef17
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/collections.h
@@ -0,0 +1,122 @@
+/*
+ * 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 <hidl/HidlSupport.h>
+
+#include <type_traits>
+#include <variant>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * Converts hidl_vec<T> HIDL list to std::vector<T> AIDL list.
+ *
+ * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp vector to convert
+ */
+template <typename T>
+auto toAidl(const hidl_vec<T>& inp) {
+ std::vector<decltype(toAidl(T{}))> out(inp.size());
+ for (size_t i = 0; i < inp.size(); i++) {
+ out[i] = toAidl(inp[i]);
+ }
+ return out;
+}
+
+/**
+ * Converts std::vector<T> AIDL list to hidl_vec<T> HIDL list.
+ *
+ * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp vector to convert
+ */
+template <typename T>
+auto toHidl(const std::vector<T>& inp) {
+ hidl_vec<decltype(toHidl(T{}))> out(inp.size());
+ for (size_t i = 0; i < inp.size(); i++) {
+ out[i] = toHidl(inp[i]);
+ }
+ return out;
+}
+
+/**
+ * Converts hidl_array<T> HIDL list to std::vector<T> AIDL list.
+ *
+ * To convert values, the template uses toAidl functions for a given type T, assuming it's defined.
+ *
+ * \param inp array to convert
+ */
+template <typename T, size_t N>
+auto toAidl(const hidl_array<T, N>& inp) {
+ std::vector<decltype(toAidl(T{}))> out(N);
+ for (size_t i = 0; i < N; i++) {
+ out[i] = toAidl(inp[i]);
+ }
+ return out;
+}
+
+/**
+ * Converts T=OptionalX HIDL value to std::optional<X> AIDL value.
+ *
+ * To convert values, the template uses toAidl functions for a given type T.value.
+ */
+template <typename T>
+std::optional<decltype(toAidl(T{}.value()))> toAidl(const T& opt) {
+ if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return std::nullopt;
+ return toAidl(opt.value());
+}
+
+/**
+ * Converts T=OptionalX HIDL value to std::variant<bool, X> AIDL value.
+ *
+ * For some reason, not every OptionalX gets generated into a std::optional<X>.
+ */
+template <typename T>
+std::variant<bool, decltype(toAidl(T{}.value()))> toAidlVariant(const T& opt) {
+ if (opt.getDiscriminator() == T::hidl_discriminator::noinit) return false;
+ return toAidl(opt.value());
+}
+
+/**
+ * Converts std::optional<X> AIDL value to T=OptionalX HIDL value.
+ *
+ * X is inferred from toAidl(T.value) declaration. Please note that toAidl(T.value) doesn't have to
+ * be implemented if it's not needed for anything else than giving this hint to type system.
+ *
+ * To convert values, the template uses toHidl functions for a given type T, assuming it's defined.
+ *
+ * \param opt value to convert
+ */
+template <typename T>
+T toHidl(const std::optional<decltype(toAidl(T{}.value()))>& opt) {
+ T hidl;
+ if (opt.has_value()) hidl.value(toHidl(*opt));
+ return hidl;
+}
+
+/**
+ * Converts U AIDL bitfield value to HIDL T bitfield value.
+ *
+ * \param val value to convert
+ */
+template <typename T, typename U>
+hidl_bitfield<T> toHidlBitfield(U val) {
+ return static_cast<int>(val);
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.cpp b/radio/aidl/compat/libradiocompat/commonStructs.cpp
new file mode 100644
index 0000000..c25768d
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/commonStructs.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 "commonStructs.h"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio;
+
+V1_6::RadioResponseInfo notSupported(int32_t serial) {
+ return {
+ .type = V1_0::RadioResponseType::SOLICITED,
+ .serial = serial,
+ .error = V1_6::RadioError::REQUEST_NOT_SUPPORTED,
+ };
+}
+
+std::string toAidl(const hidl_string& str) {
+ return str;
+}
+
+hidl_string toHidl(const std::string& str) {
+ return str;
+}
+
+uint8_t toAidl(int8_t v) {
+ return v;
+}
+
+int8_t toAidl(uint8_t v) {
+ return v;
+}
+
+int32_t toAidl(uint32_t v) {
+ return v;
+}
+
+aidl::RadioIndicationType toAidl(V1_0::RadioIndicationType type) {
+ return aidl::RadioIndicationType(type);
+}
+
+aidl::RadioResponseType toAidl(V1_0::RadioResponseType type) {
+ return aidl::RadioResponseType(type);
+}
+
+aidl::RadioError toAidl(V1_0::RadioError err) {
+ return aidl::RadioError(err);
+}
+
+aidl::RadioError toAidl(V1_6::RadioError err) {
+ return aidl::RadioError(err);
+}
+
+aidl::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info) {
+ return {
+ .type = toAidl(info.type),
+ .serial = info.serial,
+ .error = toAidl(info.error),
+ };
+}
+
+aidl::RadioResponseInfo toAidl(const V1_6::RadioResponseInfo& info) {
+ return {
+ .type = toAidl(info.type),
+ .serial = info.serial,
+ .error = toAidl(info.error),
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.h b/radio/aidl/compat/libradiocompat/commonStructs.h
new file mode 100644
index 0000000..b859916
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/commonStructs.h
@@ -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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/RadioIndicationType.h>
+#include <aidl/android/hardware/radio/RadioResponseInfo.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_6::RadioResponseInfo notSupported(int32_t serial);
+
+std::string toAidl(const hidl_string& str);
+hidl_string toHidl(const std::string& str);
+uint8_t toAidl(int8_t v);
+int8_t toAidl(uint8_t v);
+int32_t toAidl(uint32_t v);
+
+aidl::android::hardware::radio::RadioIndicationType toAidl(V1_0::RadioIndicationType type);
+aidl::android::hardware::radio::RadioResponseType toAidl(V1_0::RadioResponseType type);
+aidl::android::hardware::radio::RadioError toAidl(V1_0::RadioError type);
+aidl::android::hardware::radio::RadioError toAidl(V1_6::RadioError type);
+
+aidl::android::hardware::radio::RadioResponseInfo toAidl(const V1_0::RadioResponseInfo& info);
+aidl::android::hardware::radio::RadioResponseInfo toAidl(const V1_6::RadioResponseInfo& info);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
new file mode 100644
index 0000000..d0d6f7a
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 <libradiocompat/RadioConfig.h>
+
+#include "RadioConfigIndication.h"
+#include "RadioConfigResponse.h"
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "Config"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::config;
+constexpr auto ok = &ScopedAStatus::ok;
+
+RadioConfig::RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal)
+ : mHal1_1(hidlHal), mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)) {}
+
+config::V1_3::IRadioConfigResponse& RadioConfig::respond() {
+ CHECK(mRadioConfigResponse) << "setResponseFunctions was not called yet";
+ return *mRadioConfigResponse;
+}
+
+ScopedAStatus RadioConfig::getHalDeviceCapabilities(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_3) {
+ mHal1_3->getHalDeviceCapabilities(serial);
+ } else {
+ respond().getHalDeviceCapabilitiesResponse(notSupported(serial), false);
+ }
+ return ok();
+}
+
+ScopedAStatus RadioConfig::getNumOfLiveModems(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_1->getModemsConfig(serial);
+ return ok();
+}
+
+ScopedAStatus RadioConfig::getPhoneCapability(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_1->getPhoneCapability(serial);
+ return ok();
+}
+
+ScopedAStatus RadioConfig::getSimSlotsStatus(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_1->getSimSlotsStatus(serial);
+ return ok();
+}
+
+ScopedAStatus RadioConfig::setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) {
+ LOG_CALL << serial;
+ mHal1_1->setModemsConfig(serial, {static_cast<uint8_t>(numOfLiveModems)});
+ return ok();
+}
+
+ScopedAStatus RadioConfig::setPreferredDataModem(int32_t serial, int8_t modemId) {
+ LOG_CALL << serial;
+ mHal1_1->setPreferredDataModem(serial, modemId);
+ return ok();
+}
+
+ScopedAStatus RadioConfig::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioConfigResponse>& radioConfigResponse,
+ const std::shared_ptr<aidl::IRadioConfigIndication>& radioConfigIndication) {
+ LOG_CALL << radioConfigResponse << ' ' << radioConfigIndication;
+
+ CHECK(radioConfigResponse);
+ CHECK(radioConfigIndication);
+
+ mRadioConfigResponse = sp<RadioConfigResponse>::make(radioConfigResponse);
+ mRadioConfigIndication = sp<RadioConfigIndication>::make(radioConfigIndication);
+ mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication);
+
+ return ok();
+}
+
+ScopedAStatus RadioConfig::setSimSlotsMapping( //
+ int32_t serial, const std::vector<aidl::SlotPortMapping>& slotMap) {
+ LOG_CALL << serial;
+ mHal1_1->setSimSlotsMapping(serial, toHidl(slotMap));
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
new file mode 100644
index 0000000..0320ad7
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
@@ -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.
+ */
+
+#include "RadioConfigIndication.h"
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ConfigIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+RadioConfigIndication::RadioConfigIndication(std::shared_ptr<aidl::IRadioConfigIndication> callback)
+ : mCallback(callback) {}
+
+Return<void> RadioConfigIndication::simSlotsStatusChanged(
+ V1_0::RadioIndicationType type, const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
+ LOG_CALL << type;
+ mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+ return {};
+}
+
+Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
+ V1_0::RadioIndicationType type, const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
+ LOG_CALL << type;
+ mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
new file mode 100644
index 0000000..3d8d971
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
@@ -0,0 +1,38 @@
+/*
+ * 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/radio/config/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioConfigIndication : public config::V1_2::IRadioConfigIndication {
+ std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> mCallback;
+
+ Return<void> simSlotsStatusChanged(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) override;
+ Return<void> simSlotsStatusChanged_1_2(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
+
+ public:
+ RadioConfigIndication(
+ std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> cb);
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
new file mode 100644
index 0000000..7066ae4
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 "RadioConfigResponse.h"
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ConfigResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+RadioConfigResponse::RadioConfigResponse(std::shared_ptr<aidl::IRadioConfigResponse> callback)
+ : mCallback(callback) {}
+
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
+ LOG_CALL << info.serial;
+ mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+ return {};
+};
+
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse_1_2(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
+ LOG_CALL << info.serial;
+ mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+ return {};
+};
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ mCallback->setSimSlotsMappingResponse(toAidl(info));
+ return {};
+};
+
+Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
+ const V1_0::RadioResponseInfo& info, const config::V1_1::PhoneCapability& phoneCapability) {
+ LOG_CALL << info.serial;
+ mCallback->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
+ return {};
+};
+
+Return<void> RadioConfigResponse::setPreferredDataModemResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ mCallback->setPreferredDataModemResponse(toAidl(info));
+ return {};
+};
+
+Return<void> RadioConfigResponse::setModemsConfigResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ mCallback->setNumOfLiveModemsResponse(toAidl(info));
+ return {};
+};
+
+Return<void> RadioConfigResponse::getModemsConfigResponse(
+ const V1_0::RadioResponseInfo& info, const config::V1_1::ModemsConfig& modemsConfig) {
+ LOG_CALL << info.serial;
+ mCallback->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
+ return {};
+};
+
+Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
+ const V1_6::RadioResponseInfo& info, bool modemReducedFeatureSet1) {
+ LOG_CALL << info.serial;
+ mCallback->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
+ return {};
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
new file mode 100644
index 0000000..1461dd2
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
@@ -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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/config/IRadioConfigResponse.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioConfigResponse : public config::V1_3::IRadioConfigResponse {
+ std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> mCallback;
+
+ Return<void> getSimSlotsStatusResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) override;
+ Return<void> setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getPhoneCapabilityResponse(
+ const V1_0::RadioResponseInfo& info,
+ const config::V1_1::PhoneCapability& phoneCapability) override;
+ Return<void> setPreferredDataModemResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setModemsConfigResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getModemsConfigResponse(const V1_0::RadioResponseInfo& info,
+ const config::V1_1::ModemsConfig& modemsConfig) override;
+ Return<void> getSimSlotsStatusResponse_1_2(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
+ Return<void> getHalDeviceCapabilitiesResponse(const V1_6::RadioResponseInfo& info,
+ bool modemReducedFeatureSet1) override;
+
+ public:
+ RadioConfigResponse(
+ std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> callback);
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/structs.cpp b/radio/aidl/compat/libradiocompat/config/structs.cpp
new file mode 100644
index 0000000..9ba5623
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/structs.cpp
@@ -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.
+ */
+
+#include "structs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::config;
+
+hidl_vec<uint32_t> toHidl(const std::vector<aidl::SlotPortMapping>& slotMap) {
+ hidl_vec<uint32_t> out(slotMap.size());
+ for (const auto& el : slotMap) {
+ CHECK_GE(el.portId, 0);
+ CHECK_LT(static_cast<size_t>(el.portId), out.size());
+ out[el.portId] = el.physicalSlotId;
+ }
+ return out;
+}
+
+aidl::SimSlotStatus toAidl(const config::V1_0::SimSlotStatus& sst) {
+ return toAidl({sst, ""});
+}
+
+aidl::SimSlotStatus toAidl(const config::V1_2::SimSlotStatus& sst) {
+ const aidl::SimPortInfo portInfo = {
+ .iccId = sst.base.iccid,
+ .logicalSlotId = static_cast<int32_t>(sst.base.logicalSlotId),
+ .portActive = sst.base.slotState == config::V1_0::SlotState::ACTIVE,
+ };
+
+ return {
+ .cardState = static_cast<int32_t>(sst.base.cardState),
+ .atr = sst.base.atr,
+ .eid = sst.eid,
+ .portInfo = {portInfo},
+ };
+}
+
+uint8_t toAidl(const config::V1_1::ModemInfo& info) {
+ return info.modemId;
+}
+
+aidl::PhoneCapability toAidl(const config::V1_1::PhoneCapability& phoneCapability) {
+ return {
+ .maxActiveData = static_cast<int8_t>(phoneCapability.maxActiveData),
+ .maxActiveInternetData = static_cast<int8_t>(phoneCapability.maxActiveInternetData),
+ .isInternetLingeringSupported = phoneCapability.isInternetLingeringSupported,
+ .logicalModemIds = toAidl(phoneCapability.logicalModemList),
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/structs.h b/radio/aidl/compat/libradiocompat/config/structs.h
new file mode 100644
index 0000000..b8a0385
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/config/structs.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/radio/config/PhoneCapability.h>
+#include <aidl/android/hardware/radio/config/SimSlotStatus.h>
+#include <aidl/android/hardware/radio/config/SlotPortMapping.h>
+#include <android/hardware/radio/config/1.1/types.h>
+#include <android/hardware/radio/config/1.2/types.h>
+
+namespace android::hardware::radio::compat {
+
+hidl_vec<uint32_t> //
+toHidl(const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap);
+
+aidl::android::hardware::radio::config::SimSlotStatus //
+toAidl(const config::V1_0::SimSlotStatus& sst);
+aidl::android::hardware::radio::config::SimSlotStatus //
+toAidl(const config::V1_2::SimSlotStatus& sst);
+
+uint8_t toAidl(const config::V1_1::ModemInfo& info);
+
+aidl::android::hardware::radio::config::PhoneCapability //
+toAidl(const config::V1_1::PhoneCapability& pc);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
new file mode 100644
index 0000000..fdb1273
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -0,0 +1,180 @@
+/*
+ * 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 <libradiocompat/RadioData.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Data"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::data;
+namespace aidlCommon = ::aidl::android::hardware::radio;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioData::allocatePduSessionId(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->allocatePduSessionId(serial);
+ } else {
+ respond().allocatePduSessionIdResponse(notSupported(serial), 0);
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::cancelHandover(int32_t serial, int32_t callId) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->cancelHandover(serial, callId);
+ } else {
+ respond().cancelHandoverResponse(notSupported(serial));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::deactivateDataCall(int32_t serial, int32_t cid,
+ aidl::DataRequestReason reason) {
+ LOG_CALL << serial;
+ mHal1_5->deactivateDataCall_1_2(serial, cid, V1_2::DataRequestReason(reason));
+ return ok();
+}
+
+ScopedAStatus RadioData::getDataCallList(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getDataCallList(serial);
+ return ok();
+}
+
+ScopedAStatus RadioData::getSlicingConfig(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->getSlicingConfig(serial);
+ } else {
+ respond().getSlicingConfigResponse(notSupported(serial), {});
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::releasePduSessionId(int32_t serial, int32_t id) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->releasePduSessionId(serial, id);
+ } else {
+ respond().releasePduSessionIdResponse(notSupported(serial));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::responseAcknowledgement() {
+ LOG_CALL;
+ mHal1_5->responseAcknowledgement();
+ return ok();
+}
+
+ScopedAStatus RadioData::setDataAllowed(int32_t serial, bool allow) {
+ LOG_CALL << serial;
+ mHal1_5->setDataAllowed(serial, allow);
+ return ok();
+}
+
+ScopedAStatus RadioData::setDataProfile(int32_t serial,
+ const std::vector<aidl::DataProfileInfo>& profiles) {
+ LOG_CALL << serial;
+ mHal1_5->setDataProfile_1_5(serial, toHidl(profiles));
+ return ok();
+}
+
+ScopedAStatus RadioData::setDataThrottling(int32_t serial, aidl::DataThrottlingAction dta,
+ int64_t completionDurationMs) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->setDataThrottling(serial, V1_6::DataThrottlingAction(dta), completionDurationMs);
+ } else {
+ respond().setDataThrottlingResponse(notSupported(serial));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::setInitialAttachApn(int32_t serial, const aidl::DataProfileInfo& info) {
+ LOG_CALL << serial;
+ mHal1_5->setInitialAttachApn_1_5(serial, toHidl(info));
+ return ok();
+}
+
+ScopedAStatus RadioData::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioDataResponse>& dataResponse,
+ const std::shared_ptr<aidl::IRadioDataIndication>& dataIndication) {
+ LOG_CALL << dataResponse << ' ' << dataIndication;
+
+ CHECK(dataResponse);
+ CHECK(dataIndication);
+
+ mRadioResponse->setResponseFunction(dataResponse);
+ mRadioIndication->setResponseFunction(dataIndication);
+
+ return ok();
+}
+
+ScopedAStatus RadioData::setupDataCall( //
+ int32_t serial, aidlCommon::AccessNetwork accessNetwork,
+ const aidl::DataProfileInfo& dataProfileInfo, bool roamingAllowed,
+ aidl::DataRequestReason reason, const std::vector<aidl::LinkAddress>& addresses,
+ const std::vector<std::string>& dnses, int32_t pduSessId,
+ const std::optional<aidl::SliceInfo>& sliceInfo,
+ const std::optional<aidl::TrafficDescriptor>& trDesc, bool matchAllRuleAllowed) {
+ if (mHal1_6) {
+ mHal1_6->setupDataCall_1_6( //
+ serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
+ V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
+ toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
+ toHidl<V1_6::OptionalTrafficDescriptor>(trDesc), matchAllRuleAllowed);
+ } else {
+ mHal1_5->setupDataCall_1_5( //
+ serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
+ V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::startHandover(int32_t serial, int32_t callId) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->startHandover(serial, callId);
+ } else {
+ respond().startHandoverResponse(notSupported(serial));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioData::startKeepalive(int32_t serial, const aidl::KeepaliveRequest& keepalive) {
+ LOG_CALL << serial;
+ mHal1_5->startKeepalive(serial, toHidl(keepalive));
+ return ok();
+}
+
+ScopedAStatus RadioData::stopKeepalive(int32_t serial, int32_t sessionHandle) {
+ LOG_CALL << serial;
+ mHal1_5->stopKeepalive(serial, sessionHandle);
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
new file mode 100644
index 0000000..f51d1a8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -0,0 +1,90 @@
+/*
+ * 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 <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "DataIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioDataIndication> dataCb) {
+ CHECK(dataCb);
+ mDataCb = dataCb;
+}
+
+Return<void> RadioIndication::dataCallListChanged(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_0::SetupDataCallResult>&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_4(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_4::SetupDataCallResult>&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_5(
+ V1_0::RadioIndicationType type, const hidl_vec<V1_5::SetupDataCallResult>& dcList) {
+ LOG_CALL << type;
+ CHECK_CB(mDataCb);
+ mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+ return {};
+}
+
+Return<void> RadioIndication::dataCallListChanged_1_6(
+ V1_0::RadioIndicationType type, const hidl_vec<V1_6::SetupDataCallResult>& dcList) {
+ LOG_CALL << type;
+ CHECK_CB(mDataCb);
+ mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+ return {};
+}
+
+Return<void> RadioIndication::keepaliveStatus(V1_0::RadioIndicationType type,
+ const V1_1::KeepaliveStatus& status) {
+ LOG_CALL << type;
+ CHECK_CB(mDataCb);
+ mDataCb->keepaliveStatus(toAidl(type), toAidl(status));
+ return {};
+}
+
+Return<void> RadioIndication::pcoData(V1_0::RadioIndicationType type,
+ const V1_0::PcoDataInfo& pco) {
+ LOG_CALL << type;
+ CHECK_CB(mDataCb);
+ mDataCb->pcoData(toAidl(type), toAidl(pco));
+ return {};
+}
+
+Return<void> RadioIndication::unthrottleApn(V1_0::RadioIndicationType type,
+ const hidl_string& apn) {
+ LOG_CALL << type;
+ CHECK_CB(mDataCb);
+ mDataCb->unthrottleApn(toAidl(type), apn);
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
new file mode 100644
index 0000000..171f692
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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 <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "DataResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioDataResponse> dataCb) {
+ CHECK(dataCb);
+ mDataCb = dataCb;
+}
+
+Return<void> RadioResponse::allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
+ int32_t id) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->allocatePduSessionIdResponse(toAidl(info), id);
+ return {};
+}
+
+Return<void> RadioResponse::cancelHandoverResponse(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->cancelHandoverResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->deactivateDataCallResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::SetupDataCallResult>&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_4(
+ const V1_0::RadioResponseInfo& info, const hidl_vec<V1_4::SetupDataCallResult>&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_5(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+ return {};
+}
+
+Return<void> RadioResponse::getDataCallListResponse_1_6(
+ const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+ return {};
+}
+
+Return<void> RadioResponse::getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
+ const V1_6::SlicingConfig& slicingConfig) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
+ return {};
+}
+
+Return<void> RadioResponse::releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->releasePduSessionIdResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setDataAllowedResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setDataAllowedResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setDataProfileResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setDataProfileResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setDataProfileResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setDataThrottlingResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setInitialAttachApnResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setInitialAttachApnResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SetupDataCallResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const V1_4::SetupDataCallResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
+ const V1_5::SetupDataCallResult& dcResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+ return {};
+}
+
+Return<void> RadioResponse::setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_6::SetupDataCallResult& dcResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+ return {};
+}
+
+Return<void> RadioResponse::startHandoverResponse(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->startHandoverResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+ const V1_1::KeepaliveStatus& status) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->startKeepaliveResponse(toAidl(info), toAidl(status));
+ return {};
+}
+
+Return<void> RadioResponse::stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mDataCb);
+ mDataCb->stopKeepaliveResponse(toAidl(info));
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/structs.cpp b/radio/aidl/compat/libradiocompat/data/structs.cpp
new file mode 100644
index 0000000..4ff89a1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/structs.cpp
@@ -0,0 +1,288 @@
+/*
+ * 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 "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::data;
+
+V1_5::DataProfileInfo toHidl(const aidl::DataProfileInfo& info) {
+ return {
+ .profileId = V1_0::DataProfileId{info.profileId},
+ .apn = info.apn,
+ .protocol = V1_4::PdpProtocolType{info.protocol},
+ .roamingProtocol = V1_4::PdpProtocolType{info.roamingProtocol},
+ .authType = V1_0::ApnAuthType{info.authType},
+ .user = info.user,
+ .password = info.password,
+ .type = V1_0::DataProfileInfoType{info.type},
+ .maxConnsTime = info.maxConnsTime,
+ .maxConns = info.maxConns,
+ .waitTime = info.waitTime,
+ .enabled = info.enabled,
+ .supportedApnTypesBitmap = toHidlBitfield<V1_5::ApnTypes>(info.supportedApnTypesBitmap),
+ .bearerBitmap = toHidlBitfield<V1_4::RadioAccessFamily>(info.bearerBitmap),
+ .mtuV4 = info.mtuV4,
+ .mtuV6 = info.mtuV6,
+ .preferred = info.preferred,
+ .persistent = info.persistent,
+ };
+}
+
+V1_5::LinkAddress toHidl(const aidl::LinkAddress& addr) {
+ return {
+ .address = addr.address,
+ .properties = addr.addressProperties,
+ .deprecationTime = static_cast<uint64_t>(addr.deprecationTime),
+ .expirationTime = static_cast<uint64_t>(addr.expirationTime),
+ };
+}
+
+aidl::SliceInfo toAidl(const V1_6::SliceInfo& info) {
+ return {
+ .sliceServiceType = static_cast<int8_t>(info.sst),
+ .sliceDifferentiator = info.sliceDifferentiator,
+ .mappedHplmnSst = static_cast<int8_t>(info.mappedHplmnSst),
+ .mappedHplmnSd = info.mappedHplmnSD,
+ .status = static_cast<int8_t>(info.status),
+ };
+}
+
+V1_6::SliceInfo toHidl(const aidl::SliceInfo& info) {
+ return {
+ .sst = static_cast<V1_6::SliceServiceType>(info.sliceServiceType),
+ .sliceDifferentiator = info.sliceDifferentiator,
+ .mappedHplmnSst = static_cast<V1_6::SliceServiceType>(info.mappedHplmnSst),
+ .mappedHplmnSD = info.mappedHplmnSd,
+ .status = V1_6::SliceStatus{info.status},
+ };
+}
+
+aidl::TrafficDescriptor toAidl(const V1_6::TrafficDescriptor& descr) {
+ return {
+ .dnn = toAidl(descr.dnn),
+ .osAppId = toAidl(descr.osAppId),
+ };
+}
+
+V1_6::TrafficDescriptor toHidl(const aidl::TrafficDescriptor& descr) {
+ return {
+ .dnn = toHidl<V1_6::OptionalDnn>(descr.dnn),
+ .osAppId = toHidl<V1_6::OptionalOsAppId>(descr.osAppId),
+ };
+}
+
+aidl::OsAppId toAidl(const V1_6::OsAppId& appId) {
+ return {
+ .osAppId = appId.osAppId,
+ };
+}
+
+V1_6::OsAppId toHidl(const aidl::OsAppId& appId) {
+ return {
+ .osAppId = appId.osAppId,
+ };
+}
+
+V1_1::KeepaliveRequest toHidl(const aidl::KeepaliveRequest& keep) {
+ return {
+ .type = V1_1::KeepaliveType{keep.type},
+ .sourceAddress = keep.sourceAddress,
+ .sourcePort = keep.sourcePort,
+ .destinationAddress = keep.destinationAddress,
+ .destinationPort = keep.destinationPort,
+ .maxKeepaliveIntervalMillis = keep.maxKeepaliveIntervalMillis,
+ .cid = keep.cid,
+ };
+}
+
+static aidl::QosBandwidth toAidl(const V1_6::QosBandwidth& bw) {
+ return {
+ .maxBitrateKbps = static_cast<int32_t>(bw.maxBitrateKbps),
+ .guaranteedBitrateKbps = static_cast<int32_t>(bw.guaranteedBitrateKbps),
+ };
+}
+
+static aidl::EpsQos toAidl(const V1_6::EpsQos& qos) {
+ return {
+ .qci = qos.qci,
+ .downlink = toAidl(qos.downlink),
+ .uplink = toAidl(qos.uplink),
+ };
+}
+
+static aidl::NrQos toAidl(const V1_6::NrQos& qos) {
+ return {
+ .fiveQi = qos.fiveQi,
+ .downlink = toAidl(qos.downlink),
+ .uplink = toAidl(qos.uplink),
+ .qfi = static_cast<int8_t>(qos.qfi),
+ .averagingWindowMs = qos.averagingWindowMs,
+ };
+}
+
+static std::variant<bool, aidl::EpsQos, aidl::NrQos> toAidl(const V1_6::Qos& qos) {
+ if (qos.getDiscriminator() == V1_6::Qos::hidl_discriminator::eps) return toAidl(qos.eps());
+ if (qos.getDiscriminator() == V1_6::Qos::hidl_discriminator::nr) return toAidl(qos.nr());
+ return false;
+}
+
+aidl::SetupDataCallResult toAidl(const V1_5::SetupDataCallResult& res) {
+ return {
+ .cause = aidl::DataCallFailCause(res.cause),
+ .suggestedRetryTime = res.suggestedRetryTime,
+ .cid = res.cid,
+ .active = static_cast<int32_t>(res.active),
+ .type = aidl::PdpProtocolType(res.type),
+ .ifname = res.ifname,
+ .addresses = toAidl(res.addresses),
+ .dnses = toAidl(res.dnses),
+ .gateways = toAidl(res.gateways),
+ .pcscf = toAidl(res.pcscf),
+ .mtuV4 = res.mtuV4,
+ .mtuV6 = res.mtuV6,
+ };
+}
+
+aidl::SetupDataCallResult toAidl(const V1_6::SetupDataCallResult& res) {
+ return {
+ .cause = aidl::DataCallFailCause(res.cause),
+ .suggestedRetryTime = res.suggestedRetryTime,
+ .cid = res.cid,
+ .active = static_cast<int32_t>(res.active),
+ .type = aidl::PdpProtocolType(res.type),
+ .ifname = res.ifname,
+ .addresses = toAidl(res.addresses),
+ .dnses = toAidl(res.dnses),
+ .gateways = toAidl(res.gateways),
+ .pcscf = toAidl(res.pcscf),
+ .mtuV4 = res.mtuV4,
+ .mtuV6 = res.mtuV6,
+ .defaultQos = toAidl(res.defaultQos),
+ .qosSessions = toAidl(res.qosSessions),
+ .handoverFailureMode = static_cast<int8_t>(res.handoverFailureMode),
+ .pduSessionId = res.pduSessionId,
+ .sliceInfo = toAidl(res.sliceInfo),
+ .trafficDescriptors = toAidl(res.trafficDescriptors),
+ };
+}
+
+aidl::LinkAddress toAidl(const V1_5::LinkAddress& addr) {
+ return {
+ .address = addr.address,
+ .addressProperties = addr.properties,
+ .deprecationTime = static_cast<int64_t>(addr.deprecationTime),
+ .expirationTime = static_cast<int64_t>(addr.expirationTime),
+ };
+}
+
+aidl::QosSession toAidl(const V1_6::QosSession& sess) {
+ return {
+ .qosSessionId = sess.qosSessionId,
+ .qos = toAidl(sess.qos),
+ .qosFilters = toAidl(sess.qosFilters),
+ };
+}
+
+static aidl::PortRange toAidl(const V1_6::PortRange& range) {
+ return {
+ .start = range.start,
+ .end = range.end,
+ };
+}
+
+static std::optional<aidl::PortRange> toAidl(const V1_6::MaybePort& opt) {
+ if (opt.getDiscriminator() == V1_6::MaybePort::hidl_discriminator::noinit) return std::nullopt;
+ return toAidl(opt.range()); // can't use MaybeX template - this field is not named "value"
+}
+
+aidl::QosFilter toAidl(const V1_6::QosFilter& filter) {
+ return {
+ .localAddresses = toAidl(filter.localAddresses),
+ .remoteAddresses = toAidl(filter.remoteAddresses),
+ .localPort = toAidl(filter.localPort),
+ .remotePort = toAidl(filter.remotePort),
+ .protocol = static_cast<int8_t>(filter.protocol),
+ .tos = toAidlVariant(filter.tos),
+ .flowLabel = toAidlVariant(filter.flowLabel),
+ .spi = toAidlVariant(filter.spi),
+ .direction = static_cast<int8_t>(filter.direction),
+ .precedence = filter.precedence,
+ };
+}
+
+aidl::KeepaliveStatus toAidl(const V1_1::KeepaliveStatus& status) {
+ return {
+ .sessionHandle = status.sessionHandle,
+ .code = static_cast<int32_t>(status.code),
+ };
+}
+
+aidl::PcoDataInfo toAidl(const V1_0::PcoDataInfo& info) {
+ return {
+ .cid = info.cid,
+ .bearerProto = info.bearerProto,
+ .pcoId = info.pcoId,
+ .contents = info.contents,
+ };
+}
+
+aidl::SlicingConfig toAidl(const V1_6::SlicingConfig& cfg) {
+ return {
+ .urspRules = toAidl(cfg.urspRules),
+ .sliceInfo = toAidl(cfg.sliceInfo),
+ };
+}
+
+aidl::UrspRule toAidl(const V1_6::UrspRule& rule) {
+ return {
+ .precedence = rule.precedence,
+ .trafficDescriptors = toAidl(rule.trafficDescriptors),
+ .routeSelectionDescriptor = toAidl(rule.routeSelectionDescriptor),
+ };
+}
+
+static int8_t toAidl(const V1_6::OptionalSscMode& opt) {
+ if (opt.getDiscriminator() == V1_6::OptionalSscMode::hidl_discriminator::noinit) {
+ return aidl::RouteSelectionDescriptor::SSC_MODE_UNKNOWN;
+ }
+ return static_cast<int8_t>(opt.value());
+}
+
+static aidl::PdpProtocolType toAidl(const V1_6::OptionalPdpProtocolType& opt) {
+ using discriminator = V1_6::OptionalPdpProtocolType::hidl_discriminator;
+ if (opt.getDiscriminator() == discriminator::noinit) return aidl::PdpProtocolType::UNKNOWN;
+ return aidl::PdpProtocolType(opt.value());
+}
+
+aidl::RouteSelectionDescriptor toAidl(const V1_6::RouteSelectionDescriptor& descr) {
+ return {
+ .precedence = static_cast<int8_t>(descr.precedence),
+ .sessionType = toAidl(descr.sessionType),
+ .sscMode = toAidl(descr.sscMode),
+ .sliceInfo = toAidl(descr.sliceInfo),
+ .dnn = toAidl(descr.dnn),
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/data/structs.h b/radio/aidl/compat/libradiocompat/data/structs.h
new file mode 100644
index 0000000..60fad57
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/data/structs.h
@@ -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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/DataProfileInfo.h>
+#include <aidl/android/hardware/radio/data/KeepaliveRequest.h>
+#include <aidl/android/hardware/radio/data/KeepaliveStatus.h>
+#include <aidl/android/hardware/radio/data/LinkAddress.h>
+#include <aidl/android/hardware/radio/data/OsAppId.h>
+#include <aidl/android/hardware/radio/data/PcoDataInfo.h>
+#include <aidl/android/hardware/radio/data/RouteSelectionDescriptor.h>
+#include <aidl/android/hardware/radio/data/SetupDataCallResult.h>
+#include <aidl/android/hardware/radio/data/SliceInfo.h>
+#include <aidl/android/hardware/radio/data/SlicingConfig.h>
+#include <aidl/android/hardware/radio/data/TrafficDescriptor.h>
+#include <aidl/android/hardware/radio/data/UrspRule.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_5::DataProfileInfo toHidl(const ::aidl::android::hardware::radio::data::DataProfileInfo& info);
+
+V1_5::LinkAddress toHidl(const ::aidl::android::hardware::radio::data::LinkAddress& addr);
+
+::aidl::android::hardware::radio::data::SliceInfo toAidl(const V1_6::SliceInfo& info);
+V1_6::SliceInfo toHidl(const ::aidl::android::hardware::radio::data::SliceInfo& info);
+
+::aidl::android::hardware::radio::data::TrafficDescriptor toAidl(const V1_6::TrafficDescriptor& td);
+V1_6::TrafficDescriptor toHidl(const ::aidl::android::hardware::radio::data::TrafficDescriptor& td);
+
+V1_1::KeepaliveRequest toHidl(const ::aidl::android::hardware::radio::data::KeepaliveRequest& keep);
+
+::aidl::android::hardware::radio::data::OsAppId toAidl(const V1_6::OsAppId& appId);
+V1_6::OsAppId toHidl(const ::aidl::android::hardware::radio::data::OsAppId& appId);
+
+::aidl::android::hardware::radio::data::SetupDataCallResult //
+toAidl(const V1_5::SetupDataCallResult& res);
+::aidl::android::hardware::radio::data::SetupDataCallResult //
+toAidl(const V1_6::SetupDataCallResult& res);
+
+::aidl::android::hardware::radio::data::LinkAddress toAidl(const V1_5::LinkAddress& addr);
+
+::aidl::android::hardware::radio::data::QosSession toAidl(const V1_6::QosSession& session);
+
+::aidl::android::hardware::radio::data::QosFilter toAidl(const V1_6::QosFilter& filter);
+
+::aidl::android::hardware::radio::data::KeepaliveStatus toAidl(const V1_1::KeepaliveStatus& status);
+
+::aidl::android::hardware::radio::data::PcoDataInfo toAidl(const V1_0::PcoDataInfo& info);
+
+::aidl::android::hardware::radio::data::SlicingConfig toAidl(const V1_6::SlicingConfig& cfg);
+
+::aidl::android::hardware::radio::data::UrspRule toAidl(const V1_6::UrspRule& rule);
+
+::aidl::android::hardware::radio::data::RouteSelectionDescriptor //
+toAidl(const V1_6::RouteSelectionDescriptor& descr);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/debug.h b/radio/aidl/compat/libradiocompat/debug.h
new file mode 100644
index 0000000..4158059
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/debug.h
@@ -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.
+ */
+#pragma once
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace debug {
+
+static constexpr bool kSuperVerbose = true;
+
+#define LOG_CALL \
+ if constexpr (debug::kSuperVerbose) LOG(VERBOSE) << (RADIO_MODULE ".") << __func__ << ' '
+
+#define CHECK_CB(field) \
+ if (!field) { \
+ LOG(WARNING) << "Callback not set"; \
+ return {}; \
+ }
+
+} // namespace debug
+
+inline std::ostream& operator<<(std::ostream& os, const V1_0::RadioIndicationType& type) {
+ return os << static_cast<int>(type);
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
new file mode 100644
index 0000000..a412c34
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
@@ -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.
+ */
+#pragma once
+
+#include "RadioIndication.h"
+#include "RadioResponse.h"
+
+#include <android/hardware/radio/1.6/IRadio.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioCompatBase {
+ protected:
+ sp<V1_5::IRadio> mHal1_5;
+ sp<V1_6::IRadio> mHal1_6;
+
+ sp<RadioResponse> mRadioResponse;
+ sp<RadioIndication> mRadioIndication;
+
+ V1_6::IRadioResponse& respond();
+
+ public:
+ RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
+ sp<RadioIndication> radioIndication);
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
new file mode 100644
index 0000000..31ad207
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -0,0 +1,66 @@
+/*
+ * 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/radio/config/BnRadioConfig.h>
+#include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
+#include <android/hardware/radio/config/1.3/IRadioConfig.h>
+#include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
+
+namespace android::hardware::radio::compat {
+
+/**
+ * HAL translator from HIDL IRadioConfig to AIDL IRadioConfig.
+ *
+ * This class wraps existing HIDL implementation (either a binder stub or real
+ * class implementing the HAL) and implements AIDL HAL. It's up to the caller to
+ * fetch source implementation and publish resulting HAL instance.
+ */
+class RadioConfig : public aidl::android::hardware::radio::config::BnRadioConfig {
+ sp<config::V1_1::IRadioConfig> mHal1_1;
+ sp<config::V1_3::IRadioConfig> mHal1_3;
+
+ sp<config::V1_3::IRadioConfigResponse> mRadioConfigResponse;
+ sp<config::V1_2::IRadioConfigIndication> mRadioConfigIndication;
+
+ ::ndk::ScopedAStatus getHalDeviceCapabilities(int32_t serial) override;
+ ::ndk::ScopedAStatus getNumOfLiveModems(int32_t serial) override;
+ ::ndk::ScopedAStatus getPhoneCapability(int32_t serial) override;
+ ::ndk::ScopedAStatus getSimSlotsStatus(int32_t serial) override;
+ ::ndk::ScopedAStatus setNumOfLiveModems(int32_t serial, int8_t numOfLiveModems) override;
+ ::ndk::ScopedAStatus setPreferredDataModem(int32_t serial, int8_t modemId) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse>&
+ radioConfigResponse,
+ const std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication>&
+ radioConfigIndication) override;
+ ::ndk::ScopedAStatus setSimSlotsMapping(
+ int32_t serial,
+ const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
+ override;
+
+ config::V1_3::IRadioConfigResponse& respond();
+
+ public:
+ /**
+ * Constructs AIDL IRadioConfig instance wrapping existing HIDL IRadioConfig instance.
+ *
+ * \param hidlHal existing HIDL IRadioConfig HAL instance
+ */
+ RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal);
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
new file mode 100644
index 0000000..900a669
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -0,0 +1,70 @@
+/*
+ * 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 "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/data/BnRadioData.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioData : public RadioCompatBase, public aidl::android::hardware::radio::data::BnRadioData {
+ ::ndk::ScopedAStatus allocatePduSessionId(int32_t serial) override;
+ ::ndk::ScopedAStatus cancelHandover(int32_t serial, int32_t callId) override;
+ ::ndk::ScopedAStatus deactivateDataCall(
+ int32_t serial, int32_t cid,
+ ::aidl::android::hardware::radio::data::DataRequestReason reason) override;
+ ::ndk::ScopedAStatus getDataCallList(int32_t serial) override;
+ ::ndk::ScopedAStatus getSlicingConfig(int32_t serial) override;
+ ::ndk::ScopedAStatus releasePduSessionId(int32_t serial, int32_t id) override;
+ ::ndk::ScopedAStatus responseAcknowledgement() override;
+ ::ndk::ScopedAStatus setDataAllowed(int32_t serial, bool allow) override;
+ ::ndk::ScopedAStatus setDataProfile(
+ int32_t serial,
+ const std::vector<::aidl::android::hardware::radio::data::DataProfileInfo>& profiles)
+ override;
+ ::ndk::ScopedAStatus setDataThrottling(
+ int32_t serial,
+ ::aidl::android::hardware::radio::data::DataThrottlingAction dataThrottlingAction,
+ int64_t completionDurationMillis) override;
+ ::ndk::ScopedAStatus setInitialAttachApn(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::data::DataProfileInfo& dpInfo) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse>&
+ radioDataResponse,
+ const std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication>&
+ radioDataIndication) override;
+ ::ndk::ScopedAStatus setupDataCall(
+ int32_t serial, ::aidl::android::hardware::radio::AccessNetwork accessNetwork,
+ const ::aidl::android::hardware::radio::data::DataProfileInfo& dataProfileInfo,
+ bool roamingAllowed, ::aidl::android::hardware::radio::data::DataRequestReason reason,
+ const std::vector<::aidl::android::hardware::radio::data::LinkAddress>& addresses,
+ const std::vector<std::string>& dnses, int32_t pduSessionId,
+ const std::optional<::aidl::android::hardware::radio::data::SliceInfo>& sliceInfo,
+ const std::optional<::aidl::android::hardware::radio::data::TrafficDescriptor>& trDescr,
+ bool matchAllRuleAllowed) override;
+ ::ndk::ScopedAStatus startHandover(int32_t serial, int32_t callId) override;
+ ::ndk::ScopedAStatus startKeepalive(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::data::KeepaliveRequest& keepalive) override;
+ ::ndk::ScopedAStatus stopKeepalive(int32_t serial, int32_t sessionHandle) override;
+
+ 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
new file mode 100644
index 0000000..20e0973
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -0,0 +1,199 @@
+/*
+ * 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/radio/data/IRadioDataIndication.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>
+#include <aidl/android/hardware/radio/sim/IRadioSimIndication.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoiceIndication.h>
+#include <android/hardware/radio/1.6/IRadioIndication.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioIndication : public V1_6::IRadioIndication {
+ std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> mDataCb;
+ std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+ mMessagingCb;
+ std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> mModemCb;
+ std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> mNetworkCb;
+ std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> mSimCb;
+ std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> mVoiceCb;
+
+ // IRadioIndication @ 1.0
+ Return<void> radioStateChanged(V1_0::RadioIndicationType type,
+ V1_0::RadioState radioState) override;
+ Return<void> callStateChanged(V1_0::RadioIndicationType type) override;
+ Return<void> networkStateChanged(V1_0::RadioIndicationType type) override;
+ Return<void> newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) override;
+ Return<void> newSmsStatusReport(V1_0::RadioIndicationType type,
+ const hidl_vec<uint8_t>& pdu) override;
+ Return<void> newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) override;
+ Return<void> onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+ const hidl_string& msg) override;
+ Return<void> nitzTimeReceived(V1_0::RadioIndicationType type, const hidl_string& nitzTime,
+ uint64_t receivedTime) override;
+ Return<void> currentSignalStrength(V1_0::RadioIndicationType type,
+ const V1_0::SignalStrength& signalStrength) override;
+ Return<void> dataCallListChanged(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_0::SetupDataCallResult>& dcList) override;
+ Return<void> suppSvcNotify(V1_0::RadioIndicationType type,
+ const V1_0::SuppSvcNotification& suppSvc) override;
+ Return<void> stkSessionEnd(V1_0::RadioIndicationType type) override;
+ Return<void> stkProactiveCommand(V1_0::RadioIndicationType type,
+ const hidl_string& cmd) override;
+ Return<void> stkEventNotify(V1_0::RadioIndicationType type, const hidl_string& cmd) override;
+ Return<void> stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) override;
+ Return<void> simSmsStorageFull(V1_0::RadioIndicationType type) override;
+ Return<void> simRefresh(V1_0::RadioIndicationType type,
+ const V1_0::SimRefreshResult& refreshResult) override;
+ Return<void> callRing(V1_0::RadioIndicationType type, bool isGsm,
+ const V1_0::CdmaSignalInfoRecord& record) override;
+ Return<void> simStatusChanged(V1_0::RadioIndicationType type) override;
+ Return<void> cdmaNewSms(V1_0::RadioIndicationType type,
+ const V1_0::CdmaSmsMessage& msg) override;
+ Return<void> newBroadcastSms(V1_0::RadioIndicationType type,
+ const hidl_vec<uint8_t>& data) override;
+ Return<void> cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) override;
+ Return<void> restrictedStateChanged(V1_0::RadioIndicationType type,
+ V1_0::PhoneRestrictedState state) override;
+ Return<void> enterEmergencyCallbackMode(V1_0::RadioIndicationType type) override;
+ Return<void> cdmaCallWaiting(V1_0::RadioIndicationType type,
+ const V1_0::CdmaCallWaiting& callWaitingRecord) override;
+ Return<void> cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+ V1_0::CdmaOtaProvisionStatus status) override;
+ Return<void> cdmaInfoRec(V1_0::RadioIndicationType type,
+ const V1_0::CdmaInformationRecords& records) override;
+ Return<void> indicateRingbackTone(V1_0::RadioIndicationType type, bool start) override;
+ Return<void> resendIncallMute(V1_0::RadioIndicationType type) override;
+ Return<void> cdmaSubscriptionSourceChanged(V1_0::RadioIndicationType type,
+ V1_0::CdmaSubscriptionSource cdmaSource) override;
+ Return<void> cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) override;
+ Return<void> exitEmergencyCallbackMode(V1_0::RadioIndicationType type) override;
+ Return<void> rilConnected(V1_0::RadioIndicationType type) override;
+ Return<void> voiceRadioTechChanged(V1_0::RadioIndicationType type,
+ V1_0::RadioTechnology rat) override;
+ Return<void> cellInfoList(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_0::CellInfo>& records) override;
+ Return<void> imsNetworkStateChanged(V1_0::RadioIndicationType type) override;
+ Return<void> subscriptionStatusChanged(V1_0::RadioIndicationType type, bool activate) override;
+ Return<void> srvccStateNotify(V1_0::RadioIndicationType type, V1_0::SrvccState state) override;
+ Return<void> hardwareConfigChanged(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_0::HardwareConfig>& configs) override;
+ Return<void> radioCapabilityIndication(V1_0::RadioIndicationType type,
+ const V1_0::RadioCapability& rc) override;
+ Return<void> onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+ const V1_0::StkCcUnsolSsResult& ss) override;
+ Return<void> stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+ const hidl_string& alpha) override;
+ Return<void> lceData(V1_0::RadioIndicationType type, const V1_0::LceDataInfo& lce) override;
+ Return<void> pcoData(V1_0::RadioIndicationType type, const V1_0::PcoDataInfo& pco) override;
+ Return<void> modemReset(V1_0::RadioIndicationType type, const hidl_string& reason) override;
+
+ // IRadioIndication @ 1.1
+ Return<void> carrierInfoForImsiEncryption(V1_0::RadioIndicationType info) override;
+ Return<void> networkScanResult(V1_0::RadioIndicationType type,
+ const V1_1::NetworkScanResult& result) override;
+ Return<void> keepaliveStatus(V1_0::RadioIndicationType type,
+ const V1_1::KeepaliveStatus& status) override;
+
+ // IRadioIndication @ 1.2
+ Return<void> networkScanResult_1_2(V1_0::RadioIndicationType type,
+ const V1_2::NetworkScanResult& result) override;
+ Return<void> cellInfoList_1_2(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_2::CellInfo>& records) override;
+ Return<void> currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+ const V1_2::LinkCapacityEstimate& lce) override;
+ Return<void> currentPhysicalChannelConfigs(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_2::PhysicalChannelConfig>& configs) override;
+ Return<void> currentSignalStrength_1_2(V1_0::RadioIndicationType type,
+ const V1_2::SignalStrength& signalStrength) override;
+
+ // IRadioIndication @ 1.4
+ Return<void> currentEmergencyNumberList(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_4::EmergencyNumber>& emergencyNumberList) override;
+ Return<void> cellInfoList_1_4(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_4::CellInfo>& records) override;
+ Return<void> networkScanResult_1_4(V1_0::RadioIndicationType type,
+ const V1_4::NetworkScanResult& result) override;
+ Return<void> currentPhysicalChannelConfigs_1_4(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_4::PhysicalChannelConfig>& configs) override;
+ Return<void> dataCallListChanged_1_4(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_4::SetupDataCallResult>& dcList) override;
+ Return<void> currentSignalStrength_1_4(V1_0::RadioIndicationType type,
+ const V1_4::SignalStrength& signalStrength) override;
+
+ // IRadioIndication @ 1.5
+ Return<void> uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
+ bool enabled) override;
+ Return<void> registrationFailed( //
+ V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+ const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
+ int32_t additionalCauseCode) override;
+ Return<void> barringInfoChanged( //
+ V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+ const hidl_vec<V1_5::BarringInfo>& barringInfos) override;
+ Return<void> cellInfoList_1_5(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_5::CellInfo>& records) override;
+ Return<void> networkScanResult_1_5(V1_0::RadioIndicationType type,
+ const V1_5::NetworkScanResult& result) override;
+ Return<void> dataCallListChanged_1_5(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_5::SetupDataCallResult>& dcList) override;
+
+ // IRadioIndication @ 1.6
+ Return<void> dataCallListChanged_1_6(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_6::SetupDataCallResult>& dcList) override;
+ Return<void> unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override;
+ Return<void> currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type,
+ const V1_6::LinkCapacityEstimate& lce) override;
+ Return<void> currentSignalStrength_1_6(V1_0::RadioIndicationType type,
+ const V1_6::SignalStrength& signalStrength) override;
+ Return<void> cellInfoList_1_6(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_6::CellInfo>& records) override;
+ Return<void> networkScanResult_1_6(V1_0::RadioIndicationType type,
+ const V1_6::NetworkScanResult& result) override;
+ Return<void> currentPhysicalChannelConfigs_1_6(
+ V1_0::RadioIndicationType type,
+ const hidl_vec<V1_6::PhysicalChannelConfig>& configs) override;
+ Return<void> simPhonebookChanged(V1_0::RadioIndicationType type) override;
+ Return<void> simPhonebookRecordsReceived(
+ V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
+ const hidl_vec<V1_6::PhonebookRecordInfo>& records) override;
+
+ public:
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+ radioMessagingIndication);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> modmCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> ni);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
new file mode 100644
index 0000000..0cd3381
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -0,0 +1,89 @@
+/*
+ * 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 "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/messaging/BnRadioMessaging.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioMessaging : public RadioCompatBase,
+ public aidl::android::hardware::radio::messaging::BnRadioMessaging {
+ ::ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
+ const std::string& ackPdu) override;
+ ::ndk::ScopedAStatus acknowledgeLastIncomingCdmaSms(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::CdmaSmsAck& smsAck) override;
+ ::ndk::ScopedAStatus acknowledgeLastIncomingGsmSms(
+ int32_t serial, bool success,
+ ::aidl::android::hardware::radio::messaging::SmsAcknowledgeFailCause cause) override;
+ ::ndk::ScopedAStatus cancelPendingUssd(int32_t serial) override;
+ ::ndk::ScopedAStatus deleteSmsOnRuim(int32_t serial, int32_t index) override;
+ ::ndk::ScopedAStatus deleteSmsOnSim(int32_t serial, int32_t index) override;
+ ::ndk::ScopedAStatus getCdmaBroadcastConfig(int32_t serial) override;
+ ::ndk::ScopedAStatus getGsmBroadcastConfig(int32_t serial) override;
+ ::ndk::ScopedAStatus getSmscAddress(int32_t serial) override;
+ ::ndk::ScopedAStatus reportSmsMemoryStatus(int32_t serial, bool available) override;
+ ::ndk::ScopedAStatus responseAcknowledgement() override;
+ ::ndk::ScopedAStatus sendCdmaSms(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& sms) override;
+ ::ndk::ScopedAStatus sendCdmaSmsExpectMore(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& sms) override;
+ ::ndk::ScopedAStatus sendImsSms(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::ImsSmsMessage& message) override;
+ ::ndk::ScopedAStatus sendSms(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
+ ::ndk::ScopedAStatus sendSmsExpectMore(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& message) override;
+ ::ndk::ScopedAStatus sendUssd(int32_t serial, const std::string& ussd) override;
+ ::ndk::ScopedAStatus setCdmaBroadcastActivation(int32_t serial, bool activate) override;
+ ::ndk::ScopedAStatus setCdmaBroadcastConfig(
+ int32_t serial,
+ const std::vector<
+ ::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo>&
+ configInfo) override;
+ ::ndk::ScopedAStatus setGsmBroadcastActivation(int32_t serial, bool activate) override;
+ ::ndk::ScopedAStatus setGsmBroadcastConfig(
+ int32_t serial,
+ const std::vector<
+ ::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo>&
+ configInfo) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<
+ ::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>&
+ radioMessagingResponse,
+ const std::shared_ptr<
+ ::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>&
+ radioMessagingIndication) override;
+ ::ndk::ScopedAStatus setSmscAddress(int32_t serial, const std::string& smsc) override;
+ ::ndk::ScopedAStatus writeSmsToRuim(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::CdmaSmsWriteArgs& cdmaSms) override;
+ ::ndk::ScopedAStatus writeSmsToSim(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::messaging::SmsWriteArgs& smsWriteArgs) override;
+
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // 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
new file mode 100644
index 0000000..666ff47
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -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.
+ */
+#pragma once
+
+#include "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/modem/BnRadioModem.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioModem : public RadioCompatBase,
+ public aidl::android::hardware::radio::modem::BnRadioModem {
+ ::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 getHardwareConfig(int32_t serial) override;
+ ::ndk::ScopedAStatus getModemActivityInfo(int32_t serial) override;
+ ::ndk::ScopedAStatus getModemStackStatus(int32_t serial) override;
+ ::ndk::ScopedAStatus getRadioCapability(int32_t serial) override;
+ ::ndk::ScopedAStatus nvReadItem(
+ int32_t serial, ::aidl::android::hardware::radio::modem::NvItem itemId) override;
+ ::ndk::ScopedAStatus nvResetConfig(
+ int32_t serial, ::aidl::android::hardware::radio::modem::ResetNvType type) override;
+ ::ndk::ScopedAStatus nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>& prl) override;
+ ::ndk::ScopedAStatus nvWriteItem(
+ int32_t serial, const ::aidl::android::hardware::radio::modem::NvWriteItem& i) override;
+ ::ndk::ScopedAStatus requestShutdown(int32_t serial) override;
+ ::ndk::ScopedAStatus responseAcknowledgement() override;
+ ::ndk::ScopedAStatus sendDeviceState(
+ int32_t serial, ::aidl::android::hardware::radio::modem::DeviceStateType stateType,
+ bool state) override;
+ ::ndk::ScopedAStatus setRadioCapability(
+ int32_t s, const ::aidl::android::hardware::radio::modem::RadioCapability& rc) override;
+ ::ndk::ScopedAStatus setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
+ bool preferredForEmergencyCall) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse>&
+ radioModemResponse,
+ const std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication>&
+ radioModemIndication) override;
+
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
new file mode 100644
index 0000000..c776fd1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -0,0 +1,96 @@
+/*
+ * 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 "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/network/BnRadioNetwork.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioNetwork : public RadioCompatBase,
+ public aidl::android::hardware::radio::network::BnRadioNetwork {
+ ::ndk::ScopedAStatus getAllowedNetworkTypesBitmap(int32_t serial) override;
+ ::ndk::ScopedAStatus getAvailableBandModes(int32_t serial) override;
+ ::ndk::ScopedAStatus getAvailableNetworks(int32_t serial) override;
+ ::ndk::ScopedAStatus getBarringInfo(int32_t serial) override;
+ ::ndk::ScopedAStatus getCdmaRoamingPreference(int32_t serial) override;
+ ::ndk::ScopedAStatus getCellInfoList(int32_t serial) override;
+ ::ndk::ScopedAStatus getDataRegistrationState(int32_t serial) override;
+ ::ndk::ScopedAStatus getImsRegistrationState(int32_t serial) override;
+ ::ndk::ScopedAStatus getNetworkSelectionMode(int32_t serial) override;
+ ::ndk::ScopedAStatus getOperator(int32_t serial) override;
+ ::ndk::ScopedAStatus getSignalStrength(int32_t serial) override;
+ ::ndk::ScopedAStatus getSystemSelectionChannels(int32_t serial) override;
+ ::ndk::ScopedAStatus getVoiceRadioTechnology(int32_t serial) override;
+ ::ndk::ScopedAStatus getVoiceRegistrationState(int32_t serial) override;
+ ::ndk::ScopedAStatus isNrDualConnectivityEnabled(int32_t serial) override;
+ ::ndk::ScopedAStatus responseAcknowledgement() override;
+ ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(
+ int32_t serial,
+ ::aidl::android::hardware::radio::RadioAccessFamily networkTypeBitmap) override;
+ ::ndk::ScopedAStatus setBandMode(
+ int32_t serial, ::aidl::android::hardware::radio::network::RadioBandMode mode) override;
+ ::ndk::ScopedAStatus setBarringPassword(int32_t serial, const std::string& facility,
+ const std::string& oldPassword,
+ const std::string& newPassword) override;
+ ::ndk::ScopedAStatus setCdmaRoamingPreference(
+ int32_t serial,
+ ::aidl::android::hardware::radio::network::CdmaRoamingType type) override;
+ ::ndk::ScopedAStatus setCellInfoListRate(int32_t serial, int32_t rate) override;
+ ::ndk::ScopedAStatus setIndicationFilter(
+ int32_t serial,
+ ::aidl::android::hardware::radio::network::IndicationFilter indicationFilter) override;
+ ::ndk::ScopedAStatus setLinkCapacityReportingCriteria(
+ int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps,
+ int32_t hysteresisUlKbps, const std::vector<int32_t>& thresholdsDownlinkKbps,
+ const std::vector<int32_t>& thresholdsUplinkKbps,
+ ::aidl::android::hardware::radio::AccessNetwork accessNetwork) override;
+ ::ndk::ScopedAStatus setLocationUpdates(int32_t serial, bool enable) override;
+ ::ndk::ScopedAStatus setNetworkSelectionModeAutomatic(int32_t serial) override;
+ ::ndk::ScopedAStatus setNetworkSelectionModeManual(
+ int32_t serial, const std::string& operatorNumeric,
+ ::aidl::android::hardware::radio::AccessNetwork ran) override;
+ ::ndk::ScopedAStatus setNrDualConnectivityState(
+ int32_t serial,
+ ::aidl::android::hardware::radio::network::NrDualConnectivityState nrSt) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse>&
+ radioNetworkResponse,
+ const std::shared_ptr<
+ ::aidl::android::hardware::radio::network::IRadioNetworkIndication>&
+ radioNetworkIndication) override;
+ ::ndk::ScopedAStatus setSignalStrengthReportingCriteria(
+ int32_t serial,
+ const std::vector<::aidl::android::hardware::radio::network::SignalThresholdInfo>&
+ signalThresholdInfos) override;
+ ::ndk::ScopedAStatus setSuppServiceNotifications(int32_t serial, bool enable) override;
+ ::ndk::ScopedAStatus setSystemSelectionChannels(
+ int32_t serial, bool specifyChannels,
+ const std::vector<::aidl::android::hardware::radio::network::RadioAccessSpecifier>&
+ specifiers) override;
+ ::ndk::ScopedAStatus startNetworkScan(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::network::NetworkScanRequest& request) override;
+ ::ndk::ScopedAStatus stopNetworkScan(int32_t serial) override;
+ ::ndk::ScopedAStatus supplyNetworkDepersonalization(int32_t serial,
+ const std::string& netPin) override;
+
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
new file mode 100644
index 0000000..5db963f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -0,0 +1,427 @@
+/*
+ * 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/radio/data/IRadioDataResponse.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>
+#include <aidl/android/hardware/radio/sim/IRadioSimResponse.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoiceResponse.h>
+#include <android/hardware/radio/1.6/IRadioResponse.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioResponse : public V1_6::IRadioResponse {
+ std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> mDataCb;
+ std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+ mMessagingCb;
+ std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> mModemCb;
+ std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> mNetworkCb;
+ std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> mSimCb;
+ std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> mVoiceCb;
+
+ // IRadioResponse @ 1.0
+ Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::CardStatus& cardStatus) override;
+ Return<void> supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> supplyNetworkDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) override;
+ Return<void> getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::Call>& calls) override;
+ Return<void> dialResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& imsi) override;
+ Return<void> hangupConnectionResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> hangupForegroundResumeBackgroundResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> switchWaitingOrHoldingAndActiveResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> conferenceResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> rejectCallResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getLastCallFailCauseResponse(
+ const V1_0::RadioResponseInfo& info,
+ const V1_0::LastCallFailCauseInfo& failCauseinfo) override;
+ Return<void> getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SignalStrength& sigStrength) override;
+ Return<void> getVoiceRegistrationStateResponse(
+ const V1_0::RadioResponseInfo& info,
+ const V1_0::VoiceRegStateResult& voiceRegResponse) override;
+ Return<void> getDataRegistrationStateResponse(
+ const V1_0::RadioResponseInfo& info,
+ const V1_0::DataRegStateResult& dataRegResponse) override;
+ Return<void> getOperatorResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& longName, const hidl_string& shortName,
+ const hidl_string& numeric) override;
+ Return<void> setRadioPowerResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> sendDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> sendSmsResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> setupDataCallResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SetupDataCallResult& dcResponse) override;
+ Return<void> iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& iccIo) override;
+ Return<void> sendUssdResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+ int32_t m) override;
+ Return<void> setClirResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCallForwardStatusResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::CallForwardInfo>& callForwardInfos) override;
+ Return<void> setCallForwardResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+ int32_t serviceClass) override;
+ Return<void> setCallWaitingResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> acknowledgeLastIncomingGsmSmsResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> acceptCallResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t response) override;
+ Return<void> setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t retry) override;
+ Return<void> setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+ bool manual) override;
+ Return<void> setNetworkSelectionModeAutomaticResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> setNetworkSelectionModeManualResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> getAvailableNetworksResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::OperatorInfo>& networkInfos) override;
+ Return<void> startDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> stopDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& version) override;
+ Return<void> separateConnectionResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setMuteResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) override;
+ Return<void> getClipResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::ClipStatus status) override;
+ Return<void> getDataCallListResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::SetupDataCallResult>& dcResponse) override;
+ Return<void> setSuppServiceNotificationsResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> writeSmsToSimResponse(const V1_0::RadioResponseInfo& info, int32_t index) override;
+ Return<void> deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setBandModeResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getAvailableBandModesResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::RadioBandMode>& bandModes) override;
+ Return<void> sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& commandResponse) override;
+ Return<void> sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> handleStkCallSetupRequestFromSimResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::PreferredNetworkType nwType) override;
+ Return<void> getNeighboringCidsResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::NeighboringCell>& cells) override;
+ Return<void> setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::CdmaRoamingType type) override;
+ Return<void> setTTYModeResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::TtyMode mode) override;
+ Return<void> setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+ bool enable) override;
+ Return<void> sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> acknowledgeLastIncomingCdmaSmsResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> getGsmBroadcastConfigResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& configs) override;
+ Return<void> setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCdmaBroadcastConfigResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) override;
+ Return<void> setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setCdmaBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCDMASubscriptionResponse( //
+ const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
+ const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) override;
+ Return<void> writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+ uint32_t index) override;
+ Return<void> deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getDeviceIdentityResponse( //
+ const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
+ const hidl_string& esn, const hidl_string& meid) override;
+ Return<void> exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& smsc) override;
+ Return<void> setSmscAddressResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::CdmaSubscriptionSource source) override;
+ Return<void> requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& response) override;
+ Return<void> acknowledgeIncomingGsmSmsWithPduResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& iccIo) override;
+ Return<void> getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::RadioTechnology rat) override;
+ Return<void> getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::CellInfo>& cellInfo) override;
+ Return<void> setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getImsRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+ bool isRegistered,
+ V1_0::RadioTechnologyFamily ratFamily) override;
+ Return<void> sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& result) override;
+ Return<void> iccOpenLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+ int32_t channelId,
+ const hidl_vec<int8_t>& selectResponse) override;
+ Return<void> iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> iccTransmitApduLogicalChannelResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& result) override;
+ Return<void> nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& result) override;
+ Return<void> nvWriteItemResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> nvResetConfigResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setDataAllowedResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getHardwareConfigResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::HardwareConfig>& config) override;
+ Return<void> requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& result) override;
+ Return<void> setDataProfileResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> requestShutdownResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::RadioCapability& rc) override;
+ Return<void> setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::RadioCapability& rc) override;
+ Return<void> startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::LceStatusInfo& statusInfo) override;
+ Return<void> stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::LceStatusInfo& statusInfo) override;
+ Return<void> pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::LceDataInfo& lceInfo) override;
+ Return<void> getModemActivityInfoResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::ActivityStatsInfo& activityInfo) override;
+ Return<void> setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+ int32_t numAllowed) override;
+ Return<void> getAllowedCarriersResponse(const V1_0::RadioResponseInfo& info, bool allAllowed,
+ const V1_0::CarrierRestrictions& carriers) override;
+ Return<void> sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> acknowledgeRequest(int32_t serial) override;
+
+ // IRadioResponse @ 1.1
+ Return<void> setCarrierInfoForImsiEncryptionResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) override;
+ Return<void> startNetworkScanResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
+ const V1_1::KeepaliveStatus& status) override;
+ Return<void> stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) override;
+
+ // IRadioResponse @ 1.2
+ Return<void> getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_2::CellInfo>& cellInfo) override;
+ Return<void> getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const V1_2::CardStatus& cardStatus) override;
+ Return<void> setSignalStrengthReportingCriteriaResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> setLinkCapacityReportingCriteriaResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_2::Call>& calls) override;
+ Return<void> getSignalStrengthResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const V1_2::SignalStrength& signalStrength) override;
+ Return<void> getVoiceRegistrationStateResponse_1_2(
+ const V1_0::RadioResponseInfo& info,
+ const V1_2::VoiceRegStateResult& voiceRegResponse) override;
+ Return<void> getDataRegistrationStateResponse_1_2(
+ const V1_0::RadioResponseInfo& info,
+ const V1_2::DataRegStateResult& dataRegResponse) override;
+
+ // IRadioResponse @ 1.3
+ Return<void> setSystemSelectionChannelsResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> enableModemResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+ bool isEnabled) override;
+
+ // IRadioResponse @ 1.4
+ Return<void> emergencyDialResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_4::CellInfo>& cellInfo) override;
+ Return<void> getDataRegistrationStateResponse_1_4(
+ const V1_0::RadioResponseInfo& info,
+ const V1_4::DataRegStateResult& dataRegResponse) override;
+ Return<void> getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const V1_4::CardStatus& cardStatus) override;
+ Return<void> getPreferredNetworkTypeBitmapResponse(
+ const V1_0::RadioResponseInfo& info,
+ hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+ Return<void> setPreferredNetworkTypeBitmapResponse(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> getDataCallListResponse_1_4(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_4::SetupDataCallResult>& dcResponse) override;
+ Return<void> setupDataCallResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const V1_4::SetupDataCallResult& dcResponse) override;
+ Return<void> setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getAllowedCarriersResponse_1_4(
+ const V1_0::RadioResponseInfo& info,
+ const V1_4::CarrierRestrictionsWithPriority& carriers,
+ V1_4::SimLockMultiSimPolicy multiSimPolicy) override;
+ Return<void> getSignalStrengthResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const V1_4::SignalStrength& signalStrength) override;
+
+ // IRadioResponse @ 1.5
+ Return<void> setSignalStrengthReportingCriteriaResponse_1_5(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> setLinkCapacityReportingCriteriaResponse_1_5(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) override;
+ Return<void> areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
+ bool enabled) override;
+ Return<void> setSystemSelectionChannelsResponse_1_5(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
+ const V1_5::SetupDataCallResult& dcResponse) override;
+ Return<void> getDataCallListResponse_1_5(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) override;
+ Return<void> setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+ Return<void> setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) override;
+ Return<void> getBarringInfoResponse(const V1_0::RadioResponseInfo& info,
+ const V1_5::CellIdentity& cellIdentity,
+ const hidl_vec<V1_5::BarringInfo>& barringInfos) override;
+ Return<void> getVoiceRegistrationStateResponse_1_5(
+ const V1_0::RadioResponseInfo& info,
+ const V1_5::RegStateResult& voiceRegResponse) override;
+ Return<void> getDataRegistrationStateResponse_1_5(
+ const V1_0::RadioResponseInfo& info,
+ const V1_5::RegStateResult& dataRegResponse) override;
+ Return<void> getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_5::CellInfo>& cellInfo) override;
+ Return<void> setNetworkSelectionModeManualResponse_1_5(
+ const V1_0::RadioResponseInfo& info) override;
+ Return<void> sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> supplySimDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+ V1_5::PersoSubstate persoType,
+ int32_t remainingRetries) override;
+ Return<void> getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
+ const V1_5::CardStatus& cardStatus) override;
+
+ // IRadioResponse @ 1.6
+ Return<void> setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) override;
+ Return<void> setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_6::SetupDataCallResult& dcResponse) override;
+ Return<void> getDataCallListResponse_1_6(
+ const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) override;
+ Return<void> sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) override;
+ Return<void> setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) override;
+ Return<void> setNrDualConnectivityStateResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
+ bool isEnabled) override;
+ Return<void> allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
+ int32_t id) override;
+ Return<void> releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> startHandoverResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> cancelHandoverResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> getAllowedNetworkTypesBitmapResponse(
+ const V1_6::RadioResponseInfo& info,
+ hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) override;
+ Return<void> setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> getSystemSelectionChannelsResponse(
+ const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) override;
+ Return<void> getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_6::CellInfo>& cellInfo) override;
+ Return<void> getSignalStrengthResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_6::SignalStrength& signalStrength) override;
+ Return<void> getVoiceRegistrationStateResponse_1_6(
+ const V1_6::RadioResponseInfo& info,
+ const V1_6::RegStateResult& voiceRegResponse) override;
+ Return<void> getDataRegistrationStateResponse_1_6(
+ const V1_6::RadioResponseInfo& info,
+ const V1_6::RegStateResult& dataRegResponse) override;
+ Return<void> getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_6::Call>& calls) override;
+ Return<void> getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
+ const V1_6::SlicingConfig& slicingConfig) override;
+ Return<void> getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) override;
+ Return<void> getSimPhonebookCapacityResponse(const V1_6::RadioResponseInfo& info,
+ const V1_6::PhonebookCapacity& capacity) override;
+ Return<void> updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
+ int32_t updatedRecordIndex) override;
+
+ public:
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+ radioMessagingResponse);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> modemCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> nwCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
+ void setResponseFunction(
+ std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+};
+
+} // 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
new file mode 100644
index 0000000..a6b77fd
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -0,0 +1,107 @@
+/*
+ * 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 "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/sim/BnRadioSim.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio::sim::BnRadioSim {
+ ::ndk::ScopedAStatus areUiccApplicationsEnabled(int32_t serial) override;
+ ::ndk::ScopedAStatus changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
+ const std::string& newPin2,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus changeIccPinForApp(int32_t serial, const std::string& oldPin,
+ const std::string& newPin,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus enableUiccApplications(int32_t serial, bool enable) override;
+ ::ndk::ScopedAStatus getAllowedCarriers(int32_t serial) override;
+ ::ndk::ScopedAStatus getCdmaSubscription(int32_t serial) override;
+ ::ndk::ScopedAStatus getCdmaSubscriptionSource(int32_t serial) override;
+ ::ndk::ScopedAStatus getFacilityLockForApp(int32_t serial, const std::string& facility,
+ const std::string& password, int32_t serviceClass,
+ const std::string& appId) override;
+ ::ndk::ScopedAStatus getIccCardStatus(int32_t serial) override;
+ ::ndk::ScopedAStatus getImsiForApp(int32_t serial, const std::string& aid) override;
+ ::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 iccIoForApp(
+ int32_t serial, const ::aidl::android::hardware::radio::sim::IccIo& iccIo) override;
+ ::ndk::ScopedAStatus iccOpenLogicalChannel(int32_t serial, const std::string& aid,
+ int32_t p2) override;
+ ::ndk::ScopedAStatus iccTransmitApduBasicChannel(
+ int32_t serial, const ::aidl::android::hardware::radio::sim::SimApdu& message) override;
+ ::ndk::ScopedAStatus iccTransmitApduLogicalChannel(
+ int32_t serial, const ::aidl::android::hardware::radio::sim::SimApdu& message) override;
+ ::ndk::ScopedAStatus reportStkServiceIsRunning(int32_t serial) override;
+ ::ndk::ScopedAStatus requestIccSimAuthentication(int32_t serial, int32_t authContext,
+ const std::string& authData,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus responseAcknowledgement() override;
+ ::ndk::ScopedAStatus sendEnvelope(int32_t serial, const std::string& command) override;
+ ::ndk::ScopedAStatus sendEnvelopeWithStatus(int32_t serial,
+ const std::string& contents) override;
+ ::ndk::ScopedAStatus sendTerminalResponseToSim(int32_t serial,
+ const std::string& commandResponse) override;
+ ::ndk::ScopedAStatus setAllowedCarriers(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::sim::CarrierRestrictions& carriers,
+ ::aidl::android::hardware::radio::sim::SimLockMultiSimPolicy multiSimPolicy) override;
+ ::ndk::ScopedAStatus setCarrierInfoForImsiEncryption(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& imsiEncryptionInfo)
+ override;
+ ::ndk::ScopedAStatus setCdmaSubscriptionSource(
+ int32_t serial,
+ ::aidl::android::hardware::radio::sim::CdmaSubscriptionSource cdmaSub) override;
+ ::ndk::ScopedAStatus setFacilityLockForApp( //
+ int32_t serial, const std::string& facility, bool lockState, const std::string& passwd,
+ int32_t serviceClass, const std::string& appId) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse>&
+ radioSimResponse,
+ const std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication>&
+ radioSimIndication) override;
+ ::ndk::ScopedAStatus setSimCardPower(
+ int32_t serial, ::aidl::android::hardware::radio::sim::CardPowerState powerUp) override;
+ ::ndk::ScopedAStatus setUiccSubscription(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::sim::SelectUiccSub& uiccSub) override;
+ ::ndk::ScopedAStatus supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus supplyIccPinForApp(int32_t serial, const std::string& pin,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
+ const std::string& pin2,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus supplyIccPukForApp(int32_t serial, const std::string& puk,
+ const std::string& pin,
+ const std::string& aid) override;
+ ::ndk::ScopedAStatus supplySimDepersonalization(
+ int32_t serial, ::aidl::android::hardware::radio::sim::PersoSubstate persoType,
+ const std::string& controlKey) override;
+ ::ndk::ScopedAStatus updateSimPhonebookRecords(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::sim::PhonebookRecordInfo& recordInfo) override;
+
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
new file mode 100644
index 0000000..5bf93e0
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -0,0 +1,84 @@
+/*
+ * 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 "RadioCompatBase.h"
+
+#include <aidl/android/hardware/radio/voice/BnRadioVoice.h>
+
+namespace android::hardware::radio::compat {
+
+class RadioVoice : public RadioCompatBase,
+ public aidl::android::hardware::radio::voice::BnRadioVoice {
+ ::ndk::ScopedAStatus acceptCall(int32_t serial) override;
+ ::ndk::ScopedAStatus conference(int32_t serial) override;
+ ::ndk::ScopedAStatus dial(
+ int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo) override;
+ ::ndk::ScopedAStatus emergencyDial(
+ int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo,
+ ::aidl::android::hardware::radio::voice::EmergencyServiceCategory categories,
+ const std::vector<std::string>& urns,
+ ::aidl::android::hardware::radio::voice::EmergencyCallRouting routing,
+ bool hasKnownUserIntentEmergency, bool isTesting) override;
+ ::ndk::ScopedAStatus exitEmergencyCallbackMode(int32_t serial) override;
+ ::ndk::ScopedAStatus explicitCallTransfer(int32_t serial) override;
+ ::ndk::ScopedAStatus getCallForwardStatus(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::voice::CallForwardInfo& callInfo) override;
+ ::ndk::ScopedAStatus getCallWaiting(int32_t serial, int32_t serviceClass) override;
+ ::ndk::ScopedAStatus getClip(int32_t serial) override;
+ ::ndk::ScopedAStatus getClir(int32_t serial) override;
+ ::ndk::ScopedAStatus getCurrentCalls(int32_t serial) override;
+ ::ndk::ScopedAStatus getLastCallFailCause(int32_t serial) override;
+ ::ndk::ScopedAStatus getMute(int32_t serial) override;
+ ::ndk::ScopedAStatus getPreferredVoicePrivacy(int32_t serial) override;
+ ::ndk::ScopedAStatus getTtyMode(int32_t serial) override;
+ ::ndk::ScopedAStatus handleStkCallSetupRequestFromSim(int32_t serial, bool accept) override;
+ ::ndk::ScopedAStatus hangup(int32_t serial, int32_t gsmIndex) override;
+ ::ndk::ScopedAStatus hangupForegroundResumeBackground(int32_t serial) override;
+ ::ndk::ScopedAStatus hangupWaitingOrBackground(int32_t serial) override;
+ ::ndk::ScopedAStatus isVoNrEnabled(int32_t serial) override;
+ ::ndk::ScopedAStatus rejectCall(int32_t serial) override;
+ ::ndk::ScopedAStatus responseAcknowledgement() override;
+ ::ndk::ScopedAStatus sendBurstDtmf(int32_t serial, const std::string& dtmf, int32_t on,
+ int32_t off) override;
+ ::ndk::ScopedAStatus sendCdmaFeatureCode(int32_t serial, const std::string& fcode) override;
+ ::ndk::ScopedAStatus sendDtmf(int32_t serial, const std::string& s) override;
+ ::ndk::ScopedAStatus separateConnection(int32_t serial, int32_t gsmIndex) override;
+ ::ndk::ScopedAStatus setCallForward(
+ int32_t serial,
+ const ::aidl::android::hardware::radio::voice::CallForwardInfo& callInfo) override;
+ ::ndk::ScopedAStatus setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) override;
+ ::ndk::ScopedAStatus setClir(int32_t serial, int32_t status) override;
+ ::ndk::ScopedAStatus setMute(int32_t serial, bool enable) override;
+ ::ndk::ScopedAStatus setPreferredVoicePrivacy(int32_t serial, bool enable) override;
+ ::ndk::ScopedAStatus setResponseFunctions(
+ const std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse>&
+ radioVoiceResponse,
+ const std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication>&
+ radioVoiceIndication) override;
+ ::ndk::ScopedAStatus setTtyMode(int32_t serial,
+ ::aidl::android::hardware::radio::voice::TtyMode mode) override;
+ ::ndk::ScopedAStatus setVoNrEnabled(int32_t serial, bool enable) override;
+ ::ndk::ScopedAStatus startDtmf(int32_t serial, const std::string& s) override;
+ ::ndk::ScopedAStatus stopDtmf(int32_t serial) override;
+ ::ndk::ScopedAStatus switchWaitingOrHoldingAndActive(int32_t serial) override;
+
+ public:
+ using RadioCompatBase::RadioCompatBase;
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
new file mode 100644
index 0000000..c7342b1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "MessagingIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingIndication> rmiCb) {
+ CHECK(rmiCb);
+ mMessagingCb = rmiCb;
+}
+
+Return<void> RadioIndication::cdmaNewSms(V1_0::RadioIndicationType type,
+ const V1_0::CdmaSmsMessage& msg) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->cdmaNewSms(toAidl(type), toAidl(msg));
+ return {};
+}
+
+Return<void> RadioIndication::cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->cdmaRuimSmsStorageFull(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::newBroadcastSms(V1_0::RadioIndicationType type,
+ const hidl_vec<uint8_t>& data) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->newBroadcastSms(toAidl(type), data);
+ return {};
+}
+
+Return<void> RadioIndication::newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->newSms(toAidl(type), pdu);
+ return {};
+}
+
+Return<void> RadioIndication::newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->newSmsOnSim(toAidl(type), recordNumber);
+ return {};
+}
+
+Return<void> RadioIndication::newSmsStatusReport(V1_0::RadioIndicationType type,
+ const hidl_vec<uint8_t>& pdu) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->newSmsStatusReport(toAidl(type), pdu);
+ return {};
+}
+
+Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
+ const hidl_string& msg) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+ return {};
+}
+
+Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->simSmsStorageFull(toAidl(type));
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
new file mode 100644
index 0000000..c1a82b5
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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 <libradiocompat/RadioMessaging.h>
+
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Messaging"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioMessaging::acknowledgeIncomingGsmSmsWithPdu( //
+ int32_t serial, bool success, const std::string& ackPdu) {
+ LOG_CALL << serial << ' ' << success << ' ' << ackPdu;
+ mHal1_5->acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::acknowledgeLastIncomingCdmaSms( //
+ int32_t serial, const aidl::CdmaSmsAck& smsAck) {
+ LOG_CALL << serial;
+ mHal1_5->acknowledgeLastIncomingCdmaSms(serial, toHidl(smsAck));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::acknowledgeLastIncomingGsmSms( //
+ int32_t serial, bool success, aidl::SmsAcknowledgeFailCause cause) {
+ LOG_CALL << serial << ' ' << success;
+ mHal1_5->acknowledgeLastIncomingGsmSms(serial, success, V1_0::SmsAcknowledgeFailCause(cause));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::cancelPendingUssd(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->cancelPendingUssd(serial);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::deleteSmsOnRuim(int32_t serial, int32_t index) {
+ LOG_CALL << serial << ' ' << index;
+ mHal1_5->deleteSmsOnRuim(serial, index);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::deleteSmsOnSim(int32_t serial, int32_t index) {
+ LOG_CALL << serial << ' ' << index;
+ mHal1_5->deleteSmsOnSim(serial, index);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::getCdmaBroadcastConfig(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getCdmaBroadcastConfig(serial);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::getGsmBroadcastConfig(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getGsmBroadcastConfig(serial);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::getSmscAddress(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getSmscAddress(serial);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::reportSmsMemoryStatus(int32_t serial, bool available) {
+ LOG_CALL << serial << ' ' << available;
+ mHal1_5->reportSmsMemoryStatus(serial, available);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::responseAcknowledgement() {
+ LOG_CALL;
+ mHal1_5->responseAcknowledgement();
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::sendCdmaSms(int32_t serial, const aidl::CdmaSmsMessage& sms) {
+ LOG_CALL << serial;
+ mHal1_5->sendCdmaSms(serial, toHidl(sms));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::sendCdmaSmsExpectMore(int32_t serial, const aidl::CdmaSmsMessage& m) {
+ LOG_CALL << serial;
+ mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::sendImsSms(int32_t serial, const aidl::ImsSmsMessage& message) {
+ LOG_CALL << serial;
+ mHal1_5->sendImsSms(serial, toHidl(message));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::sendSms(int32_t serial, const aidl::GsmSmsMessage& message) {
+ LOG_CALL << serial;
+ mHal1_5->sendSms(serial, toHidl(message));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::sendSmsExpectMore(int32_t serial, const aidl::GsmSmsMessage& msg) {
+ LOG_CALL << serial;
+ mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::sendUssd(int32_t serial, const std::string& ussd) {
+ LOG_CALL << serial << ' ' << ussd;
+ mHal1_5->sendUssd(serial, ussd);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::setCdmaBroadcastActivation(int32_t serial, bool activate) {
+ LOG_CALL << serial << ' ' << activate;
+ mHal1_5->setCdmaBroadcastActivation(serial, activate);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::setCdmaBroadcastConfig(
+ int32_t serial, const std::vector<aidl::CdmaBroadcastSmsConfigInfo>& cfgInfo) {
+ LOG_CALL << serial;
+ mHal1_5->setCdmaBroadcastConfig(serial, toHidl(cfgInfo));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::setGsmBroadcastActivation(int32_t serial, bool activate) {
+ LOG_CALL << serial << ' ' << activate;
+ mHal1_5->setGsmBroadcastActivation(serial, activate);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::setGsmBroadcastConfig(
+ int32_t serial, const std::vector<aidl::GsmBroadcastSmsConfigInfo>& configInfo) {
+ LOG_CALL << serial;
+ mHal1_5->setGsmBroadcastConfig(serial, toHidl(configInfo));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioMessagingResponse>& messagingResponse,
+ const std::shared_ptr<aidl::IRadioMessagingIndication>& messagingIndication) {
+ LOG_CALL << messagingResponse << ' ' << messagingIndication;
+
+ CHECK(messagingResponse);
+ CHECK(messagingIndication);
+
+ mRadioResponse->setResponseFunction(messagingResponse);
+ mRadioIndication->setResponseFunction(messagingIndication);
+
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::setSmscAddress(int32_t serial, const std::string& smsc) {
+ LOG_CALL << serial << ' ' << smsc;
+ mHal1_5->setSmscAddress(serial, smsc);
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::writeSmsToRuim(int32_t serial, const aidl::CdmaSmsWriteArgs& sms) {
+ LOG_CALL << serial;
+ mHal1_5->writeSmsToRuim(serial, toHidl(sms));
+ return ok();
+}
+
+ScopedAStatus RadioMessaging::writeSmsToSim(int32_t serial, const aidl::SmsWriteArgs& smsWrArgs) {
+ LOG_CALL << serial;
+ mHal1_5->writeSmsToSim(serial, toHidl(smsWrArgs));
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
new file mode 100644
index 0000000..379e463
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -0,0 +1,244 @@
+/*
+ * 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 <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "MessagingResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingResponse> rmrCb) {
+ CHECK(rmrCb);
+ mMessagingCb = rmrCb;
+}
+
+Return<void> RadioResponse::acknowledgeIncomingGsmSmsWithPduResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingCdmaSmsResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::acknowledgeLastIncomingGsmSmsResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->cancelPendingUssdResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->deleteSmsOnRuimResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->deleteSmsOnSimResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::getCdmaBroadcastConfigResponse(
+ const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
+ return {};
+}
+
+Return<void> RadioResponse::getGsmBroadcastConfigResponse(
+ const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& cfg) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
+ return {};
+}
+
+Return<void> RadioResponse::getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& smsc) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->getSmscAddressResponse(toAidl(info), smsc);
+ return {};
+}
+
+Return<void> RadioResponse::reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->reportSmsMemoryStatusResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendImsSmsResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendSmsResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const V1_0::SendSmsResult& sms) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+ return {};
+}
+
+Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->sendUssdResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->setCdmaBroadcastActivationResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->setCdmaBroadcastConfigResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->setGsmBroadcastActivationResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->setGsmBroadcastConfigResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSmscAddressResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->setSmscAddressResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
+ uint32_t index) {
+ LOG_CALL << info.serial << ' ' << index;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->writeSmsToRuimResponse(toAidl(info), index);
+ return {};
+}
+
+Return<void> RadioResponse::writeSmsToSimResponse(const V1_0::RadioResponseInfo& info,
+ int32_t index) {
+ LOG_CALL << info.serial << ' ' << index;
+ CHECK_CB(mMessagingCb);
+ mMessagingCb->writeSmsToSimResponse(toAidl(info), index);
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.cpp b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
new file mode 100644
index 0000000..9019680
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.cpp
@@ -0,0 +1,172 @@
+/*
+ * 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 "structs.h"
+
+#include "collections.h"
+
+#include <aidl/android/hardware/radio/messaging/CdmaSmsAddress.h>
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::messaging;
+
+V1_0::CdmaSmsAck toHidl(const aidl::CdmaSmsAck& smsAck) {
+ return {
+ .errorClass = (smsAck.errorClass ? V1_0::CdmaSmsErrorClass::ERROR
+ : V1_0::CdmaSmsErrorClass::NO_ERROR),
+ .smsCauseCode = smsAck.smsCauseCode,
+ };
+}
+
+static aidl::CdmaSmsAddress toAidl(const V1_0::CdmaSmsAddress& addr) {
+ return {
+ .digitMode = static_cast<int32_t>(addr.digitMode),
+ .isNumberModeDataNetwork = addr.numberMode == V1_0::CdmaSmsNumberMode::DATA_NETWORK,
+ .numberType = static_cast<int32_t>(addr.numberType),
+ .numberPlan = static_cast<int32_t>(addr.numberPlan),
+ .digits = addr.digits,
+ };
+}
+
+static V1_0::CdmaSmsAddress toHidl(const aidl::CdmaSmsAddress& addr) {
+ return {
+ .digitMode = V1_0::CdmaSmsDigitMode{addr.digitMode},
+ .numberMode = addr.isNumberModeDataNetwork ? V1_0::CdmaSmsNumberMode::DATA_NETWORK
+ : V1_0::CdmaSmsNumberMode::NOT_DATA_NETWORK,
+ .numberType = V1_0::CdmaSmsNumberType{addr.numberType},
+ .numberPlan = V1_0::CdmaSmsNumberPlan{addr.numberPlan},
+ .digits = addr.digits,
+ };
+}
+
+static aidl::CdmaSmsSubaddress toAidl(const V1_0::CdmaSmsSubaddress& addr) {
+ return {
+ .subaddressType = static_cast<int32_t>(addr.subaddressType),
+ .odd = addr.odd,
+ .digits = addr.digits,
+ };
+}
+
+static V1_0::CdmaSmsSubaddress toHidl(const aidl::CdmaSmsSubaddress& addr) {
+ return {
+ .subaddressType = V1_0::CdmaSmsSubaddressType{addr.subaddressType},
+ .odd = addr.odd,
+ .digits = addr.digits,
+ };
+}
+
+::aidl::android::hardware::radio::messaging::CdmaSmsMessage toAidl(const V1_0::CdmaSmsMessage& m) {
+ return {
+ .teleserviceId = m.teleserviceId,
+ .isServicePresent = m.isServicePresent,
+ .serviceCategory = m.serviceCategory,
+ .address = toAidl(m.address),
+ .subAddress = toAidl(m.subAddress),
+ .bearerData = m.bearerData,
+ };
+}
+
+V1_0::CdmaSmsMessage toHidl(const aidl::CdmaSmsMessage& msg) {
+ return {
+ .teleserviceId = msg.teleserviceId,
+ .isServicePresent = msg.isServicePresent,
+ .serviceCategory = msg.serviceCategory,
+ .address = toHidl(msg.address),
+ .subAddress = toHidl(msg.subAddress),
+ .bearerData = msg.bearerData,
+ };
+}
+
+V1_0::ImsSmsMessage toHidl(const aidl::ImsSmsMessage& msg) {
+ return {
+ .tech = V1_0::RadioTechnologyFamily{msg.tech},
+ .retry = msg.retry,
+ .messageRef = msg.messageRef,
+ .cdmaMessage = toHidl(msg.cdmaMessage),
+ .gsmMessage = toHidl(msg.gsmMessage),
+ };
+}
+
+V1_0::GsmSmsMessage toHidl(const aidl::GsmSmsMessage& msg) {
+ return {
+ .smscPdu = msg.smscPdu,
+ .pdu = msg.pdu,
+ };
+}
+
+aidl::CdmaBroadcastSmsConfigInfo toAidl(const V1_0::CdmaBroadcastSmsConfigInfo& info) {
+ return {
+ .serviceCategory = info.serviceCategory,
+ .language = info.language,
+ .selected = info.selected,
+ };
+}
+
+V1_0::CdmaBroadcastSmsConfigInfo toHidl(const aidl::CdmaBroadcastSmsConfigInfo& info) {
+ return {
+ .serviceCategory = info.serviceCategory,
+ .language = info.language,
+ .selected = info.selected,
+ };
+}
+
+aidl::GsmBroadcastSmsConfigInfo toAidl(const V1_0::GsmBroadcastSmsConfigInfo& info) {
+ return {
+ .fromServiceId = info.fromServiceId,
+ .toServiceId = info.toServiceId,
+ .fromCodeScheme = info.fromCodeScheme,
+ .toCodeScheme = info.toCodeScheme,
+ .selected = info.selected,
+ };
+}
+
+V1_0::GsmBroadcastSmsConfigInfo toHidl(const aidl::GsmBroadcastSmsConfigInfo& info) {
+ return {
+ .fromServiceId = info.fromServiceId,
+ .toServiceId = info.toServiceId,
+ .fromCodeScheme = info.fromCodeScheme,
+ .toCodeScheme = info.toCodeScheme,
+ .selected = info.selected,
+ };
+}
+
+V1_0::CdmaSmsWriteArgs toHidl(const aidl::CdmaSmsWriteArgs& args) {
+ return {
+ .status = V1_0::CdmaSmsWriteArgsStatus{args.status},
+ .message = toHidl(args.message),
+ };
+}
+
+V1_0::SmsWriteArgs toHidl(const aidl::SmsWriteArgs& args) {
+ return {
+ .status = V1_0::SmsWriteArgsStatus{args.status},
+ .pdu = args.pdu,
+ .smsc = args.smsc,
+ };
+}
+
+::aidl::android::hardware::radio::messaging::SendSmsResult toAidl(
+ const V1_0::SendSmsResult& result) {
+ return {
+ .messageRef = result.messageRef,
+ .ackPDU = result.ackPDU,
+ .errorCode = result.errorCode,
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/messaging/structs.h b/radio/aidl/compat/libradiocompat/messaging/structs.h
new file mode 100644
index 0000000..afb4941
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/messaging/structs.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsAck.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.h>
+#include <aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.h>
+#include <aidl/android/hardware/radio/messaging/GsmSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/ImsSmsMessage.h>
+#include <aidl/android/hardware/radio/messaging/SendSmsResult.h>
+#include <aidl/android/hardware/radio/messaging/SmsWriteArgs.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::CdmaSmsAck toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsAck& ack);
+
+::aidl::android::hardware::radio::messaging::CdmaSmsMessage toAidl(const V1_0::CdmaSmsMessage& msg);
+V1_0::CdmaSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsMessage& msg);
+
+V1_0::ImsSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::ImsSmsMessage& msg);
+
+V1_0::GsmSmsMessage toHidl(const ::aidl::android::hardware::radio::messaging::GsmSmsMessage& msg);
+
+::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo //
+toAidl(const V1_0::CdmaBroadcastSmsConfigInfo& info);
+V1_0::CdmaBroadcastSmsConfigInfo //
+toHidl(const ::aidl::android::hardware::radio::messaging::CdmaBroadcastSmsConfigInfo& info);
+
+::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo //
+toAidl(const V1_0::GsmBroadcastSmsConfigInfo& info);
+V1_0::GsmBroadcastSmsConfigInfo //
+toHidl(const ::aidl::android::hardware::radio::messaging::GsmBroadcastSmsConfigInfo& info);
+
+V1_0::CdmaSmsWriteArgs //
+toHidl(const ::aidl::android::hardware::radio::messaging::CdmaSmsWriteArgs& args);
+
+V1_0::SmsWriteArgs toHidl(const ::aidl::android::hardware::radio::messaging::SmsWriteArgs& args);
+
+::aidl::android::hardware::radio::messaging::SendSmsResult toAidl(const V1_0::SendSmsResult& res);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
new file mode 100644
index 0000000..8fc4da6
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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 <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ModemIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioModemIndication> modemCb) {
+ CHECK(modemCb);
+ mModemCb = modemCb;
+}
+
+Return<void> RadioIndication::hardwareConfigChanged(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_0::HardwareConfig>& configs) {
+ LOG_CALL << type;
+ CHECK_CB(mModemCb);
+ mModemCb->hardwareConfigChanged(toAidl(type), toAidl(configs));
+ return {};
+}
+
+Return<void> RadioIndication::modemReset(V1_0::RadioIndicationType type, const hidl_string& reasn) {
+ LOG_CALL << type;
+ CHECK_CB(mModemCb);
+ mModemCb->modemReset(toAidl(type), reasn);
+ return {};
+}
+
+Return<void> RadioIndication::radioCapabilityIndication(V1_0::RadioIndicationType type,
+ const V1_0::RadioCapability& rc) {
+ LOG_CALL << type;
+ CHECK_CB(mModemCb);
+ mModemCb->radioCapabilityIndication(toAidl(type), toAidl(rc));
+ return {};
+}
+
+Return<void> RadioIndication::radioStateChanged(V1_0::RadioIndicationType t, V1_0::RadioState st) {
+ LOG_CALL << t;
+ CHECK_CB(mModemCb);
+ mModemCb->radioStateChanged(toAidl(t), aidl::RadioState(st));
+ return {};
+}
+
+Return<void> RadioIndication::rilConnected(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mModemCb);
+ mModemCb->rilConnected(toAidl(type));
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
new file mode 100644
index 0000000..660ae9f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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 <libradiocompat/RadioModem.h>
+
+#include "debug.h"
+#include "structs.h"
+
+#define RADIO_MODULE "Modem"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::modem;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioModem::enableModem(int32_t serial, bool on) {
+ LOG_CALL << serial;
+ mHal1_5->enableModem(serial, on);
+ return ok();
+}
+
+ScopedAStatus RadioModem::getBasebandVersion(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getBasebandVersion(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::getDeviceIdentity(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getDeviceIdentity(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::getHardwareConfig(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getHardwareConfig(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::getModemActivityInfo(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getModemActivityInfo(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::getModemStackStatus(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getModemStackStatus(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::getRadioCapability(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getRadioCapability(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::nvReadItem(int32_t serial, aidl::NvItem itemId) {
+ LOG_CALL << serial;
+ mHal1_5->nvReadItem(serial, V1_0::NvItem(itemId));
+ return ok();
+}
+
+ScopedAStatus RadioModem::nvResetConfig(int32_t serial, aidl::ResetNvType resetType) {
+ LOG_CALL << serial;
+ mHal1_5->nvResetConfig(serial, V1_0::ResetNvType(resetType));
+ return ok();
+}
+
+ScopedAStatus RadioModem::nvWriteCdmaPrl(int32_t serial, const std::vector<uint8_t>& prl) {
+ LOG_CALL << serial;
+ mHal1_5->nvWriteCdmaPrl(serial, prl);
+ return ok();
+}
+
+ScopedAStatus RadioModem::nvWriteItem(int32_t serial, const aidl::NvWriteItem& item) {
+ LOG_CALL << serial;
+ mHal1_5->nvWriteItem(serial, toHidl(item));
+ return ok();
+}
+
+ScopedAStatus RadioModem::requestShutdown(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->requestShutdown(serial);
+ return ok();
+}
+
+ScopedAStatus RadioModem::responseAcknowledgement() {
+ LOG_CALL;
+ mHal1_5->responseAcknowledgement();
+ return ok();
+}
+
+ScopedAStatus RadioModem::sendDeviceState(int32_t serial, aidl::DeviceStateType type, bool state) {
+ LOG_CALL << serial;
+ mHal1_5->sendDeviceState(serial, V1_0::DeviceStateType(type), state);
+ return ok();
+}
+
+ScopedAStatus RadioModem::setRadioCapability(int32_t serial, const aidl::RadioCapability& rc) {
+ LOG_CALL << serial;
+ mHal1_5->setRadioCapability(serial, toHidl(rc));
+ return ok();
+}
+
+ScopedAStatus RadioModem::setRadioPower(int32_t serial, bool powerOn, bool forEmergencyCall,
+ bool preferredForEmergencyCall) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->setRadioPower_1_6(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+ } else {
+ mHal1_5->setRadioPower_1_5(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
+ }
+ return ok();
+}
+
+ScopedAStatus RadioModem::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioModemResponse>& modemResponse,
+ const std::shared_ptr<aidl::IRadioModemIndication>& modemIndication) {
+ LOG_CALL << modemResponse << ' ' << modemIndication;
+
+ CHECK(modemResponse);
+ CHECK(modemIndication);
+
+ mRadioResponse->setResponseFunction(modemResponse);
+ mRadioIndication->setResponseFunction(modemIndication);
+
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
new file mode 100644
index 0000000..300627c
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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 <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "ModemResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioModemResponse> modemCb) {
+ CHECK(modemCb);
+ mModemCb = modemCb;
+}
+
+Return<void> RadioResponse::enableModemResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->enableModemResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& version) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->getBasebandVersionResponse(toAidl(info), version);
+ return {};
+}
+
+Return<void> RadioResponse::getDeviceIdentityResponse( //
+ const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
+ const hidl_string& esn, const hidl_string& meid) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
+ return {};
+}
+
+Return<void> RadioResponse::getHardwareConfigResponse(
+ const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::HardwareConfig>& config) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->getHardwareConfigResponse(toAidl(info), toAidl(config));
+ return {};
+}
+
+Return<void> RadioResponse::getModemActivityInfoResponse(
+ const V1_0::RadioResponseInfo& info, const V1_0::ActivityStatsInfo& activityInfo) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
+ return {};
+}
+
+Return<void> RadioResponse::getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
+ bool isEnabled) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->getModemStackStatusResponse(toAidl(info), isEnabled);
+ return {};
+}
+
+Return<void> RadioResponse::getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::RadioCapability& rc) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
+ return {};
+}
+
+Return<void> RadioResponse::nvReadItemResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& result) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->nvReadItemResponse(toAidl(info), result);
+ return {};
+}
+
+Return<void> RadioResponse::nvResetConfigResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->nvResetConfigResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->nvWriteCdmaPrlResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::nvWriteItemResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->nvWriteItemResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::requestShutdownResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->requestShutdownResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->sendDeviceStateResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::RadioCapability& rc) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
+ return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->setRadioPowerResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->setRadioPowerResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mModemCb);
+ mModemCb->setRadioPowerResponse(toAidl(info));
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
new file mode 100644
index 0000000..c1cd64c
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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 "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::modem;
+
+V1_0::NvWriteItem toHidl(const aidl::NvWriteItem& item) {
+ return {
+ .itemId = V1_0::NvItem{item.itemId},
+ .value = item.value,
+ };
+}
+
+aidl::RadioCapability toAidl(const V1_0::RadioCapability& capa) {
+ return {
+ .session = capa.session,
+ .phase = static_cast<int32_t>(capa.phase),
+ .raf = RadioAccessFamily(capa.raf),
+ .logicalModemUuid = capa.logicalModemUuid,
+ .status = static_cast<int32_t>(capa.status),
+ };
+}
+
+V1_0::RadioCapability toHidl(const aidl::RadioCapability& capa) {
+ return {
+ .session = capa.session,
+ .phase = V1_0::RadioCapabilityPhase{capa.phase},
+ .raf = toHidlBitfield<V1_0::RadioAccessFamily>(capa.raf),
+ .logicalModemUuid = capa.logicalModemUuid,
+ .status = V1_0::RadioCapabilityStatus{capa.status},
+ };
+}
+
+aidl::HardwareConfig toAidl(const V1_0::HardwareConfig& config) {
+ return {
+ .type = static_cast<int32_t>(config.type),
+ .uuid = config.uuid,
+ .state = static_cast<int32_t>(config.state),
+ .modem = toAidl(config.modem),
+ .sim = toAidl(config.sim),
+ };
+}
+
+aidl::HardwareConfigModem toAidl(const V1_0::HardwareConfigModem& modem) {
+ return {
+ .rilModel = modem.rilModel,
+ .rat = RadioTechnology(modem.rat),
+ .maxVoiceCalls = modem.maxVoice,
+ .maxDataCalls = modem.maxData,
+ .maxStandby = modem.maxStandby,
+ };
+}
+
+aidl::HardwareConfigSim toAidl(const V1_0::HardwareConfigSim& sim) {
+ return {
+ .modemUuid = sim.modemUuid,
+ };
+}
+
+aidl::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& info) {
+ return {
+ .sleepModeTimeMs = static_cast<int32_t>(info.sleepModeTimeMs),
+ .idleModeTimeMs = static_cast<int32_t>(info.idleModeTimeMs),
+ .txmModetimeMs = toAidl(info.txmModetimeMs),
+ .rxModeTimeMs = static_cast<int32_t>(info.rxModeTimeMs),
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.h b/radio/aidl/compat/libradiocompat/modem/structs.h
new file mode 100644
index 0000000..3ac1edb
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/modem/structs.h
@@ -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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/modem/ActivityStatsInfo.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfig.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfigModem.h>
+#include <aidl/android/hardware/radio/modem/HardwareConfigSim.h>
+#include <aidl/android/hardware/radio/modem/NvWriteItem.h>
+#include <aidl/android/hardware/radio/modem/RadioCapability.h>
+#include <android/hardware/radio/1.0/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::NvWriteItem toHidl(const ::aidl::android::hardware::radio::modem::NvWriteItem& item);
+
+::aidl::android::hardware::radio::modem::RadioCapability toAidl(const V1_0::RadioCapability& capa);
+V1_0::RadioCapability toHidl(const ::aidl::android::hardware::radio::modem::RadioCapability& capa);
+
+::aidl::android::hardware::radio::modem::HardwareConfig toAidl(const V1_0::HardwareConfig& config);
+
+::aidl::android::hardware::radio::modem::HardwareConfigModem //
+toAidl(const V1_0::HardwareConfigModem& modem);
+
+::aidl::android::hardware::radio::modem::HardwareConfigSim toAidl(const V1_0::HardwareConfigSim& s);
+
+::aidl::android::hardware::radio::modem::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& i);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
new file mode 100644
index 0000000..899b133
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
@@ -0,0 +1,259 @@
+/*
+ * 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 <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "NetworkIndication"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioTechnology;
+namespace aidl = ::aidl::android::hardware::radio::network;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkIndication> netCb) {
+ CHECK(netCb);
+ mNetworkCb = netCb;
+}
+
+Return<void> RadioIndication::barringInfoChanged(V1_0::RadioIndicationType type,
+ const V1_5::CellIdentity& cellIdentity,
+ const hidl_vec<V1_5::BarringInfo>& barringInfos) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
+ return {};
+}
+
+Return<void> RadioIndication::cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->cdmaPrlChanged(toAidl(type), version);
+ return {};
+}
+
+Return<void> RadioIndication::cellInfoList(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_0::CellInfo>&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_2(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_2::CellInfo>&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_4(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_4::CellInfo>&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_5(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_5::CellInfo>& records) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+ return {};
+}
+
+Return<void> RadioIndication::cellInfoList_1_6(V1_0::RadioIndicationType type,
+ const hidl_vec<V1_6::CellInfo>& records) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+ return {};
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
+ const V1_2::LinkCapacityEstimate& lce) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+ return {};
+}
+
+Return<void> RadioIndication::currentLinkCapacityEstimate_1_6(
+ V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+ return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs(
+ V1_0::RadioIndicationType type, const hidl_vec<V1_2::PhysicalChannelConfig>&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_4(
+ V1_0::RadioIndicationType type, const hidl_vec<V1_4::PhysicalChannelConfig>& configs) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+ return {};
+}
+
+Return<void> RadioIndication::currentPhysicalChannelConfigs_1_6(
+ V1_0::RadioIndicationType type, const hidl_vec<V1_6::PhysicalChannelConfig>& configs) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+ return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength(V1_0::RadioIndicationType type,
+ const V1_0::SignalStrength&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_2(V1_0::RadioIndicationType type,
+ const V1_2::SignalStrength&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_4(
+ V1_0::RadioIndicationType type, const V1_4::SignalStrength& signalStrength) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+ return {};
+}
+
+Return<void> RadioIndication::currentSignalStrength_1_6(
+ V1_0::RadioIndicationType type, const V1_6::SignalStrength& signalStrength) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+ return {};
+}
+
+Return<void> RadioIndication::imsNetworkStateChanged(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->imsNetworkStateChanged(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::networkScanResult(V1_0::RadioIndicationType type,
+ const V1_1::NetworkScanResult&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_2(V1_0::RadioIndicationType type,
+ const V1_2::NetworkScanResult&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_4(V1_0::RadioIndicationType type,
+ const V1_4::NetworkScanResult&) {
+ LOG_CALL << type;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_5(V1_0::RadioIndicationType type,
+ const V1_5::NetworkScanResult& result) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+ return {};
+}
+
+Return<void> RadioIndication::networkScanResult_1_6(V1_0::RadioIndicationType type,
+ const V1_6::NetworkScanResult& result) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+ return {};
+}
+
+Return<void> RadioIndication::networkStateChanged(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->networkStateChanged(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::nitzTimeReceived(V1_0::RadioIndicationType type,
+ const hidl_string& nitzTime, uint64_t receivedTime) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
+ return {};
+}
+
+Return<void> RadioIndication::registrationFailed( //
+ V1_0::RadioIndicationType type, const V1_5::CellIdentity& cellIdentity,
+ const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
+ int32_t additionalCauseCode) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn,
+ aidl::Domain(domain), causeCode, additionalCauseCode);
+ return {};
+}
+
+Return<void> RadioIndication::restrictedStateChanged(V1_0::RadioIndicationType type,
+ V1_0::PhoneRestrictedState state) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
+ return {};
+}
+
+Return<void> RadioIndication::suppSvcNotify(V1_0::RadioIndicationType type,
+ const V1_0::SuppSvcNotification& suppSvc) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->suppSvcNotify(toAidl(type), toAidl(suppSvc));
+ return {};
+}
+
+Return<void> RadioIndication::voiceRadioTechChanged(V1_0::RadioIndicationType type,
+ V1_0::RadioTechnology rat) {
+ LOG_CALL << type;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
+ return {};
+}
+
+Return<void> RadioIndication::lceData(V1_0::RadioIndicationType type, const V1_0::LceDataInfo&) {
+ LOG_CALL << type;
+ LOG(WARNING) << "lceData indication is deprecated";
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
new file mode 100644
index 0000000..af0bc46
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -0,0 +1,281 @@
+/*
+ * 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 <libradiocompat/RadioNetwork.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+#include "utils.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Network"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::AccessNetwork;
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::network;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioNetwork::getAllowedNetworkTypesBitmap(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->getAllowedNetworkTypesBitmap(serial);
+ } else {
+ mHal1_5->getPreferredNetworkType(serial);
+ }
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getAvailableBandModes(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getAvailableBandModes(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getAvailableNetworks(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getAvailableNetworks(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getBarringInfo(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getBarringInfo(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getCdmaRoamingPreference(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getCdmaRoamingPreference(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getCellInfoList(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getCellInfoList(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getDataRegistrationState(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getDataRegistrationState(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getImsRegistrationState(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getImsRegistrationState(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getNetworkSelectionMode(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getNetworkSelectionMode(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getOperator(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getOperator(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getSignalStrength(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getSignalStrength(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getSystemSelectionChannels(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->getSystemSelectionChannels(serial);
+ } else {
+ respond().getSystemSelectionChannelsResponse(notSupported(serial), {});
+ }
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getVoiceRadioTechnology(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getVoiceRadioTechnology(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::getVoiceRegistrationState(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getVoiceRegistrationState(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::isNrDualConnectivityEnabled(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->isNrDualConnectivityEnabled(serial);
+ } else {
+ respond().isNrDualConnectivityEnabledResponse(notSupported(serial), false);
+ }
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::responseAcknowledgement() {
+ LOG_CALL;
+ mHal1_5->responseAcknowledgement();
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, RadioAccessFamily ntype) {
+ LOG_CALL << serial;
+ const auto raf = toHidlBitfield<V1_4::RadioAccessFamily>(ntype);
+ if (mHal1_6) {
+ mHal1_6->setAllowedNetworkTypesBitmap(serial, raf);
+ } else {
+ mHal1_5->setPreferredNetworkType(serial, getNetworkTypeFromRaf(raf));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setBandMode(int32_t serial, aidl::RadioBandMode mode) {
+ LOG_CALL << serial;
+ mHal1_5->setBandMode(serial, V1_0::RadioBandMode(mode));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setBarringPassword(int32_t serial, const std::string& facility,
+ const std::string& oldPw, const std::string& newPw) {
+ LOG_CALL << serial;
+ mHal1_5->setBarringPassword(serial, facility, oldPw, newPw);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setCdmaRoamingPreference(int32_t serial, aidl::CdmaRoamingType type) {
+ LOG_CALL << serial;
+ mHal1_5->setCdmaRoamingPreference(serial, V1_0::CdmaRoamingType(type));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setCellInfoListRate(int32_t serial, int32_t rate) {
+ LOG_CALL << serial;
+ mHal1_5->setCellInfoListRate(serial, rate);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, aidl::IndicationFilter indFilter) {
+ LOG_CALL << serial;
+ mHal1_5->setIndicationFilter(serial, toHidlBitfield<V1_0::IndicationFilter>(indFilter));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setLinkCapacityReportingCriteria( //
+ int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps, int32_t hysteresisUlKbps,
+ const std::vector<int32_t>& thrDownlinkKbps, const std::vector<int32_t>& thrUplinkKbps,
+ AccessNetwork accessNetwork) {
+ LOG_CALL << serial;
+ mHal1_5->setLinkCapacityReportingCriteria( //
+ serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps, thrDownlinkKbps,
+ thrUplinkKbps, V1_2::AccessNetwork(accessNetwork));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setLocationUpdates(int32_t serial, bool enable) {
+ LOG_CALL << serial;
+ mHal1_5->setLocationUpdates(serial, enable);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setNetworkSelectionModeAutomatic(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->setNetworkSelectionModeAutomatic(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setNetworkSelectionModeManual( //
+ int32_t serial, const std::string& opNumeric, AccessNetwork ran) {
+ LOG_CALL << serial;
+ mHal1_5->setNetworkSelectionModeManual_1_5(serial, opNumeric, V1_5::RadioAccessNetworks(ran));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setNrDualConnectivityState(int32_t serial,
+ aidl::NrDualConnectivityState st) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->setNrDualConnectivityState(serial, V1_6::NrDualConnectivityState(st));
+ } else {
+ respond().setNrDualConnectivityStateResponse(notSupported(serial));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioNetworkResponse>& networkResponse,
+ const std::shared_ptr<aidl::IRadioNetworkIndication>& networkIndication) {
+ LOG_CALL << networkResponse << ' ' << networkIndication;
+
+ CHECK(networkResponse);
+ CHECK(networkIndication);
+
+ mRadioResponse->setResponseFunction(networkResponse);
+ mRadioIndication->setResponseFunction(networkIndication);
+
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
+ int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
+ LOG_CALL << serial;
+ // TODO(b/203699028): how about other infos?
+ mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
+ V1_5::AccessNetwork(infos[0].ran));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setSuppServiceNotifications(int32_t serial, bool enable) {
+ LOG_CALL << serial;
+ mHal1_5->setSuppServiceNotifications(serial, enable);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setSystemSelectionChannels( //
+ int32_t serial, bool specifyCh, const std::vector<aidl::RadioAccessSpecifier>& specifiers) {
+ LOG_CALL << serial;
+ mHal1_5->setSystemSelectionChannels_1_5(serial, specifyCh, toHidl(specifiers));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::startNetworkScan(int32_t serial, const aidl::NetworkScanRequest& req) {
+ LOG_CALL << serial;
+ mHal1_5->startNetworkScan_1_5(serial, toHidl(req));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::stopNetworkScan(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->stopNetworkScan(serial);
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::supplyNetworkDepersonalization(int32_t ser, const std::string& nPin) {
+ LOG_CALL << ser;
+ mHal1_5->supplyNetworkDepersonalization(ser, nPin);
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
new file mode 100644
index 0000000..81f7775
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
@@ -0,0 +1,506 @@
+/*
+ * 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 <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+#include "utils.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "NetworkResponse"
+
+namespace android::hardware::radio::compat {
+
+using ::aidl::android::hardware::radio::RadioAccessFamily;
+using ::aidl::android::hardware::radio::RadioTechnology;
+using ::aidl::android::hardware::radio::RadioTechnologyFamily;
+namespace aidl = ::aidl::android::hardware::radio::network;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkResponse> netCb) {
+ CHECK(netCb);
+ mNetworkCb = netCb;
+}
+
+Return<void> RadioResponse::getAllowedNetworkTypesBitmapResponse(
+ const V1_6::RadioResponseInfo& info,
+ hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getAllowedNetworkTypesBitmapResponse(toAidl(info),
+ RadioAccessFamily(networkTypeBitmap));
+ return {};
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::PreferredNetworkType nwType) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getAllowedNetworkTypesBitmapResponse( //
+ toAidl(info), RadioAccessFamily(getRafFromNetworkType(nwType)));
+ return {};
+}
+
+Return<void> RadioResponse::getPreferredNetworkTypeBitmapResponse(
+ const V1_0::RadioResponseInfo& info, hidl_bitfield<V1_4::RadioAccessFamily>) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getAvailableBandModesResponse(
+ const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::RadioBandMode>& bandModes) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
+ return {};
+}
+
+Return<void> RadioResponse::getAvailableNetworksResponse(
+ const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::OperatorInfo>& networkInfos) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
+ return {};
+}
+
+Return<void> RadioResponse::getBarringInfoResponse(
+ const V1_0::RadioResponseInfo& info, const V1_5::CellIdentity& cellIdentity,
+ const hidl_vec<V1_5::BarringInfo>& barringInfos) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
+ return {};
+}
+
+Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::CdmaRoamingType type) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
+ return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::CellInfo>&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_2::CellInfo>&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_4::CellInfo>&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_5::CellInfo>& cellInfo) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+ return {};
+}
+
+Return<void> RadioResponse::getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_6::CellInfo>& cellInfo) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+ return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::DataRegStateResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_2(
+ const V1_0::RadioResponseInfo& info, const V1_2::DataRegStateResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_4(
+ const V1_0::RadioResponseInfo& info, const V1_4::DataRegStateResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_5(
+ const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& dataRegResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+ return {};
+}
+
+Return<void> RadioResponse::getDataRegistrationStateResponse_1_6(
+ const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& dataRegResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+ return {};
+}
+
+Return<void> RadioResponse::getImsRegistrationStateResponse( //
+ const V1_0::RadioResponseInfo& info, bool isRegd, V1_0::RadioTechnologyFamily ratFamily) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getImsRegistrationStateResponse(toAidl(info), isRegd,
+ RadioTechnologyFamily(ratFamily));
+ return {};
+}
+
+Return<void> RadioResponse::getNeighboringCidsResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::NeighboringCell>&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "getNeighboringCidsResponse is not supposed to be called";
+ return {};
+}
+
+Return<void> RadioResponse::getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
+ bool manual) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getNetworkSelectionModeResponse(toAidl(info), manual);
+ return {};
+}
+
+Return<void> RadioResponse::getOperatorResponse( //
+ const V1_0::RadioResponseInfo& info, const hidl_string& longName,
+ const hidl_string& shortName, const hidl_string& numeric) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getOperatorResponse(toAidl(info), longName, shortName, numeric);
+ return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::SignalStrength&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const V1_2::SignalStrength&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_4(
+ const V1_0::RadioResponseInfo& info, const V1_4::SignalStrength& signalStrength) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+ return {};
+}
+
+Return<void> RadioResponse::getSignalStrengthResponse_1_6(
+ const V1_6::RadioResponseInfo& info, const V1_6::SignalStrength& signalStrength) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+ return {};
+}
+
+Return<void> RadioResponse::getSystemSelectionChannelsResponse(
+ const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
+ return {};
+}
+
+Return<void> RadioResponse::getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::RadioTechnology rat) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
+ return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::VoiceRegStateResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.0 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_2(
+ const V1_0::RadioResponseInfo& info, const V1_2::VoiceRegStateResult&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.2 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_5(
+ const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& voiceRegResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+ return {};
+}
+
+Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_6(
+ const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& voiceRegResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+ return {};
+}
+
+Return<void> RadioResponse::isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
+ bool isEnabled) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
+ return {};
+}
+
+Return<void> RadioResponse::pullLceDataResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::LceDataInfo&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "pullLceDataResponse is not supposed to be called";
+ return {};
+}
+
+Return<void> RadioResponse::setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& i) {
+ LOG_CALL << i.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(i));
+ return {};
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setPreferredNetworkTypeBitmapResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "IRadio HAL 1.4 not supported";
+ return {};
+}
+
+Return<void> RadioResponse::setBandModeResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setBandModeResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setBarringPasswordResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setCdmaRoamingPreferenceResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setCellInfoListRateResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setIndicationFilterResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setIndicationFilterResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse_1_5(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setLocationUpdatesResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setNetworkSelectionModeAutomaticResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setNetworkSelectionModeManualResponse_1_5(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setNrDualConnectivityStateResponse(
+ const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setNrDualConnectivityStateResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse_1_5(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSuppServiceNotificationsResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setSuppServiceNotificationsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSystemSelectionChannelsResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSystemSelectionChannelsResponse_1_5(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->startNetworkScanResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->startNetworkScanResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->startNetworkScanResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->stopNetworkScanResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
+ const V1_0::RadioResponseInfo& info, int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mNetworkCb);
+ mNetworkCb->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::startLceServiceResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::LceStatusInfo&) {
+ LOG_CALL << info.serial;
+ LOG(WARNING) << "startLceServiceResponse is deprecated";
+ return {};
+}
+
+Return<void> RadioResponse::stopLceServiceResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::LceStatusInfo&) {
+ LOG_CALL << info.serial;
+ LOG(WARNING) << "stopLceServiceResponse is deprecated";
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.cpp b/radio/aidl/compat/libradiocompat/network/structs.cpp
new file mode 100644
index 0000000..87a021f
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/structs.cpp
@@ -0,0 +1,668 @@
+/*
+ * 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 "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::network;
+using ::aidl::android::hardware::radio::AccessNetwork;
+using ::aidl::android::hardware::radio::RadioTechnology;
+
+aidl::RadioBandMode toAidl(V1_0::RadioBandMode mode) {
+ return aidl::RadioBandMode(mode);
+}
+
+aidl::GeranBands toAidl(V1_1::GeranBands band) {
+ return aidl::GeranBands(band);
+}
+
+V1_1::GeranBands toHidl(aidl::GeranBands band) {
+ return V1_1::GeranBands(band);
+}
+
+aidl::UtranBands toAidl(V1_5::UtranBands band) {
+ return aidl::UtranBands(band);
+}
+
+V1_5::UtranBands toHidl(aidl::UtranBands band) {
+ return V1_5::UtranBands(band);
+}
+
+aidl::EutranBands toAidl(V1_5::EutranBands band) {
+ return aidl::EutranBands(band);
+}
+
+V1_5::EutranBands toHidl(aidl::EutranBands band) {
+ return V1_5::EutranBands(band);
+}
+
+aidl::NgranBands toAidl(V1_5::NgranBands band) {
+ return aidl::NgranBands(band);
+}
+
+V1_5::NgranBands toHidl(aidl::NgranBands band) {
+ return V1_5::NgranBands(band);
+}
+
+V1_5::SignalThresholdInfo toHidl(const aidl::SignalThresholdInfo& info) {
+ return {
+ .signalMeasurement = V1_5::SignalMeasurementType{info.signalMeasurement},
+ .hysteresisMs = info.hysteresisMs,
+ .hysteresisDb = info.hysteresisDb,
+ .thresholds = info.thresholds,
+ .isEnabled = info.isEnabled,
+ };
+}
+
+static aidl::RadioAccessSpecifierBands toAidl(const V1_5::RadioAccessSpecifier::Bands& bands) {
+ using Discr = V1_5::RadioAccessSpecifier::Bands::hidl_discriminator;
+ const auto discr = bands.getDiscriminator();
+
+ if (discr == Discr::geranBands) return toAidl(bands.geranBands());
+ if (discr == Discr::utranBands) return toAidl(bands.utranBands());
+ if (discr == Discr::eutranBands) return toAidl(bands.eutranBands());
+ if (discr == Discr::ngranBands) return toAidl(bands.ngranBands());
+
+ return {};
+}
+
+static V1_5::RadioAccessSpecifier::Bands toHidl(const aidl::RadioAccessSpecifierBands& bands) {
+ V1_5::RadioAccessSpecifier::Bands hidl;
+ using Tag = aidl::RadioAccessSpecifierBands::Tag;
+
+ if (bands.getTag() == Tag::geranBands) hidl.geranBands(toHidl(bands.get<Tag::geranBands>()));
+ if (bands.getTag() == Tag::utranBands) hidl.utranBands(toHidl(bands.get<Tag::utranBands>()));
+ if (bands.getTag() == Tag::eutranBands) hidl.eutranBands(toHidl(bands.get<Tag::eutranBands>()));
+ if (bands.getTag() == Tag::ngranBands) hidl.ngranBands(toHidl(bands.get<Tag::ngranBands>()));
+
+ return hidl;
+}
+
+aidl::RadioAccessSpecifier toAidl(const V1_5::RadioAccessSpecifier& spec) {
+ return {
+ .accessNetwork = AccessNetwork(spec.radioAccessNetwork),
+ .bands = toAidl(spec.bands),
+ .channels = spec.channels,
+ };
+}
+
+V1_5::RadioAccessSpecifier toHidl(const aidl::RadioAccessSpecifier& spec) {
+ return {
+ .radioAccessNetwork = V1_5::RadioAccessNetworks{spec.accessNetwork},
+ .bands = toHidl(spec.bands),
+ .channels = spec.channels,
+ };
+}
+
+V1_5::NetworkScanRequest toHidl(const aidl::NetworkScanRequest& req) {
+ return {
+ .type = V1_1::ScanType{req.type},
+ .interval = req.interval,
+ .specifiers = toHidl(req.specifiers),
+ .maxSearchTime = req.maxSearchTime,
+ .incrementalResults = req.incrementalResults,
+ .incrementalResultsPeriodicity = req.incrementalResultsPeriodicity,
+ .mccMncs = toHidl(req.mccMncs),
+ };
+}
+
+static aidl::OperatorInfo toAidl(const V1_2::CellIdentityOperatorNames& names) {
+ return {
+ .alphaLong = names.alphaLong,
+ .alphaShort = names.alphaShort,
+ .operatorNumeric = "",
+ .status = aidl::OperatorInfo::STATUS_UNKNOWN,
+ };
+}
+
+static aidl::CellIdentityGsm toAidl(const V1_5::CellIdentityGsm& ci) {
+ return {
+ .mcc = ci.base.base.mcc,
+ .mnc = ci.base.base.mnc,
+ .lac = ci.base.base.lac,
+ .cid = ci.base.base.cid,
+ .arfcn = ci.base.base.arfcn,
+ .bsic = static_cast<int8_t>(ci.base.base.bsic),
+ .operatorNames = toAidl(ci.base.operatorNames),
+ .additionalPlmns = toAidl(ci.additionalPlmns),
+ };
+}
+
+aidl::ClosedSubscriberGroupInfo toAidl(const V1_5::ClosedSubscriberGroupInfo& info) {
+ return {
+ .csgIndication = info.csgIndication,
+ .homeNodebName = info.homeNodebName,
+ .csgIdentity = info.csgIdentity,
+ };
+}
+
+static std::optional<aidl::ClosedSubscriberGroupInfo> toAidl(const V1_5::OptionalCsgInfo& opt) {
+ using descr = V1_5::OptionalCsgInfo::hidl_discriminator;
+ if (opt.getDiscriminator() == descr::noinit) return std::nullopt;
+ return toAidl(opt.csgInfo());
+}
+
+static aidl::CellIdentityWcdma toAidl(const V1_5::CellIdentityWcdma& ci) {
+ return {
+ .mcc = ci.base.base.mcc,
+ .mnc = ci.base.base.mnc,
+ .lac = ci.base.base.lac,
+ .cid = ci.base.base.cid,
+ .psc = ci.base.base.psc,
+ .uarfcn = ci.base.base.uarfcn,
+ .operatorNames = toAidl(ci.base.operatorNames),
+ .additionalPlmns = toAidl(ci.additionalPlmns),
+ .csgInfo = toAidl(ci.optionalCsgInfo),
+ };
+}
+
+static aidl::CellIdentityTdscdma toAidl(const V1_5::CellIdentityTdscdma& ci) {
+ return {
+ .mcc = ci.base.base.mcc,
+ .mnc = ci.base.base.mnc,
+ .lac = ci.base.base.lac,
+ .cid = ci.base.base.cid,
+ .cpid = ci.base.base.cpid,
+ .uarfcn = ci.base.uarfcn,
+ .operatorNames = toAidl(ci.base.operatorNames),
+ .additionalPlmns = toAidl(ci.additionalPlmns),
+ .csgInfo = toAidl(ci.optionalCsgInfo),
+ };
+}
+
+static aidl::CellIdentityCdma toAidl(const V1_2::CellIdentityCdma& ci) {
+ return {
+ .networkId = ci.base.networkId,
+ .systemId = ci.base.systemId,
+ .baseStationId = ci.base.baseStationId,
+ .longitude = ci.base.longitude,
+ .latitude = ci.base.latitude,
+ .operatorNames = toAidl(ci.operatorNames),
+ };
+}
+
+static aidl::CellIdentityLte toAidl(const V1_5::CellIdentityLte& ci) {
+ return {
+ .mcc = ci.base.base.mcc,
+ .mnc = ci.base.base.mnc,
+ .ci = ci.base.base.ci,
+ .pci = ci.base.base.pci,
+ .tac = ci.base.base.tac,
+ .earfcn = ci.base.base.earfcn,
+ .operatorNames = toAidl(ci.base.operatorNames),
+ .bandwidth = ci.base.bandwidth,
+ .additionalPlmns = toAidl(ci.additionalPlmns),
+ .csgInfo = toAidl(ci.optionalCsgInfo),
+ .bands = toAidl(ci.bands),
+ };
+}
+
+static aidl::CellIdentityNr toAidl(const V1_5::CellIdentityNr& ci) {
+ return {
+ .mcc = ci.base.mcc,
+ .mnc = ci.base.mnc,
+ .nci = static_cast<int64_t>(ci.base.nci),
+ .pci = static_cast<int32_t>(ci.base.pci),
+ .tac = ci.base.tac,
+ .nrarfcn = ci.base.nrarfcn,
+ .operatorNames = toAidl(ci.base.operatorNames),
+ .additionalPlmns = toAidl(ci.additionalPlmns),
+ .bands = toAidl(ci.bands),
+ };
+}
+
+aidl::CellIdentity toAidl(const V1_5::CellIdentity& ci) {
+ using Discr = V1_5::CellIdentity::hidl_discriminator;
+ const auto discr = ci.getDiscriminator();
+
+ if (discr == Discr::gsm) return toAidl(ci.gsm());
+ if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+ if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+ if (discr == Discr::cdma) return toAidl(ci.cdma());
+ if (discr == Discr::lte) return toAidl(ci.lte());
+ if (discr == Discr::nr) return toAidl(ci.nr());
+
+ return {};
+}
+
+static std::optional<aidl::BarringTypeSpecificInfo> //
+toAidl(const V1_5::BarringInfo::BarringTypeSpecificInfo& opt) {
+ using discr = V1_5::BarringInfo::BarringTypeSpecificInfo::hidl_discriminator;
+ if (opt.getDiscriminator() == discr::noinit) return std::nullopt;
+
+ const auto& info = opt.conditional();
+ return aidl::BarringTypeSpecificInfo{
+ .factor = info.factor,
+ .timeSeconds = info.timeSeconds,
+ .isBarred = info.isBarred,
+ };
+}
+
+aidl::BarringInfo toAidl(const V1_5::BarringInfo& info) {
+ return {
+ .serviceType = static_cast<int32_t>(info.serviceType),
+ .barringType = static_cast<int32_t>(info.barringType),
+ .barringTypeSpecificInfo = toAidl(info.barringTypeSpecificInfo),
+ };
+}
+
+static aidl::GsmSignalStrength toAidl(const V1_0::GsmSignalStrength& sig) {
+ return {
+ .signalStrength = static_cast<int32_t>(sig.signalStrength),
+ .bitErrorRate = static_cast<int32_t>(sig.bitErrorRate),
+ .timingAdvance = sig.timingAdvance,
+ };
+}
+
+static aidl::CellInfoGsm toAidl(const V1_5::CellInfoGsm& info) {
+ return {
+ .cellIdentityGsm = toAidl(info.cellIdentityGsm),
+ .signalStrengthGsm = toAidl(info.signalStrengthGsm),
+ };
+}
+
+static aidl::WcdmaSignalStrength toAidl(const V1_2::WcdmaSignalStrength& sig) {
+ return {
+ .signalStrength = sig.base.signalStrength,
+ .bitErrorRate = sig.base.bitErrorRate,
+ .rscp = static_cast<int32_t>(sig.rscp),
+ .ecno = static_cast<int32_t>(sig.ecno),
+ };
+}
+
+static aidl::CellInfoWcdma toAidl(const V1_5::CellInfoWcdma& info) {
+ return {
+ .cellIdentityWcdma = toAidl(info.cellIdentityWcdma),
+ .signalStrengthWcdma = toAidl(info.signalStrengthWcdma),
+ };
+}
+
+static aidl::TdscdmaSignalStrength toAidl(const V1_2::TdscdmaSignalStrength& sig) {
+ return {
+ .signalStrength = static_cast<int32_t>(sig.signalStrength),
+ .bitErrorRate = static_cast<int32_t>(sig.bitErrorRate),
+ .rscp = static_cast<int32_t>(sig.rscp),
+ };
+}
+
+static aidl::CellInfoTdscdma toAidl(const V1_5::CellInfoTdscdma& info) {
+ return {
+ .cellIdentityTdscdma = toAidl(info.cellIdentityTdscdma),
+ .signalStrengthTdscdma = toAidl(info.signalStrengthTdscdma),
+ };
+}
+
+static aidl::LteSignalStrength toAidl(const V1_6::LteSignalStrength& sig) {
+ return {
+ .signalStrength = static_cast<int32_t>(sig.base.signalStrength),
+ .rsrp = static_cast<int32_t>(sig.base.rsrp),
+ .rsrq = static_cast<int32_t>(sig.base.rsrq),
+ .rssnr = sig.base.rssnr,
+ .cqi = static_cast<int32_t>(sig.base.cqi),
+ .timingAdvance = static_cast<int32_t>(sig.base.timingAdvance),
+ .cqiTableIndex = static_cast<int32_t>(sig.cqiTableIndex),
+ };
+}
+
+static aidl::LteSignalStrength toAidl(const V1_0::LteSignalStrength& sig) {
+ return toAidl({sig, 0});
+}
+
+static aidl::CellInfoLte toAidl(const V1_5::CellInfoLte& info) {
+ return {
+ .cellIdentityLte = toAidl(info.cellIdentityLte),
+ .signalStrengthLte = toAidl(info.signalStrengthLte),
+ };
+}
+
+static aidl::CellInfoLte toAidl(const V1_6::CellInfoLte& info) {
+ return {
+ .cellIdentityLte = toAidl(info.cellIdentityLte),
+ .signalStrengthLte = toAidl(info.signalStrengthLte),
+ };
+}
+
+static aidl::NrSignalStrength toAidl(const V1_6::NrSignalStrength& sig) {
+ return {
+ .ssRsrp = sig.base.ssRsrp,
+ .ssRsrq = sig.base.ssRsrq,
+ .ssSinr = sig.base.ssSinr,
+ .csiRsrp = sig.base.csiRsrp,
+ .csiRsrq = sig.base.csiRsrq,
+ .csiSinr = sig.base.csiSinr,
+ .csiCqiTableIndex = static_cast<int32_t>(sig.csiCqiTableIndex),
+ .csiCqiReport = sig.csiCqiReport,
+ };
+}
+
+static aidl::NrSignalStrength toAidl(const V1_4::NrSignalStrength& sig) {
+ return toAidl({sig, 0, 0});
+}
+
+static aidl::CellInfoNr toAidl(const V1_5::CellInfoNr& info) {
+ return {
+ .cellIdentityNr = toAidl(info.cellIdentityNr),
+ .signalStrengthNr = toAidl(info.signalStrengthNr),
+ };
+}
+
+static aidl::CellInfoNr toAidl(const V1_6::CellInfoNr& info) {
+ return {
+ .cellIdentityNr = toAidl(info.cellIdentityNr),
+ .signalStrengthNr = toAidl(info.signalStrengthNr),
+ };
+}
+
+static aidl::CdmaSignalStrength toAidl(const V1_0::CdmaSignalStrength& sig) {
+ return {
+ .dbm = static_cast<int32_t>(sig.dbm),
+ .ecio = static_cast<int32_t>(sig.ecio),
+ };
+}
+
+static aidl::EvdoSignalStrength toAidl(const V1_0::EvdoSignalStrength& sig) {
+ return {
+ .dbm = static_cast<int32_t>(sig.dbm),
+ .ecio = static_cast<int32_t>(sig.ecio),
+ .signalNoiseRatio = static_cast<int32_t>(sig.signalNoiseRatio),
+ };
+}
+
+static aidl::CellInfoCdma toAidl(const V1_2::CellInfoCdma& info) {
+ return {
+ .cellIdentityCdma = toAidl(info.cellIdentityCdma),
+ .signalStrengthCdma = toAidl(info.signalStrengthCdma),
+ .signalStrengthEvdo = toAidl(info.signalStrengthEvdo),
+ };
+}
+
+static aidl::CellInfoRatSpecificInfo toAidl(const V1_5::CellInfo::CellInfoRatSpecificInfo& ci) {
+ using Discr = V1_5::CellInfo::CellInfoRatSpecificInfo::hidl_discriminator;
+ const auto discr = ci.getDiscriminator();
+
+ if (discr == Discr::gsm) return toAidl(ci.gsm());
+ if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+ if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+ if (discr == Discr::lte) return toAidl(ci.lte());
+ if (discr == Discr::nr) return toAidl(ci.nr());
+ if (discr == Discr::cdma) return toAidl(ci.cdma());
+
+ return {};
+}
+
+static aidl::CellInfoRatSpecificInfo toAidl(const V1_6::CellInfo::CellInfoRatSpecificInfo& ci) {
+ using Discr = V1_6::CellInfo::CellInfoRatSpecificInfo::hidl_discriminator;
+ const auto discr = ci.getDiscriminator();
+
+ if (discr == Discr::gsm) return toAidl(ci.gsm());
+ if (discr == Discr::wcdma) return toAidl(ci.wcdma());
+ if (discr == Discr::tdscdma) return toAidl(ci.tdscdma());
+ if (discr == Discr::lte) return toAidl(ci.lte());
+ if (discr == Discr::nr) return toAidl(ci.nr());
+ if (discr == Discr::cdma) return toAidl(ci.cdma());
+
+ return {};
+}
+
+aidl::CellInfo toAidl(const V1_5::CellInfo& info) {
+ return {
+ .registered = info.registered,
+ // ignored: timeStampType and timeStamp
+ .connectionStatus = aidl::CellConnectionStatus(info.connectionStatus),
+ .ratSpecificInfo = toAidl(info.ratSpecificInfo),
+ };
+}
+
+aidl::CellInfo toAidl(const V1_6::CellInfo& info) {
+ return {
+ .registered = info.registered,
+ .connectionStatus = aidl::CellConnectionStatus(info.connectionStatus),
+ .ratSpecificInfo = toAidl(info.ratSpecificInfo),
+ };
+}
+
+aidl::LinkCapacityEstimate toAidl(const V1_2::LinkCapacityEstimate& e) {
+ return {
+ .downlinkCapacityKbps = static_cast<int32_t>(e.downlinkCapacityKbps),
+ .uplinkCapacityKbps = static_cast<int32_t>(e.uplinkCapacityKbps),
+ };
+}
+
+aidl::LinkCapacityEstimate toAidl(const V1_6::LinkCapacityEstimate& e) {
+ return {
+ .downlinkCapacityKbps = static_cast<int32_t>(e.downlinkCapacityKbps),
+ .uplinkCapacityKbps = static_cast<int32_t>(e.uplinkCapacityKbps),
+ .secondaryDownlinkCapacityKbps = static_cast<int32_t>(e.secondaryDownlinkCapacityKbps),
+ .secondaryUplinkCapacityKbps = static_cast<int32_t>(e.secondaryUplinkCapacityKbps),
+ };
+}
+
+static aidl::PhysicalChannelConfigBand toAidl(const V1_6::PhysicalChannelConfig::Band& band) {
+ using Discr = V1_6::PhysicalChannelConfig::Band::hidl_discriminator;
+ const auto discr = band.getDiscriminator();
+
+ if (discr == Discr::geranBand) return aidl::GeranBands(band.geranBand());
+ if (discr == Discr::utranBand) return aidl::UtranBands(band.utranBand());
+ if (discr == Discr::eutranBand) return aidl::EutranBands(band.eutranBand());
+ if (discr == Discr::ngranBand) return aidl::NgranBands(band.ngranBand());
+
+ return {};
+}
+
+aidl::PhysicalChannelConfig toAidl(const V1_4::PhysicalChannelConfig& cfg) {
+ int32_t downlinkChannelNumber = 0;
+ // ignored rfInfo.range
+ using Discr = V1_4::RadioFrequencyInfo::hidl_discriminator;
+ if (cfg.rfInfo.getDiscriminator() == Discr::channelNumber) {
+ downlinkChannelNumber = cfg.rfInfo.channelNumber();
+ }
+
+ return {
+ .status = aidl::CellConnectionStatus(cfg.base.status),
+ .rat = RadioTechnology(cfg.rat),
+ .downlinkChannelNumber = downlinkChannelNumber,
+ .cellBandwidthDownlinkKhz = cfg.base.cellBandwidthDownlink,
+ .contextIds = cfg.contextIds,
+ .physicalCellId = static_cast<int32_t>(cfg.physicalCellId),
+ };
+}
+
+aidl::PhysicalChannelConfig toAidl(const V1_6::PhysicalChannelConfig& cfg) {
+ return {
+ .status = aidl::CellConnectionStatus(cfg.status),
+ .rat = RadioTechnology(cfg.rat),
+ .downlinkChannelNumber = cfg.downlinkChannelNumber,
+ .uplinkChannelNumber = cfg.uplinkChannelNumber,
+ .cellBandwidthDownlinkKhz = cfg.cellBandwidthDownlinkKhz,
+ .cellBandwidthUplinkKhz = cfg.cellBandwidthUplinkKhz,
+ .contextIds = cfg.contextIds,
+ .physicalCellId = static_cast<int32_t>(cfg.physicalCellId),
+ .band = toAidl(cfg.band),
+ };
+}
+
+aidl::SignalStrength toAidl(const V1_4::SignalStrength& sig) {
+ return {
+ .gsm = toAidl(sig.gsm),
+ .cdma = toAidl(sig.cdma),
+ .evdo = toAidl(sig.evdo),
+ .lte = toAidl(sig.lte),
+ .tdscdma = toAidl(sig.tdscdma),
+ .wcdma = toAidl(sig.wcdma),
+ .nr = toAidl(sig.nr),
+ };
+}
+
+aidl::SignalStrength toAidl(const V1_6::SignalStrength& sig) {
+ return {
+ .gsm = toAidl(sig.gsm),
+ .cdma = toAidl(sig.cdma),
+ .evdo = toAidl(sig.evdo),
+ .lte = toAidl(sig.lte),
+ .tdscdma = toAidl(sig.tdscdma),
+ .wcdma = toAidl(sig.wcdma),
+ .nr = toAidl(sig.nr),
+ };
+}
+
+aidl::NetworkScanResult toAidl(const V1_5::NetworkScanResult& res) {
+ return {
+ .status = static_cast<int32_t>(res.status),
+ .error = toAidl(res.error),
+ .networkInfos = toAidl(res.networkInfos),
+ };
+}
+
+aidl::NetworkScanResult toAidl(const V1_6::NetworkScanResult& res) {
+ return {
+ .status = static_cast<int32_t>(res.status),
+ .error = toAidl(res.error),
+ .networkInfos = toAidl(res.networkInfos),
+ };
+}
+
+aidl::SuppSvcNotification toAidl(const V1_0::SuppSvcNotification& svc) {
+ return {
+ .isMT = svc.isMT,
+ .code = svc.code,
+ .index = svc.index,
+ .type = svc.type,
+ .number = svc.number,
+ };
+}
+
+aidl::OperatorInfo toAidl(const V1_0::OperatorInfo& info) {
+ return {
+ .alphaLong = info.alphaLong,
+ .alphaShort = info.alphaShort,
+ .operatorNumeric = info.operatorNumeric,
+ .status = static_cast<int32_t>(info.status),
+ };
+}
+
+static aidl::Cdma2000RegistrationInfo //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo::Cdma2000RegistrationInfo& info) {
+ return {
+ .cssSupported = info.cssSupported,
+ .roamingIndicator = info.roamingIndicator,
+ .systemIsInPrl = static_cast<int32_t>(info.systemIsInPrl),
+ .defaultRoamingIndicator = info.defaultRoamingIndicator,
+ };
+}
+
+static aidl::LteVopsInfo toAidl(const V1_4::LteVopsInfo& info) {
+ return {
+ .isVopsSupported = info.isVopsSupported,
+ .isEmcBearerSupported = info.isEmcBearerSupported,
+ };
+}
+
+static aidl::NrIndicators toAidl(const V1_4::NrIndicators& info) {
+ return {
+ .isEndcAvailable = info.isEndcAvailable,
+ .isDcNrRestricted = info.isDcNrRestricted,
+ .isNrAvailable = info.isNrAvailable,
+ };
+}
+
+static aidl::EutranRegistrationInfo //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo::EutranRegistrationInfo& info) {
+ return {
+ .lteVopsInfo = toAidl(info.lteVopsInfo),
+ .nrIndicators = toAidl(info.nrIndicators),
+ };
+}
+
+static aidl::NrVopsInfo toAidl(const V1_6::NrVopsInfo& info) {
+ return {
+ .vopsSupported = static_cast<int8_t>(info.vopsSupported),
+ .emcSupported = static_cast<int8_t>(info.emcSupported),
+ .emfSupported = static_cast<int8_t>(info.emfSupported),
+ };
+}
+
+static aidl::AccessTechnologySpecificInfo //
+toAidl(const V1_5::RegStateResult::AccessTechnologySpecificInfo& info) {
+ using Discr = V1_5::RegStateResult::AccessTechnologySpecificInfo::hidl_discriminator;
+ const auto discr = info.getDiscriminator();
+
+ if (discr == Discr::cdmaInfo) return toAidl(info.cdmaInfo());
+ if (discr == Discr::eutranInfo) return toAidl(info.eutranInfo());
+
+ return {};
+}
+
+static aidl::AccessTechnologySpecificInfo //
+toAidl(const V1_6::RegStateResult::AccessTechnologySpecificInfo& info) {
+ using Discr = V1_6::RegStateResult::AccessTechnologySpecificInfo::hidl_discriminator;
+ const auto discr = info.getDiscriminator();
+
+ if (discr == Discr::cdmaInfo) return toAidl(info.cdmaInfo());
+ if (discr == Discr::eutranInfo) return toAidl(info.eutranInfo());
+ if (discr == Discr::ngranNrVopsInfo) return toAidl(info.ngranNrVopsInfo());
+ if (discr == Discr::geranDtmSupported) {
+ using T = aidl::AccessTechnologySpecificInfo;
+ return T::make<T::Tag::geranDtmSupported>(info.geranDtmSupported());
+ }
+
+ return {};
+}
+
+aidl::RegStateResult toAidl(const V1_5::RegStateResult& res) {
+ return {
+ .regState = aidl::RegState(res.regState),
+ .rat = RadioTechnology(res.rat),
+ .reasonForDenial = aidl::RegistrationFailCause(res.reasonForDenial),
+ .cellIdentity = toAidl(res.cellIdentity),
+ .registeredPlmn = res.registeredPlmn,
+ .accessTechnologySpecificInfo = toAidl(res.accessTechnologySpecificInfo),
+ };
+}
+
+aidl::RegStateResult toAidl(const V1_6::RegStateResult& res) {
+ return {
+ .regState = aidl::RegState(res.regState),
+ .rat = RadioTechnology(res.rat),
+ .reasonForDenial = aidl::RegistrationFailCause(res.reasonForDenial),
+ .cellIdentity = toAidl(res.cellIdentity),
+ .registeredPlmn = res.registeredPlmn,
+ .accessTechnologySpecificInfo = toAidl(res.accessTechnologySpecificInfo),
+ };
+}
+
+aidl::NeighboringCell toAidl(const V1_0::NeighboringCell& cell) {
+ return {
+ .cid = cell.cid,
+ .rssi = cell.rssi,
+ };
+}
+
+aidl::LceDataInfo toAidl(const V1_0::LceDataInfo& info) {
+ return {
+ .lastHopCapacityKbps = static_cast<int32_t>(info.lastHopCapacityKbps),
+ .confidenceLevel = static_cast<int8_t>(info.confidenceLevel),
+ .lceSuspended = info.lceSuspended,
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/structs.h b/radio/aidl/compat/libradiocompat/network/structs.h
new file mode 100644
index 0000000..854cb38
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/structs.h
@@ -0,0 +1,99 @@
+/*
+ * 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/radio/network/BarringInfo.h>
+#include <aidl/android/hardware/radio/network/CellIdentity.h>
+#include <aidl/android/hardware/radio/network/CellInfo.h>
+#include <aidl/android/hardware/radio/network/LceDataInfo.h>
+#include <aidl/android/hardware/radio/network/LinkCapacityEstimate.h>
+#include <aidl/android/hardware/radio/network/NeighboringCell.h>
+#include <aidl/android/hardware/radio/network/NetworkScanRequest.h>
+#include <aidl/android/hardware/radio/network/NetworkScanResult.h>
+#include <aidl/android/hardware/radio/network/OperatorInfo.h>
+#include <aidl/android/hardware/radio/network/PhysicalChannelConfig.h>
+#include <aidl/android/hardware/radio/network/RadioAccessSpecifier.h>
+#include <aidl/android/hardware/radio/network/RadioBandMode.h>
+#include <aidl/android/hardware/radio/network/RegStateResult.h>
+#include <aidl/android/hardware/radio/network/SignalStrength.h>
+#include <aidl/android/hardware/radio/network/SignalThresholdInfo.h>
+#include <aidl/android/hardware/radio/network/SuppSvcNotification.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+::aidl::android::hardware::radio::network::RadioBandMode toAidl(V1_0::RadioBandMode mode);
+::aidl::android::hardware::radio::network::GeranBands toAidl(V1_1::GeranBands band);
+V1_1::GeranBands toHidl(::aidl::android::hardware::radio::network::GeranBands band);
+::aidl::android::hardware::radio::network::UtranBands toAidl(V1_5::UtranBands band);
+V1_5::UtranBands toHidl(::aidl::android::hardware::radio::network::UtranBands band);
+::aidl::android::hardware::radio::network::EutranBands toAidl(V1_5::EutranBands band);
+V1_5::EutranBands toHidl(::aidl::android::hardware::radio::network::EutranBands band);
+::aidl::android::hardware::radio::network::NgranBands toAidl(V1_5::NgranBands band);
+V1_5::NgranBands toHidl(::aidl::android::hardware::radio::network::NgranBands band);
+
+V1_5::SignalThresholdInfo //
+toHidl(const ::aidl::android::hardware::radio::network::SignalThresholdInfo& info);
+
+::aidl::android::hardware::radio::network::RadioAccessSpecifier //
+toAidl(const V1_5::RadioAccessSpecifier& spec);
+V1_5::RadioAccessSpecifier //
+toHidl(const ::aidl::android::hardware::radio::network::RadioAccessSpecifier& spec);
+
+V1_5::NetworkScanRequest //
+toHidl(const ::aidl::android::hardware::radio::network::NetworkScanRequest& req);
+
+::aidl::android::hardware::radio::network::CellIdentity toAidl(const V1_5::CellIdentity& ci);
+
+::aidl::android::hardware::radio::network::BarringInfo toAidl(const V1_5::BarringInfo& info);
+
+::aidl::android::hardware::radio::network::ClosedSubscriberGroupInfo //
+toAidl(const V1_5::ClosedSubscriberGroupInfo& info);
+
+::aidl::android::hardware::radio::network::CellInfo toAidl(const V1_5::CellInfo& info);
+::aidl::android::hardware::radio::network::CellInfo toAidl(const V1_6::CellInfo& info);
+
+::aidl::android::hardware::radio::network::LinkCapacityEstimate //
+toAidl(const V1_2::LinkCapacityEstimate& lce);
+::aidl::android::hardware::radio::network::LinkCapacityEstimate //
+toAidl(const V1_6::LinkCapacityEstimate& lce);
+
+::aidl::android::hardware::radio::network::PhysicalChannelConfig //
+toAidl(const V1_4::PhysicalChannelConfig& cfg);
+::aidl::android::hardware::radio::network::PhysicalChannelConfig //
+toAidl(const V1_6::PhysicalChannelConfig& cfg);
+
+::aidl::android::hardware::radio::network::SignalStrength toAidl(const V1_4::SignalStrength& sig);
+::aidl::android::hardware::radio::network::SignalStrength toAidl(const V1_6::SignalStrength& sig);
+
+::aidl::android::hardware::radio::network::NetworkScanResult //
+toAidl(const V1_5::NetworkScanResult& res);
+::aidl::android::hardware::radio::network::NetworkScanResult //
+toAidl(const V1_6::NetworkScanResult& res);
+
+::aidl::android::hardware::radio::network::SuppSvcNotification //
+toAidl(const V1_0::SuppSvcNotification& svc);
+
+::aidl::android::hardware::radio::network::OperatorInfo toAidl(const V1_0::OperatorInfo& info);
+
+::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_5::RegStateResult& res);
+::aidl::android::hardware::radio::network::RegStateResult toAidl(const V1_6::RegStateResult& res);
+
+::aidl::android::hardware::radio::network::NeighboringCell toAidl(const V1_0::NeighboringCell& c);
+
+::aidl::android::hardware::radio::network::LceDataInfo toAidl(const V1_0::LceDataInfo& info);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/utils.cpp b/radio/aidl/compat/libradiocompat/network/utils.cpp
new file mode 100644
index 0000000..6fe3e6e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/utils.cpp
@@ -0,0 +1,196 @@
+/*
+ * 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 "utils.h"
+
+namespace android::hardware::radio::compat {
+
+namespace RAF {
+using E = V1_4::RadioAccessFamily;
+constexpr auto GSM = E::GSM | E::GPRS;
+constexpr auto CDMA = E::IS95A | E::IS95B | E::ONE_X_RTT;
+constexpr auto EVDO = E::EVDO_0 | E::EVDO_A | E::EVDO_B | E::EHRPD;
+constexpr auto HS = E::HSUPA | E::HSDPA | E::HSPA | E::HSPAP;
+constexpr auto WCDMA = HS | E::UMTS;
+constexpr auto LTE = E::LTE | E::LTE_CA;
+constexpr auto NR = E::NR;
+} // namespace RAF
+
+static hidl_bitfield<V1_4::RadioAccessFamily> //
+getAdjustedRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf) {
+ if (raf & RAF::GSM) raf |= RAF::GSM;
+ if (raf & RAF::WCDMA) raf |= RAF::WCDMA;
+ if (raf & RAF::CDMA) raf |= RAF::CDMA;
+ if (raf & RAF::EVDO) raf |= RAF::EVDO;
+ if (raf & RAF::LTE) raf |= RAF::LTE;
+ if (raf & RAF::NR) raf |= RAF::NR;
+
+ return raf;
+}
+
+V1_0::PreferredNetworkType getNetworkTypeFromRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf) {
+ raf = getAdjustedRaf(raf);
+ switch (raf) {
+ case RAF::GSM | RAF::WCDMA:
+ return V1_0::PreferredNetworkType::GSM_WCDMA_AUTO;
+ case RAF::GSM:
+ return V1_0::PreferredNetworkType::GSM_ONLY;
+ case RAF::WCDMA:
+ return V1_0::PreferredNetworkType::WCDMA;
+ case (RAF::CDMA | RAF::EVDO):
+ return V1_0::PreferredNetworkType::CDMA_EVDO_AUTO;
+ case (RAF::LTE | RAF::CDMA | RAF::EVDO):
+ return V1_0::PreferredNetworkType::LTE_CDMA_EVDO;
+ case (RAF::LTE | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::LTE_GSM_WCDMA;
+ case (RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA; // CDMA typo
+ case RAF::LTE:
+ return V1_0::PreferredNetworkType::LTE_ONLY;
+ case (RAF::LTE | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::LTE_WCDMA;
+ case RAF::CDMA:
+ return V1_0::PreferredNetworkType::CDMA_ONLY;
+ case RAF::EVDO:
+ return V1_0::PreferredNetworkType::EVDO_ONLY;
+ case (RAF::GSM | RAF::WCDMA | RAF::CDMA | RAF::EVDO):
+ return V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO;
+ case static_cast<int>(RAF::E::TD_SCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_ONLY;
+ case (RAF::E::TD_SCDMA | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_WCDMA;
+ case (RAF::LTE | RAF::E::TD_SCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_LTE;
+ case (RAF::E::TD_SCDMA | RAF::GSM):
+ return V1_0::PreferredNetworkType::TD_SCDMA_GSM;
+ case (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM):
+ return V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE;
+ case (RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA;
+ case (RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE;
+ case (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE;
+ case (RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO;
+ case (RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA;
+ case static_cast<int>(RAF::NR):
+ return V1_0::PreferredNetworkType(23); // NR_ONLY
+ case (RAF::NR | RAF::LTE):
+ return V1_0::PreferredNetworkType(24); // NR_LTE
+ case (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO):
+ return V1_0::PreferredNetworkType(25); // NR_LTE_CDMA_EVDO
+ case (RAF::NR | RAF::LTE | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType(26); // NR_LTE_GSM_WCDMA
+ case (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType(27); // NR_LTE_CDMA_EVDO_GSM_WCDMA
+ case (RAF::NR | RAF::LTE | RAF::WCDMA):
+ return V1_0::PreferredNetworkType(28); // NR_LTE_WCDMA
+ case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA):
+ return V1_0::PreferredNetworkType(29); // NR_LTE_TDSCDMA
+ case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM):
+ return V1_0::PreferredNetworkType(30); // NR_LTE_TDSCDMA_GSM
+ case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA):
+ return V1_0::PreferredNetworkType(31); // NR_LTE_TDSCDMA_WCDMA
+ case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA):
+ return V1_0::PreferredNetworkType(32); // NR_LTE_TDSCDMA_GSM_WCDMA
+ case (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM |
+ RAF::WCDMA):
+ return V1_0::PreferredNetworkType(33); // NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+ default:
+ return V1_0::PreferredNetworkType::WCDMA;
+ }
+}
+
+hidl_bitfield<V1_4::RadioAccessFamily> getRafFromNetworkType(V1_0::PreferredNetworkType type) {
+ switch (type) {
+ case V1_0::PreferredNetworkType::GSM_WCDMA_AUTO:
+ return RAF::GSM | RAF::WCDMA;
+ case V1_0::PreferredNetworkType::GSM_ONLY:
+ return RAF::GSM;
+ case V1_0::PreferredNetworkType::WCDMA:
+ return RAF::WCDMA;
+ case V1_0::PreferredNetworkType::CDMA_EVDO_AUTO:
+ return (RAF::CDMA | RAF::EVDO);
+ case V1_0::PreferredNetworkType::LTE_CDMA_EVDO:
+ return (RAF::LTE | RAF::CDMA | RAF::EVDO);
+ case V1_0::PreferredNetworkType::LTE_GSM_WCDMA:
+ return (RAF::LTE | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA:
+ return (RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::LTE_ONLY:
+ return RAF::LTE;
+ case V1_0::PreferredNetworkType::LTE_WCDMA:
+ return (RAF::LTE | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::CDMA_ONLY:
+ return RAF::CDMA;
+ case V1_0::PreferredNetworkType::EVDO_ONLY:
+ return RAF::EVDO;
+ case V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO:
+ return (RAF::GSM | RAF::WCDMA | RAF::CDMA | RAF::EVDO);
+ case V1_0::PreferredNetworkType::TD_SCDMA_ONLY:
+ return static_cast<int>(RAF::E::TD_SCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA:
+ return (RAF::E::TD_SCDMA | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_LTE:
+ return (RAF::LTE | RAF::E::TD_SCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_GSM:
+ return (RAF::E::TD_SCDMA | RAF::GSM);
+ case V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE:
+ return (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM);
+ case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA:
+ return (RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE:
+ return (RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE:
+ return (RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO:
+ return (RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA:
+ return (RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+ case V1_0::PreferredNetworkType(23): // NR_ONLY
+ return static_cast<int>(RAF::NR);
+ case V1_0::PreferredNetworkType(24): // NR_LTE
+ return (RAF::NR | RAF::LTE);
+ case V1_0::PreferredNetworkType(25): // NR_LTE_CDMA_EVDO
+ return (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO);
+ case V1_0::PreferredNetworkType(26): // NR_LTE_GSM_WCDMA
+ return (RAF::NR | RAF::LTE | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType(27): // NR_LTE_CDMA_EVDO_GSM_WCDMA
+ return (RAF::NR | RAF::LTE | RAF::CDMA | RAF::EVDO | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType(28): // NR_LTE_WCDMA
+ return (RAF::NR | RAF::LTE | RAF::WCDMA);
+ case V1_0::PreferredNetworkType(29): // NR_LTE_TDSCDMA
+ return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA);
+ case V1_0::PreferredNetworkType(30): // NR_LTE_TDSCDMA_GSM
+ return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM);
+ case V1_0::PreferredNetworkType(31): // NR_LTE_TDSCDMA_WCDMA
+ return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::WCDMA);
+ case V1_0::PreferredNetworkType(32): // NR_LTE_TDSCDMA_GSM_WCDMA
+ return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::GSM | RAF::WCDMA);
+ case V1_0::PreferredNetworkType(33): // NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+ return (RAF::NR | RAF::LTE | RAF::E::TD_SCDMA | RAF::CDMA | RAF::EVDO | RAF::GSM |
+ RAF::WCDMA);
+#pragma GCC diagnostic pop
+ default:
+ return {}; // unknown
+ }
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/utils.h b/radio/aidl/compat/libradiocompat/network/utils.h
new file mode 100644
index 0000000..10714be
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/network/utils.h
@@ -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.
+ */
+#pragma once
+
+#include <android/hardware/radio/1.4/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::PreferredNetworkType getNetworkTypeFromRaf(hidl_bitfield<V1_4::RadioAccessFamily> raf);
+hidl_bitfield<V1_4::RadioAccessFamily> getRafFromNetworkType(V1_0::PreferredNetworkType type);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
new file mode 100644
index 0000000..6b906c6
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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 <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SimIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioSimIndication> simCb) {
+ CHECK(simCb);
+ mSimCb = simCb;
+}
+
+Return<void> RadioIndication::carrierInfoForImsiEncryption(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->carrierInfoForImsiEncryption(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::cdmaSubscriptionSourceChanged(
+ V1_0::RadioIndicationType type, V1_0::CdmaSubscriptionSource cdmaSource) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
+ return {};
+}
+
+Return<void> RadioIndication::simPhonebookChanged(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->simPhonebookChanged(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::simPhonebookRecordsReceived(
+ V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
+ const hidl_vec<V1_6::PhonebookRecordInfo>& rec) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
+ return {};
+}
+
+Return<void> RadioIndication::simRefresh(V1_0::RadioIndicationType type,
+ const V1_0::SimRefreshResult& refreshResult) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->simRefresh(toAidl(type), toAidl(refreshResult));
+ return {};
+}
+
+Return<void> RadioIndication::simStatusChanged(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->simStatusChanged(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::stkEventNotify(V1_0::RadioIndicationType type,
+ const hidl_string& cmd) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->stkEventNotify(toAidl(type), cmd);
+ return {};
+}
+
+Return<void> RadioIndication::stkProactiveCommand(V1_0::RadioIndicationType type,
+ const hidl_string& cmd) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->stkProactiveCommand(toAidl(type), cmd);
+ return {};
+}
+
+Return<void> RadioIndication::stkSessionEnd(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->stkSessionEnd(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::subscriptionStatusChanged(V1_0::RadioIndicationType type,
+ bool activate) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->subscriptionStatusChanged(toAidl(type), activate);
+ return {};
+}
+
+Return<void> RadioIndication::uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
+ bool enabled) {
+ LOG_CALL << type;
+ CHECK_CB(mSimCb);
+ mSimCb->uiccApplicationsEnablementChanged(toAidl(type), enabled);
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
new file mode 100644
index 0000000..2dfbc50
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
@@ -0,0 +1,366 @@
+/*
+ * 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 <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "SimResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioSimResponse> simCb) {
+ CHECK(simCb);
+ mSimCb = simCb;
+}
+
+Return<void> RadioResponse::areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
+ bool enabled) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
+ return {};
+}
+
+Return<void> RadioResponse::changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->changeIccPinForAppResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->enableUiccApplicationsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse( //
+ const V1_0::RadioResponseInfo& info, bool allAllowed, const V1_0::CarrierRestrictions& cr) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ aidl::CarrierRestrictions aidlCr = toAidl(cr);
+ if (allAllowed) aidlCr = {};
+ mSimCb->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
+ return {};
+}
+
+Return<void> RadioResponse::getAllowedCarriersResponse_1_4(
+ const V1_0::RadioResponseInfo& info, const V1_4::CarrierRestrictionsWithPriority& carriers,
+ V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
+ aidl::SimLockMultiSimPolicy(multiSimPolicy));
+ return {};
+}
+
+Return<void> RadioResponse::getCDMASubscriptionResponse(
+ const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
+ const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
+ return {};
+}
+
+Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::CdmaSubscriptionSource s) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
+ return {};
+}
+
+Return<void> RadioResponse::getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t response) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getFacilityLockForAppResponse(toAidl(info), response);
+ return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::CardStatus& cardStatus) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+ return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const V1_2::CardStatus& cardStatus) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+ return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
+ const V1_4::CardStatus& cardStatus) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+ return {};
+}
+
+Return<void> RadioResponse::getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
+ const V1_5::CardStatus& cardStatus) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+ return {};
+}
+
+Return<void> RadioResponse::getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& imsi) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getImsiForAppResponse(toAidl(info), imsi);
+ return {};
+}
+
+Return<void> RadioResponse::getSimPhonebookCapacityResponse(
+ const V1_6::RadioResponseInfo& info, const V1_6::PhonebookCapacity& capacity) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
+ return {};
+}
+
+Return<void> RadioResponse::getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->getSimPhonebookRecordsResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->iccCloseLogicalChannelResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& iccIo) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
+ return {};
+}
+
+Return<void> RadioResponse::iccOpenLogicalChannelResponse( //
+ const V1_0::RadioResponseInfo& info, int32_t chanId, const hidl_vec<int8_t>& selectResp) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
+ return {};
+}
+
+Return<void> RadioResponse::iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& result) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
+ return {};
+}
+
+Return<void> RadioResponse::iccTransmitApduLogicalChannelResponse(
+ const V1_0::RadioResponseInfo& info, const V1_0::IccIoResult& result) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
+ return {};
+}
+
+Return<void> RadioResponse::reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->reportStkServiceIsRunningResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& result) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
+ return {};
+}
+
+Return<void> RadioResponse::requestIsimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string&) {
+ LOG_CALL << info.serial;
+ LOG(ERROR) << "requestIsimAuthenticationResponse is not supposed to be called";
+ return {};
+}
+
+Return<void> RadioResponse::sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_string& commandResponse) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->sendEnvelopeResponse(toAidl(info), commandResponse);
+ return {};
+}
+
+Return<void> RadioResponse::sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
+ const V1_0::IccIoResult& iccIo) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
+ return {};
+}
+
+Return<void> RadioResponse::sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->sendTerminalResponseToSimResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
+ int32_t numAllowed) {
+ LOG_CALL << info.serial << ' ' << numAllowed;
+ CHECK_CB(mSimCb);
+ mSimCb->setAllowedCarriersResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setAllowedCarriersResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCarrierInfoForImsiEncryptionResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setCdmaSubscriptionSourceResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t retry) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setFacilityLockForAppResponse(toAidl(info), retry);
+ return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setSimCardPowerResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setSimCardPowerResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setSimCardPowerResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->setUiccSubscriptionResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
+ int32_t remainingRetries) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
+ return {};
+}
+
+Return<void> RadioResponse::supplySimDepersonalizationResponse(const V1_0::RadioResponseInfo& info,
+ V1_5::PersoSubstate persoType,
+ int32_t rRet) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
+ return {};
+}
+
+Return<void> RadioResponse::updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
+ int32_t updatedRecordIndex) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mSimCb);
+ mSimCb->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
new file mode 100644
index 0000000..ca27918
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -0,0 +1,295 @@
+/*
+ * 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 <libradiocompat/RadioSim.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Sim"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::sim;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioSim::areUiccApplicationsEnabled(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->areUiccApplicationsEnabled(serial);
+ return ok();
+}
+
+ScopedAStatus RadioSim::changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
+ const std::string& newPin2, const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->changeIccPin2ForApp(serial, oldPin2, newPin2, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::changeIccPinForApp(int32_t serial, const std::string& oldPin,
+ const std::string& newPin, const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->changeIccPinForApp(serial, oldPin, newPin, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::enableUiccApplications(int32_t serial, bool enable) {
+ LOG_CALL << serial;
+ mHal1_5->enableUiccApplications(serial, enable);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getAllowedCarriers(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getAllowedCarriers(serial);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getCdmaSubscription(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getCDMASubscription(serial);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getCdmaSubscriptionSource(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getCdmaSubscriptionSource(serial);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getFacilityLockForApp( //
+ int32_t serial, const std::string& facility, const std::string& password,
+ int32_t serviceClass, const std::string& appId) {
+ LOG_CALL << serial;
+ mHal1_5->getFacilityLockForApp(serial, facility, password, serviceClass, appId);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getIccCardStatus(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getIccCardStatus(serial);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getImsiForApp(int32_t serial, const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->getImsiForApp(serial, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::getSimPhonebookCapacity(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->getSimPhonebookCapacity(serial);
+ } else {
+ respond().getSimPhonebookCapacityResponse(notSupported(serial), {});
+ }
+ return ok();
+}
+
+ScopedAStatus RadioSim::getSimPhonebookRecords(int32_t serial) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->getSimPhonebookRecords(serial);
+ } else {
+ respond().getSimPhonebookRecordsResponse(notSupported(serial));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioSim::iccCloseLogicalChannel(int32_t serial, int32_t channelId) {
+ LOG_CALL << serial;
+ mHal1_5->iccCloseLogicalChannel(serial, channelId);
+ return ok();
+}
+
+ScopedAStatus RadioSim::iccIoForApp(int32_t serial, const aidl::IccIo& iccIo) {
+ LOG_CALL << serial;
+ mHal1_5->iccIOForApp(serial, toHidl(iccIo));
+ return ok();
+}
+
+ScopedAStatus RadioSim::iccOpenLogicalChannel(int32_t serial, const std::string& aid, int32_t p2) {
+ LOG_CALL << serial;
+ mHal1_5->iccOpenLogicalChannel(serial, aid, p2);
+ return ok();
+}
+
+ScopedAStatus RadioSim::iccTransmitApduBasicChannel(int32_t serial, const aidl::SimApdu& message) {
+ LOG_CALL << serial;
+ mHal1_5->iccTransmitApduBasicChannel(serial, toHidl(message));
+ return ok();
+}
+
+ScopedAStatus RadioSim::iccTransmitApduLogicalChannel(int32_t serial,
+ const aidl::SimApdu& message) {
+ LOG_CALL << serial;
+ mHal1_5->iccTransmitApduLogicalChannel(serial, toHidl(message));
+ return ok();
+}
+
+ScopedAStatus RadioSim::reportStkServiceIsRunning(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->reportStkServiceIsRunning(serial);
+ return ok();
+}
+
+ScopedAStatus RadioSim::requestIccSimAuthentication( //
+ int32_t serial, int32_t authContext, const std::string& authData, const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->requestIccSimAuthentication(serial, authContext, authData, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::responseAcknowledgement() {
+ LOG_CALL;
+ mHal1_5->responseAcknowledgement();
+ return ok();
+}
+
+ScopedAStatus RadioSim::sendEnvelope(int32_t serial, const std::string& command) {
+ LOG_CALL << serial;
+ mHal1_5->sendEnvelope(serial, command);
+ return ok();
+}
+
+ScopedAStatus RadioSim::sendEnvelopeWithStatus(int32_t serial, const std::string& contents) {
+ LOG_CALL << serial;
+ mHal1_5->sendEnvelopeWithStatus(serial, contents);
+ return ok();
+}
+
+ScopedAStatus RadioSim::sendTerminalResponseToSim(int32_t serial,
+ const std::string& commandResponse) {
+ LOG_CALL << serial;
+ mHal1_5->sendTerminalResponseToSim(serial, commandResponse);
+ return ok();
+}
+
+ScopedAStatus RadioSim::setAllowedCarriers( //
+ int32_t serial, const aidl::CarrierRestrictions& carriers, aidl::SimLockMultiSimPolicy mp) {
+ LOG_CALL << serial;
+ mHal1_5->setAllowedCarriers_1_4(serial, toHidl(carriers), V1_4::SimLockMultiSimPolicy(mp));
+ return ok();
+}
+
+ScopedAStatus RadioSim::setCarrierInfoForImsiEncryption(
+ int32_t serial, const aidl::ImsiEncryptionInfo& imsiEncryptionInfo) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->setCarrierInfoForImsiEncryption_1_6(serial, toHidl_1_6(imsiEncryptionInfo));
+ } else {
+ mHal1_5->setCarrierInfoForImsiEncryption(serial, toHidl(imsiEncryptionInfo));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioSim::setCdmaSubscriptionSource(int32_t serial,
+ aidl::CdmaSubscriptionSource cdmaSub) {
+ LOG_CALL << serial;
+ mHal1_5->setCdmaSubscriptionSource(serial, V1_0::CdmaSubscriptionSource(cdmaSub));
+ return ok();
+}
+
+ScopedAStatus RadioSim::setFacilityLockForApp( //
+ int32_t serial, const std::string& facility, bool lockState, const std::string& password,
+ int32_t serviceClass, const std::string& appId) {
+ LOG_CALL << serial;
+ mHal1_5->setFacilityLockForApp(serial, facility, lockState, password, serviceClass, appId);
+ return ok();
+}
+
+ScopedAStatus RadioSim::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioSimResponse>& simResponse,
+ const std::shared_ptr<aidl::IRadioSimIndication>& simIndication) {
+ LOG_CALL << simResponse << ' ' << simIndication;
+
+ CHECK(simResponse);
+ CHECK(simIndication);
+
+ mRadioResponse->setResponseFunction(simResponse);
+ mRadioIndication->setResponseFunction(simIndication);
+
+ return ok();
+}
+
+ScopedAStatus RadioSim::setSimCardPower(int32_t serial, aidl::CardPowerState powerUp) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->setSimCardPower_1_6(serial, V1_1::CardPowerState(powerUp));
+ } else {
+ mHal1_5->setSimCardPower_1_1(serial, V1_1::CardPowerState(powerUp));
+ }
+ return ok();
+}
+
+ScopedAStatus RadioSim::setUiccSubscription(int32_t serial, const aidl::SelectUiccSub& uiccSub) {
+ LOG_CALL << serial;
+ mHal1_5->setUiccSubscription(serial, toHidl(uiccSub));
+ return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
+ const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->supplyIccPin2ForApp(serial, pin2, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPinForApp(int32_t serial, const std::string& pin,
+ const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->supplyIccPinForApp(serial, pin, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
+ const std::string& pin2, const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->supplyIccPuk2ForApp(serial, puk2, pin2, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::supplyIccPukForApp(int32_t serial, const std::string& puk,
+ const std::string& pin, const std::string& aid) {
+ LOG_CALL << serial;
+ mHal1_5->supplyIccPukForApp(serial, puk, pin, aid);
+ return ok();
+}
+
+ScopedAStatus RadioSim::supplySimDepersonalization(int32_t serial, aidl::PersoSubstate pss,
+ const std::string& controlKey) {
+ LOG_CALL << serial;
+ mHal1_5->supplySimDepersonalization(serial, V1_5::PersoSubstate(pss), controlKey);
+ return ok();
+}
+
+ScopedAStatus RadioSim::updateSimPhonebookRecords(int32_t serial,
+ const aidl::PhonebookRecordInfo& recordInfo) {
+ LOG_CALL << serial;
+ if (mHal1_6) {
+ mHal1_6->updateSimPhonebookRecords(serial, toHidl(recordInfo));
+ } else {
+ respond().updateSimPhonebookRecordsResponse(notSupported(serial), 0);
+ }
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
new file mode 100644
index 0000000..97a21a1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -0,0 +1,221 @@
+/*
+ * 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 "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::sim;
+
+V1_0::IccIo toHidl(const aidl::IccIo& icc) {
+ return {
+ .command = icc.command,
+ .fileId = icc.fileId,
+ .path = icc.path,
+ .p1 = icc.p1,
+ .p2 = icc.p2,
+ .p3 = icc.p3,
+ .data = icc.data,
+ .pin2 = icc.pin2,
+ .aid = icc.aid,
+ };
+}
+
+V1_0::SimApdu toHidl(const aidl::SimApdu& apdu) {
+ return {
+ .sessionId = apdu.sessionId,
+ .cla = apdu.cla,
+ .instruction = apdu.instruction,
+ .p1 = apdu.p1,
+ .p2 = apdu.p2,
+ .p3 = apdu.p3,
+ .data = apdu.data,
+ };
+}
+
+aidl::Carrier toAidl(const V1_0::Carrier& carrier) {
+ return {
+ .mcc = carrier.mcc,
+ .mnc = carrier.mnc,
+ .matchType = static_cast<int32_t>(carrier.matchType),
+ .matchData = carrier.matchData,
+ };
+}
+
+V1_0::Carrier toHidl(const aidl::Carrier& carrier) {
+ return {
+ .mcc = carrier.mcc,
+ .mnc = carrier.mnc,
+ .matchType = V1_0::CarrierMatchType{carrier.matchType},
+ .matchData = carrier.matchData,
+ };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_0::CarrierRestrictions& cr) {
+ return {
+ .allowedCarriers = toAidl(cr.allowedCarriers),
+ .excludedCarriers = toAidl(cr.excludedCarriers),
+ .allowedCarriersPrioritized = true,
+ };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_4::CarrierRestrictionsWithPriority& cr) {
+ return {
+ .allowedCarriers = toAidl(cr.allowedCarriers),
+ .excludedCarriers = toAidl(cr.excludedCarriers),
+ .allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+ };
+}
+
+V1_4::CarrierRestrictionsWithPriority toHidl(const aidl::CarrierRestrictions& cr) {
+ return {
+ .allowedCarriers = toHidl(cr.allowedCarriers),
+ .excludedCarriers = toHidl(cr.excludedCarriers),
+ .allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+ };
+}
+
+V1_1::ImsiEncryptionInfo toHidl(const aidl::ImsiEncryptionInfo& info) {
+ return {
+ .mcc = info.mcc,
+ .mnc = info.mnc,
+ .carrierKey = info.carrierKey,
+ .keyIdentifier = info.keyIdentifier,
+ .expirationTime = info.expirationTime,
+ };
+}
+
+V1_6::ImsiEncryptionInfo toHidl_1_6(const aidl::ImsiEncryptionInfo& info) {
+ return {
+ .base = toHidl(info),
+ .keyType = V1_6::PublicKeyType{info.keyType},
+ };
+}
+
+V1_0::SelectUiccSub toHidl(const aidl::SelectUiccSub& sub) {
+ return {
+ .slot = sub.slot,
+ .appIndex = sub.appIndex,
+ .subType = {},
+ .actStatus = {},
+ };
+}
+
+aidl::PhonebookRecordInfo toAidl(const V1_6::PhonebookRecordInfo& info) {
+ return {
+ .recordId = static_cast<int32_t>(info.recordId),
+ .name = info.name,
+ .number = info.number,
+ .emails = toAidl(info.emails),
+ .additionalNumbers = toAidl(info.additionalNumbers),
+ };
+}
+
+V1_6::PhonebookRecordInfo toHidl(const aidl::PhonebookRecordInfo& info) {
+ return {
+ .recordId = static_cast<uint32_t>(info.recordId),
+ .name = info.name,
+ .number = info.number,
+ .emails = toHidl(info.emails),
+ .additionalNumbers = toHidl(info.additionalNumbers),
+ };
+}
+
+aidl::SimRefreshResult toAidl(const V1_0::SimRefreshResult& res) {
+ return {
+ .type = static_cast<int32_t>(res.type),
+ .efId = res.efId,
+ .aid = res.aid,
+ };
+}
+
+aidl::CardStatus toAidl(const V1_0::CardStatus& status) {
+ return toAidl(V1_2::CardStatus{status, 0, "", ""});
+}
+
+aidl::CardStatus toAidl(const V1_2::CardStatus& status) {
+ return toAidl(V1_4::CardStatus{status, ""});
+}
+
+aidl::CardStatus toAidl(const V1_4::CardStatus& status) {
+ auto aidlStatus = toAidl(V1_5::CardStatus{status, {}});
+ aidlStatus.applications = toAidl(status.base.base.applications);
+ return aidlStatus;
+}
+
+aidl::CardStatus toAidl(const V1_5::CardStatus& status) {
+ return {
+ .cardState = static_cast<int32_t>(status.base.base.base.cardState),
+ .universalPinState = aidl::PinState(status.base.base.base.universalPinState),
+ .gsmUmtsSubscriptionAppIndex = status.base.base.base.gsmUmtsSubscriptionAppIndex,
+ .cdmaSubscriptionAppIndex = status.base.base.base.cdmaSubscriptionAppIndex,
+ .imsSubscriptionAppIndex = status.base.base.base.imsSubscriptionAppIndex,
+ .applications = toAidl(status.applications),
+ .atr = status.base.base.atr,
+ .iccid = status.base.base.iccid,
+ .eid = status.base.eid,
+ // TODO(b/203699028): we don't know portId here (but we can get it from RadioConfig)
+ .slotMap = {static_cast<int32_t>(status.base.base.physicalSlotId), 0},
+ };
+}
+
+aidl::AppStatus toAidl(const V1_0::AppStatus& status) {
+ return toAidl({status, V1_5::PersoSubstate(status.persoSubstate)});
+}
+
+aidl::AppStatus toAidl(const V1_5::AppStatus& status) {
+ return {
+ .appType = static_cast<int32_t>(status.base.appType),
+ .appState = static_cast<int32_t>(status.base.appState),
+ .persoSubstate = aidl::PersoSubstate(status.persoSubstate),
+ .aidPtr = status.base.aidPtr,
+ .appLabelPtr = status.base.appLabelPtr,
+ .pin1Replaced = (status.base.pin1Replaced != 0),
+ .pin1 = aidl::PinState(status.base.pin1),
+ .pin2 = aidl::PinState(status.base.pin2),
+ };
+}
+
+aidl::PhonebookCapacity toAidl(const V1_6::PhonebookCapacity& c) {
+ return {
+ .maxAdnRecords = c.maxAdnRecords,
+ .usedAdnRecords = c.usedAdnRecords,
+ .maxEmailRecords = c.maxEmailRecords,
+ .usedEmailRecords = c.usedEmailRecords,
+ .maxAdditionalNumberRecords = c.maxAdditionalNumberRecords,
+ .usedAdditionalNumberRecords = c.usedAdditionalNumberRecords,
+ .maxNameLen = c.maxNameLen,
+ .maxNumberLen = c.maxNumberLen,
+ .maxEmailLen = c.maxEmailLen,
+ .maxAdditionalNumberLen = c.maxAdditionalNumberLen,
+ };
+}
+
+aidl::IccIoResult toAidl(const V1_0::IccIoResult& iir) {
+ return {
+ .sw1 = iir.sw1,
+ .sw2 = iir.sw2,
+ .simResponse = iir.simResponse,
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.h b/radio/aidl/compat/libradiocompat/sim/structs.h
new file mode 100644
index 0000000..54099b7
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/sim/structs.h
@@ -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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/sim/AppStatus.h>
+#include <aidl/android/hardware/radio/sim/CardStatus.h>
+#include <aidl/android/hardware/radio/sim/Carrier.h>
+#include <aidl/android/hardware/radio/sim/CarrierRestrictions.h>
+#include <aidl/android/hardware/radio/sim/IccIo.h>
+#include <aidl/android/hardware/radio/sim/IccIoResult.h>
+#include <aidl/android/hardware/radio/sim/ImsiEncryptionInfo.h>
+#include <aidl/android/hardware/radio/sim/PhonebookCapacity.h>
+#include <aidl/android/hardware/radio/sim/PhonebookRecordInfo.h>
+#include <aidl/android/hardware/radio/sim/SelectUiccSub.h>
+#include <aidl/android/hardware/radio/sim/SimApdu.h>
+#include <aidl/android/hardware/radio/sim/SimRefreshResult.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::IccIo toHidl(const ::aidl::android::hardware::radio::sim::IccIo& icc);
+
+V1_0::SimApdu toHidl(const ::aidl::android::hardware::radio::sim::SimApdu& apdu);
+
+::aidl::android::hardware::radio::sim::Carrier toAidl(const V1_0::Carrier& carrier);
+V1_0::Carrier toHidl(const ::aidl::android::hardware::radio::sim::Carrier& carrier);
+
+::aidl::android::hardware::radio::sim::CarrierRestrictions //
+toAidl(const V1_0::CarrierRestrictions& cr);
+::aidl::android::hardware::radio::sim::CarrierRestrictions //
+toAidl(const V1_4::CarrierRestrictionsWithPriority& cr);
+V1_4::CarrierRestrictionsWithPriority //
+toHidl(const ::aidl::android::hardware::radio::sim::CarrierRestrictions& cr);
+
+V1_1::ImsiEncryptionInfo //
+toHidl(const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& info);
+V1_6::ImsiEncryptionInfo //
+toHidl_1_6(const ::aidl::android::hardware::radio::sim::ImsiEncryptionInfo& info);
+
+V1_0::SelectUiccSub toHidl(const ::aidl::android::hardware::radio::sim::SelectUiccSub& sub);
+
+::aidl::android::hardware::radio::sim::PhonebookRecordInfo //
+toAidl(const V1_6::PhonebookRecordInfo& info);
+V1_6::PhonebookRecordInfo //
+toHidl(const ::aidl::android::hardware::radio::sim::PhonebookRecordInfo& info);
+
+::aidl::android::hardware::radio::sim::SimRefreshResult //
+toAidl(const V1_0::SimRefreshResult& res);
+
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_0::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_2::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_4::CardStatus& status);
+::aidl::android::hardware::radio::sim::CardStatus toAidl(const V1_5::CardStatus& status);
+
+::aidl::android::hardware::radio::sim::AppStatus toAidl(const V1_0::AppStatus& status);
+::aidl::android::hardware::radio::sim::AppStatus toAidl(const V1_5::AppStatus& status);
+
+::aidl::android::hardware::radio::sim::PhonebookCapacity toAidl(const V1_6::PhonebookCapacity& c);
+
+::aidl::android::hardware::radio::sim::IccIoResult toAidl(const V1_0::IccIoResult& iir);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
new file mode 100644
index 0000000..6d9bda8
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 <libradiocompat/RadioIndication.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "VoiceIndication"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceIndication> voiceCb) {
+ CHECK(voiceCb);
+ mVoiceCb = voiceCb;
+}
+
+Return<void> RadioIndication::callRing(V1_0::RadioIndicationType type, bool isGsm,
+ const V1_0::CdmaSignalInfoRecord& record) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->callRing(toAidl(type), isGsm, toAidl(record));
+ return {};
+}
+
+Return<void> RadioIndication::callStateChanged(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->callStateChanged(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::cdmaCallWaiting(V1_0::RadioIndicationType type,
+ const V1_0::CdmaCallWaiting& callWaitingRecord) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
+ return {};
+}
+
+Return<void> RadioIndication::cdmaInfoRec(V1_0::RadioIndicationType type,
+ const V1_0::CdmaInformationRecords& records) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
+ return {};
+}
+
+Return<void> RadioIndication::cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
+ V1_0::CdmaOtaProvisionStatus status) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
+ return {};
+}
+
+Return<void> RadioIndication::currentEmergencyNumberList(
+ V1_0::RadioIndicationType type, const hidl_vec<V1_4::EmergencyNumber>& emergencyNumbers) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
+ return {};
+}
+
+Return<void> RadioIndication::enterEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->enterEmergencyCallbackMode(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::exitEmergencyCallbackMode(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->exitEmergencyCallbackMode(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::indicateRingbackTone(V1_0::RadioIndicationType type, bool start) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->indicateRingbackTone(toAidl(type), start);
+ return {};
+}
+
+Return<void> RadioIndication::onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
+ const V1_0::StkCcUnsolSsResult& ss) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
+ return {};
+}
+
+Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->resendIncallMute(toAidl(type));
+ return {};
+}
+
+Return<void> RadioIndication::srvccStateNotify(V1_0::RadioIndicationType type,
+ V1_0::SrvccState state) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
+ return {};
+}
+
+Return<void> RadioIndication::stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
+ const hidl_string& alpha) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->stkCallControlAlphaNotify(toAidl(type), alpha);
+ return {};
+}
+
+Return<void> RadioIndication::stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) {
+ LOG_CALL << type;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->stkCallSetup(toAidl(type), timeout);
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
new file mode 100644
index 0000000..0a64c56
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -0,0 +1,294 @@
+/*
+ * 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 <libradiocompat/RadioResponse.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "VoiceResponse"
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceResponse> voiceCb) {
+ CHECK(voiceCb);
+ mVoiceCb = voiceCb;
+}
+
+Return<void> RadioResponse::acceptCallResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->acceptCallResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->conferenceResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::dialResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->dialResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::emergencyDialResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->emergencyDialResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->exitEmergencyCallbackModeResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->explicitCallTransferResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::getCallForwardStatusResponse(
+ const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::CallForwardInfo>& callFwdInfos) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
+ return {};
+}
+
+Return<void> RadioResponse::getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
+ int32_t serviceClass) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getCallWaitingResponse(toAidl(info), enable, serviceClass);
+ return {};
+}
+
+Return<void> RadioResponse::getClipResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::ClipStatus status) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getClipResponse(toAidl(info), aidl::ClipStatus(status));
+ return {};
+}
+
+Return<void> RadioResponse::getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
+ int32_t m) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getClirResponse(toAidl(info), n, m);
+ return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_0::Call>& calls) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+ return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
+ const hidl_vec<V1_2::Call>& calls) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+ return {};
+}
+
+Return<void> RadioResponse::getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
+ const hidl_vec<V1_6::Call>& calls) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+ return {};
+}
+
+Return<void> RadioResponse::getLastCallFailCauseResponse(
+ const V1_0::RadioResponseInfo& info, const V1_0::LastCallFailCauseInfo& failCauseinfo) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
+ return {};
+}
+
+Return<void> RadioResponse::getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getMuteResponse(toAidl(info), enable);
+ return {};
+}
+
+Return<void> RadioResponse::getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
+ bool enable) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getPreferredVoicePrivacyResponse(toAidl(info), enable);
+ return {};
+}
+
+Return<void> RadioResponse::getTTYModeResponse(const V1_0::RadioResponseInfo& info,
+ V1_0::TtyMode mode) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
+ return {};
+}
+
+Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->handleStkCallSetupRequestFromSimResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::hangupConnectionResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->hangupConnectionResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::hangupForegroundResumeBackgroundResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->hangupForegroundResumeBackgroundResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->hangupWaitingOrBackgroundResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::rejectCallResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->rejectCallResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->sendBurstDtmfResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->sendCdmaFeatureCodeResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::sendDtmfResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->sendDtmfResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->separateConnectionResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCallForwardResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->setCallForwardResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setCallWaitingResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->setCallWaitingResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setClirResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->setClirResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setMuteResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->setMuteResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->setPreferredVoicePrivacyResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::setTTYModeResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->setTtyModeResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::startDtmfResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->startDtmfResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::stopDtmfResponse(const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->stopDtmfResponse(toAidl(info));
+ return {};
+}
+
+Return<void> RadioResponse::switchWaitingOrHoldingAndActiveResponse(
+ const V1_0::RadioResponseInfo& info) {
+ LOG_CALL << info.serial;
+ CHECK_CB(mVoiceCb);
+ mVoiceCb->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
+ return {};
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
new file mode 100644
index 0000000..16c6b14
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -0,0 +1,270 @@
+/*
+ * 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 <libradiocompat/RadioVoice.h>
+
+#include "commonStructs.h"
+#include "debug.h"
+#include "structs.h"
+
+#include "collections.h"
+
+#define RADIO_MODULE "Voice"
+
+namespace android::hardware::radio::compat {
+
+using ::ndk::ScopedAStatus;
+namespace aidl = ::aidl::android::hardware::radio::voice;
+constexpr auto ok = &ScopedAStatus::ok;
+
+ScopedAStatus RadioVoice::acceptCall(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->acceptCall(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::conference(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->conference(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::dial(int32_t serial, const aidl::Dial& dialInfo) {
+ LOG_CALL << serial;
+ mHal1_5->dial(serial, toHidl(dialInfo));
+ return ok();
+}
+
+ScopedAStatus RadioVoice::emergencyDial( //
+ int32_t serial, const aidl::Dial& dialInfo, aidl::EmergencyServiceCategory categories,
+ const std::vector<std::string>& urns, aidl::EmergencyCallRouting routing,
+ bool hasKnownUserIntentEmerg, bool isTesting) {
+ LOG_CALL << serial;
+ mHal1_5->emergencyDial(serial, toHidl(dialInfo),
+ toHidlBitfield<V1_4::EmergencyServiceCategory>(categories), toHidl(urns),
+ V1_4::EmergencyCallRouting(routing), hasKnownUserIntentEmerg, isTesting);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::exitEmergencyCallbackMode(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->exitEmergencyCallbackMode(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::explicitCallTransfer(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->explicitCallTransfer(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getCallForwardStatus(int32_t serial,
+ const aidl::CallForwardInfo& callInfo) {
+ LOG_CALL << serial;
+ mHal1_5->getCallForwardStatus(serial, toHidl(callInfo));
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getCallWaiting(int32_t serial, int32_t serviceClass) {
+ LOG_CALL << serial;
+ mHal1_5->getCallWaiting(serial, serviceClass);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getClip(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getClip(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getClir(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getClir(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getCurrentCalls(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getCurrentCalls(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getLastCallFailCause(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getLastCallFailCause(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getMute(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getMute(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getPreferredVoicePrivacy(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getPreferredVoicePrivacy(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::getTtyMode(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->getTTYMode(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) {
+ LOG_CALL << serial;
+ mHal1_5->handleStkCallSetupRequestFromSim(serial, accept);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::hangup(int32_t serial, int32_t gsmIndex) {
+ LOG_CALL << serial;
+ mHal1_5->hangup(serial, gsmIndex);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::hangupForegroundResumeBackground(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->hangupForegroundResumeBackground(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::hangupWaitingOrBackground(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->hangupWaitingOrBackground(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::isVoNrEnabled(int32_t serial) {
+ LOG_CALL << serial;
+ // TODO(b/203699028): can't call isVoNrEnabledResponse with 1.6 callback
+ return ok();
+}
+
+ScopedAStatus RadioVoice::rejectCall(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->rejectCall(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::responseAcknowledgement() {
+ LOG_CALL;
+ mHal1_5->responseAcknowledgement();
+ return ok();
+}
+
+ScopedAStatus RadioVoice::sendBurstDtmf(int32_t serial, const std::string& dtmf, int32_t on,
+ int32_t off) {
+ LOG_CALL << serial;
+ mHal1_5->sendBurstDtmf(serial, dtmf, on, off);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::sendCdmaFeatureCode(int32_t serial, const std::string& featureCode) {
+ LOG_CALL << serial;
+ mHal1_5->sendCDMAFeatureCode(serial, featureCode);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::sendDtmf(int32_t serial, const std::string& s) {
+ LOG_CALL << serial;
+ mHal1_5->sendDtmf(serial, s);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::separateConnection(int32_t serial, int32_t gsmIndex) {
+ LOG_CALL << serial;
+ mHal1_5->separateConnection(serial, gsmIndex);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setCallForward(int32_t serial, const aidl::CallForwardInfo& callInfo) {
+ LOG_CALL << serial;
+ mHal1_5->setCallForward(serial, toHidl(callInfo));
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) {
+ LOG_CALL << serial;
+ mHal1_5->setCallWaiting(serial, enable, serviceClass);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setClir(int32_t serial, int32_t status) {
+ LOG_CALL << serial;
+ mHal1_5->setClir(serial, status);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setMute(int32_t serial, bool enable) {
+ LOG_CALL << serial;
+ mHal1_5->setMute(serial, enable);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setPreferredVoicePrivacy(int32_t serial, bool enable) {
+ LOG_CALL << serial;
+ mHal1_5->setPreferredVoicePrivacy(serial, enable);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setResponseFunctions(
+ const std::shared_ptr<aidl::IRadioVoiceResponse>& voiceResponse,
+ const std::shared_ptr<aidl::IRadioVoiceIndication>& voiceIndication) {
+ LOG_CALL << voiceResponse << ' ' << voiceIndication;
+
+ CHECK(voiceResponse);
+ CHECK(voiceIndication);
+
+ mRadioResponse->setResponseFunction(voiceResponse);
+ mRadioIndication->setResponseFunction(voiceIndication);
+
+ return ok();
+}
+
+ScopedAStatus RadioVoice::setTtyMode(int32_t serial, aidl::TtyMode mode) {
+ LOG_CALL << serial;
+ mHal1_5->setTTYMode(serial, V1_0::TtyMode(mode));
+ return ok();
+}
+
+ndk::ScopedAStatus RadioVoice::setVoNrEnabled(int32_t serial, [[maybe_unused]] bool enable) {
+ LOG_CALL << serial;
+ // TODO(b/203699028): should set `persist.radio.is_vonr_enabled_` property instead
+ return ok();
+}
+
+ScopedAStatus RadioVoice::startDtmf(int32_t serial, const std::string& s) {
+ LOG_CALL << serial;
+ mHal1_5->startDtmf(serial, s);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::stopDtmf(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->stopDtmf(serial);
+ return ok();
+}
+
+ScopedAStatus RadioVoice::switchWaitingOrHoldingAndActive(int32_t serial) {
+ LOG_CALL << serial;
+ mHal1_5->switchWaitingOrHoldingAndActive(serial);
+ return ok();
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.cpp b/radio/aidl/compat/libradiocompat/voice/structs.cpp
new file mode 100644
index 0000000..ae6342e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/structs.cpp
@@ -0,0 +1,223 @@
+/*
+ * 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 "structs.h"
+
+#include "commonStructs.h"
+
+#include "collections.h"
+
+#include <android-base/logging.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio::voice;
+
+V1_0::Dial toHidl(const aidl::Dial& info) {
+ return {
+ .address = info.address,
+ .clir = V1_0::Clir{info.clir},
+ .uusInfo = toHidl(info.uusInfo),
+ };
+}
+
+V1_0::UusInfo toHidl(const aidl::UusInfo& info) {
+ return {
+ .uusType = V1_0::UusType{info.uusType},
+ .uusDcs = V1_0::UusDcs{info.uusDcs},
+ .uusData = info.uusData,
+ };
+}
+
+aidl::CallForwardInfo toAidl(const V1_0::CallForwardInfo& info) {
+ return {
+ .status = static_cast<int32_t>(info.status),
+ .reason = info.reason,
+ .serviceClass = info.serviceClass,
+ .toa = info.toa,
+ .number = info.number,
+ .timeSeconds = info.timeSeconds,
+ };
+}
+
+V1_0::CallForwardInfo toHidl(const aidl::CallForwardInfo& info) {
+ return {
+ .status = V1_0::CallForwardInfoStatus{info.status},
+ .reason = info.reason,
+ .serviceClass = info.serviceClass,
+ .toa = info.toa,
+ .number = info.number,
+ .timeSeconds = info.timeSeconds,
+ };
+}
+
+aidl::CdmaSignalInfoRecord toAidl(const V1_0::CdmaSignalInfoRecord& record) {
+ return {
+ .isPresent = record.isPresent,
+ .signalType = record.signalType,
+ .alertPitch = record.alertPitch,
+ .signal = record.signal,
+ };
+}
+
+aidl::CdmaCallWaiting toAidl(const V1_0::CdmaCallWaiting& call) {
+ return {
+ .number = call.number,
+ .numberPresentation = static_cast<int32_t>(call.numberPresentation),
+ .name = call.name,
+ .signalInfoRecord = toAidl(call.signalInfoRecord),
+ .numberType = static_cast<int32_t>(call.numberType),
+ .numberPlan = static_cast<int32_t>(call.numberPlan),
+ };
+}
+
+aidl::CdmaInformationRecord toAidl(const V1_0::CdmaInformationRecord& record) {
+ return {
+ .name = static_cast<int32_t>(record.name),
+ .display = toAidl(record.display),
+ .number = toAidl(record.number),
+ .signal = toAidl(record.signal),
+ .redir = toAidl(record.redir),
+ .lineCtrl = toAidl(record.lineCtrl),
+ .clir = toAidl(record.clir),
+ .audioCtrl = toAidl(record.audioCtrl),
+ };
+}
+
+aidl::CdmaDisplayInfoRecord toAidl(const V1_0::CdmaDisplayInfoRecord& record) {
+ return {
+ .alphaBuf = record.alphaBuf,
+ };
+}
+
+aidl::CdmaNumberInfoRecord toAidl(const V1_0::CdmaNumberInfoRecord& record) {
+ return {
+ .number = record.number,
+ .numberType = static_cast<int8_t>(record.numberType),
+ .numberPlan = static_cast<int8_t>(record.numberPlan),
+ .pi = static_cast<int8_t>(record.pi),
+ .si = static_cast<int8_t>(record.si),
+ };
+}
+
+aidl::CdmaRedirectingNumberInfoRecord toAidl(const V1_0::CdmaRedirectingNumberInfoRecord& record) {
+ return {
+ .redirectingNumber = toAidl(record.redirectingNumber),
+ .redirectingReason = static_cast<int32_t>(record.redirectingReason),
+ };
+}
+
+aidl::CdmaLineControlInfoRecord toAidl(const V1_0::CdmaLineControlInfoRecord& record) {
+ return {
+ .lineCtrlPolarityIncluded = static_cast<int8_t>(record.lineCtrlPolarityIncluded),
+ .lineCtrlToggle = static_cast<int8_t>(record.lineCtrlToggle),
+ .lineCtrlReverse = static_cast<int8_t>(record.lineCtrlReverse),
+ .lineCtrlPowerDenial = static_cast<int8_t>(record.lineCtrlPowerDenial),
+ };
+}
+
+aidl::CdmaT53ClirInfoRecord toAidl(const V1_0::CdmaT53ClirInfoRecord& record) {
+ return {
+ .cause = static_cast<int8_t>(record.cause),
+ };
+}
+
+aidl::CdmaT53AudioControlInfoRecord toAidl(const V1_0::CdmaT53AudioControlInfoRecord& record) {
+ return {
+ .upLink = static_cast<int8_t>(record.upLink),
+ .downLink = static_cast<int8_t>(record.downLink),
+ };
+}
+
+aidl::EmergencyNumber toAidl(const V1_4::EmergencyNumber& num) {
+ return {
+ .number = num.number,
+ .mcc = num.mcc,
+ .mnc = num.mnc,
+ .categories = aidl::EmergencyServiceCategory(num.categories),
+ .urns = toAidl(num.urns),
+ .sources = num.sources,
+ };
+}
+
+aidl::StkCcUnsolSsResult toAidl(const V1_0::StkCcUnsolSsResult& res) {
+ return {
+ .serviceType = static_cast<int32_t>(res.serviceType),
+ .requestType = static_cast<int32_t>(res.requestType),
+ .teleserviceType = static_cast<int32_t>(res.teleserviceType),
+ .serviceClass = res.serviceClass,
+ .result = toAidl(res.result),
+ .ssInfo = toAidl(res.ssInfo),
+ .cfData = toAidl(res.cfData),
+ };
+}
+
+aidl::SsInfoData toAidl(const V1_0::SsInfoData& info) {
+ return {
+ .ssInfo = info.ssInfo,
+ };
+}
+
+aidl::CfData toAidl(const V1_0::CfData& data) {
+ return {
+ .cfInfo = toAidl(data.cfInfo),
+ };
+}
+
+aidl::Call toAidl(const V1_0::Call& call) {
+ return toAidl(V1_2::Call{call, {}});
+}
+
+aidl::Call toAidl(const V1_2::Call& call) {
+ return toAidl(V1_6::Call{call, {}});
+}
+
+aidl::Call toAidl(const V1_6::Call& call) {
+ return {
+ .state = static_cast<int32_t>(call.base.base.state),
+ .index = call.base.base.index,
+ .toa = call.base.base.toa,
+ .isMpty = call.base.base.isMpty,
+ .isMT = call.base.base.isMT,
+ .als = static_cast<int8_t>(call.base.base.als),
+ .isVoice = call.base.base.isVoice,
+ .isVoicePrivacy = call.base.base.isVoicePrivacy,
+ .number = call.base.base.number,
+ .numberPresentation = static_cast<int32_t>(call.base.base.numberPresentation),
+ .name = call.base.base.name,
+ .namePresentation = static_cast<int32_t>(call.base.base.namePresentation),
+ .uusInfo = toAidl(call.base.base.uusInfo),
+ .audioQuality = aidl::AudioQuality(call.base.audioQuality),
+ .forwardedNumber = call.forwardedNumber,
+ };
+}
+
+aidl::UusInfo toAidl(const V1_0::UusInfo& info) {
+ return {
+ .uusType = static_cast<int32_t>(info.uusType),
+ .uusDcs = static_cast<int32_t>(info.uusDcs),
+ .uusData = info.uusData,
+ };
+}
+
+aidl::LastCallFailCauseInfo toAidl(const V1_0::LastCallFailCauseInfo& info) {
+ return {
+ .causeCode = aidl::LastCallFailCause(info.causeCode),
+ .vendorCause = info.vendorCause,
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.h b/radio/aidl/compat/libradiocompat/voice/structs.h
new file mode 100644
index 0000000..b55a089
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/voice/structs.h
@@ -0,0 +1,91 @@
+/*
+ * 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/radio/voice/Call.h>
+#include <aidl/android/hardware/radio/voice/CallForwardInfo.h>
+#include <aidl/android/hardware/radio/voice/CdmaCallWaiting.h>
+#include <aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaInformationRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.h>
+#include <aidl/android/hardware/radio/voice/CfData.h>
+#include <aidl/android/hardware/radio/voice/Dial.h>
+#include <aidl/android/hardware/radio/voice/EmergencyNumber.h>
+#include <aidl/android/hardware/radio/voice/LastCallFailCauseInfo.h>
+#include <aidl/android/hardware/radio/voice/SsInfoData.h>
+#include <aidl/android/hardware/radio/voice/StkCcUnsolSsResult.h>
+#include <aidl/android/hardware/radio/voice/UusInfo.h>
+#include <android/hardware/radio/1.6/types.h>
+
+namespace android::hardware::radio::compat {
+
+V1_0::Dial toHidl(const ::aidl::android::hardware::radio::voice::Dial& info);
+
+V1_0::UusInfo toHidl(const ::aidl::android::hardware::radio::voice::UusInfo& info);
+
+::aidl::android::hardware::radio::voice::CallForwardInfo toAidl(const V1_0::CallForwardInfo& info);
+V1_0::CallForwardInfo toHidl(const ::aidl::android::hardware::radio::voice::CallForwardInfo& info);
+
+::aidl::android::hardware::radio::voice::CdmaSignalInfoRecord //
+toAidl(const V1_0::CdmaSignalInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaCallWaiting toAidl(const V1_0::CdmaCallWaiting& call);
+
+::aidl::android::hardware::radio::voice::CdmaInformationRecord //
+toAidl(const V1_0::CdmaInformationRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaDisplayInfoRecord //
+toAidl(const V1_0::CdmaDisplayInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaNumberInfoRecord //
+toAidl(const V1_0::CdmaNumberInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaRedirectingNumberInfoRecord //
+toAidl(const V1_0::CdmaRedirectingNumberInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaLineControlInfoRecord //
+toAidl(const V1_0::CdmaLineControlInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaT53ClirInfoRecord //
+toAidl(const V1_0::CdmaT53ClirInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::CdmaT53AudioControlInfoRecord //
+toAidl(const V1_0::CdmaT53AudioControlInfoRecord& record);
+
+::aidl::android::hardware::radio::voice::EmergencyNumber toAidl(const V1_4::EmergencyNumber& num);
+
+::aidl::android::hardware::radio::voice::StkCcUnsolSsResult //
+toAidl(const V1_0::StkCcUnsolSsResult& res);
+
+::aidl::android::hardware::radio::voice::SsInfoData toAidl(const V1_0::SsInfoData& info);
+
+::aidl::android::hardware::radio::voice::CfData toAidl(const V1_0::CfData& data);
+
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_0::Call& call);
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_2::Call& call);
+::aidl::android::hardware::radio::voice::Call toAidl(const V1_6::Call& call);
+
+::aidl::android::hardware::radio::voice::UusInfo toAidl(const V1_0::UusInfo& info);
+
+::aidl::android::hardware::radio::voice::LastCallFailCauseInfo //
+toAidl(const V1_0::LastCallFailCauseInfo& info);
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/service/Android.bp b/radio/aidl/compat/service/Android.bp
new file mode 100644
index 0000000..52eb71f
--- /dev/null
+++ b/radio/aidl/compat/service/Android.bp
@@ -0,0 +1,64 @@
+// 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 {
+ // 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.radio-service.compat",
+ relative_install_path: "hw",
+ init_rc: ["radio-compat.rc"],
+ vintf_fragments: ["radio-compat.xml"],
+ vendor: true,
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+ ],
+ shared_libs: [
+ "android.hardware.radio-library.compat",
+ "android.hardware.radio.config-V1-ndk",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ "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.sim-V1-ndk",
+ "android.hardware.radio.voice-V1-ndk",
+ "android.hardware.radio@1.0",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.2",
+ "android.hardware.radio@1.3",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.5",
+ "android.hardware.radio@1.6",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ ],
+ srcs: [
+ "hidl-utils.cpp",
+ "service.cpp",
+ ],
+}
diff --git a/radio/aidl/compat/service/hidl-utils.cpp b/radio/aidl/compat/service/hidl-utils.cpp
new file mode 100644
index 0000000..fc0d54d
--- /dev/null
+++ b/radio/aidl/compat/service/hidl-utils.cpp
@@ -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.
+ */
+
+#include "hidl-utils.h"
+
+#include <android-base/logging.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+
+namespace android::hardware::hidl_utils {
+
+class HalDeathRecipient : public hidl_death_recipient {
+ void serviceDied(uint64_t /* cookie */, const wp<hidl::base::V1_0::IBase>& /* who */) override {
+ LOG(FATAL) << "One of the linked HALs died. Restarting...";
+ }
+};
+
+static const auto gHalDeathRecipient = sp<HalDeathRecipient>::make();
+
+void linkDeathToDeath(sp<::android::hidl::base::V1_0::IBase> hal) {
+ const auto linkStatus = hal->linkToDeath(gHalDeathRecipient, 0);
+ CHECK(linkStatus.withDefault(false)) << "Failed to link to HAL death";
+}
+
+hidl_vec<hidl_string> listManifestByInterface(const char* descriptor) {
+ auto manager = hidl::manager::V1_2::IServiceManager::getService();
+ hidl_vec<hidl_string> services;
+ manager->listManifestByInterface(descriptor, hidl_utils::fill(&services));
+ CHECK_GT(services.size(), 0u) << "No " << descriptor
+ << " services in manifest (missing privileges?)" << std::endl;
+ return services;
+}
+
+} // namespace android::hardware::hidl_utils
diff --git a/radio/aidl/compat/service/hidl-utils.h b/radio/aidl/compat/service/hidl-utils.h
new file mode 100644
index 0000000..be3386f
--- /dev/null
+++ b/radio/aidl/compat/service/hidl-utils.h
@@ -0,0 +1,78 @@
+/*
+ * 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/hidl/base/1.0/IBase.h>
+
+#include <functional>
+
+namespace android::hardware::hidl_utils {
+
+/**
+ * Helper functor to fetch results from multi-return HIDL calls.
+ * It's meant to be used in place of _hidl_cb callbacks.
+ *
+ * Please note extracting these return variables outside of the callback scope requires making
+ * a copy of each return variable. This may be costly for frequently called HIDL methods with
+ * non-negligible return object size. Please be cautious about performance when using this.
+ *
+ * Example usage:
+ * Result result;
+ * sp<ISomeInterface> iface;
+ * hidlObject->someMethod(arg1, arg2, hidl_utils::fill(&result, &iface)).assertOk();
+ * // use result and iface
+ */
+template <typename... T>
+struct fill : public std::function<void(const T&...)> {
+ /**
+ * Create _hidl_cb functor that copies the call arguments to specified pointers.
+ *
+ * \param args... Targets to copy the call arguments to
+ */
+ fill(T*... args) : mTargets(args...) {}
+
+ void operator()(const T&... args) { copy<0, T...>(args...); }
+
+ private:
+ std::tuple<T*...> mTargets;
+
+ template <int Pos, typename First>
+ inline void copy(const First& first) {
+ *std::get<Pos>(mTargets) = first;
+ }
+
+ template <int Pos, typename First, typename... Rest>
+ inline void copy(const First& first, const Rest&... rest) {
+ *std::get<Pos>(mTargets) = first;
+ copy<Pos + 1, Rest...>(rest...);
+ }
+};
+
+/**
+ * Link to a given HALs death and restart the current process in such a case.
+ * \param hal HAL to which death to link
+ */
+void linkDeathToDeath(sp<hidl::base::V1_0::IBase> hal);
+
+/**
+ * List HAL instances of a given interface.
+ *
+ * \descriptor HIDL HAL descriptor
+ */
+hidl_vec<hidl_string> listManifestByInterface(const char* descriptor);
+
+} // namespace android::hardware::hidl_utils
diff --git a/radio/aidl/compat/service/radio-compat.rc b/radio/aidl/compat/service/radio-compat.rc
new file mode 100644
index 0000000..a159876
--- /dev/null
+++ b/radio/aidl/compat/service/radio-compat.rc
@@ -0,0 +1,4 @@
+service vendor.radio-compat /vendor/bin/hw/android.hardware.radio-service.compat
+ class hal
+ user nobody
+ group system
diff --git a/radio/aidl/compat/service/radio-compat.xml b/radio/aidl/compat/service/radio-compat.xml
new file mode 100644
index 0000000..a7089e6
--- /dev/null
+++ b/radio/aidl/compat/service/radio-compat.xml
@@ -0,0 +1,37 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.radio.config</name>
+ <fqname>IRadioConfig/default</fqname>
+ </hal>
+<!--
+ Instances other than config are configured per-device, depending on the slot count (framework
+ currently supports slot1, slot2 and slot3 instances) and Radio HALs device wishes to provide.
+ You can either copy the following tags to device manifest or simply uncomment them here for
+ quick testing.
+
+ <hal format="aidl">
+ <name>android.hardware.radio.data</name>
+ <fqname>IRadioData/slot1</fqname>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.radio.messaging</name>
+ <fqname>IRadioMessaging/slot1</fqname>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.radio.modem</name>
+ <fqname>IRadioModem/slot1</fqname>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.radio.network</name>
+ <fqname>IRadioNetwork/slot1</fqname>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.radio.sim</name>
+ <fqname>IRadioSim/slot1</fqname>
+ </hal>
+ <hal format="aidl">
+ <name>android.hardware.radio.voice</name>
+ <fqname>IRadioVoice/slot1</fqname>
+ </hal>
+-->
+</manifest>
diff --git a/radio/aidl/compat/service/service.cpp b/radio/aidl/compat/service/service.cpp
new file mode 100644
index 0000000..2a67569
--- /dev/null
+++ b/radio/aidl/compat/service/service.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "hidl-utils.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <libradiocompat/RadioConfig.h>
+#include <libradiocompat/RadioData.h>
+#include <libradiocompat/RadioIndication.h>
+#include <libradiocompat/RadioMessaging.h>
+#include <libradiocompat/RadioModem.h>
+#include <libradiocompat/RadioNetwork.h>
+#include <libradiocompat/RadioResponse.h>
+#include <libradiocompat/RadioSim.h>
+#include <libradiocompat/RadioVoice.h>
+
+namespace android::hardware::radio::service {
+
+using namespace std::string_literals;
+
+static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
+
+template <typename T>
+static void publishRadioHal(sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
+ sp<compat::RadioIndication> indicationCb, const std::string& slot) {
+ const auto instance = T::descriptor + "/"s + slot;
+ if (!AServiceManager_isDeclared(instance.c_str())) {
+ LOG(INFO) << instance << " is not declared in VINTF (this may be intentional)";
+ return;
+ }
+ LOG(DEBUG) << "Publishing " << instance;
+
+ auto aidlHal = ndk::SharedRefBase::make<T>(hidlHal, responseCb, indicationCb);
+ gPublishedHals.push_back(aidlHal);
+ const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+}
+
+static void publishRadio(std::string slot) {
+ auto radioHidl = V1_5::IRadio::getService(slot);
+ CHECK(radioHidl) << "HIDL IRadio not present in VINTF";
+
+ hidl_utils::linkDeathToDeath(radioHidl);
+
+ auto responseCb = sp<compat::RadioResponse>::make();
+ auto indicationCb = sp<compat::RadioIndication>::make();
+ radioHidl->setResponseFunctions(responseCb, indicationCb).assertOk();
+
+ publishRadioHal<compat::RadioData>(radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioMessaging>(radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioModem>(radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioNetwork>(radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioSim>(radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioVoice>(radioHidl, responseCb, indicationCb, slot);
+}
+
+static void publishRadioConfig() {
+ auto hidlHal = config::V1_1::IRadioConfig::getService();
+ CHECK(hidlHal) << "HIDL IRadioConfig not present in VINTF";
+
+ hidl_utils::linkDeathToDeath(hidlHal);
+
+ auto aidlHal = ndk::SharedRefBase::make<compat::RadioConfig>(hidlHal);
+ gPublishedHals.push_back(aidlHal);
+ const auto instance = compat::RadioConfig::descriptor + "/default"s;
+ const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+}
+
+static void main() {
+ base::SetDefaultTag("radiocompat");
+ base::SetMinimumLogSeverity(base::VERBOSE);
+ LOG(DEBUG) << "Radio HAL compat service starting...";
+
+ publishRadioConfig();
+
+ const auto slots = hidl_utils::listManifestByInterface(V1_0::IRadio::descriptor);
+ LOG(INFO) << "Found " << slots.size() << " slot(s)";
+ for (const auto& slot : slots) {
+ publishRadio(slot);
+ }
+
+ LOG(DEBUG) << "Radio HAL compat service is operational";
+ ABinderProcess_joinThreadPool();
+ LOG(FATAL) << "Radio HAL compat service has stopped";
+}
+
+} // namespace android::hardware::radio::service
+
+int main() {
+ android::hardware::radio::service::main();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index 028d297..3cf6ff2 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -38,3 +38,30 @@
},
versions: ["1"],
}
+
+// cc_defaults that includes the latest KeyMint AIDL library.
+// Modules that depend on KeyMint directly can include this cc_defaults to avoid
+// managing dependency versions explicitly.
+cc_defaults {
+ name: "keymint_use_latest_hal_aidl_ndk_static",
+ static_libs: [
+ "android.hardware.security.keymint-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "keymint_use_latest_hal_aidl_ndk_shared",
+ shared_libs: [
+ "android.hardware.security.keymint-V1-ndk",
+ ],
+}
+
+// A rust_defaults that includes the latest KeyMint AIDL library.
+// Modules that depend on KeyMint directly can include this cc_defaults to avoid
+// managing dependency versions explicitly.
+rust_defaults {
+ name: "keymint_use_latest_hal_aidl_rust",
+ rustlibs: [
+ "android.hardware.security.keymint-V1-rust",
+ ],
+}
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index c2918ef..1a17fd4 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -21,8 +21,10 @@
"-Wall",
"-Wextra",
],
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
shared_libs: [
- "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.sharedsecret-V1-ndk",
"android.hardware.security.secureclock-V1-ndk",
"libbase",
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index ff6a6f8..2d2d701 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_defaults {
name: "keymint_vts_defaults",
defaults: [
+ "keymint_use_latest_hal_aidl_ndk_static",
"use_libaidlvintf_gtest_helper_static",
"VtsHalTargetTestDefaults",
],
@@ -34,7 +35,6 @@
"libcrypto",
],
static_libs: [
- "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.secureclock-V1-ndk",
"libcppbor_external",
"libcppcose_rkp",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 26ed344..64550ef 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -50,7 +50,7 @@
vector<KeyCharacteristics> attest_key_characteristics;
vector<Certificate> attest_key_cert_chain;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(size, 65537)
+ .RsaKey(size, 65537)
.AttestKey()
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
@@ -200,7 +200,7 @@
vector<Certificate> attest_key_cert_chain;
ASSERT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
+ .RsaKey(2048, 65537)
.AttestKey()
.AttestationChallenge(challenge)
.AttestationApplicationId(app_id)
@@ -299,7 +299,7 @@
EXPECT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
+ .RsaKey(2048, 65537)
.AttestKey()
.AttestationChallenge("foo")
.AttestationApplicationId("bar")
@@ -371,7 +371,7 @@
EXPECT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(EcCurve::P_256)
+ .EcdsaKey(EcCurve::P_256)
.AttestKey()
.AttestationChallenge("foo")
.AttestationApplicationId("bar")
@@ -446,7 +446,7 @@
if ((i & 0x1) == 1) {
EXPECT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(EcCurve::P_256)
+ .EcdsaKey(EcCurve::P_256)
.AttestKey()
.AttestationChallenge("foo")
.AttestationApplicationId("bar")
@@ -459,7 +459,7 @@
} else {
EXPECT_EQ(ErrorCode::OK,
GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
+ .RsaKey(2048, 65537)
.AttestKey()
.AttestationChallenge("foo")
.AttestationApplicationId("bar")
@@ -509,7 +509,7 @@
vector<KeyCharacteristics> attest_key_characteristics;
vector<Certificate> attest_key_cert_chain;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(size, 65537)
+ .RsaKey(size, 65537)
.AttestKey()
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
@@ -555,12 +555,12 @@
AttestationKey attest_key;
vector<KeyCharacteristics> attest_key_characteristics;
vector<Certificate> attest_key_cert_chain;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(curve)
- .AttestKey()
- .SetDefaultValidity(),
- {} /* attestation signing key */, &attest_key.keyBlob,
- &attest_key_characteristics, &attest_key_cert_chain));
+ ASSERT_EQ(
+ ErrorCode::OK,
+ GenerateKey(
+ AuthorizationSetBuilder().EcdsaKey(curve).AttestKey().SetDefaultValidity(),
+ {} /* attestation signing key */, &attest_key.keyBlob,
+ &attest_key_characteristics, &attest_key_cert_chain));
ASSERT_GT(attest_key_cert_chain.size(), 0);
EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -671,7 +671,7 @@
vector<KeyCharacteristics> attest_key_characteristics;
vector<Certificate> attest_key_cert_chain;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(EcCurve::P_256)
+ .EcdsaKey(EcCurve::P_256)
.AttestKey()
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
@@ -735,7 +735,7 @@
vector<KeyCharacteristics> attest_key_characteristics;
vector<Certificate> attest_key_cert_chain;
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(EcCurve::P_256)
+ .EcdsaKey(EcCurve::P_256)
.AttestKey()
.SetDefaultValidity(),
{} /* attestation signing key */, &attest_key.keyBlob,
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 12ce859..6140df1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1067,6 +1067,8 @@
}
} else {
switch (algorithm) {
+ case Algorithm::AES:
+ return {64, 96, 131, 512};
case Algorithm::TRIPLE_DES:
return {56};
default:
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 919d79f..c99e1d0 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -69,8 +69,11 @@
namespace {
+// Whether to check that BOOT_PATCHLEVEL is populated.
+bool check_boot_pl = true;
+
// The maximum number of times we'll attempt to verify that corruption
-// of an ecrypted blob results in an error. Retries are necessary as there
+// of an encrypted blob results in an error. Retries are necessary as there
// is a small (roughly 1/256) chance that corrupting ciphertext still results
// in valid PKCS7 padding.
constexpr size_t kMaxPaddingCorruptionRetries = 8;
@@ -527,12 +530,17 @@
EXPECT_TRUE(os_pl);
EXPECT_EQ(*os_pl, os_patch_level());
- // Should include vendor and boot patchlevels.
+ // Should include vendor patchlevel.
auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
EXPECT_TRUE(vendor_pl);
EXPECT_EQ(*vendor_pl, vendor_patch_level());
- auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
- EXPECT_TRUE(boot_pl);
+
+ // Should include boot patchlevel (but there are some test scenarios where this is not
+ // possible).
+ if (check_boot_pl) {
+ auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
+ EXPECT_TRUE(boot_pl);
+ }
return auths;
}
@@ -6914,6 +6922,12 @@
} else {
std::cout << "NOT dumping attestations" << std::endl;
}
+ if (std::string(argv[i]) == "--skip_boot_pl_check") {
+ // Allow checks of BOOT_PATCHLEVEL to be disabled, so that the tests can
+ // be run in emulated environments that don't have the normal bootloader
+ // interactions.
+ aidl::android::hardware::security::keymint::test::check_boot_pl = false;
+ }
}
}
return RUN_ALL_TESTS();
diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp
index 355f87b..7e3a3e5 100644
--- a/security/keymint/aidl/vts/performance/Android.bp
+++ b/security/keymint/aidl/vts/performance/Android.bp
@@ -27,6 +27,7 @@
name: "VtsAidlKeyMintBenchmarkTest",
defaults: [
"VtsHalTargetTestDefaults",
+ "keymint_use_latest_hal_aidl_ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
srcs: [
@@ -39,7 +40,6 @@
"libkeymint_support",
],
static_libs: [
- "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.secureclock-V1-ndk",
"libcppbor_external",
"libchrome",
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index e162934..36969bb 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -40,8 +40,10 @@
export_include_dirs: [
"include",
],
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
shared_libs: [
- "android.hardware.security.keymint-V1-ndk",
"libbase",
"libcrypto",
"libutils",
diff --git a/security/secureclock/aidl/vts/functional/Android.bp b/security/secureclock/aidl/vts/functional/Android.bp
index 806517d..a34668b 100644
--- a/security/secureclock/aidl/vts/functional/Android.bp
+++ b/security/secureclock/aidl/vts/functional/Android.bp
@@ -27,6 +27,7 @@
name: "VtsAidlSecureClockTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
+ "keymint_use_latest_hal_aidl_ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
cflags: [
@@ -41,7 +42,6 @@
"libcrypto",
],
static_libs: [
- "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.secureclock-V1-ndk",
"libkeymint",
],
diff --git a/security/sharedsecret/aidl/vts/functional/Android.bp b/security/sharedsecret/aidl/vts/functional/Android.bp
index 94da675..1f0f6a6 100644
--- a/security/sharedsecret/aidl/vts/functional/Android.bp
+++ b/security/sharedsecret/aidl/vts/functional/Android.bp
@@ -27,6 +27,7 @@
name: "VtsAidlSharedSecretTargetTest",
defaults: [
"VtsHalTargetTestDefaults",
+ "keymint_use_latest_hal_aidl_ndk_static",
"use_libaidlvintf_gtest_helper_static",
],
srcs: [
@@ -41,7 +42,6 @@
"libcrypto",
],
static_libs: [
- "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.sharedsecret-V1-ndk",
"libkeymint",
],
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
index 8e31bd9..95ecc51 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
@@ -47,4 +47,5 @@
INVALID_FRONTEND_ID = -1,
INVALID_LNB_ID = -1,
INVALID_KEYTOKEN = 0,
+ INVALID_TABINFO_VERSION = -1,
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
index 95911f9..3e5df2d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -36,4 +36,5 @@
@VintfStability
parcelable DemuxFilterAvSettings {
boolean isPassthrough;
+ boolean isSecureMemory;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
index 17bdd1f..02c478f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -36,6 +36,6 @@
@VintfStability
parcelable DemuxFilterRecordSettings {
int tsIndexMask;
- android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.UNDEFINED;
+ android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.NONE;
android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
}
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 3fd1910..371e075 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
@@ -36,5 +36,6 @@
@VintfStability
union DemuxFilterScIndexMask {
int scIndex;
+ int scAvc;
int scHevc;
}
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 91a5e52..30ec29a 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
@@ -38,5 +38,5 @@
NONE = 0,
SC = 1,
SC_HEVC = 2,
- UNDEFINED = 3,
+ SC_AVC = 3,
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
new file mode 100644
index 0000000..651b66c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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 */
+@Backing(type="int") @VintfStability
+enum DemuxScAvcIndex {
+ UNDEFINED = 0,
+ I_SLICE = 1,
+ P_SLICE = 2,
+ B_SLICE = 4,
+ SI_SLICE = 8,
+ SP_SLICE = 16,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index 3035dad..670b34e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -35,6 +35,7 @@
/* @hide */
@Backing(type="int") @VintfStability
enum DemuxScHevcIndex {
+ UNDEFINED = 0,
SPS = 1,
AUD = 2,
SLICE_CE_BLA_W_LP = 4,
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
index 808b212..25f0585 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -40,9 +40,4 @@
P_FRAME = 2,
B_FRAME = 4,
SEQUENCE = 8,
- I_SLICE = 16,
- P_SLICE = 32,
- B_SLICE = 64,
- SI_SLICE = 128,
- SP_SLICE = 256,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
index 891794a..0751d26 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
@@ -83,4 +83,9 @@
* An invalid key token. It is used to remove the current key from the descrambler.
*/
INVALID_KEYTOKEN = 0x00,
+
+ /**
+ * An invalid section filter version number.
+ */
+ INVALID_TABINFO_VERSION = 0xFFFFFFFF,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
index 30a1054..fe4db5b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -26,4 +26,9 @@
* true if the filter output goes to decoder directly in pass through mode.
*/
boolean isPassthrough;
+
+ /**
+ * true if the avMemory should be allocated from secure area.
+ */
+ boolean isSecureMemory;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
index 2f88864..475910b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -30,7 +30,7 @@
*/
int tsIndexMask;
- DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.UNDEFINED;
+ DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.NONE;
DemuxFilterScIndexMask scIndexMask;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
index a9f4b6f..4036b06 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -16,6 +16,7 @@
package android.hardware.tv.tuner;
+import android.hardware.tv.tuner.DemuxScAvcIndex;
import android.hardware.tv.tuner.DemuxScHevcIndex;
import android.hardware.tv.tuner.DemuxScIndex;
@@ -30,6 +31,11 @@
int scIndex;
/**
+ * Indexes defined by DemuxScAvcIndex.
+ */
+ int scAvc;
+
+ /**
* Indexes defined by DemuxScHevcIndex.
*/
int scHevc;
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
index 898b9cc..dbd438c 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
@@ -28,7 +28,8 @@
int tableId;
/**
- * Version number for Section Filter
+ * Optional version number for Section Filter. It should be ignored if INVALID_TABINFO_VERSION
+ * is set.
*/
int version;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index 44b985c..98427f7 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -39,7 +39,7 @@
SC_HEVC,
/**
- * SC index is undefined
+ * Use Start Code index for AVC
*/
- UNDEFINED,
+ SC_AVC,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
new file mode 100644
index 0000000..ed418f2
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+/**
+ * Indexes can be tagged by start point of slice groups according to ISO/IEC 14496-10.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScAvcIndex {
+ UNDEFINED = 0,
+
+ /**
+ * All blocks are coded as I blocks.
+ */
+ I_SLICE = 1 << 0,
+
+ /**
+ * Blocks are coded as I or P blocks.
+ */
+ P_SLICE = 1 << 1,
+
+ /**
+ * Blocks are coded as I, P or B blocks.
+ */
+ B_SLICE = 1 << 2,
+
+ /**
+ * A so-called switching I slice that is coded.
+ */
+ SI_SLICE = 1 << 3,
+
+ /**
+ * A so-called switching P slice that is coded.
+ */
+ SP_SLICE = 1 << 4,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index f2ddd00..0d1f112 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -23,6 +23,8 @@
@VintfStability
@Backing(type="int")
enum DemuxScHevcIndex {
+ UNDEFINED = 0,
+
SPS = 1 << 0,
AUD = 1 << 1,
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
index 0aef739..4fed1e5 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -18,7 +18,7 @@
/**
* Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
- * according to ISO/IEC 13818-1 and Slice Groups according to ISO/IEC 14496-10.
+ * according to ISO/IEC 13818-1.
* @hide
*/
@VintfStability
@@ -45,29 +45,4 @@
* Start Code is for a new Sequence
*/
SEQUENCE = 1 << 3,
-
- /**
- * All blocks are coded as I blocks.
- */
- I_SLICE = 1 << 4,
-
- /**
- * Blocks are coded as I or P blocks.
- */
- P_SLICE = 1 << 5,
-
- /**
- * Blocks are coded as I, P or B blocks.
- */
- B_SLICE = 1 << 6,
-
- /**
- * A so-called switching I slice that is coded.
- */
- SI_SLICE = 1 << 7,
-
- /**
- * A so-called switching P slice that is coded.
- */
- SP_SLICE = 1 << 8,
}
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 5f61c8d..54037be 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -35,7 +35,11 @@
#define WAIT_TIMEOUT 3000000000
FilterCallbackScheduler::FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb)
- : mCallback(cb), mDataLength(0), mTimeDelayInMs(0), mDataSizeDelayInBytes(0) {
+ : mCallback(cb),
+ mIsConditionMet(false),
+ mDataLength(0),
+ mTimeDelayInMs(0),
+ mDataSizeDelayInBytes(0) {
start();
}
@@ -44,12 +48,14 @@
}
void FilterCallbackScheduler::onFilterEvent(DemuxFilterEvent&& event) {
- std::lock_guard<std::mutex> lock(mLock);
+ std::unique_lock<std::mutex> lock(mLock);
mCallbackBuffer.push_back(std::move(event));
mDataLength += getDemuxFilterEventDataLength(event);
- if (mDataLength >= mDataSizeDelayInBytes) {
- // size limit has been reached, send out events
+ if (isDataSizeDelayConditionMetLocked()) {
+ mIsConditionMet = true;
+ // unlock, so thread is not immediately blocked when it is notified.
+ lock.unlock();
mCv.notify_all();
}
}
@@ -67,21 +73,22 @@
}
void FilterCallbackScheduler::setTimeDelayHint(int timeDelay) {
- // updating the setTimeDelay does not go into effect until the condition
- // variable times out or is notified.
- // One possibility is to notify the condition variable right away when the
- // time delay changes, but I don't see the benefit over waiting for the next
- // timeout / push, since -- in any case -- this will not change very often.
+ std::unique_lock<std::mutex> lock(mLock);
mTimeDelayInMs = timeDelay;
+ // always notify condition variable to update timeout
+ mIsConditionMet = true;
+ lock.unlock();
+ mCv.notify_all();
}
void FilterCallbackScheduler::setDataSizeDelayHint(int dataSizeDelay) {
- // similar to updating the time delay hint, when mDataSizeDelayInBytes
- // changes, this will not go into immediate effect, but will wait until the
- // next filterEvent.
- // We could technically check the current data length and notify the
- // condition variable if we wanted to, but again, this may be overkill.
+ std::unique_lock<std::mutex> lock(mLock);
mDataSizeDelayInBytes = dataSizeDelay;
+ if (isDataSizeDelayConditionMetLocked()) {
+ mIsConditionMet = true;
+ lock.unlock();
+ mCv.notify_all();
+ }
}
bool FilterCallbackScheduler::hasCallbackRegistered() const {
@@ -96,6 +103,10 @@
void FilterCallbackScheduler::stop() {
mIsRunning = false;
if (mCallbackThread.joinable()) {
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ mIsConditionMet = true;
+ }
mCv.notify_all();
mCallbackThread.join();
}
@@ -109,17 +120,15 @@
void FilterCallbackScheduler::threadLoopOnce() {
std::unique_lock<std::mutex> lock(mLock);
- // mTimeDelayInMs is an atomic value, so it should be copied into a local
- // variable before use (to make sure both the if statement and wait_for use
- // the same value).
- int timeDelayInMs = mTimeDelayInMs;
- if (timeDelayInMs > 0) {
- mCv.wait_for(lock, std::chrono::milliseconds(timeDelayInMs));
+ if (mTimeDelayInMs > 0) {
+ // Note: predicate protects from lost and spurious wakeups
+ mCv.wait_for(lock, std::chrono::milliseconds(mTimeDelayInMs),
+ [this] { return mIsConditionMet; });
} else {
- // no reason to timeout, just wait until main thread determines it's
- // okay to send data.
- mCv.wait(lock);
+ // Note: predicate protects from lost and spurious wakeups
+ mCv.wait(lock, [this] { return mIsConditionMet; });
}
+ mIsConditionMet = false;
// condition_variable wait locks mutex on timeout / notify
// Note: if stop() has been called in the meantime, do not send more filter
@@ -131,7 +140,22 @@
mCallbackBuffer.clear();
mDataLength = 0;
}
- lock.unlock();
+}
+
+// mLock needs to be held to call this function
+bool FilterCallbackScheduler::isDataSizeDelayConditionMetLocked() {
+ if (mDataSizeDelayInBytes == 0) {
+ // Data size delay is disabled.
+ if (mTimeDelayInMs == 0) {
+ // Events should only be sent immediately if time delay is disabled
+ // as well.
+ return true;
+ }
+ return false;
+ }
+
+ // Data size delay is enabled.
+ return mDataLength >= mDataSizeDelayInBytes;
}
int FilterCallbackScheduler::getDemuxFilterEventDataLength(const DemuxFilterEvent& event) {
@@ -542,7 +566,9 @@
// For the first time of filter output, implementation needs to send the filter
// Event Callback without waiting for the DATA_CONSUMED to init the process.
while (mFilterThreadRunning) {
+ std::unique_lock<std::mutex> lock(mFilterEventsLock);
if (mFilterEvents.size() == 0) {
+ lock.unlock();
if (DEBUG_FILTER) {
ALOGD("[Filter] wait for filter data output.");
}
@@ -559,6 +585,7 @@
mConfigured = false;
}
+ // lock is still being held
for (auto&& event : mFilterEvents) {
mCallbackScheduler.onFilterEvent(std::move(event));
}
@@ -741,7 +768,6 @@
}
::ndk::ScopedAStatus Filter::startPesFilterHandler() {
- std::lock_guard<std::mutex> lock(mFilterEventsLock);
if (mFilterOutput.empty()) {
return ::ndk::ScopedAStatus::ok();
}
@@ -796,7 +822,11 @@
ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
}
- mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(pesEvent));
+ {
+ std::lock_guard<std::mutex> lock(mFilterEventsLock);
+ mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(pesEvent));
+ }
+
mPesOutput.clear();
}
@@ -811,7 +841,6 @@
}
::ndk::ScopedAStatus Filter::startMediaFilterHandler() {
- std::lock_guard<std::mutex> lock(mFilterEventsLock);
if (mFilterOutput.empty()) {
return ::ndk::ScopedAStatus::ok();
}
@@ -900,7 +929,12 @@
.firstMbInSlice = 0, // random address
};
- mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(recordEvent));
+ {
+ std::lock_guard<std::mutex> lock(mFilterEventsLock);
+ mFilterEvents.push_back(
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(recordEvent));
+ }
+
mRecordFilterOutput.clear();
return ::ndk::ScopedAStatus::ok();
}
@@ -918,7 +952,6 @@
bool Filter::writeSectionsAndCreateEvent(vector<int8_t>& data) {
// TODO check how many sections has been read
ALOGD("[Filter] section handler");
- std::lock_guard<std::mutex> lock(mFilterEventsLock);
if (!writeDataToFilterMQ(data)) {
return false;
}
@@ -930,7 +963,12 @@
.sectionNum = 1,
.dataLength = static_cast<int32_t>(data.size()),
};
- mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+
+ {
+ std::lock_guard<std::mutex> lock(mFilterEventsLock);
+ mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
+ }
+
return true;
}
@@ -1028,7 +1066,11 @@
mediaEvent.pts = mPts;
mPts = 0;
}
- mFilterEvents.push_back(std::move(event));
+
+ {
+ std::lock_guard<std::mutex> lock(mFilterEventsLock);
+ mFilterEvents.push_back(std::move(event));
+ }
// Clear and log
native_handle_close(nativeHandle);
@@ -1068,7 +1110,11 @@
mediaEvent.pts = mPts;
mPts = 0;
}
- mFilterEvents.push_back(std::move(event));
+
+ {
+ std::lock_guard<std::mutex> lock(mFilterEventsLock);
+ mFilterEvents.push_back(std::move(event));
+ }
mSharedAvMemOffset += output.size();
@@ -1092,8 +1138,6 @@
void Filter::createMediaEvent(vector<DemuxFilterEvent>& events) {
AudioExtraMetaData audio;
- events.resize(1);
-
audio.adFade = 1;
audio.adPan = 2;
audio.versionTextTag = 3;
@@ -1101,17 +1145,15 @@
audio.adGainFront = 5;
audio.adGainSurround = 6;
- events[0] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
- events[0].get<DemuxFilterEvent::Tag::media>().streamId = 1;
- events[0].get<DemuxFilterEvent::Tag::media>().isPtsPresent = true;
- events[0].get<DemuxFilterEvent::Tag::media>().dataLength = 3;
- events[0].get<DemuxFilterEvent::Tag::media>().offset = 4;
- events[0].get<DemuxFilterEvent::Tag::media>().isSecureMemory = true;
- events[0].get<DemuxFilterEvent::Tag::media>().mpuSequenceNumber = 6;
- events[0].get<DemuxFilterEvent::Tag::media>().isPesPrivateData = true;
- events[0]
- .get<DemuxFilterEvent::Tag::media>()
- .extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
+ DemuxFilterMediaEvent mediaEvent;
+ mediaEvent.streamId = 1;
+ mediaEvent.isPtsPresent = true;
+ mediaEvent.dataLength = 3;
+ mediaEvent.offset = 4;
+ mediaEvent.isSecureMemory = true;
+ mediaEvent.mpuSequenceNumber = 6;
+ mediaEvent.isPesPrivateData = true;
+ mediaEvent.extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
int av_fd = createAvIonFd(BUFFER_SIZE_16M);
if (av_fd == -1) {
@@ -1129,16 +1171,16 @@
uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
mDataId2Avfd[dataId] = dup(av_fd);
- events[0].get<DemuxFilterEvent::Tag::media>().avDataId = static_cast<int64_t>(dataId);
- events[0].get<DemuxFilterEvent::Tag::media>().avMemory = ::android::dupToAidl(nativeHandle);
+ mediaEvent.avDataId = static_cast<int64_t>(dataId);
+ mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
+
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>(std::move(mediaEvent)));
native_handle_close(nativeHandle);
native_handle_delete(nativeHandle);
}
void Filter::createTsRecordEvent(vector<DemuxFilterEvent>& events) {
- events.resize(2);
-
DemuxPid pid;
DemuxFilterScIndexMask mask;
DemuxFilterTsRecordEvent tsRecord1;
@@ -1153,13 +1195,11 @@
tsRecord2.pts = 1;
tsRecord2.firstMbInSlice = 2; // random address
- events[0].set<DemuxFilterEvent::Tag::tsRecord>(tsRecord1);
- events[1].set<DemuxFilterEvent::Tag::tsRecord>(tsRecord2);
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(std::move(tsRecord1)));
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(std::move(tsRecord2)));
}
void Filter::createMmtpRecordEvent(vector<DemuxFilterEvent>& events) {
- events.resize(2);
-
DemuxFilterMmtpRecordEvent mmtpRecord1;
mmtpRecord1.scHevcIndexMask = 1;
mmtpRecord1.byteNumber = 2;
@@ -1170,36 +1210,32 @@
mmtpRecord2.firstMbInSlice = 3;
mmtpRecord2.tsIndexMask = 4;
- events[0].set<DemuxFilterEvent::Tag::mmtpRecord>(mmtpRecord1);
- events[1].set<DemuxFilterEvent::Tag::mmtpRecord>(mmtpRecord2);
+ events.push_back(
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::mmtpRecord>(std::move(mmtpRecord1)));
+ events.push_back(
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::mmtpRecord>(std::move(mmtpRecord2)));
}
void Filter::createSectionEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
DemuxFilterSectionEvent section;
section.tableId = 1;
section.version = 2;
section.sectionNum = 3;
section.dataLength = 0;
- events[0].set<DemuxFilterEvent::Tag::section>(section);
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(std::move(section)));
}
void Filter::createPesEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
DemuxFilterPesEvent pes;
pes.streamId = 1;
pes.dataLength = 1;
pes.mpuSequenceNumber = 2;
- events[0].set<DemuxFilterEvent::Tag::pes>(pes);
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(std::move(pes)));
}
void Filter::createDownloadEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
DemuxFilterDownloadEvent download;
download.itemId = 1;
download.mpuSequenceNumber = 2;
@@ -1207,41 +1243,36 @@
download.lastItemFragmentIndex = 4;
download.dataLength = 0;
- events[0].set<DemuxFilterEvent::Tag::download>(download);
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::download>(std::move(download)));
}
void Filter::createIpPayloadEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
DemuxFilterIpPayloadEvent ipPayload;
ipPayload.dataLength = 0;
- events[0].set<DemuxFilterEvent::Tag::ipPayload>(ipPayload);
+ events.push_back(
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::ipPayload>(std::move(ipPayload)));
}
void Filter::createTemiEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
DemuxFilterTemiEvent temi;
temi.pts = 1;
temi.descrTag = 2;
temi.descrData = {3};
- events[0].set<DemuxFilterEvent::Tag::temi>(temi);
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::temi>(std::move(temi)));
}
void Filter::createMonitorEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
DemuxFilterMonitorEvent monitor;
monitor.set<DemuxFilterMonitorEvent::Tag::scramblingStatus>(ScramblingStatus::SCRAMBLED);
- events[0].set<DemuxFilterEvent::Tag::monitorEvent>(monitor);
+
+ events.push_back(
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::monitorEvent>(std::move(monitor)));
}
void Filter::createRestartEvent(vector<DemuxFilterEvent>& events) {
- events.resize(1);
-
- events[0].set<DemuxFilterEvent::Tag::startId>(1);
+ events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::startId>(1));
}
} // namespace tuner
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index 7298561..8388c98 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -77,6 +77,9 @@
void threadLoop();
void threadLoopOnce();
+ // function needs to be called while holding mLock
+ bool isDataSizeDelayConditionMetLocked();
+
static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event);
private:
@@ -84,16 +87,15 @@
std::thread mCallbackThread;
std::atomic<bool> mIsRunning;
- // mLock protects mCallbackBuffer, mCv, and mDataLength
+ // mLock protects mCallbackBuffer, mIsConditionMet, mCv, mDataLength,
+ // mTimeDelayInMs, and mDataSizeDelayInBytes
std::mutex mLock;
std::vector<DemuxFilterEvent> mCallbackBuffer;
+ bool mIsConditionMet;
std::condition_variable mCv;
int mDataLength;
-
- // both of these need to be atomic (not just mTimeDelayInMs) as this class
- // needs to be threadsafe.
- std::atomic<int> mTimeDelayInMs;
- std::atomic<int> mDataSizeDelayInBytes;
+ int mTimeDelayInMs;
+ int mDataSizeDelayInBytes;
};
class Filter : public BnFilter {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index c53adb2..a5acdc1 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -23,6 +23,33 @@
using ::aidl::android::hardware::common::NativeHandle;
+::ndk::ScopedAStatus FilterCallback::onFilterEvent(const vector<DemuxFilterEvent>& events) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ // Temprarily we treat the first coming back filter data on the matching pid a success
+ // once all of the MQ are cleared, means we got all the expected output
+ readFilterEventsData(events);
+ mPidFilterOutputCount++;
+ mMsgCondition.signal();
+
+ // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor
+ // that cannot be copied.
+ for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) {
+ auto it = mFilterEventPromises.find(e.getTag());
+ if (it != mFilterEventPromises.cend()) {
+ it->second.set_value(std::move(e));
+ mFilterEventPromises.erase(it);
+ }
+ }
+
+ return ::ndk::ScopedAStatus::ok();
+}
+
+std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) {
+ // Note: this currently only supports one future per DemuxFilterEvent::Tag.
+ mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>();
+ return mFilterEventPromises[tag].get_future();
+}
+
void FilterCallback::testFilterDataOutput() {
android::Mutex::Autolock autoLock(mMsgLock);
while (mPidFilterOutputCount < 1) {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index c965d95..6258bac 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -24,7 +24,9 @@
#include <log/log.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
+#include <future>
#include <map>
+#include <unordered_map>
#include <fmq/AidlMessageQueue.h>
@@ -58,15 +60,9 @@
class FilterCallback : public BnFilterCallback {
public:
- virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override {
- android::Mutex::Autolock autoLock(mMsgLock);
- // Temprarily we treat the first coming back filter data on the matching pid a success
- // once all of the MQ are cleared, means we got all the expected output
- readFilterEventsData(events);
- mPidFilterOutputCount++;
- mMsgCondition.signal();
- return ::ndk::ScopedAStatus::ok();
- }
+ virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
+
+ std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag);
virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override {
return ::ndk::ScopedAStatus::ok();
@@ -89,6 +85,7 @@
int32_t mFilterId;
std::shared_ptr<IFilter> mFilter;
+ std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises;
native_handle_t* mAvSharedHandle = nullptr;
uint64_t mAvSharedMemSize = -1;
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 85e5c68..88890e4 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -640,6 +640,57 @@
testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
}
+// TODO: move boilerplate into text fixture
+TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) {
+ description("Test filter delay hint.");
+
+ int32_t feId;
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+ int64_t filterId;
+
+ 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);
+
+ const auto& filterConf = filterMap[live.ipFilterId];
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+ ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
+ ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+ ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
+
+ auto filter = mFilterTests.getFilterById(filterId);
+
+ auto delayValue = std::chrono::milliseconds(5000);
+ FilterDelayHint delayHint;
+ delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
+ delayHint.hintValue = delayValue.count();
+
+ auto status = filter->setDelayHint(delayHint);
+ ASSERT_TRUE(status.isOk());
+
+ auto startTime = std::chrono::steady_clock::now();
+ ASSERT_TRUE(mFilterTests.startFilter(filterId));
+
+ auto cb = mFilterTests.getFilterCallbacks().at(filterId);
+ auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload);
+
+ // block and wait for callback to be received.
+ ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready);
+ auto duration = std::chrono::steady_clock::now() - startTime;
+ ASSERT_GE(duration, delayValue);
+
+ // cleanup
+ ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+ ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
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) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 006bf17..5a72ba4 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -52,7 +52,7 @@
const int32_t FMQ_SIZE_4M = 0x400000;
const int32_t FMQ_SIZE_16M = 0x1000000;
-const string configFilePath = "/vendor/etc/tuner_vts_config_1_1.xml";
+const string configFilePath = "/vendor/etc/tuner_vts_config_aidl_V1.xml";
#define FILTER_MAIN_TYPE_BIT_COUNT 5
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 08270d6..7ccf31a 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -956,6 +956,7 @@
}
auto av = filterConfig.getFirstAvFilterSettings_optional();
settings.isPassthrough = av->getIsPassthrough();
+ settings.isSecureMemory = av->getIsSecureMemory();
return settings;
}
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index d026bf9..6c637a4 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -5,9 +5,11 @@
ctor public AvFilterSettings();
method @Nullable public short getAudioStreamType_optional();
method @Nullable public boolean getIsPassthrough();
+ method @Nullable public boolean getIsSecureMemory();
method @Nullable public short getVideoStreamType_optional();
method public void setAudioStreamType_optional(@Nullable short);
method public void setIsPassthrough(@Nullable boolean);
+ method public void setIsSecureMemory(@Nullable boolean);
method public void setVideoStreamType_optional(@Nullable short);
}
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
new file mode 100644
index 0000000..8a6229e
--- /dev/null
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -0,0 +1,159 @@
+<?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.
+ The version section contains a “version” tag in the form “major.minor” e.g. version=”1.0”
+ This shows the tuner dynamic configuration version. -->
+<TunerConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <!-- Hardware Configuration section contains the configurations of all the hardwares
+ that would be used in the tests. In the "dataFlowConfiguration" section, each data flow
+ under test has its required/optional hardwares. The ids configured in the
+ "dataFlowConfiguration" would be used to connect the hardware to each data flow test. -->
+ <hardwareConfiguration>
+ <!-- Frontends section:
+ This section contains configurations of all the frontends that would be used
+ in the tests.
+ - This section is optional and can be skipped to use the default fe settings.
+ - 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"
+ "type": the frontend type. The enums are defined in the xsd.
+ "isSoftwareFrontend": if the test environment is using hardware or software
+ frontend. If using software, a ts input file path needs to be configured.
+ "softwareFeInputPath": used as the source of the software frontend.
+ "connectToCicamId": if the device supports frontend connecting to cicam, the target
+ cicam id needs to be configured here. Supported in Tuner 1.1 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.
+ - This is optional and skipping the settings would pass a setting with frequency
+ config only to the hal.
+ -->
+ <frontends>
+ <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+ connectToCicamId="0" frequency="578000000" endFrequency="800000000">
+ <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+ </frontend>
+ <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
+ connectToCicamId="0" frequency="578000000" endFrequency="800000000">
+ </frontend>
+ </frontends>
+ <!-- Filter section:
+ This section contains configurations of all the filters that would be used in the tests.
+ - This section is optional and can be skipped to use the default filter settings.
+ - The default settings can be found in the sample_tuner_vts_configurations.xml.
+ - 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"
+ "mainType": the main filter type. The enums are defined in the xsd.
+ "subType": the sub filter type. The enums are defined in the xsd.
+ "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
+ configured.
+ - This is optional and skipping the settings would pass a setting with tpid config
+ only to the hal.
+ -->
+ <filters>
+ <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
+ bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+ <avFilterSettings isPassthrough="false" isSecureMemory="false">
+ <audioStreamType>2</audioStreamType>
+ </avFilterSettings>
+ </filter>
+ <filter id="FILTER_VIDEO_DEFAULT" mainType="TS" subType="VIDEO"
+ bufferSize="16777216" pid="256" useFMQ="false" monitorEventTypes="3">
+ <avFilterSettings isPassthrough="false" isSecureMemory="false">
+ <videoStreamType>2</videoStreamType>
+ </avFilterSettings>
+ </filter>
+ <filter id="FILTER_TS_RECORD_0" mainType="TS" subType="RECORD"
+ bufferSize="16777216" pid="257" useFMQ="false">
+ <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
+ </filter>
+ <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+ <ipFilterConfig ipCid="1">
+ <srcIpAddress isIpV4="true" ip="192 168 1 1"/>
+ <destIpAddress isIpV4="true" ip="192 168 1 1"/>
+ </ipFilterConfig>
+ </filter>
+ </filters>
+ <!-- Dvr section:
+ 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"
+ "type": the dvr type.
+ "bufferSize": the dvr buffer size.
+ "statusMask": register callbacks of specific status.
+ "lowThreshold": the dvr status low threshold.
+ "highThreshold": the dvr status high threshold.
+ "dataFormat": the dvr data format.
+ "packetSize": the dvr packet size.
+ "inputFilePath": the dvr playback input file path. Only required in playback dvr.
+ -->
+ <dvrs>
+ <dvr id="DVR_PLAYBACK_0" type="PLAYBACK" bufferSize="4194304"
+ statusMask="15" lowThreshold="4096" highThreshold="32767"
+ dataFormat="TS" packetSize="188" inputFilePath="/data/local/tmp/segment000000.ts"/>
+ <dvr id="DVR_RECORD_0" type="RECORD" bufferSize="4194304"
+ statusMask="15" lowThreshold="4096" highThreshold="32767"
+ dataFormat="TS" packetSize="188"/>
+ <dvr id="DVR_PLAYBACK_1" type="PLAYBACK" bufferSize="4194304"
+ statusMask="15" lowThreshold="4096" highThreshold="32767"
+ dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
+ </dvrs>
+ </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>
+ <clearLiveBroadcast frontendConnection="FE_DEFAULT"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ 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"/>
+ </dataFlowConfiguration>
+</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 6a04b7e..fc2827f 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -191,7 +191,7 @@
<xs:enumeration value="IP"/>
<xs:enumeration value="NTP"/>
<xs:enumeration value="IP_PAYLOAD"/>
- <xs:enumeration value="PAYLOAD_THROUGH"/>
+ <xs:enumeration value="PAYLOAD_THROUGH"/>
</xs:restriction>
</xs:simpleType>
@@ -220,6 +220,7 @@
<xs:element name="videoStreamType" type="xs:unsignedByte"/>
</xs:choice>
<xs:attribute name="isPassthrough" type="xs:boolean" use="required"/>
+ <xs:attribute name="isSecureMemory" type="xs:boolean" use="required"/>
</xs:complexType>
<xs:complexType name="sectionFilterSettings">
<xs:attribute name="isCheckCrc" type="xs:boolean" use="required"/>
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 5f56fe0..4bed2c7 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -21,11 +21,21 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+filegroup {
+ name: "android.hardware.usb@1.0-service.xml",
+ srcs: ["android.hardware.usb@1.0-service.xml"],
+}
+
+filegroup {
+ name: "android.hardware.usb@1.0-service.rc",
+ srcs: ["android.hardware.usb@1.0-service.rc"],
+}
+
cc_binary {
name: "android.hardware.usb@1.0-service",
defaults: ["hidl_defaults"],
- init_rc: ["android.hardware.usb@1.0-service.rc"],
- vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
+ init_rc: [":android.hardware.usb@1.0-service.rc"],
+ vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
relative_install_path: "hw",
vendor: true,
srcs: [
diff --git a/usb/1.0/default/apex/Android.bp b/usb/1.0/default/apex/Android.bp
new file mode 100644
index 0000000..ee50fdf
--- /dev/null
+++ b/usb/1.0/default/apex/Android.bp
@@ -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 {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+ name: "com.android.hardware.usb.key",
+ public_key: "com.android.hardware.usb.avbpubkey",
+ private_key: "com.android.hardware.usb.pem",
+}
+
+android_app_certificate {
+ name: "com.android.hardware.usb.certificate",
+ certificate: "com.android.hardware.usb",
+}
+
+genrule {
+ name: "com.android.hardware.usb.rc-gen",
+ srcs: [":android.hardware.usb@1.0-service.rc"],
+ out: ["com.android.hardware.usb.rc"],
+ cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+ name: "com.android.hardware.usb.rc",
+ src: ":com.android.hardware.usb.rc-gen",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.usb",
+ manifest: "manifest.json",
+ file_contexts: "file_contexts",
+ key: "com.android.hardware.usb.key",
+ certificate: ":com.android.hardware.usb.certificate",
+ updatable: false,
+ soc_specific: true,
+ use_vndk_as_stable: true,
+ binaries: ["android.hardware.usb@1.0-service"],
+ prebuilts: [
+ "com.android.hardware.usb.rc",
+ "android.hardware.usb.accessory.prebuilt.xml",
+ "android.hardware.usb.host.prebuilt.xml",
+ ],
+ vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+}
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
new file mode 100644
index 0000000..0302d63
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pem b/usb/1.0/default/apex/com.android.hardware.usb.pem
new file mode 100644
index 0000000..e1e57da
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAwdimmHgIZHrep3H3YfVaNYEAGg45LUEPIiwHV6aIC9V7zjBS
+SftD30Z21jGyk7hmtas6WMI2vRBDNGrZWDgPeiEQoxXQinuU4Ug5S5X2F8LpWs0y
+ZeNFwQkqZwqGdQlkmy8upfb6T7rDxqRv+C0AtGP1r4r36+Xh5ld5stVaMK0UNhZt
+VW0nQAxyeJL3tm0zfiEA9Zu7FF2IyHm+bo9+eJ7WXfjiJfkclLgqlX3ec2cvVqAf
+NHisj18PEd/qtC64b+FnkgbsdHzWbo8HW5x4STkGXNnH+O3dvkWBX60MOfywfZFw
++yaz5mt7K+ft/V4UA7zKiAEFM+J1lND9/UMJnd0XMYYtcRQF8lmu4dlcjfbbAm0k
+VgoUEsizIeMPLrMj837uVloKKzIXmPsVsfMarP/MrX6TJfzdUhdm01pVO1g0wtHJ
+J3eYQsEnOI7RjL+uZDQvPWAnr71pvacn66PAJC1UPulEEla5lhd30RDItbJkngXp
+3UggW32ZOQt3Oc8P0eo9SCnBlHtCVr8wfxAbxCoPR9qIdX3azkQRqcKqGbBbPnkc
+hSCzeIofUkYGibfbZg4k1yY82xEqZuN7J1zycoGP4wyhXeRLTRWxfPR5dxxmQZaS
+67A1LWrYvAzF8Rd44VMRlI/Qk6zuBsL01j2dfBqit+le+viQmTYb3BpV+1kCAwEA
+AQKCAgAmSfX2LddyiXaLWo6DsePkp5tuihqvHqevl0TIAmPi+oMe4hqO9GueoZt9
+iYl9djILdkvrFkmbpKexpd1SeJhOBlPz8q4jfG+W5B41GOToIp7XSarHx1GS5I2U
+ltaiLX3KzVIIhDVDJF/hT7+yJKl7+DaiOu/nj5vEVMj8EvpinP1eBaYI9quHEi5W
+NKlrRjyikEBRQzZ7ulH3T1zXF87iYnVzUGLTH1aO5aW7q4YSA3KtSKmBQsjK9PrU
+DAefGY9iwgIkLOvtwm7UnbnVVZ3I0NO56WZ/e/SNzcrVLCg7F/eAhgbsBOQKAnbs
+4D35CuknJ9ZVcOYnLncNMw7IRMKULKYLAuLLN1X33y22qaVxYA42rq13mZrijlua
+CMQ2Ur+GNcq8OI3mRDO38yKeJ5b4885LQdlrXXyoGnSjlkU5n8U9Jw6q2rZGiWlk
+4Q71g+KUl0rtXSnFSIJLNTK6Cd3ETStxswLvvCvfLTrRQcO8f2SdVxblmsc9eCDs
+JUxz6Sahkpb9hsY8fozu6laXC/5Ezy0TinRgGjQM/DQqbXtFXgse56mDxzSho5oh
+Spy3X7Q/v4VUtrSKsEZEIEVWCpplzVULpHenCDbU58rHyEcS7ew+kwlfHC73iEhX
+HPujSIKvStO7yCEeY6IdhON8iVX34uvQeAgEe4+rehQHLZUg0QKCAQEA9AS3imKF
+yEt0yNRLcdXSqYkak+OM2kfhBBcLndCT7Terr6yluv/SkPGYjUbmr2XiygMv8IwO
+8f+KbWsNwYCaB22HVYVGL0oUYAlCvWhnia3Iwn6ZZuXuJv5mmfqt/GMlaIfohNLy
+zI2OlcpcAuRfNlenjNyd+inxwdXL28Z86kbabnUlijgqpu4KFOYOlxbTRv93IlfM
+Ico1pZkLS1glDMFLetF+IWq4zqpXrdgNUk1KX3sofOCfZQnlWFrrHbXJPCgPAtlv
+xP4dmJQgtWkWwxUlelfz34LcCUVX2aTlgKjuvgvyCt2ZPWixXbDtjsCBTn3xBhoY
+kDp2OyMC+d543QKCAQEAy11GpYOQvTMKbV07EmN9jTRYg7gRrxsT3Kd4Xy+NpIY8
+v6J5Keeppk9t6WBrJi2cQU/EoHcd3fRkWMnWMNorZDiCu34VG5bfa4pTqnSLdLC4
+/e5UHdHqCy9deAwhlHYWbAx0KnxXWGxkq05dXvQsVuOtAs528NcujnLpwDONQt5P
+e3RIZmOOjr+7rqGp3vA9SuNOINOQpeKxQT6GRGw4mlYofdwOPaE1wCsO8vQCNmCJ
+DEfdm+hWjTLAV2IBCfi5BKRsIAXrABPzkzDeLGDmaQkJTDpK8UQcrFnqItGeo+yl
+fDjxA0zAPWYGcyXcXbtvayX+zCk/SKwQABqUtaumrQKCAQEA0mdizwsGqd8OMsCC
+0QP64j4a0Zvqbqh9yCYK2Sfo9SkEe7SVLnm5WUtIK8EP1fs3ItK+ul454MZj2Nbv
+BINbzL3PbJk/HDV2/hveFS154UgcjD/XC9eEktDXLTvuW2ot7kUJ48V0n5YLdPMI
+hWHfCx9nlFkCSptyHp23aqhqOyOe4pFWLikh9c/Yl46K1BJVWKmcUtt7Y0NVIJWn
+HG9Dew0MhTkv1aaM9X4Bnh9l1SpZz5yFG7AfIGL5A0dZ5cNCYgF0eBN+gVBPuqk2
+ztVvUATizOwblwThr4jAKCU70sVXHj10lZPftwiXrt6I54brt/92HLnRpkMSgQk+
+Xq9KbQKCAQAXxPM47UPBmXGijr8UyyQlmPSvkJggi12q8LgVCA3aKQZ4r5jR2Q3v
+LmF+YZKkh7g3ugcValbHVoVUC2NJmnZv5FsDZx04eE3s1+Inji+ul+lHZM/YHGzq
+mcKnAWP7YkIEpv/850OeRi0OCL7JFmkITtwt88vbIouCgtPnbx8XrbxEhbbgoMpM
+zQQ2yRZ9xD6lviOnmpLRkMl/ArvWy39iKqfY7huMAIezylSY+QQ5LtdV5CB21JUp
+M8FfdUkBzVxyunUY2Rg6jhpuHcwaC8lihXfcvQN9Z6SiUHAZWb7dEg/VkSI6bIIb
+qw0d8FLtcbb4IxzA6CFJcTL9kB3JjiKRAoIBAQC15t3mQHb9iCM4P4U9fpR4syvN
+46vDMhtj3vejerzOro2R7UUCJDvT59DrCQvtKO/ZCyhdTyuyResu6r1vbwq3KWiB
+i0RIeW87cKgJRr6w+KivB+a805WfI9zNRz778b7ajEpBkOs4vRPWu6S1306tdvgM
+Dhj7GT9UFh/k7pNuoSbiuaPUqgZRP55nzgj/FoIN985wnxo/ugckSqZ1bFGFXhYt
+zfIdFvPkf1BlLCnLTE8yESsJ3P37Gfj2XRv9h2I2/8qAGZniKtbVWHlu+5LDJf6V
+x9VpDAH2ZQAqRC3za3gfTjMsglYi7mUDeMYlB4osURNt7jDtElEmsto7AAkI
+-----END RSA PRIVATE KEY-----
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pk8 b/usb/1.0/default/apex/com.android.hardware.usb.pk8
new file mode 100644
index 0000000..9f3f39b
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pk8
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.x509.pem b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
new file mode 100644
index 0000000..210c30d
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF1TCCA70CFFEdsyLGoTRk+VIzqb6aDl1tXeuZMA0GCSqGSIb3DQEBCwUAMIGl
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEhMB8GA1UEAwwYY29t
+LmFuZHJvaWQuaGFyZHdhcmUudXNiMCAXDTIxMTExNzIyMzAwM1oYDzQ3NTkxMDE0
+MjIzMDAzWjCBpTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAU
+BgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsM
+B0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb20xITAf
+BgNVBAMMGGNvbS5hbmRyb2lkLmhhcmR3YXJlLnVzYjCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAM2E0E9ubNU/or7r9UIcFrC4l7CeM0HwtwSjTUKV1Z9K
+7rPFoUPE3cQ+cResnWQay8IGnomLYptAIMe8sLCC83LwU1ucTihxX87qq2W3V14w
+U4AkqDzNvYqKiD3yz9WofKxcu7ut8+1O4Pvp11X8UXuy5kNzf8WGpGB04k6U6KtA
+q8+U8+4h9h1Uvhaa0AeG9Yp22LzRLTb3J+eCoGHJnjoXYsd9T/gvedyXKkuf0lWB
+b3Aor3/CQrpdCW2/iJbuASdBdfilpQShaagxy2wmQsYxnT8ZWf+tIDYjg3xqqVPl
+GChFwCQBdaTuLI/k9gbaXkSxuzRkp5wc/ELhYbkhIS25yefAF2C6num++AHQBh1+
+qO0fHztsK80c5cVoDPWu17/nP7y3QloRyLFUrL3hVW1RQaFwE2Hmv4H0UwVAsleU
+ZIsz2ifTjiSl/tnkFTx0I6BVk7T87QhO3WXN4v6VDYZKeD4gQYS0NfwplahejrFw
+s3EcwKgt6f0KlIpzoEQBmNQBXxsRgL31GWCwCszb7+VrTMzgUpO41R3PyewbeaZk
+S/SHyEOwyf0WIvnZhZ/5CNd9qirClu6jS8kdLvwC2qA25VqSPw126EX1e2xUqm02
+C/6c7JDVocuQhvsJOnnpZt68Iwgw9g/xLCLA9RszH9ccRctZqRnzHB1AjTrBOq0P
+AgMBAAEwDQYJKoZIhvcNAQELBQADggIBAELbSot2Io/JZIYLTxgeReI4lk1KUzf8
+fGlDNlRm+goxOHXWQgvXgiftwM9IOB+H+EtNHAA9Q6ojAmfRe6rZC4p0ZxWOamtR
+V+pQj0c6Zvx8HJPMQdyoHx538iNXM093s2wnf+QuACb3BnvkK7uuLGAlIzWdImtL
+DKKFN05nppViY04tGP5HgT57b7YGwdkEp6euCJcyWIKjlyEH/bwTWM8ws/Px6uhw
++5W2K7KrBsdRKPBF7qwXoS8Ak8pS5de9Xd7mbGBLaUtjsZ0pJbq0aFpuT0GbLWUm
+wiD5Ljq3ea/2GZxbHGiXQ2yNjFSd/jpuxDnnm99t7+HGw1v5Jld+hUVqXXfVNhWe
+hUKIv5TOk1nttNdsaLyDtxyt22JX7NnoPM0MqrkYwA8Xqrbv0VC8D/CVjiBC9Tce
+crhpCISNfQSkdEn/c+q/naFUvQy8oYqXkg1TjeGlcxwJOpGliYbbYT6VAwuI/ssI
+yX3Fkr8f5KhfN2aFnOpidknmLp9EyL2j5bxAtSD9xAHtczMn10uCUdLELjRB1L4f
+1qY+EjpIgK0NIFuEt9K5uZXirXq3K3eixKeJFNji3x/X8NgDALSdnT8JIlSg4DMg
+iWupLrQ9CSHMlgh5P43ALamiRIHQNqEwgj8OIGzsvQTSLbRjbPWYcDZa+Q1hosiA
+Fv7vjDI6oySM
+-----END CERTIFICATE-----
diff --git a/usb/1.0/default/apex/file_contexts b/usb/1.0/default/apex/file_contexts
new file mode 100644
index 0000000..bc84ac4
--- /dev/null
+++ b/usb/1.0/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
+# binary
+/bin/hw/android\.hardware\.usb@1\.0-service u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/1.0/default/apex/manifest.json b/usb/1.0/default/apex/manifest.json
new file mode 100644
index 0000000..6a1095f
--- /dev/null
+++ b/usb/1.0/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.usb",
+ "version": 1
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 774133e..7e3be56 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -35,4 +35,5 @@
@Backing(type="long") @VintfStability
enum UwbAndroidCapabilities {
POWER_STATS_QUERY = 1,
+ ANTENNAE_INTERLEAVING = 2,
}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index 4e3d4a2..cd2e122 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -35,4 +35,5 @@
@Backing(type="byte") @VintfStability
enum UwbVendorGidAndroidOids {
ANDROID_GET_POWER_STATS = 0,
+ ANDROID_SET_COUNTRY_CODE = 1,
}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 37b7efb..f449c60 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -38,4 +38,7 @@
CCC_UWB_CONFIG_ID = 164,
CCC_PULSESHAPE_COMBO = 165,
CCC_URSK_TTL = 166,
+ NB_OF_RANGE_MEASUREMENTS = 227,
+ NB_OF_AZIMUTH_MEASUREMENTS = 228,
+ NB_OF_ELEVATION_MEASUREMENTS = 229,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 3486d5a..0af99e0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -26,6 +26,6 @@
@VintfStability
@Backing(type="long")
enum UwbAndroidCapabilities {
- /** TODO: Change the name if necessary when the corresponding vendor commands are added */
POWER_STATS_QUERY = 0x1,
+ ANTENNAE_INTERLEAVING = 0x2,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index de4a2d8..1dfcd6f 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -27,4 +27,7 @@
// Supported only if the value returned by getSupportedAndroidCapabilities()
// has the bit of UwbAndroidCapabilities.POWER_STATS_QUERY set to 1.
ANDROID_GET_POWER_STATS = 0x0,
+ // Used to set the current regulatory country code (determined usinag
+ // SIM or hardcoded by OEM).
+ ANDROID_SET_COUNTRY_CODE = 0x1,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 850e2da..f5e02c0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -29,9 +29,29 @@
enum UwbVendorSessionSetAppConfigCmdParams {
/** CCC params for ranging start */
- /** Added in vendor version 0. */
+ /**
+ * Added in vendor version 0.
+ * Range 0xA0 - 0xDF reserved for CCC use.
+ */
CCC_RANGING_PROTOCOL_VER = 0xA3,
CCC_UWB_CONFIG_ID = 0xA4,
CCC_PULSESHAPE_COMBO = 0xA5,
CCC_URSK_TTL = 0xA6,
+
+ /**
+ * Range 0xE3 - 0xFF is reserved for proprietary use in the FIRA spec.
+ * In Android, this range is reserved by the Android platform for Android-specific
+ * app config cmd params.
+ * Vendors must not define additional app config cmd params in this range.
+ */
+
+ /**
+ * Added in vendor version 0.
+ * Interleaving ratio if AOA_RESULT_REQ is set to 0xF0.
+ * Supported only if the value returned by getSupportedAndroidCapabilities()
+ * has the bit of UwbAndroidCapabilities.ANTENNAE_INTERLEAVING set to 1.
+ */
+ NB_OF_RANGE_MEASUREMENTS = 0xE3,
+ NB_OF_AZIMUTH_MEASUREMENTS = 0xE4,
+ NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
}
diff --git a/wifi/.clang-format b/wifi/.clang-format
deleted file mode 100644
index 25ed932..0000000
--- a/wifi/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-IndentWidth: 4
\ No newline at end of file