2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <libxml/xpath.h>
20 #include "here_manager.h"
21 #include "here_base.h"
22 #include "here_geocode.h"
23 #include "here_revgeocode.h"
24 #include "here_multirevgeocode.h"
25 #include "here_place.h"
26 #include "here_route.h"
27 #include "here_utils.h"
28 #include "here_view.h"
29 #include "heremaps-uc-dbus.h"
31 #include <common/HereConfig.h>
37 #include <vconf-internal-location-keys.h>
39 using namespace HERE_PLUGIN_NAMESPACE_PREFIX;
40 using namespace TIZEN_MAPS_NAMESPACE_PREFIX;
42 HERE_PLUGIN_BEGIN_NAMESPACE
44 HereManager *HereManager::m_pHereManager = NULL;
45 int HereManager::m_nRefCnt = 0;
46 pthread_mutex_t g_mtxRef;
48 HereManager::HereManager()
54 pthread_mutex_init(&m_mtxHereList, NULL);
55 pthread_mutex_init(&g_mtxRef, NULL);
58 HereManager::~HereManager()
62 connection_unset_type_changed_cb(m_hConnection);
63 connection_destroy(m_hConnection);
67 pthread_mutex_destroy(&m_mtxHereList);
68 pthread_mutex_destroy(&g_mtxRef);
72 bool HereManager::Create()
77 m_pHereManager = new (std::nothrow) HereManager();
79 pthread_mutex_lock(&g_mtxRef);
83 MAPS_LOGD("Created a HereManager instance (%d).", m_nRefCnt);
85 pthread_mutex_unlock(&g_mtxRef);
88 m_pHereManager->SetCredentials();
92 void HereManager::Close()
94 pthread_mutex_lock(&g_mtxRef);
95 bool terminate = (--m_nRefCnt == 0 && m_pHereManager);
96 pthread_mutex_unlock(&g_mtxRef);
99 m_pHereManager->TerminateAllServices();
100 HereConfig::Shutdown();
102 delete m_pHereManager;
103 m_pHereManager = NULL;
105 MAPS_LOGD("Closed a HereManager instance (%d).", m_nRefCnt);
108 HereManager* HereManager::GetHandler()
110 return m_pHereManager;
113 void* HereManager::CreateInstance(HereSvcType nHereSvc, void* pCbFunc,
114 void* pUserData, int *nReqId)
116 HereBase *pHere = NULL;
118 int reqId = m_nNextReqId++;
119 if (nReqId) *nReqId = reqId;
123 case HERE_SVC_GEOCODE:
124 pHere = (HereBase*)new (std::nothrow) HereGeocode(pCbFunc, pUserData, reqId);
127 case HERE_SVC_REV_GEOCODE:
128 pHere = (HereBase*)new (std::nothrow) HereRevGeocode(pCbFunc, pUserData, reqId);
132 pHere = (HereBase*)new (std::nothrow) HerePlace(pCbFunc, pUserData, reqId);
136 pHere = (HereBase*)new (std::nothrow) HereRoute(pCbFunc, pUserData, reqId);
139 case HERE_SVC_MULTI_REV_GEOCODE:
140 pHere = (HereBase*)new (std::nothrow) HereMultiRevGeocode(pCbFunc, pUserData, reqId);
144 pHere = (HereBase*)new (std::nothrow) HereView();
151 pthread_mutex_lock(&m_mtxHereList);
153 m_HereList.push_back(pHere);
154 pthread_mutex_unlock(&m_mtxHereList);
159 here_error_e HereManager::CloseInstance(int nReqId)
161 HereSvcList::iterator it;
163 pthread_mutex_lock(&m_mtxHereList);
164 for (it = m_HereList.begin(); it != m_HereList.end(); it++) {
165 if ((*it)->GetReqId() == nReqId) {
166 m_HereList.erase(it);
170 pthread_mutex_unlock(&m_mtxHereList);
172 return HERE_ERROR_NONE;
175 here_error_e HereManager::CancelInstance(int nReqId)
177 HereSvcList::iterator it;
179 pthread_mutex_lock(&m_mtxHereList);
180 for (it = m_HereList.begin(); it != m_HereList.end(); it++) {
181 if ((*it)->GetReqId() == nReqId) {
182 m_HereList.erase(it);
183 RestItemHandle::Cancel((*it)->GetRestReqId());
184 (*it)->TerminateService();
185 pthread_mutex_unlock(&m_mtxHereList);
186 return HERE_ERROR_NONE;
189 pthread_mutex_unlock(&m_mtxHereList);
191 return HERE_ERROR_NOT_FOUND;
194 bool HereManager::AppInfoMetadataCb(const char *metadata_key, const char *metadata_value, void *user_data)
196 if (!metadata_key || !metadata_value)
199 if (!strncmp(metadata_key, "http://tizen.org/metadata/here_key", 35) && strlen(metadata_value) > 0) {
200 if (m_pHereManager->SetCredentials(metadata_value) == HERE_ERROR_NONE)
201 MAPS_LOGD("Succeeded getting credential from metadata");
209 here_error_e HereManager::SetCredentials(void)
213 pid_t nProcessId = -1;
214 char *strAppId = NULL;
216 nProcessId = getpid();
217 nRet = app_manager_get_app_id(nProcessId, &strAppId);
218 if (nRet != APP_MANAGER_ERROR_NONE) {
219 MAPS_LOGI("Get app_id [%ld]. nRet[%d]", nProcessId, nRet);
220 return HERE_ERROR_NONE;
223 nRet = app_info_create(strAppId, &hAppInfo);
224 if (nRet != APP_MANAGER_ERROR_NONE) {
225 MAPS_LOGI("Get appinfo of [%s]. nRet[%d]", strAppId, nRet);
226 if (strAppId) free(strAppId);
227 return HERE_ERROR_NONE;
230 if (strAppId) free(strAppId);
232 nRet = app_info_foreach_metadata(hAppInfo, AppInfoMetadataCb, NULL);
233 if (nRet != APP_MANAGER_ERROR_NONE)
234 MAPS_LOGI("Get metadata. nRet[%d]", nRet);
236 nRet = app_info_destroy(hAppInfo);
237 if (nRet != APP_MANAGER_ERROR_NONE)
238 MAPS_LOGI("Destroy app_info. nRet[%d]", nRet);
240 return HERE_ERROR_NONE;
243 here_error_e HereManager::SetCredentials(const char *szKey)
246 return HERE_ERROR_INVALID_PARAMETER;
248 String strKey(szKey);
249 String strAppId, strAppCode, strRequestAppId = "";
252 nCodeStart = strKey.find("/");
254 if(nCodeStart == 0 || nCodeStart >= (strKey.length()-1)) {
255 MAPS_LOGE("[error] Key type fault : Key type should be as like XXXXX/YYYYY");
256 return HERE_ERROR_INVALID_PARAMETER;
259 strAppId = strKey.substr(0, nCodeStart);
260 strAppCode = strKey.substr(nCodeStart+1, std::string::npos);
262 if (ApplicationContext::GetInstance().GetRequestAppId().length() < 1) {
263 char *strAppId = NULL;
264 pid_t nProcessId = getpid();
266 app_manager_get_app_id(nProcessId, &strAppId);
267 if (strAppId != NULL) {
268 MAPS_LOGE("RequestAppId is %s", strAppId);
269 strRequestAppId.append(strAppId);
273 strRequestAppId = ApplicationContext::GetInstance().GetRequestAppId();
276 if(!ApplicationContext::GetInstance().Initialize(strAppCode, strAppId, strRequestAppId))
277 return HERE_ERROR_INVALID_OPERATION;
279 //MAPS_LOGD("[success] credential setted to 'XXXXX/XXXXX'");
281 return HERE_ERROR_NONE;
284 here_error_e HereManager::GetCredentials(char **szKey)
287 return HERE_ERROR_INVALID_PARAMETER;
289 if (!ApplicationContext::GetInstance().IsInitialized())
290 return HERE_ERROR_NOT_FOUND;
292 String strCredentials = ApplicationContext::GetInstance().GetAppId() + "/" +
293 ApplicationContext::GetInstance().GetAppCode();
295 *szKey = g_strndup(strCredentials.c_str(), strCredentials.length());
298 return HERE_ERROR_INVALID_OPERATION;
300 //MAPS_LOGD("current credential : %s", *szKey);
302 return HERE_ERROR_NONE;
305 here_error_e HereManager::SetPreference(maps_preference_h hPref)
307 int error = HERE_ERROR_NONE;
310 return HERE_ERROR_INVALID_PARAMETER;
313 if (maps_preference_destroy(m_hPref) != MAPS_ERROR_NONE)
314 return HERE_ERROR_INVALID_OPERATION;
318 error = maps_preference_clone(hPref, &m_hPref);
319 if (error != MAPS_ERROR_NONE) break;
321 char *szLanguage = NULL;
322 error = maps_preference_get_language(hPref, &szLanguage);
323 if (error == MAPS_ERROR_NONE && szLanguage && strlen(szLanguage) > 0)
324 ApplicationContext::GetInstance().SetPreferredLanguage(String(szLanguage));
327 return (here_error_e)ConvertToHereError(error);
330 here_error_e HereManager::GetPreference(maps_preference_h *hPref)
332 int ret = HERE_ERROR_NONE;
335 return HERE_ERROR_INVALID_PARAMETER;
338 return HERE_ERROR_NOT_FOUND;
340 ret = maps_preference_clone(m_hPref, hPref);
342 return (here_error_e)ConvertToHereError(ret);
345 maps_preference_h HereManager::GetPreference()
350 void HereManager::TerminateAllServices(void)
352 HereSvcList::iterator it;
355 pthread_mutex_lock(&m_mtxHereList);
356 if (m_HereList.empty()) {
357 pthread_mutex_unlock(&m_mtxHereList);
360 it = m_HereList.begin();
361 pthread_mutex_unlock(&m_mtxHereList);
364 if (*it) (*it)->TerminateService();
365 m_HereList.erase(it);
366 } catch (std::exception &e) {
367 MAPS_LOGD("Exception caught: %s", e.what());
372 maps_preference_destroy(m_hPref);
377 here_error_e HereManager::ConvertNetworkErrorCode(const int nErrorCode)
379 here_error_e err = HERE_ERROR_NONE;
381 switch (nErrorCode) {
382 case CONNECTION_ERROR_NONE:
383 //MAPS_LOGD("No error");
384 err = HERE_ERROR_NONE;
386 case CONNECTION_ERROR_INVALID_PARAMETER:
387 MAPS_LOGD("Invalid parameter");
388 err = HERE_ERROR_INVALID_PARAMETER;
390 case CONNECTION_ERROR_OUT_OF_MEMORY:
391 MAPS_LOGD("Out of memory error");
392 err = HERE_ERROR_OUT_OF_MEMORY;
394 case CONNECTION_ERROR_INVALID_OPERATION:
395 MAPS_LOGD("Invalid Operation");
396 err = HERE_ERROR_INVALID_OPERATION;
398 case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
399 MAPS_LOGD("Address family not supported");
400 err = HERE_ERROR_NOT_SUPPORTED;
402 case CONNECTION_ERROR_PERMISSION_DENIED:
403 MAPS_LOGD("Permission denied");
404 err = HERE_ERROR_PERMISSION_DENIED;
406 case CONNECTION_ERROR_OPERATION_FAILED:
407 MAPS_LOGD("Operation failed");
408 err = HERE_ERROR_INVALID_OPERATION;
410 case CONNECTION_ERROR_ITERATOR_END:
411 MAPS_LOGD("End of iteration");
413 case CONNECTION_ERROR_NO_CONNECTION:
414 MAPS_LOGD("There is no connection");
415 err = HERE_ERROR_NETWORK_UNREACHABLE;
417 case CONNECTION_ERROR_NOW_IN_PROGRESS:
418 MAPS_LOGD("Now in progress");
419 err = HERE_ERROR_RESOURCE_BUSY;
421 case CONNECTION_ERROR_ALREADY_EXISTS:
422 MAPS_LOGD("Already exists");
424 case CONNECTION_ERROR_OPERATION_ABORTED:
425 MAPS_LOGD("Operation is aborted");
426 err = HERE_ERROR_CANCELED;
428 case CONNECTION_ERROR_DHCP_FAILED:
429 MAPS_LOGD("DHCP failed");
431 case CONNECTION_ERROR_INVALID_KEY:
432 MAPS_LOGD("Invalid key");
433 err = HERE_ERROR_KEY_NOT_AVAILABLE;
435 case CONNECTION_ERROR_NO_REPLY:
436 MAPS_LOGD("No Reply");
437 err = HERE_ERROR_RESOURCE_BUSY;
439 case CONNECTION_ERROR_NOT_SUPPORTED:
440 MAPS_LOGD("Not Supported");
441 err = HERE_ERROR_NOT_SUPPORTED;
444 MAPS_LOGD("Unknown");
447 //MAPS_LOGD("nErrorCode = 0x%08X", nErrorCode);
452 here_error_e HereManager::SetProxyAddress()
454 int errorCode = CONNECTION_ERROR_NONE;
456 char *proxy_address = NULL;
458 if (!m_hConnection) {
459 errorCode = connection_create(&m_hConnection);
460 if (errorCode == CONNECTION_ERROR_NONE)
461 errorCode = connection_set_type_changed_cb(m_hConnection, NetworkStateChangedIndCb, this);
463 if (errorCode != CONNECTION_ERROR_NONE)
464 return ConvertNetworkErrorCode(errorCode);
466 errorCode = connection_get_proxy(m_hConnection, CONNECTION_ADDRESS_FAMILY_IPV4, &proxy_address);
467 if (errorCode == CONNECTION_ERROR_NONE) {
468 MAPS_LOGD("Proxy = %s", (proxy_address ? proxy_address : "(null)"));
469 Tizen::Maps::HereConfig::SetProxyAddress(proxy_address);
471 g_free(proxy_address);
473 return ConvertNetworkErrorCode(errorCode);
476 void HereManager::NetworkStateChangedIndCb(connection_type_e type, void *user_data)
478 MAPS_LOGD("Network state is changed. type=%d", type);
480 if (!user_data) return;
482 HereManager *pManager = (HereManager*)user_data;
484 if ((type != CONNECTION_TYPE_DISCONNECTED) && (type != CONNECTION_TYPE_BT))
485 pManager->SetProxyAddress();
488 here_error_e HereManager::CheckAgreement()
490 const char UTC_TPK_APP[] = "org.tizen.capi-maps-service-native-utc";
491 const char ITC_TPK_APP[] = "org.tizen.capi-maps-service-native-itc";
492 const char UTC_APP[] = "core.capi-maps-service-tests";
493 const char ITC_APP[] = "native.capi-maps-service-itc";
497 char *strAppId = NULL;
498 here_error_e error = HERE_ERROR_NONE;
500 ret = vconf_get_bool(VCONFKEY_LOCATION_HEREMAPS_CONSENT, &enabled);
501 MAPS_LOGD("VCONFKEY_LOCATION_HEREMAPS_CONSENT is %d", enabled);
502 if (ret != 0 || enabled == 0) {
503 error = HERE_ERROR_SERVICE_NOT_AVAILABLE;
505 MAPS_LOGD("Fail to get vconf value");
507 pid_t nProcessId = getpid();
508 ret = app_manager_get_app_id(nProcessId, &strAppId);
509 if (ret != APP_MANAGER_ERROR_NONE)
510 MAPS_LOGI("Get app_id [%ld]. nRet[%d]", nProcessId, ret);
511 else if (!strncmp(strAppId, UTC_APP, strlen(UTC_APP)) ||
512 !strncmp(strAppId, ITC_APP, strlen(ITC_APP)) ||
513 !strncmp(strAppId, UTC_TPK_APP, strlen(UTC_TPK_APP)) ||
514 !strncmp(strAppId, ITC_TPK_APP, strlen(ITC_TPK_APP))) {
515 MAPS_LOGD("Requested by tct");
516 error = HERE_ERROR_NONE;
520 if (error != HERE_ERROR_NONE) {
521 MAPS_LOGD("heremaps_uc_dbus_launch_receiver is called");
522 ret = heremaps_uc_dbus_launch_receiver();
523 if (ret != HEREMAPS_UC_DBUS_ERROR_NONE)
524 MAPS_LOGD("heremaps_uc_dbus_launch_receiver fail");
526 MAPS_LOGD("Vconf value of HereMaps is true");
528 if (strAppId != NULL)
533 HERE_PLUGIN_END_NAMESPACE