2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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
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 , __appTerminating(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 ThumbnailJob* pThumbnailJob = new (std::nothrow) ThumbnailJob();
197 pThumbnailJob->Construct(contentId, ++__requestId, event);
198 __pCmdQueue->Add(pThumbnailJob);
200 __pMutexCmd->Release();
202 SendUserEvent(null, null);
203 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
207 ThumbnailProvider::CancelThumbnailRequest(const ContentId& contentId, const ThumbnailEvent* event)
209 AppLogDebug("ENTER");
210 ThumbnailJob* pThumbnailJob = null;
212 if (__pMutexCmd == null || __pCmdQueue == null)
214 AppLogDebug("EXIT 1(%s)", GetErrorMessage(GetLastResult()));
218 __pMutexCmd->Acquire();
220 int loopCount = __pCmdQueue->GetCount();
221 for (int i = 0; i < loopCount; ++i)
223 pThumbnailJob = static_cast<ThumbnailJob*>(__pCmdQueue->GetAt(i));
225 if (pThumbnailJob != null
226 && pThumbnailJob->GetContentId() == contentId
227 && pThumbnailJob->GetEvent() == event)
229 AppLogDebug("ENTER i(%d) event(%x)", i, event);
230 __pCmdQueue->RemoveAt(i, true);
234 __pMutexCmd->Release();
235 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
239 ThumbnailProvider::ClearThumbnailRequests(bool appTerminating)
241 AppLogDebug("ENTER");
242 if (__pMutexCmd != null)
244 __pMutexCmd->Acquire();
245 if (__pCmdQueue != null && __pCmdQueue->GetCount() > 0)
247 __pCmdQueue->RemoveAll(true);
250 if (appTerminating == true)
252 __appTerminating = true;
254 __pMutexCmd->Release();
256 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
260 ThumbnailProvider::OnStart(void)
262 AppLogDebug("ENTER");
263 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
269 ThumbnailProvider::OnStop(void)
271 AppLogDebug("ENTER");
272 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
276 ThumbnailProvider::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
278 AppLogDebug("ENTER");
279 AppLogDebug("[THREAD] Receive Job Message - (SubThread)");
280 ThumbnailJob* pThumbnailJob = null;
281 ThumbnailInfo* pThumbnailInfo = null;
284 if (__pMutexCmd == null || __pCmdQueue == null)
287 AppLogDebug("EXIT1(%s)", GetErrorMessage(GetLastResult()));
291 __pMutexCmd->Acquire();
292 if (__pCmdQueue->GetCount() > 0)
294 pThumbnailJob = static_cast<ThumbnailJob*>(__pCmdQueue->GetAt(0));
295 if (pThumbnailJob == null)
297 __pCmdQueue->RemoveAt(0);
298 __pMutexCmd->Release();
302 unsigned long requestId = pThumbnailJob->GetRequestId();
303 ContentId contentId = pThumbnailJob->GetContentId();
304 __pMutexCmd->Release();
306 pThumbnailInfo = GetThumbnailInfoN(contentId);
308 __pMutexCmd->Acquire();
309 pThumbnailJob = static_cast<ThumbnailJob*>(__pCmdQueue->GetAt(0));
311 if (pThumbnailJob != null && pThumbnailInfo != null && requestId == pThumbnailJob->GetRequestId())
313 ContentType contentType = pThumbnailInfo->GetContentType();
314 if (contentType == CONTENT_TYPE_IMAGE || contentType == CONTENT_TYPE_VIDEO)
316 ThumbnailEvent* pThumbnailEvent = const_cast<ThumbnailEvent*>(pThumbnailJob->GetEvent());
317 if (pThumbnailEvent != null)
319 if (__appTerminating != true)
321 ThumbnailEventArg* pSendingArg = new (std::nothrow)ThumbnailEventArg(pThumbnailInfo);
322 pThumbnailEvent->Fire(*pSendingArg);
328 delete pThumbnailInfo;
330 __pCmdQueue->RemoveAt(0, true);
334 delete pThumbnailInfo;
337 __pMutexCmd->Release();
341 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
345 ThumbnailProvider::GetThumbnailInfoN(const ContentId& contentId) const
347 AppLogDebug("ENTER");
348 ThumbnailInfo* pNewThumbnailInfo = null;
350 ContentManager contentManager;
351 result r = contentManager.Construct();
354 Bitmap* pBitmap = null;
357 ContentInfo* pContentInfo = contentManager.GetContentInfoN(contentId);
359 if (pContentInfo != null)
361 pBitmap = pContentInfo->GetThumbnailN();
365 pBitmap = GetThumbnailByDecodeN(pContentInfo->GetContentPath(), pContentInfo->GetContentType());
368 pBitmap = ResourceManager::GetBitmapN(IDB_NO_CONTENTS_BROKEN);
371 pBitmap->Scale(DIMENSION_DEFAULT_THUMBNAIL);
376 AppLogDebug("EXIT 2(%s)", GetErrorMessage(GetLastResult()));
381 ContentType contentType = pContentInfo->GetContentType();
382 if (contentType == CONTENT_TYPE_VIDEO)
384 VideoContentInfo* pVideoContentInfo = static_cast<VideoContentInfo*>(pContentInfo);
385 duration = pVideoContentInfo->GetDuration();
387 pNewThumbnailInfo = new (std::nothrow) ThumbnailInfo();
388 pNewThumbnailInfo->Construct(contentId, pContentInfo->GetContentPath(), *pBitmap, contentType, duration);
391 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
393 return pNewThumbnailInfo;
397 ThumbnailProvider::GetThumbnailByDecodeN(const String& filePath, const ContentType contentType) const
399 AppLogDebug("ENTER");
400 Bitmap* pBitmap = null;
401 if (&filePath == null || filePath.GetLength() <= 0)
403 pBitmap = new (std::nothrow) Bitmap();
404 pBitmap->Construct(DIMENSION_DEFAULT_THUMBNAIL, BITMAP_PIXEL_FORMAT_RGB565);
408 if (contentType == CONTENT_TYPE_IMAGE)
410 ImageBuffer pImageBuffer;
411 result r = pImageBuffer.Construct(filePath);
414 pBitmap = pImageBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_AUTO);
417 else if (contentType == CONTENT_TYPE_VIDEO)
419 VideoFrameExtractor extractor;
420 result r = extractor.Construct(filePath, MEDIA_PIXEL_FORMAT_RGB565LE);
423 ImageBuffer* pImageBuffer = extractor.GetFrameN(0);
424 if (pImageBuffer != null)
426 pBitmap = pImageBuffer->GetBitmapN(BITMAP_PIXEL_FORMAT_RGB565, BUFFER_SCALING_AUTO);
432 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));
438 ThumbnailProvider::GetFileNameFromFullPath(const String& fullPath, bool withExt) const
440 AppLogDebug("ENTER");
441 if (fullPath.CompareTo(EMPTY_SPACE) == 0)
443 AppLogDebug("EXIT 1(%s)", GetErrorMessage(GetLastResult()));
448 String delim(DIRECTORY_SEPARATOR);
449 StringTokenizer st(fullPath,delim);
451 while (st.HasMoreTokens())
453 st.GetNextToken(token);
458 AppLogDebug("EXIT 2(%s)", GetErrorMessage(GetLastResult()));
464 String subDelim(FILE_EXT_SEPARATOR);
465 StringTokenizer subSt(token, subDelim);
467 subSt.GetNextToken(subToken);
468 AppLogDebug("EXIT(%s)", GetErrorMessage(GetLastResult()));