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 FApp_MapDataControlImpl.cpp
20 * @brief This is the implementation for the %_MapDataControlImpl class.
25 #include <unique_ptr.h>
27 #include <appsvc/appsvc.h>
29 #include <FBaseInteger.h>
30 #include <FBaseString.h>
31 #include <FBaseRtIEventArg.h>
32 #include <FAppMapDataControl.h>
33 #include <FAppIMapDataControlResponseListener.h>
35 #include <FBaseSysLog.h>
36 #include <FBaseRtWaitingLoop.h>
38 #include "FApp_AppControlManager.h"
39 #include "FApp_MapDataControlImpl.h"
40 #include "FApp_AppArg.h"
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Runtime;
47 using namespace Tizen::App;
48 using namespace Tizen::Io;
50 namespace Tizen { namespace App
53 class _MapDataControlEventArg
57 _MapDataControlEventArg(_DataControlRequestType requestType, RequestId reqId, String providerId, String dataId,
58 IList* pResultValueList, bool providerResult, String* pErrorMsg)
59 : __requestType(requestType)
61 , __providerId(providerId)
63 , __pResultValueList(pResultValueList)
64 , __providerResult(providerResult)
65 , __pErrorMsg(pErrorMsg)
68 ~_MapDataControlEventArg(void)
70 if (__pResultValueList)
72 __pResultValueList->RemoveAll(true);
73 delete __pResultValueList;
78 _DataControlRequestType __requestType;
82 IList* __pResultValueList;
83 bool __providerResult;
87 class _MapDataControlEvent
91 virtual void FireImpl(IEventListener& listener, const IEventArg& arg);
95 _MapDataControlEvent::FireImpl(IEventListener& listener, const IEventArg& arg)
97 const _MapDataControlEventArg* pArg = dynamic_cast<const _MapDataControlEventArg*>(&arg);
100 IMapDataControlResponseListener* pListener = dynamic_cast<IMapDataControlResponseListener*> (&listener);
101 if (pListener != null)
103 switch (pArg->__requestType)
105 case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
106 pListener->OnMapDataControlGetValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
107 *(pArg->__pResultValueList), pArg->__providerResult, pArg->__pErrorMsg);
109 case _DATACONTROL_REQUEST_TYPE_MAP_INSERT:
110 pListener->OnMapDataControlAddValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
111 pArg->__providerResult, pArg->__pErrorMsg);
113 case _DATACONTROL_REQUEST_TYPE_MAP_UPDATE:
114 pListener->OnMapDataControlSetValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
115 pArg->__providerResult, pArg->__pErrorMsg);
117 case _DATACONTROL_REQUEST_TYPE_MAP_DELETE:
118 pListener->OnMapDataControlRemoveValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
119 pArg->__providerResult, pArg->__pErrorMsg);
129 _MapDataControlImpl::_MapDataControlImpl(void)
132 , __access(_DATACONTROL_ACCESS_UNDEFINED)
133 , __pPreviousListener(null)
134 , __pMapDataControlEvent(null)
138 _MapDataControlImpl::~_MapDataControlImpl(void)
140 delete __pMapDataControlEvent;
144 _MapDataControlImpl::GetInstance(MapDataControl& dc)
146 return dc.__pMapDataControlImpl;
149 const _MapDataControlImpl*
150 _MapDataControlImpl::GetInstance(const MapDataControl& dc)
152 return dc.__pMapDataControlImpl;
156 _MapDataControlImpl::StartMapDataControl(int type, const IList* pDataList, int* pReq)
158 result r = E_SUCCESS;
160 _AppArg* pArg = new(std::nothrow) _AppArg; // XXX: pArg will be released in _AppManagerImpl::LaunchApp().
161 SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
163 pArg->Construct(*this, static_cast <_DataControlRequestType>(type), pDataList);
165 _AppControlManager* pAppManagerImpl = _AppControlManager::GetInstance();
168 // Proceeds the previous request
169 WaitingLoop* pLoop = WaitingLoop::GetInstance();
172 if (__pMapDataControlEvent)
174 // reqId is system-wide id because the bundle is system-wide.
175 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pAppManagerImpl, pArg, MapDataControlCallback, __pMapDataControlEvent, -1);
176 req = reqObj.GetRequestNumber();
178 r = pAppManagerImpl->LaunchApp(__appId, pArg, req);
179 SysTryCatch(NID_APP, r == E_SUCCESS, reqObj.Invalidate(), r, "[%s] Propgated.", GetErrorMessage(r));
188 r = pAppManagerImpl->LaunchApp(__appId, pArg);
197 _MapDataControlImpl::GetValue(const String& dataId, const String& key,
198 RequestId& reqId, int pageNo, int countPerPage)
200 SysTryReturnResult(NID_APP, pageNo > 0, E_INVALID_ARG, "The specified pageNo parameter is less than 1");
201 SysTryReturnResult(NID_APP, countPerPage > 0, E_INVALID_ARG, "The specified countPerPage parameter is less than 1");
202 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_READ) > 0, E_ILLEGAL_ACCESS,
203 "The GetValue query is not permitted by DataControl provider.");
206 result r = E_SUCCESS;
208 ArrayList* pArgList = null;
209 pArgList = new ArrayList();
210 pArgList->Construct();
212 pArgList->Add(*(new String(dataId)));
213 pArgList->Add(*(new String(key)));
215 String* pPageNo = new String();
216 pPageNo->Append(pageNo);
217 pArgList->Add(*pPageNo);
219 String* pCountPerPage = new String();
220 pCountPerPage->Append(countPerPage);
221 pArgList->Add(*pCountPerPage);
223 r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_QUERY, pArgList, &id);
224 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
226 reqId = static_cast< RequestId >(id);
228 SysLog(NID_APP, "dataId: %ls, key: %ls, reqId: %d, pageNo: %d, countPerPage: %d",
229 dataId.GetPointer(), key.GetPointer(), reqId, pageNo, countPerPage);
233 pArgList->RemoveAll(true);
240 _MapDataControlImpl::MapDataControlCallback(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop)
242 ArrayList* pResultList = null;
243 ArrayList* pOrigList = null;
244 String* pRequestType = null;
245 String* pResult = null;
246 String* pReqId = null;
247 String* pProviderId = null;
248 String* pDataId = null;
249 String* pErrorMessage = null;
250 String* pErrorMsg = null;
251 String* pResultCount = null;
252 String* pValue = null;
253 ArrayList* pResultValueList = null;
258 bool providerResult = true;
259 bundle* origBundle = null;
260 bundle* resBundle = null;
261 _MapDataControlEventArg* pEventArg = null;
262 result r = E_SUCCESS;
264 SysTryReturnResult(NID_APP, pResArg != null, E_INVALID_ARG, "Empty result callback.");
265 SysLog(NID_APP, "appsvc result value: %d", res);
267 resBundle = pResArg->GetBundle();
270 _MapDataControlEvent* pMapDataControlEvent = static_cast< _MapDataControlEvent* >(data);
272 if (pMapDataControlEvent != null && typeid(pMapDataControlEvent) == typeid(_MapDataControlEvent*))
274 const char* p = null;
277 pResultList = _AppArg::GetListN(resBundle, OSP_K_ARG);
278 SysTryCatch(NID_APP, pResultList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
280 pResult = dynamic_cast <String*>(pResultList->GetAt(0));
281 SysTryCatch(NID_APP, pResult, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
282 Integer::Parse(*pResult, providerRes);
283 providerResult = static_cast< bool >(providerRes);
285 pErrorMessage = dynamic_cast< String* >(pResultList->GetAt(1));
286 SysTryCatch(NID_APP, pErrorMessage, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
287 pErrorMsg = new (std::nothrow) String(*pErrorMessage);
288 SysTryCatch(NID_APP, pErrorMsg, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
289 "[E_OUT_OF_MEMORY] The memory is insufficient.");
292 origBundle = pArg->GetBundle();
294 p = appsvc_get_data(origBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
295 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
296 pRequestType = new (std::nothrow) String(p);
297 SysTryCatch(NID_APP, pRequestType, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
298 "[E_OUT_OF_MEMORY] The memory is insufficient.");
299 Integer::Parse(*pRequestType, requestType);
301 p = appsvc_get_data(origBundle, OSP_K_REQUEST_ID);
302 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
303 pReqId = new (std::nothrow) String(p);
304 SysTryCatch(NID_APP, pReqId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
305 "[E_OUT_OF_MEMORY] The memory is insufficient.");
306 Integer::Parse(*pReqId, reqId);
308 p = appsvc_get_data(origBundle, OSP_K_DATACONTROL_PROVIDER);
309 SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
310 pProviderId = new (std::nothrow) String(p);
311 SysTryCatch(NID_APP, pProviderId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
312 "[E_OUT_OF_MEMORY] The memory is insufficient.");
314 pOrigList = _AppArg::GetListN(origBundle, OSP_K_ARG);
315 SysTryCatch(NID_APP, pOrigList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
316 pDataId = dynamic_cast <String*>(pOrigList->GetAt(0));
317 SysTryCatch(NID_APP, pDataId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
319 SysLog(NID_APP, "result: %ld, requestType: %d, reqId: %d, providerId: %ls, dataId: %ls, errorMsg: %ls ",
320 providerRes, requestType, reqId, pProviderId->GetPointer(), pDataId->GetPointer(), pErrorMsg->GetPointer());
322 switch (static_cast< _DataControlRequestType >(requestType))
324 case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
326 pResultValueList = new (std::nothrow) ArrayList();
327 SysTryCatch(NID_APP, pResultValueList, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
328 "[E_OUT_OF_MEMORY] The memory is insufficient.");
330 if (providerResult == true)
332 pResultCount = dynamic_cast< String* >(pResultList->GetAt(2));
333 if (pResultCount == null)
335 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
336 pResultValueList->RemoveAll(true);
337 delete pResultValueList;
340 Integer::Parse(*pResultCount, resultCount);
345 pValue = dynamic_cast< String* >(pResultList->GetAt(index));
348 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
349 pResultValueList->RemoveAll(true);
350 delete pResultValueList;
354 pResultValueList->Add(*(new (std::nothrow) String(*pValue)));
360 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_QUERY, static_cast <RequestId>(reqId),
361 *pProviderId, *pDataId, pResultValueList, providerResult, pErrorMsg);
362 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
363 pMapDataControlEvent->Fire(*pEventArg);
367 case _DATACONTROL_REQUEST_TYPE_MAP_INSERT:
369 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_INSERT, static_cast <RequestId>(reqId),
370 *pProviderId, *pDataId, null, providerResult, pErrorMsg);
371 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
372 pMapDataControlEvent->Fire(*pEventArg);
375 case _DATACONTROL_REQUEST_TYPE_MAP_UPDATE:
377 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_UPDATE, static_cast <RequestId>(reqId),
378 *pProviderId, *pDataId, null, providerResult, pErrorMsg);
379 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
380 pMapDataControlEvent->Fire(*pEventArg);
383 case _DATACONTROL_REQUEST_TYPE_MAP_DELETE:
385 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_DELETE, static_cast <RequestId>(reqId),
386 *pProviderId, *pDataId, null, providerResult, pErrorMsg);
387 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
388 pMapDataControlEvent->Fire(*pEventArg);
395 pResultList->RemoveAll(true);
398 pOrigList->RemoveAll(true);
412 pResultList->RemoveAll(true);
418 pOrigList->RemoveAll(true);
430 _MapDataControlImpl::AddValue(const String& dataId, const String& key,
431 const String& value, RequestId& reqId)
433 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
434 "The AddValue query is not permitted by DataControl provider.");
437 result r = E_SUCCESS;
439 ArrayList* pArgList = null;
440 pArgList = new ArrayList();
441 pArgList->Construct();
443 pArgList->Add(*(new String(dataId)));
444 pArgList->Add(*(new String(key)));
445 pArgList->Add(*(new String(value)));
447 r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_INSERT, pArgList, &id);
448 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
450 reqId = static_cast< RequestId >(id);
452 SysLog(NID_APP, "dataId: %ls, key: %ls, value: %ls, reqId: %d",
453 dataId.GetPointer(), key.GetPointer(), value.GetPointer(), reqId);
457 pArgList->RemoveAll(true);
464 _MapDataControlImpl::SetValue(const String& dataId, const String& key,
465 const String& oldValue, const String& newValue, RequestId& reqId)
467 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
468 "The SetValue query is not permitted by DataControl provider.");
471 result r = E_SUCCESS;
473 ArrayList* pArgList = null;
474 pArgList = new ArrayList();
475 pArgList->Construct();
477 pArgList->Add(*(new String(dataId)));
478 pArgList->Add(*(new String(key)));
479 pArgList->Add(*(new String(oldValue)));
480 pArgList->Add(*(new String(newValue)));
482 r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_UPDATE, pArgList, &id);
483 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
485 reqId = static_cast< RequestId >(id);
487 SysLog(NID_APP, "dataId: %ls, key: %ls, oldValue: %ls, newValue: %ls, reqId: %d",
488 dataId.GetPointer(), key.GetPointer(), oldValue.GetPointer(), newValue.GetPointer(), reqId);
492 pArgList->RemoveAll(true);
499 _MapDataControlImpl::RemoveValue(const String& dataId, const String& key,
500 const String& value, RequestId& reqId)
502 SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
503 "The RemoveValue query is not permitted by DataControl provider.");
506 result r = E_SUCCESS;
508 ArrayList* pArgList = null;
509 pArgList = new ArrayList();
510 pArgList->Construct();
512 pArgList->Add(*(new String(dataId)));
513 pArgList->Add(*(new String(key)));
514 pArgList->Add(*(new String(value)));
516 r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_DELETE, pArgList, &id);
517 SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
519 reqId = static_cast< RequestId >(id);
521 SysLog(NID_APP, "dataId: %ls, key: %ls, value: %ls, reqId: %d",
522 dataId.GetPointer(), key.GetPointer(), value.GetPointer(), reqId);
526 pArgList->RemoveAll(true);
533 _MapDataControlImpl::SetMapDataControlResponseListener(IMapDataControlResponseListener* pListener)
535 result r = E_SUCCESS;
537 if (__pPreviousListener != null)
539 r = __pMapDataControlEvent->RemoveListener(*__pPreviousListener);
540 SysTryReturnResult(NID_APP, !IsFailed(r), E_SYSTEM, "Remove listener failed.");
541 __pPreviousListener = null;
544 if (pListener != null)
546 r = __pMapDataControlEvent->AddListener(*pListener);
551 case E_OBJ_ALREADY_EXIST:
553 case E_INVALID_OPERATION:
554 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] The thread setting the listener is worker thread.");
557 SysLogException(NID_APP, r, "[%s] Propagating to caller...", GetErrorMessage(r));
563 __pPreviousListener = pListener;
570 _MapDataControlImpl::CreateMapDataControl(const AppId& appId, const String& providerId, const String& access)
572 unique_ptr<MapDataControl> pDc(new (std::nothrow) MapDataControl);
573 SysTryReturn(NID_APP, pDc != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient");
575 _MapDataControlImpl* pDcImpl = _MapDataControlImpl::GetInstance(*pDc);
576 unique_ptr<_MapDataControlEvent> pMapDataControlEvent(new (std::nothrow) _MapDataControlEvent);
577 SysTryReturn(NID_IO, pMapDataControlEvent != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
579 pDcImpl->__pMapDataControlEvent = pMapDataControlEvent.release();
580 pDcImpl->__appId = appId;
581 pDcImpl->__providerId = providerId;
583 if (access == L"readonly")
585 pDcImpl->__access = _DATACONTROL_ACCESS_READ;
587 else if (access == L"writeonly")
589 pDcImpl->__access = _DATACONTROL_ACCESS_WRITE;
591 else if (access == L"readwrite")
593 pDcImpl->__access = _DATACONTROL_ACCESS_READWRITE;
597 pDcImpl->__access = _DATACONTROL_ACCESS_UNDEFINED;
598 SysLog(NID_IO, "The accessibility of DataControl provider is invalid.");
601 return pDc.release();