Merge "wifi/supplicant: Add SHA256 key management definition"
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 8e0b763..bec22df 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -137,12 +137,11 @@
return Void();
}
-Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
- const AudioConfig& config, AudioOutputFlagBitfield flags,
-#if MAJOR_VERSION >= 4
- const SourceMetadata& /* sourceMetadata */,
-#endif
- openOutputStream_cb _hidl_cb) {
+std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle,
+ const DeviceAddress& device,
+ const AudioConfig& config,
+ AudioOutputFlagBitfield flags,
+ AudioConfig* suggestedConfig) {
audio_config_t halConfig;
HidlUtils::audioConfigToHal(config, &halConfig);
audio_stream_out_t* halStream;
@@ -161,16 +160,13 @@
if (status == OK) {
streamOut = new StreamOut(this, halStream);
}
- AudioConfig suggestedConfig;
- HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
- _hidl_cb(analyzeStatus("open_output_stream", status, {EINVAL} /* ignore */), streamOut,
- suggestedConfig);
- return Void();
+ HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
}
-Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
- const AudioConfig& config, AudioInputFlagBitfield flags,
- AudioSource source, openInputStream_cb _hidl_cb) {
+std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+ AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) {
audio_config_t halConfig;
HidlUtils::audioConfigToHal(config, &halConfig);
audio_stream_in_t* halStream;
@@ -190,14 +186,46 @@
if (status == OK) {
streamIn = new StreamIn(this, halStream);
}
+ HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+ return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
+}
+
+#if MAJOR_VERSION == 2
+Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioOutputFlagBitfield flags,
+ openOutputStream_cb _hidl_cb) {
AudioConfig suggestedConfig;
- HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig);
- _hidl_cb(analyzeStatus("open_input_stream", status, {EINVAL} /* ignore */), streamIn,
- suggestedConfig);
+ auto [result, streamOut] =
+ openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
+ _hidl_cb(result, streamOut, suggestedConfig);
return Void();
}
-#if MAJOR_VERSION >= 4
+Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioInputFlagBitfield flags,
+ AudioSource source, openInputStream_cb _hidl_cb) {
+ AudioConfig suggestedConfig;
+ auto [result, streamIn] =
+ openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
+ _hidl_cb(result, streamIn, suggestedConfig);
+ return Void();
+}
+
+#elif MAJOR_VERSION >= 4
+Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioOutputFlagBitfield flags,
+ const SourceMetadata& sourceMetadata,
+ openOutputStream_cb _hidl_cb) {
+ AudioConfig suggestedConfig;
+ auto [result, streamOut] =
+ openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig);
+ if (streamOut) {
+ streamOut->updateSourceMetadata(sourceMetadata);
+ }
+ _hidl_cb(result, streamOut, suggestedConfig);
+ return Void();
+}
+
Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
const AudioConfig& config, AudioInputFlagBitfield flags,
const SinkMetadata& sinkMetadata,
@@ -209,11 +237,18 @@
_hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig());
return Void();
}
- // Pick the first one as the main until the legacy API is update
+ // Pick the first one as the main.
AudioSource source = sinkMetadata.tracks[0].source;
- return openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
+ AudioConfig suggestedConfig;
+ auto [result, streamIn] =
+ openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig);
+ if (streamIn) {
+ streamIn->updateSinkMetadata(sinkMetadata);
+ }
+ _hidl_cb(result, streamIn, suggestedConfig);
+ return Void();
}
-#endif
+#endif /* MAJOR_VERSION */
Return<bool> Device::supportsAudioPatches() {
return version() >= AUDIO_DEVICE_API_VERSION_3_0;
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index ac7c2cb..0014022 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -454,8 +454,19 @@
std::vector<record_track_metadata> halTracks;
halTracks.reserve(sinkMetadata.tracks.size());
for (auto& metadata : sinkMetadata.tracks) {
- halTracks.push_back(
- {.source = static_cast<audio_source_t>(metadata.source), .gain = metadata.gain});
+ record_track_metadata halTrackMetadata = {
+ .source = static_cast<audio_source_t>(metadata.source), .gain = metadata.gain};
+#if MAJOR_VERSION >= 5
+ if (metadata.destination.getDiscriminator() ==
+ RecordTrackMetadata::Destination::hidl_discriminator::device) {
+ halTrackMetadata.dest_device =
+ static_cast<audio_devices_t>(metadata.destination.device().device);
+ strncpy(halTrackMetadata.dest_device_address,
+ deviceAddressToHal(metadata.destination.device()).c_str(),
+ AUDIO_DEVICE_MAX_ADDRESS_LEN);
+ }
+#endif
+ halTracks.push_back(halTrackMetadata);
}
const sink_metadata_t halMetadata = {
.track_count = halTracks.size(),
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index 836259f..e64f00f 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -62,14 +62,21 @@
Return<void> getInputBufferSize(const AudioConfig& config,
getInputBufferSize_cb _hidl_cb) override;
- // V2 openInputStream is called by V4 input stream thus present in both versions
- Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device,
- const AudioConfig& config, AudioInputFlagBitfield flags,
- AudioSource source, openInputStream_cb _hidl_cb);
+ std::tuple<Result, sp<IStreamOut>> openOutputStreamImpl(int32_t ioHandle,
+ const DeviceAddress& device,
+ const AudioConfig& config,
+ AudioOutputFlagBitfield flags,
+ AudioConfig* suggestedConfig);
+ std::tuple<Result, sp<IStreamIn>> openInputStreamImpl(
+ int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
+ AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig);
#if MAJOR_VERSION == 2
Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
const AudioConfig& config, AudioOutputFlagBitfield flags,
openOutputStream_cb _hidl_cb) override;
+ Return<void> openInputStream(int32_t ioHandle, const DeviceAddress& device,
+ const AudioConfig& config, AudioInputFlagBitfield flags,
+ AudioSource source, openInputStream_cb _hidl_cb) override;
#elif MAJOR_VERSION >= 4
Return<void> openOutputStream(int32_t ioHandle, const DeviceAddress& device,
const AudioConfig& config, AudioOutputFlagBitfield flags,
diff --git a/audio/effect/5.0/xml/Android.bp b/audio/effect/5.0/xml/Android.bp
new file mode 100644
index 0000000..967135c
--- /dev/null
+++ b/audio/effect/5.0/xml/Android.bp
@@ -0,0 +1,6 @@
+
+xsd_config {
+ name: "audio_effects_conf",
+ srcs: ["audio_effects_conf.xsd"],
+ package_name: "audio.effects.V5_0",
+}
diff --git a/audio/effect/5.0/xml/api/current.txt b/audio/effect/5.0/xml/api/current.txt
new file mode 100644
index 0000000..294501d
--- /dev/null
+++ b/audio/effect/5.0/xml/api/current.txt
@@ -0,0 +1,136 @@
+package audio.effects.V5_0 {
+
+ public class Audioeffectsconf {
+ ctor public Audioeffectsconf();
+ method public audio.effects.V5_0.EffectsType getEffects();
+ method public audio.effects.V5_0.LibrariesType getLibraries();
+ method public audio.effects.V5_0.Audioeffectsconf.Postprocess getPostprocess();
+ method public audio.effects.V5_0.Audioeffectsconf.Preprocess getPreprocess();
+ method public audio.effects.V5_0.VersionType getVersion();
+ method public void setEffects(audio.effects.V5_0.EffectsType);
+ method public void setLibraries(audio.effects.V5_0.LibrariesType);
+ method public void setPostprocess(audio.effects.V5_0.Audioeffectsconf.Postprocess);
+ method public void setPreprocess(audio.effects.V5_0.Audioeffectsconf.Preprocess);
+ method public void setVersion(audio.effects.V5_0.VersionType);
+ }
+
+ public static class Audioeffectsconf.Postprocess {
+ ctor public Audioeffectsconf.Postprocess();
+ method public java.util.List<audio.effects.V5_0.StreamPostprocessType> getStream();
+ }
+
+ public static class Audioeffectsconf.Preprocess {
+ ctor public Audioeffectsconf.Preprocess();
+ method public java.util.List<audio.effects.V5_0.StreamPreprocessType> getStream();
+ }
+
+ public class EffectImplType {
+ ctor public EffectImplType();
+ method public java.lang.String getLibrary();
+ method public java.lang.String getUuid();
+ method public void setLibrary(java.lang.String);
+ method public void setUuid(java.lang.String);
+ }
+
+ public class EffectProxyType extends audio.effects.V5_0.EffectType {
+ ctor public EffectProxyType();
+ method public audio.effects.V5_0.EffectImplType getLibhw();
+ method public audio.effects.V5_0.EffectImplType getLibsw();
+ method public void setLibhw(audio.effects.V5_0.EffectImplType);
+ method public void setLibsw(audio.effects.V5_0.EffectImplType);
+ }
+
+ public class EffectType extends audio.effects.V5_0.EffectImplType {
+ ctor public EffectType();
+ method public java.lang.String getName();
+ method public void setName(java.lang.String);
+ }
+
+ public class EffectsType {
+ ctor public EffectsType();
+ method public java.util.List<audio.effects.V5_0.EffectProxyType> getEffectProxy_optional();
+ method public java.util.List<audio.effects.V5_0.EffectType> getEffect_optional();
+ }
+
+ public class LibrariesType {
+ ctor public LibrariesType();
+ method public java.util.List<audio.effects.V5_0.LibrariesType.Library> getLibrary();
+ }
+
+ public static class LibrariesType.Library {
+ ctor public LibrariesType.Library();
+ method public java.lang.String getName();
+ method public java.lang.String getPath();
+ method public void setName(java.lang.String);
+ method public void setPath(java.lang.String);
+ }
+
+ public final class StreamInputType extends java.lang.Enum {
+ method public java.lang.String getRawName();
+ method public static audio.effects.V5_0.StreamInputType valueOf(java.lang.String);
+ method public static final audio.effects.V5_0.StreamInputType[] values();
+ enum_constant public static final audio.effects.V5_0.StreamInputType camcorder;
+ enum_constant public static final audio.effects.V5_0.StreamInputType mic;
+ enum_constant public static final audio.effects.V5_0.StreamInputType unprocessed;
+ enum_constant public static final audio.effects.V5_0.StreamInputType voice_call;
+ enum_constant public static final audio.effects.V5_0.StreamInputType voice_communication;
+ enum_constant public static final audio.effects.V5_0.StreamInputType voice_downlink;
+ enum_constant public static final audio.effects.V5_0.StreamInputType voice_recognition;
+ enum_constant public static final audio.effects.V5_0.StreamInputType voice_uplink;
+ }
+
+ public final class StreamOutputType extends java.lang.Enum {
+ method public java.lang.String getRawName();
+ method public static audio.effects.V5_0.StreamOutputType valueOf(java.lang.String);
+ method public static final audio.effects.V5_0.StreamOutputType[] values();
+ enum_constant public static final audio.effects.V5_0.StreamOutputType alarm;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType bluetooth_sco;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType dtmf;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType enforced_audible;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType music;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType notification;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType ring;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType system;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType tts;
+ enum_constant public static final audio.effects.V5_0.StreamOutputType voice_call;
+ }
+
+ public class StreamPostprocessType extends audio.effects.V5_0.StreamProcessingType {
+ ctor public StreamPostprocessType();
+ method public audio.effects.V5_0.StreamOutputType getType();
+ method public void setType(audio.effects.V5_0.StreamOutputType);
+ }
+
+ public class StreamPreprocessType extends audio.effects.V5_0.StreamProcessingType {
+ ctor public StreamPreprocessType();
+ method public audio.effects.V5_0.StreamInputType getType();
+ method public void setType(audio.effects.V5_0.StreamInputType);
+ }
+
+ public class StreamProcessingType {
+ ctor public StreamProcessingType();
+ method public java.util.List<audio.effects.V5_0.StreamProcessingType.Apply> getApply();
+ }
+
+ public static class StreamProcessingType.Apply {
+ ctor public StreamProcessingType.Apply();
+ method public java.lang.String getEffect();
+ method public void setEffect(java.lang.String);
+ }
+
+ public final class VersionType extends java.lang.Enum {
+ method public java.lang.String getRawName();
+ method public static audio.effects.V5_0.VersionType valueOf(java.lang.String);
+ method public static final audio.effects.V5_0.VersionType[] values();
+ enum_constant public static final audio.effects.V5_0.VersionType _2_0;
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static audio.effects.V5_0.Audioeffectsconf read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static java.lang.String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/audio/effect/5.0/xml/api/last_current.txt b/audio/effect/5.0/xml/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/effect/5.0/xml/api/last_current.txt
diff --git a/audio/effect/5.0/xml/api/last_removed.txt b/audio/effect/5.0/xml/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/effect/5.0/xml/api/last_removed.txt
diff --git a/audio/effect/5.0/xml/api/removed.txt b/audio/effect/5.0/xml/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/audio/effect/5.0/xml/api/removed.txt
diff --git a/camera/common/1.0/default/VendorTagDescriptor.cpp b/camera/common/1.0/default/VendorTagDescriptor.cpp
index 052bf5b..d2bee85 100644
--- a/camera/common/1.0/default/VendorTagDescriptor.cpp
+++ b/camera/common/1.0/default/VendorTagDescriptor.cpp
@@ -176,6 +176,93 @@
}
+int VendorTagDescriptorCache::getTagCount(metadata_vendor_id_t id) const {
+ int ret = 0;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getTagCount();
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+void VendorTagDescriptorCache::getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const {
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ desc->second->getTagArray(tagArray);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+}
+
+const char* VendorTagDescriptorCache::getSectionName(uint32_t tag, metadata_vendor_id_t id) const {
+ const char* ret = nullptr;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getSectionName(tag);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+const char* VendorTagDescriptorCache::getTagName(uint32_t tag, metadata_vendor_id_t id) const {
+ const char* ret = nullptr;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getTagName(tag);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+int VendorTagDescriptorCache::getTagType(uint32_t tag, metadata_vendor_id_t id) const {
+ int ret = 0;
+ auto desc = mVendorMap.find(id);
+ if (desc != mVendorMap.end()) {
+ ret = desc->second->getTagType(tag);
+ } else {
+ ALOGE("%s: Vendor descriptor id is missing!", __func__);
+ }
+
+ return ret;
+}
+
+void VendorTagDescriptorCache::dump(int fd, int verbosity, int indentation) const {
+ for (const auto& desc : mVendorMap) {
+ desc.second->dump(fd, verbosity, indentation);
+ }
+}
+
+int32_t VendorTagDescriptorCache::addVendorDescriptor(
+ metadata_vendor_id_t id, sp<hardware::camera::common::V1_0::helper::VendorTagDescriptor> desc) {
+ auto entry = mVendorMap.find(id);
+ if (entry != mVendorMap.end()) {
+ ALOGE("%s: Vendor descriptor with same id already present!", __func__);
+ return BAD_VALUE;
+ }
+
+ mVendorMap.emplace(id, desc);
+ return NO_ERROR;
+}
+
+int32_t VendorTagDescriptorCache::getVendorTagDescriptor(
+ metadata_vendor_id_t id,
+ sp<hardware::camera::common::V1_0::helper::VendorTagDescriptor>* desc /*out*/) {
+ auto entry = mVendorMap.find(id);
+ if (entry == mVendorMap.end()) {
+ return NAME_NOT_FOUND;
+ }
+
+ *desc = entry->second;
+
+ return NO_ERROR;
+}
} // namespace params
} // namespace camera2
@@ -192,10 +279,17 @@
static const char* vendor_tag_descriptor_get_tag_name(const vendor_tag_ops_t* v, uint32_t tag);
static int vendor_tag_descriptor_get_tag_type(const vendor_tag_ops_t* v, uint32_t tag);
+static int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id);
+static void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id);
+static const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag,
+ metadata_vendor_id_t id);
+static const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id);
+static int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id);
} /* extern "C" */
static Mutex sLock;
static sp<VendorTagDescriptor> sGlobalVendorTagDescriptor;
+static sp<VendorTagDescriptorCache> sGlobalVendorTagDescriptorCache;
status_t VendorTagDescriptor::createDescriptorFromOps(const vendor_tag_ops_t* vOps,
/*out*/
@@ -310,6 +404,39 @@
return sGlobalVendorTagDescriptor;
}
+status_t VendorTagDescriptorCache::setAsGlobalVendorTagCache(
+ const sp<VendorTagDescriptorCache>& cache) {
+ status_t res = OK;
+ Mutex::Autolock al(sLock);
+ sGlobalVendorTagDescriptorCache = cache;
+
+ struct vendor_tag_cache_ops* opsPtr = NULL;
+ if (cache != NULL) {
+ opsPtr = &(cache->mVendorCacheOps);
+ opsPtr->get_tag_count = vendor_tag_descriptor_cache_get_tag_count;
+ opsPtr->get_all_tags = vendor_tag_descriptor_cache_get_all_tags;
+ opsPtr->get_section_name = vendor_tag_descriptor_cache_get_section_name;
+ opsPtr->get_tag_name = vendor_tag_descriptor_cache_get_tag_name;
+ opsPtr->get_tag_type = vendor_tag_descriptor_cache_get_tag_type;
+ }
+ if ((res = set_camera_metadata_vendor_cache_ops(opsPtr)) != OK) {
+ ALOGE("%s: Could not set vendor tag cache, received error %s (%d).", __FUNCTION__,
+ strerror(-res), res);
+ }
+ return res;
+}
+
+void VendorTagDescriptorCache::clearGlobalVendorTagCache() {
+ Mutex::Autolock al(sLock);
+ set_camera_metadata_vendor_cache_ops(NULL);
+ sGlobalVendorTagDescriptorCache.clear();
+}
+
+sp<VendorTagDescriptorCache> VendorTagDescriptorCache::getGlobalVendorTagCache() {
+ Mutex::Autolock al(sLock);
+ return sGlobalVendorTagDescriptorCache;
+}
+
extern "C" {
int vendor_tag_descriptor_get_tag_count(const vendor_tag_ops_t* /*v*/) {
@@ -357,6 +484,50 @@
return sGlobalVendorTagDescriptor->getTagType(tag);
}
+int vendor_tag_descriptor_cache_get_tag_count(metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_TAG_COUNT_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getTagCount(id);
+}
+
+void vendor_tag_descriptor_cache_get_all_tags(uint32_t* tagArray, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ }
+ sGlobalVendorTagDescriptorCache->getTagArray(tagArray, id);
+}
+
+const char* vendor_tag_descriptor_cache_get_section_name(uint32_t tag, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_SECTION_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getSectionName(tag, id);
+}
+
+const char* vendor_tag_descriptor_cache_get_tag_name(uint32_t tag, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_TAG_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getTagName(tag, id);
+}
+
+int vendor_tag_descriptor_cache_get_tag_type(uint32_t tag, metadata_vendor_id_t id) {
+ Mutex::Autolock al(sLock);
+ if (sGlobalVendorTagDescriptorCache == NULL) {
+ ALOGE("%s: Vendor tag descriptor cache not initialized.", __FUNCTION__);
+ return VENDOR_TAG_NAME_ERR;
+ }
+ return sGlobalVendorTagDescriptorCache->getTagType(tag, id);
+}
+
} /* extern "C" */
} // namespace helper
diff --git a/camera/common/1.0/default/include/VendorTagDescriptor.h b/camera/common/1.0/default/include/VendorTagDescriptor.h
index a040540..0f54db5 100644
--- a/camera/common/1.0/default/include/VendorTagDescriptor.h
+++ b/camera/common/1.0/default/include/VendorTagDescriptor.h
@@ -157,6 +157,81 @@
};
+} /* namespace helper */
+} /* namespace V1_0 */
+} /* namespace common */
+} /* namespace camera */
+
+namespace camera2 {
+namespace params {
+
+class VendorTagDescriptorCache {
+ public:
+ typedef android::hardware::camera::common::V1_0::helper::VendorTagDescriptor
+ VendorTagDescriptor;
+ VendorTagDescriptorCache(){};
+ int32_t addVendorDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor> desc);
+
+ int32_t getVendorTagDescriptor(metadata_vendor_id_t id, sp<VendorTagDescriptor>* desc /*out*/);
+
+ // Returns the number of vendor tags defined.
+ int getTagCount(metadata_vendor_id_t id) const;
+
+ // Returns an array containing the id's of vendor tags defined.
+ void getTagArray(uint32_t* tagArray, metadata_vendor_id_t id) const;
+
+ // Returns the section name string for a given vendor tag id.
+ const char* getSectionName(uint32_t tag, metadata_vendor_id_t id) const;
+
+ // Returns the tag name string for a given vendor tag id.
+ const char* getTagName(uint32_t tag, metadata_vendor_id_t id) const;
+
+ // Returns the tag type for a given vendor tag id.
+ int getTagType(uint32_t tag, metadata_vendor_id_t id) const;
+
+ /**
+ * Dump the currently configured vendor tags to a file descriptor.
+ */
+ void dump(int fd, int verbosity, int indentation) const;
+
+ protected:
+ std::unordered_map<metadata_vendor_id_t, sp<VendorTagDescriptor>> mVendorMap;
+ struct vendor_tag_cache_ops mVendorCacheOps;
+};
+
+} /* namespace params */
+} /* namespace camera2 */
+
+namespace camera {
+namespace common {
+namespace V1_0 {
+namespace helper {
+
+class VendorTagDescriptorCache
+ : public ::android::hardware::camera2::params::VendorTagDescriptorCache,
+ public LightRefBase<VendorTagDescriptorCache> {
+ public:
+ /**
+ * Sets the global vendor tag descriptor cache to use for this process.
+ * Camera metadata operations that access vendor tags will use the
+ * vendor tag definitions set this way.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ static status_t setAsGlobalVendorTagCache(const sp<VendorTagDescriptorCache>& cache);
+
+ /**
+ * Returns the global vendor tag cache used by this process.
+ * This will contain NULL if no vendor tags are defined.
+ */
+ static sp<VendorTagDescriptorCache> getGlobalVendorTagCache();
+
+ /**
+ * Clears the global vendor tag cache used by this process.
+ */
+ static void clearGlobalVendorTagCache();
+};
+
} // namespace helper
} // namespace V1_0
} // namespace common
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index e1a4203..2fd8861 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -203,6 +203,7 @@
<hal format="hidl" optional="false">
<name>android.hardware.graphics.allocator</name>
<version>2.0</version>
+ <version>3.0</version>
<interface>
<name>IAllocator</name>
<instance>default</instance>
@@ -218,7 +219,8 @@
</hal>
<hal format="hidl" optional="false">
<name>android.hardware.graphics.mapper</name>
- <version>2.0</version>
+ <version>2.0-1</version>
+ <version>3.0</version>
<interface>
<name>IMapper</name>
<instance>default</instance>
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 9b6b076..9b04be0 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -19,6 +19,7 @@
],
interfaces: [
"android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hidl.base@1.0",
diff --git a/gnss/2.0/IGnss.hal b/gnss/2.0/IGnss.hal
index e1acd6d..1f1858e 100644
--- a/gnss/2.0/IGnss.hal
+++ b/gnss/2.0/IGnss.hal
@@ -17,6 +17,7 @@
package android.hardware.gnss@2.0;
import android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections;
+import android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl;
import @1.1::IGnss;
import IGnssCallback;
@@ -25,7 +26,15 @@
import IAGnss;
import IAGnssRil;
-/** Represents the standard GNSS (Global Navigation Satellite System) interface. */
+/**
+ * Represents the standard GNSS (Global Navigation Satellite System) interface.
+ *
+ * Due to the introduction of new GNSS HAL package android.hardware.gnss.visibility_control@1.0
+ * the interface @1.0::IGnssNi.hal and @1.0::IGnssNiCallback.hal are deprecated in this version
+ * and are not supported by the framework. The GNSS HAL implementation of this interface
+ * must return nullptr for the following @1.0::IGnss method.
+ * getExtensionGnssNi() generates (IGnssNi gnssNiIface);
+ */
interface IGnss extends @1.1::IGnss {
/**
* Opens the interface and provides the callback routines to the implementation of this
@@ -76,6 +85,13 @@
*
* @return measurementCorrectionsIface Handle to the IMeasurementCorrections interface.
*/
- getExtensionMeasurementCorrections()
+ getExtensionMeasurementCorrections()
generates (IMeasurementCorrections measurementCorrectionsIface);
-};
+
+ /**
+ * This method returns the IGnssVisibilityControl interface.
+ *
+ * @return visibilityControlIface Handle to the IGnssVisibilityControl interface.
+ */
+ getExtensionVisibilityControl() generates (IGnssVisibilityControl visibilityControlIface);
+};
\ No newline at end of file
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 92d5c1f..985aa2b 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -26,6 +26,7 @@
"AGnssRil.cpp",
"Gnss.cpp",
"GnssMeasurement.cpp",
+ "GnssVisibilityControl.cpp",
"service.cpp"
],
shared_libs: [
@@ -35,6 +36,7 @@
"liblog",
"android.hardware.gnss@2.0",
"android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
],
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index 5c752d5..217f0f3 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -22,8 +22,10 @@
#include "AGnssRil.h"
#include "GnssConfiguration.h"
#include "GnssMeasurement.h"
+#include "GnssVisibilityControl.h"
using ::android::hardware::Status;
+using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
namespace android {
namespace hardware {
@@ -93,8 +95,8 @@
}
Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
- // TODO implement
- return sp<V1_0::IGnssNi>{};
+ // The IGnssNi.hal interface is deprecated in 2.0.
+ return nullptr;
}
Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
@@ -205,6 +207,11 @@
return sp<measurement_corrections::V1_0::IMeasurementCorrections>{};
}
+Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
+ ALOGD("Gnss::getExtensionVisibilityControl");
+ return new GnssVisibilityControl();
+}
+
Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
ALOGD("Gnss::setCallback_2_0");
if (callback == nullptr) {
diff --git a/gnss/2.0/default/Gnss.h b/gnss/2.0/default/Gnss.h
index e86158f..890b026 100644
--- a/gnss/2.0/default/Gnss.h
+++ b/gnss/2.0/default/Gnss.h
@@ -79,6 +79,8 @@
Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
getExtensionMeasurementCorrections() override;
+ Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
+ override;
private:
static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
diff --git a/gnss/2.0/default/GnssVisibilityControl.cpp b/gnss/2.0/default/GnssVisibilityControl.cpp
new file mode 100644
index 0000000..99b8e34
--- /dev/null
+++ b/gnss/2.0/default/GnssVisibilityControl.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssVisibilityControl"
+
+#include "GnssVisibilityControl.h"
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+Return<bool> GnssVisibilityControl::enableNfwLocationAccess(
+ const hidl_vec<hidl_string>& proxyApps) {
+ std::string os;
+ bool first = true;
+ for (const auto& proxyApp : proxyApps) {
+ if (first) {
+ first = false;
+ } else {
+ os += " ";
+ }
+
+ os += proxyApp;
+ }
+
+ ALOGD("enableNfwLocationAccess proxyApps: %s", os.c_str());
+ return true;
+}
+
+Return<bool> GnssVisibilityControl::setCallback(const sp<V1_0::IGnssVisibilityControlCallback>&) {
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace visibility_control
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/2.0/default/GnssVisibilityControl.h b/gnss/2.0/default/GnssVisibilityControl.h
new file mode 100644
index 0000000..45febff
--- /dev/null
+++ b/gnss/2.0/default/GnssVisibilityControl.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_VISIBILITY_CONTROL_V1_0_GNSSVISIBILITYCONTROL_H
+#define ANDROID_HARDWARE_GNSS_VISIBILITY_CONTROL_V1_0_GNSSVISIBILITYCONTROL_H
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+struct GnssVisibilityControl : public IGnssVisibilityControl {
+ // Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl
+ // follow.
+ Return<bool> enableNfwLocationAccess(const hidl_vec<hidl_string>& proxyApps) override;
+ Return<bool> setCallback(const sp<V1_0::IGnssVisibilityControlCallback>& callback) override;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace visibility_control
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GNSS_VISIBILITY_CONTROL_V1_0_GNSSVISIBILITYCONTROL_H
\ No newline at end of file
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 894716d..684b381 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -24,6 +24,7 @@
],
static_libs: [
"android.hardware.gnss.measurement_corrections@1.0",
+ "android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index cef06a2..552cf1b 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -19,6 +19,7 @@
#include <VtsHalHidlTargetTestBase.h>
#include <gnss_hal_test.h>
+using android::hardware::hidl_string;
using android::hardware::hidl_vec;
using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
@@ -30,6 +31,8 @@
using IAGnss_2_0 = android::hardware::gnss::V2_0::IAGnss;
using IAGnss_1_0 = android::hardware::gnss::V1_0::IAGnss;
using IAGnssCallback_2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
+using android::hardware::gnss::V1_0::IGnssNi;
+using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
/*
* SetupTeardownCreateCleanup:
@@ -117,7 +120,7 @@
* The GNSS HAL 2.0 implementation must support @2.0::IAGnssRil interface due to the deprecation
* of framework network API methods needed to support the @1.0::IAGnssRil interface.
*
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launced with Q or later.
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
*/
TEST_F(GnssHalTest, TestAGnssRilExtension) {
auto agnssRil = gnss_hal_->getExtensionAGnssRil_2_0();
@@ -199,7 +202,7 @@
* The GNSS HAL 2.0 implementation must support @2.0::IAGnss interface due to the deprecation
* of framework network API methods needed to support the @1.0::IAGnss interface.
*
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launced with Q or later.
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
*/
TEST_F(GnssHalTest, TestAGnssExtension) {
// Verify IAGnss 2.0 is supported.
@@ -218,10 +221,45 @@
* TestAGnssExtension_1_0_Deprecation:
* Gets the @1.0::IAGnss extension and verifies that it is a nullptr.
*
- * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launced with Q or later.
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
*/
TEST_F(GnssHalTest, TestAGnssExtension_1_0_Deprecation) {
// Verify IAGnss 1.0 is not supported.
auto agnss_1_0 = gnss_hal_->getExtensionAGnss();
ASSERT_TRUE(!agnss_1_0.isOk() || ((sp<IAGnss_1_0>)agnss_1_0) == nullptr);
}
+
+/*
+ * TestGnssNiExtension_Deprecation:
+ * Gets the @1.0::IGnssNi extension and verifies that it is a nullptr.
+ *
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
+ */
+TEST_F(GnssHalTest, TestGnssNiExtension_Deprecation) {
+ // Verify IGnssNi 1.0 is not supported.
+ auto gnssNi = gnss_hal_->getExtensionGnssNi();
+ ASSERT_TRUE(!gnssNi.isOk() || ((sp<IGnssNi>)gnssNi) == nullptr);
+}
+
+/*
+ * TestGnssVisibilityControlExtension:
+ * Gets the GnssVisibilityControlExtension and verifies that it supports the
+ * gnss.visibility_control@1.0::IGnssVisibilityControl interface by invoking a method.
+ *
+ * The GNSS HAL 2.0 implementation must support gnss.visibility_control@1.0::IGnssVisibilityControl.
+ *
+ * TODO (b/121287858): Enforce gnss@2.0 HAL package is supported on devices launched with Q or later
+ */
+TEST_F(GnssHalTest, TestGnssVisibilityControlExtension) {
+ // Verify IGnssVisibilityControl is supported.
+ auto gnssVisibilityControl = gnss_hal_->getExtensionVisibilityControl();
+ ASSERT_TRUE(gnssVisibilityControl.isOk());
+ sp<IGnssVisibilityControl> iGnssVisibilityControl = gnssVisibilityControl;
+ ASSERT_NE(iGnssVisibilityControl, nullptr);
+
+ // Set non-framework proxy apps.
+ hidl_vec<hidl_string> proxyApps{"ims.example.com", "mdt.example.com"};
+ auto result = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
diff --git a/gnss/visibility_control/1.0/Android.bp b/gnss/visibility_control/1.0/Android.bp
new file mode 100644
index 0000000..40a28c9
--- /dev/null
+++ b/gnss/visibility_control/1.0/Android.bp
@@ -0,0 +1,18 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.gnss.visibility_control@1.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IGnssVisibilityControl.hal",
+ "IGnssVisibilityControlCallback.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
+
diff --git a/gnss/visibility_control/1.0/IGnssVisibilityControl.hal b/gnss/visibility_control/1.0/IGnssVisibilityControl.hal
new file mode 100644
index 0000000..9148127
--- /dev/null
+++ b/gnss/visibility_control/1.0/IGnssVisibilityControl.hal
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.visibility_control@1.0;
+
+import IGnssVisibilityControlCallback;
+
+/**
+ * Represents the GNSS location reporting permissions and notification interface.
+ *
+ * This interface is used to tell the GNSS HAL implementation whether the framework user has
+ * granted permission to the GNSS HAL implementation to provide GNSS location information for
+ * non-framework (NFW), non-user initiated emergency use cases, and to notify the framework user
+ * of these GNSS location information deliveries.
+ *
+ * For user initiated emergency cases (and for the configured extended emergency session duration),
+ * the GNSS HAL implementation must serve the emergency location supporting network initiated
+ * location requests immediately irrespective of this permission settings.
+ *
+ * There is no separate need for the GNSS HAL implementation to monitor the global device location
+ * on/off setting. Permission to use GNSS for non-framework use cases is expressly controlled
+ * by the method enableNfwLocationAccess(). The framework monitors the location permission settings
+ * of the configured proxy applications(s), and device location settings, and calls the method
+ * enableNfwLocationAccess() whenever the user control proxy applications have, or do not have,
+ * location permission. The proxy applications are used to provide user visibility and control of
+ * location access by the non-framework on/off device entities they are representing.
+ *
+ * For device user visibility, the GNSS HAL implementation must call the method
+ * IGnssVisibilityControlCallback.nfwNotifyCb() whenever location request is rejected or
+ * location information is provided to non-framework entities (on or off device). This includes
+ * the network initiated location requests for user-initiated emergency use cases as well.
+ *
+ * The HAL implementations that support this interface must not report GNSS location, measurement,
+ * status, or other information that can be used to derive user location to any entity when not
+ * expressly authorized by this HAL. This includes all endpoints for location information
+ * off the device, including carriers, vendors, OEM and others directly or indirectly.
+ */
+interface IGnssVisibilityControl {
+ /**
+ * Enables/disables non-framework entity location access permission in the GNSS HAL.
+ *
+ * The framework will call this method to update GNSS HAL implementation every time the
+ * framework user, through the given proxy application(s) and/or device location settings,
+ * explicitly grants/revokes the location access permission for non-framework, non-user
+ * initiated emergency use cases.
+ *
+ * Whenever the user location information is delivered to non-framework entities, the HAL
+ * implementation must call the method IGnssVisibilityControlCallback.nfwNotifyCb() to notify
+ * the framework for user visibility.
+ *
+ * @param proxyApps Full list of package names of proxy Android applications representing
+ * the non-framework location access entities (on/off the device) for which the framework
+ * user has granted non-framework location access permission. The GNSS HAL implementation
+ * must provide location information only to non-framework entities represented by these
+ * proxy applications.
+ *
+ * The package name of the proxy Android application follows the standard Java language
+ * package naming format. For example, com.example.myapp.
+ *
+ * @return success True if the operation was successful.
+ */
+ enableNfwLocationAccess(vec<string> proxyApps) generates (bool success);
+
+ /**
+ * Registers the callback for HAL implementation to use.
+ *
+ * @param callback Handle to IGnssVisibilityControlCallback interface.
+ */
+ setCallback(IGnssVisibilityControlCallback callback) generates (bool success);
+};
\ No newline at end of file
diff --git a/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal b/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
new file mode 100644
index 0000000..5a582c2
--- /dev/null
+++ b/gnss/visibility_control/1.0/IGnssVisibilityControlCallback.hal
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.visibility_control@1.0;
+
+/**
+ * GNSS location reporting permissions and notification callback interface.
+ */
+interface IGnssVisibilityControlCallback {
+ /**
+ * Protocol stack that is requesting the non-framework location information.
+ */
+ enum NfwProtocolStack : uint8_t {
+ /** Cellular control plane requests */
+ CTRL_PLANE = 0,
+ /** All types of SUPL requests */
+ SUPL = 1,
+
+ /** All types of requests from IMS */
+ IMS = 10,
+ /** All types of requests from SIM */
+ SIM = 11,
+
+ /** Requests from other protocol stacks */
+ OTHER_PROTOCOL_STACK = 100
+ };
+
+ /*
+ * Entity that is requesting/receiving the location information.
+ */
+ enum NfwRequestor : uint8_t {
+ /** Wireless service provider */
+ CARRIER = 0,
+
+ /** Device manufacturer */
+ OEM = 10,
+ /** Modem chipset vendor */
+ MODEM_CHIPSET_VENDOR = 11,
+ /** GNSS chipset vendor */
+ GNSS_CHIPSET_VENDOR = 12,
+ /** Other chipset vendor */
+ OTHER_CHIPSET_VENDOR = 13,
+
+ /** Automobile client */
+ AUTOMOBILE_CLIENT = 20,
+
+ /** Other sources */
+ OTHER_REQUESTOR = 100
+ };
+
+ /**
+ * GNSS response type for non-framework location requests.
+ */
+ enum NfwResponseType : uint8_t {
+ /** Request rejected because framework has not given permission for this use case */
+ REJECTED = 0,
+
+ /** Request accepted but could not provide location because of a failure */
+ ACCEPTED_NO_LOCATION_PROVIDED = 1,
+
+ /** Request accepted and location provided */
+ ACCEPTED_LOCATION_PROVIDED = 2,
+ };
+
+ /**
+ * Represents a non-framework location information request/response notification.
+ */
+ struct NfwNotification {
+ /**
+ * Package name of the Android proxy application representing the non-framework
+ * entity that requested location. Set to empty string if unknown.
+ */
+ string proxyAppPackageName;
+
+ /** Protocol stack that initiated the non-framework location request. */
+ NfwProtocolStack protocolStack;
+
+ /**
+ * Name of the protocol stack if protocolStack field is set to OTHER_PROTOCOL_STACK.
+ * Otherwise, set to empty string.
+ *
+ * This field is opaque to the framework and used for logging purposes.
+ */
+ string otherProtocolStackName;
+
+ /** Source initiating/receiving the location information. */
+ NfwRequestor requestor;
+
+ /**
+ * Identity of the endpoint receiving the location information. For example, carrier
+ * name, OEM name, SUPL SLP/E-SLP FQDN, chipset vendor name, etc.
+ *
+ * This field is opaque to the framework and used for logging purposes.
+ */
+ string requestorId;
+
+ /** Indicates whether location information was provided for this request. */
+ NfwResponseType responseType;
+
+ /** Is the device in user initiated emergency session. */
+ bool inEmergencyMode;
+
+ /** Is cached location provided */
+ bool isCachedLocation;
+ };
+
+ /**
+ * Callback to report a non-framework delivered location.
+ *
+ * The GNSS HAL implementation must call this method to notify the framework whenever
+ * a non-framework location request is made to the GNSS HAL.
+ *
+ * Non-framework entities like low power sensor hubs that request location from GNSS and
+ * only pass location information through Android framework controls are exempt from this
+ * power-spending reporting. However, low power sensor hubs or other chipsets which may send
+ * the location information to anywhere other than Android framework (which provides user
+ * visibility and control), must report location information use through this API whenever
+ * location information (or events driven by that location such as "home" location detection)
+ * leaves the domain of that low power chipset.
+ *
+ * To avoid overly spamming the framework, high speed location reporting of the exact same
+ * type may be throttled to report location at a lower rate than the actual report rate, as
+ * long as the location is reported with a latency of no more than the larger of 5 seconds,
+ * or the next the Android processor awake time. For example, if an Automotive client is
+ * getting location information from the GNSS location system at 20Hz, this method may be
+ * called at 1Hz. As another example, if a low power processor is getting location from the
+ * GNSS chipset, and the Android processor is asleep, the notification to the Android HAL may
+ * be delayed until the next wake of the Android processor.
+ *
+ * @param notification Non-framework delivered location request/response description.
+ */
+ nfwNotifyCb(NfwNotification notification);
+
+ /**
+ * Tells if the device is currently in an emergency session.
+ *
+ * Emergency session is defined as the device being actively in a user initiated emergency
+ * call or in post emergency call extension time period.
+ *
+ * If the GNSS HAL implementation cannot determine if the device is in emergency session
+ * mode, it must call this method to confirm that the device is in emergency session before
+ * serving network initiated emergency SUPL and Control Plane location requests.
+ *
+ * @return success True if the framework determines that the device is in emergency session.
+ */
+ isInEmergencySession() generates (bool success);
+};
\ No newline at end of file
diff --git a/graphics/allocator/3.0/Android.bp b/graphics/allocator/3.0/Android.bp
new file mode 100644
index 0000000..fa3e2ce
--- /dev/null
+++ b/graphics/allocator/3.0/Android.bp
@@ -0,0 +1,21 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.graphics.allocator@3.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IAllocator.hal",
+ ],
+ interfaces: [
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
+
diff --git a/graphics/allocator/3.0/IAllocator.hal b/graphics/allocator/3.0/IAllocator.hal
new file mode 100644
index 0000000..3651e91
--- /dev/null
+++ b/graphics/allocator/3.0/IAllocator.hal
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.allocator@3.0;
+
+import android.hardware.graphics.mapper@3.0;
+
+interface IAllocator {
+ /**
+ * Retrieves implementation-defined debug information, which will be
+ * displayed during, for example, `dumpsys SurfaceFlinger`.
+ *
+ * @return debugInfo is a string of debug information.
+ */
+ dumpDebugInfo() generates (string debugInfo);
+
+ /**
+ * Allocates buffers with the properties specified by the descriptor.
+ *
+ * @param descriptor Properties of the buffers to allocate. This must be
+ * obtained from IMapper::createDescriptor().
+ * @param count The number of buffers to allocate.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_DESCRIPTOR` if the descriptor is invalid.
+ * - `NO_RESOURCES` if the allocation cannot be fulfilled at this time.
+ * - `UNSUPPORTED` if any of the properties encoded in the descriptor
+ * are not supported.
+ * @return stride The number of pixels between two consecutive rows of
+ * an allocated buffer, when the concept of consecutive rows is defined.
+ * Otherwise, it has no meaning.
+ * @return buffers Array of raw handles to the allocated buffers.
+ */
+ allocate(BufferDescriptor descriptor, uint32_t count)
+ generates (Error error,
+ uint32_t stride,
+ vec<handle> buffers);
+};
+
diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
index 2de1e3c..63accff 100644
--- a/graphics/composer/2.1/default/Android.bp
+++ b/graphics/composer/2.1/default/Android.bp
@@ -10,6 +10,7 @@
shared_libs: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
"libbase",
"libcutils",
"libfmq",
diff --git a/graphics/composer/2.1/utils/hal/Android.bp b/graphics/composer/2.1/utils/hal/Android.bp
index f24e768..7a501fc 100644
--- a/graphics/composer/2.1/utils/hal/Android.bp
+++ b/graphics/composer/2.1/utils/hal/Android.bp
@@ -20,11 +20,13 @@
shared_libs: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
"libhardware", // TODO remove hwcomposer2.h dependency
],
export_shared_lib_headers: [
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
"libhardware",
],
header_libs: [
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
index f249f1a..3a73f84 100644
--- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerResources.h
@@ -26,6 +26,7 @@
#include <vector>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <log/log.h>
namespace android {
@@ -39,9 +40,16 @@
class ComposerHandleImporter {
public:
bool init() {
- mMapper = mapper::V2_0::IMapper::getService();
- ALOGE_IF(!mMapper, "failed to get mapper service");
- return mMapper != nullptr;
+ mMapper3 = mapper::V3_0::IMapper::getService();
+ if (mMapper3) {
+ return true;
+ }
+ ALOGW_IF(!mMapper3, "failed to get mapper 3.0 service");
+
+ mMapper2 = mapper::V2_0::IMapper::getService();
+ ALOGE_IF(!mMapper2, "failed to get mapper 2.0 service");
+
+ return mMapper2 != nullptr;
}
Error importBuffer(const native_handle_t* rawHandle, const native_handle_t** outBufferHandle) {
@@ -50,14 +58,28 @@
return Error::NONE;
}
- mapper::V2_0::Error error;
const native_handle_t* bufferHandle;
- mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBufferHandle) {
- error = tmpError;
- bufferHandle = static_cast<const native_handle_t*>(tmpBufferHandle);
- });
- if (error != mapper::V2_0::Error::NONE) {
- return Error::NO_RESOURCES;
+ if (mMapper2) {
+ mapper::V2_0::Error error;
+ mMapper2->importBuffer(
+ rawHandle, [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ error = tmpError;
+ bufferHandle = static_cast<const native_handle_t*>(tmpBufferHandle);
+ });
+ if (error != mapper::V2_0::Error::NONE) {
+ return Error::NO_RESOURCES;
+ }
+ }
+ if (mMapper3) {
+ mapper::V3_0::Error error;
+ mMapper3->importBuffer(
+ rawHandle, [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ error = tmpError;
+ bufferHandle = static_cast<const native_handle_t*>(tmpBufferHandle);
+ });
+ if (error != mapper::V3_0::Error::NONE) {
+ return Error::NO_RESOURCES;
+ }
}
*outBufferHandle = bufferHandle;
@@ -66,7 +88,13 @@
void freeBuffer(const native_handle_t* bufferHandle) {
if (bufferHandle) {
- mMapper->freeBuffer(static_cast<void*>(const_cast<native_handle_t*>(bufferHandle)));
+ if (mMapper2) {
+ mMapper2->freeBuffer(
+ static_cast<void*>(const_cast<native_handle_t*>(bufferHandle)));
+ } else if (mMapper3) {
+ mMapper3->freeBuffer(
+ static_cast<void*>(const_cast<native_handle_t*>(bufferHandle)));
+ }
}
}
@@ -91,7 +119,8 @@
}
private:
- sp<mapper::V2_0::IMapper> mMapper;
+ sp<mapper::V2_0::IMapper> mMapper2;
+ sp<mapper::V3_0::IMapper> mMapper3;
};
class ComposerHandleCache {
diff --git a/graphics/composer/2.2/default/Android.mk b/graphics/composer/2.2/default/Android.mk
index 2f80f0c..7dedf61 100644
--- a/graphics/composer/2.2/default/Android.mk
+++ b/graphics/composer/2.2/default/Android.mk
@@ -12,6 +12,7 @@
android.hardware.graphics.composer@2.1 \
android.hardware.graphics.composer@2.2 \
android.hardware.graphics.mapper@2.0 \
+ android.hardware.graphics.mapper@3.0 \
libbase \
libbinder \
libcutils \
diff --git a/graphics/composer/2.3/default/Android.bp b/graphics/composer/2.3/default/Android.bp
index ad49ec3..07afd6c 100644
--- a/graphics/composer/2.3/default/Android.bp
+++ b/graphics/composer/2.3/default/Android.bp
@@ -29,6 +29,7 @@
"android.hardware.graphics.composer@2.2",
"android.hardware.graphics.composer@2.3",
"android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
"libbase",
"libbinder",
"libcutils",
diff --git a/graphics/mapper/3.0/Android.bp b/graphics/mapper/3.0/Android.bp
new file mode 100644
index 0000000..b2f0aa6
--- /dev/null
+++ b/graphics/mapper/3.0/Android.bp
@@ -0,0 +1,26 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.graphics.mapper@3.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ srcs: [
+ "types.hal",
+ "IMapper.hal",
+ ],
+ interfaces: [
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hidl.base@1.0",
+ ],
+ types: [
+ "Error",
+ "YCbCrLayout",
+ ],
+ gen_java: false,
+}
+
diff --git a/graphics/mapper/3.0/IMapper.hal b/graphics/mapper/3.0/IMapper.hal
new file mode 100644
index 0000000..e399045
--- /dev/null
+++ b/graphics/mapper/3.0/IMapper.hal
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.mapper@3.0;
+
+import android.hardware.graphics.common@1.1::BufferUsage;
+import android.hardware.graphics.common@1.1::PixelFormat;
+import android.hardware.graphics.common@1.2::Rect;
+
+interface IMapper {
+ struct BufferDescriptorInfo {
+ /**
+ * The width specifies how many columns of pixels must be in the
+ * allocated buffer, but does not necessarily represent the offset in
+ * columns between the same column in adjacent rows. The rows may be
+ * padded.
+ */
+ uint32_t width;
+
+ /**
+ * The height specifies how many rows of pixels must be in the
+ * allocated buffer.
+ */
+ uint32_t height;
+
+ /**
+ * The number of image layers that must be in the allocated buffer.
+ */
+ uint32_t layerCount;
+
+ /** Buffer pixel format. */
+ PixelFormat format;
+
+ /**
+ * Buffer usage mask; valid flags can be found in the definition of
+ * BufferUsage.
+ */
+ bitfield<BufferUsage> usage;
+ };
+
+ struct Rect {
+ int32_t left;
+ int32_t top;
+ int32_t width;
+ int32_t height;
+ };
+
+ /**
+ * Creates a buffer descriptor. The descriptor can be used with IAllocator
+ * to allocate buffers.
+ *
+ * Since the buffer descriptor fully describes a buffer, any device
+ * dependent or device independent checks must be performed here whenever
+ * possible. Specifically, when layered buffers are not supported, this
+ * function must return `UNSUPPORTED` if `description.layers` is great than
+ * 1.
+ *
+ * @param description Attributes of the descriptor.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_VALUE` if any of the specified attributes are invalid or
+ * inconsistent.
+ * - `NO_RESOURCES` if the creation cannot be fullfilled due to
+ * unavailability of resources.
+ * - `UNSUPPORTED` when any of the specified attributes are not
+ * supported.
+ * @return descriptor Newly created buffer descriptor.
+ */
+ createDescriptor(BufferDescriptorInfo description)
+ generates (Error error,
+ BufferDescriptor descriptor);
+
+ /**
+ * Imports a raw buffer handle to create an imported buffer handle for use
+ * with the rest of the mapper or with other in-process libraries.
+ *
+ * A buffer handle is considered raw when it is cloned (e.g., with
+ * `native_handle_clone()`) from another buffer handle locally, or when it
+ * is received from another HAL server/client or another process. A raw
+ * buffer handle must not be used to access the underlying graphic
+ * buffer. It must be imported to create an imported handle first.
+ *
+ * This function must at least validate the raw handle before creating the
+ * imported handle. It must also support importing the same raw handle
+ * multiple times to create multiple imported handles. The imported handle
+ * must be considered valid everywhere in the process, including in
+ * another instance of the mapper.
+ *
+ * Because of passthrough HALs, a raw buffer handle received from a HAL
+ * may actually have been imported in the process. importBuffer() must treat
+ * such a handle as if it is raw and must not return `BAD_BUFFER`. The
+ * returned handle is independent from the input handle as usual, and
+ * freeBuffer() must be called on it when it is no longer needed.
+ *
+ * @param rawHandle Raw buffer handle to import.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the raw handle cannot be imported due to
+ * unavailability of resources.
+ * @return buffer Imported buffer handle that has the type
+ * `buffer_handle_t` which is a handle type.
+ */
+ importBuffer(handle rawHandle) generates (Error error, pointer buffer);
+
+ /**
+ * Frees a buffer handle. Buffer handles returned by importBuffer() must be
+ * freed with this function when no longer needed.
+ *
+ * This function must free up all resources allocated by importBuffer() for
+ * the imported handle. For example, if the imported handle was created
+ * with `native_handle_create()`, this function must call
+ * `native_handle_close()` and `native_handle_delete()`.
+ *
+ * @param buffer Imported buffer handle.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ */
+ freeBuffer(pointer buffer) generates (Error error);
+
+ /**
+ * Validates that the buffer can be safely accessed by a caller who assumes
+ * the specified @p description and @p stride. This must at least validate
+ * that the buffer size is large enough. Validating the buffer against
+ * individual buffer attributes is optional.
+ *
+ * @param buffer Buffer to validate against.
+ * @param description Attributes of the buffer.
+ * @param stride Stride returned by IAllocator::allocate().
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ * - `BAD_VALUE` if the buffer cannot be safely accessed.
+ */
+ validateBufferSize(pointer buffer,
+ BufferDescriptorInfo description,
+ uint32_t stride)
+ generates (Error error);
+
+ /**
+ * Calculates the transport size of a buffer. An imported buffer handle is a
+ * raw buffer handle with the process-local runtime data appended. This
+ * function, for example, allows a caller to omit the process-local runtime
+ * data at the tail when serializing the imported buffer handle.
+ *
+ * Note that a client might or might not omit the process-local runtime data
+ * when sending an imported buffer handle. The mapper must support both
+ * cases on the receiving end.
+ *
+ * @param buffer Buffer to get the transport size from.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid.
+ * @return numFds The number of file descriptors needed for transport.
+ * @return numInts The number of integers needed for transport.
+ */
+ getTransportSize(pointer buffer)
+ generates (Error error,
+ uint32_t numFds,
+ uint32_t numInts);
+
+ /**
+ * Locks the given buffer for the specified CPU usage.
+ *
+ * Locking the same buffer simultaneously from multiple threads is
+ * permitted, but if any of the threads attempt to lock the buffer for
+ * writing, the behavior is undefined, except that it must not cause
+ * process termination or block the client indefinitely. Leaving the
+ * buffer content in an indeterminate state or returning an error are both
+ * acceptable.
+ *
+ * The client must not modify the content of the buffer outside of
+ * @p accessRegion, and the device need not guarantee that content outside
+ * of @p accessRegion is valid for reading. The result of reading or writing
+ * outside of @p accessRegion is undefined, except that it must not cause
+ * process termination.
+ *
+ * On success, @p data must be filled with a pointer to the locked buffer
+ * memory. This address will represent the top-left corner of the entire
+ * buffer, even if @p accessRegion does not begin at the top-left corner.
+ *
+ * @param buffer Buffer to lock.
+ * @param cpuUsage CPU usage flags to request. See +ndk
+ * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
+ * @param accessRegion Portion of the buffer that the client intends to
+ * access.
+ * @param acquireFence Handle containing a file descriptor referring to a
+ * sync fence object, which will be signaled when it is safe for the
+ * mapper to lock the buffer. @p acquireFence may be an empty fence if
+ * it is already safe to lock.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
+ * function.
+ * - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
+ * is incompatible with the buffer.
+ * - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
+ * that locking may succeed at a later time.
+ * @return data CPU-accessible pointer to the buffer data.
+ */
+ lock(pointer buffer,
+ uint64_t cpuUsage,
+ Rect accessRegion,
+ handle acquireFence)
+ generates (Error error,
+ pointer data);
+
+ /**
+ * Locks a YCbCr buffer for the specified CPU usage.
+ *
+ * This is largely the same as lock(), except that instead of returning a
+ * pointer directly to the buffer data, it returns a `YCbCrLayout` struct
+ * describing how to access the data planes.
+ *
+ * This function must work on buffers with
+ * `AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_*` if supported by the device, as well
+ * as with any other formats requested by multimedia codecs when they are
+ * configured with a flexible-YUV-compatible color format.
+ *
+ * @param buffer Buffer to lock.
+ * @param cpuUsage CPU usage flags to request. See +ndk
+ * libnativewindow#AHardwareBuffer_UsageFlags for possible values.
+ * @param accessRegion Portion of the buffer that the client intends to
+ * access.
+ * @param acquireFence Handle containing a file descriptor referring to a
+ * sync fence object, which will be signaled when it is safe for the
+ * mapper to lock the buffer. @p acquireFence may be empty if it is
+ * already safe to lock.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
+ * function.
+ * - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
+ * is incompatible with the buffer.
+ * - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
+ * that locking may succeed at a later time.
+ * @return layout Data layout of the locked buffer.
+ */
+ lockYCbCr(pointer buffer,
+ uint64_t cpuUsage,
+ Rect accessRegion,
+ handle acquireFence)
+ generates (Error error,
+ YCbCrLayout layout);
+
+ /**
+ * Unlocks a buffer to indicate all CPU accesses to the buffer have
+ * completed.
+ *
+ * @param buffer Buffer to unlock.
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the buffer is invalid or not locked.
+ * @return releaseFence Handle containing a file descriptor referring to a
+ * sync fence object. The sync fence object will be signaled when the
+ * mapper has completed any pending work. @p releaseFence may be an
+ * empty fence.
+ */
+ unlock(pointer buffer) generates (Error error, handle releaseFence);
+
+};
+
diff --git a/graphics/mapper/3.0/types.hal b/graphics/mapper/3.0/types.hal
new file mode 100644
index 0000000..f94abd3
--- /dev/null
+++ b/graphics/mapper/3.0/types.hal
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.mapper@3.0;
+
+/**
+ * Error values that may be returned by a method of IAllocator or IMapper.
+ */
+enum Error : int32_t {
+ /**
+ * No error.
+ */
+ NONE = 0,
+ /**
+ * Invalid BufferDescriptor.
+ */
+ BAD_DESCRIPTOR = 1,
+ /**
+ * Invalid buffer handle.
+ */
+ BAD_BUFFER = 2,
+ /**
+ * Invalid HardwareBufferDescription.
+ */
+ BAD_VALUE = 3,
+ /**
+ * Resource unavailable.
+ */
+ NO_RESOURCES = 5,
+ /**
+ * Permanent failure.
+ */
+ UNSUPPORTED = 7,
+};
+
+/**
+ * A buffer descriptor is an implementation-defined opaque data returned by
+ * createDescriptor(). It describes the properties of a buffer and is consumed
+ * by the allocator.
+ */
+typedef vec<uint32_t> BufferDescriptor;
+
+/**
+ * Structure for describing YCbCr formats for consumption by applications.
+ * This is used with PixelFormat::YCBCR_*_888.
+ *
+ * Buffer chroma subsampling is defined in the format.
+ * e.g. PixelFormat::YCBCR_420_888 has subsampling 4:2:0.
+ *
+ * Buffers must have a 8 bit depth.
+ *
+ * y, cb, and cr point to the first byte of their respective planes.
+ *
+ * Stride describes the distance in bytes from the first value of one row of
+ * the image to the first value of the next row. It includes the width of the
+ * image plus padding.
+ * yStride is the stride of the luma plane.
+ * cStride is the stride of the chroma planes.
+ *
+ * chromaStep is the distance in bytes from one chroma pixel value to the
+ * next. This is 2 bytes for semiplanar (because chroma values are interleaved
+ * and each chroma value is one byte) and 1 for planar.
+ */
+struct YCbCrLayout {
+ pointer y;
+ pointer cb;
+ pointer cr;
+ uint32_t yStride;
+ uint32_t cStride;
+ uint32_t chromaStep;
+};
diff --git a/graphics/mapper/3.0/utils/OWNERS b/graphics/mapper/3.0/utils/OWNERS
new file mode 100644
index 0000000..96f6d51
--- /dev/null
+++ b/graphics/mapper/3.0/utils/OWNERS
@@ -0,0 +1,3 @@
+# Graphics team
+marissaw@google.com
+stoza@google.com
diff --git a/graphics/mapper/3.0/utils/vts/Android.bp b/graphics/mapper/3.0/utils/vts/Android.bp
new file mode 100644
index 0000000..c3d480a
--- /dev/null
+++ b/graphics/mapper/3.0/utils/vts/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_library_static {
+ name: "android.hardware.graphics.mapper@3.0-vts",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["MapperVts.cpp"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+ static_libs: [
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.mapper@3.0",
+ ],
+ export_static_lib_headers: [
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.mapper@3.0",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/graphics/mapper/3.0/utils/vts/MapperVts.cpp b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
new file mode 100644
index 0000000..8428403
--- /dev/null
+++ b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mapper-vts/3.0/MapperVts.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V3_0 {
+namespace vts {
+
+Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
+ init(allocatorServiceName, mapperServiceName);
+}
+
+void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
+ mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>(allocatorServiceName);
+ ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
+
+ mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>(mapperServiceName);
+ ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
+ ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
+}
+
+Gralloc::~Gralloc() {
+ for (auto bufferHandle : mClonedBuffers) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
+ }
+ mClonedBuffers.clear();
+
+ for (auto bufferHandle : mImportedBuffers) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer)) << "failed to free buffer " << buffer;
+ }
+ mImportedBuffers.clear();
+}
+
+sp<IAllocator> Gralloc::getAllocator() const {
+ return mAllocator;
+}
+
+std::string Gralloc::dumpDebugInfo() {
+ std::string debugInfo;
+ mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
+
+ return debugInfo;
+}
+
+const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
+ const native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
+ EXPECT_NE(nullptr, bufferHandle);
+
+ if (bufferHandle) {
+ mClonedBuffers.insert(bufferHandle);
+ }
+
+ return bufferHandle;
+}
+
+std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
+ uint32_t count, bool import,
+ uint32_t* outStride) {
+ std::vector<const native_handle_t*> bufferHandles;
+ bufferHandles.reserve(count);
+ mAllocator->allocate(
+ descriptor, count,
+ [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
+ ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
+
+ for (uint32_t i = 0; i < count; i++) {
+ if (import) {
+ ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(importBuffer(tmpBuffers[i])));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
+ }
+ }
+
+ if (outStride) {
+ *outStride = tmpStride;
+ }
+ });
+
+ if (::testing::Test::HasFatalFailure()) {
+ bufferHandles.clear();
+ }
+
+ return bufferHandles;
+}
+
+const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ bool import, uint32_t* outStride) {
+ BufferDescriptor descriptor = createDescriptor(descriptorInfo);
+ if (::testing::Test::HasFatalFailure()) {
+ return nullptr;
+ }
+
+ auto buffers = allocate(descriptor, 1, import, outStride);
+ if (::testing::Test::HasFatalFailure()) {
+ return nullptr;
+ }
+
+ return buffers[0];
+}
+
+sp<IMapper> Gralloc::getMapper() const {
+ return mMapper;
+}
+
+BufferDescriptor Gralloc::createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+ BufferDescriptor descriptor;
+ mMapper->createDescriptor(descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
+ descriptor = tmpDescriptor;
+ });
+
+ return descriptor;
+}
+
+const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
+ const native_handle_t* bufferHandle = nullptr;
+ mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+ ASSERT_EQ(Error::NONE, tmpError)
+ << "failed to import buffer %p" << rawHandle.getNativeHandle();
+ bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
+ });
+
+ if (bufferHandle) {
+ mImportedBuffers.insert(bufferHandle);
+ }
+
+ return bufferHandle;
+}
+
+void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ if (mImportedBuffers.erase(bufferHandle)) {
+ Error error = mMapper->freeBuffer(buffer);
+ ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
+ } else {
+ mClonedBuffers.erase(bufferHandle);
+ native_handle_close(buffer);
+ native_handle_delete(buffer);
+ }
+}
+
+void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int acquireFence) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ hidl_handle acquireFenceHandle;
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ void* data = nullptr;
+ mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpData) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
+ data = tmpData;
+ });
+
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return data;
+}
+
+YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int acquireFence) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ hidl_handle acquireFenceHandle;
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ YCbCrLayout layout = {};
+ mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpLayout) {
+ ASSERT_EQ(Error::NONE, tmpError)
+ << "failed to lockYCbCr buffer " << buffer;
+ layout = tmpLayout;
+ });
+
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return layout;
+}
+
+int Gralloc::unlock(const native_handle_t* bufferHandle) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer " << buffer;
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle) {
+ ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle " << fenceHandle;
+ if (fenceHandle->numFds == 1) {
+ releaseFence = dup(fenceHandle->data[0]);
+ ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
+ } else {
+ ASSERT_EQ(0, fenceHandle->numFds) << " invalid fence handle " << fenceHandle;
+ }
+ }
+ });
+
+ return releaseFence;
+}
+
+bool Gralloc::validateBufferSize(const native_handle_t* bufferHandle,
+ const IMapper::BufferDescriptorInfo& descriptorInfo,
+ uint32_t stride) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ Error error = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
+ return error == Error::NONE;
+}
+
+void Gralloc::getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
+ uint32_t* outNumInts) {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ *outNumFds = 0;
+ *outNumInts = 0;
+ mMapper->getTransportSize(
+ buffer, [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to get transport size";
+ ASSERT_GE(bufferHandle->numFds, int(tmpNumFds)) << "invalid numFds " << tmpNumFds;
+ ASSERT_GE(bufferHandle->numInts, int(tmpNumInts)) << "invalid numInts " << tmpNumInts;
+
+ *outNumFds = tmpNumFds;
+ *outNumInts = tmpNumInts;
+ });
+}
+
+} // namespace vts
+} // namespace V3_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
new file mode 100644
index 0000000..c94961c
--- /dev/null
+++ b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V3_0 {
+namespace vts {
+
+using android::hardware::graphics::allocator::V3_0::IAllocator;
+
+// A wrapper to IAllocator and IMapper.
+class Gralloc {
+ public:
+ Gralloc(const std::string& allocatorServiceName = "default",
+ const std::string& mapperServiceName = "default");
+ ~Gralloc();
+
+ // IAllocator methods
+
+ sp<IAllocator> getAllocator() const;
+
+ std::string dumpDebugInfo();
+
+ // When import is false, this simply calls IAllocator::allocate. When import
+ // is true, the returned buffers are also imported into the mapper.
+ //
+ // Either case, the returned buffers must be freed with freeBuffer.
+ std::vector<const native_handle_t*> allocate(const BufferDescriptor& descriptor, uint32_t count,
+ bool import = true, uint32_t* outStride = nullptr);
+ const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ bool import = true, uint32_t* outStride = nullptr);
+
+ // IMapper methods
+
+ sp<IMapper> getMapper() const;
+
+ BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo);
+
+ const native_handle_t* importBuffer(const hidl_handle& rawHandle);
+ void freeBuffer(const native_handle_t* bufferHandle);
+
+ // We use fd instead of hidl_handle in these functions to pass fences
+ // in and out of the mapper. The ownership of the fd is always transferred
+ // with each of these functions.
+ void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int acquireFence);
+ YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+ const IMapper::Rect& accessRegion, int acquireFence);
+ int unlock(const native_handle_t* bufferHandle);
+
+ bool validateBufferSize(const native_handle_t* bufferHandle,
+ const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t stride);
+ void getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
+ uint32_t* outNumInts);
+
+ private:
+ void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
+ const native_handle_t* cloneBuffer(const hidl_handle& rawHandle);
+
+ sp<IAllocator> mAllocator;
+ sp<IMapper> mMapper;
+
+ // Keep track of all cloned and imported handles. When a test fails with
+ // ASSERT_*, the destructor will free the handles for the test.
+ std::unordered_set<const native_handle_t*> mClonedBuffers;
+ std::unordered_set<const native_handle_t*> mImportedBuffers;
+};
+
+} // namespace vts
+} // namespace V3_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/mapper/3.0/vts/OWNERS b/graphics/mapper/3.0/vts/OWNERS
new file mode 100644
index 0000000..96f6d51
--- /dev/null
+++ b/graphics/mapper/3.0/vts/OWNERS
@@ -0,0 +1,3 @@
+# Graphics team
+marissaw@google.com
+stoza@google.com
diff --git a/graphics/mapper/3.0/vts/functional/Android.bp b/graphics/mapper/3.0/vts/functional/Android.bp
new file mode 100644
index 0000000..77075a5
--- /dev/null
+++ b/graphics/mapper/3.0/vts/functional/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_test {
+ name: "VtsHalGraphicsMapperV3_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalGraphicsMapperV3_0TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@3.0-vts",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
new file mode 100644
index 0000000..430a526
--- /dev/null
+++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
@@ -0,0 +1,445 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "VtsHalGraphicsMapperV3_0TargetTest"
+
+#include <chrono>
+#include <thread>
+#include <vector>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
+#include <mapper-vts/3.0/MapperVts.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V3_0 {
+namespace vts {
+namespace {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using android::hardware::graphics::common::V1_1::PixelFormat;
+
+// Test environment for graphics.mapper.
+class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static GraphicsMapperHidlEnvironment* Instance() {
+ static GraphicsMapperHidlEnvironment* instance = new GraphicsMapperHidlEnvironment;
+ return instance;
+ }
+
+ virtual void registerTestServices() override {
+ registerTestService<IAllocator>();
+ registerTestService<IMapper>();
+ }
+};
+
+class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ protected:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(
+ mGralloc = std::make_unique<Gralloc>(
+ GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
+ GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+
+ mDummyDescriptorInfo.width = 64;
+ mDummyDescriptorInfo.height = 64;
+ mDummyDescriptorInfo.layerCount = 1;
+ mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
+ mDummyDescriptorInfo.usage =
+ static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+ }
+
+ void TearDown() override {}
+
+ std::unique_ptr<Gralloc> mGralloc;
+ IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
+};
+
+/**
+ * Test IAllocator::dumpDebugInfo by calling it.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+ mGralloc->dumpDebugInfo();
+}
+
+/**
+ * Test IAllocator::allocate with valid buffer descriptors.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+ BufferDescriptor descriptor;
+ ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
+
+ for (uint32_t count = 0; count < 5; count++) {
+ std::vector<const native_handle_t*> bufferHandles;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(bufferHandles =
+ mGralloc->allocate(descriptor, count, false, &stride));
+
+ if (count >= 1) {
+ EXPECT_LE(mDummyDescriptorInfo.width, stride) << "invalid buffer stride";
+ }
+
+ for (auto bufferHandle : bufferHandles) {
+ mGralloc->freeBuffer(bufferHandle);
+ }
+ }
+}
+
+/**
+ * Test IAllocator::allocate with invalid buffer descriptors.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+ // this assumes any valid descriptor is non-empty
+ BufferDescriptor descriptor;
+ mGralloc->getAllocator()->allocate(descriptor, 1,
+ [&](const auto& tmpError, const auto&, const auto&) {
+ EXPECT_EQ(Error::BAD_DESCRIPTOR, tmpError);
+ });
+}
+
+/**
+ * Test IAllocator::allocate does not leak.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+ auto info = mDummyDescriptorInfo;
+ info.width = 1024;
+ info.height = 1024;
+
+ for (int i = 0; i < 2048; i++) {
+ auto bufferHandle = mGralloc->allocate(info, false);
+ mGralloc->freeBuffer(bufferHandle);
+ }
+}
+
+/**
+ * Test that IAllocator::allocate is thread-safe.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateThreaded) {
+ BufferDescriptor descriptor;
+ ASSERT_NO_FATAL_FAILURE(descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
+
+ std::atomic<bool> timeUp(false);
+ std::atomic<uint64_t> allocationCount(0);
+ auto threadLoop = [&]() {
+ while (!timeUp) {
+ mGralloc->getAllocator()->allocate(
+ descriptor, 1, [&](const auto&, const auto&, const auto&) { allocationCount++; });
+ }
+ };
+
+ std::vector<std::thread> threads;
+ for (int i = 0; i < 8; i++) {
+ threads.push_back(std::thread(threadLoop));
+ }
+
+ std::this_thread::sleep_for(std::chrono::seconds(3));
+ timeUp = true;
+ LOG(VERBOSE) << "Made " << allocationCount << " threaded allocations";
+
+ for (auto& thread : threads) {
+ thread.join();
+ }
+}
+
+/**
+ * Test IMapper::createDescriptor with valid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+ ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
+}
+
+/**
+ * Test IMapper::createDescriptor with invalid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+ auto info = mDummyDescriptorInfo;
+ info.width = 0;
+ mGralloc->getMapper()->createDescriptor(info, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_VALUE, tmpError) << "createDescriptor did not fail with BAD_VALUE";
+ });
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+ const native_handle_t* bufferHandle;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+ const native_handle_t* clonedBufferHandle;
+ ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+
+ // A cloned handle is a raw handle. Check that we can import it multiple
+ // times.
+ const native_handle_t* importedBufferHandles[2];
+ ASSERT_NO_FATAL_FAILURE(importedBufferHandles[0] = mGralloc->importBuffer(clonedBufferHandle));
+ ASSERT_NO_FATAL_FAILURE(importedBufferHandles[1] = mGralloc->importBuffer(clonedBufferHandle));
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[0]));
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[1]));
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(clonedBufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+ const native_handle_t* rawHandle;
+ ASSERT_NO_FATAL_FAILURE(rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+
+ native_handle_t* importedHandle = nullptr;
+ mGralloc->getMapper()->importBuffer(rawHandle, [&](const auto& tmpError, const auto& buffer) {
+ ASSERT_EQ(Error::NONE, tmpError);
+ importedHandle = static_cast<native_handle_t*>(buffer);
+ });
+
+ // free the imported handle with another mapper
+ std::unique_ptr<Gralloc> anotherGralloc;
+ ASSERT_NO_FATAL_FAILURE(
+ anotherGralloc = std::make_unique<Gralloc>(
+ GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
+ GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
+ ASSERT_EQ(Error::NONE, error);
+
+ ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+ auto info = mDummyDescriptorInfo;
+ info.width = 1024;
+ info.height = 1024;
+
+ for (int i = 0; i < 2048; i++) {
+ auto bufferHandle = mGralloc->allocate(info, true);
+ mGralloc->freeBuffer(bufferHandle);
+ }
+}
+
+/**
+ * Test IMapper::importBuffer with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "importBuffer with nullptr did not fail with BAD_BUFFER";
+ });
+
+ invalidHandle = native_handle_create(0, 0);
+ mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "importBuffer with invalid handle did not fail with BAD_BUFFER";
+ });
+ native_handle_delete(invalidHandle);
+}
+
+/**
+ * Test IMapper::freeBuffer with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+ EXPECT_EQ(Error::BAD_BUFFER, error) << "freeBuffer with nullptr did not fail with BAD_BUFFER";
+
+ invalidHandle = native_handle_create(0, 0);
+ error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+ EXPECT_EQ(Error::BAD_BUFFER, error)
+ << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
+ native_handle_delete(invalidHandle);
+
+ const native_handle_t* clonedBufferHandle;
+ ASSERT_NO_FATAL_FAILURE(clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+ error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+ EXPECT_EQ(Error::BAD_BUFFER, error)
+ << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
+
+ mGralloc->freeBuffer(clonedBufferHandle);
+}
+
+/**
+ * Test IMapper::lock and IMapper::unlock.
+ */
+TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+ const auto& info = mDummyDescriptorInfo;
+
+ const native_handle_t* bufferHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
+
+ // lock buffer for writing
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+ int fence = -1;
+ uint8_t* data;
+ ASSERT_NO_FATAL_FAILURE(
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+
+ // RGBA_8888
+ size_t strideInBytes = stride * 4;
+ size_t writeInBytes = info.width * 4;
+
+ for (uint32_t y = 0; y < info.height; y++) {
+ memset(data, y, writeInBytes);
+ data += strideInBytes;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+
+ // lock again for reading
+ ASSERT_NO_FATAL_FAILURE(
+ data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+ for (uint32_t y = 0; y < info.height; y++) {
+ for (size_t i = 0; i < writeInBytes; i++) {
+ EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
+ }
+ data += strideInBytes;
+ }
+
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
+}
+
+/**
+ * Test IMapper::lockYCbCr. This locks a YV12 buffer, and makes sure we can
+ * write to and read from it.
+ */
+TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+ auto info = mDummyDescriptorInfo;
+ info.format = PixelFormat::YV12;
+
+ const native_handle_t* bufferHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
+
+ // lock buffer for writing
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+ int fence = -1;
+ YCbCrLayout layout;
+ ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
+
+ auto yData = static_cast<uint8_t*>(layout.y);
+ auto cbData = static_cast<uint8_t*>(layout.cb);
+ auto crData = static_cast<uint8_t*>(layout.cr);
+ for (uint32_t y = 0; y < info.height; y++) {
+ for (uint32_t x = 0; x < info.width; x++) {
+ auto val = static_cast<uint8_t>(info.height * y + x);
+
+ yData[layout.yStride * y + x] = val;
+ if (y % 2 == 0 && x % 2 == 0) {
+ cbData[layout.cStride * y / 2 + x / 2] = val;
+ crData[layout.cStride * y / 2 + x / 2] = val;
+ }
+ }
+ }
+
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+
+ // lock again for reading
+ ASSERT_NO_FATAL_FAILURE(layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
+
+ yData = static_cast<uint8_t*>(layout.y);
+ cbData = static_cast<uint8_t*>(layout.cb);
+ crData = static_cast<uint8_t*>(layout.cr);
+ for (uint32_t y = 0; y < info.height; y++) {
+ for (uint32_t x = 0; x < info.width; x++) {
+ auto val = static_cast<uint8_t>(info.height * y + x);
+
+ EXPECT_EQ(val, yData[layout.yStride * y + x]);
+ if (y % 2 == 0 && x % 2 == 0) {
+ EXPECT_EQ(val, cbData[layout.cStride * y / 2 + x / 2]);
+ EXPECT_EQ(val, crData[layout.cStride * y / 2 + x / 2]);
+ }
+ }
+ }
+
+ ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+ if (fence >= 0) {
+ close(fence);
+ }
+}
+
+/**
+ * Test IMapper::unlock with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+ native_handle_t* invalidHandle = nullptr;
+ mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with nullptr did not fail with BAD_BUFFER";
+ });
+
+ invalidHandle = native_handle_create(0, 0);
+ mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with invalid handle did not fail with BAD_BUFFER";
+ });
+ native_handle_delete(invalidHandle);
+
+ ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast<native_handle_t*>(
+ mGralloc->allocate(mDummyDescriptorInfo, false)));
+ mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with un-imported handle did not fail with BAD_BUFFER";
+ });
+ mGralloc->freeBuffer(invalidHandle);
+
+// disabled as it fails on many existing drivers
+#if 0
+ ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast<native_handle_t*>(
+ mGralloc->allocate(mDummyDescriptorInfo, true)));
+ mGralloc->getMapper()->unlock(
+ invalidHandle, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "unlock with unlocked handle did not fail with BAD_BUFFER";
+ });
+ mGralloc->freeBuffer(invalidHandle);
+#endif
+}
+
+} // namespace
+} // namespace vts
+} // namespace V3_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+int main(int argc, char** argv) {
+ using android::hardware::graphics::mapper::V3_0::vts::GraphicsMapperHidlEnvironment;
+ ::testing::AddGlobalTestEnvironment(GraphicsMapperHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ GraphicsMapperHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}