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"
19 #include <media_content_internal.h>
20 #include <metadata_extractor.h>
30 #include "common/converter.h"
31 #include "common/filesystem/filesystem_provider.h"
32 #include "common/logger.h"
33 #include "common/scope_exit.h"
34 #include "common/tools.h"
36 #include "content/content_filter.h"
39 using namespace common;
41 using common::tools::ReportSuccess;
42 using common::tools::ReportError;
48 static const std::string uri_prefix = "file://";
49 static const std::string uri_absolute_prefix = "file:///";
52 std::string get_date(char* tmpStr) {
55 struct tm* result = (struct tm*)calloc(1, sizeof(struct tm));
56 if (nullptr != result) {
57 if (strptime(tmpStr, "%Y:%m:%d %H:%M:%S", result) == NULL) {
61 time_t t = mktime(result); // + get_utc_offset() * 3600;
62 std::stringstream str_date;
65 return str_date.str();
72 void ContentToJson(media_info_h info, picojson::object& o) {
80 long long unsigned int tmpLong;
81 media_content_type_e type;
83 ret = media_info_get_media_type(info, &type);
85 if (ret != MEDIA_CONTENT_ERROR_NONE) {
86 LoggerE("Get media type failed: %d", ret);
87 type = MEDIA_CONTENT_TYPE_OTHERS;
90 if (type == MEDIA_CONTENT_TYPE_IMAGE) {
91 o["type"] = picojson::value(std::string("IMAGE"));
93 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_image(info, &img)) {
94 std::unique_ptr<std::remove_pointer<image_meta_h>::type, int (*)(image_meta_h)> img_ptr(
95 img, &image_meta_destroy); // automatically release the memory
96 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_date_taken(img, &tmpStr)) {
98 o["releaseDate"] = picojson::value(get_date(tmpStr));
103 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_width(img, &tmpInt)) {
104 o["width"] = picojson::value(static_cast<double>(tmpInt));
106 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_height(img, &tmpInt)) {
107 o["height"] = picojson::value(static_cast<double>(tmpInt));
109 picojson::object geo;
110 // Deprecated since 9.0 //TODO remove after 2 versions
111 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_latitude(info, &tmpDouble)) {
112 geo["latitude"] = picojson::value(tmpDouble);
114 // Deprecated since 9.0 //TODO remove after 2 versions
115 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_longitude(info, &tmpDouble)) {
116 geo["longitude"] = picojson::value(tmpDouble);
118 o["geolocation"] = picojson::value(geo);
120 media_content_orientation_e orientation;
121 if (MEDIA_CONTENT_ERROR_NONE == image_meta_get_orientation(img, &orientation)) {
122 switch (orientation) {
123 case MEDIA_CONTENT_ORIENTATION_NOT_AVAILABLE:
124 case MEDIA_CONTENT_ORIENTATION_NORMAL:
127 case MEDIA_CONTENT_ORIENTATION_HFLIP:
128 ori = "FLIP_HORIZONTAL";
130 case MEDIA_CONTENT_ORIENTATION_ROT_180:
133 case MEDIA_CONTENT_ORIENTATION_VFLIP:
134 ori = "FLIP_VERTICAL";
136 case MEDIA_CONTENT_ORIENTATION_TRANSPOSE:
139 case MEDIA_CONTENT_ORIENTATION_ROT_90:
142 case MEDIA_CONTENT_ORIENTATION_TRANSVERSE:
145 case MEDIA_CONTENT_ORIENTATION_ROT_270:
149 o["orientation"] = picojson::value(ori);
152 } else if (type == MEDIA_CONTENT_TYPE_VIDEO) {
153 o["type"] = picojson::value(std::string("VIDEO"));
154 // Deprecated since 9.0 //TODO remove after 2 versions
156 // Deprecated since 9.0 //TODO remove after 2 versions
157 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_video(info, &video)) {
158 // Deprecated since 9.0 //TODO remove after 2 versions
159 std::unique_ptr<std::remove_pointer<video_meta_h>::type, int (*)(video_meta_h)> video_ptr(
160 video, &video_meta_destroy); // automatically release the memory
161 // Deprecated since 9.0 //TODO remove after 2 versions
162 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_width(video, &tmpInt)) {
163 o["width"] = picojson::value(static_cast<double>(tmpInt));
165 // Deprecated since 9.0 //TODO remove after 2 versions
166 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_height(video, &tmpInt)) {
167 o["height"] = picojson::value(static_cast<double>(tmpInt));
169 // Deprecated since 9.0 //TODO remove after 2 versions
170 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_artist(video, &tmpStr)) {
171 picojson::array artists;
173 artists.push_back(picojson::value(std::string(tmpStr)));
177 o["artists"] = picojson::value(artists);
179 // Deprecated since 9.0 //TODO remove after 2 versions
180 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_album(video, &tmpStr)) {
182 o["album"] = picojson::value(tmpStr);
187 // Deprecated since 9.0 //TODO remove after 2 versions
188 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_duration(video, &tmpInt)) {
189 o["duration"] = picojson::value(static_cast<double>(tmpInt));
191 // Deprecated since 9.0 //TODO remove after 2 versions
192 if (MEDIA_CONTENT_ERROR_NONE == video_meta_get_recorded_date(video, &tmpStr)) {
194 o["releaseDate"] = picojson::value(get_date(tmpStr));
200 picojson::object geo;
201 // Deprecated since 9.0 //TODO remove after 2 versions
202 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_latitude(info, &tmpDouble)) {
203 geo["latitude"] = picojson::value(tmpDouble);
205 // Deprecated since 9.0 //TODO remove after 2 versions
206 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_longitude(info, &tmpDouble)) {
207 geo["longitude"] = picojson::value(tmpDouble);
209 o["geolocation"] = picojson::value(geo);
210 } else if (type == MEDIA_CONTENT_TYPE_SOUND || type == MEDIA_CONTENT_TYPE_MUSIC) {
211 o["type"] = picojson::value(std::string("AUDIO"));
213 if (MEDIA_CONTENT_ERROR_NONE == media_info_get_audio(info, &audio)) {
214 std::unique_ptr<std::remove_pointer<audio_meta_h>::type, int (*)(audio_meta_h)> audio_ptr(
215 audio, &audio_meta_destroy); // automatically release the memory
216 // Deprecated since 9.0 //TODO remove after 2 versions
217 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_recorded_date(audio, &tmpStr)) {
219 o["releaseDate"] = picojson::value(get_date(tmpStr));
224 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_album(audio, &tmpStr)) {
226 o["album"] = picojson::value(std::string(tmpStr));
231 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_artist(audio, &tmpStr)) {
233 picojson::array artists;
234 artists.push_back(picojson::value(std::string(tmpStr)));
235 o["artists"] = picojson::value(artists);
240 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_genre(audio, &tmpStr)) {
242 picojson::array genres;
243 genres.push_back(picojson::value(std::string(tmpStr)));
244 o["genres"] = picojson::value(genres);
249 // Deprecated since 9.0 //TODO remove after 2 versions
250 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_composer(audio, &tmpStr)) {
252 picojson::array composers;
253 composers.push_back(picojson::value(std::string(tmpStr)));
254 o["composers"] = picojson::value(composers);
259 // Deprecated since 9.0 //TODO remove after 2 versions
260 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_copyright(audio, &tmpStr)) {
262 o["copyright"] = picojson::value(std::string(tmpStr));
267 // Deprecated since 9.0 //TODO remove after 2 versions
268 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_bit_rate(audio, &tmpInt)) {
269 o["bitrate"] = picojson::value(static_cast<double>(tmpInt));
271 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_track_num(audio, &tmpStr)) {
273 o["trackNumber"] = picojson::value(static_cast<double>(std::atoi(tmpStr)));
277 o["trackNumber"] = picojson::value();
280 // Deprecated since 9.0 //TODO remove after 2 versions
281 if (MEDIA_CONTENT_ERROR_NONE == audio_meta_get_duration(audio, &tmpInt)) {
282 o["duration"] = picojson::value(static_cast<double>(tmpInt));
286 o["type"] = picojson::value(std::string("OTHER"));
289 ret = media_info_get_media_id(info, &tmpStr);
290 if (ret == MEDIA_CONTENT_ERROR_NONE) {
292 o["id"] = picojson::value(std::string(tmpStr));
297 ret = media_info_get_display_name(info, &tmpStr);
298 if (ret == MEDIA_CONTENT_ERROR_NONE) {
300 o["name"] = picojson::value(std::string(tmpStr));
306 ret = media_info_get_mime_type(info, &tmpStr);
307 if (ret == MEDIA_CONTENT_ERROR_NONE) {
309 o["mimeType"] = picojson::value(std::string(tmpStr));
314 ret = media_info_get_title(info, &tmpStr);
315 if (ret == MEDIA_CONTENT_ERROR_NONE) {
317 o["title"] = picojson::value(std::string(tmpStr));
322 ret = media_info_get_file_path(info, &tmpStr);
323 if (ret == MEDIA_CONTENT_ERROR_NONE) {
325 o["contentURI"] = picojson::value(std::string(tmpStr));
330 ret = media_info_get_thumbnail_path(info, &tmpStr);
331 if (ret == MEDIA_CONTENT_ERROR_NONE) {
333 picojson::array thumbnails;
334 thumbnails.push_back(picojson::value(std::string(tmpStr)));
335 o["thumbnailURIs"] = picojson::value(thumbnails);
340 // Deprecated since 9.0 //TODO remove after 2 versions
341 ret = media_info_get_description(info, &tmpStr);
342 if (ret == MEDIA_CONTENT_ERROR_NONE) {
344 o["description"] = picojson::value(std::string(tmpStr));
349 // Deprecated since 9.0 //TODO remove after 2 versions
350 ret = media_info_get_rating(info, &tmpInt);
351 if (ret == MEDIA_CONTENT_ERROR_NONE) {
352 o["rating"] = picojson::value(static_cast<double>(tmpInt));
354 ret = media_info_get_size(info, &tmpLong);
355 if (ret == MEDIA_CONTENT_ERROR_NONE) {
356 o["size"] = picojson::value(static_cast<double>(tmpLong));
358 // Deprecated since 9.0 //TODO remove after 2 versions
359 ret = media_info_get_favorite(info, &tmpBool);
360 if (ret == MEDIA_CONTENT_ERROR_NONE) {
361 o["isFavorite"] = picojson::value(tmpBool);
363 ret = media_info_get_modified_time(info, &tmpDate);
364 if (ret == MEDIA_CONTENT_ERROR_NONE) {
365 o["modifiedDate"] = picojson::value(static_cast<double>(tmpDate));
369 void ContentDirToJson(media_folder_h folder, picojson::object& o) {
375 ret = media_folder_get_folder_id(folder, &tmpStr);
376 if (ret == MEDIA_CONTENT_ERROR_NONE) {
378 o["id"] = picojson::value(std::string(tmpStr));
385 std::string folder_path;
386 ret = media_folder_get_path(folder, &tmpStr);
387 if (ret == MEDIA_CONTENT_ERROR_NONE) {
389 o["directoryURI"] = picojson::value(std::string(tmpStr));
390 // folder_path value kept for modifiedDate property gathering
391 folder_path = tmpStr;
398 ret = media_folder_get_name(folder, &tmpStr);
399 if (ret == MEDIA_CONTENT_ERROR_NONE) {
401 o["title"] = picojson::value(std::string(tmpStr));
408 struct stat stat_res;
409 if (stat(folder_path.c_str(), &stat_res) == 0) {
410 auto mod_time = stat_res.st_mtime;
411 o["modifiedDate"] = picojson::value(static_cast<double>(mod_time));
415 static int setContent(media_info_h media, const picojson::value& content) {
418 int ret = MEDIA_CONTENT_ERROR_NONE;
419 bool is_fav = content.get("isFavorite").get<bool>();
422 LoggerE("MEDIA_CONTENT_ERROR_DB_FAILED");
423 return MEDIA_CONTENT_ERROR_DB_FAILED;
426 // Deprecated since 9.0 //TODO remove after 2 versions
427 ret = media_info_set_favorite(media, is_fav);
428 if (ret != MEDIA_CONTENT_ERROR_NONE) {
429 LoggerE("Updating isFavorite failed.");
432 if (ret != MEDIA_CONTENT_ERROR_NONE) {
433 LoggerE("Updating favorite failed.");
436 return MEDIA_CONTENT_ERROR_NONE;
439 static int updateContent(const picojson::value& content) {
442 int ret = MEDIA_CONTENT_ERROR_NONE;
443 std::string id = content.get("id").to_str();
444 media_info_h media = nullptr;
447 media_info_destroy(media);
451 ret = media_info_get_media_from_db(id.c_str(), &media);
452 if (ret != MEDIA_CONTENT_ERROR_NONE) {
453 LoggerE("media_info_get_media_from_db failed: %d", ret);
456 ret = setContent(media, content);
457 if (ret != MEDIA_CONTENT_ERROR_NONE) {
458 LoggerE("setContent failed: %d", ret);
461 ret = media_info_update_to_db(media);
462 if (ret != MEDIA_CONTENT_ERROR_NONE) {
463 LoggerE("media_info_update_to_db failed: %d", ret);
470 static void FolderToJson(media_folder_h folder, picojson::object* out) {
480 ret = media_folder_get_folder_id(folder, &id);
481 if (ret != MEDIA_CONTENT_ERROR_NONE) {
482 LogAndReportError(ContentManager::convertError(ret), out,
483 ("Failed: media_folder_get_folder_id"));
486 std::unique_ptr<char, decltype(&free)> id_ptr(id, &free);
488 ret = media_folder_get_name(folder, &name);
489 if (ret != MEDIA_CONTENT_ERROR_NONE) {
490 LogAndReportError(ContentManager::convertError(ret), out, ("Failed: media_folder_get_name"));
493 std::unique_ptr<char, decltype(&free)> name_ptr(name, &free);
495 ret = media_folder_get_path(folder, &path);
496 if (ret != MEDIA_CONTENT_ERROR_NONE) {
497 LogAndReportError(ContentManager::convertError(ret), out, ("Failed: media_folder_get_path"));
500 std::unique_ptr<char, decltype(&free)> path_ptr(path, &free);
502 struct stat stat_res;
503 ret = stat(path, &stat_res);
505 LogAndReportError(ContentManager::convertError(errno), out, ("Failed: stat"));
508 date = stat_res.st_mtime;
510 (*out)["id"] = picojson::value(std::string(id));
511 (*out)["directoryURI"] = picojson::value(std::string(path));
512 (*out)["title"] = picojson::value(std::string(name));
514 (*out)["modifiedDate"] = picojson::value(static_cast<double>(date));
517 static bool media_foreach_directory_cb(media_folder_h folder, void* user_data) {
519 picojson::array* array = static_cast<picojson::array*>(user_data);
520 picojson::object json;
521 FolderToJson(folder, &json);
522 array->push_back(picojson::value(json));
526 static bool media_foreach_content_cb(media_info_h media, void* user_data) {
528 picojson::value::array* contents = static_cast<picojson::value::array*>(user_data);
529 picojson::value::object o;
530 ContentToJson(media, o);
531 contents->push_back(picojson::value(o));
535 static bool playlist_foreach_cb(media_playlist_h playlist, void* user_data) {
537 picojson::value::array* playlists = static_cast<picojson::value::array*>(user_data);
538 picojson::value::object o;
539 if (playlist != NULL) {
541 char* thumb_path = NULL;
543 filter_h filter = NULL;
544 if (media_playlist_get_playlist_id(playlist, &id) == MEDIA_CONTENT_ERROR_NONE) {
545 std::stringstream str_id;
547 o["id"] = picojson::value(std::to_string(id));
549 LoggerD("Invalid ID for playlist.");
551 if (media_playlist_get_thumbnail_path(playlist, &thumb_path) == MEDIA_CONTENT_ERROR_NONE) {
552 if (thumb_path != NULL) {
553 std::string thumbnail_uri(thumb_path);
554 if (thumbnail_uri != " ") {
555 thumbnail_uri = uri_prefix + thumbnail_uri;
557 o["thumbnailURI"] = picojson::value(thumbnail_uri);
560 o["thumbnailURI"] = picojson::value(); // picojson::value(std::string(""));
563 LoggerD("Invalid thumbnail path for playlist.");
565 if (media_playlist_get_name(playlist, &name) == MEDIA_CONTENT_ERROR_NONE) {
566 o["name"] = picojson::value(std::string(name));
569 LoggerD("Invalid name for playlist.");
572 media_filter_create(&filter);
573 std::unique_ptr<std::remove_pointer<filter_h>::type, int (*)(filter_h)> filter_ptr(
574 filter, &media_filter_destroy); // automatically release the memory
575 if (media_playlist_get_media_count_from_db(id, filter, &cnt) == MEDIA_CONTENT_ERROR_NONE) {
576 o["numberOfTracks"] = picojson::value(static_cast<double>(cnt));
578 LoggerE("Invalid count for playlist.");
580 playlists->push_back(picojson::value(o));
585 static bool playlist_content_member_cb(int playlist_member_id, media_info_h media,
588 picojson::value::array* contents = static_cast<picojson::value::array*>(user_data);
589 picojson::value::object o;
591 o["playlist_member_id"] = picojson::value(static_cast<double>(playlist_member_id));
592 ContentToJson(media, o);
593 contents->push_back(picojson::value(o));
597 ContentManager::ContentManager() {
598 ScopeLogger("ContentManager called");
599 if (media_content_connect() == MEDIA_CONTENT_ERROR_NONE) {
600 m_dbConnected = true;
602 m_dbConnected = false;
604 m_contentInstance = nullptr;
607 ContentManager::~ContentManager() {
610 if (media_content_disconnect() == MEDIA_CONTENT_ERROR_NONE) {
611 m_dbConnected = false;
616 ContentManager* ContentManager::getInstance() {
618 static ContentManager instance;
622 ContentInstance* ContentManager::getContentInstance() {
624 return m_contentInstance;
627 void ContentManager::setContentInstance(ContentInstance* const content_instance) {
629 m_contentInstance = content_instance;
632 bool ContentManager::isConnected() {
634 return m_dbConnected;
637 void ContentManager::getDirectories(const std::shared_ptr<ReplyCallbackData>& user_data) {
641 picojson::array pico_dirs;
642 ret = media_folder_foreach_folder_from_db(nullptr, media_foreach_directory_cb,
644 if (ret != MEDIA_CONTENT_ERROR_NONE) {
645 PlatformResult err = LogAndCreateResult(
646 ErrorCode::UNKNOWN_ERR, "Getting the directories failed.",
647 ("Failed: Getting the directories failed %d (%s)", ret, get_error_message(ret)));
648 user_data->isSuccess = err;
652 user_data->result = picojson::value(pico_dirs);
655 void ContentManager::find(const std::shared_ptr<ReplyCallbackData>& user_data) {
662 picojson::value::array arrayContent;
663 filter_h filter = nullptr;
664 media_filter_create(&filter);
667 media_filter_destroy(filter);
671 if (!IsNull(user_data->args.get("filter"))) {
672 ContentFilter filterMechanism;
674 picojson::object argsObject = JsonCast<picojson::object>(user_data->args);
675 if (filterMechanism.BuildQuery(FromJson<picojson::object>(argsObject, "filter"), &query)) {
676 LoggerD("Filter query: %s", query.c_str());
677 ret = media_filter_set_condition(filter, query.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
678 if (MEDIA_CONTENT_ERROR_NONE != ret) {
679 LoggerE("Platform filter setting failed, error %d", ret);
684 if (user_data->args.contains("sortMode")) {
685 picojson::value vSortMode = user_data->args.get("sortMode");
687 if (vSortMode.is<picojson::object>()) {
688 std::string sortModeName, sortModeOrder;
690 ContentFilter::MapField(vSortMode.get("attributeName").to_str(), &sortModeName);
692 sortModeOrder = vSortMode.get("order").to_str();
693 if (!sortModeOrder.empty()) {
694 media_content_order_e order = MEDIA_CONTENT_ORDER_ASC;
696 if (sortModeOrder == "ASC") {
697 order = MEDIA_CONTENT_ORDER_ASC;
698 } else if (sortModeOrder == "DESC") {
699 order = MEDIA_CONTENT_ORDER_DESC;
702 ret = media_filter_set_order(filter, order, sortModeName.c_str(),
703 MEDIA_CONTENT_COLLATE_DEFAULT);
704 if (MEDIA_CONTENT_ERROR_NONE != ret) {
705 LoggerE("Platform SortMode setting failed, error: %d", ret);
711 if (!IsNull(user_data->args.get("count"))) {
712 count = static_cast<int>(user_data->args.get("count").get<double>());
716 if (!IsNull(user_data->args.get("offset"))) {
717 offset = static_cast<int>(user_data->args.get("offset").get<double>());
721 ret = media_filter_set_offset(filter, offset, count);
722 if (MEDIA_CONTENT_ERROR_NONE != ret) {
723 LoggerE("A platform error occurs in media_filter_set_offset: %d", ret);
725 if (!IsNull(user_data->args.get("directoryId"))) {
726 dirId = user_data->args.get("directoryId").get<std::string>();
727 ret = media_folder_foreach_media_from_db(dirId.c_str(), filter, media_foreach_content_cb,
728 static_cast<void*>(&arrayContent));
730 ret = media_info_foreach_media_from_db(filter, media_foreach_content_cb,
731 static_cast<void*>(&arrayContent));
734 if (ret == MEDIA_CONTENT_ERROR_NONE) {
735 user_data->result = picojson::value(arrayContent);
737 PlatformResult err = LogAndCreateResult(
738 ErrorCode::UNKNOWN_ERR, "The iteration failed in platform",
739 ("The iteration failed in platform: %d (%s)", ret, get_error_message(ret)));
740 user_data->isSuccess = err;
744 int ContentManager::scanFile(std::string& uri) {
746 return media_content_scan_file(uri.c_str());
749 PlatformResult ContentManager::scanDirectory(media_scan_completed_cb callback,
750 ReplyCallbackData* cbData) {
752 const std::string& contentDirURI = cbData->args.get("contentDirURI").get<std::string>();
753 std::string real_path = common::FilesystemProvider::Create().GetRealPath(contentDirURI);
754 const bool recursive = cbData->args.get("recursive").get<bool>();
756 int ret = media_content_scan_folder(real_path.c_str(), recursive, callback, (void*)cbData);
758 if (ret != MEDIA_CONTENT_ERROR_NONE) {
759 if (MEDIA_CONTENT_ERROR_INVALID_PARAMETER == ret) {
760 return LogAndCreateResult(
761 ErrorCode::INVALID_VALUES_ERR, "Scanning content directory failed",
762 ("Scan folder failed in platform: %d (%s)", ret, get_error_message(ret)));
765 return LogAndCreateResult(
766 ErrorCode::UNKNOWN_ERR, "Scanning content directory failed",
767 ("Scan folder failed in platform: %d (%s)", ret, get_error_message(ret)));
770 return PlatformResult(ErrorCode::NO_ERROR);
773 PlatformResult ContentManager::cancelScanDirectory(const std::string& content_dir_uri) {
776 int ret = media_content_cancel_scan_folder(content_dir_uri.c_str());
777 if (ret != MEDIA_CONTENT_ERROR_NONE) {
778 return LogAndCreateResult(
779 ErrorCode::UNKNOWN_ERR, "Cancel scan content directory failed",
780 ("Cancel scan folder failed in platform: %d (%s)", ret, get_error_message(ret)));
782 return PlatformResult(ErrorCode::NO_ERROR);
785 PlatformResult ContentManager::addChangeListener(media_content_noti_h* noti_handle,
786 media_content_db_update_cb callback,
790 int ret = media_content_add_db_updated_cb(callback, user_data, noti_handle);
792 if (MEDIA_CONTENT_ERROR_NONE != ret) {
793 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Failed to add the listener.",
794 ("Failed to add the listener: %d (%s)", ret, get_error_message(ret)));
797 return PlatformResult(ErrorCode::NO_ERROR);
800 PlatformResult ContentManager::removeChangeListener(media_content_noti_h noti_handle) {
803 int ret = media_content_remove_db_updated_cb(noti_handle);
806 case MEDIA_CONTENT_ERROR_NONE:
807 return PlatformResult(ErrorCode::NO_ERROR);
808 case MEDIA_CONTENT_ERROR_INVALID_PARAMETER:
809 // Trying to remove non-existent listener, ignoring
810 LoggerI("Failed to remove the listener: %d (%s)", ret, get_error_message(ret));
811 return PlatformResult(ErrorCode::NO_ERROR);
813 return LogAndCreateResult(
814 ErrorCode::ABORT_ERR, "Failed to remove the listener.",
815 ("Failed to remove the listener: %d (%s)", ret, get_error_message(ret)));
819 void ContentManager::createPlaylist(std::string name,
820 const std::shared_ptr<ReplyCallbackData>& user_data) {
822 media_playlist_h playlist = NULL;
824 int ret = media_playlist_insert_to_db(name.c_str(), &playlist);
825 std::unique_ptr<std::remove_pointer<media_playlist_h>::type, int (*)(media_playlist_h)>
826 playlist_ptr(playlist, &media_playlist_destroy); // automatically release the memory
827 if (ret != MEDIA_CONTENT_ERROR_NONE) {
828 // MEDIA_CONTENT_ERROR_DB_FAILED means that playlist probably already exists
829 PlatformResult err = LogAndCreateResult(
830 MEDIA_CONTENT_ERROR_DB_FAILED == ret ? ErrorCode::INVALID_VALUES_ERR
831 : ErrorCode::UNKNOWN_ERR,
832 "Creation of playlist has failed.",
833 ("Failed: creation of playlist is failed: %d (%s)", ret, get_error_message(ret)));
834 user_data->isSuccess = err;
837 picojson::value::object o;
839 if (playlist != NULL) {
841 char* thumb_path = NULL;
842 char* name_playlist = NULL;
843 filter_h filter = NULL;
844 if (media_playlist_get_playlist_id(playlist, &id) == MEDIA_CONTENT_ERROR_NONE) {
845 o["id"] = picojson::value(std::to_string(id));
848 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "loading of playlist is failed.");
849 user_data->isSuccess = err;
852 if (media_playlist_get_thumbnail_path(playlist, &thumb_path) == MEDIA_CONTENT_ERROR_NONE) {
853 if (thumb_path != NULL) {
854 o["thumbnailURI"] = picojson::value(std::string(thumb_path));
857 o["thumbnailURI"] = picojson::value();
860 LoggerE("Invalid thumbnail path for playlist.");
862 if (media_playlist_get_name(playlist, &name_playlist) == MEDIA_CONTENT_ERROR_NONE) {
863 o["name"] = picojson::value(std::string(name_playlist));
866 LoggerE("Invalid name for playlist.");
868 media_filter_create(&filter);
869 std::unique_ptr<std::remove_pointer<filter_h>::type, int (*)(filter_h)> filter_ptr(
870 filter, &media_filter_destroy); // automatically release the memory
872 if (media_playlist_get_media_count_from_db(id, filter, &cnt) == MEDIA_CONTENT_ERROR_NONE) {
873 o["numberOfTracks"] = picojson::value(static_cast<double>(cnt));
875 LoggerE("Invalid count for playlist.");
879 user_data->result = picojson::value(o);
882 void ContentManager::getPlaylists(const std::shared_ptr<ReplyCallbackData>& user_data) {
885 filter_h filter = nullptr;
886 media_filter_create(&filter);
887 std::unique_ptr<std::remove_pointer<filter_h>::type, int (*)(filter_h)> filter_ptr(
888 filter, &media_filter_destroy); // automatically release the memory
889 picojson::value::array playlists;
891 ret = media_playlist_foreach_playlist_from_db(filter, playlist_foreach_cb,
892 static_cast<void*>(&playlists));
894 if (ret != MEDIA_CONTENT_ERROR_NONE) {
895 PlatformResult err = LogAndCreateResult(
896 ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
897 ("Failed: Getting playlist is failed %d (%s)", ret, get_error_message(ret)));
898 user_data->isSuccess = err;
901 user_data->result = picojson::value(playlists);
904 void ContentManager::removePlaylist(std::string playlistId,
905 const std::shared_ptr<ReplyCallbackData>& user_data) {
907 int id = std::atoi(playlistId.c_str());
909 PlatformResult err = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "PlaylistId is wrong.");
910 user_data->isSuccess = err;
914 int ret = media_playlist_delete_from_db(id);
915 if (ret != MEDIA_CONTENT_ERROR_NONE) {
917 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Removal of playlist is failed.");
918 user_data->isSuccess = err;
922 int ContentManager::update(const picojson::value& args) {
924 const picojson::value content = args.get("content");
925 int ret = updateContent(content);
926 if (ret != MEDIA_CONTENT_ERROR_NONE) {
927 LoggerE("updateContent failed: %d", ret);
932 int ContentManager::updateBatch(const picojson::value& args) {
934 int ret = MEDIA_CONTENT_ERROR_NONE;
935 std::vector<picojson::value> contents = args.get("contents").get<picojson::array>();
937 for (picojson::value::array::iterator it = contents.begin(); it != contents.end(); ++it) {
938 const picojson::value content = *it;
939 ret = updateContent(content);
940 if (ret != MEDIA_CONTENT_ERROR_NONE) {
941 LoggerE("updateContent failed: %d", ret);
948 int ContentManager::playlistAdd(std::string playlist_id, std::string content_id) {
951 media_playlist_h playlist = NULL;
952 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
954 if (playlist != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
955 ret = media_playlist_add_media(playlist, content_id.c_str());
956 if (ret != MEDIA_CONTENT_ERROR_NONE) {
957 LoggerE("The content(id:%s) can't add to playlist", content_id.c_str());
960 ret = media_playlist_update_to_db(playlist);
961 if (ret != MEDIA_CONTENT_ERROR_NONE) {
962 LoggerE("The content(id:%s) can't add to playlist", content_id.c_str());
965 LoggerE("Playlist(id:%s) is not exist", playlist_id.c_str());
968 media_playlist_destroy(playlist);
972 int ContentManager::playlistRemove(std::string playlist_id, int member_id) {
975 media_playlist_h playlist = NULL;
976 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
977 if (playlist != NULL && ret == MEDIA_CONTENT_ERROR_NONE) {
978 ret = media_playlist_remove_media(playlist, member_id);
979 if (ret != MEDIA_CONTENT_ERROR_NONE) {
980 LoggerE("The content can't remove to playlist");
983 ret = media_playlist_update_to_db(playlist);
984 if (ret != MEDIA_CONTENT_ERROR_NONE) {
985 LoggerE("The content can't remove to playlist");
988 LoggerE("Playlist(id:%s) is not exist", playlist_id.c_str());
990 media_playlist_destroy(playlist);
995 void ContentManager::playlistAddbatch(const std::shared_ptr<ReplyCallbackData>& user_data) {
997 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
999 media_playlist_h playlist = NULL;
1000 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1002 if (ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1003 PlatformResult err =
1004 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1005 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1006 user_data->isSuccess = err;
1010 std::vector<picojson::value> contents = user_data->args.get("contents").get<picojson::array>();
1011 for (picojson::value::array::iterator it = contents.begin(); it != contents.end(); ++it) {
1012 picojson::value content = *it;
1013 std::string id = content.get("id").to_str();
1014 ret = media_playlist_add_media(playlist, id.c_str());
1015 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1016 LoggerE("Adding Content(id:%s) is failed.", id.c_str());
1020 ret = media_playlist_update_to_db(playlist);
1021 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1022 PlatformResult err =
1023 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Adding playlist is failed.",
1024 ("Adding playlist is failed: %d (%s)", ret, get_error_message(ret)));
1025 user_data->isSuccess = err;
1027 media_playlist_destroy(playlist);
1030 void ContentManager::playlistGet(const std::shared_ptr<ReplyCallbackData>& user_data) {
1032 media_playlist_h playlist = NULL;
1033 media_content_order_e order = MEDIA_CONTENT_ORDER_ASC;
1034 const std::string playOrder("playlist_member_order");
1038 media_playlist_destroy(playlist);
1042 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1043 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1044 if (ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1045 PlatformResult err =
1046 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1047 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1048 user_data->isSuccess = err;
1052 filter_h filter = NULL;
1053 ret = media_filter_create(&filter);
1054 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1055 PlatformResult err =
1056 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Creating a filter is failed.",
1057 ("Creating a filter is failed: %d (%s)", ret, get_error_message(ret)));
1058 user_data->isSuccess = err;
1062 int count = user_data->args.get("count").get<double>();
1063 int offset = user_data->args.get("offset").get<double>();
1064 ret = media_filter_set_offset(filter, offset, count);
1065 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1066 LoggerD("Setting a offset/count is failed.");
1068 ret = media_filter_set_order(filter, order, playOrder.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
1069 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1070 LoggerD("Setting a offset/count is failed.");
1073 picojson::value::array arrayContent;
1074 ret = media_playlist_foreach_media_from_db(std::stoi(playlist_id), filter,
1075 playlist_content_member_cb,
1076 static_cast<void*>(&arrayContent));
1078 media_filter_destroy(filter);
1079 if (ret == MEDIA_CONTENT_ERROR_NONE) {
1080 user_data->result = picojson::value(arrayContent);
1082 PlatformResult err =
1083 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Creating a filter is failed.",
1084 ("Creating a filter is failed: %d (%s)", ret, get_error_message(ret)));
1085 user_data->isSuccess = err;
1089 void ContentManager::playlistRemovebatch(const std::shared_ptr<ReplyCallbackData>& user_data) {
1091 media_playlist_h playlist = NULL;
1095 media_playlist_destroy(playlist);
1099 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1100 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1101 if (ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1102 PlatformResult err =
1103 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1104 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1105 user_data->isSuccess = err;
1109 std::vector<picojson::value> members = user_data->args.get("members").get<picojson::array>();
1110 std::size_t members_size = members.size();
1111 for (std::size_t i = 0; i < members_size; ++i) {
1112 int member_id = static_cast<int>(members.at(i).get<double>());
1113 ret = media_playlist_remove_media(playlist, member_id);
1115 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1116 LoggerD("Removing a content is failed.");
1120 ret = media_playlist_update_to_db(playlist);
1121 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1122 PlatformResult err = LogAndCreateResult(
1123 ErrorCode::UNKNOWN_ERR, "Removing the contents is failed.",
1124 ("Removing the contents is failed: %d (%s)", ret, get_error_message(ret)));
1125 user_data->isSuccess = err;
1129 void ContentManager::playlistSetOrder(const std::shared_ptr<ReplyCallbackData>& user_data) {
1131 media_playlist_h playlist = NULL;
1135 media_playlist_destroy(playlist);
1139 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1140 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1141 if (ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1142 PlatformResult err =
1143 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1144 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1145 user_data->isSuccess = err;
1150 std::vector<picojson::value> members = user_data->args.get("members").get<picojson::array>();
1152 ret = media_playlist_get_media_count_from_db(std::stoi(playlist_id), NULL, &cnt);
1153 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1154 LoggerE("Failed: media_playlist_get_media_count_from_db");
1155 PlatformResult err = convertError(ret);
1156 user_data->isSuccess = err;
1159 std::size_t members_size = members.size();
1160 if (cnt < 0 || static_cast<size_t>(cnt) != members_size) {
1161 PlatformResult err = LogAndCreateResult(
1162 ErrorCode::INVALID_VALUES_ERR,
1163 "The items array does not contain all items from the playlist.",
1164 ("Failed: The items array does not contain all items from the playlist: %d (%s)", ret,
1165 get_error_message(ret)));
1166 user_data->isSuccess = err;
1170 for (std::size_t i = 0; i < members_size; ++i) {
1171 int member_id = static_cast<int>(members.at(i).get<double>());
1172 ret = media_playlist_set_play_order(playlist, member_id, i);
1173 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1174 LoggerD("Removing a content is failed.");
1178 ret = media_playlist_update_to_db(playlist);
1179 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1180 PlatformResult err = LogAndCreateResult(
1181 ErrorCode::UNKNOWN_ERR, "Removing the contents is failed.",
1182 ("Removing the contents is failed: %d (%s)", ret, get_error_message(ret)));
1183 user_data->isSuccess = err;
1187 void ContentManager::playlistMove(const std::shared_ptr<ReplyCallbackData>& user_data) {
1189 media_playlist_h playlist = NULL;
1193 media_playlist_destroy(playlist);
1197 std::string playlist_id = user_data->args.get("playlistId").get<std::string>();
1198 int ret = media_playlist_get_playlist_from_db(std::stoi(playlist_id), &playlist);
1199 if (ret != MEDIA_CONTENT_ERROR_NONE && playlist == NULL) {
1200 PlatformResult err =
1201 LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Getting playlist is failed.",
1202 ("Getting playlist is failed: %d (%s)", ret, get_error_message(ret)));
1203 user_data->isSuccess = err;
1207 double member_id = user_data->args.get("memberId").get<double>();
1208 double delta = user_data->args.get("delta").get<double>();
1209 ret = media_playlist_get_play_order(playlist, static_cast<int>(member_id), &old_order);
1210 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1211 PlatformResult err = LogAndCreateResult(
1212 ErrorCode::UNKNOWN_ERR, "The content can't find form playlist.",
1213 ("The content can't find form playlist: %d (%s)", ret, get_error_message(ret)));
1214 user_data->isSuccess = err;
1217 int new_order = static_cast<int>(old_order) + static_cast<int>(delta);
1218 ret = media_playlist_set_play_order(playlist, static_cast<int>(member_id), new_order);
1219 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1220 PlatformResult err = LogAndCreateResult(
1221 ErrorCode::UNKNOWN_ERR, "The content can't update play_order.",
1222 ("The content can't update play_order: %d (%s)", ret, get_error_message(ret)));
1223 user_data->isSuccess = err;
1226 ret = media_playlist_update_to_db(playlist);
1227 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1228 PlatformResult err = LogAndCreateResult(
1229 ErrorCode::UNKNOWN_ERR, "Updateing play_order is failed.",
1230 ("Updateing play_order is failed: %d (%s)", ret, get_error_message(ret)));
1231 user_data->isSuccess = err;
1235 int ContentManager::getLyrics(const picojson::value& args, picojson::object& result) {
1238 int ret = METADATA_EXTRACTOR_ERROR_NONE;
1239 const std::string& contentURI = args.get("contentURI").to_str();
1240 if (contentURI.empty()) {
1241 LoggerE("contentURI empty - skipping media extractor");
1245 metadata_extractor_h extractor;
1246 ret = metadata_extractor_create(&extractor);
1247 if (METADATA_EXTRACTOR_ERROR_NONE != ret) {
1248 LoggerE("metadata_extractor_create failed, error: %d", ret);
1250 std::unique_ptr<std::remove_pointer<metadata_extractor_h>::type, int (*)(metadata_extractor_h)>
1251 extractor_ptr(extractor, &metadata_extractor_destroy); // automatically release the memory
1253 ret = metadata_extractor_set_path(extractor, contentURI.c_str());
1254 if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
1255 LoggerE("metadata_extractor_set_path failed, error: %d", ret);
1258 picojson::array timestamps;
1259 picojson::array texts = picojson::array();
1260 char* strSyncTextNum = NULL;
1262 ret = metadata_extractor_get_metadata(extractor, METADATA_SYNCLYRICS_NUM, &strSyncTextNum);
1263 if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
1264 LoggerE("Media extractor error %d", ret);
1268 int nSyncTextNum = 0;
1269 if (strSyncTextNum) {
1270 nSyncTextNum = atoi(strSyncTextNum);
1271 free(strSyncTextNum);
1272 strSyncTextNum = NULL;
1274 if (nSyncTextNum > 0) {
1275 result["type"] = picojson::value(std::string("SYNCHRONIZED"));
1276 for (int i = 0; i < nSyncTextNum; i++) {
1277 unsigned long time_info = 0;
1278 char* lyrics = NULL;
1279 ret = metadata_extractor_get_synclyrics(extractor, i, &time_info, &lyrics);
1280 if (ret == METADATA_EXTRACTOR_ERROR_NONE) {
1281 timestamps.push_back(picojson::value(static_cast<double>(time_info)));
1282 texts.push_back(picojson::value(std::string(lyrics)));
1286 result["texts"] = picojson::value(texts);
1287 result["timestamps"] = picojson::value(timestamps);
1288 ret = METADATA_EXTRACTOR_ERROR_NONE;
1290 char* unSyncText = nullptr;
1291 ret = metadata_extractor_get_metadata(extractor, METADATA_UNSYNCLYRICS, &unSyncText);
1292 if (ret == METADATA_EXTRACTOR_ERROR_NONE) {
1293 result["type"] = picojson::value(std::string("UNSYNCHRONIZED"));
1294 if (nullptr == unSyncText) {
1295 LoggerE("Unsynchronized lyrics text is NULL");
1297 texts.push_back(picojson::value(unSyncText ? unSyncText : ""));
1298 result["texts"] = picojson::value(texts);
1306 media_playlist_h getPlaylistHandle(int id) {
1308 media_playlist_h playlist_handle = nullptr;
1309 int ret_code = media_playlist_get_playlist_from_db(id, &playlist_handle);
1310 if (MEDIA_CONTENT_ERROR_NONE != ret_code || playlist_handle == nullptr) {
1311 LoggerE("could not get playlist handle for id: %d", id);
1315 return playlist_handle;
1318 void destroyMediaPlaylistHandle(media_playlist_h playlist_handle) {
1320 if (playlist_handle) {
1321 int ret_code = media_playlist_destroy(playlist_handle);
1322 playlist_handle = nullptr;
1324 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1325 LoggerE("media_playlist_destroy failed");
1330 int ContentManager::getPlaylistName(int id, std::string* result) {
1332 media_playlist_h playlist_handle = getPlaylistHandle(id);
1333 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1335 char* tmp_playlist_name = nullptr;
1336 const int ret_code = media_playlist_get_name(playlist_handle, &tmp_playlist_name);
1338 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1339 LoggerE("media_playlist_get_name failed");
1340 return TIZEN_ERROR_UNKNOWN;
1343 std::string playlist_name;
1344 if (tmp_playlist_name) {
1345 playlist_name = tmp_playlist_name;
1346 free(tmp_playlist_name);
1347 tmp_playlist_name = nullptr;
1350 *result = playlist_name;
1351 return MEDIA_CONTENT_ERROR_NONE;
1354 int updatePlaylistInDB(media_playlist_h playlist_handle) {
1356 int ret_code = media_playlist_update_to_db(playlist_handle);
1357 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1358 LoggerE("media_playlist_update_to_db failed");
1361 return MEDIA_CONTENT_ERROR_NONE;
1364 int ContentManager::setPlaylistName(int id, const std::string& name) {
1367 LoggerE("Cannot set empty playlist name!");
1368 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1371 media_playlist_h playlist_handle = getPlaylistHandle(id);
1372 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1374 const int ret_code = media_playlist_set_name(playlist_handle, name.c_str());
1375 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1376 LoggerE("media_playlist_set_name failed");
1377 // Setting name that is used by other playlist does not return bad error code here.
1378 // MEDIA_CONTENT_ERROR_INVALID_OPERATION is being returned in updatePlaylistInDB
1379 return TIZEN_ERROR_UNKNOWN;
1382 int ret = updatePlaylistInDB(playlist_handle);
1383 if (MEDIA_CONTENT_ERROR_NONE != ret) {
1384 LoggerE("Error while updating playlist: %d", ret);
1385 if (MEDIA_CONTENT_ERROR_DB_FAILED == ret) {
1386 // We could fetch list of playlists and check if other playlist is using this
1387 // name, but that seems to be to much work in synchronous method
1388 LoggerE("Playlist name: %s is probably already used", name.c_str());
1389 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1393 return MEDIA_CONTENT_ERROR_NONE;
1396 int ContentManager::getThumbnailUri(int id, std::string* result) {
1398 media_playlist_h playlist_handle = getPlaylistHandle(id);
1399 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1401 char* tmp_playlist_thb_path = nullptr;
1402 const int ret_code = media_playlist_get_thumbnail_path(playlist_handle, &tmp_playlist_thb_path);
1404 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1405 LoggerE("media_playlist_get_name failed");
1406 return TIZEN_ERROR_UNKNOWN;
1409 std::string playlist_thb_path;
1410 if (tmp_playlist_thb_path) {
1411 playlist_thb_path = tmp_playlist_thb_path;
1412 free(tmp_playlist_thb_path);
1413 tmp_playlist_thb_path = nullptr;
1416 if (playlist_thb_path != " ") {
1417 playlist_thb_path = uri_prefix + playlist_thb_path;
1420 *result = playlist_thb_path;
1421 return MEDIA_CONTENT_ERROR_NONE;
1424 int ContentManager::setThumbnailUri(int id, const std::string& thb_uri) {
1427 // Allow setting empty URI, unfortunately Core API does not allow to set empty
1428 // path so we need to set one empty space. This is probably issue of Core API.
1429 if (!thb_uri.empty() && " " != thb_uri) {
1430 if (thb_uri.find(uri_absolute_prefix) != 0) {
1431 LoggerE("thumbnail URI is not valid: [%s]", thb_uri.c_str());
1432 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
1436 media_playlist_h playlist_handle = getPlaylistHandle(id);
1437 PlaylistUniquePtr playlist_ptr(playlist_handle, destroyMediaPlaylistHandle);
1439 std::string real_path = common::FilesystemProvider::Create().GetRealPath(thb_uri);
1440 const int ret_code = media_playlist_set_thumbnail_path(playlist_handle, real_path.c_str());
1441 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1442 LoggerE("media_playlist_set_thumbnail_path failed");
1443 return TIZEN_ERROR_UNKNOWN;
1446 int ret = updatePlaylistInDB(playlist_handle);
1450 int ContentManager::getNumberOfTracks(int id, int* result) {
1454 const int ret_code = media_playlist_get_media_count_from_db(id, nullptr, &count);
1456 if (MEDIA_CONTENT_ERROR_NONE != ret_code) {
1457 LoggerE("media_playlist_get_media_count_from_db failed");
1458 return TIZEN_ERROR_UNKNOWN;
1462 return MEDIA_CONTENT_ERROR_NONE;
1465 common::PlatformResult ContentManager::createThumbnail(const std::string& id,
1466 picojson::object* obj) {
1469 media_info_h media_h = nullptr;
1470 int ret = media_info_get_media_from_db(id.c_str(), &media_h);
1471 if (MEDIA_CONTENT_ERROR_NONE != ret || nullptr == media_h) {
1472 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Getting media failed.",
1473 ("Getting media failed: %d (%s)", ret, get_error_message(ret)));
1476 media_info_destroy(media_h);
1479 ret = media_info_generate_thumbnail(media_h);
1480 if (MEDIA_CONTENT_ERROR_NONE != ret) {
1481 return LogAndCreateResult(ErrorCode::ABORT_ERR, "Creating thumbnail failed.",
1482 ("Creating thumbnail failed: %d (%s)", ret, get_error_message(ret)));
1485 char* path = nullptr;
1486 ret = media_info_get_thumbnail_path(media_h, &path);
1487 if (MEDIA_CONTENT_ERROR_NONE != ret) {
1488 return LogAndCreateResult(
1489 ErrorCode::ABORT_ERR, "Creating thumbnail succeeded, but failed to get thumbnail path.",
1490 ("Getting thumbnail path failed: %d (%s)", ret, get_error_message(ret)));
1492 obj->emplace("result", picojson::value(path));
1493 std::unique_ptr<char[], decltype(&free)>(path, free);
1494 return PlatformResult(ErrorCode::NO_ERROR);
1497 PlatformResult ContentManager::convertError(int err) {
1498 char* error_msg = get_error_message(err);
1500 case MEDIA_CONTENT_ERROR_INVALID_PARAMETER:
1501 return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, error_msg);
1502 case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY:
1503 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1504 case MEDIA_CONTENT_ERROR_INVALID_OPERATION:
1505 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1506 case MEDIA_CONTENT_FILE_NO_SPACE_ON_DEVICE:
1507 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1508 case MEDIA_CONTENT_ERROR_PERMISSION_DENIED:
1509 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1510 case MEDIA_CONTENT_ERROR_DB_FAILED:
1511 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1512 case MEDIA_CONTENT_ERROR_DB_BUSY:
1513 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1514 case MEDIA_CONTENT_ERROR_NETWORK:
1515 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1516 case MEDIA_CONTENT_ERROR_UNSUPPORTED_CONTENT:
1517 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, error_msg);
1519 return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown error.");
1523 } // namespace content
1524 } // namespace extension