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);
84 MAPS_LOGD("Created a HereManager instance (%d).", m_nRefCnt);
86 pthread_mutex_unlock(&g_mtxRef);
89 m_pHereManager->SetCredentials();
93 void HereManager::Close()
95 pthread_mutex_lock(&g_mtxRef);
96 bool terminate = (--m_nRefCnt == 0 && m_pHereManager);
97 pthread_mutex_unlock(&g_mtxRef);
101 m_pHereManager->TerminateAllServices();
102 HereConfig::Shutdown();
104 delete m_pHereManager;
105 m_pHereManager = NULL;
107 MAPS_LOGD("Closed a HereManager instance (%d).", m_nRefCnt);
110 HereManager* HereManager::GetHandler()
112 return m_pHereManager;
115 void* HereManager::CreateInstance(HereSvcType nHereSvc, void* pCbFunc,
116 void* pUserData, int *nReqId)
118 HereBase *pHere = NULL;
120 int reqId = m_nNextReqId++;
121 if (nReqId) *nReqId = reqId;
125 case HERE_SVC_GEOCODE:
126 pHere = (HereBase*)new (std::nothrow) HereGeocode(pCbFunc, pUserData, reqId);
129 case HERE_SVC_REV_GEOCODE:
130 pHere = (HereBase*)new (std::nothrow) HereRevGeocode(pCbFunc, pUserData, reqId);
134 pHere = (HereBase*)new (std::nothrow) HerePlace(pCbFunc, pUserData, reqId);
138 pHere = (HereBase*)new (std::nothrow) HereRoute(pCbFunc, pUserData, reqId);
141 case HERE_SVC_MULTI_REV_GEOCODE:
142 pHere = (HereBase*)new (std::nothrow) HereMultiRevGeocode(pCbFunc, pUserData, reqId);
146 pHere = (HereBase*)new (std::nothrow) HereView();
153 pthread_mutex_lock(&m_mtxHereList);
155 m_HereList.push_back(pHere);
156 pthread_mutex_unlock(&m_mtxHereList);
161 here_error_e HereManager::CloseInstance(int nReqId)
163 HereSvcList::iterator it;
165 pthread_mutex_lock(&m_mtxHereList);
166 for (it = m_HereList.begin(); it != m_HereList.end(); it++)
168 if ((*it)->GetReqId() == nReqId)
170 m_HereList.erase(it);
174 pthread_mutex_unlock(&m_mtxHereList);
176 return HERE_ERROR_NONE;
179 here_error_e HereManager::CancelInstance(int nReqId)
181 HereSvcList::iterator it;
183 pthread_mutex_lock(&m_mtxHereList);
184 for (it = m_HereList.begin(); it != m_HereList.end(); it++)
186 if ((*it)->GetReqId() == nReqId)
188 m_HereList.erase(it);
189 RestItemHandle::Cancel((*it)->GetRestReqId());
190 (*it)->TerminateService();
191 pthread_mutex_unlock(&m_mtxHereList);
192 return HERE_ERROR_NONE;
195 pthread_mutex_unlock(&m_mtxHereList);
197 return HERE_ERROR_NOT_FOUND;
200 bool HereManager::AppInfoMetadataCb(const char *metadata_key, const char *metadata_value, void *user_data)
202 if (!metadata_key || !metadata_value)
205 if (!strncmp(metadata_key, "http://tizen.org/metadata/here_key", 35) && strlen(metadata_value) > 0 )
207 if (m_pHereManager->SetCredentials(metadata_value) == HERE_ERROR_NONE)
209 MAPS_LOGD("Succeeded getting credential from metadata");
218 here_error_e HereManager::SetCredentials(void)
222 pid_t nProcessId = -1;
223 char *strAppId = NULL;
225 nProcessId = getpid();
226 nRet = app_manager_get_app_id(nProcessId, &strAppId);
227 if (nRet != APP_MANAGER_ERROR_NONE)
229 MAPS_LOGI("Get app_id [%ld]. nRet[%d]", nProcessId, nRet);
230 return HERE_ERROR_NONE;
233 nRet = app_info_create(strAppId, &hAppInfo);
234 if (nRet != APP_MANAGER_ERROR_NONE)
236 MAPS_LOGI("Get appinfo of [%s]. nRet[%d]", strAppId, nRet);
237 if (strAppId) free(strAppId);
238 return HERE_ERROR_NONE;
241 if (strAppId) free(strAppId);
243 nRet = app_info_foreach_metadata(hAppInfo, AppInfoMetadataCb, NULL);
244 if (nRet != APP_MANAGER_ERROR_NONE)
246 MAPS_LOGI("Get metadata. nRet[%d]", nRet);
249 nRet = app_info_destroy(hAppInfo);
250 if (nRet != APP_MANAGER_ERROR_NONE)
252 MAPS_LOGI("Destroy app_info. nRet[%d]", nRet);
255 return HERE_ERROR_NONE;
258 here_error_e HereManager::SetCredentials(const char *szKey)
261 return HERE_ERROR_INVALID_PARAMETER;
263 String strKey(szKey);
264 String strAppId, strAppCode, strRequestAppId = "";
267 nCodeStart = strKey.find("/");
269 if(nCodeStart == 0 || nCodeStart >= (strKey.length()-1))
271 MAPS_LOGE("[error] Key type fault : Key type should be as like XXXXX/YYYYY");
272 return HERE_ERROR_INVALID_PARAMETER;
275 strAppId = strKey.substr(0, nCodeStart);
276 strAppCode = strKey.substr(nCodeStart+1, std::string::npos);
278 if (ApplicationContext::GetInstance().GetRequestAppId().length() < 1) {
279 char *strAppId = NULL;
280 pid_t nProcessId = getpid();
282 app_manager_get_app_id(nProcessId, &strAppId);
283 if (strAppId != NULL) {
284 MAPS_LOGE("RequestAppId is %s", strAppId);
285 strRequestAppId.append(strAppId);
289 strRequestAppId = ApplicationContext::GetInstance().GetRequestAppId();
291 if(!ApplicationContext::GetInstance().Initialize(strAppCode, strAppId, strRequestAppId))
292 return HERE_ERROR_INVALID_OPERATION;
294 //MAPS_LOGD("[success] credential setted to 'XXXXX/XXXXX'");
296 return HERE_ERROR_NONE;
299 here_error_e HereManager::GetCredentials(char **szKey)
302 return HERE_ERROR_INVALID_PARAMETER;
304 if (!ApplicationContext::GetInstance().IsInitialized())
305 return HERE_ERROR_NOT_FOUND;
307 String strCredentials = ApplicationContext::GetInstance().GetAppId() + "/" +
308 ApplicationContext::GetInstance().GetAppCode();
310 *szKey = g_strndup(strCredentials.c_str(), strCredentials.length());
313 return HERE_ERROR_INVALID_OPERATION;
315 //MAPS_LOGD("current credential : %s", *szKey);
317 return HERE_ERROR_NONE;
320 here_error_e HereManager::SetPreference(maps_preference_h hPref)
322 int error = HERE_ERROR_NONE;
325 return HERE_ERROR_INVALID_PARAMETER;
329 if (maps_preference_destroy(m_hPref) != MAPS_ERROR_NONE)
330 return HERE_ERROR_INVALID_OPERATION;
334 error = maps_preference_clone(hPref, &m_hPref);
335 if (error != MAPS_ERROR_NONE) break;
337 char *szLanguage = NULL;
338 error = maps_preference_get_language(hPref, &szLanguage);
339 if (error == MAPS_ERROR_NONE && szLanguage && strlen(szLanguage) > 0)
340 ApplicationContext::GetInstance().SetPreferredLanguage(String(szLanguage));
343 return (here_error_e)ConvertToHereError(error);
346 here_error_e HereManager::GetPreference(maps_preference_h *hPref)
348 int ret = HERE_ERROR_NONE;
351 return HERE_ERROR_INVALID_PARAMETER;
354 return HERE_ERROR_NOT_FOUND;
356 ret = maps_preference_clone(m_hPref, hPref);
358 return (here_error_e)ConvertToHereError(ret);
361 maps_preference_h HereManager::GetPreference()
366 void HereManager::TerminateAllServices(void)
368 HereSvcList::iterator it;
372 pthread_mutex_lock(&m_mtxHereList);
373 if (m_HereList.empty())
375 pthread_mutex_unlock(&m_mtxHereList);
378 it = m_HereList.begin();
379 pthread_mutex_unlock(&m_mtxHereList);
382 if (*it) (*it)->TerminateService();
383 m_HereList.erase(it);
385 catch (std::exception &e) {
386 MAPS_LOGD("Exception caught: %s", e.what());
392 maps_preference_destroy(m_hPref);
397 here_error_e HereManager::ConvertNetworkErrorCode(const int nErrorCode)
399 here_error_e err = HERE_ERROR_NONE;
403 case CONNECTION_ERROR_NONE:
404 //MAPS_LOGD("No error");
405 err = HERE_ERROR_NONE;
407 case CONNECTION_ERROR_INVALID_PARAMETER:
408 MAPS_LOGD("Invalid parameter");
409 err = HERE_ERROR_INVALID_PARAMETER;
411 case CONNECTION_ERROR_OUT_OF_MEMORY:
412 MAPS_LOGD("Out of memory error");
413 err = HERE_ERROR_OUT_OF_MEMORY;
415 case CONNECTION_ERROR_INVALID_OPERATION:
416 MAPS_LOGD("Invalid Operation");
417 err = HERE_ERROR_INVALID_OPERATION;
419 case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
420 MAPS_LOGD("Address family not supported");
421 err = HERE_ERROR_NOT_SUPPORTED;
423 case CONNECTION_ERROR_PERMISSION_DENIED:
424 MAPS_LOGD("Permission denied");
425 err = HERE_ERROR_PERMISSION_DENIED;
427 case CONNECTION_ERROR_OPERATION_FAILED:
428 MAPS_LOGD("Operation failed");
429 err = HERE_ERROR_INVALID_OPERATION;
431 case CONNECTION_ERROR_ITERATOR_END:
432 MAPS_LOGD("End of iteration");
434 case CONNECTION_ERROR_NO_CONNECTION:
435 MAPS_LOGD("There is no connection");
436 err = HERE_ERROR_NETWORK_UNREACHABLE;
438 case CONNECTION_ERROR_NOW_IN_PROGRESS:
439 MAPS_LOGD("Now in progress");
440 err = HERE_ERROR_RESOURCE_BUSY;
442 case CONNECTION_ERROR_ALREADY_EXISTS:
443 MAPS_LOGD("Already exists");
445 case CONNECTION_ERROR_OPERATION_ABORTED:
446 MAPS_LOGD("Operation is aborted");
447 err = HERE_ERROR_CANCELED;
449 case CONNECTION_ERROR_DHCP_FAILED:
450 MAPS_LOGD("DHCP failed");
452 case CONNECTION_ERROR_INVALID_KEY:
453 MAPS_LOGD("Invalid key");
454 err = HERE_ERROR_KEY_NOT_AVAILABLE;
456 case CONNECTION_ERROR_NO_REPLY:
457 MAPS_LOGD("No Reply");
458 err = HERE_ERROR_RESOURCE_BUSY;
460 case CONNECTION_ERROR_NOT_SUPPORTED:
461 MAPS_LOGD("Not Supported");
462 err = HERE_ERROR_NOT_SUPPORTED;
465 MAPS_LOGD("Unknown");
468 //MAPS_LOGD("nErrorCode = 0x%08X", nErrorCode);
473 here_error_e HereManager::SetProxyAddress()
475 int errorCode = CONNECTION_ERROR_NONE;
477 char *proxy_address = NULL;
481 errorCode = connection_create(&m_hConnection);
482 if (errorCode == CONNECTION_ERROR_NONE)
484 errorCode = connection_set_type_changed_cb(m_hConnection, NetworkStateChangedIndCb, this);
488 if (errorCode != CONNECTION_ERROR_NONE)
489 return ConvertNetworkErrorCode(errorCode);
491 errorCode = connection_get_proxy(m_hConnection, CONNECTION_ADDRESS_FAMILY_IPV4, &proxy_address);
492 if (errorCode == CONNECTION_ERROR_NONE)
494 MAPS_LOGD("Proxy = %s", (proxy_address ? proxy_address : "(null)"));
495 Tizen::Maps::HereConfig::SetProxyAddress(proxy_address);
497 g_free(proxy_address);
499 return ConvertNetworkErrorCode(errorCode);
502 void HereManager::NetworkStateChangedIndCb(connection_type_e type, void *user_data)
504 MAPS_LOGD("Network state is changed. type=%d", type);
506 if (!user_data) return;
508 HereManager *pManager = (HereManager*)user_data;
510 if ((type != CONNECTION_TYPE_DISCONNECTED) && (type != CONNECTION_TYPE_BT))
511 pManager->SetProxyAddress();
514 here_error_e HereManager::CheckAgreement()
516 const char UTC_TPK_APP[] = "org.tizen.capi-maps-service-native-utc";
517 const char ITC_TPK_APP[] = "org.tizen.capi-maps-service-native-itc";
518 const char UTC_APP[] = "core.capi-maps-service-tests";
519 const char ITC_APP[] = "native.capi-maps-service-itc";
523 char *strAppId = NULL;
524 here_error_e error = HERE_ERROR_NONE;
526 ret = vconf_get_bool(VCONFKEY_LOCATION_HEREMAPS_CONSENT, &enabled);
527 MAPS_LOGD("VCONFKEY_LOCATION_HEREMAPS_CONSENT is %d", enabled);
528 if (ret != 0 || enabled == 0) {
529 error = HERE_ERROR_SERVICE_NOT_AVAILABLE;
531 MAPS_LOGD("Fail to get vconf value");
533 pid_t nProcessId = getpid();
534 ret = app_manager_get_app_id(nProcessId, &strAppId);
535 if (ret != APP_MANAGER_ERROR_NONE)
536 MAPS_LOGI("Get app_id [%ld]. nRet[%d]", nProcessId, ret);
537 else if (!strncmp(strAppId, UTC_APP, strlen(UTC_APP)) ||
538 !strncmp(strAppId, ITC_APP, strlen(ITC_APP)) ||
539 !strncmp(strAppId, UTC_TPK_APP, strlen(UTC_TPK_APP)) ||
540 !strncmp(strAppId, ITC_TPK_APP, strlen(ITC_TPK_APP))) {
541 MAPS_LOGD("Requested by tct");
542 error = HERE_ERROR_NONE;
546 if (error != HERE_ERROR_NONE) {
547 MAPS_LOGD("heremaps_uc_dbus_launch_receiver is called");
548 ret = heremaps_uc_dbus_launch_receiver();
549 if (ret != HEREMAPS_UC_DBUS_ERROR_NONE)
550 MAPS_LOGD("heremaps_uc_dbus_launch_receiver fail");
552 MAPS_LOGD("Vconf value of HereMaps is true");
554 if (strAppId != NULL)
559 HERE_PLUGIN_END_NAMESPACE