2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FMedia_ImageUriDataFactory.cpp
20 * @brief This file contains the implementation of _ImageUriDataFactory class,
21 * required internally by Image::DecodeUrl.
28 #include <unique_ptr.h>
29 #include <FBaseSysLog.h>
30 #include <FMediaIImageEventListener.h>
32 #include "FMedia_ImageUriData.h"
33 #include "FMedia_ImageUriDataHolder.h"
34 #include "FMedia_ImageUriDataFactory.h"
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Utility;
38 using namespace Tizen::Graphics;
40 namespace Tizen{ namespace Media{
42 // 3 requests in worker queue. As in 2.0.
43 static const int _MAX_IMAGE_URI_DATA_WORK = 3;
44 // 3 requests in pending queue. As in 2.0.
45 static const int _MAX_IMAGE_URI_DATA_QUEUE_COUNT = 3;
47 _ImageUriDataFactory* _ImageUriDataFactory::__pTheInstance = null;
50 _ImageUriDataFactory::InitSingleton(void)
52 std::unique_ptr<_ImageUriDataFactory> pInst(new (std::nothrow) _ImageUriDataFactory());
54 SysTryReturnVoidResult(NID_MEDIA, pInst, E_OUT_OF_MEMORY,
55 "[%s] Memory allocation failed.",
56 GetErrorMessage(E_OUT_OF_MEMORY));
58 result r = pInst->Construct();
59 SysTryReturnVoidResult(NID_MEDIA, r == E_SUCCESS, r,
60 "[%s] Propagating.", GetErrorMessage(r));
62 __pTheInstance = pInst.release();
63 std::atexit(DestroySingleton);
67 _ImageUriDataFactory::DestroySingleton(void)
69 delete __pTheInstance;
73 _ImageUriDataFactory::GetInstance(void)
75 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
77 if (__pTheInstance == null)
80 pthread_once(&onceBlock, InitSingleton);
81 result r = GetLastResult();
84 onceBlock = PTHREAD_ONCE_INIT;
87 return __pTheInstance;
90 _ImageUriDataFactory::_ImageUriDataFactory(void)
95 _ImageUriDataFactory::~_ImageUriDataFactory(void)
97 if (__pImageUriDataHolderQueue.get() != null)
99 if (__pImageUriDataHolderQueue->GetCount() > 0)
101 __pImageUriDataHolderQueue->RemoveAll(true);
105 if (__pImageUriDataWorkingList.get() != null)
107 if (__pImageUriDataWorkingList->GetCount() > 0)
109 __pImageUriDataWorkingList->RemoveAll(true);
118 _ImageUriDataFactory::Construct(void)
120 result r = E_SUCCESS;
122 __pImageUriDataHolderQueue.reset(new (std::nothrow) Collection::Queue());
123 SysTryReturn(NID_MEDIA, __pImageUriDataHolderQueue.get() != null,
124 E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] while creating Queue");
126 r = __pImageUriDataHolderQueue->Construct(_MAX_IMAGE_URI_DATA_QUEUE_COUNT);
127 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
129 __pImageUriDataWorkingList.reset(new (std::nothrow) Collection::LinkedList());
130 SysTryReturn(NID_MEDIA, __pImageUriDataWorkingList.get() != null ,
131 E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] while creating List");
137 _ImageUriDataFactory::DecodeUrl(const Uri& srcImageUrl,
138 BitmapPixelFormat colorFormat, int destWidth, int destHeight,
139 RequestId &reqId, const Runtime::IEventListener& listener, long timeout)
141 result r = E_SUCCESS;
143 reqId = -1; // if fail it returns -1;
145 if (__pImageUriDataHolderQueue.get() == null)
148 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Construct failed.",
152 SysTryReturn(NID_MEDIA, GetWorkerCount() < _MAX_IMAGE_URI_DATA_WORK,
153 E_MAX_EXCEEDED, E_MAX_EXCEEDED,
154 "[E_MAX_EXCEEDED] The concurrent working limitation is exceeded.");
156 reqId = ++__requestId;
158 index = AddImageUriData(srcImageUrl, colorFormat, destWidth, destHeight, reqId, listener, timeout);
159 SysTryReturn(NID_MEDIA, index > 0, GetLastResult(), GetLastResult(),
160 "[%s] Propagated.", GetErrorMessage(GetLastResult()));
162 // 0, 1, 2.. //max 3 instances
163 SysTryReturn(NID_MEDIA, GetWorkerCount() < _MAX_IMAGE_URI_DATA_WORK, E_SUCCESS,
164 E_SUCCESS, "[E_SUCCESS] But this operation is now pending .");
171 _ImageUriDataFactory::AddImageUriData(const Uri& srcImageUrl,
172 BitmapPixelFormat colorFormat, int destWidth, int destHeight,
173 RequestId &reqId, const Runtime::IEventListener& listener, long timeout)
175 result r = E_SUCCESS;
178 _ImageUriDataHolder* pImageUriDataHolder = new (std::nothrow) _ImageUriDataHolder();
179 SysTryCatch(NID_MEDIA, pImageUriDataHolder != null ,
180 r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] while creating Image holder");
182 pImageUriDataHolder->SetUri(srcImageUrl);
183 pImageUriDataHolder->SetColorFormat(colorFormat);
184 pImageUriDataHolder->SetDestDim(Dimension(destWidth, destHeight));
185 pImageUriDataHolder->SetRequestId(reqId);
186 pImageUriDataHolder->SetListener(const_cast<Runtime::IEventListener*>(&listener));
187 pImageUriDataHolder->SetTimeout(timeout);
189 r = __pImageUriDataHolderQueue->Enqueue(*pImageUriDataHolder);
190 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated.", GetErrorMessage(r));
193 return GetHolderCount();
197 if (pImageUriDataHolder)
199 delete pImageUriDataHolder;
200 pImageUriDataHolder = null;
206 _ImageUriDataFactory::StartDecode(void)
208 result r = E_SUCCESS;
210 _ImageUriDataHolder* pImageUriDataHolder = null;
211 IImageDecodeUrlEventListener* pImageListener = null;
212 Runtime::IEventListener* pListener = null;
213 std::unique_ptr<_ImageUriData> pImageUriData;
214 RequestId reqId = -1;
216 SysTryCatch(NID_MEDIA, __pImageUriDataHolderQueue.get() != null,
217 r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE]");
219 pObj = __pImageUriDataHolderQueue->Dequeue();
220 SysTryCatch(NID_MEDIA, pObj != null, r = E_UNDERFLOW, E_UNDERFLOW, "[E_UNDERFLOW]");
222 pImageUriDataHolder = dynamic_cast<_ImageUriDataHolder*>(pObj);
223 SysTryCatch(NID_MEDIA, pImageUriDataHolder != null, r = E_INVALID_ARG,
224 E_INVALID_ARG, "[E_INVALID_ARG] : RequestId = %d",
225 pImageUriDataHolder->GetRequestId());
227 pListener = pImageUriDataHolder->GetListener();
228 pImageListener = dynamic_cast<IImageDecodeUrlEventListener*>(pListener);
229 SysTryCatch(NID_MEDIA, pImageListener != null, r = E_INVALID_ARG,
230 E_INVALID_ARG, "[E_INVALID_ARG] GetListener() : RequestId = %d",
231 pImageUriDataHolder->GetRequestId());
233 pImageUriData.reset(new (std::nothrow) _ImageUriData());
234 SysTryCatch(NID_MEDIA, pImageUriData.get() != null, r = E_OUT_OF_MEMORY,
235 E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] : RequestId = %d",
236 pImageUriDataHolder->GetRequestId());
238 r = pImageUriData->Construct(*pImageListener);
239 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated : RequestId = %d.",
240 GetErrorMessage(r), pImageUriDataHolder->GetRequestId());
242 reqId = pImageUriDataHolder->GetRequestId();
244 r = pImageUriData->RequestDecode(pImageUriDataHolder->GetUri(),
245 pImageUriDataHolder->GetColorFormat(), pImageUriDataHolder->GetDestDim(),
246 reqId, pImageUriDataHolder->GetTimeout());
247 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated : RequestId = %d.",
248 GetErrorMessage(r), pImageUriDataHolder->GetRequestId());
250 r = __pImageUriDataWorkingList->Add(*pImageUriData.release());
251 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagated : RequestId = %d.",
252 GetErrorMessage(r), pImageUriDataHolder->GetRequestId());
254 delete pImageUriDataHolder;
260 if (pImageUriDataHolder)
262 delete pImageUriDataHolder;
268 _ImageUriDataFactory::Watchout(void)
270 result r = E_SUCCESS;
271 int heldCount = GetHolderCount();
273 while (0 < heldCount)
280 heldCount = GetHolderCount();
285 _ImageUriDataFactory::OnMediaSessionEnded(RequestId requestId)
291 num = __pImageUriDataWorkingList->GetCount();
292 for (int i = 0; i < num; i++)
294 pObj = __pImageUriDataWorkingList->GetAt(i);
297 _ImageUriData* pImageUriData = dynamic_cast<_ImageUriData*>(pObj);
298 if (pImageUriData != null)
300 if (requestId == pImageUriData->GetRequestId())
302 __pImageUriDataWorkingList->RemoveAt(i, true);
313 _ImageUriDataFactory::Remove(RequestId reqId)
317 bool deleted = false;
318 result r = E_SUCCESS;
320 // Remove ImageUriData for this request id from the working list.
321 num = __pImageUriDataWorkingList->GetCount();
322 for (int i = 0; i < num; i++)
324 pObj = __pImageUriDataWorkingList->GetAt(i);
327 _ImageUriData* pImageUriData = dynamic_cast<_ImageUriData*>(pObj);
328 if (pImageUriData != null)
330 if (reqId == pImageUriData->GetRequestId())
332 pImageUriData->Cancel(reqId, r);
333 __pImageUriDataWorkingList->RemoveAt(i, true);
341 // If ImageUriData for this request id is not present in working list,
342 // remove it from the holder queue.
345 num = __pImageUriDataHolderQueue->GetCount();
346 for (int i = 0; i < num; i++)
348 // Dequeue elements one by one to check for reqId.
349 pObj = __pImageUriDataHolderQueue->Dequeue();
352 _ImageUriData* pImageUriData = dynamic_cast<_ImageUriData*>(pObj);
353 if (pImageUriData != null)
355 if (reqId == pImageUriData->GetRequestId())
357 pImageUriData->Cancel(reqId, r);
358 delete pImageUriData;
362 // if Dequeued data does not have the same reqId, Enqueue is again.
363 __pImageUriDataHolderQueue->Enqueue(*pObj);
371 SysLog(NID_MEDIA, "Could not find ReqId %ld in both queues!!", reqId);
376 _ImageUriDataFactory::GetHolderCount(void)
378 int count = __pImageUriDataHolderQueue->GetCount();
383 _ImageUriDataFactory::GetWorkerCount(void)
385 int count = __pImageUriDataWorkingList->GetCount();