From: Piotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics
Date: Mon, 6 Jul 2020 05:16:50 +0000 (+0200)
Subject: [Metadata] Implementation of get() and release()
X-Git-Tag: submit/tizen/20200708.105445~3
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cafaa4162acd373ad859677d5cc8796248f4a7b4;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git
[Metadata] Implementation of get() and release()
Implementation supports release() which frees all resources allocated
for metadata extraction.
Implementation supports get() for gathering metadata values. If get is called
after release(), API automatically recreates all handles for file.
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-265
[Verification] Chcecked in chrome console:
> m = tizen.metadata.createFileHandle("file:///home/owner/media/Videos/mp4video_mp3audio.mp4")
> m.get("DURATION")
> m.release()
> m.get("DURATION")
> m.get("VIDEO_WIDTH")
> m.release()
Change-Id: I2ed27a7c8009325817c32c993f5f8d4f00cd063e
---
diff --git a/src/metadata/metadata_api.js b/src/metadata/metadata_api.js
index 5b877c95..d89b5ad8 100755
--- a/src/metadata/metadata_api.js
+++ b/src/metadata/metadata_api.js
@@ -21,6 +21,44 @@ var types_ = validator_.Types;
var T_ = privUtils_.type;
var native_ = new xwalk.utils.NativeManager(extension);
+var MetadataType = {
+ ALBUM: 'ALBUM',
+ ALBUM_ARTIST: 'ALBUM_ARTIST',
+ ALTITUDE: 'ALTITUDE',
+ ARTIST: 'ARTIST',
+ AUDIO_BITPERSAMPLE: 'AUDIO_BITPERSAMPLE',
+ AUDIO_BITRATE: 'AUDIO_BITRATE',
+ AUDIO_CHANNELS: 'AUDIO_CHANNELS',
+ AUDIO_CODEC: 'AUDIO_CODEC',
+ AUDIO_SAMPLERATE: 'AUDIO_SAMPLERATE',
+ CLASSIFICATION: 'CLASSIFICATION',
+ COMMENT: 'COMMENT',
+ COMPOSER: 'COMPOSER',
+ CONDUCTOR: 'CONDUCTOR',
+ COPYRIGHT: 'COPYRIGHT',
+ DATE: 'DATE',
+ DESCRIPTION: 'DESCRIPTION',
+ DURATION: 'DURATION',
+ GENRE: 'GENRE',
+ HAS_AUDIO: 'HAS_AUDIO',
+ HAS_VIDEO: 'HAS_VIDEO',
+ LATITUDE: 'LATITUDE',
+ LONGITUDE: 'LONGITUDE',
+ MODE_360: 'MODE_360',
+ RATING: 'RATING',
+ RECDATE: 'RECDATE',
+ ROTATE: 'ROTATE',
+ SYNCLYRICS_NUM: 'SYNCLYRICS_NUM',
+ TITLE: 'TITLE',
+ TRACK_NUM: 'TRACK_NUM',
+ UNSYNCLYRICS: 'UNSYNCLYRICS',
+ VIDEO_BITRATE: 'VIDEO_BITRATE',
+ VIDEO_CODEC: 'VIDEO_CODEC',
+ VIDEO_FPS: 'VIDEO_FPS',
+ VIDEO_HEIGHT: 'VIDEO_HEIGHT',
+ VIDEO_WIDTH: 'VIDEO_WIDTH'
+};
+
function MetadataManager() {}
MetadataManager.prototype.createFileHandle = function() {
@@ -54,5 +92,40 @@ function MetadataFileHandle(data) {
});
}
+MetadataFileHandle.prototype.get = function() {
+ var args = validator_.validateArgs(arguments, [
+ {
+ name: 'type',
+ type: types_.ENUM,
+ values: Object.keys(MetadataType)
+ }
+ ]);
+ var data = {
+ path: this.path,
+ id: this._id,
+ type: args.type
+ };
+
+ var result = native_.callSync('MetadataFileHandleGet', data);
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ return native_.getResultObject(result);
+};
+
+MetadataFileHandle.prototype.release = function() {
+ var data = {
+ id: this._id
+ };
+
+ var result = native_.callSync('MetadataFileHandleRelease', data);
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ return native_.getResultObject(result);
+};
+
// Exports
exports = new MetadataManager();
diff --git a/src/metadata/metadata_file_handle.cc b/src/metadata/metadata_file_handle.cc
index ed7dc303..920a9abc 100644
--- a/src/metadata/metadata_file_handle.cc
+++ b/src/metadata/metadata_file_handle.cc
@@ -17,6 +17,7 @@
#include "metadata/metadata_file_handle.h"
#include "common/logger.h"
+#include "common/platform_enum.h"
#include "common/platform_exception.h"
namespace extension {
@@ -24,6 +25,45 @@ namespace metadata {
using namespace common;
+namespace types {
+const common::PlatformEnum MetadataTypeEnum{
+ {"ALBUM", METADATA_ALBUM},
+ {"ALBUM_ARTIST", METADATA_ALBUM_ARTIST},
+ {"ALTITUDE", METADATA_ALTITUDE},
+ {"ARTIST", METADATA_ARTIST},
+ {"AUDIO_BITPERSAMPLE", METADATA_AUDIO_BITPERSAMPLE},
+ {"AUDIO_BITRATE", METADATA_AUDIO_BITRATE},
+ {"AUDIO_CHANNELS", METADATA_AUDIO_CHANNELS},
+ {"AUDIO_CODEC", METADATA_AUDIO_CODEC},
+ {"AUDIO_SAMPLERATE", METADATA_AUDIO_SAMPLERATE},
+ {"CLASSIFICATION", METADATA_CLASSIFICATION},
+ {"COMMENT", METADATA_COMMENT},
+ {"COMPOSER", METADATA_COMPOSER},
+ {"CONDUCTOR", METADATA_CONDUCTOR},
+ {"COPYRIGHT", METADATA_COPYRIGHT},
+ {"DATE", METADATA_DATE},
+ {"DESCRIPTION", METADATA_DESCRIPTION},
+ {"DURATION", METADATA_DURATION},
+ {"GENRE", METADATA_GENRE},
+ {"HAS_AUDIO", METADATA_HAS_AUDIO},
+ {"HAS_VIDEO", METADATA_HAS_VIDEO},
+ {"LATITUDE", METADATA_LATITUDE},
+ {"LONGITUDE", METADATA_LONGITUDE},
+ {"MODE_360", METADATA_360},
+ {"RATING", METADATA_RATING},
+ {"RECDATE", METADATA_RECDATE},
+ {"ROTATE", METADATA_ROTATE},
+ {"SYNCLYRICS_NUM", METADATA_SYNCLYRICS_NUM},
+ {"TITLE", METADATA_TITLE},
+ {"TRACK_NUM", METADATA_TRACK_NUM},
+ {"UNSYNCLYRICS", METADATA_UNSYNCLYRICS},
+ {"VIDEO_BITRATE", METADATA_VIDEO_BITRATE},
+ {"VIDEO_CODEC", METADATA_VIDEO_CODEC},
+ {"VIDEO_FPS", METADATA_VIDEO_FPS},
+ {"VIDEO_HEIGHT", METADATA_VIDEO_HEIGHT},
+ {"VIDEO_WIDTH", METADATA_VIDEO_WIDTH}};
+}
+
PlatformResult convertErrorCode(int err) {
switch (err) {
case METADATA_EXTRACTOR_ERROR_FILE_EXISTS:
@@ -98,5 +138,30 @@ picojson::value MetadataFileHandle::ToJSON() {
return result;
}
+PlatformResult MetadataFileHandle::Get(const std::string& type, std::string* result) {
+ ScopeLogger();
+
+ metadata_extractor_attr_e native_type;
+ auto res = types::MetadataTypeEnum.getValue(type, &native_type);
+ if (!res) {
+ LoggerE("MetadataTypeEnum.getValue() failed, error: %s", res.message().c_str());
+ return res;
+ }
+
+ char* value = nullptr;
+ int native_res = metadata_extractor_get_metadata(handle_, native_type, &value);
+ if (METADATA_EXTRACTOR_ERROR_NONE != native_res) {
+ LoggerE("Error during getting metadata: %d", native_res);
+ return convertErrorCode(native_res);
+ }
+ // it is possible that native function returns success, but
+ // value is null in case when metadata is missing in file, thus returning empty string then
+ if (value) {
+ *result = value;
+ free(value);
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // namespace metadata
} // namespace extension
diff --git a/src/metadata/metadata_file_handle.h b/src/metadata/metadata_file_handle.h
index e6800a9a..da5bb4f5 100644
--- a/src/metadata/metadata_file_handle.h
+++ b/src/metadata/metadata_file_handle.h
@@ -36,6 +36,7 @@ class MetadataFileHandle {
picojson::value ToJSON();
common::PlatformResult Initialize(const std::string& path);
+ common::PlatformResult Get(const std::string& type, std::string* result);
private:
metadata_extractor_h handle_;
diff --git a/src/metadata/metadata_instance.cc b/src/metadata/metadata_instance.cc
index 8734db0e..25643bac 100644
--- a/src/metadata/metadata_instance.cc
+++ b/src/metadata/metadata_instance.cc
@@ -88,15 +88,57 @@ void MetadataInstance::MetadataManagerCreateFileHandle(const picojson::value& ar
void MetadataInstance::MetadataFileHandleGet(const picojson::value& args, picojson::object& out) {
ScopeLogger();
+ const std::string& path = args.get("path").get();
+ const int id = static_cast(args.get("id").get());
+ const std::string& type = args.get("type").get();
+
+ LoggerD("File: %s getting metadata type: %s", path.c_str(), type.c_str());
+
+ std::string value;
+
+ auto it = handles_map_.find(id);
+ if (handles_map_.end() == it) {
+ LoggerD("Handle does not exist in map, creating new one");
+ // re- create handle
+ auto m = MetadataFileHandle{id};
+ auto res = m.Initialize(path);
+ if (!res) {
+ // if everything works fine with a file, handle should be created successfully, as this is a
+ // re-creation. In case of errors, just return an AbortError
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Unknown error during accessing a file."), &out);
+ return;
+ }
+ // store it in the map
+ handles_map_.insert(std::pair(id, std::move(m)));
+ }
- LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Not implemented yet"), &out);
+ try {
+ MetadataFileHandle& m = handles_map_.at(id);
+ auto res = m.Get(type, &value);
+ if (!res) {
+ LogAndReportError(res, &out);
+ return;
+ }
+ } catch (...) {
+ // this should never happen
+ LogAndReportError(
+ PlatformResult(ErrorCode::ABORT_ERR, "Unknown error during accessing a file."), &out);
+ return;
+ }
+
+ ReportSuccess(picojson::value(value), out);
}
void MetadataInstance::MetadataFileHandleRelease(const picojson::value& args,
picojson::object& out) {
ScopeLogger();
+ const int id = static_cast(args.get("id").get());
+
+ int erased_elems = handles_map_.erase(id);
+ LoggerD("Released %d handle for id %d", erased_elems, id);
- LogAndReportError(PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Not implemented yet"), &out);
+ ReportSuccess(out);
}
} // namespace metadata