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