// // Open Service Platform // Copyright (c) 2012 Samsung Electronics Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /** * @file FLoc_LocationManager.cpp * @brief This is the implementation file for the %_LocationManager class. * * This implementation file contains the definitions of the %_LocationManager class. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FLoc_AlarmRequestInfo.h" #include "FLoc_Config.h" #include "FLoc_LocationImpl.h" #include "FLoc_LocationManager.h" #include "FLoc_LocationMonitor.h" #include "FLoc_LocationRequestInfo.h" #include "FLoc_SyncLocationRequestInfo.h" using namespace Tizen::Base; using namespace Tizen::Base::Collection; using namespace Tizen::Base::Runtime; using namespace Tizen::Base::Utility; using namespace Tizen::System; using namespace std; namespace Tizen { namespace Locations { _LocationManager* _LocationManager::__pUniqueInstance = null; _LocationManager::_LocationManager(void) : Tizen::Base::Runtime::EventDrivenThread() , __locMethodRequested(LOC_METHOD_REQUESTED_NONE) , __locationMgrState(LOC_MGR_STATE_IDLE) , __minRequestedAccuracy(LOC_ACCURACY_INVALID) , __timerInterval(0) , __timerTicks(0) , __pLocRequestInfoList(null) , __pSyncLocRequestInfoList(null) , __pLocUpdateTimer(null) , __pInitMonitor(null) { } _LocationManager::~_LocationManager(void) { delete __pInitMonitor; } result _LocationManager::StartLocationUpdates(LocationAccuracy accuracy, int interval, _ILocationManagerListener* pListener, RequestId& reqId) { static RequestId nextLocRequestId = 1; const int ARRAY_LIST_CAPACITY = 1; std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); std::unique_ptr< _LocationRequestInfo > pLocRequestInfo(new (std::nothrow) _LocationRequestInfo(accuracy, interval, pListener, nextLocRequestId)); SysTryReturn(NID_LOC, pLocRequestInfo, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pLocRequestInfo); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating", GetErrorMessage(r)); pLocRequestInfo.release(); r = SendUserEvent(REQ_ID_START_LOC_UPDATES, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); reqId = nextLocRequestId; nextLocRequestId++; pArgList.release(); SysLog(NID_LOC, "Request ID (%ld) is assigned for the location request with accuracy (%d) and interval (%d).", reqId, accuracy, interval); return E_SUCCESS; } result _LocationManager::StopLocationUpdates(RequestId reqId) { SysLog(NID_LOC, "Location update stop requested for request ID (%d).", reqId); const int ARRAY_LIST_CAPACITY = 1; std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); std::unique_ptr< Integer > pReqId(new (std::nothrow) Integer(static_cast< int >(reqId))); SysTryReturn(NID_LOC, pReqId, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pReqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); pReqId.release(); r = SendUserEvent(REQ_ID_STOP_LOC_UPDATES, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); pArgList.release(); return E_SUCCESS; } result _LocationManager::ChangeUpdateInterval(RequestId reqId, int interval) { SysLog(NID_LOC, "Interval update requested for request ID (%d).", reqId); const int ARRAY_LIST_CAPACITY = 2; std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); std::unique_ptr< Integer > pReqId(new (std::nothrow) Integer(static_cast< int >(reqId))); SysTryReturn(NID_LOC, pReqId, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pArgList->Add(*pReqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); pReqId.release(); std::unique_ptr< Integer > pInterval(new (std::nothrow) Integer(interval)); SysTryReturn(NID_LOC, pInterval, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pArgList->Add(*pInterval); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); pInterval.release(); r = SendUserEvent(REQ_ID_UPDATE_INTERVAL, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); pArgList.release(); return E_SUCCESS; } result _LocationManager::RegisterLocationMonitor(_LocationMonitor* pLocationMonitor) { RequestId reqId; const int ARRAY_LIST_CAPACITY = 1; Location location = GetLastKnownLocation(); Tizen::Base::DateTime lastLocTime = location.GetTimestamp(); result r = StartLocationUpdates(pLocationMonitor->GetAccuracy(), 1, null, reqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Error to request location updates.", GetErrorMessage(r)); std::unique_ptr< _SyncLocationRequestInfo > pSyncLocationRequestInfo(new (std::nothrow) _SyncLocationRequestInfo(pLocationMonitor, reqId, lastLocTime)); std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryCatch(NID_LOC, pSyncLocationRequestInfo != null && pArgList != null, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pSyncLocationRequestInfo.get()); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); pSyncLocationRequestInfo.release(); r = SendUserEvent(REQ_ID_SYNC_LOC_RETRIEVAL, pArgList.get()); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); pArgList.release(); return E_SUCCESS; CATCH: StopLocationUpdates(reqId); return r; } result _LocationManager::RequestStartAlarm(int interval, _ILocationManagerListener* pListener, RequestId reqId) { const int ARRAY_LIST_CAPACITY = 1; std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); std::unique_ptr< _AlarmRequestInfo > pAlarmRequestInfo(new (std::nothrow) _AlarmRequestInfo(interval, pListener, reqId)); SysTryReturn(NID_LOC, pAlarmRequestInfo, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pAlarmRequestInfo.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating", GetErrorMessage(r)); pAlarmRequestInfo.release(); r = SendUserEvent(REQ_ID_START_ALARM, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); pArgList.release(); SysLog(NID_LOC, "Success to add the alarm."); return E_SUCCESS; } result _LocationManager::RequestStopAlarm(RequestId reqId) { SysLog(NID_LOC, "Alarm stop requested for request ID (%d).", reqId); const int ARRAY_LIST_CAPACITY = 1; std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); std::unique_ptr< Integer > pReqId(new (std::nothrow) Integer(static_cast< int >(reqId))); SysTryReturn(NID_LOC, pReqId, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pArgList->Construct(ARRAY_LIST_CAPACITY); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r)); r = pArgList->Add(*pReqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Arraylist addition of an object failed. Propogating.", GetErrorMessage(r)); pReqId.release(); r = SendUserEvent(REQ_ID_STOP_ALARM, pArgList.get()); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to send the user event. Propagating.", GetErrorMessage(r)); pArgList.release(); return E_SUCCESS; } Location _LocationManager::GetLastKnownLocation(void) { Location location = _LocationImpl::GetLocationInstance(); Monitor synchronizer; result r = synchronizer.Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, location, r, "[%s] Propogating.", GetErrorMessage(r)); std::unique_ptr< Tizen::Base::Collection::ArrayList > pArgList(new (std::nothrow) ArrayList()); SysTryReturn(NID_LOC, pArgList, location, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pArgList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, location, r, "[%s] Propogating.", GetErrorMessage(r)); r = pArgList->Add(location); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Propogating", GetErrorMessage(r)); r = pArgList->Add(synchronizer); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Propogating", GetErrorMessage(r)); r = synchronizer.Enter(); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Propogating", GetErrorMessage(r)); r = SendUserEvent(REQ_ID_GET_LAST_LOCATION, pArgList.get()); SysTryCatch(NID_LOC, r == E_SUCCESS, synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r)); pArgList.release(); SysLog(NID_LOC, "Wait till location manager gets the last location."); r = synchronizer.Wait(); SysTryCatch(NID_LOC, r == E_SUCCESS, synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r)); synchronizer.Exit(); SysLog(NID_LOC, "Last location(validity: %x, method: %ls) retrieved.", location.IsValid(), location.GetExtraInfo(L"location_method").GetPointer()); return location; CATCH: pArgList->RemoveAll(false); return location; } LocationAccuracy _LocationManager::GetAccuracyLevel(double horAcc) const { if (Double::IsNaN(horAcc)) { return LOC_ACCURACY_INVALID; } else if (horAcc <= 5.0) { return LOC_ACCURACY_FINEST; } else if (horAcc <= 10.0) { return LOC_ACCURACY_TEN_METERS; } else if (horAcc <= 100.0) { return LOC_ACCURACY_HUNDRED_METERS; } else if (horAcc <= 1000.0) { return LOC_ACCURACY_ONE_KILOMETER; } else if (horAcc <= 10000.0) { return LOC_ACCURACY_ANY; } else { return LOC_ACCURACY_INVALID; } } _LocationManager* _LocationManager::GetInstance(void) { static pthread_once_t onceBlock = PTHREAD_ONCE_INIT; if (__pUniqueInstance == null) { ClearLastResult(); pthread_once(&onceBlock, InitLocationManager); result r = GetLastResult(); if (IsFailed(r)) { onceBlock = PTHREAD_ONCE_INIT; } } return __pUniqueInstance; } void _LocationManager::AddToLocRequestInfoList(const _LocationRequestInfo* pLocRequestInfo) { std::unique_ptr< _LocationRequestInfo > pNewLocRequestInfo(new (std::nothrow) _LocationRequestInfo(*pLocRequestInfo)); SysTryReturnVoidResult(NID_LOC, pNewLocRequestInfo, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); __pLocRequestInfoList->Add(*pNewLocRequestInfo.get()); pNewLocRequestInfo.release(); if (__minRequestedAccuracy == LOC_ACCURACY_INVALID) { result r = _PowerManagerImpl::PowerControl(1, 1); SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to keep the CPU in awake state.", GetErrorMessage(r)); } SysLog(NID_LOC, "Total count of request info is (%d).", __pLocRequestInfoList->GetCount()); RestartLocationUpdates(); RestartUpdateTimer(); } void _LocationManager::RemoveFromLocRequestInfoList(RequestId reqId) { const int LIST_COUNT_ZERO = 0; int count = __pLocRequestInfoList->GetCount(); for (int i = 0; i < count; i++) { const _LocationRequestInfo* pLocRequestInfo = static_cast< const _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i)); if (reqId == pLocRequestInfo->GetRequestId()) { __pLocRequestInfoList->RemoveAt(i); break; } } SysLog(NID_LOC, "Total count of request info is (%d).", __pLocRequestInfoList->GetCount()); if (__pLocRequestInfoList->GetCount() == LIST_COUNT_ZERO) { _PowerManagerImpl::PowerControl(1, 0); __pLocUpdateTimer->Cancel(); location_manager_stop(__gpsHandler.handle); location_manager_stop(__wpsHandler.handle); Reset(); } else { RestartLocationUpdates(); RestartUpdateTimer(); } } void _LocationManager::AddToSyncLocationRequestInfoList(_SyncLocationRequestInfo& syncLocRequestInfo) { result r = syncLocRequestInfo.StartTimer(*this); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the sync timer.", GetErrorMessage(r)); r = __pSyncLocRequestInfoList->Add(syncLocRequestInfo); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to add the sync request into the list.", GetErrorMessage(r)); return; CATCH: StopLocationUpdates(syncLocRequestInfo.GetRequestId()); syncLocRequestInfo.GetLocationMonitor()->Notify(); delete &syncLocRequestInfo; } void _LocationManager::RemoveSyncLocRetrievalRequest(_SyncLocationRequestInfo& syncLocRequestInfo) { StopLocationUpdates(syncLocRequestInfo.GetRequestId()); __pSyncLocRequestInfoList->Remove(syncLocRequestInfo, true); } void _LocationManager::AddToAlarmRequestInfoList(_AlarmRequestInfo& alarmRequestInfo) { alarm_id_t alarmId; int res = alarmmgr_add_alarm_withcb(ALARM_TYPE_DEFAULT, alarmRequestInfo.GetInterval(), 0, AlarmExpiryCallback, this, &alarmId); SysTryReturnVoidResult(NID_LOC, res == ALARMMGR_RESULT_SUCCESS, E_SYSTEM, "Failed to add the alarm for next cycle."); SysLog(NID_LOC, "The alarm ID (%d) will be set to the request.", alarmId); alarmRequestInfo.SetAlarmId(alarmId); std::unique_ptr< _AlarmRequestInfo > pNewAlarmRequestInfo(new (std::nothrow) _AlarmRequestInfo(alarmRequestInfo)); SysTryReturnVoidResult(NID_LOC, pNewAlarmRequestInfo, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = __pAlarmRequestInfoList->Add(*pNewAlarmRequestInfo.get()); SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, E_SYSTEM, "Failed to add the alarm request into list."); pNewAlarmRequestInfo.release(); return; } void _LocationManager::RemoveFromAlarmRequestInfoList(RequestId reqId) { int count = __pAlarmRequestInfoList->GetCount(); SysLog(NID_LOC, "Total count of Alarm Request pending is (%d).", count); for (int i = 0; i < count; i++) { const _AlarmRequestInfo* pAlarmRequestInfo = static_cast< const _AlarmRequestInfo* >(__pAlarmRequestInfoList->GetAt(i)); if (reqId == pAlarmRequestInfo->GetRequestId()) { int res = alarmmgr_remove_alarm(pAlarmRequestInfo->GetAlarmId()); SysTryLog(NID_LOC, res == ALARMMGR_RESULT_SUCCESS, "Failed to remove the Alarm."); SysLog(NID_LOC, "The alarm with request Id (%d) and Alarm Id (%d) will be removed.", reqId, pAlarmRequestInfo->GetAlarmId()); __pAlarmRequestInfoList->RemoveAt(i); break; } } return; } void _LocationManager::RestartLocationUpdates(void) { int count = __pLocRequestInfoList->GetCount(); int result = 0; bool isAccuracyChanged = false; for (int i = 0; i < count; i++) { const _LocationRequestInfo* pLocRequestInfo = static_cast< const _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i)); if (__minRequestedAccuracy > pLocRequestInfo->GetAccuracy() || __minRequestedAccuracy == LOC_ACCURACY_INVALID) { __minRequestedAccuracy = pLocRequestInfo->GetAccuracy(); isAccuracyChanged = true; } } if (!isAccuracyChanged) { return; } SysLog(NID_LOC, "Location updates are restarted and new minimum requested Accuracy is (%d).", __minRequestedAccuracy); switch (__locMethodRequested) { case LOC_METHOD_REQUESTED_NONE: { SysLog(NID_LOC, "None of the methods running. Start all"); result = location_manager_start(__gpsHandler.handle); SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS."); result = location_manager_start(__wpsHandler.handle); SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS."); } break; case LOC_METHOD_REQUESTED_GPS: { SysLog(NID_LOC, "GPS Running. Start WPS."); result = location_manager_start(__wpsHandler.handle); SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS."); } break; case LOC_METHOD_REQUESTED_WPS: { SysLog(NID_LOC, "WPS Running. Start GPS."); result = location_manager_start(__gpsHandler.handle); SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS."); } break; case LOC_METHOD_REQUESTED_ALL: { SysLog(NID_LOC, "All the providers are already started."); } break; } __locationMgrState = LOC_MGR_STATE_FAST_SENSING; __locMethodRequested = LOC_METHOD_REQUESTED_ALL; } void _LocationManager::RestartUpdateTimer(void) { int gcd = 1; int count = __pLocRequestInfoList->GetCount(); __pLocUpdateTimer->Cancel(); if (count > 0) { const _LocationRequestInfo* pLocRequestInfo = static_cast< _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(0)); gcd = pLocRequestInfo->GetInterval(); for (int i = 1; i < count; i++) { pLocRequestInfo = static_cast< const _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i)); int interval = pLocRequestInfo->GetInterval(); if (gcd != interval) { while (gcd != 0 && interval != 0) { ((gcd > interval) ? gcd : interval) %= ((gcd > interval) ? interval : gcd); } gcd += interval; } } } __timerInterval = gcd; __timerTicks = 0; SysLog(NID_LOC, "Updated Timer interval is (%d).", __timerInterval); result r = __pLocUpdateTimer->Start(__timerInterval * 1000); if (IsFailed(r)) { SysLog(NID_LOC, "Failed to start the Location update timer."); } } void _LocationManager::HandleSyncRetrievalTimerExpiry(_SyncLocationRequestInfo& syncLocRequestInfo) { LocationAccuracy accuracy = LOC_ACCURACY_INVALID; DateTime timestamp = DateTime::GetMinValue(); const Location* pBestLoc = FindBestLocation(); SysLog(NID_LOC, "Location(timestamp: %ls, validity: %x, accuracy: %f) is retrieved.", pBestLoc->GetTimestamp().ToString().GetPointer(), pBestLoc->IsValid(), pBestLoc->GetHorizontalAccuracy()); if (pBestLoc->IsValid()) { accuracy = GetAccuracyLevel(pBestLoc->GetHorizontalAccuracy()); timestamp = pBestLoc->GetTimestamp(); } bool inTime = syncLocRequestInfo.IsInTime(timestamp); bool accurate = syncLocRequestInfo.IsAccuracySatisfying(accuracy); if (inTime && accurate) { unique_ptr< Location > pLocation(new (std::nothrow) Location(*pBestLoc)); SysTryCatchLabel(NID_LOC, pLocation != null, , NOTIFY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); syncLocRequestInfo.GetLocationMonitor()->SetLocation(pLocation.get()); pLocation.release(); goto NOTIFY; } if (syncLocRequestInfo.GetTickCount() > MAX_WAIT_TIME_FOR_SYNC_LOC) { if (inTime) { unique_ptr< Location > pLocation(new (std::nothrow) Location(*pBestLoc)); SysTryCatchLabel(NID_LOC, pLocation != null, , NOTIFY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); syncLocRequestInfo.GetLocationMonitor()->SetLocation(pLocation.get()); pLocation.release(); goto NOTIFY; } else { SysLog(NID_LOC, "Unable to fix the current location in %d ticks.", MAX_WAIT_TIME_FOR_SYNC_LOC); goto NOTIFY; } } SysLog(NID_LOC, "Wait for next location(Tick: %d).", syncLocRequestInfo.GetTickCount()); syncLocRequestInfo.StartTimer(*this); return; NOTIFY: syncLocRequestInfo.GetLocationMonitor()->Notify(); RemoveSyncLocRetrievalRequest(syncLocRequestInfo); } result _LocationManager::SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod, Location* pLocation) { SysSecureLog(NID_LOC, "Location Information is: Latitude (%lf), Longitude (%lf), Altitude (%lf), TimeStamp (%ld), Location method (%d)", latitude, longitude, altitude, timestamp, locMethod); int res = -1; LocationAccuracy requiredAcc; int rangeValue = 0; //Accuracy details. location_accuracy_level_e accLevel = LOCATIONS_ACCURACY_NONE; double horAcc = Tizen::Locations::NaN; double verAcc = Tizen::Locations::NaN; //Velocity details. double climb = Tizen::Locations::NaN; double direction = Tizen::Locations::NaN; double speed = Tizen::Locations::NaN; time_t time_stamp = 0; RequestId requestId; Location locationData = _LocationImpl::GetLocationInstance(); _LocationImpl* pLocDataImpl = _LocationImpl::GetInstance(locationData); switch (locMethod) { case LOCATIONS_METHOD_GPS: { res = location_manager_get_accuracy(__gpsHandler.handle, &accLevel, &horAcc, &verAcc); SysLog(NID_LOC, "Get Accuracy: Result (%d), Horizontal Acc (%lf), Vertical Acc (%lf)", res, horAcc, verAcc); SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Invalid accuracy values from Native Location Provider."); res = location_manager_get_velocity(__gpsHandler.handle, &climb, &direction, &speed, &time_stamp); SysLog(NID_LOC, "Get Velocity: Result (%d), Climb (%lf), Direction (%lf), Speed (%lf), Time stamp (%ld)", res, climb, direction, speed, time_stamp); SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Invalid accuracy values from Native Location Provider."); pLocDataImpl->SetExtraInfo(L"location_method", L"gps"); requestId = REQ_ID_SUSTAIN_GPS; } break; case LOCATIONS_METHOD_WPS: { res = location_manager_get_accuracy(__wpsHandler.handle, &accLevel, &horAcc, &verAcc); SysLog(NID_LOC, "Get Accuracy: Result (%d), Horizontal Acc (%lf), Vertical Acc (%lf)", res, horAcc, verAcc); SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Invalid accuracy values from Native Location Provider."); res = location_manager_get_velocity(__wpsHandler.handle, &climb, &direction, &speed, &time_stamp); SysTryLog(NID_LOC, res == 0, "Get Velocity: Result (%d), Climb (%lf), Direction (%lf), Speed (%lf), Time stamp (%ld)", res, climb, direction, speed, time_stamp); pLocDataImpl->SetExtraInfo(L"location_method", L"network"); requestId = REQ_ID_SUSTAIN_WPS; } break; default: SysTryReturn(NID_LOC, false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The location method is not valid"); } Coordinates coordinates; coordinates.Set(latitude, longitude, altitude); pLocDataImpl->SetCoordinates(coordinates); horAcc = ConvertToNativeFormat(horAcc); pLocDataImpl->SetHorizontalAccuracy(horAcc); verAcc = ConvertToNativeFormat(verAcc); pLocDataImpl->SetVerticalAccuracy(verAcc); pLocDataImpl->SetTimestamp((long long) timestamp * 1000); direction = ConvertToNativeFormat(direction); pLocDataImpl->SetCourse(direction); speed = ConvertToNativeFormat(speed); pLocDataImpl->SetSpeed(speed); pLocDataImpl->SetValidity(true); *pLocation = locationData; requiredAcc = __minRequestedAccuracy; switch (requiredAcc) { case LOC_ACCURACY_FINEST: rangeValue = ACCURACY_FINEST; break; case LOC_ACCURACY_TEN_METERS: rangeValue = ACCURACY_TEN_MTRS; break; case LOC_ACCURACY_HUNDRED_METERS: rangeValue = ACCURACY_HUNDRED_MTRS; break; case LOC_ACCURACY_ONE_KILOMETER: rangeValue = ACCURACY_ONE_KILOMETER; break; case LOC_ACCURACY_ANY: rangeValue = ACCURACY_ANY; break; case LOC_ACCURACY_INVALID: // follow through default: SysAssertf(false, "The Accuracy value is not defined."); } if (__locationMgrState == LOC_MGR_STATE_FAST_SENSING && (!Double::IsNaN(horAcc) && horAcc <= rangeValue)) { SysLog(NID_LOC, "State is LOC_MGR_STATE_FAST_SENSING and accuracy is within range. RequestId is (%d)", requestId); __locationMgrState = LOC_MGR_STATE_FAST_SENSING_SETTLED; SendUserEvent(requestId, null); } else { SysLog(NID_LOC, "State is LOC_MGR_STATE_FAST_SENSING_SETTLED and accuracy is out of range. Restart location updates."); SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null); } return E_SUCCESS; } void _LocationManager::SendLocationCallbacks(void) { const Location* pBestLocation = FindBestLocation(); SysLog(NID_LOC, "Send location(validity: %x) through the callback.", pBestLocation->IsValid()); unique_ptr< Location > pLocation(new (std::nothrow) Location(*pBestLocation)); SysTryReturnVoidResult(NID_LOC, pLocation != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); int interval = __timerTicks * __timerInterval; for (int i = 0; i < __pLocRequestInfoList->GetCount(); i++) { const _LocationRequestInfo* pLocRequestInfo = static_cast< const _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i)); if (interval % pLocRequestInfo->GetInterval() == 0 && pLocRequestInfo->GetListener() != null) { pLocRequestInfo->GetListener()->OnLocationUpdated(pLocRequestInfo->GetRequestId(), *pLocation.get()); } } } void _LocationManager::Reset(void) { __locMethodRequested = LOC_METHOD_REQUESTED_NONE; __locationMgrState = LOC_MGR_STATE_IDLE; __minRequestedAccuracy = LOC_ACCURACY_INVALID; __timerInterval = 0; __timerTicks = 0; } result _LocationManager::Construct() { result r = EventDrivenThread::Construct(); SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to Construct", GetErrorMessage(r)); std::unique_ptr< Monitor > pMonitor(new (std::nothrow) Monitor()); SysTryReturnResult(NID_LOC, pMonitor, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pMonitor->Construct(); SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to Construct Monitor. Propagating.", GetErrorMessage(r)); __pInitMonitor = pMonitor.release(); return E_SUCCESS; } Location _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod) { String locationMethod; location_manager_h nativeHandle = null; switch (nativeLocMethod) { case LOCATIONS_METHOD_GPS: { nativeHandle = __gpsHandler.handle; locationMethod = L"gps"; } break; case LOCATIONS_METHOD_WPS: { nativeHandle = __wpsHandler.handle; locationMethod = L"network"; } break; default: break; } SysLog(NID_LOC, "Last location requested(method: %x, handle: %x).", nativeLocMethod, nativeHandle); Location location = _LocationImpl::GetLocationInstance(); if (nativeHandle != null) { _LocationImpl* pLocationImpl = _LocationImpl::GetInstance(location); double altitude = Tizen::Locations::NaN; double latitude = Tizen::Locations::NaN; double longitude = Tizen::Locations::NaN; time_t timestampPosition = 0; int res = location_manager_get_last_position(nativeHandle, &altitude, &latitude, &longitude, ×tampPosition); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to fetch last position from nativeHandle(%x).", nativeHandle); SysSecureLog(NID_LOC, "Last position(latitude: %lf, longitude: %lf, altitude: %lf, timestamp: %ld", latitude, longitude, altitude, timestampPosition); altitude = ConvertToNativeFormatAltitude(altitude); Coordinates coord; coord.Set(latitude, longitude, altitude); pLocationImpl->SetCoordinates(coord); double horAcc = Tizen::Locations::NaN; double verAcc = Tizen::Locations::NaN; location_accuracy_level_e level; res = location_manager_get_last_accuracy(nativeHandle, &level, &horAcc, &verAcc); if (res == 0) { SysLog(NID_LOC, "Last accuracy(horAcc: %lf, vAcc: %lf, level: %x)", horAcc, verAcc, level); horAcc = ConvertToNativeFormat(horAcc); pLocationImpl->SetHorizontalAccuracy(horAcc); verAcc = ConvertToNativeFormat(verAcc); pLocationImpl->SetVerticalAccuracy(verAcc); } double climb = Tizen::Locations::NaN; double direction = Tizen::Locations::NaN; double speed = Tizen::Locations::NaN; time_t timestampVelocity = 0; res = location_manager_get_last_velocity(nativeHandle, &climb, &direction, &speed, ×tampVelocity); if (res == 0) { SysLog(NID_LOC, "Last velocity(climb: %lf, direction: %lf, speed: %lf, timestamp: %ld)", climb, direction, speed, timestampVelocity); direction = ConvertToNativeFormat(direction); pLocationImpl->SetCourse(direction); speed = ConvertToNativeFormat(speed); pLocationImpl->SetSpeed(speed); } if (nativeLocMethod == LOCATIONS_METHOD_GPS) { int satUsedCount = 0; int satViewCount = 0; time_t timestampSatellite = 0; String satInfo = L""; res = gps_status_get_last_satellite(nativeHandle, &satUsedCount, &satViewCount, ×tampSatellite); if (res == 0) { long timeDiff = abs(timestampPosition - timestampSatellite); res = gps_status_foreach_last_satellites_in_view(nativeHandle, SatelliteInfoUpdated, &satInfo); SysLog(NID_LOC, "Last satellite(foreachResult: %d, inUse: %d, inView: %d, timestamp: %ld, timeDiff: %ld)", res, satUsedCount, satViewCount, timestampSatellite, timeDiff); satInfo.Trim(); SysLog(NID_LOC, "Last satellite(info: %ls)", satInfo.GetPointer()); pLocationImpl->SetExtraInfo(L"satellite", satInfo); } } pLocationImpl->SetTimestamp(((long long) timestampPosition) * 1000); // in milliseconds pLocationImpl->SetValidity(true); pLocationImpl->SetExtraInfo(L"location_method", locationMethod); } ClearLastResult(); return location; CATCH: return location; } Location _LocationManager::GetRecentLocationAvailable(void) { long long gpsTimestamp = 0; long long wpsTimestamp = 0; Location lastGpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_GPS); if (lastGpsLocation.IsValid()) { gpsTimestamp = _LocationImpl::GetInstance(lastGpsLocation)->GetTimestampInMs(); } Location lastWpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_WPS); if (lastWpsLocation.IsValid()) { wpsTimestamp = _LocationImpl::GetInstance(lastWpsLocation)->GetTimestampInMs(); } SysLog(NID_LOC, "Compare timestamp(gps: %lld, wps: %lld) for recent location.", gpsTimestamp, wpsTimestamp); if (gpsTimestamp >= wpsTimestamp) { return lastGpsLocation; } else { return lastWpsLocation; } } void _LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval) { int count = __pLocRequestInfoList->GetCount(); for (int i = 0; i < count; i++) { _LocationRequestInfo* pLocRequestInfo = static_cast< _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i)); if (reqId == pLocRequestInfo->GetRequestId()) { pLocRequestInfo->SetInterval(interval); RestartUpdateTimer(); break; } } } const Location* _LocationManager::FindBestLocation(void) { switch (__locMethodRequested) { case LOC_METHOD_REQUESTED_GPS: { SysLog(NID_LOC, "GPS location provider running."); return __gpsHandler.pLocation.get(); } break; case LOC_METHOD_REQUESTED_WPS: { SysLog(NID_LOC, "WPS location provider running."); return __wpsHandler.pLocation.get(); } break; case LOC_METHOD_REQUESTED_ALL: { SysLog(NID_LOC, "All the methods are running. Get the best location among all the providers."); long long gpsTimestamp = 0; long long wpsTimestamp = 0; if (__gpsHandler.pLocation->IsValid()) { gpsTimestamp = _LocationImpl::GetInstance(*__gpsHandler.pLocation)->GetTimestampInMs(); } if (__wpsHandler.pLocation->IsValid()) { wpsTimestamp = _LocationImpl::GetInstance(*__wpsHandler.pLocation)->GetTimestampInMs(); } SysLog(NID_LOC, "Compare timestamp(gps: %lld, wps: %lld) of different locations.", gpsTimestamp, wpsTimestamp); if (gpsTimestamp > wpsTimestamp) { SysLog(NID_LOC, "GPS time stamp is greater than WPS."); return __gpsHandler.pLocation.get(); } else if (wpsTimestamp > gpsTimestamp) { SysLog(NID_LOC, "WPS time stamp is greater than GPS."); return __wpsHandler.pLocation.get(); } else if (gpsTimestamp == wpsTimestamp) { if (__gpsHandler.pLocation->GetHorizontalAccuracy() <= __wpsHandler.pLocation->GetHorizontalAccuracy()) { SysLog(NID_LOC, "GPS time stamp is equal to WPS and GPS accuracy is better than WPS."); return __gpsHandler.pLocation.get(); } else { SysLog(NID_LOC, "WPS time stamp is equal to GPS but WPS accuracy is better than GPS."); return __wpsHandler.pLocation.get(); } } } break; case LOC_METHOD_REQUESTED_NONE: // follow through default: SysLog(NID_LOC, "Location updates not running."); return null; } SysLog(NID_LOC, "Returning null as none of the conditions are satsfied."); return null; } result _LocationManager::GetLocation(location_method_e nativeLocMethod) { const int MAX_VALID_TIME_DIFFERENCE = 2000; double altitude = Tizen::Locations::NaN; double latitude = Tizen::Locations::NaN; double longitude = Tizen::Locations::NaN; time_t timestamp; int res = -1; int satellitesInViewCount = 0; int satellitesInUseCount = 0; time_t timestampSatellite = 0; String satInfo = L""; long long timeDiff = 0; location_manager_h nativeHandle = null; Location* pLocation = null; switch (nativeLocMethod) { case LOCATIONS_METHOD_GPS: { nativeHandle = __gpsHandler.handle; pLocation = __gpsHandler.pLocation.get(); } break; case LOCATIONS_METHOD_WPS: { nativeHandle = __wpsHandler.handle; pLocation = __wpsHandler.pLocation.get(); } break; default: break; } res = location_manager_get_position(nativeHandle, &altitude, &latitude, &longitude, ×tamp); SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Failed to obtain the natvie location information for the method (%x)", nativeLocMethod); if (res == 0) { altitude = ConvertToNativeFormatAltitude(altitude); result r = SetLocationInformation(latitude, longitude, altitude, timestamp, nativeLocMethod, pLocation); if (r != E_SUCCESS) { SysLog(NID_LOC, "Failed to set the location information"); } if (nativeLocMethod == LOCATIONS_METHOD_GPS) { res = gps_status_get_satellite(__gpsHandler.handle, &satellitesInUseCount, &satellitesInViewCount, ×tampSatellite); timeDiff = abs(timestamp - timestampSatellite); timeDiff = timeDiff * 1000; SysLog(NID_LOC, "Result (%d), Satellites in Use (%d), Satellites in View (%d), Time stamp (%ld), Time Difference (Loc and Sat) (%ld)", res, satellitesInUseCount, satellitesInViewCount, timestampSatellite, timeDiff); if (res == 0 && timeDiff <= MAX_VALID_TIME_DIFFERENCE) { res = gps_status_foreach_satellites_in_view(__gpsHandler.handle, SatelliteInfoUpdated, &satInfo); } satInfo.Trim(); SysLog(NID_LOC, "Result of get satellite is (%d) and satelliteInfo string representation is (%ls)", res, satInfo.GetPointer()); _LocationImpl::GetInstance(*__gpsHandler.pLocation.get())->SetExtraInfo(L"satellite", satInfo); } } return E_SUCCESS; } bool _LocationManager::OnStart(void) { SysTryReturn(NID_LOC, __pInitMonitor, false, E_INVALID_STATE, "[E_INVALID_STATE] __pInitMonitor must not be null."); int res = -1; std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pLocInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pLocInfoRequestList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Location Request list."); std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pSyncLocInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pSyncLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pSyncLocInfoRequestList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Sync Location Request list."); std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pAlarmInfoRequestList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pAlarmInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pAlarmInfoRequestList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Sync Location Request list."); unique_ptr< Tizen::Locations::Location > pGpsLocation(_LocationImpl::GetLocationInstanceN()); SysTryReturn(NID_LOC, pGpsLocation != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); unique_ptr< Tizen::Locations::Location > pWpsLocation(_LocationImpl::GetLocationInstanceN()); SysTryReturn(NID_LOC, pWpsLocation != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); std::unique_ptr< Tizen::Base::Runtime::Timer > pLocUpdateTimer(new (std::nothrow) Timer()); r = pLocUpdateTimer->Construct(*this); SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location timer."); res = location_manager_create(LOCATIONS_METHOD_GPS, &__gpsHandler.handle); SysTryReturn(NID_LOC, res == 0, false, E_SYSTEM, "[E_SYSTEM] Failed to create Native GPS Location provider."); res = location_manager_set_service_state_changed_cb(__gpsHandler.handle, GpsServiceUpdateCallback, this); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native GPS Location provider."); res = location_manager_create(LOCATIONS_METHOD_WPS, &__wpsHandler.handle); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native WPS Location provider."); res = location_manager_set_service_state_changed_cb(__wpsHandler.handle, WpsServiceUpdateCallback, this); SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native WPS Location provider."); __pLocRequestInfoList = std::move(pLocInfoRequestList); __pSyncLocRequestInfoList = std::move(pSyncLocInfoRequestList); __pAlarmRequestInfoList = std::move(pAlarmInfoRequestList); __pLocUpdateTimer = std::move(pLocUpdateTimer); __gpsHandler.pLocation = std::move(pGpsLocation); __wpsHandler.pLocation = std::move(pWpsLocation); r = __pInitMonitor->Enter(); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to Enter Monitor. Propagating.", GetErrorMessage(r)); r = __pInitMonitor->Notify(); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to Notify Monitor. Propagating.", GetErrorMessage(r)); r = __pInitMonitor->Exit(); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to Exit Monitor. Propagating.", GetErrorMessage(r)); SysLog(NID_LOC, "All the resources for location manager successfully created."); return true; CATCH: if (__gpsHandler.handle) { location_manager_destroy(__gpsHandler.handle); } if (__wpsHandler.handle) { location_manager_destroy(__wpsHandler.handle); } return false; } void _LocationManager::OnStop(void) { delete __pInitMonitor; __pInitMonitor = null; if (__gpsHandler.handle) { location_manager_destroy(__gpsHandler.handle); } if (__wpsHandler.handle) { location_manager_destroy(__wpsHandler.handle); } } void _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs) { const int ARRAY_LIST_CAPACITY = 1; switch (requestId) { case REQ_ID_START_LOC_UPDATES: { SysLog(NID_LOC, "REQ_ID_START_LOC_UPDATES"); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); _LocationRequestInfo* pLocRequestInfo = null; SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_CAPACITY, pArgs->RemoveAll(true), E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); pLocRequestInfo = static_cast< _LocationRequestInfo* >(pArgs->GetAt(0)); SysTryCatch(NID_LOC, pLocRequestInfo, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); AddToLocRequestInfoList(pLocRequestInfo); } break; case REQ_ID_STOP_LOC_UPDATES: { SysLog(NID_LOC, "REQ_ID_STOP_LOC_UPDATES"); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); Integer* pReqId = null; SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_CAPACITY, pArgs->RemoveAll(true), E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); pReqId = static_cast< Integer* >(pArgs->GetAt(0)); SysTryCatch(NID_LOC, pReqId, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); RemoveFromLocRequestInfoList(static_cast< long >(pReqId->ToInt())); } break; case REQ_ID_RESTART_LOC_UPDATES: { SysLog(NID_LOC, "REQ_ID_RESTART_LOC_UPDATES."); RestartLocationUpdates(); } break; case REQ_ID_SUSTAIN_GPS: { SysLog(NID_LOC, "REQ_ID_SUSTAIN_GPS."); location_manager_stop(__wpsHandler.handle); __locMethodRequested = LOC_METHOD_REQUESTED_GPS; } break; case REQ_ID_SUSTAIN_WPS: { SysLog(NID_LOC, "REQ_ID_SUSTAIN_WPS."); location_manager_stop(__gpsHandler.handle); __locMethodRequested = LOC_METHOD_REQUESTED_WPS; } break; case REQ_ID_SYNC_LOC_RETRIEVAL: { SysLog(NID_LOC, "REQ_ID_SYNC_LOC_RETRIEVAL."); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); _SyncLocationRequestInfo* pSyncLocRequestInfo = null; SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_CAPACITY, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(pArgs->GetAt(0)); SysTryCatch(NID_LOC, pSyncLocRequestInfo, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); AddToSyncLocationRequestInfoList(*pSyncLocRequestInfo); pArgs->RemoveAt(0); } break; case REQ_ID_GET_LAST_LOCATION: { SysLog(NID_LOC, "REQ_ID_GET_LAST_LOCATION"); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); Location* pLocation = static_cast< Location* >(pArgs->GetAt(0)); Monitor* pMonitor = static_cast< Monitor* >(pArgs->GetAt(1)); SysAssertf(pLocation != null && pMonitor != null, "Invalid request has been made on the location manager."); if (pMonitor != null) { pMonitor->Enter(); if (pLocation != null) { *pLocation = GetRecentLocationAvailable(); } pMonitor->Notify(); pMonitor->Exit(); } pArgs->RemoveAt(1); pArgs->RemoveAt(0); } break; case REQ_ID_UPDATE_INTERVAL: { const int ARRAY_LIST_LENGTH = 2; SysLog(NID_LOC, "REQ_ID_UPDATE_INTERVAL"); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_LENGTH, pArgs->RemoveAll(true), E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); Integer* pReqId = null; pReqId = static_cast< Integer* >(pArgs->GetAt(0)); SysTryCatch(NID_LOC, pReqId, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); Integer* pInterval = null; pInterval = static_cast< Integer* >(pArgs->GetAt(1)); SysTryCatch(NID_LOC, pInterval, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); UpdateLocRequestInfoList(static_cast< long >(pReqId->ToInt()), pInterval->ToInt()); } break; case REQ_ID_START_ALARM: { SysLog(NID_LOC, "REQ_ID_START_ALARM"); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); _AlarmRequestInfo* pAlarmRequestInfo = null; SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_CAPACITY, pArgs->RemoveAll(true), E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); pAlarmRequestInfo = static_cast< _AlarmRequestInfo* >(pArgs->GetAt(0)); SysTryCatch(NID_LOC, pAlarmRequestInfo, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); AddToAlarmRequestInfoList(*pAlarmRequestInfo); } break; case REQ_ID_STOP_ALARM: { SysLog(NID_LOC, "REQ_ID_STOP_ALARM"); SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored."); Integer* pReqId = null; SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_CAPACITY, pArgs->RemoveAll(true), E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); pReqId = static_cast< Integer* >(pArgs->GetAt(0)); SysTryCatch(NID_LOC, pReqId, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored."); RemoveFromAlarmRequestInfoList(static_cast< long >(pReqId->ToInt())); } break; } if (pArgs) { pArgs->RemoveAll(true); delete pArgs; } return; CATCH: pArgs->RemoveAll(true); delete pArgs; } void _LocationManager::OnTimerExpired(Tizen::Base::Runtime::Timer& timer) { if (__pLocUpdateTimer->Equals(timer)) { __timerTicks++; SysLog(NID_LOC, "LocationManager update timer expired. Timer Tick value is (%d).", __timerTicks); result r = E_SUCCESS; switch (__locMethodRequested) { case LOC_METHOD_REQUESTED_GPS: { r = GetLocation(LOCATIONS_METHOD_GPS); SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information"); if (IsFailed(r)) { SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null); } } break; case LOC_METHOD_REQUESTED_WPS: { r = GetLocation(LOCATIONS_METHOD_WPS); SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information"); if (IsFailed(r)) { SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null); } } break; case LOC_METHOD_REQUESTED_ALL: { if (__wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) { r = GetLocation(LOCATIONS_METHOD_WPS); SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information"); } else { SysLog(NID_LOC, "WPS Location not available at the Native side."); } if (__gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED) { r = GetLocation(LOCATIONS_METHOD_GPS); SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information"); } else { SysLog(NID_LOC, "GPS Location not available at the Native side."); } } break; case LOC_METHOD_REQUESTED_NONE: // follow through default: SysLog(NID_LOC, "Timer expired when no location update is called."); return; } __pLocUpdateTimer->Start(__timerInterval * 1000); SendLocationCallbacks(); } else { int count = __pSyncLocRequestInfoList->GetCount(); for (int i = 0; i < count; i++) { _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i)); if (pSyncLocRequestInfo != null && pSyncLocRequestInfo->Equals(timer)) { SysLog(NID_LOC, "Timer expired for the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId()); HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo); break; } } } return; } bool _LocationManager::SatelliteInfoUpdated(unsigned int azimuth, unsigned int elevation, unsigned int prn, int snr, bool is_active, void* user_data) { if (user_data == null) { SysLog(NID_LOC, "User data Null. Return."); return true; } String* pSatInfo = static_cast< String* >(user_data); SysLog(NID_LOC, "GPS Position Satellite Info: SatID (%d), Used (%d), Elevation (%d), Azimuth (%d), Snr (%d).", prn, is_active, elevation, azimuth, snr); pSatInfo->Append(static_cast< int >(prn)); pSatInfo->Append(", "); pSatInfo->Append(static_cast< int >(elevation)); pSatInfo->Append(", "); pSatInfo->Append(static_cast< int >(azimuth)); pSatInfo->Append(", "); pSatInfo->Append(snr); pSatInfo->Append(", "); pSatInfo->Append(is_active); pSatInfo->Append("; "); return true; } void _LocationManager::GpsServiceUpdateCallback(location_service_state_e state, void* user_data) { SysLog(NID_LOC, "Updated State is (%d).", state); if (user_data == null) { SysLog(NID_LOC, "User data is null. Return"); return; } _LocationManager* pThis = static_cast< _LocationManager* >(user_data); pThis->__gpsHandler.serviceState = state; } void _LocationManager::WpsServiceUpdateCallback(location_service_state_e state, void* user_data) { SysLog(NID_LOC, "Updated State is (%d).", state); if (user_data == null) { SysLog(NID_LOC, "User data is null. Return"); return; } _LocationManager* pThis = static_cast< _LocationManager* >(user_data); pThis->__wpsHandler.serviceState = state; } int _LocationManager::AlarmExpiryCallback(alarm_id_t alarm_id, void* user_param) { SysLog(NID_LOC, "The Alarm expired successfully for the alarm ID (%d).", alarm_id); if (user_param == null) { SysLog(NID_LOC, "The user parameter is null. So cannot handle the callback."); return -1; } _LocationManager* pThis = static_cast< _LocationManager* >(user_param); int count = pThis->__pAlarmRequestInfoList->GetCount(); for (int i = 0; i < count; i++) { _AlarmRequestInfo* pAlarmRequestInfo = static_cast< _AlarmRequestInfo* >(pThis->__pAlarmRequestInfoList->GetAt(i)); if (pAlarmRequestInfo) { if (alarm_id == pAlarmRequestInfo->GetAlarmId()) { pAlarmRequestInfo->GetListener()->OnAlarmExpired(); pThis->__pAlarmRequestInfoList->RemoveAt(i); break; } } } return 0; } void _LocationManager::InitLocationManager(void) { SysLog(NID_LOC, "Creating the first location manager instance."); unique_ptr< _LocationManager > pLocMgr(new (std::nothrow) _LocationManager()); SysTryReturnVoidResult(NID_LOC, pLocMgr, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pLocMgr->Construct(); SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to construct the Location Manager. Propagating.", GetErrorMessage(r)); r = pLocMgr->Start(); SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the Location Manager. Propagating.", GetErrorMessage(r)); r = pLocMgr->WaitUntilThreadStart(); SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to WaitUntilThreadStart. Propagating.", GetErrorMessage(r)); __pUniqueInstance = pLocMgr.release(); std::atexit(DestroyLocationManager); } void _LocationManager::DestroyLocationManager(void) { delete __pUniqueInstance; } result _LocationManager::WaitUntilThreadStart() { result r = __pInitMonitor->Enter(); SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to Enter Monitor. Propagating.", GetErrorMessage(r)); r = __pInitMonitor->Wait(); SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to Wait Monitor. Propagating.", GetErrorMessage(r)); r = __pInitMonitor->Exit(); SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to Exit Monitor. Propagating.", GetErrorMessage(r)); return E_SUCCESS; } }}