2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file ContactAppControlDllEntry.cpp
20 * @brief This is the implementation for the ContactAppControlDllEntry.cpp class.
23 #include <unique_ptr.h>
24 #include <appsvc/appsvc.h>
27 #include <FBaseSysLog.h>
28 #include <FBaseInteger.h>
29 #include <FBaseUtilStringUtil.h>
30 #include <FAppAppControl.h>
31 #include <FBaseColHashMap.h>
32 #include <FBaseColAllElementsDeleter.h>
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>
40 #include <FApp_AppArg.h>
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;
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";
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";
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";
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;
71 static char PICK_OP_SEL_MODE_VALUE_SINGLE[] = "single";
72 static char PICK_OP_SEL_MODE_VALUE_MULTIPLE[] = "multiple";
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";
79 static int PICK_OP_SEL_MODE_VALUE_LENGTH_MAX = 8;
80 static int PICK_OP_RET_VALUE_LENGTH_MAX = 10;
82 static char ADD_OP_KEY_NUMBER[] = "phone";
83 static char ADD_OP_KEY_EMAIL[] = "email";
84 static char ADD_OP_KEY_URL[] = "url";
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";
94 static char CORE_OP_VALUE_EDIT_PERSON[] = "11";
95 static char CORE_OP_VALUE_EDIT_PERSON_BY_SEL[] = "20";
97 static char CORE_OP_VALUE_VIEW_PERSON[] = "0";
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";
108 static char CORE_OP_VALUE_ADD_CONTACT[] = "21";
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";
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";
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*);
130 static int __req = -1;
131 static int __processId = -1;
133 static const char __allowedAppControlLegacyPickTable[][2][96] =
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"},
141 static const char __allowedAppControlPickTable[][2][96] =
143 {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/pick"},
146 static const char __allowedAppControlLegacyAddTable[][2][96] =
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"},
154 static const char __allowedAppControlAddTable[][2][96] =
156 {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/add"},
159 static const char __allowedAppControlLegacyEditTable[][2][96] =
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"},
167 static const char __allowedAppControlEditTable[][2][96] =
169 {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/edit"},
172 static const char __allowedAppControlLegacyViewTable[][2][96] =
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"},
180 static const char __allowedAppControlViewTable[][2][96] =
182 {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/view"},
185 static const char __allowedAppControlChooseTable[][2][96] =
187 {"tizen.contacts", "http://tizen.org/appcontrol/operation/social/choose"},
191 class ScopedConnection
194 ScopedConnection(void)
197 int ret = contacts_connect2();
198 if (ret == CONTACTS_ERROR_NONE)
204 ~ScopedConnection(void)
208 contacts_disconnect2();
212 bool IsConnected(void) const
225 ScopedHandle(contacts_record_h handle)
232 if (__handle != null)
234 contacts_record_destroy(__handle, true);
238 contacts_record_h Get(void)
243 contacts_record_h Release(void)
245 contacts_record_h handle = __handle;
252 contacts_record_h __handle;
258 ScopedList(contacts_list_h handle)
265 if (__handle != null)
267 contacts_list_destroy(__handle, true);
271 contacts_list_h Get(void)
277 contacts_list_h __handle;
283 ScopedFilter(contacts_filter_h filter)
290 if (__filter != null)
292 contacts_filter_destroy(__filter);
296 contacts_filter_h Get(void)
302 contacts_filter_h __filter;
308 ScopedQuery(contacts_query_h query)
317 contacts_query_destroy(__query);
321 contacts_query_h Get(void)
327 contacts_query_h __query;
331 StartAppControl(int req, const String& aId, const String& oId, const String* pUri, const String* pMime, const IMap* pMap)
333 SysLog(NID_APP, "StartAppControl: Entry to Contact AppControl");
335 result r = E_SUCCESS;
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);
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());
352 AppSvcResFn pCb = NULL;
354 String providerAppId;
357 const String* pActualUri = pUri;
358 const char* pBuf = null;
360 if (isContactAdd || isLegacyContactAdd)
362 providerAppId = L"tizen.contact_detail";
363 operation = L"http://tizen.org/appcontrol/operation/social/add";
365 if (isLegacyContactAdd)
367 msg.AddData(CONTACT_ITEM_TYPE, L"contact");
369 pBuf = appsvc_get_data(msg.GetBundle(), "phone");
372 msg.AddData(L"http://tizen.org/appcontrol/data/social/phone", String(pBuf));
375 pBuf = appsvc_get_data(msg.GetBundle(), "email");
378 msg.AddData(L"http://tizen.org/appcontrol/data/social/email", String(pBuf));
381 pBuf = appsvc_get_data(msg.GetBundle(), "url");
384 msg.AddData(L"http://tizen.org/appcontrol/data/social/url", String(pBuf));
389 pCb = OnAppControlResultTizen;
392 else if (isContactEdit || isLegacyContactEdit)
394 providerAppId = L"tizen.contact_detail";
396 if (isLegacyContactEdit)
398 msg.AddData(CONTACT_ITEM_TYPE, L"person");
400 pBuf = appsvc_get_data(msg.GetBundle(), EDIT_OP_KEY_CONTACT_ID);
403 operation = L"http://tizen.org/appcontrol/operation/social/edit";
405 int contactId = atoi(pBuf);
408 ScopedConnection conn;
409 if (conn.IsConnected())
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)
415 contacts_record_get_int(contactHandle, _contacts_simple_contact.person_id, &personId);
416 contacts_record_destroy(contactHandle, true);
420 msg.AddData(L"http://tizen.org/appcontrol/data/social/item_id", Integer::ToString(personId));
424 operation = L"http://tizen.org/appcontrol/operation/social/choose";
427 pBuf = appsvc_get_data(msg.GetBundle(), "phone");
430 msg.AddData(L"http://tizen.org/appcontrol/data/social/phone", String(pBuf));
433 pBuf = appsvc_get_data(msg.GetBundle(), "email");
436 msg.AddData(L"http://tizen.org/appcontrol/data/social/email", String(pBuf));
439 pBuf = appsvc_get_data(msg.GetBundle(), "url");
442 msg.AddData(L"http://tizen.org/appcontrol/data/social/url", String(pBuf));
447 operation = L"http://tizen.org/appcontrol/operation/social/edit";
450 else if (isContactView || isLegacyContactView)
455 const String& path = msg.GetValue(L"path");
465 providerAppId = L"tizen.contact_viewer";
466 operation = L"http://tizen.org/appcontrol/operation/view";
470 providerAppId = L"tizen.contact_detail";
471 operation = L"http://tizen.org/appcontrol/operation/social/view";
472 msg.AddData(CONTACT_ITEM_TYPE, L"person");
474 pBuf = appsvc_get_data(msg.GetBundle(), "contactId");
477 int contactId = atoi(pBuf);
480 ScopedConnection conn;
481 if (conn.IsConnected())
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)
487 contacts_record_get_int(contactHandle, _contacts_simple_contact.person_id, &personId);
488 contacts_record_destroy(contactHandle, true);
492 msg.AddData(L"http://tizen.org/appcontrol/data/social/item_id", Integer::ToString(personId));
496 else if (isContactPick || isLegacyContactPick)
498 providerAppId = L"tizen.contact_list";
499 operation = L"http://tizen.org/appcontrol/operation/social/pick";
501 if (isLegacyContactPick)
503 msg.AddData(CONTACT_ITEM_TYPE, L"person");
505 const String& mode = msg.GetValue(L"selectionMode");
508 msg.AddData(SELECTION_MODE, mode);
509 msg.RemoveData(L"selectionMode");
512 const String& retType = msg.GetValue(L"returnType");
513 if (!retType.IsEmpty())
515 if (retType == L"contactId")
517 msg.AddData(CONTACT_RESULT_TYPE, L"item_id");
521 msg.AddData(CONTACT_RESULT_TYPE, retType);
524 msg.RemoveData(L"returnType");
527 pCb = OnAppControlResultLegacy;
531 pCb = OnAppControlResultTizen;
534 else if (isContactChoose)
536 providerAppId = L"tizen.contact_list";
537 operation = L"http://tizen.org/appcontrol/operation/social/choose";
538 pCb = OnAppControlResultTizen;
541 const String& package = _AppControlManager::GetAliasAppId(providerAppId);
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.");
548 SysLog(NID_APP, "StartAppControl: Launching Contact AppControl succeeded");
554 TerminateAppControl(int req)
556 if (__processId >= 0)
558 _Aul::TerminateApplicationByPid(__processId);
564 OnAppControlResultTizen(void* b, int requestCode, service_result_e res, void* userData)
567 bundle* pBundle = static_cast<bundle*>(b);
569 HashMap* pResult = new (std::nothrow) HashMap();
570 SysTryCatch(NID_APP, pResult != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
572 r = pResult->Construct();
574 _AppArg::SetArgMap(pBundle, pResult);
576 _AppControlManager::GetInstance()->FinishAppControl(__req, res, pResult);
583 OnAppControlResultLegacy(void* b, int requestCode, service_result_e res, void* userData)
586 bundle* pBundle = static_cast<bundle*>(b);
588 HashMap* pResult = new (std::nothrow) HashMap();
589 SysTryCatch(NID_APP, pResult != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
591 r = pResult->Construct();
595 case SERVICE_RESULT_SUCCEEDED:
597 _AppArg::SetArgMap(pBundle, pResult);
599 ArrayList* pList = static_cast<ArrayList*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/social/phone")));
605 std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
606 SysTryCatch(NID_APP, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
608 while (pEnum->MoveNext() == E_SUCCESS)
610 String* pPhoneNumber = static_cast<String*>(pEnum->GetCurrent());
614 retValue.Append(L";");
621 retValue.Append(*pPhoneNumber);
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));
628 pList = static_cast<ArrayList*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/social/email")));
634 std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
635 SysTryCatch(NID_APP, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
637 while (pEnum->MoveNext() == E_SUCCESS)
639 String* pEmail = static_cast<String*>(pEnum->GetCurrent());
643 retValue.Append(L";");
650 retValue.Append(*pEmail);
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));
657 String* pString = dynamic_cast<String*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/path")));
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));
665 String* pString = static_cast<String*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/path")));
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));
673 pList = static_cast<ArrayList*>(pResult->GetValue(String(L"http://tizen.org/appcontrol/data/social/item_id")));
681 std::unique_ptr<IEnumerator> pEnum(pList->GetEnumeratorN());
682 SysTryCatch(NID_APP, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Allocation failure.");
684 ScopedConnection conn;
685 if (conn.IsConnected())
687 unsigned int simple_contact_projection[] = {
688 _contacts_simple_contact.id,
689 _contacts_simple_contact.address_book_id,
693 while (pEnum->MoveNext() == E_SUCCESS)
695 String* pPersonId = static_cast<String*>(pEnum->GetCurrent());
696 Integer::Decode(*pPersonId, id);
698 contacts_filter_h filterHandle = null;
699 int ret = contacts_filter_create(_contacts_simple_contact._uri, &filterHandle);
700 if (ret != CONTACTS_ERROR_NONE)
705 ScopedFilter filter(filterHandle);
707 contacts_filter_add_int(filter.Get(), _contacts_simple_contact.person_id, CONTACTS_MATCH_EQUAL, id);
709 contacts_query_h queryHandle = null;
710 ret = contacts_query_create(_contacts_simple_contact._uri, &queryHandle);
711 if (ret != CONTACTS_ERROR_NONE)
716 ScopedQuery query(queryHandle);
718 ret = contacts_query_set_filter(query.Get(), filter.Get());
719 if (ret != CONTACTS_ERROR_NONE)
724 ret = contacts_query_set_projection(query.Get(), simple_contact_projection, sizeof(simple_contact_projection)/sizeof(unsigned int));
725 if (ret != CONTACTS_ERROR_NONE)
730 ret = contacts_query_set_sort(query.Get(), _contacts_simple_contact.address_book_id, true);
731 if (ret != CONTACTS_ERROR_NONE)
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)
744 ScopedList contactList(listHandle);
745 unsigned int count = 0;
746 contacts_list_get_count(contactList.Get(), &count);
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);
756 retValue.Append(L";");
763 retValue.Append(contactId);
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));
777 _AppControlManager::GetInstance()->FinishAppControl(__req, res, pResult);