6b2e2d6e8f28609d1e3b45f4e522b52c9cc69c88
[platform/framework/native/appfw.git] / src / app / FApp_MapDataControlImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file        FApp_MapDataControlImpl.cpp
20  * @brief       This is the implementation for the %_MapDataControlImpl class.
21  */
22
23 #include <typeinfo>
24 #include <new>
25 #include <unique_ptr.h>
26
27 #include <appsvc/appsvc.h>
28
29 #include <FBaseInteger.h>
30 #include <FBaseString.h>
31 #include <FBaseRtIEventArg.h>
32 #include <FAppMapDataControl.h>
33 #include <FAppIMapDataControlResponseListener.h>
34
35 #include <FBaseSysLog.h>
36
37 #include "FApp_AppControlManager.h"
38 #include "FApp_MapDataControlImpl.h"
39 #include "FApp_AppArg.h"
40
41 using namespace std;
42
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Collection;
45 using namespace Tizen::Base::Runtime;
46 using namespace Tizen::App;
47 using namespace Tizen::Io;
48
49 namespace Tizen { namespace App
50 {
51
52 static const int MAX_REQUEST_COUNT = 128;
53 static const int _MAX_ARGUMENT_SIZE = 16384; // 16KB
54
55 class _MapDataControlEventArg
56         : public IEventArg
57 {
58 public:
59                 _MapDataControlEventArg(_DataControlRequestType requestType, RequestId reqId, String providerId, String dataId,
60                                 IList* pResultValueList, bool providerResult, String* pErrorMsg)
61                         : __requestType(requestType)
62                         , __reqId(reqId)
63                         , __providerId(providerId)
64                         , __dataId(dataId)
65                         , __pResultValueList(pResultValueList)
66                         , __providerResult(providerResult)
67                         , __pErrorMsg(pErrorMsg)
68                 {
69                 }
70                 ~_MapDataControlEventArg(void)
71                 {
72                         if (__pResultValueList)
73                         {
74                                 __pResultValueList->RemoveAll(true);
75                                 delete __pResultValueList;
76                         }
77                         delete __pErrorMsg;
78                 }
79
80                 _DataControlRequestType __requestType;
81                 RequestId __reqId;
82                 String __providerId;
83                 String __dataId;
84                 IList* __pResultValueList;
85                 bool __providerResult;
86                 String* __pErrorMsg;
87 };
88
89 class _MapDataControlEvent
90         : public Event
91 {
92 protected:
93                 virtual void FireImpl(IEventListener& listener, const IEventArg& arg);
94 };
95
96 void
97 _MapDataControlEvent::FireImpl(IEventListener& listener, const IEventArg& arg)
98 {
99         const _MapDataControlEventArg* pArg = dynamic_cast<const _MapDataControlEventArg*>(&arg);
100         if (pArg != null)
101         {
102                 IMapDataControlResponseListener* pListener = dynamic_cast<IMapDataControlResponseListener*> (&listener);
103                 if (pListener != null)
104                 {
105                         switch (pArg->__requestType)
106                         {
107                         case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
108                                 pListener->OnMapDataControlGetValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
109                                                 *(pArg->__pResultValueList), pArg->__providerResult, pArg->__pErrorMsg);
110                                 break;
111                         case _DATACONTROL_REQUEST_TYPE_MAP_INSERT:
112                                 pListener->OnMapDataControlAddValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
113                                                  pArg->__providerResult, pArg->__pErrorMsg);
114                                 break;
115                         case _DATACONTROL_REQUEST_TYPE_MAP_UPDATE:
116                                 pListener->OnMapDataControlSetValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
117                                                 pArg->__providerResult, pArg->__pErrorMsg);
118                                 break;
119                         case _DATACONTROL_REQUEST_TYPE_MAP_DELETE:
120                                 pListener->OnMapDataControlRemoveValueResponseReceived(pArg->__reqId, pArg->__providerId, pArg->__dataId,
121                                                 pArg->__providerResult, pArg->__pErrorMsg);
122                                 break;
123                         default:
124                                 break;
125                         }
126                 }
127         }
128 }
129
130 // private
131 _MapDataControlImpl::_MapDataControlImpl(void)
132         : __appId(L"")
133         , __providerId(L"")
134         , __access(_DATACONTROL_ACCESS_UNDEFINED)
135         , __pPreviousListener(null)
136         , __pMapDataControlEvent(null)
137 {
138 }
139
140 _MapDataControlImpl::~_MapDataControlImpl(void)
141 {
142         delete __pMapDataControlEvent;
143 }
144
145 _MapDataControlImpl*
146 _MapDataControlImpl::GetInstance(MapDataControl& dc)
147 {
148         return dc.__pMapDataControlImpl;
149 }
150
151 const _MapDataControlImpl*
152 _MapDataControlImpl::GetInstance(const MapDataControl& dc)
153 {
154         return dc.__pMapDataControlImpl;
155 }
156
157 result
158 _MapDataControlImpl::StartMapDataControl(int type, const IList* pDataList, int* pReq)
159 {
160         result r = E_SUCCESS;
161
162         int req = -1;
163         _AppControlManager* pAppManagerImpl = _AppControlManager::GetInstance();
164
165         // Check the request count of DataControl operation
166         int count = pAppManagerImpl->GetLaunchRequestCount();
167         SysLog(NID_APP, "Current launch request count: %d", count);
168
169         SysTryReturnResult(NID_APP, count < MAX_REQUEST_COUNT, E_MAX_EXCEEDED, "The number of requests has exceeded the maximum limit.");
170
171         _AppArg* pArg = new(std::nothrow) _AppArg; // XXX: pArg will be released in _AppManagerImpl::LaunchApp().
172         SysTryReturnResult(NID_APP, pArg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
173
174         pArg->Construct(*this, static_cast <_DataControlRequestType>(type), pDataList);
175
176         if (__pMapDataControlEvent)
177         {
178                 // reqId is system-wide id because the bundle is system-wide.
179                 _AppControlManager::_RequestGuard reqObj = _AppControlManager::_RequestGuard(*pAppManagerImpl, pArg, MapDataControlCallback, __pMapDataControlEvent, -1);
180                 req = reqObj.GetRequestNumber();
181
182                 r = pAppManagerImpl->LaunchApp(__appId, pArg, req);
183                 SysTryCatch(NID_APP, r == E_SUCCESS, reqObj.Invalidate(), r, "[%s] Propgated.", GetErrorMessage(r));
184
185                 if (pReq)
186                 {
187                         *pReq = req;
188                 }
189         }
190         else
191         {
192                 r = pAppManagerImpl->LaunchApp(__appId, pArg);
193                 delete pArg;
194         }
195
196 CATCH:
197         return r;
198 }
199
200 result
201 _MapDataControlImpl::GetValue(const String& dataId, const String& key,
202                 RequestId& reqId, int pageNo, int countPerPage)
203 {
204         SysTryReturnResult(NID_APP, pageNo > 0, E_INVALID_ARG, "The specified pageNo parameter is less than 1");
205         SysTryReturnResult(NID_APP, countPerPage > 0, E_INVALID_ARG, "The specified countPerPage parameter is less than 1");
206         SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_READ) > 0, E_ILLEGAL_ACCESS,
207                         "The GetValue query is not permitted by DataControl provider.");
208
209         String* pPageNo = null;
210         String* pCountPerPage = null;
211         int id = 0;
212         result r = E_SUCCESS;
213
214         ArrayList* pArgList = new ArrayList();
215         pArgList->Construct();
216
217         pArgList->Add(*(new String(dataId)));
218         pArgList->Add(*(new String(key)));
219         long long argSize = dataId.GetLength() * sizeof(wchar_t);
220         argSize += key.GetLength() * sizeof(wchar_t);
221         SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
222                         "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
223
224         pPageNo = new (std::nothrow) String();
225         pPageNo->Append(pageNo);
226         pArgList->Add(*pPageNo);
227
228         pCountPerPage = new (std::nothrow) String();
229         pCountPerPage->Append(countPerPage);
230         pArgList->Add(*pCountPerPage);
231
232         r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_QUERY, pArgList, &id);
233         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
234
235         reqId = static_cast< RequestId >(id);
236
237         SysLog(NID_APP, "dataId: %ls, key: %ls, reqId: %d, pageNo: %d, countPerPage: %d",
238                         dataId.GetPointer(), key.GetPointer(), reqId, pageNo, countPerPage);
239
240         // fall through
241 CATCH:
242         pArgList->RemoveAll(true);
243         delete pArgList;
244
245         return r;
246 }
247
248 result
249 _MapDataControlImpl::MapDataControlCallback(void* data, _AppArg* pArg, _AppArg* pResArg, service_result_e res, int prop)
250 {
251         ArrayList* pResultList = null;
252         ArrayList* pOrigList = null;
253         String* pRequestType = null;
254         String* pResult = null;
255         String* pReqId = null;
256         String* pProviderId = null;
257         String* pDataId = null;
258         String* pErrorMessage = null;
259         String* pErrorMsg = null;
260         String* pResultCount = null;
261         String* pValue = null;
262         ArrayList* pResultValueList = null;
263         int resultCount = 0;
264         int requestType = 0;
265         int reqId = 0;
266         int providerRes = 0;
267         bool providerResult = true;
268         bundle* origBundle = null;
269         bundle* resBundle = null;
270         _MapDataControlEventArg* pEventArg = null;
271         result r = E_SUCCESS;
272
273         SysTryReturnResult(NID_APP, pResArg != null, E_INVALID_ARG, "Empty result callback.");
274         SysLog(NID_APP, "appsvc result value: %d", res);
275
276         resBundle = pResArg->GetBundle();
277         if (resBundle)
278         {
279                 _MapDataControlEvent* pMapDataControlEvent = static_cast< _MapDataControlEvent* >(data);
280
281                 if (pMapDataControlEvent != null && typeid(pMapDataControlEvent) == typeid(_MapDataControlEvent*))
282                 {
283                         const char* p = null;
284
285                         // result list
286                         pResultList = _AppArg::GetListN(resBundle, OSP_K_ARG);
287                         SysTryCatch(NID_APP, pResultList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
288
289                         pResult = dynamic_cast <String*>(pResultList->GetAt(0));
290                         SysTryCatch(NID_APP, pResult, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
291                         Integer::Parse(*pResult, providerRes);
292                         providerResult = static_cast< bool >(providerRes);
293
294                         pErrorMessage = dynamic_cast< String* >(pResultList->GetAt(1));
295                         SysTryCatch(NID_APP, pErrorMessage, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid result");
296                         pErrorMsg = new (std::nothrow) String(*pErrorMessage);
297                         SysTryCatch(NID_APP, pErrorMsg, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
298                                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
299
300                         // request info
301                         origBundle = pArg->GetBundle();
302
303                         p = appsvc_get_data(origBundle, OSP_K_DATACONTROL_REQUEST_TYPE);
304                         SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
305                         pRequestType = new (std::nothrow) String(p);
306                         SysTryCatch(NID_APP, pRequestType, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
307                                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
308                         Integer::Parse(*pRequestType, requestType);
309
310                         p = appsvc_get_data(origBundle, OSP_K_REQUEST_ID);
311                         SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
312                         pReqId = new (std::nothrow) String(p);
313                         SysTryCatch(NID_APP, pReqId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
314                                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
315                         Integer::Parse(*pReqId, reqId);
316
317                         p = appsvc_get_data(origBundle, OSP_K_DATACONTROL_PROVIDER);
318                         SysTryCatch(NID_APP, p, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
319                         pProviderId = new (std::nothrow) String(p);
320                         SysTryCatch(NID_APP, pProviderId, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
321                                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
322
323                         pOrigList = _AppArg::GetListN(origBundle, OSP_K_ARG);
324                         SysTryCatch(NID_APP, pOrigList, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
325                         pDataId = dynamic_cast <String*>(pOrigList->GetAt(0));
326                         SysTryCatch(NID_APP, pDataId, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] invalid bundle");
327
328                         SysLog(NID_APP, "result: %ld, requestType: %d, reqId: %d, providerId: %ls, dataId: %ls, errorMsg: %ls ",
329                                         providerRes, requestType, reqId, pProviderId->GetPointer(), pDataId->GetPointer(), pErrorMsg->GetPointer());
330
331                         switch (static_cast< _DataControlRequestType >(requestType))
332                         {
333                         case _DATACONTROL_REQUEST_TYPE_MAP_QUERY:
334                         {
335                                 pResultValueList = new (std::nothrow) ArrayList();
336                                 SysTryCatch(NID_APP, pResultValueList, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
337                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
338
339                                 if (providerResult == true)
340                                 {
341                                         pResultCount = dynamic_cast< String* >(pResultList->GetAt(2));
342                                         if (pResultCount == null)
343                                         {
344                                                 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
345                                                 pResultValueList->RemoveAll(true);
346                                                 delete pResultValueList;
347                                                 goto CATCH;
348                                         }
349                                         Integer::Parse(*pResultCount, resultCount);
350
351                                         int index = 3;
352                                         while (resultCount)
353                                         {
354                                                 pValue = dynamic_cast< String* >(pResultList->GetAt(index));
355                                                 if (pValue == null)
356                                                 {
357                                                         SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] invalid result");
358                                                         pResultValueList->RemoveAll(true);
359                                                         delete pResultValueList;
360                                                         goto CATCH;
361                                                 }
362
363                                                 pResultValueList->Add(*(new (std::nothrow) String(*pValue)));
364                                                 resultCount--;
365                                                 index++;
366                                         }
367                                 }
368
369                                 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_QUERY, static_cast <RequestId>(reqId),
370                                                 *pProviderId, *pDataId, pResultValueList, 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);
373
374                                 break;
375                         }
376                         case _DATACONTROL_REQUEST_TYPE_MAP_INSERT:
377                         {
378                                 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_INSERT, static_cast <RequestId>(reqId),
379                                                 *pProviderId, *pDataId, null, providerResult, pErrorMsg);
380                                 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
381                                 pMapDataControlEvent->Fire(*pEventArg);
382                                 break;
383                         }
384                         case _DATACONTROL_REQUEST_TYPE_MAP_UPDATE:
385                         {
386                                 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_UPDATE, static_cast <RequestId>(reqId),
387                                                 *pProviderId, *pDataId, null, providerResult, pErrorMsg);
388                                 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
389                                 pMapDataControlEvent->Fire(*pEventArg);
390                                 break;
391                         }
392                         case _DATACONTROL_REQUEST_TYPE_MAP_DELETE:
393                         {
394                                 pEventArg = new (std::nothrow) _MapDataControlEventArg(_DATACONTROL_REQUEST_TYPE_MAP_DELETE, static_cast <RequestId>(reqId),
395                                                 *pProviderId, *pDataId, null, providerResult, pErrorMsg);
396                                 SysTryCatch(NID_APP, pEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
397                                 pMapDataControlEvent->Fire(*pEventArg);
398                                 break;
399                         }
400                         default:
401                                 break;
402                         }
403
404                         pResultList->RemoveAll(true);
405                         delete pResultList;
406
407                         pOrigList->RemoveAll(true);
408                         delete pOrigList;
409
410                         delete pRequestType;
411                         delete pReqId;
412                         delete pProviderId;
413                 }
414         }
415
416         // Remove the request count
417         SysLog(NID_APP, "Remove a launch request: reqId: %d", reqId);
418         _AppControlManager::GetInstance()->RemoveLaunchRequest(reqId);
419
420         return E_SUCCESS;
421
422 CATCH:
423         if (pResultList)
424         {
425                 pResultList->RemoveAll(true);
426                 delete pResultList;
427         }
428
429         if (pOrigList)
430         {
431                 pOrigList->RemoveAll(true);
432                 delete pOrigList;
433         }
434
435         delete pRequestType;
436         delete pReqId;
437         delete pProviderId;
438
439         return r;
440 }
441
442 result
443 _MapDataControlImpl::AddValue(const String& dataId, const String& key,
444                 const String& value, RequestId& reqId)
445 {
446         SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
447                         "The AddValue query is not permitted by DataControl provider.");
448
449         int id = 0;
450         result r = E_SUCCESS;
451
452         ArrayList* pArgList = null;
453         pArgList = new ArrayList();
454         pArgList->Construct();
455
456         pArgList->Add(*(new String(dataId)));
457         pArgList->Add(*(new String(key)));
458         pArgList->Add(*(new String(value)));
459         long long argSize = dataId.GetLength() * sizeof(wchar_t);
460         argSize += key.GetLength() * sizeof(wchar_t);
461         argSize += value.GetLength() * sizeof(wchar_t);
462         SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
463                         "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
464
465         r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_INSERT, pArgList, &id);
466         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
467
468         reqId = static_cast< RequestId >(id);
469
470         SysLog(NID_APP, "dataId: %ls, key: %ls, value: %ls, reqId: %d",
471                         dataId.GetPointer(), key.GetPointer(), value.GetPointer(), reqId);
472
473         // fall through
474 CATCH:
475         pArgList->RemoveAll(true);
476         delete pArgList;
477
478         return r;
479 }
480
481 result
482 _MapDataControlImpl::SetValue(const String& dataId, const String& key,
483                 const String& oldValue, const String& newValue, RequestId& reqId)
484 {
485         SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
486                         "The SetValue query is not permitted by DataControl provider.");
487
488         int id = 0;
489         result r = E_SUCCESS;
490
491         ArrayList* pArgList = null;
492         pArgList = new ArrayList();
493         pArgList->Construct();
494
495         pArgList->Add(*(new String(dataId)));
496         pArgList->Add(*(new String(key)));
497         pArgList->Add(*(new String(oldValue)));
498         pArgList->Add(*(new String(newValue)));
499         long long argSize = dataId.GetLength() * sizeof(wchar_t);
500         argSize += key.GetLength() * sizeof(wchar_t);
501         argSize += oldValue.GetLength() * sizeof(wchar_t);
502         argSize += newValue.GetLength() * sizeof(wchar_t);
503         SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
504                         "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
505
506         r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_UPDATE, pArgList, &id);
507         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
508
509         reqId = static_cast< RequestId >(id);
510
511         SysLog(NID_APP, "dataId: %ls, key: %ls, oldValue: %ls, newValue: %ls, reqId: %d",
512                         dataId.GetPointer(), key.GetPointer(), oldValue.GetPointer(), newValue.GetPointer(), reqId);
513
514         // fall through
515 CATCH:
516         pArgList->RemoveAll(true);
517         delete pArgList;
518
519         return r;
520 }
521
522 result
523 _MapDataControlImpl::RemoveValue(const String& dataId, const String& key,
524                 const String& value, RequestId& reqId)
525 {
526         SysTryReturnResult(NID_APP, (__access & _DATACONTROL_ACCESS_WRITE) > 0, E_ILLEGAL_ACCESS,
527                         "The RemoveValue query is not permitted by DataControl provider.");
528
529         int id = 0;
530         result r = E_SUCCESS;
531
532         ArrayList* pArgList = null;
533         pArgList = new ArrayList();
534         pArgList->Construct();
535
536         pArgList->Add(*(new String(dataId)));
537         pArgList->Add(*(new String(key)));
538         pArgList->Add(*(new String(value)));
539         long long argSize = dataId.GetLength() * sizeof(wchar_t);
540         argSize += key.GetLength() * sizeof(wchar_t);
541         argSize += value.GetLength() * sizeof(wchar_t);
542         SysTryCatch(NID_APP, argSize <= _MAX_ARGUMENT_SIZE, r = E_MAX_EXCEEDED, E_MAX_EXCEEDED,
543                         "[E_MAX_EXCEEDED] The size of sending argument (%d) exceeds the maximum limit.", argSize);
544
545         r = StartMapDataControl(_DATACONTROL_REQUEST_TYPE_MAP_DELETE, pArgList, &id);
546         SysTryCatch(NID_APP, !IsFailed(r), , r, "[%s] Propagating to caller...", GetErrorMessage(r));
547
548         reqId = static_cast< RequestId >(id);
549
550         SysLog(NID_APP, "dataId: %ls, key: %ls, value: %ls, reqId: %d",
551                         dataId.GetPointer(), key.GetPointer(), value.GetPointer(), reqId);
552
553         // fall through
554 CATCH:
555         pArgList->RemoveAll(true);
556         delete pArgList;
557
558         return r;
559 }
560
561 result
562 _MapDataControlImpl::SetMapDataControlResponseListener(IMapDataControlResponseListener* pListener)
563 {
564         result r = E_SUCCESS;
565
566         if (__pPreviousListener != null)
567         {
568                 r =  __pMapDataControlEvent->RemoveListener(*__pPreviousListener);
569                 SysTryReturnResult(NID_APP, !IsFailed(r), E_SYSTEM, "Remove listener failed.");
570                  __pPreviousListener = null;
571         }
572
573         if (pListener != null)
574         {
575                 r =  __pMapDataControlEvent->AddListener(*pListener);
576                 if (IsFailed(r))
577                 {
578                         switch (r)
579                         {
580                         case E_OBJ_ALREADY_EXIST:
581                                 return E_SUCCESS;
582                         case E_INVALID_OPERATION:
583                                 SysLogException(NID_APP, E_SYSTEM, "[E_SYSTEM] The thread setting the listener is worker thread.");
584                                 return E_SYSTEM;
585                         default:
586                                 SysLogException(NID_APP, r, "[%s] Propagating to caller...", GetErrorMessage(r));
587                                 return r;
588                         }
589                 }
590         }
591
592         __pPreviousListener = pListener;
593
594         return E_SUCCESS;
595 }
596
597 // private
598 MapDataControl*
599 _MapDataControlImpl::CreateMapDataControl(const AppId& appId, const String& providerId, const String& access)
600 {
601         unique_ptr<MapDataControl> pDc(new (std::nothrow) MapDataControl);
602         SysTryReturn(NID_APP, pDc != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient");
603
604         _MapDataControlImpl* pDcImpl = _MapDataControlImpl::GetInstance(*pDc);
605         unique_ptr<_MapDataControlEvent> pMapDataControlEvent(new (std::nothrow) _MapDataControlEvent);
606         SysTryReturn(NID_IO, pMapDataControlEvent != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
607
608         pDcImpl->__pMapDataControlEvent = pMapDataControlEvent.release();
609         pDcImpl->__appId = appId;
610         pDcImpl->__providerId = providerId;
611
612         if (access == L"readonly")
613         {
614                 pDcImpl->__access = _DATACONTROL_ACCESS_READ;
615         }
616         else if (access == L"writeonly")
617         {
618                 pDcImpl->__access = _DATACONTROL_ACCESS_WRITE;
619         }
620         else if (access == L"readwrite")
621         {
622                 pDcImpl->__access = _DATACONTROL_ACCESS_READWRITE;
623         }
624         else
625         {
626                 pDcImpl->__access = _DATACONTROL_ACCESS_UNDEFINED;
627                 SysLog(NID_IO, "The accessibility of DataControl provider is invalid.");
628         }
629
630         return pDc.release();
631 }
632
633 }} // Tizen::App
634