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_instance.h"
20 #include <media_content.h>
25 #include "common/logger.h"
26 #include "common/picojson.h"
27 #include "common/platform_result.h"
28 #include "common/task-queue.h"
29 #include "common/tools.h"
31 #include "common/filesystem/filesystem_provider.h"
32 #include "content/content_manager.h"
34 using namespace common;
40 // The privileges that required in Content API
41 const std::string kPrivilegeContentRead = "http://tizen.org/privilege/content.read";
42 const std::string kPrivilegeContentWrite = "http://tizen.org/privilege/content.write";
46 using common::tools::ReportSuccess;
47 using common::tools::ReportError;
48 using common::PlatformResult;
50 ContentInstance::ContentInstance()
51 : noti_handle_(nullptr),
52 listener_handle_(nullptr),
53 listener_data_(nullptr),
54 callback_data_(nullptr) {
56 using std::placeholders::_1;
57 using std::placeholders::_2;
59 #define REGISTER_METHOD(M) RegisterSyncHandler(#M, std::bind(&ContentInstance::M, this, _1, _2))
61 REGISTER_METHOD(ContentManagerFind);
62 REGISTER_METHOD(ContentManagerUpdate);
63 REGISTER_METHOD(ContentManagerScanfile);
64 REGISTER_METHOD(ContentManagerScanDirectory);
65 REGISTER_METHOD(ContentManagerCancelScanDirectory);
66 REGISTER_METHOD(ContentManagerAddChangeListener);
67 REGISTER_METHOD(ContentManagerRemoveChangeListener);
68 REGISTER_METHOD(ContentManagerUnsetchangelistener);
69 REGISTER_METHOD(ContentManagerSetchangelistener);
70 REGISTER_METHOD(ContentManagerGetdirectories);
71 REGISTER_METHOD(ContentManagerUpdatebatch);
72 REGISTER_METHOD(ContentManagerRemoveplaylist);
73 REGISTER_METHOD(ContentManagerCreateplaylist);
74 REGISTER_METHOD(ContentManagerGetplaylists);
75 REGISTER_METHOD(ContentManagerPlaylistAdd);
76 REGISTER_METHOD(ContentManagerPlaylistAddbatch);
77 REGISTER_METHOD(ContentManagerPlaylistGet);
78 REGISTER_METHOD(ContentManagerPlaylistRemove);
79 REGISTER_METHOD(ContentManagerPlaylistRemovebatch);
80 REGISTER_METHOD(ContentManagerPlaylistSetorder);
81 REGISTER_METHOD(ContentManagerPlaylistMove);
82 REGISTER_METHOD(ContentManagerAudioGetLyrics);
84 REGISTER_METHOD(PlaylistGetName);
85 REGISTER_METHOD(PlaylistSetName);
86 REGISTER_METHOD(PlaylistGetThumbnailUri);
87 REGISTER_METHOD(PlaylistSetThumbnailUri);
88 REGISTER_METHOD(PlaylistGetNumberOfTracks);
89 REGISTER_METHOD(ContentManagerCreateThumbnail);
91 #undef REGISTER_METHOD
93 ContentManager::getInstance()->setContentInstance(this);
96 ContentInstance::~ContentInstance() {
100 media_content_remove_db_updated_cb(noti_handle_);
101 noti_handle_ = nullptr;
104 if (listener_handle_) {
105 media_content_remove_db_updated_cb(listener_handle_);
106 listener_handle_ = nullptr;
109 if (listener_data_) {
110 delete listener_data_;
111 listener_data_ = nullptr;
114 if (callback_data_) {
115 delete callback_data_;
116 callback_data_ = nullptr;
119 ContentManager::getInstance()->setContentInstance(nullptr);
122 static gboolean CompletedCallback(const std::shared_ptr<ReplyCallbackData>& user_data) {
125 picojson::object out;
126 out["callbackId"] = picojson::value(user_data->callbackId);
128 if (user_data->isSuccess) {
129 ReportSuccess(user_data->result, out);
131 LogAndReportError(user_data->isSuccess, &out, ("Failed: user_data->isSuccess"));
134 common::Instance::PostMessage(user_data->instance, picojson::value(out).serialize().c_str());
139 static void* WorkThread(const std::shared_ptr<ReplyCallbackData>& user_data) {
142 int ret = MEDIA_CONTENT_ERROR_NONE;
143 ContentCallbacks cbType = user_data->cbType;
145 case ContentManagerUpdatebatchCallback: {
146 ret = ContentManager::getInstance()->updateBatch(user_data->args);
147 if (ret != MEDIA_CONTENT_ERROR_NONE) {
148 LoggerD("UpdateBatch Failed");
149 user_data->isSuccess = ContentManager::getInstance()->convertError(ret);
153 case ContentManagerGetdirectoriesCallback: {
154 ContentManager::getInstance()->getDirectories(user_data);
157 case ContentManagerFindCallback: {
158 ContentManager::getInstance()->find(user_data);
161 case ContentManagerScanfileCallback: {
162 std::string contentURI = user_data->args.get("contentURI").get<std::string>();
163 std::string real_path = common::FilesystemProvider::Create().GetRealPath(contentURI);
164 ret = ContentManager::getInstance()->scanFile(real_path);
165 if (ret != MEDIA_CONTENT_ERROR_NONE) {
167 LogAndCreateResult(common::ErrorCode::UNKNOWN_ERR, "Scan file failed.",
168 ("Scan file failed, error: %d (%s)", ret, get_error_message(ret)));
169 user_data->isSuccess = err;
173 case ContentManagerGetplaylistsCallback: {
174 ContentManager::getInstance()->getPlaylists(user_data);
177 case ContentManagerCreateplaylistCallback: {
178 if (user_data->args.contains("sourcePlaylist")) {
179 picojson::object playlist = user_data->args.get("sourcePlaylist").get<picojson::object>();
180 user_data->result = picojson::value(playlist);
182 std::string name = user_data->args.get("name").get<std::string>();
183 ContentManager::getInstance()->createPlaylist(name, user_data);
187 case ContentManagerRemoveplaylistCallback: {
188 std::string id = user_data->args.get("id").get<std::string>();
189 ContentManager::getInstance()->removePlaylist(id, user_data);
193 case ContentManagerPlaylistAddbatchCallback: {
194 ContentManager::getInstance()->playlistAddbatch(user_data);
197 case ContentManagerPlaylistGetCallback: {
198 ContentManager::getInstance()->playlistGet(user_data);
201 case ContentManagerPlaylistRemovebatchCallback: {
202 ContentManager::getInstance()->playlistRemovebatch(user_data);
205 case ContentManagerPlaylistSetOrderCallback: {
206 ContentManager::getInstance()->playlistSetOrder(user_data);
208 // ContentManagerPlaylistSetOrderCallback
210 case ContentManagerPlaylistMoveCallback: {
211 ContentManager::getInstance()->playlistMove(user_data);
214 case ContentManagerErrorCallback: {
215 common::PlatformResult err =
216 LogAndCreateResult(common::ErrorCode::UNKNOWN_ERR, "DB Connection is failed.");
217 user_data->isSuccess = err;
221 LoggerE("Invalid Callback Type");
228 static void ScanDirectoryCallback(media_content_error_e error, void* user_data) {
231 ReplyCallbackData* cbData = (ReplyCallbackData*)user_data;
233 picojson::object out;
234 out["callbackId"] = picojson::value(cbData->callbackId);
236 if (error == MEDIA_CONTENT_ERROR_NONE) {
239 LoggerE("Scanning directory failed error: %d (%s)", error, get_error_message(error));
243 common::Instance::PostMessage(cbData->instance, picojson::value(out).serialize().c_str());
246 static void changedContentCallback(media_content_error_e error, int pid,
247 media_content_db_update_item_type_e update_item,
248 media_content_db_update_type_e update_type,
249 media_content_type_e media_type, char* uuid, char* path,
250 char* mime_type, void* user_data) {
251 ScopeLogger("Directory change callback");
253 if (error != MEDIA_CONTENT_ERROR_NONE) {
254 LoggerE("Media content changed v2 callback error: %d", (int)error);
258 if (update_item == MEDIA_ITEM_DIRECTORY) {
260 LoggerE("Provided uuid is NULL, ignoring");
264 ReplyCallbackData* cbData = static_cast<ReplyCallbackData*>(user_data);
267 picojson::value result = picojson::value(picojson::object());
268 picojson::object& obj = result.get<picojson::object>();
270 if (update_type == MEDIA_CONTENT_INSERT || update_type == MEDIA_CONTENT_UPDATE) {
271 media_folder_h folder = NULL;
272 ret = media_folder_get_folder_from_db(uuid, &folder);
273 if (ret == MEDIA_CONTENT_ERROR_NONE && folder != NULL) {
276 ContentDirToJson(folder, o);
277 ReportSuccess(picojson::value(o), obj);
279 if (update_type == MEDIA_CONTENT_INSERT) {
280 obj["state"] = picojson::value("oncontentdiradded");
282 obj["state"] = picojson::value("oncontentdirupdated");
285 media_folder_destroy(folder);
288 ReportSuccess(picojson::value(std::string(uuid)), obj);
289 obj["state"] = picojson::value("oncontentdirremoved");
292 obj["listenerId"] = cbData->args.get("listenerId");
293 common::Instance::PostMessage(cbData->instance, result.serialize().c_str());
295 LoggerD("Media item is not directory, skipping.");
300 static PlatformResult prepareDirectoryChangeResponse(media_content_db_update_type_e update_type,
301 char* uuid, picojson::object& obj) {
302 ScopeLogger("Media item is a directory");
304 if (MEDIA_CONTENT_DELETE == update_type) {
305 ReportSuccess(picojson::value(std::string(uuid)), obj);
306 obj["state"] = picojson::value("oncontentdirremoved");
307 return PlatformResult(ErrorCode::NO_ERROR);
310 media_folder_h folder = nullptr;
311 int ret = media_folder_get_folder_from_db(uuid, &folder);
313 if (MEDIA_CONTENT_ERROR_NONE != ret || nullptr == folder) {
314 LoggerE("Failed to get media item (media_folder_get_folder_from_db): %d", ret);
315 return PlatformResult(ErrorCode::ABORT_ERR);
319 ContentDirToJson(folder, o);
321 ret = media_folder_destroy(folder);
323 if (MEDIA_CONTENT_ERROR_NONE != ret) {
324 LoggerE("Failed to destroy media folder (media_folder_destroy): %d", ret);
325 return PlatformResult(ErrorCode::ABORT_ERR);
328 ReportSuccess(picojson::value(o), obj);
330 if (MEDIA_CONTENT_INSERT == update_type) {
331 obj["state"] = picojson::value("oncontentdiradded");
332 } else if (MEDIA_CONTENT_UPDATE == update_type) {
333 obj["state"] = picojson::value("oncontentdirupdated");
336 return PlatformResult(ErrorCode::NO_ERROR);
339 static PlatformResult prepareFileChangeResponse(media_content_db_update_type_e update_type,
340 char* uuid, picojson::object& obj) {
341 ScopeLogger("Media item is a file");
343 if (MEDIA_CONTENT_DELETE == update_type) {
344 ReportSuccess(picojson::value(std::string(uuid)), obj);
345 obj["state"] = picojson::value("oncontentremoved");
346 return PlatformResult(ErrorCode::NO_ERROR);
349 media_info_h media = nullptr;
350 int ret = media_info_get_media_from_db(uuid, &media);
352 if (MEDIA_CONTENT_ERROR_NONE != ret || nullptr == media) {
353 LoggerE("Failed to get media item (media_info_get_media_from_db): %d", ret);
354 return PlatformResult(ErrorCode::ABORT_ERR);
358 ContentToJson(media, o);
360 ret = media_info_destroy(media);
362 if (MEDIA_CONTENT_ERROR_NONE != ret) {
363 LoggerE("Failed to destroy media info (media_info_destroy): %d", ret);
364 return PlatformResult(ErrorCode::ABORT_ERR);
367 ReportSuccess(picojson::value(o), obj);
369 if (MEDIA_CONTENT_INSERT == update_type) {
370 obj["state"] = picojson::value("oncontentadded");
371 } else if (MEDIA_CONTENT_UPDATE == update_type) {
372 obj["state"] = picojson::value("oncontentupdated");
375 return PlatformResult(ErrorCode::NO_ERROR);
378 static void contentChangeCallback(media_content_error_e error, int pid,
379 media_content_db_update_item_type_e update_item,
380 media_content_db_update_type_e update_type,
381 media_content_type_e media_type, char* uuid, char* path,
382 char* mime_type, void* user_data) {
383 ScopeLogger("directory and file change callback");
385 if (MEDIA_CONTENT_ERROR_NONE != error) {
386 LoggerE("Failed to perform contentChangeCallback: %d", error);
391 LoggerE("Provided uuid is NULL, ignoring");
395 if (nullptr == user_data) {
396 LoggerE("Provided user data is NULL, ignoring");
400 if (MEDIA_ITEM_DIRECTORY != update_item && MEDIA_ITEM_FILE != update_item) {
401 LoggerD("Media item is not a directory nor a file, skipping");
405 ReplyCallbackData* cbData = static_cast<ReplyCallbackData*>(user_data);
407 picojson::value result = picojson::value(picojson::object());
408 picojson::object& obj = result.get<picojson::object>();
410 PlatformResult ret(ErrorCode::NO_ERROR);
411 if (MEDIA_ITEM_DIRECTORY == update_item) {
412 ret = prepareDirectoryChangeResponse(update_type, uuid, obj);
413 } else if (MEDIA_ITEM_FILE == update_item) {
414 ret = prepareFileChangeResponse(update_type, uuid, obj);
417 if (ret.IsSuccess()) {
418 obj["listenerId"] = picojson::value("ContentManagerChangeCallback");
419 Instance::PostMessage(cbData->instance, result.serialize().c_str());
421 LoggerD("Failed to prepare content change callback, ignoring");
425 #define CHECK_EXIST(args, name, out) \
426 if (!args.contains(name)) { \
427 LogAndReportError(common::PlatformResult(common::ErrorCode::TYPE_MISMATCH_ERR, \
428 (name " is required argument")), \
433 void ContentInstance::ContentManagerUpdate(const picojson::value& args, picojson::object& out) {
435 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
437 if (ContentManager::getInstance()->isConnected()) {
438 int ret = ContentManager::getInstance()->update(args);
440 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
444 common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "DB connection is failed."), &out);
448 void ContentInstance::ContentManagerUpdatebatch(const picojson::value& args,
449 picojson::object& out) {
451 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
452 double callbackId = args.get("callbackId").get<double>();
454 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
455 cbData->callbackId = callbackId;
456 cbData->instance = this;
459 if (ContentManager::getInstance()->isConnected()) {
460 cbData->cbType = ContentManagerUpdatebatchCallback;
462 cbData->cbType = ContentManagerErrorCallback;
464 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
466 void ContentInstance::ContentManagerGetdirectories(const picojson::value& args,
467 picojson::object& out) {
469 CHECK_EXIST(args, "callbackId", out)
471 double callbackId = args.get("callbackId").get<double>();
474 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
475 cbData->callbackId = callbackId;
476 cbData->instance = this;
478 if (ContentManager::getInstance()->isConnected()) {
479 cbData->cbType = ContentManagerGetdirectoriesCallback;
481 cbData->cbType = ContentManagerErrorCallback;
483 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
485 void ContentInstance::ContentManagerFind(const picojson::value& args, picojson::object& out) {
487 // CHECK_PRIVILEGE_ACCESS(kPrivilegeContentRead, &out);
488 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
490 CHECK_EXIST(args, "callbackId", out)
492 double callbackId = args.get("callbackId").get<double>();
494 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
495 cbData->callbackId = callbackId;
496 cbData->instance = this;
498 if (ContentManager::getInstance()->isConnected()) {
499 cbData->cbType = ContentManagerFindCallback;
501 cbData->cbType = ContentManagerErrorCallback;
504 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
507 void ContentInstance::ContentManagerScanfile(const picojson::value& args, picojson::object& out) {
509 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
511 CHECK_EXIST(args, "callbackId", out)
512 CHECK_EXIST(args, "contentURI", out)
514 const std::string& contentURI = args.get("contentURI").get<std::string>();
515 const std::string& real_path = common::FilesystemProvider::Create().GetRealPath(contentURI);
517 CHECK_STORAGE_ACCESS(real_path, &out);
519 double callbackId = args.get("callbackId").get<double>();
520 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
521 cbData->callbackId = callbackId;
522 cbData->instance = this;
524 if (ContentManager::getInstance()->isConnected()) {
525 cbData->cbType = ContentManagerScanfileCallback;
527 cbData->cbType = ContentManagerErrorCallback;
529 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
532 void ContentInstance::ContentManagerScanDirectory(const picojson::value& args,
533 picojson::object& out) {
535 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
537 CHECK_EXIST(args, "callbackId", out)
538 CHECK_EXIST(args, "contentDirURI", out)
539 CHECK_EXIST(args, "recursive", out)
541 const std::string& contentURI = args.get("contentDirURI").get<std::string>();
542 const std::string& real_path = common::FilesystemProvider::Create().GetRealPath(contentURI);
544 CHECK_STORAGE_ACCESS(real_path, &out);
546 ReplyCallbackData* cbData = new ReplyCallbackData;
547 cbData->callbackId = args.get("callbackId").get<double>();
548 cbData->instance = this;
551 common::PlatformResult result =
552 ContentManager::getInstance()->scanDirectory(ScanDirectoryCallback, cbData);
553 if (result.IsError()) {
554 LogAndReportError(result, &out);
558 void ContentInstance::ContentManagerCancelScanDirectory(const picojson::value& args,
559 picojson::object& out) {
561 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
563 CHECK_EXIST(args, "contentDirURI", out)
564 const std::string& content_dir_uri = args.get("contentDirURI").get<std::string>();
566 if (ContentManager::getInstance()->cancelScanDirectory(content_dir_uri).IsError()) {
568 common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "Cancel scan directory failed"),
573 void ContentInstance::ContentManagerAddChangeListener(const picojson::value& args,
574 picojson::object& out) {
577 callback_data_ = new ReplyCallbackData();
578 callback_data_->instance = this;
579 callback_data_->args = args;
581 if (ContentManager::getInstance()->isConnected()) {
582 callback_data_->cbType = ContentManagerAddChangeListenerCallback;
584 callback_data_->cbType = ContentManagerErrorCallback;
587 PlatformResult result = ContentManager::getInstance()->addChangeListener(
588 &listener_handle_, contentChangeCallback, static_cast<void*>(callback_data_));
590 if (result.IsError()) {
591 delete callback_data_;
592 callback_data_ = nullptr;
593 LogAndReportError(result, &out);
597 void ContentInstance::ContentManagerRemoveChangeListener(const picojson::value& args,
598 picojson::object& out) {
601 PlatformResult result = ContentManager::getInstance()->removeChangeListener(listener_handle_);
603 if (result.IsSuccess()) {
604 listener_handle_ = nullptr;
605 delete callback_data_;
606 callback_data_ = nullptr;
608 LogAndReportError(result, &out);
612 void ContentInstance::ContentManagerSetchangelistener(const picojson::value& args,
613 picojson::object& out) {
616 "setChangeListener() is deprecated and will be removed from next "
617 "release. Use addChangeListener() instead.",
619 // CHECK_PRIVILEGE_ACCESS(kPrivilegeContentRead, &out);
620 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
622 CHECK_EXIST(args, "listenerId", out)
624 if (!listener_data_) {
625 listener_data_ = new ReplyCallbackData();
628 listener_data_->instance = this;
629 listener_data_->args = args;
630 if (ContentManager::getInstance()->isConnected()) {
631 listener_data_->cbType = ContentManagerSetchangelistenerCallback;
633 listener_data_->cbType = ContentManagerErrorCallback;
636 if (nullptr == noti_handle_) { // To remain consistency with the previous implementation
637 if (ContentManager::getInstance()
638 ->addChangeListener(¬i_handle_, changedContentCallback,
639 static_cast<void*>(listener_data_))
641 LogAndReportError(common::PlatformResult(common::ErrorCode::UNKNOWN_ERR,
642 "The callback did not register properly"),
648 void ContentInstance::ContentManagerUnsetchangelistener(const picojson::value& args,
649 picojson::object& out) {
652 "unsetChangeListener() is deprecated and will be removed from next "
653 "release. Use removeChangeListener() instead.",
655 // CHECK_PRIVILEGE_ACCESS(kPrivilegeContentRead, &out);
656 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
658 if (ContentManager::getInstance()->removeChangeListener(noti_handle_).IsError()) {
659 LoggerD("unsuccesfull deregistering of callback");
661 noti_handle_ = nullptr; // To remain consistency with the previous implementation
665 void ContentInstance::ContentManagerGetplaylists(const picojson::value& args,
666 picojson::object& out) {
668 // CHECK_PRIVILEGE_ACCESS(kPrivilegeContentRead, &out);
669 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
671 CHECK_EXIST(args, "callbackId", out)
673 double callbackId = args.get("callbackId").get<double>();
676 std::shared_ptr<ReplyCallbackData> cbData(new ReplyCallbackData);
678 cbData->callbackId = callbackId;
679 cbData->instance = this;
681 if (ContentManager::getInstance()->isConnected()) {
682 cbData->cbType = ContentManagerGetplaylistsCallback;
684 cbData->cbType = ContentManagerErrorCallback;
687 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
689 void ContentInstance::ContentManagerCreateplaylist(const picojson::value& args,
690 picojson::object& out) {
692 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
694 CHECK_EXIST(args, "callbackId", out)
695 CHECK_EXIST(args, "name", out)
697 double callbackId = args.get("callbackId").get<double>();
699 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
700 cbData->callbackId = callbackId;
701 cbData->instance = this;
704 if (ContentManager::getInstance()->isConnected()) {
705 cbData->cbType = ContentManagerCreateplaylistCallback;
707 cbData->cbType = ContentManagerErrorCallback;
710 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
712 void ContentInstance::ContentManagerRemoveplaylist(const picojson::value& args,
713 picojson::object& out) {
715 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
717 double callbackId = args.get("callbackId").get<double>();
719 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
720 cbData->callbackId = callbackId;
721 cbData->instance = this;
724 if (ContentManager::getInstance()->isConnected()) {
725 cbData->cbType = ContentManagerRemoveplaylistCallback;
727 cbData->cbType = ContentManagerErrorCallback;
731 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
734 void ContentInstance::ContentManagerCreateThumbnail(const picojson::value& args,
735 picojson::object& out) {
737 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
738 double callback_id = args.get("callbackId").get<double>();
740 if (not ContentManager::getInstance()->isConnected()) {
741 TaskQueue::GetInstance().Async([this, callback_id]() {
742 PlatformResult result =
743 LogAndCreateResult(common::ErrorCode::ABORT_ERR, "DB Connection is not established.");
744 picojson::value response = picojson::value(picojson::object());
745 picojson::object& obj = response.get<picojson::object>();
746 obj.emplace("callbackId", picojson::value(callback_id));
747 LogAndReportError(result, &obj, ("DB Connection is not established."));
748 Instance::PostMessage(this, response.serialize().c_str());
753 const std::string& id = args.get("id").get<std::string>();
754 auto work = [this, id, callback_id]() {
756 picojson::value response = picojson::value(picojson::object());
757 picojson::object& obj = response.get<picojson::object>();
758 obj.emplace("callbackId", picojson::value(callback_id));
759 auto result = ContentManager::getInstance()->createThumbnail(id, &obj);
763 LogAndReportError(result, &obj);
765 Instance::PostMessage(this, response.serialize().c_str());
767 TaskQueue::GetInstance().Async(work);
771 void ContentInstance::ContentManagerPlaylistAdd(const picojson::value& args,
772 picojson::object& out) {
774 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
776 if (ContentManager::getInstance()->isConnected()) {
777 std::string playlist_id = args.get("playlistId").get<std::string>();
778 std::string content_id = args.get("contentId").get<std::string>();
779 int ret = ContentManager::getInstance()->playlistAdd(playlist_id, content_id);
780 if (ret != MEDIA_CONTENT_ERROR_NONE) {
781 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
785 common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "DB connection is failed."), &out);
789 void ContentInstance::ContentManagerPlaylistAddbatch(const picojson::value& args,
790 picojson::object& out) {
792 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
794 double callbackId = args.get("callbackId").get<double>();
796 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
797 cbData->callbackId = callbackId;
798 cbData->instance = this;
801 if (ContentManager::getInstance()->isConnected()) {
802 cbData->cbType = ContentManagerPlaylistAddbatchCallback;
804 cbData->cbType = ContentManagerErrorCallback;
806 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
809 void ContentInstance::ContentManagerPlaylistGet(const picojson::value& args,
810 picojson::object& out) {
812 // CHECK_PRIVILEGE_ACCESS(kPrivilegeContentRead, &out);
813 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
815 double callbackId = args.get("callbackId").get<double>();
817 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
818 cbData->callbackId = callbackId;
819 cbData->instance = this;
822 if (ContentManager::getInstance()->isConnected()) {
823 cbData->cbType = ContentManagerPlaylistGetCallback;
825 cbData->cbType = ContentManagerErrorCallback;
827 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
830 void ContentInstance::ContentManagerPlaylistRemove(const picojson::value& args,
831 picojson::object& out) {
833 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
835 if (ContentManager::getInstance()->isConnected()) {
836 std::string playlist_id = args.get("playlistId").get<std::string>();
837 int member_id = args.get("memberId").get<double>();
838 int ret = ContentManager::getInstance()->playlistRemove(playlist_id, member_id);
839 if (ret != MEDIA_CONTENT_ERROR_NONE) {
840 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
844 common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "DB connection is failed."), &out);
848 void ContentInstance::ContentManagerPlaylistRemovebatch(const picojson::value& args,
849 picojson::object& out) {
851 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
853 double callbackId = args.get("callbackId").get<double>();
855 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
856 cbData->callbackId = callbackId;
857 cbData->instance = this;
860 if (ContentManager::getInstance()->isConnected()) {
861 cbData->cbType = ContentManagerPlaylistRemovebatchCallback;
863 cbData->cbType = ContentManagerErrorCallback;
865 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
868 void ContentInstance::ContentManagerPlaylistSetorder(const picojson::value& args,
869 picojson::object& out) {
871 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
873 double callbackId = args.get("callbackId").get<double>();
875 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
876 cbData->callbackId = callbackId;
877 cbData->instance = this;
880 if (ContentManager::getInstance()->isConnected()) {
881 cbData->cbType = ContentManagerPlaylistSetOrderCallback;
883 cbData->cbType = ContentManagerErrorCallback;
885 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
888 void ContentInstance::ContentManagerPlaylistMove(const picojson::value& args,
889 picojson::object& out) {
891 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
893 double callbackId = args.get("callbackId").get<double>();
895 auto cbData = std::shared_ptr<ReplyCallbackData>(new ReplyCallbackData);
896 cbData->callbackId = callbackId;
897 cbData->instance = this;
900 if (ContentManager::getInstance()->isConnected()) {
901 cbData->cbType = ContentManagerPlaylistMoveCallback;
903 cbData->cbType = ContentManagerErrorCallback;
905 common::TaskQueue::GetInstance().Queue<ReplyCallbackData>(WorkThread, CompletedCallback, cbData);
908 void ContentInstance::ContentManagerAudioGetLyrics(const picojson::value& args,
909 picojson::object& out) {
912 const std::string& contentURI = args.get("contentURI").get<std::string>();
913 const std::string& real_path = common::FilesystemProvider::Create().GetRealPath(contentURI);
915 CHECK_STORAGE_ACCESS(real_path, &out);
917 picojson::object lyrics;
918 if (ContentManager::getInstance()->isConnected()) {
919 int ret = ContentManager::getInstance()->getLyrics(args, lyrics);
920 if (ret != MEDIA_CONTENT_ERROR_NONE) {
921 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
923 ReportSuccess(picojson::value(lyrics), out);
927 common::PlatformResult(common::ErrorCode::UNKNOWN_ERR, "DB connection is failed."), &out);
931 void ContentInstance::PlaylistGetName(const picojson::value& args, picojson::object& out) {
934 CHECK_EXIST(args, "id", out)
935 int id = static_cast<int>(args.get("id").get<double>());
937 ret = ContentManager::getInstance()->getPlaylistName(id, &name);
938 if (ret != MEDIA_CONTENT_ERROR_NONE) {
939 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
941 ReportSuccess(picojson::value(name), out);
945 void ContentInstance::PlaylistSetName(const picojson::value& args, picojson::object& out) {
947 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
950 CHECK_EXIST(args, "id", out)
951 CHECK_EXIST(args, "name", out)
952 int id = static_cast<int>(args.get("id").get<double>());
953 std::string name = args.get("name").get<std::string>();
954 ret = ContentManager::getInstance()->setPlaylistName(id, name);
955 if (ret != MEDIA_CONTENT_ERROR_NONE) {
956 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
962 void ContentInstance::PlaylistGetThumbnailUri(const picojson::value& args, picojson::object& out) {
965 CHECK_EXIST(args, "id", out)
966 int id = static_cast<int>(args.get("id").get<double>());
968 ret = ContentManager::getInstance()->getThumbnailUri(id, &uri);
969 if (ret != MEDIA_CONTENT_ERROR_NONE) {
970 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
972 ReportSuccess(picojson::value(uri), out);
976 void ContentInstance::PlaylistSetThumbnailUri(const picojson::value& args, picojson::object& out) {
978 CHECK_PRIVILEGE_ACCESS(kPrivilegeContentWrite, &out);
981 CHECK_EXIST(args, "id", out)
982 CHECK_EXIST(args, "uri", out)
983 int id = static_cast<int>(args.get("id").get<double>());
984 std::string uri = args.get("uri").get<std::string>();
985 const std::string& real_path = common::FilesystemProvider::Create().GetRealPath(uri);
987 CHECK_STORAGE_ACCESS(real_path, &out);
989 ret = ContentManager::getInstance()->setThumbnailUri(id, uri);
990 if (ret != MEDIA_CONTENT_ERROR_NONE) {
991 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
997 void ContentInstance::PlaylistGetNumberOfTracks(const picojson::value& args,
998 picojson::object& out) {
1000 CHECK_EXIST(args, "id", out)
1001 int id = static_cast<int>(args.get("id").get<double>());
1003 int ret = ContentManager::getInstance()->getNumberOfTracks(id, &count);
1004 if (ret != MEDIA_CONTENT_ERROR_NONE) {
1005 LogAndReportError(ContentManager::getInstance()->convertError(ret), &out);
1007 ReportSuccess(picojson::value(static_cast<double>(count)), out);
1013 } // namespace content
1014 } // namespace extension