2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.1 (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
8 // http://floralicense.org/license/
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.
18 * @file GlThumbnailProvider.cpp
19 * @brief This is the implementation file for ThumbnailProvider class.
25 #include "GlResourceManager.h"
26 #include "GlThumbnailEvent.h"
27 #include "GlThumbnailEventArg.h"
28 #include "GlThumbnailJob.h"
29 #include "GlThumbnailProvider.h"
32 using namespace Tizen::Base;
33 using namespace Tizen::Base::Collection;
34 using namespace Tizen::Base::Runtime;
35 using namespace Tizen::Base::Utility;
36 using namespace Tizen::Content;
37 using namespace Tizen::Graphics;
38 using namespace Tizen::Media;
40 ThumbnailProvider* ThumbnailProvider::__pThumbnailProviderInstance = null;
41 ArrayList* ThumbnailProvider::__pThumbnailEventListener = null;
43 ThumbnailProvider::ThumbnailProvider(void)
47 , __isAppTerminating(false)
50 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
53 ThumbnailProvider::~ThumbnailProvider(void)
56 if (__pThumbnailProviderInstance != null)
58 __pThumbnailProviderInstance->Stop();
59 __pThumbnailProviderInstance->Join();
62 if (__pThumbnailEventListener != null)
64 delete __pThumbnailEventListener;
67 if (__pMutexCmd != null)
72 if (__pCmdQueue != null)
76 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
80 ThumbnailProvider::GetInstance(void)
83 if (__pThumbnailProviderInstance == null)
86 __pThumbnailProviderInstance->Start();
88 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
90 return __pThumbnailProviderInstance;
94 ThumbnailProvider::Construct(void)
98 __pThumbnailEventListener = new (std::nothrow) ArrayList(SingleObjectDeleter);
99 result r = __pThumbnailEventListener->Construct();
100 TryCatch(r == E_SUCCESS,, "[%s] Unable to set event listener", GetErrorMessage(r));
102 __pMutexCmd = new (std::nothrow) Mutex();
103 r = __pMutexCmd->Create();
104 TryCatch(r == E_SUCCESS,, "[%s] Unable to create mutex", GetErrorMessage(r));
106 if (__pCmdQueue != null)
110 __pCmdQueue = new (std::nothrow) ArrayList(SingleObjectDeleter);
111 r = __pCmdQueue->Construct();
112 TryCatch(r == E_SUCCESS,, "[%s] Unable to construct queue", GetErrorMessage(r));
113 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
115 return EventDrivenThread::Construct();
118 if (__pThumbnailEventListener != null)
120 delete __pThumbnailEventListener;
121 __pThumbnailEventListener = null;
124 if (__pMutexCmd != null)
130 if (__pCmdQueue != null)
135 AppLogDebug("EXIT with exception(%s)", GetErrorMessage(GetLastResult()));
141 ThumbnailProvider::CreateInstance(void)
143 AppLogDebug("ENTER");
144 __pThumbnailProviderInstance = new (std::nothrow) ThumbnailProvider();
145 result r = __pThumbnailProviderInstance->Construct();
147 if (IsFailed(r) == true)
149 delete __pThumbnailProviderInstance;
150 __pThumbnailProviderInstance = null;
151 AppLogDebug("EXIT 1(%s)", GetErrorMessage(GetLastResult()));
156 std::atexit(DestroyInstance);
157 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
161 ThumbnailProvider::DestroyInstance(void)
163 AppLogDebug("ENTER");
164 delete __pThumbnailProviderInstance;
165 __pThumbnailProviderInstance = null;
166 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
170 ThumbnailProvider::Release(void)
172 AppLogDebug("ENTER");
173 if (__pThumbnailProviderInstance != null)
175 delete __pThumbnailProviderInstance;
176 __pThumbnailProviderInstance = null;
178 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
182 ThumbnailProvider::RequestThumbnail(const ContentId& contentId, const ThumbnailEvent* event)
184 AppLogDebug("ENTER");
185 AppLogDebug("[THREAD] Request Job - (MainThread)");
187 if (contentId.ToString().IsEmpty() == true || event == null
188 || __pMutexCmd == null || __pCmdQueue == null)
190 AppLogDebug("EXIT 1(%s)", GetErrorMessage(GetLastResult()));
194 __pMutexCmd->Acquire();
196 AppLogDebug("__pMutexCmd: %x", __pMutexCmd);
198 ThumbnailJob* pThumbnailJob = new (std::nothrow) ThumbnailJob();
199 AppLogDebug("pThumbnailJob: %x", pThumbnailJob);
200 pThumbnailJob->Construct(contentId, ++__requestId, event);
201 __pCmdQueue->Add(pThumbnailJob);
203 __pMutexCmd->Release();
205 SendUserEvent(null, null);
206 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
210 ThumbnailProvider::ClearThumbnailRequests(const bool appTerminating)
212 AppLogDebug("ENTER");
213 if (__pMutexCmd != null)
215 __pMutexCmd->Acquire();
216 if (__pCmdQueue != null && __pCmdQueue->GetCount() > 0)
218 __pCmdQueue->RemoveAll(true);
221 if (appTerminating == true)
223 __isAppTerminating = true;
225 __pMutexCmd->Release();
227 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
231 ThumbnailProvider::OnStart(void)
233 AppLogDebug("ENTER");
234 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
240 ThumbnailProvider::OnStop(void)
242 AppLogDebug("ENTER");
243 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
247 ThumbnailProvider::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
249 AppLogDebug("ENTER");
250 AppLogDebug("[THREAD] Receive Job Message - (SubThread)");
251 ThumbnailJob* pThumbnailJob = null;
252 ThumbnailInfo* pThumbnailInfo = null;
255 if (__pMutexCmd == null || __pCmdQueue == null)
258 AppLogDebug("EXIT1(%s)", GetErrorMessage(GetLastResult()));
262 __pMutexCmd->Acquire();
263 if (__pCmdQueue->GetCount() > 0)
265 pThumbnailJob = static_cast<ThumbnailJob*>(__pCmdQueue->GetAt(0));
266 if (pThumbnailJob == null)
268 __pCmdQueue->RemoveAt(0);
269 __pMutexCmd->Release();
273 unsigned long requestId = pThumbnailJob->GetRequestId();
274 ContentId contentId = pThumbnailJob->GetContentId();
275 __pMutexCmd->Release();
277 pThumbnailInfo = GetThumbnailInfoN(contentId);
279 __pMutexCmd->Acquire();
280 pThumbnailJob = static_cast<ThumbnailJob*>(__pCmdQueue->GetAt(0));
282 if (pThumbnailJob != null && pThumbnailInfo != null && requestId == pThumbnailJob->GetRequestId())
284 ContentType contentType = pThumbnailInfo->GetContentType();
285 if (contentType == CONTENT_TYPE_IMAGE || contentType == CONTENT_TYPE_VIDEO)
287 ThumbnailEvent* pThumbnailEvent = const_cast<ThumbnailEvent*>(pThumbnailJob->GetEvent());
288 if (pThumbnailEvent != null)
290 if (__isAppTerminating != true)
292 ThumbnailEventArg* pSendingArg = new (std::nothrow)ThumbnailEventArg(pThumbnailInfo);
293 pThumbnailEvent->Fire(*pSendingArg);
299 delete pThumbnailInfo;
301 __pCmdQueue->RemoveAt(0, true);
305 delete pThumbnailInfo;
308 __pMutexCmd->Release();
312 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
316 ThumbnailProvider::GetThumbnailInfoN(const ContentId& contentId) const
318 AppLogDebug("ENTER");
319 ThumbnailInfo* pNewThumbnailInfo = null;
321 ContentManager contentManager;
322 result r = contentManager.Construct();
325 Bitmap* pBitmap = null;
328 ContentInfo* pContentInfo = contentManager.GetContentInfoN(contentId);
330 if (pContentInfo != null)
332 String path = pContentInfo->GetContentPath();
333 if (path.EndsWith(L"tif") != true
334 && path.EndsWith(L"tiff") != true
335 && path.EndsWith(L"wbmp") != true
336 && path.EndsWith(L"TIF") != true
337 && path.EndsWith(L"TIFF") != true
338 && path.EndsWith(L"WBMP") != true)
340 pBitmap = pContentInfo->GetThumbnailN();
345 pBitmap = GetThumbnailByDecodeN(pContentInfo->GetContentPath(), pContentInfo->GetContentType());
348 pBitmap = ResourceManager::GetBitmapN(IDB_NO_CONTENTS_BROKEN);
351 pBitmap->Scale(DIMENSION_DEFAULT_THUMBNAIL);
353 ContentType contentType = pContentInfo->GetContentType();
355 if (contentType == CONTENT_TYPE_VIDEO)
357 VideoContentInfo* pVideoContentInfo = static_cast<VideoContentInfo*>(pContentInfo);
358 duration = pVideoContentInfo->GetDuration();
361 pNewThumbnailInfo = new (std::nothrow) ThumbnailInfo();
362 pNewThumbnailInfo->Construct(contentId, pContentInfo->GetContentPath(), *pBitmap, contentType, duration);
367 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
369 return pNewThumbnailInfo;
373 ThumbnailProvider::GetThumbnailByDecodeN(const String& filePath, const ContentType contentType) const
375 AppLogDebug("ENTER");
376 Bitmap* pBitmap = null;
377 if (&filePath == null || filePath.GetLength() <= 0)
379 pBitmap = new (std::nothrow) Bitmap();
380 pBitmap->Construct(DIMENSION_DEFAULT_THUMBNAIL, BITMAP_PIXEL_FORMAT_RGB565);
384 if (contentType == CONTENT_TYPE_IMAGE)
386 ImageBuffer pImageBuffer;
387 result r = pImageBuffer.Construct(filePath);
390 pBitmap = pImageBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_AUTO);
393 else if (contentType == CONTENT_TYPE_VIDEO)
395 VideoFrameExtractor extractor;
396 result r = extractor.Construct(filePath, MEDIA_PIXEL_FORMAT_RGB565LE);
399 ImageBuffer* pImageBuffer = extractor.GetFrameN(0);
400 if (pImageBuffer != null)
402 pBitmap = pImageBuffer->GetBitmapN(BITMAP_PIXEL_FORMAT_RGB565, BUFFER_SCALING_AUTO);
408 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
414 ThumbnailProvider::GetFileNameFromFullPath(const String& fullPath, bool withExt) const
416 AppLogDebug("ENTER");
417 if (fullPath.CompareTo(EMPTY_SPACE) == 0)
419 AppLogDebug("EXIT 1(%s)", GetErrorMessage(GetLastResult()));
424 String delim(DIRECTORY_SEPARATOR);
425 StringTokenizer st(fullPath,delim);
427 while (st.HasMoreTokens())
429 st.GetNextToken(token);
434 AppLogDebug("EXIT 2(%s)", GetErrorMessage(GetLastResult()));
440 String subDelim(FILE_EXT_SEPARATOR);
441 StringTokenizer subSt(token, subDelim);
443 subSt.GetNextToken(subToken);
444 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));