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