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