2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "content/content_manager.h"
22 #include <metadata_extractor.h>
28 #include "common/converter.h"
29 #include "common/logger.h"
30 #include "common/scope_exit.h"
31 #include "common/tools.h"
32 #include "common/filesystem/filesystem_provider.h"
34 #include "content/content_filter.h"
37 using namespace common;
39 using common::tools::ReportSuccess;
40 using common::tools::ReportError;
46 static const std::string uri_prefix = "file://";
47 static const std::string uri_absolute_prefix = "file:///";
50 const std::map<std::string, media_content_orientation_e> orientationMap = {
51 {"NORMAL", MEDIA_CONTENT_ORIENTATION_NORMAL},
52 {"FLIP_HORIZONTAL", MEDIA_CONTENT_ORIENTATION_HFLIP},
53 {"ROTATE_180", MEDIA_CONTENT_ORIENTATION_ROT_180},
54 {"FLIP_VERTICAL", MEDIA_CONTENT_ORIENTATION_VFLIP},
55 {"TRANSPOSE", MEDIA_CONTENT_ORIENTATION_TRANSPOSE},
56 {"ROTATE_90", MEDIA_CONTENT_ORIENTATION_ROT_90},
57 {"TRANSVERSE", MEDIA_CONTENT_ORIENTATION_TRANSVERSE},
58 {"ROTATE_270", MEDIA_CONTENT_ORIENTATION_ROT_270},
61 std::string get_date(char* tmpStr) {
64 struct tm* result = (struct tm*) calloc(1, sizeof(struct tm));
65 if (nullptr != result) {
66 if (strptime(tmpStr, "%Y:%m:%d %H:%M:%S", result) == NULL) {
70 time_t t = mktime(result);// + get_utc_offset() * 3600;
71 std::stringstream str_date;
74 return str_date.str();
81 void ContentToJson(media_info_h info, picojson::object& o) {
89 long long unsigned int tmpLong;
90 media_content_type_e type;
92 ret = media_info_get_media_type(info, &type);
94 if (ret != MEDIA_CONTENT_ERROR_NONE) {
95 LOGGER(ERROR) << "Get media type failed: " << ret;
96 type = MEDIA_CONTENT_TYPE_OTHERS;
99 if (type == MEDIA_CONTENT_TYPE_IMAGE) {
100 o["type"] = picojson::value(std::string("IMAGE"));
102 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_image(info, &img)) {
103 std::unique_ptr<std::remove_pointer<image_meta_h>::type, int(*)(image_meta_h)>
104 img_ptr(img, &image_meta_destroy); // automatically release the memory
105 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_date_taken(img, &tmpStr)) {
107 o["releaseDate"] = picojson::value(get_date(tmpStr));
112 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_width(img, &tmpInt)) {
113 o["width"] = picojson::value(static_cast<double>(tmpInt));
115 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_height(img, &tmpInt)) {
116 o["height"] = picojson::value(static_cast<double>(tmpInt));
118 picojson::object geo;
119 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_latitude(info, &tmpDouble)) {
120 geo["latitude"] = picojson::value(tmpDouble);
122 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_longitude(info, &tmpDouble)) {
123 geo["longitude"] = picojson::value(tmpDouble);
125 o["geolocation"] = picojson::value(geo);
127 media_content_orientation_e orientation;
128 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_orientation(img, &orientation)) {
129 switch (orientation) {
130 case MEDIA_CONTENT_ORIENTATION_NOT_AVAILABLE:
131 case MEDIA_CONTENT_ORIENTATION_NORMAL:
134 case MEDIA_CONTENT_ORIENTATION_HFLIP:
135 ori = "FLIP_HORIZONTAL";
137 case MEDIA_CONTENT_ORIENTATION_ROT_180:
140 case MEDIA_CONTENT_ORIENTATION_VFLIP:
141 ori = "FLIP_VERTICAL";
143 case MEDIA_CONTENT_ORIENTATION_TRANSPOSE:
146 case MEDIA_CONTENT_ORIENTATION_ROT_90:
149 case MEDIA_CONTENT_ORIENTATION_TRANSVERSE:
152 case MEDIA_CONTENT_ORIENTATION_ROT_270:
156 o["orientation"] = picojson::value(ori);
159 } else if (type == MEDIA_CONTENT_TYPE_VIDEO) {
160 o["type"] = picojson::value(std::string("VIDEO"));
162 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_video(info, &video)) {
163 std::unique_ptr<std::remove_pointer<video_meta_h>::type, int(*)(video_meta_h)>
164 video_ptr(video, &video_meta_destroy); // automatically release the memory
165 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_width(video, &tmpInt)) {
166 o["width"] = picojson::value(static_cast<double>(tmpInt));
169 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_height(video, &tmpInt)) {
170 o["height"] = picojson::value(static_cast<double>(tmpInt));
172 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_artist(video, &tmpStr)) {
173 picojson::array artists;
175 artists.push_back(picojson::value(std::string(tmpStr)));
179 o["artists"] = picojson::value(artists);
181 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_album(video, &tmpStr)) {
183 o["album"] = picojson::value(tmpStr);
188 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_duration(video, &tmpInt)) {
189 o["duration"] = picojson::value(static_cast<double>(tmpInt));
191 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_recorded_date(video, &tmpStr)) {
193 o["releaseDate"] = picojson::value(get_date(tmpStr));
199 picojson::object geo;
200 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_latitude(info, &tmpDouble)) {
201 geo["latitude"] = picojson::value(tmpDouble);
203 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_longitude(info, &tmpDouble)) {
204 geo["longitude"] = picojson::value(tmpDouble);
206 o["geolocation"] = picojson::value(geo);
207 } else if (type == MEDIA_CONTENT_TYPE_SOUND || type == MEDIA_CONTENT_TYPE_MUSIC) {
208 o["type"] = picojson::value(std::string("AUDIO"));
210 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_audio(info, &audio)) {
211 std::unique_ptr<std::remove_pointer<audio_meta_h>::type, int(*)(audio_meta_h)>
212 audio_ptr(audio, &audio_meta_destroy); // automatically release the memory
213 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_recorded_date(audio, &tmpStr)) {
215 o["releaseDate"] = picojson::value(get_date(tmpStr));
220 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_album(audio, &tmpStr)) {
222 o["album"] = picojson::value(std::string(tmpStr));
227 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_artist(audio, &tmpStr)) {
229 picojson::array artists;
230 artists.push_back(picojson::value(std::string(tmpStr)));
231 o["artists"] = picojson::value(artists);
236 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_genre(audio, &tmpStr)) {
238 picojson::array genres;
239 genres.push_back(picojson::value(std::string(tmpStr)));
240 o["genres"] = picojson::value(genres);
245 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_composer(audio, &tmpStr)) {
247 picojson::array composers;
248 composers.push_back(picojson::value(std::string(tmpStr)));
249 o["composers"] = picojson::value(composers);
254 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_copyright(audio, &tmpStr)) {
256 o["copyright"] = picojson::value(std::string(tmpStr));
261 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_bit_rate(audio, &tmpInt)) {
262 o["bitrate"] = picojson::value(static_cast<double>(tmpInt));
264 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_track_num(audio, &tmpStr)) {
266 o["trackNumber"] = picojson::value(static_cast<double>(std::atoi(tmpStr)));
271 o["trackNumber"] = picojson::value();
274 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_duration(audio, &tmpInt)) {
275 o["duration"] = picojson::value(static_cast<double>(tmpInt));
279 o["type"] = picojson::value(std::string("OTHER"));
282 ret = media_info_get_media_id(info, &tmpStr);
283 if(ret == MEDIA_CONTENT_ERROR_NONE) {
285 o["id"] = picojson::value(std::string(tmpStr));
290 ret = media_info_get_display_name(info, &tmpStr);
291 if(ret == MEDIA_CONTENT_ERROR_NONE) {
293 o["name"] = picojson::value(std::string(tmpStr));
299 ret = media_info_get_mime_type(info, &tmpStr);
300 if(ret == MEDIA_CONTENT_ERROR_NONE) {
302 o["mimeType"] = picojson::value(std::string(tmpStr));
307 ret = media_info_get_title(info, &tmpStr);
308 if(ret == MEDIA_CONTENT_ERROR_NONE) {
310 o["title"] = picojson::value(std::string(tmpStr));
315 ret = media_info_get_file_path(info, &tmpStr);
316 if(ret == MEDIA_CONTENT_ERROR_NONE) {
318 o["contentURI"] = picojson::value(std::string(tmpStr));
323 ret = media_info_get_thumbnail_path(info, &tmpStr);
324 if(ret == MEDIA_CONTENT_ERROR_NONE) {
326 picojson::array thumbnails;
327 thumbnails.push_back(picojson::value(std::string(tmpStr)));
328 o["thumbnailURIs"] = picojson::value(thumbnails);
333 ret = media_info_get_description(info, &tmpStr);
334 if(ret == MEDIA_CONTENT_ERROR_NONE) {
336 o["description"] = picojson::value(std::string(tmpStr));
341 ret = media_info_get_rating(info, &tmpInt);
342 if(ret == MEDIA_CONTENT_ERROR_NONE) {
343 o["rating"] = picojson::value(static_cast<double>(tmpInt));
345 ret = media_info_get_size(info, &tmpLong);
346 if(ret == MEDIA_CONTENT_ERROR_NONE) {
347 o["size"] = picojson::value(static_cast<double>(tmpLong));
349 ret = media_info_get_favorite(info, &tmpBool);
350 if(ret == MEDIA_CONTENT_ERROR_NONE) {
351 o["isFavorite"] = picojson::value(tmpBool);
353 ret = media_info_get_modified_time(info, &tmpDate);
354 if(ret == MEDIA_CONTENT_ERROR_NONE) {
355 o["modifiedDate"] = picojson::value(static_cast<double>(tmpDate));
359 void ContentDirToJson(media_folder_h folder, picojson::object& o) {
363 media_content_storage_e storage_type;
367 ret = media_folder_get_folder_id(folder, &tmpStr);
368 if(ret == MEDIA_CONTENT_ERROR_NONE) {
370 o["id"] = picojson::value(std::string(tmpStr));
377 ret = media_folder_get_path(folder, &tmpStr);
378 if(ret == MEDIA_CONTENT_ERROR_NONE) {
380 o["directoryURI"] = picojson::value(std::string(tmpStr));
387 ret = media_folder_get_name(folder, &tmpStr);
388 if(ret == MEDIA_CONTENT_ERROR_NONE) {
390 o["title"] = picojson::value(std::string(tmpStr));
397 ret = media_folder_get_storage_type(folder, &storage_type);
398 if(ret == MEDIA_CONTENT_ERROR_NONE) {
399 if (storage_type == MEDIA_CONTENT_STORAGE_INTERNAL) {
400 o["storageType"] = picojson::value(std::string("INTERNAL"));
401 } else if (storage_type == MEDIA_CONTENT_STORAGE_EXTERNAL) {
402 o["storageType"] = picojson::value(std::string("EXTERNAL"));
403 } else if (storage_type == MEDIA_CONTENT_STORAGE_CLOUD) {
404 o["storageType"] = picojson::value(std::string("CLOUD"));
409 ret = media_folder_get_modified_time(folder, &tmpDate);
410 if(ret == MEDIA_CONTENT_ERROR_NONE) {
411 o["modifiedDate"] = picojson::value(static_cast<double>(tmpDate));
415 static int setContent(media_info_h media, const picojson::value& content) {
419 std::string name = content.get("name").to_str();
420 std::string description = content.get("description").to_str();
421 int rating = std::stoi(content.get("rating").to_str());
422 bool is_fav = content.get("isFavorite").get<bool>();
425 LoggerE("MEDIA_CONTENT_ERROR_DB_FAILED");
426 return MEDIA_CONTENT_ERROR_DB_FAILED;
429 media_content_type_e type;
430 ret = media_info_get_media_type(media, &type);
431 if (ret != MEDIA_CONTENT_ERROR_NONE) {
432 LoggerE("Failed: media_info_get_media_type()");
436 ret = media_info_set_display_name(media, name.c_str());
437 if (ret != MEDIA_CONTENT_ERROR_NONE) {
438 LoggerE("Updating name failed.");
441 ret = media_info_set_description(media, description.c_str());
442 if (ret != MEDIA_CONTENT_ERROR_NONE) {
443 LoggerE("Updating description failed.");
446 ret = media_info_set_rating(media, rating);
447 if (ret != MEDIA_CONTENT_ERROR_NONE) {
448 LoggerE("Updating rating failed.");
451 ret = media_info_set_favorite(media, is_fav);
452 if (ret != MEDIA_CONTENT_ERROR_NONE) {
453 LoggerE("Updating isFavorite failed.");
456 if (ret != MEDIA_CONTENT_ERROR_NONE) {
457 LoggerE("Updating favorite failed.");
460 if (type == MEDIA_CONTENT_TYPE_IMAGE) {
461 std::string orientation = content.get("orientation").to_str();
462 auto orientationToSet = orientationMap.find(orientation);
464 if (orientationToSet != orientationMap.end()) {
466 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_image(media, &img) &&
467 MEDIA_CONTENT_ERROR_NONE == image_meta_set_orientation(img, orientationToSet->second) &&
468 MEDIA_CONTENT_ERROR_NONE == image_meta_update_to_db(img)) {
469 LoggerD("orientation update was successful");
471 LoggerE("orientation update failed");
473 image_meta_destroy(img);
477 if (type == MEDIA_CONTENT_TYPE_IMAGE || type == MEDIA_CONTENT_TYPE_VIDEO) {
478 picojson::value geo = content.get("geolocation");
479 if (geo.evaluate_as_boolean()) {
480 LoggerD("geolocation is not null");
481 double latitude = atof(geo.get("latitude").to_str().c_str());
482 double longitude = atof(geo.get("longitude").to_str().c_str());
483 ret = media_info_set_latitude(media, latitude);
484 if (ret != MEDIA_CONTENT_ERROR_NONE) {
485 LoggerE("Updating geolocation is failed.");
487 ret = media_info_set_longitude(media, longitude);
488 if (ret != MEDIA_CONTENT_ERROR_NONE) {
489 LoggerD("Updating geolocation is failed.");
492 LoggerD("geolocation is null");
496 return MEDIA_CONTENT_ERROR_NONE;
499 static void FolderToJson(media_folder_h folder, picojson::object* out) {
506 media_content_storage_e storageType;
510 ret = media_folder_get_folder_id(folder, &id);
511 if(ret!=MEDIA_CONTENT_ERROR_NONE)
513 LogAndReportError(ContentManager::convertError(ret), out,
514 ("Failed: media_folder_get_folder_id"));
518 ret = media_folder_get_name(folder, &name);
519 if(ret!=MEDIA_CONTENT_ERROR_NONE)
521 LogAndReportError(ContentManager::convertError(ret), out,
522 ("Failed: media_folder_get_name"));
527 ret = media_folder_get_path(folder, &path);
528 if(ret!=MEDIA_CONTENT_ERROR_NONE)
530 LogAndReportError(ContentManager::convertError(ret), out,
531 ("Failed: media_folder_get_path"));
537 ret = media_folder_get_modified_time(folder, &date);
538 if(ret!=MEDIA_CONTENT_ERROR_NONE)
540 LogAndReportError(ContentManager::convertError(ret), out,
541 ("Failed: media_folder_get_path"));
548 ret = media_folder_get_storage_type(folder, &storageType);
549 if(ret!=MEDIA_CONTENT_ERROR_NONE)
554 LogAndReportError(ContentManager::convertError(ret), out,
555 ("Failed: media_folder_get_storage_type"));
560 (*out)["id"] = picojson::value(std::string(id));
561 (*out)["directoryURI"] = picojson::value(std::string(path));
562 (*out)["title"] = picojson::value(std::string(name));
564 if (storageType == MEDIA_CONTENT_STORAGE_INTERNAL) {
565 (*out)["storageType"] = picojson::value(std::string("INTERNAL"));
566 } else if (storageType == MEDIA_CONTENT_STORAGE_EXTERNAL) {
567 (*out)["storageType"] = picojson::value(std::string("EXTERNAL"));
570 (*out)["modifiedDate"] = picojson::value(static_cast<double>(date));
577 static bool media_foreach_directory_cb(media_folder_h folder, void *user_data) {
579 picojson::array *array = static_cast<picojson::array*>(user_data);
580 picojson::object json;
581 FolderToJson(folder, &json);
582 array->push_back(picojson::value(json));
586 static bool media_foreach_content_cb(media_info_h media, void *user_data) {
588 picojson::value::array *contents = static_cast<picojson::value::array*>(user_data);
589 picojson::value::object o;
590 ContentToJson(media, o);
591 contents->push_back(picojson::value(o));
595 static bool playlist_foreach_cb(media_playlist_h playlist, void *user_data) {
598 picojson::value::array *playlists = static_cast<picojson::value::array*>(user_data);
599 picojson::value::object o;
600 if (playlist != NULL) {
602 char* thumb_path = NULL;
604 filter_h filter = NULL;
605 if( media_playlist_get_playlist_id(playlist, &id) == MEDIA_CONTENT_ERROR_NONE) {
606 std::stringstream str_id;
608 o["id"] = picojson::value(std::to_string(id));
611 LoggerD("Invalid ID for playlist.");
613 if( media_playlist_get_thumbnail_path(playlist, &thumb_path) == MEDIA_CONTENT_ERROR_NONE) {
614 if (thumb_path != NULL) {
615 std::string thumbnail_uri (thumb_path);
616 if (thumbnail_uri != " ") {
617 thumbnail_uri = uri_prefix + thumbnail_uri;
619 o["thumbnailURI"] = picojson::value(thumbnail_uri);
623 o["thumbnailURI"] = picojson::value();//picojson::value(std::string(""));
627 LoggerD("Invalid thumbnail path for playlist.");
629 if( media_playlist_get_name(playlist, &name) == MEDIA_CONTENT_ERROR_NONE) {
630 o["name"] = picojson::value(std::string(name));
634 LoggerD("Invalid name for playlist.");
637 media_filter_create(&filter);
638 std::unique_ptr<std::remove_pointer<filter_h>::type, int(*)(filter_h)>
639 filter_ptr(filter, &media_filter_destroy); // automatically release the memory
640 if( media_playlist_get_media_count_from_db(id, filter, &cnt) == MEDIA_CONTENT_ERROR_NONE) {
641 o["numberOfTracks"] = picojson::value(static_cast<double>(cnt));
644 LoggerE("Invalid count for playlist.");
646 playlists->push_back(picojson::value(o));
652 static bool playlist_content_member_cb(int playlist_member_id, media_info_h media, void *user_data) {
655 picojson::value::array *contents = static_cast<picojson::value::array*>(user_data);
656 picojson::value::object o;
658 o["playlist_member_id"] = picojson::value(static_cast<double>(playlist_member_id));
659 ContentToJson(media, o);
660 contents->push_back(picojson::value(o));
664 void CreateThumbnailCallback(media_content_error_e err, const char* path, void* user_data) {
667 unsigned int* callbackId = (unsigned int*) user_data;
669 if (!(ContentManager::getInstance()->getContentInstance())) {
670 // There is not instance already
671 LoggerD("There is not instance now");
676 picojson::object out;
678 out["callbackId"] = picojson::value(static_cast<double>(*callbackId));
680 if (MEDIA_CONTENT_ERROR_NONE == err) {
681 out["result"] = picojson::value(std::string(path));
684 PlatformResult result = ContentManager::getInstance()->convertError(err);
685 LogAndReportError(result, &out, ("Failed to create a thumbnail"));
689 common::Instance::PostMessage(ContentManager::getInstance()->getContentInstance(),
690 picojson::value(out).serialize().c_str());
694 ContentManager::ContentManager() {
695 LoggerD("ContentManager called");
696 if(media_content_connect() == MEDIA_CONTENT_ERROR_NONE) {
697 m_dbConnected = true;
700 m_dbConnected = false;
701 m_contentInstance = nullptr;
704 ContentManager::~ContentManager() {
707 if(media_content_disconnect() == MEDIA_CONTENT_ERROR_NONE) {
708 m_dbConnected = false;
713 ContentManager* ContentManager::getInstance() {
715 static ContentManager instance;
719 ContentInstance* ContentManager::getContentInstance() {
721 return m_contentInstance;
724 void ContentManager::setContentInstance(ContentInstance* const content_instance) {
726 m_contentInstance = content_instance;
729 bool ContentManager::isConnected() {
731 return m_dbConnected;
734 void ContentManager::getDirectories(const std::shared_ptr<ReplyCallbackData>& user_data) {
738 filter_h filter = NULL;
739 ret = media_filter_create(&filter);
740 if (ret != MEDIA_CONTENT_ERROR_NONE) {
741 LoggerE("Failed: media_filter_create failed");
746 media_filter_destroy(filter);
749 std::string condition = "(FOLDER_STORAGE_TYPE = 0 OR FOLDER_STORAGE_TYPE = 1)";
750 media_filter_set_condition(filter, condition.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
752 picojson::array pico_dirs;
753 ret = media_folder_foreach_folder_from_db(filter, media_foreach_directory_cb, &pico_dirs);
754 if (ret != MEDIA_CONTENT_ERROR_NONE) {
755 PlatformResult err = LogAndCreateResult(
756 ErrorCode::UNKNOWN_ERR, "Getting the directories failed.",
757 ("Failed: Getting the directories failed %d (%s)",
758 ret, get_error_message(ret)));
759 user_data->isSuccess = err;
763 user_data->result = picojson::value(pico_dirs);
766 void ContentManager::find(const std::shared_ptr<ReplyCallbackData>& user_data) {
773 picojson::value::array arrayContent;
774 filter_h filter = nullptr;
775 media_filter_create(&filter);
778 media_filter_destroy(filter);
782 if (!IsNull(user_data->args.get("filter"))) {
783 ContentFilter filterMechanism;
785 picojson::object argsObject = JsonCast<picojson::object>(user_data->args);
786 if (filterMechanism.BuildQuery(
787 FromJson<picojson::object>(argsObject, "filter"), &query)) {
788 LOGGER(DEBUG) << "Filter query: " << query;
789 ret = media_filter_set_condition(filter, query.c_str(),
790 MEDIA_CONTENT_COLLATE_DEFAULT);
791 if (MEDIA_CONTENT_ERROR_NONE != ret) {
792 LoggerE("Platform filter setting failed, error %d", ret);
797 if (user_data->args.contains("sortMode")) {
798 picojson::value vSortMode = user_data->args.get("sortMode");
800 if (vSortMode.is<picojson::object>()) {
801 std::string sortModeName, sortModeOrder;
803 ContentFilter::MapField(vSortMode.get("attributeName").to_str(), &sortModeName);
805 sortModeOrder = vSortMode.get("order").to_str();
806 if (!sortModeOrder.empty()) {
807 media_content_order_e order = MEDIA_CONTENT_ORDER_ASC;
809 if (sortModeOrder == "ASC") {
810 order = MEDIA_CONTENT_ORDER_ASC;
811 } else if (sortModeOrder == "DESC") {
812 order = MEDIA_CONTENT_ORDER_DESC;
815 ret = media_filter_set_order(filter, order, sortModeName.c_str(),
816 MEDIA_CONTENT_COLLATE_DEFAULT);
817 if (MEDIA_CONTENT_ERROR_NONE != ret) {
818 LoggerE("Platform SortMode setting failed, error: %d", ret);
824 if (!IsNull(user_data->args.get("count"))) {
825 count = static_cast<int>(user_data->args.get("count").get<double>());
829 if (!IsNull(user_data->args.get("offset"))) {
830 offset = static_cast<int>(user_data->args.get("offset").get<double>());
834 ret = media_filter_set_offset(filter, offset, count);
835 if (MEDIA_CONTENT_ERROR_NONE != ret) {
836 LoggerE("A platform error occurs in media_filter_set_offset: %d", ret);
838 if (!IsNull(user_data->args.get("directoryId"))) {
839 dirId = user_data->args.get("directoryId").get<std::string>();
840 ret = media_folder_foreach_media_from_db(dirId.c_str(), filter, media_foreach_content_cb, static_cast<void*>(&arrayContent));
842 ret = media_info_foreach_media_from_db(filter, media_foreach_content_cb, static_cast<void*>(&arrayContent));
845 if (ret == MEDIA_CONTENT_ERROR_NONE) {
846 user_data->result = picojson::value(arrayContent);
848 PlatformResult err = LogAndCreateResult(
849 ErrorCode::UNKNOWN_ERR, "The iteration failed in platform",
850 ("The iteration failed in platform: %d (%s)",
851 ret, get_error_message(ret)));
852 user_data->isSuccess = err;
856 int ContentManager::scanFile(std::string& uri) {
858 return media_content_scan_file(uri.c_str());
861 PlatformResult ContentManager::scanDirectory(media_scan_completed_cb callback, ReplyCallbackData* cbData) {
863 const std::string& contentDirURI = cbData->args.get("contentDirURI").get<std::string>();
864 std::string real_path = common::FilesystemProvider::Create().GetRealPath(contentDirURI);
865 const bool recursive = cbData->args.get("recursive").get<bool>();
867 int ret = media_content_scan_folder(real_path.c_str(), recursive, callback, (void*) cbData);
869 if (ret != MEDIA_CONTENT_ERROR_NONE) {
870 if (MEDIA_CONTENT_ERROR_INVALID_PARAMETER == ret) {
871 return LogAndCreateResult(
872 ErrorCode::INVALID_VALUES_ERR, "Scanning content directory failed",
873 ("Scan folder failed in platform: %d (%s)", ret, get_error_message(ret)));
876 return LogAndCreateResult(
877 ErrorCode::UNKNOWN_ERR, "Scanning content directory failed",
878 ("Scan folder failed in platform: %d (%s)", ret, get_error_message(ret)));
881 return PlatformResult(ErrorCode::NO_ERROR);
884 PlatformResult ContentManager::cancelScanDirectory(const std::string& content_dir_uri) {
887 int ret = media_content_cancel_scan_folder(content_dir_uri.c_str());
888 if (ret != MEDIA_CONTENT_ERROR_NONE) {
889 return LogAndCreateResult(
890 ErrorCode::UNKNOWN_ERR, "Cancel scan content directory failed",
891 ("Cancel scan folder failed in platform: %d (%s)", ret, get_error_message(ret)));
893 return PlatformResult(ErrorCode::NO_ERROR);
896 PlatformResult ContentManager::addChangeListener(media_content_noti_h* noti_handle,
897 media_content_db_update_cb callback,
901 int ret = media_content_add_db_updated_cb(callback, user_data, noti_handle);
903 if (MEDIA_CONTENT_ERROR_NONE != ret) {
904 return LogAndCreateResult(
905 ErrorCode::ABORT_ERR,
906 "Failed to add the listener.",
907 ("Failed to add the listener: %d (%s)", ret, get_error_message(ret)));
910 return PlatformResult(ErrorCode::NO_ERROR);
913 PlatformResult ContentManager::removeChangeListener(media_content_noti_h noti_handle) {
916 int ret = media_content_remove_db_updated_cb(noti_handle);
919 case MEDIA_CONTENT_ERROR_NONE:
920 return PlatformResult(ErrorCode::NO_ERROR);
921 case MEDIA_CONTENT_ERROR_INVALID_PARAMETER:
922 // Trying to remove non-existent listener, ignoring
923 LoggerI("Failed to remove the listener: %d (%s)", ret, get_error_message(ret));
924 return PlatformResult(ErrorCode::NO_ERROR);
926 return LogAndCreateResult(
927 ErrorCode::ABORT_ERR,
928 "Failed to remove the listener.",
929 ("Failed to remove the listener: %d (%s)", ret, get_error_message(ret)));
933 PlatformResult ContentManager::setChangeListener(media_content_db_update_cb callback,
937 int ret = media_content_set_db_updated_cb(callback, user_data);
938 if(ret != MEDIA_CONTENT_ERROR_NONE) {
939 return LogAndCreateResult(
940 ErrorCode::UNKNOWN_ERR, "registering the listener is failed.",
941 ("Failed: registering the listener is failed %d (%s)", ret, get_error_message(ret)));
943 return PlatformResult(ErrorCode::NO_ERROR);
946 PlatformResult ContentManager::unSetChangeListener() {
949 int ret = media_content_unset_db_updated_cb();
950 if(ret != MEDIA_CONTENT_ERROR_NONE) {
951 return LogAndCreateResult(
952 ErrorCode::UNKNOWN_ERR, "unregistering the listener is failed.",
953 ("Failed: unregistering the listener is failed: %d (%s)", ret, get_error_message(ret)));
955 return PlatformResult(ErrorCode::NO_ERROR);
958 void ContentManager::createPlaylist(std::string name,
959 const std::shared_ptr<ReplyCallbackData>& user_data) {
961 media_playlist_h playlist = NULL;
963 int ret = media_playlist_insert_to_db(name.c_str(),&playlist);
964 std::unique_ptr<std::remove_pointer<media_playlist_h>::type, int(*)(media_playlist_h)>
965 playlist_ptr(playlist, &media_playlist_destroy); // automatically release the memory
966 if(ret != MEDIA_CONTENT_ERROR_NONE) {
967 // MEDIA_CONTENT_ERROR_DB_FAILED means that playlist probably already exists
968 PlatformResult err = LogAndCreateResult(MEDIA_CONTENT_ERROR_DB_FAILED == ret ?
969 ErrorCode::INVALID_VALUES_ERR :
970 ErrorCode::UNKNOWN_ERR, "Creation of playlist has failed.",
971 ("Failed: creation of playlist is failed: %d (%s)",
972 ret, get_error_message(ret)));
973 user_data->isSuccess = err;
976 picojson::value::object o;
978 if( playlist != NULL) {
980 char* thumb_path = NULL;
982 filter_h filter = NULL;
983 if( media_playlist_get_playlist_id(playlist, &id) == MEDIA_CONTENT_ERROR_NONE) {
984 o["id"] = picojson::value(std::to_string(id));
987 PlatformResult err = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "loading of playlist is failed.");
988 user_data->isSuccess = err;
991 if( media_playlist_get_thumbnail_path(playlist, &thumb_path) == MEDIA_CONTENT_ERROR_NONE) {
992 if (thumb_path != NULL) {
993 o["thumbnailURI"] = picojson::value(std::string(thumb_path));
997 o["thumbnailURI"] = picojson::value();
1001 LoggerE("Invalid thumbnail path for playlist.");
1003 if( media_playlist_get_name(playlist, &name) == MEDIA_CONTENT_ERROR_NONE) {
1004 o["name"] = picojson::value(std::string(name));
1008 LoggerE("Invalid name for playlist.");
1010 media_filter_create(&filter);
1011 std::unique_ptr<std::remove_pointer<filter_h>::type, int(*)(filter_h)>
1012 filter_ptr(filter, &media_filter_destroy); // automatically release the memory
1014 if( media_playlist_get_media_count_from_db(id, filter, &cnt) == MEDIA_CONTENT_ERROR_NONE) {
1015 o["numberOfTracks"] = picojson::value(static_cast<double>(cnt));
1018 LoggerE("Invalid count for playlist.");
1022 user_data->result = picojson::value(o);
1025 void ContentManager::getPlaylists(const std::shared_ptr<ReplyCallbackData>& user_data) {
1029 filter_h filter = nullptr;
1030 media_filter_create(&filter);
1031 std::unique_ptr<std::remove_pointer<filter_h>::type, int(*)(filter_h)>
1032 filter_ptr(filter, &media_filter_destroy); // automatically release the memory
1033 picojson::value::array playlists;
1035 ret = media_playlist_foreach_playlist_from_db(filter, playlist_foreach_cb, static_cast<void*>(&playlists));
1037 if(ret != MEDIA_CONTENT_ERROR_NONE) {
1038 PlatformResult err = LogAndCreateResult(
1039 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1040 ("Failed: Getting playlist is failed %d (%s)", ret, get_error_message(ret)));
1041 user_data->isSuccess = err;
1044 user_data->result = picojson::value(playlists);
1047 void ContentManager::removePlaylist(std::string playlistId,
1048 const std::shared_ptr<ReplyCallbackData>& user_data) {
1051 int id = std::atoi(playlistId.c_str());
1053 PlatformResult err = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "PlaylistId is wrong.");
1054 user_data->isSuccess = err;
1058 int ret = media_playlist_delete_from_db(id);
1059 if(ret != MEDIA_CONTENT_ERROR_NONE) {
1060 PlatformResult err = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Removal of playlist is failed.");
1061 user_data->isSuccess = err;
1065 int ContentManager::update(picojson::value args) {
1069 picojson::value content = args.get("content");
1070 std::string id = content.get("id").to_str();
1072 media_info_h media = NULL;
1073 ret = media_info_get_media_from_db(id.c_str(), &media);
1074 if (ret == MEDIA_CONTENT_ERROR_NONE) {
1075 setContent(media, content);
1076 ret = media_info_update_to_db(media);
1077 media_info_destroy(media);
1083 int ContentManager::updateBatch(picojson::value args) {
1086 std::vector<picojson::value> contents = args.get("contents").get<picojson::array>();
1088 for (picojson::value::array::iterator it = contents.begin(); it != contents.end(); ++it) {
1089 picojson::value content = *it;
1090 std::string id = content.get("id").to_str();
1091 media_info_h media = NULL;
1092 ret = media_info_get_media_from_db(id.c_str(), &media);
1093 if (media != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
1094 ret = setContent(media, content);
1095 if(ret != MEDIA_CONTENT_ERROR_NONE){
1096 LoggerE("setContent failed");
1100 ret = media_info_update_to_db(media);
1101 if(ret != MEDIA_CONTENT_ERROR_NONE){
1102 LoggerE("update to db failed");
1104 media_info_destroy(media);
1112 int ContentManager::playlistAdd(std::string playlist_id, std::string content_id) {
1115 media_playlist_h playlist = NULL;
1116 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1118 if (playlist != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
1119 ret = media_playlist_add_media(playlist, content_id.c_str());
1120 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1121 LoggerE("The content(id:%s) can't add to playlist",content_id.c_str());
1124 ret = media_playlist_update_to_db(playlist);
1125 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1126 LoggerE("The content(id:%s) can't add to playlist",content_id.c_str());
1130 LoggerE("Playlist(id:%s) is not exist",playlist_id.c_str());
1133 media_playlist_destroy(playlist);
1137 int ContentManager::playlistRemove(std::string playlist_id, int member_id) {
1140 media_playlist_h playlist = NULL;
1141 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1142 if (playlist != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
1143 ret = media_playlist_remove_media(playlist, member_id);
1144 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1145 LoggerE("The content can't remove to playlist");
1148 ret = media_playlist_update_to_db(playlist);
1149 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1150 LoggerE("The content can't remove to playlist");
1154 LoggerE("Playlist(id:%s) is not exist",playlist_id.c_str());
1156 media_playlist_destroy(playlist);
1162 void ContentManager::playlistAddbatch(const std::shared_ptr<ReplyCallbackData>& user_data) {
1165 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1167 media_playlist_h playlist = NULL;
1168 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1170 if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1171 PlatformResult err = LogAndCreateResult(
1172 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1173 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1174 user_data->isSuccess = err;
1178 std::vector<picojson::value> contents = user_data->args.get("contents").get<picojson::array>();
1179 for (picojson::value::array::iterator it = contents.begin(); it != contents.end(); ++it) {
1180 picojson::value content = *it;
1181 std::string id = content.get("id").to_str();
1182 ret = media_playlist_add_media(playlist, id.c_str());
1183 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1184 LoggerE("Adding Content(id:%s) is failed.", id.c_str());
1188 ret = media_playlist_update_to_db(playlist);
1189 if(ret != MEDIA_CONTENT_ERROR_NONE ) {
1190 PlatformResult err = LogAndCreateResult(
1191 ErrorCode::UNKNOWN_ERR, "Adding playlist is failed.",
1192 ("Adding playlist is failed: %d (%s)", ret, get_error_message(ret)));
1193 user_data->isSuccess = err;
1195 media_playlist_destroy(playlist);
1198 void ContentManager::playlistGet(const std::shared_ptr<ReplyCallbackData>& user_data) {
1201 media_playlist_h playlist = NULL;
1202 media_content_order_e order = MEDIA_CONTENT_ORDER_ASC;
1203 const std::string playOrder("play_order");
1207 media_playlist_destroy(playlist);
1211 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1212 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1213 if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1214 PlatformResult err = LogAndCreateResult(
1215 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1216 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1217 user_data->isSuccess = err;
1221 filter_h filter = NULL;
1222 ret = media_filter_create(&filter);
1223 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1224 PlatformResult err = LogAndCreateResult(
1225 ErrorCode::UNKNOWN_ERR, "Creating a filter is failed.",
1226 ("Creating a filter is failed: %d (%s)", ret, get_error_message(ret)));
1227 user_data->isSuccess = err;
1231 int count = user_data->args.get("count").get<double>();
1232 int offset = user_data->args.get("offset").get<double>();
1233 ret = media_filter_set_offset(filter, offset, count);
1234 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1235 LoggerD("Setting a offset/count is failed.");
1237 ret = media_filter_set_order(filter, order, playOrder.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
1238 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1239 LoggerD("Setting a offset/count is failed.");
1242 picojson::value::array arrayContent;
1243 ret = media_playlist_foreach_media_from_db(std::stoi(playlist_id),
1244 filter, playlist_content_member_cb, static_cast<void*>(&arrayContent));
1246 media_filter_destroy(filter);
1247 if (ret == MEDIA_CONTENT_ERROR_NONE) {
1248 user_data->result = picojson::value(arrayContent);
1251 PlatformResult err = LogAndCreateResult(
1252 ErrorCode::UNKNOWN_ERR, "Creating a filter is failed.",
1253 ("Creating a filter is failed: %d (%s)", ret, get_error_message(ret)));
1254 user_data->isSuccess = err;
1258 void ContentManager::playlistRemovebatch(const std::shared_ptr<ReplyCallbackData>& user_data) {
1261 media_playlist_h playlist = NULL;
1265 media_playlist_destroy(playlist);
1269 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1270 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1271 if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1272 PlatformResult err = LogAndCreateResult(
1273 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1274 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1275 user_data->isSuccess = err;
1279 std::vector<picojson::value> members = user_data->args.get("members").get<picojson::array>();
1280 std::size_t members_size = members.size();
1281 for (std::size_t i = 0; i < members_size; ++i) {
1282 int member_id = static_cast<int>(members.at(i).get<double>());
1283 ret = media_playlist_remove_media(playlist, member_id);
1285 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1286 LoggerD("Removing a content is failed.");
1290 ret = media_playlist_update_to_db(playlist);
1291 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1292 PlatformResult err = LogAndCreateResult(
1293 ErrorCode::UNKNOWN_ERR, "Removing the contents is failed.",
1294 ("Removing the contents is failed: %d (%s)", ret, get_error_message(ret)));
1295 user_data->isSuccess = err;
1299 void ContentManager::playlistSetOrder(const std::shared_ptr<ReplyCallbackData>& user_data) {
1302 media_playlist_h playlist = NULL;
1306 media_playlist_destroy(playlist);
1310 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1311 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1312 if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1313 PlatformResult err = LogAndCreateResult(
1314 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1315 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1316 user_data->isSuccess = err;
1321 std::vector<picojson::value> members = user_data->args.get("members").get<picojson::array>();
1323 ret = media_playlist_get_media_count_from_db(std::stoi(playlist_id), NULL, &cnt);
1324 if(ret != MEDIA_CONTENT_ERROR_NONE)
1326 LoggerE("Failed: media_playlist_get_media_count_from_db");
1327 PlatformResult err = convertError(ret);
1328 user_data->isSuccess = err;
1331 std::size_t members_size = members.size();
1332 if (cnt < 0 || static_cast<size_t>(cnt) != members_size ) {
1333 PlatformResult err = LogAndCreateResult(
1334 ErrorCode::INVALID_VALUES_ERR,
1335 "The items array does not contain all items from the playlist.",
1336 ("Failed: The items array does not contain all items from the playlist: %d (%s)",
1337 ret, get_error_message(ret)));
1338 user_data->isSuccess = err;
1342 for (std::size_t i = 0; i < members_size; ++i) {
1343 int member_id = static_cast<int>(members.at(i).get<double>());
1344 ret = media_playlist_set_play_order(playlist, member_id, i);
1345 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1346 LoggerD("Removing a content is failed.");
1350 ret = media_playlist_update_to_db(playlist);
1351 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1352 PlatformResult err = LogAndCreateResult(
1353 ErrorCode::UNKNOWN_ERR, "Removing the contents is failed.",
1354 ("Removing the contents is failed: %d (%s)", ret, get_error_message(ret)));
1355 user_data->isSuccess = err;
1359 void ContentManager::playlistMove(const std::shared_ptr<ReplyCallbackData>& user_data) {
1361 media_playlist_h playlist = NULL;
1365 media_playlist_destroy(playlist);
1369 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1370 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1371 if(ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1372 PlatformResult err = LogAndCreateResult(
1373 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1374 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1375 user_data->isSuccess = err;
1379 double member_id = user_data->args.get("memberId").get<double>();
1380 double delta = user_data->args.get("delta").get<double>();
1381 ret = media_playlist_get_play_order(playlist, static_cast<int>(member_id), &old_order);
1382 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1383 PlatformResult err = LogAndCreateResult(
1384 ErrorCode::UNKNOWN_ERR, "The content can't find form playlist.",
1385 ("The content can't find form playlist: %d (%s)", ret, get_error_message(ret)));
1386 user_data->isSuccess = err;
1389 int new_order = static_cast<int>(old_order) + static_cast<int>(delta);
1390 ret = media_playlist_set_play_order(playlist, static_cast<int>(member_id), new_order);
1391 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1392 PlatformResult err = LogAndCreateResult(
1393 ErrorCode::UNKNOWN_ERR, "The content can't update play_order.",
1394 ("The content can't update play_order: %d (%s)", ret, get_error_message(ret)));
1395 user_data->isSuccess = err;
1398 ret = media_playlist_update_to_db(playlist);
1399 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1400 PlatformResult err = LogAndCreateResult(
1401 ErrorCode::UNKNOWN_ERR, "Updateing play_order is failed.",
1402 ("Updateing play_order is failed: %d (%s)", ret, get_error_message(ret)));
1403 user_data->isSuccess = err;
1407 int ContentManager::getLyrics(const picojson::value& args, picojson::object& result) {
1410 int ret = METADATA_EXTRACTOR_ERROR_NONE;
1411 const std::string& contentURI = args.get("contentURI").to_str();
1412 if (contentURI.empty()) {
1413 LOGGER(ERROR) << "contentURI empty - skipping media extractor";
1417 metadata_extractor_h extractor;
1418 metadata_extractor_create(&extractor);
1419 std::unique_ptr<std::remove_pointer<metadata_extractor_h>::type, int(*)(metadata_extractor_h)>
1420 extractor_ptr(extractor, &metadata_extractor_destroy); // automatically release the memory
1422 ret = metadata_extractor_set_path(extractor, contentURI.c_str());
1423 if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
1424 LOGGER(ERROR) << "metadata_extractor_set_path failed, error: " << ret;
1427 picojson::array timestamps;
1428 picojson::array texts = picojson::array();
1429 char* strSyncTextNum = NULL;
1431 ret = metadata_extractor_get_metadata(extractor,
1432 METADATA_SYNCLYRICS_NUM, &strSyncTextNum);
1433 if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
1434 LOGGER(ERROR) << "Media extractor error " << ret;
1438 int nSyncTextNum = 0;
1439 if (strSyncTextNum) {
1440 nSyncTextNum = atoi(strSyncTextNum);
1441 free(strSyncTextNum);
1442 strSyncTextNum = NULL;
1444 if (nSyncTextNum > 0) {
1445 result["type"] = picojson::value(std::string("SYNCHRONIZED"));
1446 for (int i = 0; i < nSyncTextNum; i++) {
1447 unsigned long time_info = 0;
1448 char* lyrics = NULL;
1449 ret = metadata_extractor_get_synclyrics(extractor, i, &time_info, &lyrics);
1450 if (ret == METADATA_EXTRACTOR_ERROR_NONE) {
1451 timestamps.push_back(picojson::value(static_cast<double>(time_info)));
1452 texts.push_back(picojson::value(std::string(lyrics)));
1456 result["texts"] = picojson::value(texts);
1457 result["timestamps"] = picojson::value(timestamps);
1458 ret = METADATA_EXTRACTOR_ERROR_NONE;
1460 char* unSyncText = nullptr;
1461 ret = metadata_extractor_get_metadata(extractor, METADATA_UNSYNCLYRICS,
1463 if (ret == METADATA_EXTRACTOR_ERROR_NONE) {
1464 result["type"] = picojson::value(std::string("UNSYNCHRONIZED"));
1465 if (nullptr == unSyncText) {
1466 LOGGER(ERROR) << "Unsynchronized lyrics text is NULL";
1468 texts.push_back(picojson::value(unSyncText ? unSyncText : ""));
1469 result["texts"] = picojson::value(texts);
1477 media_playlist_h getPlaylistHandle(int id)
1480 media_playlist_h playlist_handle = nullptr;
1481 int ret_code = media_playlist_get_playlist_from_db(id, &playlist_handle);
1482 if(MEDIA_CONTENT_ERROR_NONE != ret_code ||
1483 playlist_handle == nullptr) {
1484 LoggerE("could not get playlist handle for id: %d", id);
1488 return playlist_handle;
1491 void destroyMediaPlaylistHandle(media_playlist_h& playlist_handle)
1494 if(playlist_handle) {
1495 int ret_code = media_playlist_destroy(playlist_handle);
1496 playlist_handle = nullptr;
1498 if(MEDIA_CONTENT_ERROR_NONE != ret_code) {
1499 LoggerE("media_playlist_destroy failed");
1504 int ContentManager::getPlaylistName(int id, std::string* result) {
1506 media_playlist_h playlist_handle = getPlaylistHandle(id);
1507 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1509 char* tmp_playlist_name = nullptr;
1510 const int ret_code = media_playlist_get_name(playlist_handle, &tmp_playlist_name);
1512 if(MEDIA_CONTENT_ERROR_NONE != ret_code) {
1513 LoggerE("media_playlist_get_name failed");
1514 return TIZEN_ERROR_UNKNOWN;
1517 std::string playlist_name;
1518 if(tmp_playlist_name) {
1519 playlist_name = tmp_playlist_name;
1520 free(tmp_playlist_name);
1521 tmp_playlist_name = nullptr;
1524 *result = playlist_name;
1525 return MEDIA_CONTENT_ERROR_NONE;
1528 int updatePlaylistInDB(media_playlist_h playlist_handle)
1531 int ret_code = media_playlist_update_to_db(playlist_handle);
1532 if(MEDIA_CONTENT_ERROR_NONE != ret_code) {
1533 LoggerE("media_playlist_update_to_db failed");
1536 return MEDIA_CONTENT_ERROR_NONE;
1539 int ContentManager::setPlaylistName(int id, const std::string& name)
1543 LoggerE("Cannot set empty playlist name!");
1544 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1547 media_playlist_h playlist_handle = getPlaylistHandle(id);
1548 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1550 const int ret_code = media_playlist_set_name(playlist_handle, name.c_str());
1551 if(MEDIA_CONTENT_ERROR_NONE != ret_code) {
1552 LoggerE("media_playlist_set_name failed");
1553 //Setting name that is used by other playlist does not return bad error code here.
1554 //MEDIA_CONTENT_ERROR_INVALID_OPERATION is being returned in updatePlaylistInDB
1555 return TIZEN_ERROR_UNKNOWN;
1558 int ret = updatePlaylistInDB(playlist_handle);
1559 if (MEDIA_CONTENT_ERROR_NONE != ret) {
1560 LoggerE("Error while updating playlist: %d", ret);
1561 if (MEDIA_CONTENT_ERROR_DB_FAILED == ret) {
1562 //We could fetch list of playlists and check if other playlist is using this
1563 //name, but that seems to be to much work in synchronous method
1564 LoggerE("Playlist name: %s is probably already used", name.c_str());
1565 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1569 return MEDIA_CONTENT_ERROR_NONE;
1572 int ContentManager::getThumbnailUri(int id, std::string* result)
1575 media_playlist_h playlist_handle = getPlaylistHandle(id);
1576 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1578 char* tmp_playlist_thb_path = nullptr;
1579 const int ret_code = media_playlist_get_thumbnail_path(playlist_handle, &tmp_playlist_thb_path);
1581 if(MEDIA_CONTENT_ERROR_NONE != ret_code) {
1582 LoggerE("media_playlist_get_name failed");
1583 return TIZEN_ERROR_UNKNOWN;
1586 std::string playlist_thb_path;
1587 if(tmp_playlist_thb_path) {
1588 playlist_thb_path = tmp_playlist_thb_path;
1589 free(tmp_playlist_thb_path);
1590 tmp_playlist_thb_path = nullptr;
1593 if (playlist_thb_path != " ") {
1594 playlist_thb_path = uri_prefix + playlist_thb_path;
1597 *result = playlist_thb_path;
1598 return MEDIA_CONTENT_ERROR_NONE;
1601 int ContentManager::setThumbnailUri(int id, const std::string& thb_uri)
1605 //Allow setting empty URI, unfortunately Core API does not allow to set empty
1606 //path so we need to set one empty space. This is probably issue of Core API.
1607 if(!thb_uri.empty() && " " != thb_uri) {
1608 if(thb_uri.find(uri_absolute_prefix) != 0) {
1609 LoggerE("thumbnail URI is not valid: [%s]", thb_uri.c_str());
1610 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1614 media_playlist_h playlist_handle = getPlaylistHandle(id);
1615 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1617 std::string real_path = common::FilesystemProvider::Create().GetRealPath(thb_uri);
1618 const int ret_code = media_playlist_set_thumbnail_path(playlist_handle,
1620 if(MEDIA_CONTENT_ERROR_NONE != ret_code) {
1621 LoggerE("media_playlist_set_thumbnail_path failed");
1622 return TIZEN_ERROR_UNKNOWN;
1625 int ret = updatePlaylistInDB(playlist_handle);
1629 int ContentManager::getNumberOfTracks(int id, int* result) {
1633 const int ret_code = media_playlist_get_media_count_from_db(id, nullptr,
1636 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1637 LoggerE("media_playlist_get_media_count_from_db failed");
1638 return TIZEN_ERROR_UNKNOWN;
1642 return MEDIA_CONTENT_ERROR_NONE;
1645 common::PlatformResult ContentManager::createThumbnail(const picojson::value& args) {
1648 unsigned int* callbackId = new unsigned int(static_cast<unsigned int>(args.get("callbackId").get<double>()));
1649 std::string id = args.get("id").get<std::string>();
1651 media_info_h media = NULL;
1652 int ret = media_info_get_media_from_db(id.c_str(), &media);
1653 if(MEDIA_CONTENT_ERROR_NONE != ret && nullptr == media) {
1655 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Getting media is failed.",
1656 ("Getting media is failed: %d (%s)", ret, get_error_message(ret)));
1659 ret = media_info_create_thumbnail(media, CreateThumbnailCallback, /* (void*) callbackId */ nullptr);
1660 media_info_destroy(media);
1661 if(MEDIA_CONTENT_ERROR_NONE != ret) {
1663 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Creating thumbnail failed.",
1664 ("Creating thumbnail failed: %d (%s)", ret, get_error_message(ret)));
1669 return PlatformResult(ErrorCode::NO_ERROR);
1672 PlatformResult ContentManager::convertError(int err) {
1673 char* error_msg = get_error_message(err);
1675 case MEDIA_CONTENT_ERROR_INVALID_PARAMETER :
1676 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, error_msg);
1677 case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY :
1678 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1679 case MEDIA_CONTENT_ERROR_INVALID_OPERATION :
1680 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1681 case MEDIA_CONTENT_FILE_NO_SPACE_ON_DEVICE :
1682 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1683 case MEDIA_CONTENT_ERROR_PERMISSION_DENIED :
1684 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1685 case MEDIA_CONTENT_ERROR_DB_FAILED :
1686 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1687 case MEDIA_CONTENT_ERROR_DB_BUSY :
1688 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1689 case MEDIA_CONTENT_ERROR_NETWORK :
1690 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1691 case MEDIA_CONTENT_ERROR_UNSUPPORTED_CONTENT :
1692 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1694 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
1698 } // namespace content
1699 } // namespace extension