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