diff options
Diffstat (limited to 'src/FLoc_LocationProviderImpl.cpp')
-rw-r--r-- | src/FLoc_LocationProviderImpl.cpp | 171 |
1 files changed, 103 insertions, 68 deletions
diff --git a/src/FLoc_LocationProviderImpl.cpp b/src/FLoc_LocationProviderImpl.cpp index 2d25b79..57700ee 100644 --- a/src/FLoc_LocationProviderImpl.cpp +++ b/src/FLoc_LocationProviderImpl.cpp @@ -39,7 +39,7 @@ #include <FLocTypes.h> #include <FSysPowerManager.h> #include <FSysSystemTime.h> -#include <FSys_AlarmImpl.h> +#include <FSec_AccessController.h> #include <FSys_SettingInfoImpl.h> #include "FLoc_LocationImpl.h" #include "FLoc_LocationManager.h" @@ -54,6 +54,7 @@ using namespace Tizen::Base; using namespace Tizen::Base::Collection; using namespace Tizen::Base::Runtime; using namespace Tizen::Base::Utility; +using namespace Tizen::Security; using namespace Tizen::System; namespace Tizen { namespace Locations @@ -69,7 +70,7 @@ _LocationProviderImpl::_LocationProviderImpl(void) _LocationProviderImpl::~_LocationProviderImpl(void) { - UiApp* pAppInstance = Tizen::App::UiApp::GetInstance(); + UiApp* pAppInstance = UiApp::GetInstance(); if (pAppInstance) { _AppManagerImpl* pAppManager = _AppManagerImpl::GetInstance(); @@ -89,22 +90,17 @@ _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProv _LocationManager* pLocationManager = _LocationManager::GetInstance(); SysTryReturn(NID_LOC, pLocationManager != null, GetLastResult(), GetLastResult(), "[%s] Failed to get the location manager instance.", GetErrorMessage(GetLastResult())); - std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pRegionList(new (std::nothrow) ArrayList()); + std::unique_ptr< ArrayList, AllElementsDeleter > pRegionList(new (std::nothrow) ArrayList(SingleObjectDeleter)); SysTryReturn(NID_LOC, pRegionList != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pRegionList->Construct(); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the list. Propagating.", GetErrorMessage(r)); - std::unique_ptr< Tizen::Base::Runtime::Timer> pTimer (new (std::nothrow) Timer()); + std::unique_ptr< Timer > pTimer(new (std::nothrow) Timer()); SysTryReturn(NID_LOC, pTimer != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pTimer->Construct(*this); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the timer. Propagating.", GetErrorMessage(r)); - std::unique_ptr< Tizen::System::Alarm> pAlarm (new (std::nothrow) Alarm()); - SysTryReturn(NID_LOC, pAlarm != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - r = pAlarm->Construct(*this); - SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the alarm. Propagating.", GetErrorMessage(r)); - - UiApp* pAppInstance = Tizen::App::UiApp::GetInstance(); + UiApp* pAppInstance = UiApp::GetInstance(); if (pAppInstance != null) { _AppManagerImpl* pAppManager = _AppManagerImpl::GetInstance(); @@ -116,7 +112,7 @@ _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProv std::unique_ptr< Tizen::Locations::Location > pLastLocation(_LocationImpl::GetLocationInstanceN()); SysTryReturn(NID_LOC, pLastLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); - std::unique_ptr<Tizen::Locations::Location> pLastRegionLocation (_LocationImpl::GetLocationInstanceN()); + std::unique_ptr< Tizen::Locations::Location > pLastRegionLocation(_LocationImpl::GetLocationInstanceN()); SysTryReturn(NID_LOC, pLastRegionLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); _Event::Initialize(); @@ -124,10 +120,9 @@ _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProv __regionMonitor.pRegionList = std::move(pRegionList); __regionMonitor.pTimer = std::move(pTimer); - __regionMonitor.pAlarm = std::move(pAlarm); __regionMonitor.pLocation = std::move(pLastRegionLocation); __locationUpdater.pLocation = std::move(pLastLocation); - + __criteria = criteria; __pLocationListener = &listener; __pLocationManager = pLocationManager; @@ -187,7 +182,7 @@ _LocationProviderImpl::KeepLocationUpdateAwake(bool enable) } __locationUpdater.awakeEnabled = enable; - UiApp* appInstance = Tizen::App::UiApp::GetInstance(); + UiApp* appInstance = UiApp::GetInstance(); if (appInstance == null) // This is service APP. So should be handled now. { SysLog(NID_LOC, "Handling the request awake mode(%d) for the service application.", enable); @@ -266,7 +261,7 @@ _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId) _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__regionMonitor.pRegionList->GetAt(i)); if (regionId == pRegionInfo->GetRegionId()) { - __regionMonitor.pRegionList->RemoveAt(i, true); + __regionMonitor.pRegionList->RemoveAt(i); isIdValid = true; break; } @@ -413,12 +408,29 @@ _LocationProviderImpl::OnLocationUpdated(RequestId reqId, const Tizen::Locations } void +_LocationProviderImpl::OnAlarmExpired(void) +{ + SysLog(NID_LOC, "The call back of the Alarm expiry is called from location manager."); + + std::unique_ptr< _LocProviderEventArg > pLocProviderEventArg(new (std::nothrow) _LocProviderEventArg()); + SysTryReturnVoidResult(NID_LOC, pLocProviderEventArg, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); + + pLocProviderEventArg->SetEventType(_LOC_PRV_EVENT_SEND_ALARM_EXPIRY); + + result r = _Event::FireAsync(*pLocProviderEventArg); + SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to fire the event.", GetErrorMessage(r)); + pLocProviderEventArg.release(); + + return; +} + +void _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Locations::Location& location) { SysLog(NID_LOC, "Location Event received."); bool isNew = false; + bool isPrivilegeDenied = false; LocationAccuracy currentAccuracy = LOC_ACCURACY_INVALID; - LocationAccuracy lastLocAccuracy = __lastLocationAccuracy; long long lastLocationTime = 0; Location* pLocation = &location; @@ -443,6 +455,11 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location currentAccuracy = __pLocationManager->GetAccuracyLevel(pLocation->GetHorizontalAccuracy()); } + if (!GetUserPrivilege()) + { + isPrivilegeDenied = true; + } + if (currentAccuracy != __lastLocationAccuracy) { SysLog(NID_LOC, "Notify the accuracy change."); @@ -452,35 +469,39 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location if (reqId == __locationUpdater.reqId) { - HandleLocationUpdate(location, isNew); + HandleLocationUpdate(location, isNew, isPrivilegeDenied); } else if (reqId == __regionMonitor.reqId) { if (isNew) { bool gpsEnabled = false; + bool isAccuracyMet = false; _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.gps", gpsEnabled); SysLog(NID_LOC, "The GPS settings value is %d", gpsEnabled); - + __regionMonitor.speed = location.GetSpeed() * 0.2777778; - if ( currentAccuracy <= lastLocAccuracy || timeDifference > DEFAULT_THRESHOLD_LOC_VALIDITY_TIME_OUT) // Copy the location only if it is new and accuracy is better than before. + double currentHorAcc = pLocation->GetHorizontalAccuracy(); + double previousHorAcc = __regionMonitor.pLocation->GetHorizontalAccuracy(); + + + if (Double::IsNaN(previousHorAcc) || (!Double::IsNaN(currentHorAcc) && currentHorAcc <= previousHorAcc) || timeDifference > DEFAULT_THRESHOLD_LOC_VALIDITY_TIME_OUT) // Copy the location only if it is new and accuracy is better than before. { *__regionMonitor.pLocation = location; } - if ((currentAccuracy != LOC_ACCURACY_INVALID && currentAccuracy <= __criteria.GetAccuracy()) || !gpsEnabled) + if (!gpsEnabled || (currentAccuracy != LOC_ACCURACY_INVALID && currentAccuracy <= __criteria.GetAccuracy())) { SysLog(NID_LOC, "Location criteria (accuracy: %ld) is met for handling region monitoring.", currentAccuracy); - result r = __regionMonitor.pTimer->Cancel(); - SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to cancel the timer."); - - HandleRegionMonitoring(location, isNew); + isAccuracyMet = true; } else { SysLog(NID_LOC, "Location criteria (accuracy: %ld) is not met for handling region monitoring.", currentAccuracy); - } + } + + HandleRegionMonitoring(location, isNew, isPrivilegeDenied, isAccuracyMet); } } @@ -500,10 +521,18 @@ _LocationProviderImpl::OnRegionMonitoringStatusChanged(Tizen::Locations::Locatio } void +_LocationProviderImpl::OnAlarmExpiredEventReceived(void) +{ + SysLog(NID_LOC, "Region Monitor Alarm expired event received."); + result r = ActivateRegionMonitoring(true); + SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r)); +} + +void _LocationProviderImpl::OnActiveAppChanged(const Tizen::App::AppId& appId) { Tizen::App::App* pApp = Tizen::App::App::GetInstance(); - Tizen::App::AppId currentAppId = pApp->GetAppId(); + AppId currentAppId = pApp->GetAppId(); SysLog(NID_LOC, "Active App ID is (%ls) and the current app Id is (%ls)", appId.GetPointer(), currentAppId.GetPointer()); @@ -534,19 +563,10 @@ _LocationProviderImpl::OnActiveAppChanged(const Tizen::App::AppId& appId) } void -_LocationProviderImpl::OnAlarmExpired(Alarm& alarm) -{ - SysLog(NID_LOC, "Region Monitor Alarm expired."); - result r = ActivateRegionMonitoring(true); - SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r)); -} - -void _LocationProviderImpl::OnTimerExpired(Timer& timer) { SysLog(NID_LOC, "Region Monitor timer expired due to unavailability of location information."); - __pLocationManager->StopLocationUpdates(__regionMonitor.reqId); - HandleRegionMonitoring(*__regionMonitor.pLocation, __regionMonitor.pLocation->IsValid()); + HandleRegionMonitoring(*__regionMonitor.pLocation, __regionMonitor.pLocation->IsValid(), !GetUserPrivilege(), true); } result @@ -565,9 +585,9 @@ _LocationProviderImpl::StartLocationUpdates(LocationUpdateType updateType, int i __locationUpdater.distanceThreshold = distance; } - if (!__locationUpdater.awakeEnabled) + if (!__locationUpdater.awakeEnabled) { - UiApp* pAppInstance = Tizen::App::UiApp::GetInstance(); + UiApp* pAppInstance = UiApp::GetInstance(); if (pAppInstance == null) { startUpdate = false; @@ -599,11 +619,11 @@ _LocationProviderImpl::StartLocationUpdates(LocationUpdateType updateType, int i r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __locationUpdater.updateInterval, this, __locationUpdater.reqId); SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the Native location updates. Propagating.", GetErrorMessage(r)); __locationUpdater.status = LOC_SVC_STATUS_NOT_FIXED; - } + } } else { - __locationUpdater.status = LOC_SVC_STATUS_PAUSED; + __locationUpdater.status = LOC_SVC_STATUS_PAUSED; } __locationUpdater.type = updateType; @@ -672,27 +692,31 @@ _LocationProviderImpl::FireImpl(Tizen::Base::Runtime::IEventListener& listener, case _LOC_PRV_EVENT_SEND_MONITOR_SVC_CB: pLocProviderEventListener->OnRegionMonitoringStatusChanged(pEventArg->GetLocServiceStatus()); break; + + case _LOC_PRV_EVENT_SEND_ALARM_EXPIRY: + pLocProviderEventListener->OnAlarmExpiredEventReceived(); + break; } } void -_LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location, bool isNew) +_LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location, bool isNew, bool isPrivilegeDenied) { LocationServiceStatus newLocationUpdateStatus = __locationUpdater.status; - if (isNew) + if (isPrivilegeDenied) { + SysLog(NID_LOC, "User consent not available."); if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED) { - newLocationUpdateStatus = LOC_SVC_STATUS_RUNNING; + newLocationUpdateStatus = LOC_SVC_STATUS_DENIED; } } - else if (!GetUserPrivilege()) + else if (isNew) { - SysLog(NID_LOC, "User consent not available."); if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED) { - newLocationUpdateStatus = LOC_SVC_STATUS_DENIED; + newLocationUpdateStatus = LOC_SVC_STATUS_RUNNING; } } else @@ -732,17 +756,17 @@ _LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location } void -_LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& location, bool isNew) +_LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& location, bool isNew, bool isPrivilegeDenied, bool isAccuracyMet) { LocationServiceStatus newRegionMonitorStatus = __regionMonitor.status; - if (isNew) + if (isPrivilegeDenied) { - newRegionMonitorStatus = LOC_SVC_STATUS_RUNNING; + newRegionMonitorStatus = LOC_SVC_STATUS_DENIED; } - else if (!GetUserPrivilege()) + else if (isNew) { - newRegionMonitorStatus = LOC_SVC_STATUS_DENIED; + newRegionMonitorStatus = LOC_SVC_STATUS_RUNNING; } else { @@ -756,12 +780,16 @@ _LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& locati __pLocationListener->OnRegionMonitoringStatusChanged(__regionMonitor.status); } - if (newRegionMonitorStatus == LOC_SVC_STATUS_RUNNING) + if (isAccuracyMet) { - NotifyRegionCrossedStatus(location); + result r = __regionMonitor.pTimer->Cancel(); + SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to cancel the timer."); + if (newRegionMonitorStatus == LOC_SVC_STATUS_RUNNING) + { + NotifyRegionCrossedStatus(location); + } + SetNextRegionMonitoringTime(); } - - SetNextRegionMonitoringTime(); } void @@ -815,12 +843,17 @@ _LocationProviderImpl::NotifyRegionCrossedStatus(const Tizen::Locations::Locatio _RegionState _LocationProviderImpl::GetRegionCurrentState(const _RegionInfo& region, const Location& location) { - TryReturn(location.GetHorizontalAccuracy() >= 0.0, REGION_STATE_UNKNOWN, "Location received with invalid accuracy"); + double horAcc = location.GetHorizontalAccuracy(); + if (Double::IsNaN(horAcc)) + { + horAcc = 0.0; + } + TryReturn(horAcc >= 0.0, REGION_STATE_UNKNOWN, "Location received with invalid accuracy"); SysSecureLog(NID_LOC, "[RegionID %d] Region Information is (Center latitude: %lf, Center longitude: %lf, Region radius:%lf", region.GetRegionId(), region.GetCoordinate().GetLatitude(), - region.GetCoordinate().GetLongitude(), region.GetRadius()); + region.GetCoordinate().GetLongitude(), region.GetRadius()); SysSecureLog(NID_LOC, "[RegionID %d] Location Information is (Latitude: %lf, Longitude: %lf, Horizontal accuracy:%lf", region.GetRegionId(), location.GetCoordinates().GetLatitude(), - location.GetCoordinates().GetLongitude(), location.GetHorizontalAccuracy()); + location.GetCoordinates().GetLongitude(), location.GetHorizontalAccuracy()); _RegionState regionState = REGION_STATE_UNKNOWN; double distanceBtwCenters = region.GetCoordinate().GetDistanceTo(location.GetCoordinates()); @@ -923,6 +956,10 @@ _LocationProviderImpl::GetUserPrivilege(void) { return false; } + + result r = _AccessController::CheckUserPrivilege(_PRV_LOCATION); + SysTryReturn(NID_LOC, r == E_SUCCESS, false, r, "[%s] The user does not allow the application to use location information.", GetErrorMessage(r)); + return true; } @@ -944,25 +981,25 @@ _LocationProviderImpl::ActivateRegionMonitoring(bool startUpdate) } result r = __regionMonitor.pTimer->Start(DEFAULT_WAITING_TIME * 1000); - SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the timer. Propogating.", GetErrorMessage(r)); + SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the timer. Propogating.", GetErrorMessage(r)); if (startUpdate) { _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetValidity(false); - _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetTimestamp(currentTime); + _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetTimestamp(currentTime); r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), MIN_LOCATION_UPDATE_INTERVAL, this, __regionMonitor.reqId); SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the location updates. Propogating.", GetErrorMessage(r)); SysLog(NID_LOC, "Location updates started."); } - + return E_SUCCESS; } void _LocationProviderImpl::StopRegionMonitoring(void) { - result r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Cancel(); + result r = __pLocationManager->RequestStopAlarm(__regionMonitor.reqId); SysTryLog(NID_LOC, r == E_SUCCESS, "[%s] Failed to stop the alarm. Ignored.", GetErrorMessage(r)); r = __regionMonitor.pTimer->Cancel(); @@ -992,7 +1029,7 @@ _LocationProviderImpl::SetNextRegionMonitoringTime(void) const int bufferTime = 5; //Buffer of 5 seconds for determining the alarmTime; double minDistance = _MathUtils::GetShortestDistance(*__regionMonitor.pLocation, *__regionMonitor.pRegionList); - long long newAlarmTime = ((int) minDistance / speed) - bufferTime; //Calculate the alarm time based on the shortest distance between current location and nearest region boundary. + long long newAlarmTime = ((int) minDistance / speed) - bufferTime; //Calculate the alarm time based on the shortest distance between current location and nearest region boundary. if (newAlarmTime < DEFAULT_REGION_MONITORING_CYCLE_INTERVAL) { @@ -1008,11 +1045,9 @@ _LocationProviderImpl::SetNextRegionMonitoringTime(void) result r = __pLocationManager->StopLocationUpdates(__regionMonitor.reqId); SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to stop the location updates."); - - alarmDateTime.AddSeconds(alarmTime); - r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Set(alarmDateTime, 0, null); - SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to set the alarm for next cycle."); - + + r = __pLocationManager->RequestStartAlarm(alarmTime, this, __regionMonitor.reqId); + SysLog(NID_LOC, "Next alarm expires after %ld seconds.", alarmTime); } }} |