Update change log and spec for wrt-plugins-tizen_0.4.11
[framework/web/wrt-plugins-tizen.git] / src / Content / IContentManager.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
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"
30
31
32 namespace DeviceAPI {
33 namespace Content {
34
35
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)
41
42 {
43 }
44
45 IMediacontentManager::~IMediacontentManager()
46 {
47 }
48
49 void IMediacontentManager::findFolder(IEventFindFolderPtr &ptr)
50 {
51         LogDebug("IMediacontentManager::called findFolders");
52     WrtDeviceApis::Commons::EventRequestReceiver<IEventFindFolder>::PostRequest(ptr);
53 }
54
55 void IMediacontentManager::updateMedia(IEventUpdateMediaPtr &ptr)
56 {
57         LogDebug("IMediacontentManager::called updateMedia");
58     WrtDeviceApis::Commons::EventRequestReceiver<IEventUpdateMedia>::PostRequest(ptr);
59 }
60
61 void IMediacontentManager::browseFolder(IEventBrowseFolderPtr &ptr)
62 {
63         LogDebug("IMediacontentManager::called IEventBrowseFolder");
64     WrtDeviceApis::Commons::EventRequestReceiver<IEventBrowseFolder>::PostRequest(ptr);
65 }
66
67 void IMediacontentManager::updateMediaItems(IEventUpdateMediaItemsPtr &ptr)
68 {
69         LogDebug("IMediacontentManager::called IEventBrowseFolder");
70     WrtDeviceApis::Commons::EventRequestReceiver<IEventUpdateMediaItems>::PostRequest(ptr);
71 }
72
73
74 struct scanCallbackData
75 {
76     std::string path;
77         int result;
78     scanCompletedCallback callback;
79     void *user_data;
80 };
81
82 static gboolean _scan_file_completed_cb(void *user_data)
83 {
84
85         LogDebug("called _scan_file_completed_cb:");
86
87         scanCallbackData *data = static_cast<scanCallbackData*>(user_data);
88
89         if(data != NULL)
90         {
91                 string path = data->path;
92                 void* _user_data = data->user_data;
93                 scanCompletedCallback _callback = data->callback;
94
95                 std::string err_msg;
96
97                 if( data->result == MEDIA_CONTENT_ERROR_NONE)
98                 {
99                         err_msg = "";
100                 }
101                 else if( data->result == MEDIA_CONTENT_ERROR_OUT_OF_MEMORY)
102                 {
103                         err_msg = "scanning is failed by out of memory";
104                 }
105                 else if( data->result == MEDIA_CONTENT_ERROR_INVALID_OPERATION)
106                 {
107                         err_msg = "scanning is failed by invalid operation";
108                 }
109                 else if( data->result == MEDIA_CONTENT_ERROR_DB_FAILED)
110                 {
111                         err_msg = "scanning is failed because db operation is failed";
112                 }
113                 else if( data->result == MEDIA_CONTENT_ERROR_DB_BUSY)
114                 {
115                         err_msg = "scanning is failed because db operation is failed";
116                 }
117                 else
118                 {
119                         err_msg = "scanning is failed by unknown reason";
120                 }
121                 _callback(err_msg, path, _user_data);
122
123                 delete data;
124         }
125         return false;
126 }
127
128
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);
135 }
136
137 bool IMediacontentManager::scanFile(scanCompletedCallback callback, std::string path, void* user_data)
138 {
139         LogDebug("ContentManager::called scan");
140         bool ret = false;
141         if( !path.empty() )
142         {
143                 LogDebug("ContentManager::path:" << path);
144
145                 scanCallbackData *data = new scanCallbackData();
146                 data->path = path;
147                 data->callback = callback;
148                 data->user_data = user_data;
149
150                 ecore_thread_run( _scan_file_thread, NULL, NULL, static_cast<void*>(data));
151                 ret = true;
152
153         }
154         else
155         {
156                 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "URI is not available");
157         }
158         return ret;
159 }
160
161 static bool mediaItemCallback(media_info_h info, void* user_data)
162 {
163         media_content_type_e type;
164         LogDebug("mediaItemCallback is called");
165
166         if ( MEDIA_CONTENT_ERROR_NONE == media_info_get_media_type( info, &type) )
167         {
168                 if ( type == MEDIA_CONTENT_TYPE_IMAGE)
169                 {
170                         MediacontentManager::readImageFromMediaInfo(info, static_cast<MediacontentImage*>(user_data));
171                 }
172                 else if ( type == MEDIA_CONTENT_TYPE_VIDEO)
173                 {
174                         MediacontentManager::readVideoFromMediaInfo(info, static_cast<MediacontentVideo*>(user_data));
175                 }
176                 else if ( type == MEDIA_CONTENT_TYPE_MUSIC || type == MEDIA_CONTENT_TYPE_SOUND)
177                 {
178                         MediacontentManager::readMusicFromMediaInfo(info, static_cast<MediacontentAudio*>(user_data));
179                 }
180                 else if( type == MEDIA_CONTENT_TYPE_OTHERS)
181                 {
182                         MediacontentManager::readCommonDataFromMediaInfo(info, static_cast<MediacontentMedia*>(user_data));
183                 }
184
185         }
186         return false;
187 }
188
189 static void content_notification_cb(
190                                                                         media_content_error_e error,
191                                                                         int pid,
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,
195                                                                         char *uuid,
196                                                                         char *path,
197                                                                         char *mime_type,
198                                                                         void *user_data)
199 {
200
201         ContentListener *listener = static_cast<ContentListener*>(user_data);
202         std::string err_msg;
203         if( error == MEDIA_CONTENT_ERROR_NONE)
204         {
205                 err_msg = "";
206                 if( update_item == MEDIA_ITEM_FILE)
207                 {
208                         string condition = "MEDIA_ID=\"";
209                         condition += uuid;
210                         condition += "\"";
211
212                         MediacontentMedia *p_content;
213                         if(update_type == MEDIA_CONTENT_INSERT)
214                         {
215                                 filter_h filter = NULL;
216                                 if ( MEDIA_CONTENT_ERROR_NONE == media_filter_create(&filter))
217                                 {
218                                         media_filter_set_condition(filter, condition.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
219
220                                         if(media_type == MEDIA_CONTENT_TYPE_IMAGE)
221                                         {
222                                                 p_content = new MediacontentImage();
223                                         }
224                                         else if(media_type == MEDIA_CONTENT_TYPE_VIDEO)
225                                         {
226                                                 p_content = new MediacontentVideo();
227                                         }
228                                         else if(media_type == MEDIA_CONTENT_TYPE_SOUND || media_type == MEDIA_CONTENT_TYPE_MUSIC)
229                                         {
230                                                 p_content = new MediacontentAudio();
231                                         }
232                                         else
233                                         {
234                                                 p_content = new MediacontentMedia();
235                                         }
236
237                                         if( MEDIA_CONTENT_ERROR_NONE == media_info_foreach_media_from_db(filter,mediaItemCallback,(void*)p_content))
238                                         {
239                                                 MediacontentMediaPtr result(p_content);
240                                                 listener->oncontentadded(result);
241                                         }
242                                         media_filter_destroy(filter);
243                                 }
244                         }
245                         else if(update_type == MEDIA_CONTENT_UPDATE)
246                         {
247
248                                 filter_h filter = NULL;
249                                 if ( MEDIA_CONTENT_ERROR_NONE == media_filter_create(&filter))
250                                 {
251                                         media_filter_set_condition(filter, condition.c_str(), MEDIA_CONTENT_COLLATE_DEFAULT);
252
253                                         if(media_type == MEDIA_CONTENT_TYPE_IMAGE)
254                                         {
255                                                 p_content = new MediacontentImage();
256                                         }
257                                         else if(media_type == MEDIA_CONTENT_TYPE_VIDEO)
258                                         {
259                                                 p_content = new MediacontentVideo();
260                                         }
261                                         else if(media_type == MEDIA_CONTENT_TYPE_SOUND || media_type == MEDIA_CONTENT_TYPE_MUSIC)
262                                         {
263                                                 p_content = new MediacontentAudio();
264                                         }
265                                         else
266                                         {
267                                                 p_content = new MediacontentMedia();
268                                         }
269
270                                         if( MEDIA_CONTENT_ERROR_NONE == media_info_foreach_media_from_db(filter,mediaItemCallback,(void*)p_content))
271                                         {
272                                                 MediacontentMediaPtr result(p_content);
273                                                 listener->oncontentupdated(result);
274                                         }
275                                         media_filter_destroy(filter);
276                                 }
277
278                         }
279                         else if(update_type == MEDIA_CONTENT_DELETE)
280                         {
281                                 listener->oncontentremoved(uuid);
282                         }
283                 }
284         }
285         else if( error == MEDIA_CONTENT_ERROR_OUT_OF_MEMORY)
286         {
287                 err_msg = "scanning is failed by out of memory";
288         }
289         else if( error == MEDIA_CONTENT_ERROR_INVALID_OPERATION)
290         {
291                 err_msg = "scanning is failed by invalid operation";
292         }
293         else if( error == MEDIA_CONTENT_ERROR_DB_FAILED)
294         {
295                 err_msg = "scanning is failed because db operation is failed";
296         }
297         else if( error == MEDIA_CONTENT_ERROR_DB_BUSY)
298         {
299                 err_msg = "scanning is failed because db operation is failed";
300         }
301         else
302         {
303                 err_msg = "scanning is failed by unknown reason";
304         }
305
306         LogDebug("ContentListener is called:" + err_msg );
307
308 }
309
310 bool IMediacontentManager::setListener( void* user_data)
311 {
312         LogDebug("ContentManager::called setListener");
313         bool ret = false;
314
315         if(media_content_set_db_updated_cb(content_notification_cb,user_data) == MEDIA_CONTENT_ERROR_NONE)
316         {
317                 ret = true;
318         }
319
320         return ret;
321 }
322
323 bool IMediacontentManager::unsetListener()
324 {
325         LogDebug("ContentManager::called unsetListener");
326         bool ret = false;
327
328         if(media_content_unset_db_updated_cb() == MEDIA_CONTENT_ERROR_NONE)
329         {
330                 ret = true;
331         }
332
333         return ret;
334 }
335
336 bool IMediacontentManager::updateMetadata(MediacontentImagePtr &ptr)
337 {
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)
343         {
344                 orientation_value= 1; //MEDIA_CONTENT_ORIENTATION_NORMAL
345         }
346         else if (orientation.compare("FLIP_HORIZONTAL")==0)
347         {
348                 orientation_value = 2; //MEDIA_CONTENT_ORIENTATION_HFLIP;
349         }
350         else if (orientation.compare("ROTATE_180")==0)
351         {
352                 orientation_value = 3; //MEDIA_CONTENT_ORIENTATION_ROT_180;
353         }
354         else if (orientation.compare("FLIP_VERTICAL")==0)
355         {
356                 orientation_value = 4; //MEDIA_CONTENT_ORIENTATION_VFLIP;
357         }
358         else if (orientation.compare("TRANSPOSE")==0)
359         {
360                 orientation_value = 5; //MEDIA_CONTENT_ORIENTATION_TRANSPOSE;
361         }
362         else if (orientation.compare("ROTATE_90")==0)
363         {
364                 orientation_value = 6; //MEDIA_CONTENT_ORIENTATION_ROT_90;
365         }
366         else if (orientation.compare("TRANSVERSE")==0)
367         {
368                 orientation_value = 7; //MEDIA_CONTENT_ORIENTATION_TRANSVERSE;
369         }
370         else if (orientation.compare("ROTATE_270")==0)
371         {
372                 orientation_value = 8; //MEDIA_CONTENT_ORIENTATION_ROT_270;
373         }
374         else
375         {
376                 LogDebug("wrong value.");
377                 return false;
378         }
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();
383         if( res == 0)
384         {
385                 ThrowMsg(WrtDeviceApis::Commons::InvalidArgumentException, "Invalid image");
386                 return false;
387         }
388         else if(res < 0)
389         {
390                 ThrowMsg(WrtDeviceApis::Commons::UnsupportedException, "Not supported image type");
391                 return false;
392
393         }
394         exif.SetExifChar(EXIF_TAG_ORIENTATION,orientation_value);
395
396
397         return true;
398
399 }
400
401 }
402 }