Geo-fencing optimization
authorNandan SR <nandan.sr@samsung.com>
Tue, 23 Apr 2013 13:05:56 +0000 (18:35 +0530)
committerNandan SR <nandan.sr@samsung.com>
Wed, 24 Apr 2013 06:07:38 +0000 (11:37 +0530)
Change-Id: Iff1a8afc9b0b54b6bf5e0bd615e24e93a375aa50
Signed-off-by: Nandan SR <nandan.sr@samsung.com>
src/FLocLocationProvider.cpp
src/FLoc_Config.h
src/FLoc_LocationManager.cpp
src/FLoc_LocationManager.h
src/FLoc_LocationProviderImpl.cpp
src/FLoc_LocationProviderImpl.h

index 2ecde3e..18a0803 100644 (file)
@@ -30,7 +30,6 @@
 #include "FLoc_LocationImpl.h"
 #include "FLoc_LocationProviderImpl.h"
 
-
 using namespace Tizen::Security;
 
 namespace Tizen { namespace Locations
@@ -53,7 +52,7 @@ LocationProvider::Construct(const LocationCriteria& criteria, ILocationProviderL
        SysAssertf(__pImpl == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
 
        __pImpl = new (std::nothrow) _LocationProviderImpl();
-       SysTryReturnResult(NID_LOC, __pImpl, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+       SysTryReturnResult(NID_LOC, __pImpl, E_OUT_OF_MEMORY, "Memory allocation failed.");
        result r = __pImpl->Construct(criteria, listener);
        SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to construct location Provider.", GetErrorMessage(r));
 
@@ -109,7 +108,7 @@ LocationProvider::KeepLocationUpdateAwake(bool enable)
 {
        result r = _AccessController::CheckUserPrivilege(_PRV_LOCATION);
        r = TransExceptionsExclusive(r, E_PRIVILEGE_DENIED, E_USER_NOT_CONSENTED);
-       SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] The application is not permitted to call this method.",GetErrorMessage(r));
+       SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "The application is not permitted to call this method.");
 
        r = _AccessController::CheckUserPrivilege(_PRV_POWER);
        SysTryReturn(NID_LOC, r == E_SUCCESS, E_PRIVILEGE_DENIED, E_PRIVILEGE_DENIED, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
@@ -124,7 +123,7 @@ LocationProvider::AddMonitoringRegion(const Coordinates& regionCenter, double ra
 {
        result r = _AccessController::CheckUserPrivilege(_PRV_LOCATION);
        r = TransExceptionsExclusive(r, E_PRIVILEGE_DENIED, E_USER_NOT_CONSENTED);
-       SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] The application is not permitted to call this method.",GetErrorMessage(r));
+       SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "The application is not permitted to call this method.");
        r = _AccessController::CheckUserPrivilege(_PRV_POWER);
        SysTryReturn(NID_LOC, r == E_SUCCESS, E_PRIVILEGE_DENIED, E_PRIVILEGE_DENIED, "[E_PRIVILEGE_DENIED] The application does not have the privilege to call this method.");
        SysAssertf(__pImpl != null, "Not yet constructed. Construct() should be called before use.");
index 819d1a1..46c2b7e 100644 (file)
@@ -29,10 +29,12 @@ namespace Tizen { namespace Locations
 
 const int MAX_WAIT_TIME_FOR_SYNC_LOC = 5;
 const int MIN_LOCATION_UPDATE_INTERVAL = 1;
-const int DEFAULT_WAITING_TIME_FOR_FIXING_LOCATION = 40;
+const int DEFAULT_WAITING_TIME_FOR_FIXING_GPS_LOCATION = 40;
+const int DEFAULT_WAITING_TIME_FOR_FIXING_WPS_LOCATION = 10;
 const int DEFAULT_AVG_SPEED = 20;  //Take average car speed as 72 km/hr = 20 m/s
 const int DEFAULT_REGION_MONITORING_CYCLE_INTERVAL = 5;
 const int DEFAULT_DISTANCE_CHECKING_INTERVAL = 10;
+const int DEFAULT_THRESHOLD_LOC_VALIDITY_TIME_OUT = 3;
 
 }} // Tizen::Locations
 #endif //_FLOC_INTERNAL_CONFIG_H_
index 71e518c..394590e 100644 (file)
@@ -943,7 +943,7 @@ _LocationManager::GetLocation(location_method_e nativeLocMethod)
        }
 
        res = location_manager_get_position(nativeHandle, &altitude, &latitude, &longitude, &timestamp);
-       SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM,  "[E_SYSTEM] Failed to obtain the natvie location information for the method (%x)", nativeLocMethod);
+       SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM,  "Failed to obtain the natvie location information for the method (%x)", nativeLocMethod);
 
        if (res == 0)
        {
index 2c2322a..af29cea 100644 (file)
@@ -46,13 +46,13 @@ class _LocationManager
        , public Tizen::Base::Runtime::ITimerEventListener
 {
 public:
-       // This method adds the location request into the list of requests and requests for location updates from native location provider.
+       // This method adds the location request into the list of requests and requests for location updates from core location provider.
        //
        // @since 2.0
        //
        result StartLocationUpdates(LocationAccuracy accuracy, int interval, _ILocationManagerListener* pListener, RequestId& reqId);
 
-       // This method removes the location request wrt to the reqId provided. If the list entries is zero, then stops the native location provider.
+       // This method removes the location request wrt to the reqId provided. If the list entries is zero, then stops the core location provider.
        //
        // @since 2.0
        //
index f88e03b..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
 {
@@ -243,7 +242,7 @@ _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;
@@ -419,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;
@@ -456,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);
+                       }                       
                }
        }
 
@@ -530,7 +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));
 }
 
@@ -920,23 +927,35 @@ _LocationProviderImpl::GetUserPrivilege(void)
 }
 
 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);
+       SysLog(NID_LOC, "Current system time is %lld and location update request is %d", currentTime, startUpdate);
 
-       _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetValidity(false);
-       _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetTimestamp(currentTime);
+       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_FOR_FIXING_LOCATION * 1000);
-       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the timer. Propogating.", GetErrorMessage(r));
+       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));        
 
-       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));
+       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;
 }
 
@@ -962,19 +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);
index cc23a48..e00f64c 100644 (file)
@@ -35,6 +35,7 @@
 #include <FSysAlarm.h>
 #include <FSysIAlarmEventListener.h>
 #include <FBaseRt_Event.h>
+#include <FLoc_Config.h>
 #include "FLoc_ILocationManagerListener.h"
 #include "FLoc_ILocProviderEventListener.h"
 #include "FLoc_LocProviderEventArg.h"
@@ -251,7 +252,7 @@ private:
        //
        // @since 2.0
        //
-       result ActivateRegionMonitoring(void);
+       result ActivateRegionMonitoring(bool startUpdate);
 
        // This method stops the location updates and cancels the timer and alarm set for the area monitoring.
        //
@@ -302,6 +303,7 @@ private:
                _RegionMonitor(void)
                        : reqId(-1)
                        , status(LOC_SVC_STATUS_IDLE)
+                       , speed (DEFAULT_AVG_SPEED)
                        , pTimer(null)
                        , pAlarm(null)
                        , pLocation(null)
@@ -316,6 +318,7 @@ private:
        public:
                RequestId reqId;
                LocationServiceStatus status;
+               double speed;
                std::unique_ptr<Tizen::Base::Runtime::Timer> pTimer;
                std::unique_ptr<Tizen::System::Alarm> pAlarm;
                std::unique_ptr<Tizen::Locations::Location> pLocation;