2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 #include <libexif/exif-loader.h>
19 #include <Commons/StringUtils.h>
20 #include <Commons/ThreadPool.h>
21 #include "IContentManager.h"
22 #include "ContentListener.h"
23 #include "ContentImage.h"
24 #include "ContentMedia.h"
25 #include "ContentVideo.h"
26 #include "ContentAudio.h"
27 #include "ContentManager.h"
28 #include "ContentExif.h"
29 #include "ContentUtility.h"
36 IMediacontentManager::IMediacontentManager() :
37 WrtDeviceApis::Commons::EventRequestReceiver<IEventFindFolder>(WrtDeviceApis::Commons::ThreadEnum::MEDIACONTENT_THREAD),
38 WrtDeviceApis::Commons::EventRequestReceiver<IEventBrowseFolder>(WrtDeviceApis::Commons::ThreadEnum::MEDIACONTENT_THREAD),
39 WrtDeviceApis::Commons::EventRequestReceiver<IEventUpdateMedia>(WrtDeviceApis::Commons::ThreadEnum::MEDIACONTENT_THREAD),
40 WrtDeviceApis::Commons::EventRequestReceiver<IEventUpdateMediaItems>(WrtDeviceApis::Commons::ThreadEnum::MEDIACONTENT_THREAD)
45 IMediacontentManager::~IMediacontentManager()
49 void IMediacontentManager::findFolder(IEventFindFolderPtr &ptr)
51 LogDebug("IMediacontentManager::called findFolders");
52 WrtDeviceApis::Commons::EventRequestReceiver<IEventFindFolder>::PostRequest(ptr);
55 void IMediacontentManager::updateMedia(IEventUpdateMediaPtr &ptr)
57 LogDebug("IMediacontentManager::called updateMedia");
58 WrtDeviceApis::Commons::EventRequestReceiver<IEventUpdateMedia>::PostRequest(ptr);
61 void IMediacontentManager::browseFolder(IEventBrowseFolderPtr &ptr)
63 LogDebug("IMediacontentManager::called IEventBrowseFolder");
64 WrtDeviceApis::Commons::EventRequestReceiver<IEventBrowseFolder>::PostRequest(ptr);
67 void IMediacontentManager::updateMediaItems(IEventUpdateMediaItemsPtr &ptr)
69 LogDebug("IMediacontentManager::called IEventBrowseFolder");
70 WrtDeviceApis::Commons::EventRequestReceiver<IEventUpdateMediaItems>::PostRequest(ptr);
74 struct scanCallbackData
78 scanCompletedCallback callback;
82 static gboolean _scan_file_completed_cb(void *user_data)
85 LogDebug("called _scan_file_completed_cb:");
87 scanCallbackData *data = static_cast<scanCallbackData*>(user_data);
91 string path = data->path;
92 void* _user_data = data->user_data;
93 scanCompletedCallback _callback = data->callback;
97 if( data->result == MEDIA_CONTENT_ERROR_NONE)
101 else if( data->result == MEDIA_CONTENT_ERROR_OUT_OF_MEMORY)
103 err_msg = "scanning is failed by out of memory";
105 else if( data->result == MEDIA_CONTENT_ERROR_INVALID_OPERATION)
107 err_msg = "scanning is failed by invalid operation";
109 else if( data->result == MEDIA_CONTENT_ERROR_DB_FAILED)
111 err_msg = "scanning is failed because db operation is failed";
113 else if( data->result == MEDIA_CONTENT_ERROR_DB_BUSY)
115 err_msg = "scanning is failed because db operation is failed";
119 err_msg = "scanning is failed by unknown reason";
121 _callback(err_msg, path, _user_data);
129 static void _scan_file_thread(void *user_data, Ecore_Thread *thread){
130 LogDebug("_scan_file_thread::called");
131 scanCallbackData *data = static_cast<scanCallbackData*>(user_data);
132 data->result = media_content_scan_file(data->path.c_str());
133 LogDebug("native error code:" << data->result);
134 g_idle_add(_scan_file_completed_cb, data);
137 bool IMediacontentManager::scanFile(scanCompletedCallback callback, std::string path, void* user_data)
139 LogDebug("ContentManager::called scan");
143 LogDebug("ContentManager::path:" << path);
145 scanCallbackData *data = new scanCallbackData();
147 data->callback = callback;
148 data->user_data = user_data;
150 ecore_thread_run( _scan_file_thread, NULL, NULL, static_cast<void*>(data));
156 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "URI is not available");
161 static bool mediaItemCallback(media_info_h info, void* user_data)
163 media_content_type_e type;
164 LogDebug("mediaItemCallback is called");
166 if ( MEDIA_CONTENT_ERROR_NONE == media_info_get_media_type( info, &type) )
168 if ( type == MEDIA_CONTENT_TYPE_IMAGE)
170 MediacontentManager::readImageFromMediaInfo(info, static_cast<MediacontentImage*>(user_data));
172 else if ( type == MEDIA_CONTENT_TYPE_VIDEO)
174 MediacontentManager::readVideoFromMediaInfo(info, static_cast<MediacontentVideo*>(user_data));
176 else if ( type == MEDIA_CONTENT_TYPE_MUSIC || type == MEDIA_CONTENT_TYPE_SOUND)
178 MediacontentManager::readMusicFromMediaInfo(info, static_cast<MediacontentAudio*>(user_data));
180 else if( type == MEDIA_CONTENT_TYPE_OTHERS)
182 MediacontentManager::readCommonDataFromMediaInfo(info, static_cast<MediacontentMedia*>(user_data));
189 static void content_notification_cb(
190 media_content_error_e error,
192 media_content_db_update_item_type_e update_item,
193 media_content_db_update_type_e update_type,
194 media_content_type_e media_type,
201 ContentListener *listener = static_cast<ContentListener*>(user_data);
203 if( error == MEDIA_CONTENT_ERROR_NONE)
206 if( update_item == MEDIA_ITEM_FILE)
208 string condition = "MEDIA_ID=\"";
212 MediacontentMedia *p_content;
213 if(update_type == MEDIA_CONTENT_INSERT)
215 filter_h filter = NULL;
216 if ( MEDIA_CONTENT_ERROR_NONE == media_filter_create(&filter))
218 media_filter_set_condition(filter, condition.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
220 if(media_type == MEDIA_CONTENT_TYPE_IMAGE)
222 p_content = new MediacontentImage();
224 else if(media_type == MEDIA_CONTENT_TYPE_VIDEO)
226 p_content = new MediacontentVideo();
228 else if(media_type == MEDIA_CONTENT_TYPE_SOUND || media_type == MEDIA_CONTENT_TYPE_MUSIC)
230 p_content = new MediacontentAudio();
234 p_content = new MediacontentMedia();
237 if( MEDIA_CONTENT_ERROR_NONE == media_info_foreach_media_from_db(filter,mediaItemCallback,(void*)p_content))
239 MediacontentMediaPtr result(p_content);
240 listener->oncontentadded(result);
242 media_filter_destroy(filter);
245 else if(update_type == MEDIA_CONTENT_UPDATE)
248 filter_h filter = NULL;
249 if ( MEDIA_CONTENT_ERROR_NONE == media_filter_create(&filter))
251 media_filter_set_condition(filter, condition.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
253 if(media_type == MEDIA_CONTENT_TYPE_IMAGE)
255 p_content = new MediacontentImage();
257 else if(media_type == MEDIA_CONTENT_TYPE_VIDEO)
259 p_content = new MediacontentVideo();
261 else if(media_type == MEDIA_CONTENT_TYPE_SOUND || media_type == MEDIA_CONTENT_TYPE_MUSIC)
263 p_content = new MediacontentAudio();
267 p_content = new MediacontentMedia();
270 if( MEDIA_CONTENT_ERROR_NONE == media_info_foreach_media_from_db(filter,mediaItemCallback,(void*)p_content))
272 MediacontentMediaPtr result(p_content);
273 listener->oncontentupdated(result);
275 media_filter_destroy(filter);
279 else if(update_type == MEDIA_CONTENT_DELETE)
281 listener->oncontentremoved(uuid);
285 else if( error == MEDIA_CONTENT_ERROR_OUT_OF_MEMORY)
287 err_msg = "scanning is failed by out of memory";
289 else if( error == MEDIA_CONTENT_ERROR_INVALID_OPERATION)
291 err_msg = "scanning is failed by invalid operation";
293 else if( error == MEDIA_CONTENT_ERROR_DB_FAILED)
295 err_msg = "scanning is failed because db operation is failed";
297 else if( error == MEDIA_CONTENT_ERROR_DB_BUSY)
299 err_msg = "scanning is failed because db operation is failed";
303 err_msg = "scanning is failed by unknown reason";
306 LogDebug("ContentListener is called:" + err_msg );
310 bool IMediacontentManager::setListener( void* user_data)
312 LogDebug("ContentManager::called setListener");
315 if(media_content_set_db_updated_cb(content_notification_cb,user_data) == MEDIA_CONTENT_ERROR_NONE)
323 bool IMediacontentManager::unsetListener()
325 LogDebug("ContentManager::called unsetListener");
328 if(media_content_unset_db_updated_cb() == MEDIA_CONTENT_ERROR_NONE)
336 bool IMediacontentManager::updateMetadata(MediacontentImagePtr &ptr)
338 LogDebug("ContentManager::updateMetadata called");
339 string orientation = ptr->getImageOrientation();
340 unsigned char orientation_value;
341 LogDebug("ContentManager::updateMetadata called1");
342 if ( orientation.compare("NORMAL")==0)
344 orientation_value= 1; //MEDIA_CONTENT_ORIENTATION_NORMAL
346 else if (orientation.compare("FLIP_HORIZONTAL")==0)
348 orientation_value = 2; //MEDIA_CONTENT_ORIENTATION_HFLIP;
350 else if (orientation.compare("ROTATE_180")==0)
352 orientation_value = 3; //MEDIA_CONTENT_ORIENTATION_ROT_180;
354 else if (orientation.compare("FLIP_VERTICAL")==0)
356 orientation_value = 4; //MEDIA_CONTENT_ORIENTATION_VFLIP;
358 else if (orientation.compare("TRANSPOSE")==0)
360 orientation_value = 5; //MEDIA_CONTENT_ORIENTATION_TRANSPOSE;
362 else if (orientation.compare("ROTATE_90")==0)
364 orientation_value = 6; //MEDIA_CONTENT_ORIENTATION_ROT_90;
366 else if (orientation.compare("TRANSVERSE")==0)
368 orientation_value = 7; //MEDIA_CONTENT_ORIENTATION_TRANSVERSE;
370 else if (orientation.compare("ROTATE_270")==0)
372 orientation_value = 8; //MEDIA_CONTENT_ORIENTATION_ROT_270;
376 LogDebug("wrong value.");
379 LogDebug("ContentManager::updateMetadata called2");
380 string real_path = ContentUtility::convertUriToPath(ptr->getFilePath());
381 ContentExif exif(real_path.c_str());
382 int res = exif.LodExif();
385 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "Invalid image");
390 ThrowMsg(WrtDeviceApis::Commons::UnsupportedException, "Not supported image type");
394 exif.SetExifChar(EXIF_TAG_ORIENTATION,orientation_value);