Geo-fencing optimization
[platform/framework/native/locations.git] / src / FLoc_LocationProviderImpl.cpp
index bccc8a3..2d25b79 100644 (file)
@@ -41,7 +41,6 @@
 #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"
 #include "FLoc_MathUtils.h"
 #include "FLoc_Types.h"
 
+using namespace std;
 using namespace Tizen::App;
 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
 {
@@ -87,27 +86,21 @@ _LocationProviderImpl::~_LocationProviderImpl(void)
 result
 _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProviderListener& listener)
 {
-       result r = E_SUCCESS;
-       _LocationManager* pLocationManager = null;
-
-       pLocationManager = _LocationManager::GetInstance();
+       _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());
        SysTryReturn(NID_LOC, pRegionList != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
-
-       r = pRegionList->Construct();
+       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());
        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));
 
@@ -123,7 +116,6 @@ _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());
        SysTryReturn(NID_LOC, pLastRegionLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
@@ -141,7 +133,6 @@ _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProv
        __pLocationManager = pLocationManager;
 
        SysLog(NID_LOC, "Location provider constructed with the accuracy (%x).", criteria.GetAccuracy());
-
        return E_SUCCESS;
 }
 
@@ -150,14 +141,12 @@ _LocationProviderImpl::StartLocationUpdatesByInterval(int interval)
 {
        bool userConsent = GetUserPrivilege();
        SysTryReturn(NID_LOC, userConsent, E_USER_NOT_CONSENTED, E_USER_NOT_CONSENTED, "[E_USER_NOT_CONSENTED] The user has disabled the required settings.");
-
        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 (__locationUpdater.type == _LOCATION_UPDATE_TYPE_INTERVAL && __locationUpdater.updateInterval == interval)
        {
                return E_SUCCESS;
        }
-
        const double INVALID_DISTANCE_THRESHOLD = 0.0;
        return StartLocationUpdates(_LOCATION_UPDATE_TYPE_INTERVAL, interval, INVALID_DISTANCE_THRESHOLD);
 }
@@ -167,16 +156,13 @@ _LocationProviderImpl::StartLocationUpdatesByDistance(double distance)
 {
        bool userConsent = GetUserPrivilege();
        SysTryReturn(NID_LOC, userConsent, E_USER_NOT_CONSENTED, E_USER_NOT_CONSENTED, "[E_USER_NOT_CONSENTED] The user has disabled the required settings.");
-
        SysTryReturn(NID_LOC, distance > 0.0, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The distance(%lf) should be greater than 0.0", distance);
-
        SysTryReturn(NID_LOC, Double::IsNaN(distance) == false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The distance is NaN.");
 
        if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_DISTANCE && (Double::Compare(__locationUpdater.distanceThreshold, distance) == 0))
        {
                return E_SUCCESS;
        }
-
        const int INVALID_INTERVAL = 0;
        return StartLocationUpdates(_LOCATION_UPDATE_TYPE_DISTANCE, INVALID_INTERVAL, distance);
 }
@@ -185,13 +171,10 @@ result
 _LocationProviderImpl::StopLocationUpdates(void)
 {
        SysLog(NID_LOC, "Stopping the location updates for the request ID (%ld)", __locationUpdater.reqId);
-
        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(__locationUpdater.reqId);
-
        ResetLocationUpdates();
-
        return r;
 }
 
@@ -238,21 +221,16 @@ _LocationProviderImpl::AddMonitoringRegion(const Coordinates& regionCenter, doub
 {
        bool userConsent = GetUserPrivilege();
        SysTryReturn(NID_LOC, userConsent, E_USER_NOT_CONSENTED, E_USER_NOT_CONSENTED, "[E_USER_NOT_CONSENTED] The user has disabled the required settings.");
-
        SysTryReturn(NID_LOC, radius >= 50.0 && radius <= 100000.00, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The radius is not within the specified limits.");
-
        SysTryReturn(NID_LOC, (!Double::IsNaN(radius) && !Double::IsNaN(regionCenter.GetLatitude()) && !Double::IsNaN(regionCenter.GetLongitude())),
                                 E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] One of the value is NaN.");
-
-       SysLog(NID_LOC, "Requested to add the monitoring region with center (Latitude: %lf, Longitude %lf) and radius (%lf).", regionCenter.GetLatitude(), regionCenter.GetLongitude(), radius);
+       SysSecureLog(NID_LOC, "Requested to add the monitoring region with center (Latitude: %lf, Longitude %lf) and radius (%lf).", regionCenter.GetLatitude(), regionCenter.GetLongitude(), radius);
 
        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 = __regionMonitor.pRegionList->Add(*pRegionInfo.get());
+       result 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();
@@ -264,12 +242,11 @@ _LocationProviderImpl::AddMonitoringRegion(const Coordinates& regionCenter, doub
                return E_SUCCESS;
        }
 
-       r = ActivateRegionMonitoring();
+       r = ActivateRegionMonitoring(true);
        SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r));
 
        __regionMonitor.status = LOC_SVC_STATUS_NOT_FIXED;
        NotifyServiceStatus(_LOC_PRV_EVENT_SEND_MONITOR_SVC_CB, __regionMonitor.status);
-
        return E_SUCCESS;
 
 CATCH:
@@ -282,7 +259,6 @@ _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
 {
        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++)
@@ -297,7 +273,6 @@ _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
        }
 
        SysTryReturn(NID_LOC, isIdValid == true, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The region ID is invalid.");
-
        if (__regionMonitor.pRegionList->GetCount() == 0)
        {
                __regionMonitor.status = LOC_SVC_STATUS_IDLE;
@@ -307,7 +282,6 @@ _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
                }
                StopRegionMonitoring();
        }
-
        return E_SUCCESS;
 }
 
@@ -325,7 +299,6 @@ _LocationProviderImpl::RemoveAllMonitoringRegions(void)
                }
                StopRegionMonitoring();
        }
-
        return;
 }
 
@@ -364,23 +337,19 @@ _LocationProviderImpl::GetLocation(const LocationCriteria& criteria)
 
        std::unique_ptr< _LocationMonitor > pLocMonitor(new (std::nothrow) _LocationMonitor());
        SysTryCatch(NID_LOC, pLocMonitor, , E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
-
        r = pLocMonitor->Construct(MAX_TIMEOUT, criteria.GetAccuracy());
        SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to construct the Location Monitor.", GetErrorMessage(r));
 
        pLocationManager = _LocationManager::GetInstance();
        SysTryCatch(NID_LOC, pLocationManager, , r, "[%s] Failed to get the location manager instance.", GetErrorMessage(r));
-
        r = pLocationManager->RegisterLocationMonitor(pLocMonitor.get());
        SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to register the location monitor.", GetErrorMessage(r));
 
        r = pLocMonitor->Wait();
-
        if (!IsFailed(r))
        {
                pLocation = pLocMonitor->GetLocationN();
        }
-
        if (pLocation)
        {
                retLocation = *pLocation;
@@ -389,9 +358,7 @@ _LocationProviderImpl::GetLocation(const LocationCriteria& criteria)
        {
                SetLastResult(E_LOCATION_UNAVAILABLE);
        }
-
        delete pLocation;
-
        return retLocation;
 
 CATCH:
@@ -410,7 +377,6 @@ _LocationProviderImpl::GetLastKnownLocation(void)
        SysTryReturn(NID_LOC, pLocationManager, retLocation, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
        retLocation = pLocationManager->GetLastKnownLocation();
-
        if (!retLocation.IsValid())
        {
                SetLastResult(E_LOCATION_UNAVAILABLE);
@@ -419,7 +385,6 @@ _LocationProviderImpl::GetLastKnownLocation(void)
        {
                ClearLastResult();
        }
-
        return retLocation;
 }
 
@@ -432,7 +397,6 @@ _LocationProviderImpl::OnLocationUpdated(RequestId reqId, const Tizen::Locations
 
        std::unique_ptr< Location > pLocation(new (std::nothrow) Location(location));
        SysTryReturnVoidResult(NID_LOC, pLocation, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
-
        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));
 
@@ -454,6 +418,7 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location
        SysLog(NID_LOC, "Location Event received.");
        bool isNew = false;
        LocationAccuracy currentAccuracy = LOC_ACCURACY_INVALID;
+       LocationAccuracy lastLocAccuracy = __lastLocationAccuracy;
        long long lastLocationTime = 0;
 
        Location* pLocation = &location;
@@ -491,24 +456,31 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location
        }
        else if (reqId == __regionMonitor.reqId)
        {
-               if (isNew)      // Copy the location only if it is new.
+               if (isNew)
                {
-                       *__regionMonitor.pLocation = location;
-               }
+                       bool gpsEnabled = 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 != 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.");
+                       if ( currentAccuracy <= lastLocAccuracy || timeDifference > DEFAULT_THRESHOLD_LOC_VALIDITY_TIME_OUT)    // Copy the location only if it is new and accuracy is better than before.
+                       {
+                               *__regionMonitor.pLocation = location;
+                       }
 
-                       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);
+                       if ((currentAccuracy != LOC_ACCURACY_INVALID && currentAccuracy <= __criteria.GetAccuracy()) || !gpsEnabled)
+                       {
+                               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);
+                       }
+                       else
+                       {
+                               SysLog(NID_LOC, "Location criteria (accuracy: %ld) is not met for handling region monitoring.", currentAccuracy);
+                       }                       
                }
        }
 
@@ -550,7 +522,7 @@ _LocationProviderImpl::OnActiveAppChanged(const Tizen::App::AppId& appId)
        else
        {
                SysLog(NID_LOC, "Application is not active.");
-               
+
                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).", __locationUpdater.awakeEnabled, __locationUpdater.status);
@@ -565,8 +537,7 @@ void
 _LocationProviderImpl::OnAlarmExpired(Alarm& alarm)
 {
        SysLog(NID_LOC, "Region Monitor Alarm expired.");
-       
-       result r = ActivateRegionMonitoring();
+       result r = ActivateRegionMonitoring(true);
        SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r));
 }
 
@@ -601,10 +572,10 @@ _LocationProviderImpl::StartLocationUpdates(LocationUpdateType updateType, int i
                {
                        startUpdate = false;
                }
-               else 
+               else
                {
                        AppUiState appUiState = pAppInstance->GetAppUiState();
-               
+
                        if (appUiState == APP_UI_STATE_BACKGROUND)
                        {
                                SysLog(NID_LOC, "App is background.");
@@ -660,7 +631,6 @@ _LocationProviderImpl::CheckDistanceThreshold(const Location& oldPosition, const
                __locationUpdater.firstLocationUpdate = false;
                return true;
        }
-
        displacement = coordOld.GetDistanceTo(coordNew);
        SysLog(NID_LOC, "Displacement is (%lf)", displacement);
        return ((displacement > __locationUpdater.distanceThreshold) ? true : false);
@@ -717,7 +687,7 @@ _LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location
                        newLocationUpdateStatus = LOC_SVC_STATUS_RUNNING;
                }
        }
-       else if (_LocationImpl::GetInstance(location)->IsDenied())
+       else if (!GetUserPrivilege())
        {
                SysLog(NID_LOC, "User consent not available.");
                if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
@@ -770,7 +740,7 @@ _LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& locati
        {
                newRegionMonitorStatus = LOC_SVC_STATUS_RUNNING;
        }
-       else if (_LocationImpl::GetInstance(location)->IsDenied())
+       else if (!GetUserPrivilege())
        {
                newRegionMonitorStatus = LOC_SVC_STATUS_DENIED;
        }
@@ -847,13 +817,12 @@ _LocationProviderImpl::GetRegionCurrentState(const _RegionInfo& region, const Lo
 {
        TryReturn(location.GetHorizontalAccuracy() >= 0.0, REGION_STATE_UNKNOWN, "Location received with invalid accuracy");
 
-       SysLog(NID_LOC, "[RegionID %d] Region Information is (Center latitude: %lf, Center longitude: %lf, Region radius:%lf", region.GetRegionId(), region.GetCoordinate().GetLatitude(),
+       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());
-       SysLog(NID_LOC, "[RegionID %d] Location Information is (Latitude: %lf, Longitude: %lf, Horizontal accuracy:%lf", region.GetRegionId(), location.GetCoordinates().GetLatitude(),
+       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());
 
        _RegionState regionState = REGION_STATE_UNKNOWN;
-
        double distanceBtwCenters = region.GetCoordinate().GetDistanceTo(location.GetCoordinates());
        double regionRadius = region.GetRadius();
        double locationRadius = location.GetHorizontalAccuracy();
@@ -942,53 +911,51 @@ _LocationProviderImpl::NotifyServiceStatus(_LocProviderEventType eventType, Loca
 bool
 _LocationProviderImpl::GetUserPrivilege(void)
 {
-       _LocationManager* pLocMgr = _LocationManager::GetInstance();
-       SysTryReturn(NID_LOC, pLocMgr, false, E_SYSTEM, "[E_SYSTEM] Failed to get the location manager instance.");
-
-       bool appSettingEnabled = pLocMgr->IsAppEnabled();
-       if (appSettingEnabled == false)
-       {
-               return false;
-       }
-
        bool hasPrivilege = false;
-       result gps = E_SUCCESS;
-       result wps = E_SUCCESS;
-
        bool gpsEnabled = true;
        bool wpsEnabled = true;
 
-       gps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.gps", gpsEnabled);
-       wps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.wps", wpsEnabled);
+       result gps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.gps", gpsEnabled);
+       result wps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.wps", wpsEnabled);
 
        hasPrivilege = gpsEnabled | wpsEnabled;
-
        if (gps != E_SUCCESS || wps != E_SUCCESS || hasPrivilege == false)
        {
                return false;
        }
-
        return true;
 }
 
 result
-_LocationProviderImpl::ActivateRegionMonitoring(void)
+_LocationProviderImpl::ActivateRegionMonitoring(bool startUpdate)
 {
        long long currentTime;
        SystemTime::GetTicks(currentTime);
+       int DEFAULT_WAITING_TIME = DEFAULT_WAITING_TIME_FOR_FIXING_GPS_LOCATION;
 
-       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));
+       SysLog(NID_LOC, "Current system time is %lld and location update request is %d", currentTime, startUpdate);
 
-       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));
+       bool gpsEnabled = false;
+       result gps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.gps", gpsEnabled);
+       if (gps == E_SUCCESS && !gpsEnabled)
+       {
+               SysLog(NID_LOC, "The GPS setting is OFF. So wait for only 10 seconds.");
+               DEFAULT_WAITING_TIME = DEFAULT_WAITING_TIME_FOR_FIXING_WPS_LOCATION;
+       }
+
+       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));        
+
+       if (startUpdate)
+       {
+               _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetValidity(false);
+               _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetTimestamp(currentTime);      
 
-       SysLog(NID_LOC, "Timer & Location updates are started.");
+               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;
 }
 
@@ -996,10 +963,10 @@ 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));
+       SysTryLog(NID_LOC, r == E_SUCCESS, "[%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));
+       SysTryLog(NID_LOC, r == E_SUCCESS, "[%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));
@@ -1014,20 +981,36 @@ _LocationProviderImpl::SetNextRegionMonitoringTime(void)
 
        SysLog(NID_LOC, "Current System Time is %ls", alarmDateTime.ToString().GetPointer());
 
+       double speed = DEFAULT_AVG_SPEED;
+       if (__regionMonitor.speed > DEFAULT_AVG_SPEED)
+       {
+               SysLog(NID_LOC, "The speed of the user is greater than the default speed. So updating the value.");
+               speed = __regionMonitor.speed;
+       }
        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)
+               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)
+               {
+                       SysLog(NID_LOC, "The alarm time is less than 5 seconds. So do not stop the location updates.");
+                       ActivateRegionMonitoring(false);
+                       return;
+               }
+               else
                {
                        alarmTime = newAlarmTime;
                }
        }
 
+       result r = __pLocationManager->StopLocationUpdates(__regionMonitor.reqId);
+       SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to stop the location updates.");
+       
        alarmDateTime.AddSeconds(alarmTime);
-       result r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Set(alarmDateTime, 0, null);  
+       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);