[content] Change secure log
[platform/framework/native/content.git] / src / FCnt_ContentManagerUtilImpl.cpp
1 //
2 // Open Service Platform
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  * @file                FCnt_ContentManagerUtilImpl.cpp
19  * @brief               This is the implementation file for the %_ContentManagerUtilImpl class.
20  *
21  * This file contains implementation of the %_ContentManagerUtilImpl class.
22  */
23
24 #include <stdlib.h>
25 #include <mime_type.h>
26 #include <FBaseSysLog.h>
27 #include <FBaseByteBuffer.h>
28 #include <FIoDirectory.h>
29 #include <FAppApp.h>
30 #include <FSysEnvironment.h>
31 #include <FMediaImage.h>
32 #include <FMediaImageBuffer.h>
33 #include <FMediaImageUtil.h>
34 #include <FCntImageMetadata.h>
35 #include <FCntAudioMetadata.h>
36 #include <FCntVideoMetadata.h>
37 #include <FCnt_ContentManagerUtilImpl.h>
38 #include <FCnt_AudioMetadataImpl.h>
39 #include <FCnt_VideoMetadataImpl.h>
40 #include <FCnt_ImageMetadataImpl.h>
41 #include <FBase_StringConverter.h>
42 #include <FIo_FileImpl.h>
43 #include <FGrp_BitmapImpl.h>
44 #include <FMedia_ImageDecoder.h>
45 #include <FMedia_ImageImpl.h>
46 #include <FApp_AppInfo.h>
47
48 using namespace Tizen::Base;
49 using namespace Tizen::Io;
50 using namespace Tizen::Media;
51 using namespace Tizen::Graphics;
52 using namespace Tizen::App;
53 using namespace Tizen::System;
54 using namespace std;
55
56 namespace Tizen { namespace Content
57 {
58 // Types of content, format supported and default values
59 static const int IMAGE_BUFF_LENGTH = 100;
60 static const int THUMBNAIL_IMAGE_WIDTH = 80;
61 static const int THUMBNAIL_IMAGE_HEIGHT = 60;
62 static const int MINUTES = 60;
63 static const int SECONDS = 3600;
64
65 //
66 // E_SUCCESS
67 // E_INVALID_ARG
68 // E_OUT_OF_MEMORY
69 //
70 ImageMetadata*
71 _ContentManagerUtilImpl::GetImageMetaN(const String& contentPath, bool internal)
72 {
73         ClearLastResult();
74
75         if (!internal)
76         {
77                 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
78                                 "[E_INVALID_ARG] The path is not compatible.");
79         }
80         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
81                         "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
82
83         // create object here as it needs to be passed to client in any case to make sure Get APIs do not crash
84         unique_ptr<ImageMetadata> pImageMetadata(new (nothrow) ImageMetadata());
85         SysTryReturn(NID_CNT, pImageMetadata != null, null, E_OUT_OF_MEMORY,
86                         "[E_OUT_OF_MEMORY] pImageMetadata is null.");
87
88         _ImageMetadataImpl* pImageMetaImpl = _ImageMetadataImpl::GetInstance(*(pImageMetadata.get()));
89         SysTryReturn(NID_CNT, pImageMetaImpl != null, null, E_OUT_OF_MEMORY,
90                         "[E_OUT_OF_MEMORY] pImageMetaImpl is null.");
91
92         ImageMeta* pMetadata = pImageMetaImpl->GetImageMetadata();
93         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
94                         "[E_INVALID_ARG] pMetadata is null.");
95
96         //assign by default here and overwrite below if width and height presents in EXIF data.
97         ImageFormat imgType = IMG_FORMAT_NONE;
98         Dimension dim(0,0);
99
100         result r = _ImageImpl::GetImageInfo(contentPath, imgType, dim);
101         SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG,
102                         "[E_INVALID_ARG] GetImageInfo failed.");
103
104         pMetadata->width = dim.width;
105         pMetadata->height = dim.height;
106         pMetadata->contentPath = contentPath;
107
108         if (imgType == IMG_FORMAT_JPG)
109         {
110                 unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
111                 SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
112                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
113
114                 unique_ptr<ExifData, ExifDataDeleter> pExifdata(exif_data_new_from_file(pFileName.get()));
115                 if (pExifdata != null)
116                 {
117                         ExifTag tag;
118                         ExifByteOrder byteOrder;
119                         ExifEntry** pEntries = null;
120                         const char* pData = null;
121                         char buf[IMAGE_BUFF_LENGTH] = {0, };
122                         char mmBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store minutes value of GPS data
123                         char ssBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store seconds value of GPS data
124                         ExifContent* pExifcont[EXIF_IFD_COUNT];
125                         int index = 0;
126                         char latitudeRef = 0; // to store latitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
127                         char longitudeRef = 0; // to store longitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
128                         unsigned int entryCount = 0;
129
130                         for (int i = 0; i < EXIF_IFD_COUNT; i++)
131                         {
132                                 pExifcont[i] = pExifdata->ifd[i];
133                                 entryCount = pExifcont[i]->count;
134                                 pEntries = pExifcont[i]->entries;
135                                 for (unsigned int j = 0; j < entryCount; j++)
136                                 {
137                                         tag = pEntries[j]->tag;
138                                         pData = exif_entry_get_value(pEntries[j], buf, sizeof(buf));
139                                         SysTryReturn(NID_CNT, pData != null, pImageMetadata.release(), E_INVALID_ARG,
140                                                         "[E_INVALID_ARG] exif_entry_get_value failed.");
141
142                                         if (tag == EXIF_TAG_PIXEL_X_DIMENSION)
143                                         {
144                                                 pMetadata->width = atoi(buf);
145                                         }
146                                         else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION)
147                                         {
148                                                 pMetadata->height = atoi(buf);
149                                         }
150                                         else if (tag == EXIF_TAG_MAKE)
151                                         {
152                                                 pMetadata->pManufacturer = new (nothrow) String(buf);
153                                                 SysTryReturn(NID_CNT, pMetadata->pManufacturer != null, null, E_OUT_OF_MEMORY,
154                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
155                                         }
156                                         else if (tag == EXIF_TAG_MODEL)
157                                         {
158                                                 pMetadata->pModel = new (nothrow) String(buf);
159                                                 SysTryReturn(NID_CNT, pMetadata->pModel != null, null, E_OUT_OF_MEMORY,
160                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
161                                         }
162                                         else if (tag == EXIF_TAG_DATE_TIME)
163                                         {
164                                                 pMetadata->pDateTime = new (nothrow) String(buf);
165                                                 SysTryReturn(NID_CNT, pMetadata->pDateTime != null, null, E_OUT_OF_MEMORY,
166                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
167                                         }
168                                         else if (tag == EXIF_TAG_ORIENTATION)
169                                         {
170                                                 //get the byte order(little endian or big endian) before extracting orientation type
171                                                 byteOrder = exif_data_get_byte_order(pEntries[j]->parent->parent);
172                                                 pMetadata->orientation = static_cast<ImageOrientationType>(exif_get_short(pEntries[j]->data, byteOrder));
173                                         }
174                                         else if (tag == EXIF_TAG_SOFTWARE)
175                                         {
176                                                 pMetadata->pSoftware = new (nothrow) String(buf);
177                                                 SysTryReturn(NID_CNT, pMetadata->pSoftware != null, null, E_OUT_OF_MEMORY,
178                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
179                                         }
180                                         else if (tag == EXIF_TAG_GPS_LATITUDE_REF)
181                                         {
182                                                 latitudeRef = buf[0]; // GPS Latitude reference value will be 'N'(NORTH) or 'S'(SOUTH)
183                                         }
184                                         else if (tag == EXIF_TAG_GPS_LATITUDE)
185                                         {
186                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
187                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
188                                                 {
189                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
190                                                 }
191                                                 index = 0; //re-assign index value as this is new buffer
192                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
193                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
194                                                 {
195                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
196                                                 }
197
198                                                 char *pLocal;
199                                                 std::unique_ptr<char> pCurrentLocal(null);
200                                                 pLocal = setlocale (LC_ALL, 0); // Get the name of the current locale.
201                                                 if( pLocal == null )
202                                                 {
203                                                         SysLog(NID_CNT, "setlocale failed. (get current locale)");
204                                                         continue;
205                                                 }
206                                                 pCurrentLocal.reset(strdup (pLocal));
207
208                                                 pLocal = setlocale(LC_ALL, "C");
209                                                 if( pLocal == null )
210                                                 {
211                                                         SysLog(NID_CNT, "setlocale failed. (set POSIX C locale)");
212                                                         continue;
213                                                 }
214
215                                                 double ddVal = atof(buf); // degree value
216                                                 double mmVal = atof(mmBuff); // minutesvalue
217                                                 double ssVal = atof(ssBuff); // seconds value
218
219                                                 pLocal = setlocale (LC_ALL, pCurrentLocal.get()); // restore the locale.
220                                                 if( pLocal == null )
221                                                 {
222                                                         SysLog(NID_CNT, "setlocale failed. (set current locale)");
223                                                         continue;
224                                                 }
225
226                                                 pMetadata->latitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
227
228                                                 // if latitude designation is Southern (SOUTH) then latitude degree will be negative DD
229                                                 if (latitudeRef == 'S')
230                                                 {
231                                                         pMetadata->latitude = (pMetadata->latitude * (double)(-1));
232                                                 }
233                                         }
234                                         else if (tag == EXIF_TAG_GPS_LONGITUDE_REF)
235                                         {
236                                                 longitudeRef = buf[0]; // GPS Longitude reference value will be 'W'(WEST) or 'E'(EAST)
237                                         }
238                                         else if (tag == EXIF_TAG_GPS_LONGITUDE)
239                                         {
240                                                 index = 0; //re-assign index value as this is new buffer
241                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
242                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
243                                                 {
244                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
245                                                 }
246                                                 index = 0; //re-assign index value as this is new buffer
247                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
248                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
249                                                 {
250                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
251                                                 }
252
253                                                 char *pLocal;
254                                                 std::unique_ptr<char> pCurrentLocal(null);
255                                                 pLocal = setlocale (LC_ALL, 0); // Get the name of the current locale.
256                                                 if( pLocal == null )
257                                                 {
258                                                         SysLog(NID_CNT, "setlocale failed. (get current locale)");
259                                                         continue;
260                                                 }
261                                                 pCurrentLocal.reset(strdup (pLocal));
262
263                                                 pLocal = setlocale(LC_ALL, "C");
264                                                 if( pLocal == null )
265                                                 {
266                                                         SysLog(NID_CNT, "setlocale failed. (set POSIX C locale)");
267                                                         continue;
268                                                 }
269
270                                                 double ddVal = atof(buf); // degree value
271                                                 double mmVal = atof(mmBuff); // minutesvalue
272                                                 double ssVal = atof(ssBuff); // seconds value
273
274                                                 pLocal = setlocale (LC_ALL, pCurrentLocal.get()); // restore the locale.
275                                                 if( pLocal == null )
276                                                 {
277                                                         SysLog(NID_CNT, "setlocale failed. (set current locale)");
278                                                         continue;
279                                                 }
280
281                                                 pMetadata->longitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
282
283                                                 // if longitude designation is Western (WEST) then longitude degree will be negative DD
284                                                 if (longitudeRef == 'W')
285                                                 {
286                                                         pMetadata->longitude = (pMetadata->longitude * (double)(-1));
287                                                 }
288                                         }
289                                         else if (tag == EXIF_TAG_WHITE_BALANCE)
290                                         {
291                                                 pMetadata->pWhiteBalance = new (nothrow) String(buf);
292                                                 SysTryReturn(NID_CNT, pMetadata->pWhiteBalance != null, null, E_OUT_OF_MEMORY,
293                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
294                                         }
295                                 }
296                         }
297                 }
298         }
299
300         return pImageMetadata.release();
301 }
302
303 void
304 _ContentManagerUtilImpl::ParseBuffer(char* pBuffer, int& count)
305 {
306         if ((*pBuffer != ',') && (*pBuffer != '\0')) // parse the buffer till ',' or '\0' and return the index
307         {
308                 ParseBuffer(++pBuffer, ++count);
309         }
310 }
311
312 //
313 // E_SUCCESS
314 // E_INVALID_ARG
315 // E_OUT_OF_MEMORY
316 //
317 AudioMetadata*
318 _ContentManagerUtilImpl::GetAudioMetaN(const String& contentPath)
319 {
320         ClearLastResult();
321
322         SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
323                         "[E_INVALID_ARG] The path is not compatible.");
324         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
325                         "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
326
327         // create here to make sure that get apis will not crash though the below API calls fails in case of invalid file.
328         unique_ptr<AudioMetadata> pAudioMetadata(new (nothrow) AudioMetadata());
329         SysTryReturn(NID_CNT, pAudioMetadata != null, null, E_OUT_OF_MEMORY,
330                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
331
332         _AudioMetadataImpl* pAudioMetaImpl = _AudioMetadataImpl::GetInstance(*(pAudioMetadata.get()));
333         SysTryReturn(NID_CNT, pAudioMetaImpl != null, null, E_OUT_OF_MEMORY,
334                         "[E_OUT_OF_MEMORY] pAudioMetaImpl is null.");
335
336         AudioMeta* pMetadata = pAudioMetaImpl->GetAudioMetadata();
337         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
338                         "[E_INVALID_ARG] pMetadata is null.");
339
340         pMetadata->contentPath = contentPath;
341
342         // Create the metadata extractor handle
343         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
344         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
345                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
346
347         int retVal = metadata_extractor_create(pExtractor.get());
348         result r = ErrorMapToRetVal(retVal);
349         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
350                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
351
352         // Set file path of content to extract the metadata
353         unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
354         SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
355                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
356
357         retVal = metadata_extractor_set_path(*(pExtractor.get()), pFileName.get());
358         r = ErrorMapToRetVal(retVal);
359         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
360                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
361
362         // Get all relavent audio metadata by passing relavent attirbutes
363         char* __pAudioMeta = null;
364         unique_ptr<char, CharDeleter> pAudioMeta(null);
365
366         // bitrate
367         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pAudioMeta);
368         if (__pAudioMeta != null)
369         {
370                 pAudioMeta.reset(__pAudioMeta);
371                 pMetadata->bitrate = atoi(pAudioMeta.get());
372         }
373         else
374         {
375                 r = ErrorMapToRetVal(retVal);
376                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
377                                 "[%s] metadata_extractor_get_metadata(bitrate) failed.", GetErrorMessage(r));
378         }
379
380         // channelcount
381         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_CHANNELS, &__pAudioMeta);
382         if (__pAudioMeta != null)
383         {
384                 pAudioMeta.reset(__pAudioMeta);
385                 pMetadata->channelCount = atoi(pAudioMeta.get());
386         }
387         else
388         {
389                 r = ErrorMapToRetVal(retVal);
390                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
391                                 "[%s] metadata_extractor_get_metadata(channels) failed.", GetErrorMessage(r));
392         }
393
394         // duration
395         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pAudioMeta);
396         if (__pAudioMeta != null)
397         {
398                 pAudioMeta.reset(__pAudioMeta);
399                 pMetadata->duration = atoi(pAudioMeta.get());
400         }
401         else
402         {
403                 r = ErrorMapToRetVal(retVal);
404                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
405                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
406         }
407
408         // frequency
409         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_SAMPLERATE, &__pAudioMeta);
410         if (__pAudioMeta != null)
411         {
412                 pAudioMeta.reset(__pAudioMeta);
413                 pMetadata->frequency = atoi(pAudioMeta.get());
414         }
415         else
416         {
417                 r = ErrorMapToRetVal(retVal);
418                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
419                                 "[%s] metadata_extractor_get_metadata(frequency) failed.", GetErrorMessage(r));
420         }
421
422         // albumname
423         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ALBUM, &__pAudioMeta);
424         if (__pAudioMeta != null)
425         {
426                 pAudioMeta.reset(__pAudioMeta);
427                 pMetadata->pAlbumName = new (nothrow) String(pAudioMeta.get());
428                 SysTryReturn(NID_CNT, pMetadata->pAlbumName != null, null, E_OUT_OF_MEMORY,
429                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
430         }
431         else
432         {
433                 r = ErrorMapToRetVal(retVal);
434                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
435                                 "[%s] metadata_extractor_get_metadata(album name) failed.", GetErrorMessage(r));
436         }
437
438         // artist
439         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ARTIST, &__pAudioMeta);
440         if (pAudioMeta.get() != null)
441         {
442                 pAudioMeta.reset(__pAudioMeta);
443                 pMetadata->pArtist = new (nothrow) String(pAudioMeta.get());
444                 SysTryReturn(NID_CNT, pMetadata->pArtist != null, null, E_OUT_OF_MEMORY,
445                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
446         }
447         else
448         {
449                 r = ErrorMapToRetVal(retVal);
450                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
451                                 "[%s] metadata_extractor_get_metadata(artist) failed.", GetErrorMessage(r));
452         }
453
454         // copyright
455         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COPYRIGHT, &__pAudioMeta);
456         if (__pAudioMeta != null)
457         {
458                 pAudioMeta.reset(__pAudioMeta);
459                 pMetadata->pCopyright = new (nothrow) String(pAudioMeta.get());
460                 SysTryReturn(NID_CNT, pMetadata->pCopyright != null, null, E_OUT_OF_MEMORY,
461                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
462         }
463         else
464         {
465                 r = ErrorMapToRetVal(retVal);
466                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
467                                 "[%s] metadata_extractor_get_metadata(copyright) failed.", GetErrorMessage(r));
468         }
469
470         // genre
471         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pAudioMeta);
472         if (__pAudioMeta != null)
473         {
474                 pAudioMeta.reset(__pAudioMeta);
475                 pMetadata->pGenre = new (nothrow) String(pAudioMeta.get());
476                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
477                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
478         }
479         else
480         {
481                 r = ErrorMapToRetVal(retVal);
482                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
483                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
484         }
485
486         // title
487         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TITLE, &__pAudioMeta);
488         if (__pAudioMeta != null)
489         {
490                 pAudioMeta.reset(__pAudioMeta);
491                 pMetadata->pTitle = new (nothrow) String(pAudioMeta.get());
492                 SysTryReturn(NID_CNT, pMetadata->pTitle != null, null, E_OUT_OF_MEMORY,
493                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
494         }
495         else
496         {
497                 r = ErrorMapToRetVal(retVal);
498                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
499                                 "[%s] metadata_extractor_get_metadata(title) failed.", GetErrorMessage(r));
500         }
501
502         // comment
503         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pAudioMeta);
504         if (__pAudioMeta != null)
505         {
506                 pAudioMeta.reset(__pAudioMeta);
507                 pMetadata->pComment = new (nothrow) String(pAudioMeta.get());
508                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
509                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
510         }
511         else
512         {
513                 r = ErrorMapToRetVal(retVal);
514                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
515                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
516         }
517
518         // description
519         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pAudioMeta);
520         if (__pAudioMeta != null)
521         {
522                 pAudioMeta.reset(__pAudioMeta);
523                 pMetadata->pDescription = new (nothrow) String(pAudioMeta.get());
524                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
525                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
526         }
527         else
528         {
529                 r = ErrorMapToRetVal(retVal);
530                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
531                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
532         }
533
534         // recording date
535         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_RECDATE, &__pAudioMeta);
536         if (__pAudioMeta != null)
537         {
538                 pAudioMeta.reset(__pAudioMeta);
539                 pMetadata->pRecordingDate = new (nothrow) String(pAudioMeta.get());
540                 SysTryReturn(NID_CNT, pMetadata->pRecordingDate != null, null, E_OUT_OF_MEMORY,
541                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
542         }
543         else
544         {
545                 r = ErrorMapToRetVal(retVal);
546                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
547                                 "[%s] metadata_extractor_get_metadata(recording date) failed.", GetErrorMessage(r));
548         }
549
550         // author
551         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUTHOR, &__pAudioMeta);
552         if (__pAudioMeta != null)
553         {
554                 pAudioMeta.reset(__pAudioMeta);
555                 pMetadata->pComposer = new (nothrow) String(pAudioMeta.get());
556                 SysTryReturn(NID_CNT, pMetadata->pComposer != null, null, E_OUT_OF_MEMORY,
557                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
558         }
559         else
560         {
561                 r = ErrorMapToRetVal(retVal);
562                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
563                                 "[%s] metadata_extractor_get_metadata(author) failed.", GetErrorMessage(r));
564         }
565
566         // track info
567         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TRACK_NUM, &__pAudioMeta);
568         if (__pAudioMeta != null)
569         {
570                 pAudioMeta.reset(__pAudioMeta);
571                 pMetadata->pTrackInfo = new (nothrow) String(pAudioMeta.get());
572                 SysTryReturn(NID_CNT, pMetadata->pTrackInfo != null, null, E_OUT_OF_MEMORY,
573                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
574
575                 // if the string contains the track info like track num/track position,
576                 // then track position will be ignored and only track num is returned
577                 // no need to parse this string, since only track number is required
578                 pMetadata->trackNum = atoi(pAudioMeta.get());
579         }
580         else
581         {
582                 r = ErrorMapToRetVal(retVal);
583                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
584                                 "[%s] metadata_extractor_get_metadata(track info) failed.", GetErrorMessage(r));
585         }
586
587         // date
588         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DATE, &__pAudioMeta);
589         if (__pAudioMeta != null)
590         {
591                 pAudioMeta.reset(__pAudioMeta);
592                 pMetadata->year = atoi(pAudioMeta.get());
593         }
594         else
595         {
596                 r = ErrorMapToRetVal(retVal);
597                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
598                                 "[%s] metadata_extractor_get_metadata(date) failed.", GetErrorMessage(r));
599         }
600
601         // artwork
602         int size = 0;
603         void* __pArtwork = null;
604         unique_ptr<void, VoidDeleter> pArtwork(null);
605
606         // Get the artwork image in media file
607         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pAudioMeta);
608
609         //Check if the albumart present and pass it to client if it is successfully processed, otherwise ignore any errors
610         //while processing albumart. This is to pass the other metadata tags to application.
611         if (__pArtwork != null)
612         {
613                 pArtwork.reset(__pArtwork);
614
615                 Image img;
616                 ImageFormat format = IMG_FORMAT_NONE;
617                 ByteBuffer buffer;
618
619                 r = buffer.Construct(size);
620                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
621                 {
622                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
623                         if (!IsFailed(r))
624                         {
625                                 r = img.Construct();
626                                 if (!IsFailed(r))
627                                 {
628                                         format = img.GetImageFormat(buffer);
629                                         pMetadata->pThumbnail = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888,
630                                                                          THUMBNAIL_IMAGE_WIDTH, THUMBNAIL_IMAGE_HEIGHT);
631                                         if (pMetadata->pThumbnail == null)
632                                         {
633                                                 // Because Thumbnail is one of the metadata, it is not exception in this function.
634                                                 SysLog(NID_CNT, "DecodeN failed.");
635                                         }
636                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
637                                         if (pMetadata->pAlbumArt == null)
638                                         {
639                                                 // Because Album Art is one of the metadata, it is not exception in this function.
640                                                 SysLog(NID_CNT, "DecodeN failed.");
641                                         }
642                                 }
643                         }
644                 }
645         }
646         else
647         {
648                 r = ErrorMapToRetVal(retVal);
649                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
650                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
651         }
652
653         return pAudioMetadata.release();
654 }
655
656 //
657 // E_SUCCESS
658 // E_INVALID_ARG
659 // E_OUT_OF_MEMORY
660 //
661 VideoMetadata*
662 _ContentManagerUtilImpl::GetVideoMetaN(const String& contentPath)
663 {
664         ClearLastResult();
665
666         SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
667                         "[E_INVALID_ARG] The path is not compatible.");
668         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
669                         "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
670
671         // need to create here to make sure that all get APIs will not crash in case of corrupted file
672         unique_ptr<VideoMetadata> pVideoMetadata(new (nothrow) VideoMetadata());
673         SysTryReturn(NID_CNT, pVideoMetadata != null, null, E_OUT_OF_MEMORY,
674                         "[E_OUT_OF_MEMORY] The memory insufficient.");
675
676         _VideoMetadataImpl* pVideoMetaImpl = _VideoMetadataImpl::GetInstance(*(pVideoMetadata.get()));
677         SysTryReturn(NID_CNT, pVideoMetaImpl != null, null, E_OUT_OF_MEMORY,
678                         "[E_OUT_OF_MEMORY] pVideoMetaImpl is null.");
679
680         VideoMeta* pMetadata = pVideoMetaImpl->GetVideoMetadata();
681         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
682                         "[E_INVALID_ARG] pMetadata is null.");
683
684         pMetadata->contentPath = contentPath;
685
686         // Create the metadata extractor handle
687         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
688         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
689                                 "[E_OUT_OF_MEMORY] The memory insufficient.");
690
691         int retVal = metadata_extractor_create(pExtractor.get());
692         result r = ErrorMapToRetVal(retVal);
693         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
694                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
695
696         // Set file path of content to extract the metadata
697         unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
698         SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
699                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
700
701         retVal = metadata_extractor_set_path(*(pExtractor.get()), pFileName.get());
702         r = ErrorMapToRetVal(retVal);
703         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
704                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
705
706         // Get all relavent video metadata by passing relavent attirbutes
707         char* __pVideoMeta = null;
708         unique_ptr<char, CharDeleter> pVideoMeta(null);
709
710         // width
711         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_WIDTH, &__pVideoMeta);
712         if (__pVideoMeta != null)
713         {
714                 pVideoMeta.reset(__pVideoMeta);
715                 pMetadata->width = atoi(pVideoMeta.get());
716         }
717         else
718         {
719                 r = ErrorMapToRetVal(retVal);
720                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
721                                 "[%s] metadata_extractor_get_metadata(width) failed.", GetErrorMessage(r));
722         }
723
724         // height
725         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_HEIGHT, &__pVideoMeta);
726         if (__pVideoMeta != null)
727         {
728                 pVideoMeta.reset(__pVideoMeta);
729                 pMetadata->height = atoi(pVideoMeta.get());
730         }
731         else
732         {
733                 r = ErrorMapToRetVal(retVal);
734                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
735                                 "[%s] metadata_extractor_get_metadata(height) failed.", GetErrorMessage(r));
736         }
737
738         // video bitrate
739         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_BITRATE, &__pVideoMeta);
740         if (__pVideoMeta != null)
741         {
742                 pVideoMeta.reset(__pVideoMeta);
743                 pMetadata->videoBitrate = atoi(pVideoMeta.get());
744         }
745         else
746         {
747                 r = ErrorMapToRetVal(retVal);
748                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
749                                 "[%s] metadata_extractor_get_metadata(video bitrate) failed.", GetErrorMessage(r));
750         }
751
752         // audio bitrate
753         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pVideoMeta);
754         if (__pVideoMeta != null)
755         {
756                 pVideoMeta.reset(__pVideoMeta);
757                 pMetadata->audioBitrate = atoi(pVideoMeta.get());
758         }
759         else
760         {
761                 r = ErrorMapToRetVal(retVal);
762                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
763                                 "[%s] metadata_extractor_get_metadata(audio bitrate) failed.", GetErrorMessage(r));
764         }
765
766         // framerate
767         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_FPS, &__pVideoMeta);
768         if (__pVideoMeta != null)
769         {
770                 pVideoMeta.reset(__pVideoMeta);
771                 pMetadata->framerate = atoi(pVideoMeta.get());
772         }
773         else
774         {
775                 r = ErrorMapToRetVal(retVal);
776                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
777                                 "[%s] metadata_extractor_get_metadata(framerate) failed.", GetErrorMessage(r));
778         }
779
780         // duration
781         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pVideoMeta);
782         if (__pVideoMeta != null)
783         {
784                 pVideoMeta.reset(__pVideoMeta);
785                 pMetadata->duration = atoi(pVideoMeta.get());
786         }
787         else
788         {
789                 r = ErrorMapToRetVal(retVal);
790                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
791                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
792         }
793
794         // genre
795         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pVideoMeta);
796         if (__pVideoMeta != null)
797         {
798                 pVideoMeta.reset(__pVideoMeta);
799                 pMetadata->pGenre = new (nothrow) String(pVideoMeta.get()); //allocate memory
800                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
801                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
802         }
803         else
804         {
805                 r = ErrorMapToRetVal(retVal);
806                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
807                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
808         }
809
810         // comment
811         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pVideoMeta);
812         if (__pVideoMeta != null)
813         {
814                 pVideoMeta.reset(__pVideoMeta);
815                 pMetadata->pComment = new (nothrow) String(pVideoMeta.get());
816                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
817                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
818         }
819         else
820         {
821                 r = ErrorMapToRetVal(retVal);
822                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
823                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
824         }
825
826         // description
827         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pVideoMeta);
828         if (__pVideoMeta != null)
829         {
830                 pVideoMeta.reset(__pVideoMeta);
831                 pMetadata->pDescription = new (nothrow) String(pVideoMeta.get());
832                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
833                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
834         }
835         else
836         {
837                 r = ErrorMapToRetVal(retVal);
838                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
839                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
840         }
841
842         // artwork
843         int size = 0;
844         void* __pArtwork = null;
845         unique_ptr<void, VoidDeleter> pArtwork(null);
846
847         // Get the artwork image in media file
848         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pVideoMeta);
849         if (__pArtwork != null)
850         {
851                 pArtwork.reset(__pArtwork);
852
853                 Image img;
854                 ImageFormat format = IMG_FORMAT_NONE;
855                 ByteBuffer buffer;
856
857                 r = buffer.Construct(size);
858                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
859                 {
860                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
861                         if (!IsFailed(r))
862                         {
863                                 r = img.Construct();
864                                 if (!IsFailed(r))
865                                 {
866                                         format = img.GetImageFormat(buffer);
867
868                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
869                                         if (pMetadata->pAlbumArt == null)
870                                         {
871                                                 // Because Album Art is one of the metadata, it is not exception in this function.
872                                                 SysLog(NID_CNT, "DecodeN failed.");
873                                         }
874                                 }
875                         }
876                 }
877         }
878         else
879         {
880                 r = ErrorMapToRetVal(retVal);
881                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
882                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
883         }
884
885         return pVideoMetadata.release();
886 }
887
888 ImageMetadata*
889 _ContentManagerUtilImpl::GetImageMetaN(const ByteBuffer& byteBuffer)
890 {
891         ClearLastResult();
892
893         int bufferLen = byteBuffer.GetRemaining();
894         SysTryReturn(NID_CNT, bufferLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The length of buffer is less than zero.");
895
896         // create object here as it needs to be passed to client in any case to make sure Get APIs do not crash
897         unique_ptr<ImageMetadata> pImageMetadata(new (nothrow) ImageMetadata());
898         SysTryReturn(NID_CNT, pImageMetadata != null, null, E_OUT_OF_MEMORY,
899                         "[E_OUT_OF_MEMORY] pImageMetadata is null.");
900
901         _ImageMetadataImpl* pImageMetaImpl = _ImageMetadataImpl::GetInstance(*(pImageMetadata.get()));
902         SysTryReturn(NID_CNT, pImageMetaImpl != null, null, E_OUT_OF_MEMORY,
903                         "[E_OUT_OF_MEMORY] pImageMetaImpl is null.");
904
905         ImageMeta* pMetadata = pImageMetaImpl->GetImageMetadata();
906         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
907                         "[E_INVALID_ARG] pMetadata is null.");
908
909         //assign by default here and overwrite below if width and height presents in EXIF data.
910         ImageFormat imgType = IMG_FORMAT_NONE;
911         int imageWidth = 0;
912         int imageHeight = 0;
913
914         result r = ImageBuffer::GetImageInfo(byteBuffer, imgType, imageWidth, imageHeight);
915         SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG,
916                         "[E_INVALID_ARG] GetImageInfo failed.");
917
918         pMetadata->width = imageWidth;
919         pMetadata->height = imageHeight;
920
921         if (imgType == IMG_FORMAT_JPG)
922         {
923                 const byte* pByte = byteBuffer.GetPointer();
924
925                 unique_ptr<ExifData, ExifDataDeleter> pExifdata(exif_data_new_from_data(pByte, bufferLen));
926                 if (pExifdata != null)
927                 {
928                         ExifTag tag;
929                         ExifByteOrder byteOrder;
930                         ExifEntry** pEntries = null;
931                         const char* pData = null;
932                         char buf[IMAGE_BUFF_LENGTH] = {0, };
933                         char mmBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store minutes value of GPS data
934                         char ssBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store seconds value of GPS data
935                         ExifContent* pExifcont[EXIF_IFD_COUNT];
936                         int index = 0;
937                         char latitudeRef = 0; // to store latitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
938                         char longitudeRef = 0; // to store longitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
939                         unsigned int entryCount = 0;
940
941                         for (int i = 0; i < EXIF_IFD_COUNT; i++)
942                         {
943                                 pExifcont[i] = pExifdata->ifd[i];
944                                 entryCount = pExifcont[i]->count;
945                                 pEntries = pExifcont[i]->entries;
946                                 for (unsigned int j = 0; j < entryCount; j++)
947                                 {
948                                         tag = pEntries[j]->tag;
949                                         pData = exif_entry_get_value(pEntries[j], buf, sizeof(buf));
950                                         SysTryReturn(NID_CNT, pData != null, pImageMetadata.release(), E_INVALID_ARG,
951                                                         "[E_INVALID_ARG] exif_entry_get_value failed.");
952
953                                         if (tag == EXIF_TAG_PIXEL_X_DIMENSION)
954                                         {
955                                                 pMetadata->width = atoi(buf);
956                                         }
957                                         else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION)
958                                         {
959                                                 pMetadata->height = atoi(buf);
960                                         }
961                                         else if (tag == EXIF_TAG_MAKE)
962                                         {
963                                                 pMetadata->pManufacturer = new (nothrow) String(buf);
964                                                 SysTryReturn(NID_CNT, pMetadata->pManufacturer != null, null, E_OUT_OF_MEMORY,
965                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
966                                         }
967                                         else if (tag == EXIF_TAG_MODEL)
968                                         {
969                                                 pMetadata->pModel = new (nothrow) String(buf);
970                                                 SysTryReturn(NID_CNT, pMetadata->pModel != null, null, E_OUT_OF_MEMORY,
971                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
972                                         }
973                                         else if (tag == EXIF_TAG_DATE_TIME)
974                                         {
975                                                 pMetadata->pDateTime = new (nothrow) String(buf);
976                                                 SysTryReturn(NID_CNT, pMetadata->pDateTime != null, null, E_OUT_OF_MEMORY,
977                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
978                                         }
979                                         else if (tag == EXIF_TAG_ORIENTATION)
980                                         {
981                                                 //get the byte order(little endian or big endian) before extracting orientation type
982                                                 byteOrder = exif_data_get_byte_order(pEntries[j]->parent->parent);
983                                                 pMetadata->orientation = static_cast<ImageOrientationType>(exif_get_short(pEntries[j]->data, byteOrder));
984                                         }
985                                         else if (tag == EXIF_TAG_SOFTWARE)
986                                         {
987                                                 pMetadata->pSoftware = new (nothrow) String(buf);
988                                                 SysTryReturn(NID_CNT, pMetadata->pSoftware != null, null, E_OUT_OF_MEMORY,
989                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
990                                         }
991                                         else if (tag == EXIF_TAG_GPS_LATITUDE_REF)
992                                         {
993                                                 latitudeRef = buf[0]; // GPS Latitude reference value will be 'N'(NORTH) or 'S'(SOUTH)
994                                         }
995                                         else if (tag == EXIF_TAG_GPS_LATITUDE)
996                                         {
997                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
998                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
999                                                 {
1000                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
1001                                                 }
1002                                                 index = 0; //re-assign index value as this is new buffer
1003                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
1004                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
1005                                                 {
1006                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
1007                                                 }
1008                                                 double ddVal = atof(buf); // degree value
1009                                                 double mmVal = atof(mmBuff); // minutesvalue
1010                                                 double ssVal = atof(ssBuff); // seconds value
1011                                                 pMetadata->latitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
1012
1013                                                 // if latitude designation is Southern (SOUTH) then latitude degree will be negative DD
1014                                                 if (latitudeRef == 'S')
1015                                                 {
1016                                                         pMetadata->latitude = (pMetadata->latitude * (double)(-1));
1017                                                 }
1018                                         }
1019                                         else if (tag == EXIF_TAG_GPS_LONGITUDE_REF)
1020                                         {
1021                                                 longitudeRef = buf[0]; // GPS Longitude reference value will be 'W'(WEST) or 'E'(EAST)
1022                                         }
1023                                         else if (tag == EXIF_TAG_GPS_LONGITUDE)
1024                                         {
1025                                                 index = 0; //re-assign index value as this is new buffer
1026                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
1027                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
1028                                                 {
1029                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
1030                                                 }
1031                                                 index = 0; //re-assign index value as this is new buffer
1032                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
1033                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
1034                                                 {
1035                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
1036                                                 }
1037                                                 double ddVal = atof(buf); // degree value
1038                                                 double mmVal = atof(mmBuff); // minutesvalue
1039                                                 double ssVal = atof(ssBuff); // seconds value
1040                                                 pMetadata->longitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
1041
1042                                                 // if longitude designation is Western (WEST) then longitude degree will be negative DD
1043                                                 if (longitudeRef == 'W')
1044                                                 {
1045                                                         pMetadata->longitude = (pMetadata->longitude * (double)(-1));
1046                                                 }
1047                                         }
1048                                         else if (tag == EXIF_TAG_WHITE_BALANCE)
1049                                         {
1050                                                 pMetadata->pWhiteBalance = new (nothrow) String(buf);
1051                                                 SysTryReturn(NID_CNT, pMetadata->pWhiteBalance != null, null, E_OUT_OF_MEMORY,
1052                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1053                                         }
1054                                 }
1055                         }
1056                 }
1057         }
1058
1059         return pImageMetadata.release();
1060 }
1061
1062 //
1063 // E_SUCCESS
1064 // E_INVALID_ARG
1065 // E_OUT_OF_MEMORY
1066 //
1067 AudioMetadata*
1068 _ContentManagerUtilImpl::GetAudioMetaN(const ByteBuffer& byteBuffer)
1069 {
1070         ClearLastResult();
1071
1072         int bufferLen = byteBuffer.GetRemaining();
1073         SysTryReturn(NID_CNT, bufferLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The length of buffer is less than zero.");
1074
1075         // create here to make sure that get apis will not crash though the below API calls fails in case of invalid file.
1076         unique_ptr<AudioMetadata> pAudioMetadata(new (nothrow) AudioMetadata());
1077         SysTryReturn(NID_CNT, pAudioMetadata != null, null, E_OUT_OF_MEMORY,
1078                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1079
1080         _AudioMetadataImpl* pAudioMetaImpl = _AudioMetadataImpl::GetInstance(*(pAudioMetadata.get()));
1081         SysTryReturn(NID_CNT, pAudioMetaImpl != null, null, E_OUT_OF_MEMORY,
1082                         "[E_OUT_OF_MEMORY] pAudioMetaImpl is null.");
1083
1084         AudioMeta* pMetadata = pAudioMetaImpl->GetAudioMetadata();
1085         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
1086                         "[E_INVALID_ARG] pMetadata is null.");
1087
1088         // Create the metadata extractor handle
1089         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
1090         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
1091                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1092
1093         int retVal = metadata_extractor_create(pExtractor.get());
1094         result r = ErrorMapToRetVal(retVal);
1095         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1096                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
1097
1098         const byte* pByte = byteBuffer.GetPointer();
1099
1100         retVal = metadata_extractor_set_buffer(*(pExtractor.get()), pByte, bufferLen);
1101         r = ErrorMapToRetVal(retVal);
1102         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1103                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
1104
1105         // Get all relavent audio metadata by passing relavent attirbutes
1106         char* __pAudioMeta = null;
1107         unique_ptr<char, CharDeleter> pAudioMeta(null);
1108
1109         // bitrate
1110         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pAudioMeta);
1111         if (__pAudioMeta != null)
1112         {
1113                 pAudioMeta.reset(__pAudioMeta);
1114                 pMetadata->bitrate = atoi(pAudioMeta.get());
1115         }
1116         else
1117         {
1118                 r = ErrorMapToRetVal(retVal);
1119                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1120                                 "[%s] metadata_extractor_get_metadata(bitrate) failed.", GetErrorMessage(r));
1121         }
1122
1123         // channelcount
1124         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_CHANNELS, &__pAudioMeta);
1125         if (__pAudioMeta != null)
1126         {
1127                 pAudioMeta.reset(__pAudioMeta);
1128                 pMetadata->channelCount = atoi(pAudioMeta.get());
1129         }
1130         else
1131         {
1132                 r = ErrorMapToRetVal(retVal);
1133                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1134                                 "[%s] metadata_extractor_get_metadata(channels) failed.", GetErrorMessage(r));
1135         }
1136
1137         // duration
1138         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pAudioMeta);
1139         if (__pAudioMeta != null)
1140         {
1141                 pAudioMeta.reset(__pAudioMeta);
1142                 pMetadata->duration = atoi(pAudioMeta.get());
1143         }
1144         else
1145         {
1146                 r = ErrorMapToRetVal(retVal);
1147                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1148                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
1149         }
1150
1151         // frequency
1152         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_SAMPLERATE, &__pAudioMeta);
1153         if (__pAudioMeta != null)
1154         {
1155                 pAudioMeta.reset(__pAudioMeta);
1156                 pMetadata->frequency = atoi(pAudioMeta.get());
1157         }
1158         else
1159         {
1160                 r = ErrorMapToRetVal(retVal);
1161                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1162                                 "[%s] metadata_extractor_get_metadata(frequency) failed.", GetErrorMessage(r));
1163         }
1164
1165         // albumname
1166         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ALBUM, &__pAudioMeta);
1167         if (__pAudioMeta != null)
1168         {
1169                 pAudioMeta.reset(__pAudioMeta);
1170                 pMetadata->pAlbumName = new (nothrow) String(pAudioMeta.get());
1171                 SysTryReturn(NID_CNT, pMetadata->pAlbumName != null, null, E_OUT_OF_MEMORY,
1172                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1173         }
1174         else
1175         {
1176                 r = ErrorMapToRetVal(retVal);
1177                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1178                                 "[%s] metadata_extractor_get_metadata(album name) failed.", GetErrorMessage(r));
1179         }
1180
1181         // artist
1182         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ARTIST, &__pAudioMeta);
1183         if (pAudioMeta.get() != null)
1184         {
1185                 pAudioMeta.reset(__pAudioMeta);
1186                 pMetadata->pArtist = new (nothrow) String(pAudioMeta.get());
1187                 SysTryReturn(NID_CNT, pMetadata->pArtist != null, null, E_OUT_OF_MEMORY,
1188                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1189         }
1190         else
1191         {
1192                 r = ErrorMapToRetVal(retVal);
1193                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1194                                 "[%s] metadata_extractor_get_metadata(artist) failed.", GetErrorMessage(r));
1195         }
1196
1197         // copyright
1198         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COPYRIGHT, &__pAudioMeta);
1199         if (__pAudioMeta != null)
1200         {
1201                 pAudioMeta.reset(__pAudioMeta);
1202                 pMetadata->pCopyright = new (nothrow) String(pAudioMeta.get());
1203                 SysTryReturn(NID_CNT, pMetadata->pCopyright != null, null, E_OUT_OF_MEMORY,
1204                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1205         }
1206         else
1207         {
1208                 r = ErrorMapToRetVal(retVal);
1209                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1210                                 "[%s] metadata_extractor_get_metadata(copyright) failed.", GetErrorMessage(r));
1211         }
1212
1213         // genre
1214         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pAudioMeta);
1215         if (__pAudioMeta != null)
1216         {
1217                 pAudioMeta.reset(__pAudioMeta);
1218                 pMetadata->pGenre = new (nothrow) String(pAudioMeta.get());
1219                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
1220                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1221         }
1222         else
1223         {
1224                 r = ErrorMapToRetVal(retVal);
1225                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1226                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
1227         }
1228
1229         // title
1230         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TITLE, &__pAudioMeta);
1231         if (__pAudioMeta != null)
1232         {
1233                 pAudioMeta.reset(__pAudioMeta);
1234                 pMetadata->pTitle = new (nothrow) String(pAudioMeta.get());
1235                 SysTryReturn(NID_CNT, pMetadata->pTitle != null, null, E_OUT_OF_MEMORY,
1236                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1237         }
1238         else
1239         {
1240                 r = ErrorMapToRetVal(retVal);
1241                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1242                                 "[%s] metadata_extractor_get_metadata(title) failed.", GetErrorMessage(r));
1243         }
1244
1245         // comment
1246         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pAudioMeta);
1247         if (__pAudioMeta != null)
1248         {
1249                 pAudioMeta.reset(__pAudioMeta);
1250                 pMetadata->pComment = new (nothrow) String(pAudioMeta.get());
1251                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
1252                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1253         }
1254         else
1255         {
1256                 r = ErrorMapToRetVal(retVal);
1257                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1258                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
1259         }
1260
1261         // description
1262         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pAudioMeta);
1263         if (__pAudioMeta != null)
1264         {
1265                 pAudioMeta.reset(__pAudioMeta);
1266                 pMetadata->pDescription = new (nothrow) String(pAudioMeta.get());
1267                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
1268                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1269         }
1270         else
1271         {
1272                 r = ErrorMapToRetVal(retVal);
1273                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1274                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
1275         }
1276
1277         // recording date
1278         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_RECDATE, &__pAudioMeta);
1279         if (__pAudioMeta != null)
1280         {
1281                 pAudioMeta.reset(__pAudioMeta);
1282                 pMetadata->pRecordingDate = new (nothrow) String(pAudioMeta.get());
1283                 SysTryReturn(NID_CNT, pMetadata->pRecordingDate != null, null, E_OUT_OF_MEMORY,
1284                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1285         }
1286         else
1287         {
1288                 r = ErrorMapToRetVal(retVal);
1289                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1290                                 "[%s] metadata_extractor_get_metadata(recording date) failed.", GetErrorMessage(r));
1291         }
1292
1293         // author
1294         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUTHOR, &__pAudioMeta);
1295         if (__pAudioMeta != null)
1296         {
1297                 pAudioMeta.reset(__pAudioMeta);
1298                 pMetadata->pComposer = new (nothrow) String(pAudioMeta.get());
1299                 SysTryReturn(NID_CNT, pMetadata->pComposer != null, null, E_OUT_OF_MEMORY,
1300                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1301         }
1302         else
1303         {
1304                 r = ErrorMapToRetVal(retVal);
1305                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1306                                 "[%s] metadata_extractor_get_metadata(author) failed.", GetErrorMessage(r));
1307         }
1308
1309         // track info
1310         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TRACK_NUM, &__pAudioMeta);
1311         if (__pAudioMeta != null)
1312         {
1313                 pAudioMeta.reset(__pAudioMeta);
1314                 pMetadata->pTrackInfo = new (nothrow) String(pAudioMeta.get());
1315                 SysTryReturn(NID_CNT, pMetadata->pTrackInfo != null, null, E_OUT_OF_MEMORY,
1316                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1317
1318                 // if the string contains the track info like track num/track position,
1319                 // then track position will be ignored and only track num is returned
1320                 // no need to parse this string, since only track number is required
1321                 pMetadata->trackNum = atoi(pAudioMeta.get());
1322         }
1323         else
1324         {
1325                 r = ErrorMapToRetVal(retVal);
1326                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1327                                 "[%s] metadata_extractor_get_metadata(track info) failed.", GetErrorMessage(r));
1328         }
1329
1330         // date
1331         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DATE, &__pAudioMeta);
1332         if (__pAudioMeta != null)
1333         {
1334                 pAudioMeta.reset(__pAudioMeta);
1335                 pMetadata->year = atoi(pAudioMeta.get());
1336         }
1337         else
1338         {
1339                 r = ErrorMapToRetVal(retVal);
1340                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1341                                 "[%s] metadata_extractor_get_metadata(date) failed.", GetErrorMessage(r));
1342         }
1343
1344         // artwork
1345         int size = 0;
1346         void* __pArtwork = null;
1347         unique_ptr<void, VoidDeleter> pArtwork(null);
1348
1349         // Get the artwork image in media file
1350         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pAudioMeta);
1351
1352         //Check if the albumart present and pass it to client if it is successfully processed, otherwise ignore any errors
1353         //while processing albumart. This is to pass the other metadata tags to application.
1354         if (__pArtwork != null)
1355         {
1356                 pArtwork.reset(__pArtwork);
1357
1358                 Image img;
1359                 ImageFormat format = IMG_FORMAT_NONE;
1360                 ByteBuffer buffer;
1361
1362                 r = buffer.Construct(size);
1363                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
1364                 {
1365                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
1366                         if (!IsFailed(r))
1367                         {
1368                                 r = img.Construct();
1369                                 if (!IsFailed(r))
1370                                 {
1371                                         format = img.GetImageFormat(buffer);
1372                                         pMetadata->pThumbnail = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888,
1373                                                                          THUMBNAIL_IMAGE_WIDTH, THUMBNAIL_IMAGE_HEIGHT);
1374                                         if (pMetadata->pThumbnail == null)
1375                                         {
1376                                                 // Because Thumbnail is one of the metadata, it is not exception in this function.
1377                                                 SysLog(NID_CNT, "DecodeN failed.");
1378                                         }
1379                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
1380                                         if (pMetadata->pAlbumArt == null)
1381                                         {
1382                                                 // Because Album Art is one of the metadata, it is not exception in this function.
1383                                                 SysLog(NID_CNT, "DecodeN failed.");
1384                                         }
1385                                 }
1386                         }
1387                 }
1388         }
1389         else
1390         {
1391                 r = ErrorMapToRetVal(retVal);
1392                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1393                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
1394         }
1395
1396         return pAudioMetadata.release();
1397 }
1398
1399 //
1400 // E_SUCCESS
1401 // E_INVALID_ARG
1402 // E_OUT_OF_MEMORY
1403 //
1404 VideoMetadata*
1405 _ContentManagerUtilImpl::GetVideoMetaN(const ByteBuffer& byteBuffer)
1406 {
1407         ClearLastResult();
1408
1409         int bufferLen = byteBuffer.GetRemaining();
1410         SysTryReturn(NID_CNT, bufferLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The length of buffer is less than zero.");
1411
1412         // need to create here to make sure that all get APIs will not crash in case of corrupted file
1413         unique_ptr<VideoMetadata> pVideoMetadata(new (nothrow) VideoMetadata());
1414         SysTryReturn(NID_CNT, pVideoMetadata != null, null, E_OUT_OF_MEMORY,
1415                         "[E_OUT_OF_MEMORY] The memory insufficient.");
1416
1417         _VideoMetadataImpl* pVideoMetaImpl = _VideoMetadataImpl::GetInstance(*(pVideoMetadata.get()));
1418         SysTryReturn(NID_CNT, pVideoMetaImpl != null, null, E_OUT_OF_MEMORY,
1419                         "[E_OUT_OF_MEMORY] pVideoMetaImpl is null.");
1420
1421         VideoMeta* pMetadata = pVideoMetaImpl->GetVideoMetadata();
1422         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
1423                         "[E_INVALID_ARG] pMetadata is null.");
1424
1425         // Create the metadata extractor handle
1426         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
1427         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
1428                                 "[E_OUT_OF_MEMORY] The memory insufficient.");
1429
1430         int retVal = metadata_extractor_create(pExtractor.get());
1431         result r = ErrorMapToRetVal(retVal);
1432         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1433                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
1434
1435         const byte* pByte = byteBuffer.GetPointer();
1436
1437         retVal = metadata_extractor_set_buffer(*(pExtractor.get()), pByte, bufferLen);
1438         r = ErrorMapToRetVal(retVal);
1439         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1440                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
1441
1442         // Get all relavent video metadata by passing relavent attirbutes
1443         char* __pVideoMeta = null;
1444         unique_ptr<char, CharDeleter> pVideoMeta(null);
1445
1446         // width
1447         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_WIDTH, &__pVideoMeta);
1448         if (__pVideoMeta != null)
1449         {
1450                 pVideoMeta.reset(__pVideoMeta);
1451                 pMetadata->width = atoi(pVideoMeta.get());
1452         }
1453         else
1454         {
1455                 r = ErrorMapToRetVal(retVal);
1456                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1457                                 "[%s] metadata_extractor_get_metadata(width) failed.", GetErrorMessage(r));
1458         }
1459
1460         // height
1461         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_HEIGHT, &__pVideoMeta);
1462         if (__pVideoMeta != null)
1463         {
1464                 pVideoMeta.reset(__pVideoMeta);
1465                 pMetadata->height = atoi(pVideoMeta.get());
1466         }
1467         else
1468         {
1469                 r = ErrorMapToRetVal(retVal);
1470                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1471                                 "[%s] metadata_extractor_get_metadata(height) failed.", GetErrorMessage(r));
1472         }
1473
1474         // video bitrate
1475         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_BITRATE, &__pVideoMeta);
1476         if (__pVideoMeta != null)
1477         {
1478                 pVideoMeta.reset(__pVideoMeta);
1479                 pMetadata->videoBitrate = atoi(pVideoMeta.get());
1480         }
1481         else
1482         {
1483                 r = ErrorMapToRetVal(retVal);
1484                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1485                                 "[%s] metadata_extractor_get_metadata(video bitrate) failed.", GetErrorMessage(r));
1486         }
1487
1488         // audio bitrate
1489         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pVideoMeta);
1490         if (__pVideoMeta != null)
1491         {
1492                 pVideoMeta.reset(__pVideoMeta);
1493                 pMetadata->audioBitrate = atoi(pVideoMeta.get());
1494         }
1495         else
1496         {
1497                 r = ErrorMapToRetVal(retVal);
1498                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1499                                 "[%s] metadata_extractor_get_metadata(audio bitrate) failed.", GetErrorMessage(r));
1500         }
1501
1502         // framerate
1503         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_FPS, &__pVideoMeta);
1504         if (__pVideoMeta != null)
1505         {
1506                 pVideoMeta.reset(__pVideoMeta);
1507                 pMetadata->framerate = atoi(pVideoMeta.get());
1508         }
1509         else
1510         {
1511                 r = ErrorMapToRetVal(retVal);
1512                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1513                                 "[%s] metadata_extractor_get_metadata(framerate) failed.", GetErrorMessage(r));
1514         }
1515
1516         // duration
1517         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pVideoMeta);
1518         if (__pVideoMeta != null)
1519         {
1520                 pVideoMeta.reset(__pVideoMeta);
1521                 pMetadata->duration = atoi(pVideoMeta.get());
1522         }
1523         else
1524         {
1525                 r = ErrorMapToRetVal(retVal);
1526                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1527                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
1528         }
1529
1530         // genre
1531         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pVideoMeta);
1532         if (__pVideoMeta != null)
1533         {
1534                 pVideoMeta.reset(__pVideoMeta);
1535                 pMetadata->pGenre = new (nothrow) String(pVideoMeta.get()); //allocate memory
1536                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
1537                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1538         }
1539         else
1540         {
1541                 r = ErrorMapToRetVal(retVal);
1542                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1543                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
1544         }
1545
1546         // comment
1547         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pVideoMeta);
1548         if (__pVideoMeta != null)
1549         {
1550                 pVideoMeta.reset(__pVideoMeta);
1551                 pMetadata->pComment = new (nothrow) String(pVideoMeta.get());
1552                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
1553                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1554         }
1555         else
1556         {
1557                 r = ErrorMapToRetVal(retVal);
1558                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1559                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
1560         }
1561
1562         // description
1563         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pVideoMeta);
1564         if (__pVideoMeta != null)
1565         {
1566                 pVideoMeta.reset(__pVideoMeta);
1567                 pMetadata->pDescription = new (nothrow) String(pVideoMeta.get());
1568                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
1569                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1570         }
1571         else
1572         {
1573                 r = ErrorMapToRetVal(retVal);
1574                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1575                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
1576         }
1577
1578         // artwork
1579         int size = 0;
1580         void* __pArtwork = null;
1581         unique_ptr<void, VoidDeleter> pArtwork(null);
1582
1583         // Get the artwork image in media file
1584         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pVideoMeta);
1585         if (__pArtwork != null)
1586         {
1587                 pArtwork.reset(__pArtwork);
1588
1589                 Image img;
1590                 ImageFormat format = IMG_FORMAT_NONE;
1591                 ByteBuffer buffer;
1592
1593                 r = buffer.Construct(size);
1594                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
1595                 {
1596                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
1597                         if (!IsFailed(r))
1598                         {
1599                                 r = img.Construct();
1600                                 if (!IsFailed(r))
1601                                 {
1602                                         format = img.GetImageFormat(buffer);
1603
1604                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
1605                                         if (pMetadata->pAlbumArt == null)
1606                                         {
1607                                                 // Because Album Art is one of the metadata, it is not exception in this function.
1608                                                 SysLog(NID_CNT, "DecodeN failed.");
1609                                         }
1610                                 }
1611                         }
1612                 }
1613         }
1614         else
1615         {
1616                 r = ErrorMapToRetVal(retVal);
1617                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1618                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
1619         }
1620
1621         return pVideoMetadata.release();
1622 }
1623
1624 //
1625 // E_SUCCESS
1626 // E_INVALID_ARG
1627 // E_OUT_OF_MEMORY
1628 // E_FILE_NOT_FOUND
1629 // E_UNSUPPORTED_FORMAT
1630 //
1631 ContentType
1632 _ContentManagerUtilImpl::CheckContentType(const String& contentPath, bool internal)
1633 {
1634         ClearLastResult();
1635
1636         ContentType contentType = CONTENT_TYPE_UNKNOWN;
1637
1638         if (!internal)
1639         {
1640                 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), contentType, E_INVALID_ARG,
1641                                 "[E_INVALID_ARG] The path is not compatible.");
1642         }
1643         SysTryReturn(NID_CNT, contentPath.GetLength() != 0, contentType, E_INVALID_ARG,
1644                         "[E_INVALID_ARG] The length of contentPath is 0.");
1645         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), contentType, E_FILE_NOT_FOUND,
1646                         "[E_FILE_NOT_FOUND] The file corresponding to contentPath could not be found.");
1647
1648         String fileExt = _FileImpl::GetFileExtension(contentPath);
1649         result r = GetLastResult();
1650         SysTryReturn(NID_CNT, !IsFailed(r), contentType, r, "[%s] GetFileExtension failed.", GetErrorMessage(r));
1651
1652         unique_ptr<char[]> pFormat(_StringConverter::CopyToCharArrayN(fileExt));
1653         SysTryReturn(NID_CNT, pFormat != null, contentType, E_OUT_OF_MEMORY,
1654                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1655
1656         char* __pMimeType = null;
1657         int retVal = mime_type_get_mime_type(pFormat.get(), &__pMimeType);
1658         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, E_INVALID_ARG,
1659                         "[E_INVALID_ARG] mime_type_get_mime_type failed.");
1660         SysTryReturn(NID_CNT, __pMimeType != null, contentType, E_INVALID_ARG,
1661                         "[E_INVALID_ARG] mime_type_get_mime_type failed.");
1662
1663         unique_ptr<char, CharDeleter> pMimeType;
1664         pMimeType.reset(__pMimeType);
1665
1666         SysLog(NID_CNT, "The MIME type for %ls is %s", fileExt.GetPointer(), __pMimeType);
1667
1668         String mimeType(pMimeType.get());
1669
1670         if (mimeType.Contains(L"image"))
1671         {
1672                 return CONTENT_TYPE_IMAGE;
1673         }
1674         else if (mimeType.Contains(L"audio"))
1675         {
1676                 if (mimeType.Contains(L"x-mpegurl"))
1677                 {
1678                         SysLog(NID_CNT, "The type of x-mpegurl is other.");
1679                         return CONTENT_TYPE_OTHER;
1680                 }
1681                 return CONTENT_TYPE_AUDIO;
1682         }
1683         else if (mimeType.Contains(L"video"))
1684         {
1685                 String format;
1686                 fileExt.ToLowerCase(format);
1687
1688                 if (format == L"3gp" || format == L"mp4")
1689                 {
1690                         return CheckStream(contentPath);
1691                 }
1692                 return CONTENT_TYPE_VIDEO;
1693         }
1694         else if (mimeType.Contains(L"application"))
1695         {
1696                 if (mimeType.Contains(L"x-smaf"))
1697                 {
1698                         SysLog(NID_CNT, "The type of x-smaf is audio.");
1699                         return CONTENT_TYPE_AUDIO;
1700                 }
1701                 return CONTENT_TYPE_OTHER;
1702         }
1703
1704         return CONTENT_TYPE_OTHER;
1705 }
1706
1707 ContentType
1708 _ContentManagerUtilImpl::CheckStream(const String& contentPath)
1709 {
1710         ClearLastResult();
1711
1712         ContentType contentType = CONTENT_TYPE_UNKNOWN;
1713
1714         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
1715         SysTryReturn(NID_CNT, pExtractor != null, contentType, E_OUT_OF_MEMORY,
1716                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1717
1718         int retVal = metadata_extractor_create(pExtractor.get());
1719         result r = ErrorMapToRetVal(retVal);
1720         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
1721                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
1722
1723         //Set the file path to extract metadata.
1724         unique_ptr<char[]> pContentPath(_StringConverter::CopyToCharArrayN(contentPath));
1725         SysTryReturn(NID_CNT, pContentPath != null, contentType, E_INVALID_ARG,
1726                         "[E_INVALID_ARG] The memory is insufficient.");
1727
1728         retVal = metadata_extractor_set_path(*(pExtractor.get()), pContentPath.get());
1729         r = ErrorMapToRetVal(retVal);
1730         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE && pExtractor, contentType, r,
1731                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
1732
1733         //Check whether it is an audio or video file.
1734         char* __pAudio = null;
1735         unique_ptr<char, CharDeleter> pAudio(null);
1736
1737         char* __pVideo = null;
1738         unique_ptr<char, CharDeleter> pVideo(null);
1739
1740         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_HAS_AUDIO, &__pAudio);
1741         if (__pAudio != null)
1742         {
1743                 pAudio.reset(__pAudio);
1744         }
1745         else
1746         {
1747                 r = ErrorMapToRetVal(retVal);
1748                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
1749                                 "[%s] metadata_extractor_get_metadata failed.", GetErrorMessage(r));
1750         }
1751
1752         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_HAS_VIDEO, &__pVideo);
1753         if (__pVideo != null)
1754         {
1755                 pVideo.reset(__pVideo);
1756         }
1757         else
1758         {
1759                 r = ErrorMapToRetVal(retVal);
1760                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
1761                                 "[%s] metadata_extractor_get_metadata failed.", GetErrorMessage(r));
1762         }
1763
1764         if (*(pAudio.get()) > 0 && *(pVideo.get()) == 0)
1765         {
1766                 SysLog(NID_CNT, "The result of CheckStream() is audio");
1767                 return CONTENT_TYPE_AUDIO;
1768         }
1769         else if (*(pAudio.get()) == 0 && *(pVideo.get()) > 0)
1770         {
1771                 SysLog(NID_CNT, "The result of CheckStream() is video");
1772                 return CONTENT_TYPE_VIDEO;
1773         }
1774         else if (*(pAudio.get()) > 0 && *(pVideo.get()) > 0)
1775         {
1776                 SysLog(NID_CNT, "The result of CheckStream() is video");
1777                 return CONTENT_TYPE_VIDEO;
1778         }
1779         else
1780         {
1781                 SysLogException(NID_CNT, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The stream is empty.");
1782         }
1783
1784         return contentType;
1785 }
1786
1787 bool
1788 _ContentManagerUtilImpl::VerifyFilePathCompatibility(const String& contentPath)
1789 {
1790         if (!_AppInfo::IsOspCompat())
1791         {
1792                 if (contentPath.StartsWith(OSP_MEDIA_PHONE, 0) || contentPath.StartsWith(OSP_MEDIA_MMC, 0)
1793                         || contentPath.StartsWith(OSP_HOME, 0))
1794                 {
1795                         SysLogException(NID_CNT, E_INVALID_ARG,
1796                                         "/Home, /Media/, or /Storagecard/Media/ is not supported from Tizen 2.0.");
1797                         return false;
1798                 }
1799         }
1800         else
1801         {
1802                 // prior to 2.0
1803                 if (!(contentPath.StartsWith(OSP_MEDIA_PHONE, 0) || contentPath.StartsWith(OSP_MEDIA_MMC, 0)
1804                         || contentPath.StartsWith(OSP_HOME, 0)))
1805                 {
1806                         SysLogException(NID_CNT, E_INVALID_ARG,
1807                                         "The contentPath should start with /Home, /Media, or /Storagecard/Media.");
1808                         return false;
1809                 }
1810         }
1811
1812         return true;
1813 }
1814
1815 result
1816 _ContentManagerUtilImpl::ErrorMapToRetVal(int retVal)
1817 {
1818         result r = E_SUCCESS;
1819
1820         switch (retVal)
1821         {
1822         case METADATA_EXTRACTOR_ERROR_NONE:
1823                 r = E_SUCCESS;
1824                 break;
1825         case METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER:
1826                 r = E_INVALID_ARG;
1827                 break;
1828         case METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY:
1829                 r = E_OUT_OF_MEMORY;
1830                 break;
1831         case METADATA_EXTRACTOR_ERROR_FILE_EXISTS:
1832                 r = E_INVALID_ARG;
1833                 break;
1834         case METADATA_EXTRACTOR_ERROR_OPERATION_FAILED:
1835                 r = E_INVALID_ARG;
1836                 break;
1837         }
1838
1839         return r;
1840 }
1841
1842 /**
1843  * deprecation
1844  */
1845 result
1846 _ContentManagerUtilImpl::CopyToMediaDirectory(const String& srcContentPath, const String& destContentPath)
1847 {
1848         ClearLastResult();
1849
1850         // For srcContentPath
1851         SysTryReturn(NID_CNT, !_FileImpl::IsSystemPath(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1852                 "[E_INVALID_ARG] Can not copy the file in the system region.");
1853         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1854                 "[E_INVALID_ARG] Can not find the file.");
1855
1856         // For destContentPath
1857         SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destContentPath), E_INVALID_ARG, E_INVALID_ARG,
1858                 "[E_INVALID_ARG] The destination path should start with /Media or /Storagecard/Media.");
1859
1860         // E_SUCCESS, E_INVALID_ARG, E_ILLEGAL_ACCESS, E_FILE_NOT_FOUND, E_FILE_ALREADY_EXIST, E_MAX_EXCEEDED, E_STORAGE_FULL, E_IO
1861         result r = E_SUCCESS;
1862         r = _FileImpl::Copy(srcContentPath, destContentPath, true);
1863         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] CopyToMediaDirectory failed.", GetErrorMessage(r));
1864
1865         return r;
1866 }
1867
1868 /**
1869  * deprecation
1870  */
1871 result
1872 _ContentManagerUtilImpl::MoveToMediaDirectory(const String& srcContentPath, const String& destContentPath)
1873 {
1874         ClearLastResult();
1875
1876         // For srcContentPath
1877         SysTryReturn(NID_CNT, !_FileImpl::IsSystemPath(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1878                 "[E_INVALID_ARG] Can not copy the file in the system region.");
1879         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1880                 "[E_INVALID_ARG] Can not find the file.");
1881
1882         // For destContentPath
1883         SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destContentPath), E_INVALID_ARG, E_INVALID_ARG,
1884                 "[E_INVALID_ARG] The destination path should start with /Media or /Storagecard/Media.");
1885
1886         // E_SUCCESS, E_INVALID_ARG, E_ILLEGAL_ACCESS, E_FILE_NOT_FOUND, E_FILE_ALREADY_EXIST, E_MAX_EXCEEDED, E_STORAGE_FULL, E_IO
1887         result r = E_SUCCESS;
1888         r = _FileImpl::Move(srcContentPath, destContentPath);
1889         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] MoveToMediaDirectory failed.", GetErrorMessage(r));
1890
1891         return r;
1892 }
1893 }}