fix core contact app-control
[framework/osp/app-controls.git] / src / contact-app-control / ContactAppControlDllEntry.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         ContactAppControlDllEntry.cpp
20  * @brief       This is the implementation for the ContactAppControlDllEntry.cpp class.
21  */
22
23 #include <unique_ptr.h>
24 #include <appsvc/appsvc.h>
25 #include <contacts.h>
26
27 #include <FBaseSysLog.h>
28 #include <FBaseInteger.h>
29 #include <FBaseUtilStringUtil.h>
30 #include <FAppAppControl.h>
31 #include <FBaseColHashMap.h>
32 #include <FBaseColAllElementsDeleter.h>
33
34 #include <FBase_StringConverter.h>
35 #include <FIo_FileImpl.h>
36 #include <FSys_EnvironmentImpl.h>
37 #include <FApp_AppControlManager.h>
38 #include <FApp_AppMessageImpl.h>
39 #include <FApp_Aul.h>
40 #include <FApp_AppArg.h>
41
42 using namespace Tizen::App;
43 using namespace Tizen::Base;
44 using namespace Tizen::Base::Utility;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Io;
47 using namespace Tizen::System;
48 using namespace Tizen::Social;
49
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53
54 static char PICK_OP_SEL_MODE_KEY[] = "selectionMode";
55 static char PICK_OP_RET_KEY_RET_TYPE[] = "returnType";
56 static char PICK_OP_RET_KEY_VALUE[] = "value";
57
58 static char EDIT_OP_KEY_CONTACT_ID[] = "contactId";
59 static char EDIT_OP_KEY_PHONE[] = "phone";
60 static char EDIT_OP_KEY_EMAIL[] = "email";
61 static char EDIT_OP_KEY_URL[] = "url";
62
63 static char VIEW_OP_KEY_VIEW_TYPE[] = "viewType";
64 static char VIEW_OP_KEY_VCARD_PATH[] = "path";
65 static char VIEW_OP_KEY_CONTACT_ID[] = "contactId";
66
67 static char VIEW_OP_VALUE_CONTACT[] = "contact";
68 static char VIEW_OP_VALUE_VCARD[] = "vcf";
69 static int  VIEW_OP_VALUE_LENGTH_MAX = 7;
70
71 static char PICK_OP_SEL_MODE_VALUE_SINGLE[] = "single";
72 static char PICK_OP_SEL_MODE_VALUE_MULTIPLE[] = "multiple";
73
74 static char PICK_OP_RET_VALUE_PHONE[] = "phone";
75 static char PICK_OP_RET_VALUE_EMAIL[] = "email";
76 static char PICK_OP_RET_VALUE_VCARD[] = "vcard";
77 static char PICK_OP_RET_VALUE_CONTACT_ID[] = "contactId";
78
79 static int PICK_OP_SEL_MODE_VALUE_LENGTH_MAX = 8;
80 static int PICK_OP_RET_VALUE_LENGTH_MAX = 10;
81
82 static char ADD_OP_KEY_NUMBER[] = "phone";
83 static char ADD_OP_KEY_EMAIL[] = "email";
84 static char ADD_OP_KEY_URL[] = "url";
85
86
87 static char CORE_OP_KEY_TYPE[] = "type";
88 static char CORE_OP_KEY_PERSON_ID[] = "ct_person_id";
89 static char CORE_OP_KEY_NUMBER[] = "ct_num";
90 static char CORE_OP_KEY_EMAIL[] = "ct_email";
91 static char CORE_OP_KEY_URL[] = "ct_web";
92 static char CORE_OP_KEY_VCARD[] = "ct_vcard";
93
94 static char CORE_OP_VALUE_EDIT_PERSON[] = "11";
95 static char CORE_OP_VALUE_EDIT_PERSON_BY_SEL[] = "20";
96
97 static char CORE_OP_VALUE_VIEW_PERSON[] = "0";
98
99 // PICK
100 static char CORE_OP_VALUE_PICK_PERSON_ID[] = "11";
101 static char CORE_OP_VALUE_PICK_NUMBER[] = "12";
102 static char CORE_OP_VALUE_PICK_EMAIL[] = "13";
103 static char CORE_OP_VALUE_PICK_VCARD[] = "14";
104 static char CORE_OP_VALUE_PICK_PERSON_ID_LIST[] = "31";
105 static char CORE_OP_VALUE_PICK_NUMBER_LIST[] = "32";
106 static char CORE_OP_VALUE_PICK_EMAIL_LIST[] = "33";
107
108 static char CORE_OP_VALUE_ADD_CONTACT[] = "21";
109
110 static char CORE_RESULT_TYPE_KEY_NUMBER[] = "num_id";
111 static char CORE_RESULT_TYPE_KEY_NUMBER_LIST[] = "num_id_list";
112 static char CORE_RESULT_TYPE_KEY_EMAIL[] = "email_id";
113 static char CORE_RESULT_TYPE_KEY_EMAIL_LIST[] = "email_id_list";
114 static char CORE_RESULT_TYPE_KEY_PERSON[] = "person_id";
115 static char CORE_RESULT_TYPE_KEY_PERSON_LIST[] = "person_id_list";
116 static char CORE_RESULT_TYPE_KEY_VCARD[] = "vcard";
117
118 static const wchar_t CONTACT_ITEM_TYPE[] = L"http://tizen.org/appcontrol/data/social/item_type";
119 static const wchar_t CONTACT_ITEM_ID[] = L"http://tizen.org/appcontrol/data/social/item_id";
120 static const wchar_t CONTACT_RESULT_TYPE[] = L"http://tizen.org/appcontrol/data/social/result_type";
121 static const wchar_t SELECTION_MODE[] = L"http://tizen.org/appcontrol/data/selection_mode";
122
123
124 result _OSP_EXPORT_ StartAppControl(int req, const String&, const String&, const String*, const String*, const IMap*);
125 result _OSP_EXPORT_ TerminateAppControl(int req);
126 void OnAppControlResult(void*, int, service_result_e, void*);
127 void OnAppControlResultTizen(void*, int, service_result_e, void*);
128 void OnAppControlResultLegacy(void*, int, service_result_e, void*);
129
130 static int __req = -1;
131 static int __processId = -1;
132
133 static const char __allowedAppControlLegacyPickTable[][2][96] =
134 {
135         {"osp.appcontrol.CONTACT", "osp.appcontrol.operation.PICK"},
136         {"osp.appcontrol.provider.contact", "osp.appcontrol.operation.pick"},
137         {"tizen.contacts", "http://tizen.org/appcontrol/operation/pick"},
138 };
139
140
141 static const char __allowedAppControlPickTable[][2][96] =
142 {
143         {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/pick"},
144 };
145
146 static const char __allowedAppControlLegacyAddTable[][2][96] =
147 {
148         {"osp.appcontrol.CONTACT", "osp.appcontrol.operation.ADD"},
149         {"osp.appcontrol.provider.contact", "osp.appcontrol.operation.add"},
150         {"tizen.contacts", "http://tizen.org/appcontrol/operation/add"},
151 };
152
153
154 static const char __allowedAppControlAddTable[][2][96] =
155 {
156         {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/add"},
157 };
158
159 static const char __allowedAppControlLegacyEditTable[][2][96] =
160 {
161         {"osp.appcontrol.CONTACT", "osp.appcontrol.operation.EDIT"},
162         {"osp.appcontrol.provider.contact", "osp.appcontrol.operation.edit"},
163         {"tizen.contacts", "http://tizen.org/appcontrol/operation/edit"},
164 };
165
166
167 static const char __allowedAppControlEditTable[][2][96] =
168 {
169         {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/edit"},
170 };
171
172 static const char __allowedAppControlLegacyViewTable[][2][96] =
173 {
174         {"osp.appcontrol.CONTACT", "osp.appcontrol.operation.VIEW"},
175         {"osp.appcontrol.provider.contact", "osp.appcontrol.operation.view"},
176         {"tizen.contacts", "http://tizen.org/appcontrol/operation/view"},
177 };
178
179
180 static const char __allowedAppControlViewTable[][2][96] =
181 {
182         {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/view"},
183 };
184
185 static const char __allowedAppControlChooseTable[][2][96] =
186 {
187         {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/choose"},
188 };
189
190
191 class ScopedConnection
192 {
193 public:
194         ScopedConnection(void)
195         : __connected(false)
196         {
197                 int ret = contacts_connect2();
198                 if (ret == CONTACTS_ERROR_NONE)
199                 {
200                         __connected = true;
201                 }
202         }
203
204         ~ScopedConnection(void)
205         {
206                 if (__connected)
207                 {
208                         contacts_disconnect2();
209                 }
210         }
211
212         bool IsConnected(void) const
213         {
214                 return __connected;
215         }
216
217 private:
218         bool __connected;
219 };
220
221
222 class ScopedHandle
223 {
224 public:
225         ScopedHandle(contacts_record_h handle)
226         : __handle(handle)
227         {
228         }
229
230         ~ScopedHandle(void)
231         {
232                 if (__handle != null)
233                 {
234                         contacts_record_destroy(__handle, true);
235                 }
236         }
237
238         contacts_record_h Get(void)
239         {
240                 return __handle;
241         }
242
243         contacts_record_h Release(void)
244         {
245                 contacts_record_h handle = __handle;
246                 __handle = null;
247
248                 return handle;
249         }
250
251 private:
252         contacts_record_h __handle;
253 };
254
255 class ScopedList
256 {
257 public:
258         ScopedList(contacts_list_h handle)
259         : __handle(handle)
260         {
261         }
262
263         ~ScopedList(void)
264         {
265                 if (__handle != null)
266                 {
267                         contacts_list_destroy(__handle, true);
268                 }
269         }
270
271         contacts_list_h Get(void)
272         {
273                 return __handle;
274         }
275
276 private:
277         contacts_list_h __handle;
278 };
279
280 class ScopedFilter
281 {
282 public:
283         ScopedFilter(contacts_filter_h filter)
284         : __filter(filter)
285         {
286         }
287
288         ~ScopedFilter(void)
289         {
290                 if (__filter != null)
291                 {
292                         contacts_filter_destroy(__filter);
293                 }
294         }
295
296         contacts_filter_h Get(void)
297         {
298                 return __filter;
299         }
300
301 private:
302         contacts_filter_h __filter;
303 };
304
305 class ScopedQuery
306 {
307 public:
308         ScopedQuery(contacts_query_h query)
309         : __query(query)
310         {
311         }
312
313         ~ScopedQuery(void)
314         {
315                 if (__query != null)
316                 {
317                         contacts_query_destroy(__query);
318                 }
319         }
320
321         contacts_query_h Get(void)
322         {
323                 return __query;
324         }
325
326 private:
327         contacts_query_h __query;
328 };
329
330 result
331 StartAppControl(int req, const String& aId, const String& oId, const String* pUri, const String* pMime, const IMap* pMap)
332 {
333         SysLog(NID_APP, "StartAppControl: Entry to Contact AppControl");
334
335         result r = E_SUCCESS;
336
337         const bool isLegacyContactPick = _AppControlManager::IsAllowedAppControl(__allowedAppControlLegacyPickTable, 3, aId, oId);
338         const bool isContactPick = _AppControlManager::IsAllowedAppControl(__allowedAppControlPickTable, 1, aId, oId);
339         const bool isLegacyContactAdd = _AppControlManager::IsAllowedAppControl(__allowedAppControlLegacyAddTable, 3, aId, oId);
340         const bool isContactAdd = _AppControlManager::IsAllowedAppControl(__allowedAppControlAddTable, 1, aId, oId);
341         const bool isLegacyContactEdit = _AppControlManager::IsAllowedAppControl(__allowedAppControlLegacyEditTable, 3, aId, oId);
342         const bool isContactEdit = _AppControlManager::IsAllowedAppControl(__allowedAppControlEditTable, 1, aId, oId);
343         const bool isLegacyContactView = _AppControlManager::IsAllowedAppControl(__allowedAppControlLegacyViewTable, 3, aId, oId);
344         const bool isContactView = _AppControlManager::IsAllowedAppControl(__allowedAppControlViewTable, 1, aId, oId);
345         const bool isContactChoose = _AppControlManager::IsAllowedAppControl(__allowedAppControlChooseTable, 1, aId, oId);
346
347         SysTryReturnResult(NID_APP, isLegacyContactPick || isContactPick || isLegacyContactAdd || isContactAdd || isLegacyContactEdit || isContactEdit || isLegacyContactView || isContactView || isContactChoose, E_SYSTEM, "Invalid AppControl entry for (%ls, %ls).", aId.GetPointer(), oId.GetPointer());
348
349         _AppMessageImpl msg;
350         msg.AddData(pMap);
351
352         AppSvcResFn pCb = NULL;
353
354         String providerAppId;
355         String operation;
356         String uri;
357         const String* pActualUri = pUri;
358         const char* pBuf = null;
359
360         if (isContactAdd || isLegacyContactAdd)
361         {
362                 providerAppId = L"tizen.contact_detail";
363                 operation = L"http://tizen.org/appcontrol/operation/social/add";
364
365                 if (isLegacyContactAdd)
366                 {
367                         msg.AddData(CONTACT_ITEM_TYPE, L"contact");
368
369                         pBuf = appsvc_get_data(msg.GetBundle(), "phone");
370                         if (pBuf != null)
371                         {
372                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/phone", String(pBuf));
373                         }
374
375                         pBuf = appsvc_get_data(msg.GetBundle(), "email");
376                         if (pBuf != null)
377                         {
378                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/email", String(pBuf));
379                         }
380
381                         pBuf = appsvc_get_data(msg.GetBundle(), "url");
382                         if (pBuf != null)
383                         {
384                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/url", String(pBuf));
385                         }
386                 }
387                 else
388                 {
389                         pCb = OnAppControlResultTizen;
390                 }
391         }
392         else if (isContactEdit || isLegacyContactEdit)
393         {
394                 providerAppId = L"tizen.contact_detail";
395
396                 if (isLegacyContactEdit)
397                 {
398                         msg.AddData(CONTACT_ITEM_TYPE, L"person");
399
400                         pBuf = appsvc_get_data(msg.GetBundle(), EDIT_OP_KEY_CONTACT_ID);
401                         if (pBuf != null)
402                         {
403                                 operation = L"http://tizen.org/appcontrol/operation/social/edit";
404
405                                 int contactId = atoi(pBuf);
406                                 int personId = -1;
407
408                                 ScopedConnection conn;
409                                 if (conn.IsConnected())
410                                 {
411                                         contacts_record_h contactHandle = null;
412                                         int ret = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &contactHandle);
413                                         if (ret == CONTACTS_ERROR_NONE)
414                                         {
415                                                 contacts_record_get_int(contactHandle, _contacts_simple_contact.person_id, &personId);
416                                                 contacts_record_destroy(contactHandle, true);
417                                         }
418                                 }
419
420                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/item_id", Integer::ToString(personId));
421                         }
422                         else
423                         {
424                                 operation = L"http://tizen.org/appcontrol/operation/social/choose";
425                         }
426
427                         pBuf = appsvc_get_data(msg.GetBundle(), "phone");
428                         if (pBuf != null)
429                         {
430                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/phone", String(pBuf));
431                         }
432
433                         pBuf = appsvc_get_data(msg.GetBundle(), "email");
434                         if (pBuf != null)
435                         {
436                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/email", String(pBuf));
437                         }
438
439                         pBuf = appsvc_get_data(msg.GetBundle(), "url");
440                         if (pBuf != null)
441                         {
442                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/url", String(pBuf));
443                         }
444                 }
445                 else
446                 {
447                         operation = L"http://tizen.org/appcontrol/operation/social/edit";
448                 }
449         }
450         else if (isContactView || isLegacyContactView)
451         {
452
453                 if (pUri == null)
454                 {
455                         const String& path = msg.GetValue(L"path");
456                         if (!path.IsEmpty())
457                         {
458                                 uri = path;
459                                 pActualUri = &uri;
460                         }
461                 }
462
463                 if (pActualUri)
464                 {
465                         providerAppId = L"tizen.contact_viewer";
466                         operation = L"http://tizen.org/appcontrol/operation/view";
467                 }
468                 else
469                 {
470                         providerAppId = L"tizen.contact_detail";
471                         operation = L"http://tizen.org/appcontrol/operation/social/view";
472                         msg.AddData(CONTACT_ITEM_TYPE, L"person");
473
474                         pBuf = appsvc_get_data(msg.GetBundle(), "contactId");
475                         if (pBuf != null)
476                         {
477                                 int contactId = atoi(pBuf);
478                                 int personId = -1;
479
480                                 ScopedConnection conn;
481                                 if (conn.IsConnected())
482                                 {
483                                         contacts_record_h contactHandle = null;
484                                         int ret = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &contactHandle);
485                                         if (ret == CONTACTS_ERROR_NONE)
486                                         {
487                                                 contacts_record_get_int(contactHandle, _contacts_simple_contact.person_id, &personId);
488                                                 contacts_record_destroy(contactHandle, true);
489                                         }
490                                 }
491
492                                 msg.AddData(L"http://tizen.org/appcontrol/data/social/item_id", Integer::ToString(personId));
493                         }
494                 }
495         }
496         else if (isContactPick || isLegacyContactPick)
497         {
498                 providerAppId = L"tizen.contact_list";
499                 operation = L"http://tizen.org/appcontrol/operation/social/pick";
500
501                 if (isLegacyContactPick)
502                 {
503                         msg.AddData(CONTACT_ITEM_TYPE, L"person");
504
505                         const String& mode = msg.GetValue(L"selectionMode");
506                         if (!mode.IsEmpty())
507                         {
508                                 msg.AddData(SELECTION_MODE, mode);
509                                 msg.RemoveData(L"selectionMode");
510                         }
511
512                         const String& retType = msg.GetValue(L"returnType");
513                         if (!retType.IsEmpty())
514                         {
515                                 if (retType == L"contactId")
516                                 {
517                                         msg.AddData(CONTACT_RESULT_TYPE, L"item_id");
518                                 }
519                                 else
520                                 {
521                                         msg.AddData(CONTACT_RESULT_TYPE, retType);
522                                 }
523
524                                 msg.RemoveData(L"returnType");
525                         }
526
527                         pCb = OnAppControlResultLegacy;
528                 }
529                 else
530                 {
531                         pCb = OnAppControlResultTizen;
532                 }
533         }
534         else if (isContactChoose)
535         {
536                 providerAppId = L"tizen.contact_list";
537                 operation = L"http://tizen.org/appcontrol/operation/social/choose";
538                 pCb = OnAppControlResultTizen;
539         }
540
541         const String& package = _AppControlManager::GetAliasAppId(providerAppId);
542
543         __processId = _AppControlManager::GetInstance()->Launch(msg, package, operation, pActualUri, pMime, pCb, 0);
544         SysTryReturnResult(NID_APP, __processId >= 0, E_SYSTEM, "StartAppControl: Launching Contact AppControl is failed.");
545         __req = req;
546
547         r = E_SUCCESS;
548         SysLog(NID_APP, "StartAppControl: Launching Contact AppControl succeeded");
549
550         return r;
551 }
552
553 result
554 TerminateAppControl(int req)
555 {
556         if (__processId >= 0)
557         {
558                 _Aul::TerminateApplicationByPid(__processId);           
559         }
560         return E_SUCCESS;
561 }
562
563 void
564 OnAppControlResultTizen(void* b, int requestCode, service_result_e res, void* userData)
565 {
566         result r = E_SYSTEM;
567         bundle* pBundle = static_cast<bundle*>(b);
568
569         HashMap* pResult = new (std::nothrow) HashMap();
570         SysTryCatch(NID_APP, pResult != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
571
572         r = pResult->Construct();
573
574         _AppArg::SetArgMap(pBundle, pResult);
575
576         _AppControlManager::GetInstance()->FinishAppControl(__req, res, pResult);
577
578 CATCH:
579         __req = -1;
580 }
581
582 void
583 OnAppControlResultLegacy(void* b, int requestCode, service_result_e res, void* userData)
584 {
585         result r = E_SYSTEM;
586         bundle* pBundle = static_cast<bundle*>(b);
587
588         HashMap* pResult = new (std::nothrow) HashMap();
589         SysTryCatch(NID_APP, pResult != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
590
591         r = pResult->Construct();
592
593         switch (res)
594         {
595         case SERVICE_RESULT_SUCCEEDED:
596                 {
597                 _AppArg::SetArgMap(pBundle, pResult);
598
599                 ArrayList* pList = static_cast<ArrayList*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/social/phone")));
600                 if (pList != null)
601                 {
602                         bool isFirst = true;
603                         String retValue;
604
605                         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
606                         SysTryCatch(NID_APP, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
607
608                         while (pEnum->MoveNext() == E_SUCCESS)
609                         {
610                                 String* pPhoneNumber = static_cast<String*>(pEnum->GetCurrent()); 
611
612                                 if (!isFirst)
613                                 {
614                                         retValue.Append(L";");  
615                                 }
616                                 else
617                                 {
618                                         isFirst = false;
619                                 }
620
621                                 retValue.Append(*pPhoneNumber); 
622                         }
623
624                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_RET_TYPE), new (std::nothrow) String(PICK_OP_RET_VALUE_PHONE));
625                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_VALUE), new (std::nothrow) String(retValue));
626                 }
627
628                 pList = static_cast<ArrayList*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/social/email")));
629                 if (pList != null)
630                 {
631                         bool isFirst = true;
632                         String retValue;
633
634                         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
635                         SysTryCatch(NID_APP, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
636
637                         while (pEnum->MoveNext() == E_SUCCESS)
638                         {
639                                 String* pEmail = static_cast<String*>(pEnum->GetCurrent()); 
640
641                                 if (!isFirst)
642                                 {
643                                         retValue.Append(L";");  
644                                 }
645                                 else
646                                 {
647                                         isFirst = false;
648                                 }
649
650                                 retValue.Append(*pEmail);       
651                         }
652
653                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_RET_TYPE), new (std::nothrow) String(PICK_OP_RET_VALUE_EMAIL));
654                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_VALUE), new (std::nothrow) String(retValue));
655                 }
656
657                 String* pString = dynamic_cast<String*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/path")));
658                 if (pString != null)
659                 {
660                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_RET_TYPE), new (std::nothrow) String(PICK_OP_RET_VALUE_VCARD));
661                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_VALUE), new (std::nothrow) String(*pString));
662                 }
663                 else
664                 {
665                         String* pString = static_cast<String*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/path")));
666                         if (pString != null)
667                         {
668                                 pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_RET_TYPE), new (std::nothrow) String(PICK_OP_RET_VALUE_VCARD));
669                                 pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_VALUE), new (std::nothrow) String(*pString));
670                         }
671                 }
672
673                 pList = static_cast<ArrayList*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/social/item_id")));
674                 if (pList != null)
675                 {
676                         bool isFirst = true;
677                         int contactId = 0;
678                         int id = 0;
679                         String retValue;
680
681                         std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
682                         SysTryCatch(NID_APP, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
683
684                         ScopedConnection conn;
685                         if (conn.IsConnected())
686                         {
687                                 unsigned int simple_contact_projection[] = {
688                                         _contacts_simple_contact.id,
689                                         _contacts_simple_contact.address_book_id,
690                                 };
691
692
693                                 while (pEnum->MoveNext() == E_SUCCESS)
694                                 {
695                                         String* pPersonId = static_cast<String*>(pEnum->GetCurrent()); 
696                                         Integer::Decode(*pPersonId, id);
697
698                                         contacts_filter_h filterHandle = null;
699                                         int ret = contacts_filter_create(_contacts_simple_contact._uri, &filterHandle);
700                                         if (ret != CONTACTS_ERROR_NONE)
701                                         {
702                                                 break;
703                                         }
704
705                                         ScopedFilter filter(filterHandle);
706
707                                         contacts_filter_add_int(filter.Get(), _contacts_simple_contact.person_id, CONTACTS_MATCH_EQUAL, id);
708
709                                         contacts_query_h queryHandle = null;
710                                         ret = contacts_query_create(_contacts_simple_contact._uri, &queryHandle);
711                                         if (ret != CONTACTS_ERROR_NONE)
712                                         {
713                                                 break;
714                                         }
715
716                                         ScopedQuery query(queryHandle);
717
718                                         ret = contacts_query_set_filter(query.Get(), filter.Get());
719                                         if (ret != CONTACTS_ERROR_NONE)
720                                         {
721                                                 break;
722                                         }
723
724                                         ret = contacts_query_set_projection(query.Get(), simple_contact_projection, sizeof(simple_contact_projection)/sizeof(unsigned int));
725                                         if (ret != CONTACTS_ERROR_NONE)
726                                         {
727                                                 break;
728                                         }
729
730                                         ret = contacts_query_set_sort(query.Get(), _contacts_simple_contact.address_book_id, true);
731                                         if (ret != CONTACTS_ERROR_NONE)
732                                         {
733                                                 break;
734                                         }
735
736
737                                         contacts_list_h listHandle = null;
738                                         ret = contacts_db_get_records_with_query(query.Get(), 0, 0, &listHandle);
739                                         if (ret != CONTACTS_ERROR_NONE)
740                                         {
741                                                 break;
742                                         }
743
744                                         ScopedList contactList(listHandle);
745                                         unsigned int count = 0;
746                                         contacts_list_get_count(contactList.Get(), &count);
747                                         if (count > 0)
748                                         {
749                                                 contacts_record_h contactHandle = null;
750                                                 contacts_list_get_current_record_p(contactList.Get(), &contactHandle);
751                                                 contacts_record_get_int(contactHandle, _contacts_simple_contact.id, &contactId);
752                                         }
753
754                                         if (!isFirst)
755                                         {
756                                                 retValue.Append(L";");  
757                                         }
758                                         else
759                                         {
760                                                 isFirst = false;
761                                         }
762
763                                         retValue.Append(contactId);     
764                                 }
765                         }
766
767                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_RET_TYPE), new (std::nothrow) String(PICK_OP_RET_VALUE_CONTACT_ID));
768                         pResult->Add(new (std::nothrow) String(PICK_OP_RET_KEY_VALUE), new (std::nothrow) String(retValue));
769                 }
770                 }
771                 break;
772
773         default:
774                 break;
775         }
776
777         _AppControlManager::GetInstance()->FinishAppControl(__req, res, pResult);
778
779 CATCH:
780         __req = -1;
781 }
782
783
784 #ifdef __cplusplus
785 }
786 #endif