#include <FLocTypes.h>
#include <FSysPowerManager.h>
#include <FSysSystemTime.h>
+#include <FSys_AlarmImpl.h>
#include <FSys_SettingInfoImpl.h>
+#include "FLoc_Config.h"
#include "FLoc_LocationImpl.h"
#include "FLoc_LocationManager.h"
#include "FLoc_LocationMonitor.h"
_LocationProviderImpl::_LocationProviderImpl(void)
: Tizen::Base::Runtime::_Event()
- , __firstLocationUpdate(true)
- , __regionMonitoringActive(false)
- , __awakeEnabled(false)
- , __updateInterval(0)
- , __locationUpdateType(_LOCATION_UPDATE_TYPE_NONE)
- , __locationUpdateStatus(LOC_SVC_STATUS_IDLE)
- , __regionMonitorStatus(LOC_SVC_STATUS_IDLE)
, __lastLocationAccuracy(LOC_ACCURACY_INVALID)
- , __reqId(-1)
- , __regionReqId(-1)
- , __distanceThreshold(0.0)
, __pLocationListener(null)
, __pLocationManager(null)
- , __pLastLocation(null)
- , __pRegionList(null)
{
}
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());
+ 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();
if (pAppInstance != null)
{
SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Error occured during adding the event listener to app manager. Propagating.", GetErrorMessage(r));
}
- std::unique_ptr< Tizen::Locations::Location > pLocation(_LocationImpl::GetLocationInstanceN());
- SysTryReturn(NID_LOC, pLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+ 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());
+ SysTryReturn(NID_LOC, pLastRegionLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
_Event::Initialize();
_Event::AddListener(*this);
- __pRegionList = std::move(pRegionList);
- __pLastLocation = std::move(pLocation);
+ __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;
SysTryReturn(NID_LOC, interval >= 1, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The interval(%d) should be greater than or equal to 1", interval);
- if (__locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL && __updateInterval == interval)
+ if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_INTERVAL && __locationUpdater.updateInterval == interval)
{
return E_SUCCESS;
}
- else if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE || __locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL)
- {
- __pLocationManager->StopLocationUpdates(__reqId);
- __locationUpdateStatus = LOC_SVC_STATUS_IDLE;
- }
const double INVALID_DISTANCE_THRESHOLD = 0.0;
return StartLocationUpdates(_LOCATION_UPDATE_TYPE_INTERVAL, interval, INVALID_DISTANCE_THRESHOLD);
SysTryReturn(NID_LOC, Double::IsNaN(distance) == false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The distance is NaN.");
- if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE && (Double::Compare(__distanceThreshold, distance) == 0))
+ if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_DISTANCE && (Double::Compare(__locationUpdater.distanceThreshold, distance) == 0))
{
return E_SUCCESS;
}
- else if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE || __locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL)
- {
- __pLocationManager->StopLocationUpdates(__reqId);
- __locationUpdateStatus = LOC_SVC_STATUS_IDLE;
- }
const int INVALID_INTERVAL = 0;
return StartLocationUpdates(_LOCATION_UPDATE_TYPE_DISTANCE, INVALID_INTERVAL, distance);
result
_LocationProviderImpl::StopLocationUpdates(void)
{
- SysLog(NID_LOC, "Stopping the location updates for the request ID (%ld)", __reqId);
+ SysLog(NID_LOC, "Stopping the location updates for the request ID (%ld)", __locationUpdater.reqId);
- SysTryReturn(NID_LOC, __locationUpdateType != _LOCATION_UPDATE_TYPE_NONE, E_INVALID_OPERATION, E_INVALID_OPERATION, "[E_INVALID_OPERATION] Location update has not been requested.");
+ SysTryReturn(NID_LOC, __locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE, E_INVALID_OPERATION, E_INVALID_OPERATION, "[E_INVALID_OPERATION] Location update has not been requested.");
- result r = __pLocationManager->StopLocationUpdates(__reqId);
+ result r = __pLocationManager->StopLocationUpdates(__locationUpdater.reqId);
ResetLocationUpdates();
void
_LocationProviderImpl::KeepLocationUpdateAwake(bool enable)
{
- if (__awakeEnabled == enable)
+ if (__locationUpdater.awakeEnabled == enable)
{
return;
}
- __awakeEnabled = enable;
+ __locationUpdater.awakeEnabled = enable;
UiApp* appInstance = Tizen::App::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);
if (enable == true)
{
- if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus == LOC_SVC_STATUS_PAUSED)
+ if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status == LOC_SVC_STATUS_PAUSED)
{
- SysLog(NID_LOC, "Requesting to start the location updates as the update type is (%x)", __locationUpdateType);
- __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
- __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
+ SysLog(NID_LOC, "Requesting to start the location updates as the update type is (%x)", __locationUpdater.type);
+ __locationUpdater.status = LOC_SVC_STATUS_NOT_FIXED;
+ __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __locationUpdater.updateInterval, this, __locationUpdater.reqId);
- NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdateStatus);
+ NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdater.status);
}
}
else
{
- if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && (__locationUpdateStatus == LOC_SVC_STATUS_RUNNING || __locationUpdateStatus == LOC_SVC_STATUS_NOT_FIXED))
+ if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && (__locationUpdater.status == LOC_SVC_STATUS_RUNNING || __locationUpdater.status == LOC_SVC_STATUS_NOT_FIXED))
{
- SysLog(NID_LOC, "Requesting to stop the location updates as the update type is (%x)", __locationUpdateType);
- __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
- __pLocationManager->StopLocationUpdates(__reqId);
+ SysLog(NID_LOC, "Requesting to stop the location updates as the update type is (%x)", __locationUpdater.type);
+ __locationUpdater.status = LOC_SVC_STATUS_PAUSED;
+ __pLocationManager->StopLocationUpdates(__locationUpdater.reqId);
- NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdateStatus);
+ NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdater.status);
}
}
}
SysLog(NID_LOC, "Requested to add the monitoring region with center (Latitude: %lf, Longitude %lf) and radius (%lf).", regionCenter.GetLatitude(), regionCenter.GetLongitude(), radius);
- const int DEAULT_REGION_MONITOR_INTERVAL = 5;
static int nextRegionId = 0;
result r = E_SUCCESS;
std::unique_ptr< _RegionInfo > pRegionInfo(new (std::nothrow) _RegionInfo(regionCenter, radius, nextRegionId));
SysTryReturn(NID_LOC, pRegionInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
- r = __pRegionList->Add(*pRegionInfo.get());
+ r = __regionMonitor.pRegionList->Add(*pRegionInfo.get());
SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to add the Region info into the list. Propogated.", GetErrorMessage(r));
pRegionInfo.release();
regionId = nextRegionId;
nextRegionId++;
- if (__regionMonitoringActive == true)
+ if (__regionMonitor.status != LOC_SVC_STATUS_IDLE)
{
return E_SUCCESS;
}
- r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), DEAULT_REGION_MONITOR_INTERVAL, this, __regionReqId);
- SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the location updates. Propogating.", GetErrorMessage(r));
+ r = ActivateRegionMonitoring();
+ SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r));
- __regionMonitoringActive = true;
- __regionMonitorStatus = LOC_SVC_STATUS_NOT_FIXED;
- NotifyServiceStatus(_LOC_PRV_EVENT_SEND_MONITOR_SVC_CB, __regionMonitorStatus);
+ __regionMonitor.status = LOC_SVC_STATUS_NOT_FIXED;
+ NotifyServiceStatus(_LOC_PRV_EVENT_SEND_MONITOR_SVC_CB, __regionMonitor.status);
return E_SUCCESS;
+
+CATCH:
+ __regionMonitor.pRegionList->RemoveAt(0);
+ return r;
}
result
_LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
{
- int count = __pRegionList->GetCount();
- result r = E_SUCCESS;
+ int count = __regionMonitor.pRegionList->GetCount();
bool isIdValid = false;
SysLog(NID_LOC, "Total regions currently monitored is (%d).", count);
for (int i = 0; i < count; i++)
{
- _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__pRegionList->GetAt(i));
+ _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__regionMonitor.pRegionList->GetAt(i));
if (regionId == pRegionInfo->GetRegionId())
{
- __pRegionList->RemoveAt(i, true);
+ __regionMonitor.pRegionList->RemoveAt(i, true);
isIdValid = true;
break;
}
SysTryReturn(NID_LOC, isIdValid == true, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The region ID is invalid.");
- if (__pRegionList->GetCount() == 0)
+ if (__regionMonitor.pRegionList->GetCount() == 0)
{
- __regionMonitoringActive = false;
- __regionMonitorStatus = LOC_SVC_STATUS_IDLE;
- if (__locationUpdateStatus == LOC_SVC_STATUS_IDLE) // As we are using the same variable for both region monitoring and location updates, this set is required here.
+ __regionMonitor.status = LOC_SVC_STATUS_IDLE;
+ if (__locationUpdater.status == LOC_SVC_STATUS_IDLE) // As we are using the same variable for both region monitoring and location updates, this set is required here.
{
__lastLocationAccuracy = LOC_ACCURACY_INVALID;
}
- r = __pLocationManager->StopLocationUpdates(__regionReqId);
- SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] All regions are removed but failed to stop the location updates. Propagating.", GetErrorMessage(r));
+ StopRegionMonitoring();
}
return E_SUCCESS;
void
_LocationProviderImpl::RemoveAllMonitoringRegions(void)
{
- result r = E_SUCCESS;
+ __regionMonitor.pRegionList->RemoveAll(true);
- __pRegionList->RemoveAll(true);
-
- if (__regionMonitoringActive == true)
+ if (__regionMonitor.status != LOC_SVC_STATUS_IDLE)
{
- __regionMonitoringActive = false;
- __regionMonitorStatus = LOC_SVC_STATUS_IDLE;
- if (__locationUpdateStatus == LOC_SVC_STATUS_IDLE) // As we are using the same variable for both region monitoring and location updates, this set is required here.
+ __regionMonitor.status = LOC_SVC_STATUS_IDLE;
+ if (__locationUpdater.status == LOC_SVC_STATUS_IDLE) // As we are using the same variable for both region monitoring and location updates, this set is required here.
{
__lastLocationAccuracy = LOC_ACCURACY_INVALID;
}
- r = __pLocationManager->StopLocationUpdates(__regionReqId);
- SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] All regions are removed but failed to stop the location updates. Ignored.", GetErrorMessage(r));
+ StopRegionMonitoring();
}
return;
LocationServiceStatus
_LocationProviderImpl::GetLocationUpdateStatus(void) const
{
- return __locationUpdateStatus;
+ return __locationUpdater.status;
}
LocationServiceStatus
_LocationProviderImpl::GetRegionMonitoringStatus(void) const
{
- return __regionMonitorStatus;
+ return __regionMonitor.status;
}
LocationAccuracy
Location* pLocation = &location;
_LocationImpl* pLocationImpl = _LocationImpl::GetInstance(*pLocation);
- if (__pLastLocation)
+
+ if (reqId == __locationUpdater.reqId)
{
- lastLocationTime = _LocationImpl::GetInstance(*__pLastLocation.get())->GetTimestampInMs();
+ SysLog(NID_LOC, "The location is updated for Location request.");
+ lastLocationTime = _LocationImpl::GetInstance(*__locationUpdater.pLocation.get())->GetTimestampInMs();
+ }
+ else if (reqId == __regionMonitor.reqId)
+ {
+ SysLog(NID_LOC, "The location is updated for Region monitoring.");
+ lastLocationTime = _LocationImpl::GetInstance(*__regionMonitor.pLocation.get())->GetTimestampInMs();
}
- long long timeDifference = abs(pLocationImpl->GetTimestampInMs() - lastLocationTime);
+ long long timeDifference = pLocationImpl->GetTimestampInMs() - lastLocationTime;
SysLog(NID_LOC, "Time difference between last location timestamp (%lld) and current location timestamp (%lld) is (%lld).", lastLocationTime, pLocationImpl->GetTimestampInMs(), timeDifference);
if (timeDifference > 0)
{
__pLocationListener->OnAccuracyChanged(currentAccuracy);
}
- if (reqId == __reqId)
+ if (reqId == __locationUpdater.reqId)
{
HandleLocationUpdate(location, isNew);
}
- else if (reqId == __regionReqId)
+ else if (reqId == __regionMonitor.reqId)
{
- HandleRegionMonitoring(location, isNew);
+ if (isNew) // Copy the location only if it is new.
+ {
+ *__regionMonitor.pLocation = location;
+ }
+
+ if (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.");
+
+ r = __pLocationManager->StopLocationUpdates(__regionMonitor.reqId);
+ SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to stop the location updates.");
+ HandleRegionMonitoring(location, isNew);
+ }
+ else
+ {
+ SysLog(NID_LOC, "Location criteria (accuracy: %ld) is not met for handling region monitoring.", currentAccuracy);
+ }
}
delete pLocation;
{
SysLog(NID_LOC, "Application is active.");
- if (__locationUpdateStatus == LOC_SVC_STATUS_PAUSED)
+ if (__locationUpdater.status == LOC_SVC_STATUS_PAUSED)
{
SysLog(NID_LOC, "Start the location updates as the location update status is PAUSED.");
- __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
- __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
- __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdateStatus);
+ __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __locationUpdater.updateInterval, this, __locationUpdater.reqId);
+ __locationUpdater.status = LOC_SVC_STATUS_NOT_FIXED;
+ __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdater.status);
}
}
else
{
SysLog(NID_LOC, "Application is not active.");
- if (__awakeEnabled == false && (__locationUpdateStatus == LOC_SVC_STATUS_RUNNING || __locationUpdateStatus == LOC_SVC_STATUS_NOT_FIXED))
+
+ if (__locationUpdater.awakeEnabled == false && (__locationUpdater.status == LOC_SVC_STATUS_RUNNING || __locationUpdater.status == LOC_SVC_STATUS_NOT_FIXED))
{
- SysLog(NID_LOC, "Stop the location updates as application is not active with awake mode as (%d) and location update state as (%x).", __awakeEnabled, __locationUpdateStatus);
- __pLocationManager->StopLocationUpdates(__reqId);
- __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
- __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdateStatus);
+ SysLog(NID_LOC, "Stop the location updates as application is not active with awake mode as (%d) and location update state as (%x).", __locationUpdater.awakeEnabled, __locationUpdater.status);
+ __pLocationManager->StopLocationUpdates(__locationUpdater.reqId);
+ __locationUpdater.status = LOC_SVC_STATUS_PAUSED;
+ __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdater.status);
}
}
}
+void
+_LocationProviderImpl::OnAlarmExpired(Alarm& alarm)
+{
+ SysLog(NID_LOC, "Region Monitor Alarm expired.");
+
+ result r = ActivateRegionMonitoring();
+ 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());
+}
+
result
_LocationProviderImpl::StartLocationUpdates(LocationUpdateType updateType, int interval, double distance)
{
result r = E_SUCCESS;
- const int CHECKING_INTERVAL = 10;
+ bool startUpdate = true;
if (updateType == _LOCATION_UPDATE_TYPE_INTERVAL)
{
- __updateInterval = interval;
+ __locationUpdater.updateInterval = interval;
}
else if (updateType == _LOCATION_UPDATE_TYPE_DISTANCE)
{
- __updateInterval = CHECKING_INTERVAL;
- __distanceThreshold = distance;
+ __locationUpdater.updateInterval = DEFAULT_DISTANCE_CHECKING_INTERVAL;
+ __locationUpdater.distanceThreshold = distance;
}
- __locationUpdateType = updateType;
-
- if (__awakeEnabled == true)
- {
- r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
- SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the Native location updates.", GetErrorMessage(r));
- __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
- }
- else
+ if (!__locationUpdater.awakeEnabled)
{
UiApp* pAppInstance = Tizen::App::UiApp::GetInstance();
if (pAppInstance == null)
{
- __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
+ startUpdate = false;
}
- else
+ else
{
AppUiState appUiState = pAppInstance->GetAppUiState();
- if (appUiState == APP_UI_STATE_FOREGROUND || appUiState == APP_UI_STATE_PARTIAL_BACKGROUND)
- {
- r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
- SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the location updates. Propagating.", GetErrorMessage(r));
- __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
- }
- else
+
+ if (appUiState == APP_UI_STATE_BACKGROUND)
{
- __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
+ SysLog(NID_LOC, "App is background.");
+ startUpdate = false;
}
}
}
- SysLog(NID_LOC, "Update type is (%x). The request Id is (%ld) and the update status is (%x).", __locationUpdateType, __reqId, __locationUpdateStatus);
- NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdateStatus);
+ if (startUpdate)
+ {
+ if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE)
+ {
+ SysLog(NID_LOC, "Update session already running. Updating the interval to %d seconds", __locationUpdater.updateInterval);
+ r = __pLocationManager->ChangeUpdateInterval(__locationUpdater.reqId, __locationUpdater.updateInterval);
+ SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to update the request interval. Propagating.", GetErrorMessage(r));
+ __locationUpdater.type = updateType;
+ return E_SUCCESS;
+ }
+ else
+ {
+ 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.type = updateType;
+
+ SysLog(NID_LOC, "Update type is (%x). The request Id is (%ld) and the update status is (%x).", __locationUpdater.type, __locationUpdater.reqId, __locationUpdater.status);
+ NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdater.status);
return E_SUCCESS;
CATCH:
- __locationUpdateType = _LOCATION_UPDATE_TYPE_NONE;
+ __locationUpdater.type = _LOCATION_UPDATE_TYPE_NONE;
return r;
}
const Coordinates coordOld = oldPosition.GetCoordinates();
const Coordinates coordNew = newPosition.GetCoordinates();
- if (__firstLocationUpdate)
+ if (__locationUpdater.firstLocationUpdate)
{
SysLog(NID_LOC, "First location update. So send true.");
- __firstLocationUpdate = false;
+ __locationUpdater.firstLocationUpdate = false;
return true;
}
displacement = coordOld.GetDistanceTo(coordNew);
SysLog(NID_LOC, "Displacement is (%lf)", displacement);
- return ((displacement > __distanceThreshold) ? true : false);
+ return ((displacement > __locationUpdater.distanceThreshold) ? true : false);
}
void
_LocationProviderImpl::ResetLocationUpdates(void)
{
- __firstLocationUpdate = true;
- __reqId = -1;
+ __locationUpdater.firstLocationUpdate = true;
+ __locationUpdater.reqId = -1;
__lastLocationAccuracy = LOC_ACCURACY_INVALID;
- __locationUpdateType = _LOCATION_UPDATE_TYPE_NONE;
- __locationUpdateStatus = LOC_SVC_STATUS_IDLE;
- __updateInterval = 0;
- __distanceThreshold = 0.0;
+ __locationUpdater.type = _LOCATION_UPDATE_TYPE_NONE;
+ __locationUpdater.status = LOC_SVC_STATUS_IDLE;
+ __locationUpdater.updateInterval = 0;
+ __locationUpdater.distanceThreshold = 0.0;
}
void
void
_LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location, bool isNew)
{
- LocationServiceStatus newLocationUpdateStatus = __locationUpdateStatus;
+ LocationServiceStatus newLocationUpdateStatus = __locationUpdater.status;
if (isNew)
{
- if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus != LOC_SVC_STATUS_PAUSED)
+ if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
{
newLocationUpdateStatus = LOC_SVC_STATUS_RUNNING;
}
else if (_LocationImpl::GetInstance(location)->IsDenied())
{
SysLog(NID_LOC, "User consent not available.");
- if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus != LOC_SVC_STATUS_PAUSED)
+ if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
{
newLocationUpdateStatus = LOC_SVC_STATUS_DENIED;
}
else
{
SysLog(NID_LOC, "Invalid Location Update.");
- if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus != LOC_SVC_STATUS_PAUSED)
+ if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
{
newLocationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
}
}
- if (newLocationUpdateStatus != __locationUpdateStatus)
+ if (newLocationUpdateStatus != __locationUpdater.status)
{
SysLog(NID_LOC, "Location Update Satus changed to (%x). Notify the status.", newLocationUpdateStatus);
- __locationUpdateStatus = newLocationUpdateStatus;
- __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdateStatus);
+ __locationUpdater.status = newLocationUpdateStatus;
+ __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdater.status);
}
if (newLocationUpdateStatus == LOC_SVC_STATUS_RUNNING)
{
- if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE)
+ if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_DISTANCE)
{
- if (CheckDistanceThreshold(*__pLastLocation.get(), location) == true)
+ if (CheckDistanceThreshold(*__locationUpdater.pLocation.get(), location) == true)
{
- SysLog(NID_LOC, "Location displacement exceeds the distance threshold (%lf). Notify the location.", __distanceThreshold);
+ SysLog(NID_LOC, "Location displacement exceeds the distance threshold (%lf). Notify the location.", __locationUpdater.distanceThreshold);
__pLocationListener->OnLocationUpdated(location);
- *__pLastLocation.get() = location;
+ *__locationUpdater.pLocation.get() = location;
}
}
- else if (__locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL)
+ else if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_INTERVAL)
{
SysLog(NID_LOC, "Location time interval expired. Notify the location.");
__pLocationListener->OnLocationUpdated(location);
- *__pLastLocation.get() = location;
+ *__locationUpdater.pLocation.get() = location;
}
}
}
void
_LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& location, bool isNew)
{
- LocationServiceStatus newRegionMonitorStatus = __regionMonitorStatus;
+ LocationServiceStatus newRegionMonitorStatus = __regionMonitor.status;
if (isNew)
{
newRegionMonitorStatus = LOC_SVC_STATUS_NOT_FIXED;
}
- if (newRegionMonitorStatus != __regionMonitorStatus)
+ if (newRegionMonitorStatus != __regionMonitor.status)
{
SysLog(NID_LOC, "Region Monitoring Satus changed to (%x). Notify the status.", newRegionMonitorStatus);
- __regionMonitorStatus = newRegionMonitorStatus;
- __pLocationListener->OnRegionMonitoringStatusChanged(__regionMonitorStatus);
+ __regionMonitor.status = newRegionMonitorStatus;
+ __pLocationListener->OnRegionMonitoringStatusChanged(__regionMonitor.status);
}
if (newRegionMonitorStatus == LOC_SVC_STATUS_RUNNING)
{
NotifyRegionCrossedStatus(location);
- *__pLastLocation.get() = location;
}
+
+ SetNextRegionMonitoringTime();
}
void
_LocationProviderImpl::NotifyRegionCrossedStatus(const Tizen::Locations::Location& location)
{
- int count = __pRegionList->GetCount();
+ int count = __regionMonitor.pRegionList->GetCount();
SysLog(NID_LOC, "Number of regions currently monitored is (%d)", count);
for (int i = 0; i < count; i++)
{
- _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__pRegionList->GetAt(i));
+ _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__regionMonitor.pRegionList->GetAt(i));
if (pRegionInfo)
{
return true;
}
+
+result
+_LocationProviderImpl::ActivateRegionMonitoring(void)
+{
+ long long currentTime;
+ SystemTime::GetTicks(currentTime);
+
+ SysLog(NID_LOC, "Current system time is %lld", currentTime);
+
+ _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetValidity(false);
+ _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetTimestamp(currentTime);
+
+ result r = __regionMonitor.pTimer->Start(DEFAULT_WAITING_TIME_FOR_FIXING_LOCATION * 1000);
+ SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the timer. Propogating.", GetErrorMessage(r));
+
+ 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, "Timer & Location updates are started.");
+ return E_SUCCESS;
+}
+
+void
+_LocationProviderImpl::StopRegionMonitoring(void)
+{
+ result r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Cancel();
+ SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to stop the alarm. Ignored.", GetErrorMessage(r));
+
+ r = __regionMonitor.pTimer->Cancel();
+ SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to stop the timer. Ignored.", GetErrorMessage(r));
+
+ r = __pLocationManager->StopLocationUpdates(__regionMonitor.reqId);
+ SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] All regions are removed but failed to stop the location updates. Ignored.", GetErrorMessage(r));
+}
+
+void
+_LocationProviderImpl::SetNextRegionMonitoringTime(void)
+{
+ DateTime alarmDateTime;
+ long long alarmTime = DEFAULT_REGION_MONITORING_CYCLE_INTERVAL;
+ SystemTime::GetCurrentTime(TIME_MODE_WALL, alarmDateTime);
+
+ SysLog(NID_LOC, "Current System Time is %ls", alarmDateTime.ToString().GetPointer());
+
+ if (__regionMonitor.pLocation->IsValid())
+ {
+ 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 / DEFAULT_AVG_SPEED) - bufferTime; //Calculate the alarm time based on the shortest distance between current location and nearest region boundary.
+
+ if (newAlarmTime > alarmTime)
+ {
+ alarmTime = newAlarmTime;
+ }
+ }
+
+ alarmDateTime.AddSeconds(alarmTime);
+ result r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Set(alarmDateTime, 0, null);
+ SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to set the alarm for next cycle.");
+
+ SysLog(NID_LOC, "Next alarm expires after %ld seconds.", alarmTime);
+}
}}