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