Implementation of new location manager.
authorNandan SR <nandan.sr@samsung.com>
Fri, 7 Jun 2013 03:34:17 +0000 (12:34 +0900)
committerNandan SR <nandan.sr@samsung.com>
Fri, 7 Jun 2013 03:34:17 +0000 (12:34 +0900)
Change-Id: I98a81dc40192362b688ea8b5e400c37feb50e5d7
Signed-off-by: Nandan SR <nandan.sr@samsung.com>
src/FLoc_Config.h
src/FLoc_ILocProviderEventListener.h
src/FLoc_ILocationManagerListener.h
src/FLoc_LocationManager.cpp
src/FLoc_LocationManager.h
src/FLoc_LocationProviderImpl.cpp
src/FLoc_LocationProviderImpl.h
src/FLoc_SyncLocationRequestInfo.h

index 46c2b7e..00a5adb 100644 (file)
@@ -35,6 +35,7 @@ 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;
+const int MAX_TIMER_VALUE_DURING_WPS_POSITIONING = 640;
 
 }} // Tizen::Locations
 #endif //_FLOC_INTERNAL_CONFIG_H_
index b090936..e153b1f 100644 (file)
@@ -80,7 +80,7 @@ public:
        /**
         * Called when the alarm expiry event is fired from the location provider impl class to break the context. @n
         *
-        * @since 2.0
+        * @since 2.1.1
         */
        virtual void OnAlarmExpiredEventReceived(void) = 0;
 
index 85f2256..bf5f2d7 100644 (file)
@@ -62,7 +62,7 @@ public:
        /**
         * Called when the alarm requested by the location provider has expired. @n
         *
-        * @since 2.0
+        * @since 2.1.1
         */
        virtual void OnAlarmExpired(void) = 0;
 }; //_ILocationManagerListener
index cf95366..c85d4d1 100644 (file)
 #include <FBaseRtTimer.h>
 #include <FBaseRtMonitor.h>
 #include <FBaseSysLog.h>
+#include <FBaseUtilMath.h>
 #include <FLocCoordinates.h>
-#include <FSysSystemTime.h>
+#include <FSysSettingInfo.h>
 #include <FSys_PowerManagerImpl.h>
+#include <FSys_SettingInfoImpl.h>
 #include "FLoc_AlarmRequestInfo.h"
 #include "FLoc_Config.h"
 #include "FLoc_LocationImpl.h"
 #include "FLoc_LocationRequestInfo.h"
 #include "FLoc_SyncLocationRequestInfo.h"
 
+using namespace std;
 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)
+       , __gpsEnabled(false)
+       , __wpsEnabled(false)
        , __minRequestedAccuracy(LOC_ACCURACY_INVALID)
        , __timerInterval(0)
        , __timerTicks(0)
        , __pLocRequestInfoList(null)
        , __pSyncLocRequestInfoList(null)
-       , __pLocUpdateTimer(null)
+       , __pAlarmRequestInfoList(null)
+       , __pLocCallbackTimer(null)
+       , __pLocCheckTimer(null)
        , __pInitMonitor(null)
 {
 }
@@ -81,9 +86,8 @@ _LocationManager::StartLocationUpdates(LocationAccuracy accuracy, int interval,
        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());
+       std::unique_ptr< ArrayList, 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));
 
@@ -91,18 +95,16 @@ _LocationManager::StartLocationUpdates(LocationAccuracy accuracy, int interval,
        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));
+       pArgList.release();
 
        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;
 }
 
@@ -112,9 +114,8 @@ _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());
+       std::unique_ptr< ArrayList, 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));
 
@@ -122,13 +123,12 @@ _LocationManager::StopLocationUpdates(RequestId reqId)
        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;
 }
 
@@ -138,7 +138,7 @@ _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());
+       std::unique_ptr< ArrayList, 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));
@@ -148,7 +148,6 @@ _LocationManager::ChangeUpdateInterval(RequestId reqId, int interval)
 
        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));
@@ -156,13 +155,12 @@ _LocationManager::ChangeUpdateInterval(RequestId reqId, int interval)
 
        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;
 }
 
@@ -173,13 +171,13 @@ _LocationManager::RegisterLocationMonitor(_LocationMonitor* pLocationMonitor)
        const int ARRAY_LIST_CAPACITY = 1;
 
        Location location = GetLastKnownLocation();
-       Tizen::Base::DateTime lastLocTime = location.GetTimestamp();
+       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());
+       std::unique_ptr< ArrayList, 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));
 
@@ -192,8 +190,8 @@ _LocationManager::RegisterLocationMonitor(_LocationMonitor* pLocationMonitor)
 
        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:
@@ -206,9 +204,8 @@ _LocationManager::RequestStartAlarm(int interval, _ILocationManagerListener* pLi
 {
        const int ARRAY_LIST_CAPACITY = 1;
 
-       std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pArgList(new (std::nothrow) ArrayList());
+       std::unique_ptr< ArrayList, 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));
 
@@ -216,15 +213,13 @@ _LocationManager::RequestStartAlarm(int interval, _ILocationManagerListener* pLi
        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, "Successfully requested for alarm addition.");
 
-       SysLog(NID_LOC, "Success to add the alarm.");
        return E_SUCCESS;
 }
 
@@ -234,9 +229,8 @@ _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());
+       std::unique_ptr< ArrayList, 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));
 
@@ -244,13 +238,12 @@ _LocationManager::RequestStopAlarm(RequestId reqId)
        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;
 }
 
@@ -262,7 +255,7 @@ _LocationManager::GetLastKnownLocation(void)
        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());
+       std::unique_ptr< 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));
@@ -357,9 +350,15 @@ _LocationManager::AddToLocRequestInfoList(const _LocationRequestInfo* pLocReques
                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();
+       const int FIRST_REQUEST = 1;
+       int count = __pLocRequestInfoList->GetCount();
+       SysLog(NID_LOC, "Total count of request info is (%d).", count);
+       if (count == FIRST_REQUEST)
+       {
+               InitiateLocationRequest();
+       }
+       UpdateMinimunAccuracy();
+       RestartCallbackTimer();
 }
 
 void
@@ -382,15 +381,14 @@ _LocationManager::RemoveFromLocRequestInfoList(RequestId reqId)
        {
                _PowerManagerImpl::PowerControl(1, 0);
 
-               __pLocUpdateTimer->Cancel();
-               location_manager_stop(__gpsHandler.handle);
-               location_manager_stop(__wpsHandler.handle);
                Reset();
+               location_manager_stop(__locMgrStatus.gpsHandler.handle);
+               location_manager_stop(__locMgrStatus.wpsHandler.handle);
        }
        else
        {
-               RestartLocationUpdates();
-               RestartUpdateTimer();
+               UpdateMinimunAccuracy();
+               RestartCallbackTimer();
        }
 }
 
@@ -402,7 +400,6 @@ _LocationManager::AddToSyncLocationRequestInfoList(_SyncLocationRequestInfo& syn
 
        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:
@@ -422,16 +419,16 @@ 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);
+       SysLog(NID_LOC, "The alarm ID (%d) is set to the alarm request.", 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."); 
+       SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Failed to add the alarm request into list.");
        pNewAlarmRequestInfo.release();
 
        return;
@@ -442,7 +439,6 @@ _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));
@@ -455,82 +451,84 @@ _LocationManager::RemoveFromAlarmRequestInfoList(RequestId reqId)
                        break;
                }
        }
-
        return;
 }
 
 void
-_LocationManager::RestartLocationUpdates(void)
+_LocationManager::UpdateMinimunAccuracy(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)
+}
+
+void
+_LocationManager::InitiateLocationRequest(void)
+{
+       if (__locMgrStatus.locMgrState != LOC_MGR_STATE_IDLE)
        {
+               SysLog(NID_LOC, "Location manager already running.");
                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");
+       SysLog(NID_LOC, "None of the methods running. Start all");
+       bool gpsEnabled = false;
+       bool wpsEnabled = false;
+       int resultGps = -1;
+       int resultWps = -1;
+       const int LOC_CHECK_TIMER_VALUE = 1000;
 
-               result = location_manager_start(__gpsHandler.handle);
-               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS.");
+       result gps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.gps", gpsEnabled);
+       result wps = _SettingInfoImpl::GetValue(L"http://tizen.org/setting/location.wps", wpsEnabled);
+       __gpsEnabled = gpsEnabled;
+       __wpsEnabled = wpsEnabled;
 
-               result = location_manager_start(__wpsHandler.handle);
-               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS.");
+       if (gps == E_SUCCESS && __gpsEnabled)
+       {
+               resultGps = location_manager_start(__locMgrStatus.gpsHandler.handle);
+               SysTryLog(NID_LOC, resultGps == 0, "Failed to start the core GPS location provider with result (%d).", resultGps);
        }
-       break;
-
-       case LOC_METHOD_REQUESTED_GPS:
+       if (wps == E_SUCCESS && __wpsEnabled)
        {
-               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.");
+               resultWps = location_manager_start(__locMgrStatus.wpsHandler.handle);
+               SysTryLog(NID_LOC, resultWps == 0, "Failed to start the core WPS location provider with result (%d).", resultWps);
        }
-       break;
 
-       case LOC_METHOD_REQUESTED_WPS:
+       if (resultGps == 0 && resultWps == 0)
        {
-               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.");
+               __locMgrStatus.locMgrState = LOC_MGR_STATE_BOTH_GPS_WPS;
        }
-       break;
-
-       case LOC_METHOD_REQUESTED_ALL:
+       else if (resultGps == 0 && resultWps != 0)
        {
-               SysLog(NID_LOC, "All the providers are already started.");
+               __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY;
        }
-       break;
+       else if (resultGps != 0 && resultWps == 0)
+       {
+               __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY;
        }
-
-       __locationMgrState = LOC_MGR_STATE_FAST_SENSING;
-       __locMethodRequested = LOC_METHOD_REQUESTED_ALL;
+       else
+       {
+               SysLog(NID_LOC, "Failed to start both the location providers.");
+               __locMgrStatus.locMgrState = LOC_MGR_STATE_PASSIVE_IDLE;
+               return;
+       }
+       __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+       __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE);
 }
 
 void
-_LocationManager::RestartUpdateTimer(void)
+_LocationManager::RestartCallbackTimer(void)
 {
        int gcd = 1;
        int count = __pLocRequestInfoList->GetCount();
 
-       __pLocUpdateTimer->Cancel();
+       __pLocCallbackTimer->Cancel();
 
        if (count > 0)
        {
@@ -554,12 +552,9 @@ _LocationManager::RestartUpdateTimer(void)
        __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.");
-       }
+       result r = __pLocCallbackTimer->Start(__timerInterval * 1000);
+       SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the location callback timer.", GetErrorMessage(r));
+       SysLog(NID_LOC, "The callback timer interval successfully updated to (%d).", __timerInterval);
 }
 
 void
@@ -569,6 +564,7 @@ _LocationManager::HandleSyncRetrievalTimerExpiry(_SyncLocationRequestInfo& syncL
        DateTime timestamp = DateTime::GetMinValue();
 
        const Location* pBestLoc = FindBestLocation();
+       SysTryReturnVoidResult(NID_LOC, pBestLoc != null, E_INVALID_DATA, "[E_INVALID_DATA] Location not available.");
        SysLog(NID_LOC, "Location(timestamp: %ls, validity: %x, accuracy: %f) is retrieved.",
                   pBestLoc->GetTimestamp().ToString().GetPointer(), pBestLoc->IsValid(), pBestLoc->GetHorizontalAccuracy());
        if (pBestLoc->IsValid())
@@ -617,128 +613,11 @@ 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();
+       SysTryReturnVoidResult(NID_LOC, pBestLocation != null, E_INVALID_DATA, "[E_INVALID_DATA] Location not available.");
 
        SysLog(NID_LOC, "Send location(validity: %x) through the callback.", pBestLocation->IsValid());
        unique_ptr< Location > pLocation(new (std::nothrow) Location(*pBestLocation));
@@ -758,8 +637,11 @@ _LocationManager::SendLocationCallbacks(void)
 void
 _LocationManager::Reset(void)
 {
-       __locMethodRequested = LOC_METHOD_REQUESTED_NONE;
-       __locationMgrState = LOC_MGR_STATE_IDLE;
+       StopSubStateTimer();
+       __pLocCallbackTimer->Cancel();
+       __pLocCheckTimer->Cancel();
+       __locMgrStatus.locMgrSubState = LM_SS_IDLE;
+       __locMgrStatus.locMgrState = LOC_MGR_STATE_IDLE;
        __minRequestedAccuracy = LOC_ACCURACY_INVALID;
        __timerInterval = 0;
        __timerTicks = 0;
@@ -790,14 +672,14 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
        {
        case LOCATIONS_METHOD_GPS:
        {
-               nativeHandle = __gpsHandler.handle;
+               nativeHandle = __locMgrStatus.gpsHandler.handle;
                locationMethod = L"gps";
        }
        break;
 
        case LOCATIONS_METHOD_WPS:
        {
-               nativeHandle = __wpsHandler.handle;
+               nativeHandle = __locMgrStatus.wpsHandler.handle;
                locationMethod = L"network";
        }
        break;
@@ -822,8 +704,6 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
                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);
@@ -836,8 +716,8 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
                {
                        SysLog(NID_LOC, "Last accuracy(horAcc: %lf, vAcc: %lf, level: %x)", horAcc, verAcc, level);
                        horAcc = ConvertToNativeFormat(horAcc);
-                       pLocationImpl->SetHorizontalAccuracy(horAcc);
                        verAcc = ConvertToNativeFormat(verAcc);
+                       pLocationImpl->SetHorizontalAccuracy(horAcc);
                        pLocationImpl->SetVerticalAccuracy(verAcc);
                }
 
@@ -848,12 +728,10 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
                res = location_manager_get_last_velocity(nativeHandle, &climb, &direction, &speed, &timestampVelocity);
                if (res == 0)
                {
-                       SysLog(NID_LOC, "Last velocity(climb: %lf, direction: %lf, speed: %lf, timestamp: %ld)",
-                                  climb, direction, speed, timestampVelocity);
-
+                       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->SetCourse(direction);
                        pLocationImpl->SetSpeed(speed);
                }
 
@@ -866,7 +744,7 @@ _LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
                        res = gps_status_get_last_satellite(nativeHandle, &satUsedCount, &satViewCount, &timestampSatellite);
                        if (res == 0)
                        {
-                               long timeDiff = abs(timestampPosition - timestampSatellite);
+                               long timeDiff = Math::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);
@@ -918,7 +796,7 @@ _LocationManager::GetRecentLocationAvailable(void)
 }
 
 void
-_LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval)
+_LocationManager::UpdateLocRequestInterval(RequestId reqId, int interval)
 {
        int count = __pLocRequestInfoList->GetCount();
 
@@ -928,7 +806,7 @@ _LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval)
                if (reqId == pLocRequestInfo->GetRequestId())
                {
                        pLocRequestInfo->SetInterval(interval);
-                       RestartUpdateTimer();
+                       RestartCallbackTimer();
                        break;
                }
        }
@@ -937,89 +815,94 @@ _LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval)
 const Location*
 _LocationManager::FindBestLocation(void)
 {
-       switch (__locMethodRequested)
+       switch (__locMgrStatus.locMgrState)
        {
-       case LOC_METHOD_REQUESTED_GPS:
+       case LOC_MGR_STATE_GPS_ONLY:
        {
                SysLog(NID_LOC, "GPS location provider running.");
-               return __gpsHandler.pLocation.get();
+               return __locMgrStatus.gpsHandler.pLocation.get();
        }
        break;
 
-       case LOC_METHOD_REQUESTED_WPS:
+       case LOC_MGR_STATE_WPS_ONLY:
        {
                SysLog(NID_LOC, "WPS location provider running.");
-               return __wpsHandler.pLocation.get();
+               return __locMgrStatus.wpsHandler.pLocation.get();
        }
        break;
 
-       case LOC_METHOD_REQUESTED_ALL:
+       case LOC_MGR_STATE_PASSIVE_IDLE:    //Give back the available location in case of Passive location because the location provider takes care of the location and send Denied.
+       // follow through
+       case LOC_MGR_STATE_BOTH_GPS_WPS:
        {
                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())
+               if (__locMgrStatus.gpsHandler.pLocation->IsValid())
                {
-                       gpsTimestamp = _LocationImpl::GetInstance(*__gpsHandler.pLocation)->GetTimestampInMs();
+                       gpsTimestamp = _LocationImpl::GetInstance(*__locMgrStatus.gpsHandler.pLocation)->GetTimestampInMs();
                }
-               if (__wpsHandler.pLocation->IsValid())
+               if (__locMgrStatus.wpsHandler.pLocation->IsValid())
                {
-                       wpsTimestamp = _LocationImpl::GetInstance(*__wpsHandler.pLocation)->GetTimestampInMs();
+                       wpsTimestamp = _LocationImpl::GetInstance(*__locMgrStatus.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();
+                       return __locMgrStatus.gpsHandler.pLocation.get();
                }
                else if (wpsTimestamp > gpsTimestamp)
                {
                        SysLog(NID_LOC, "WPS time stamp is greater than GPS.");
-                       return __wpsHandler.pLocation.get();
+                       return __locMgrStatus.wpsHandler.pLocation.get();
                }
                else if (gpsTimestamp == wpsTimestamp)
                {
-                       if (__gpsHandler.pLocation->GetHorizontalAccuracy() <= __wpsHandler.pLocation->GetHorizontalAccuracy())
+                       double gpsAccuracy = __locMgrStatus.gpsHandler.pLocation->GetHorizontalAccuracy();
+                       double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy();
+                       if ((gpsAccuracy <= wpsAccuracy) || Double::IsNaN(wpsAccuracy))
                        {
                                SysLog(NID_LOC, "GPS time stamp is equal to WPS and GPS accuracy is better than WPS.");
-                               return __gpsHandler.pLocation.get();
+                               return __locMgrStatus.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();
+                               SysLog(NID_LOC, "WPS time stamp is equal to GPS and WPS accuracy is better than GPS.");
+                               return __locMgrStatus.wpsHandler.pLocation.get();
                        }
                }
        }
        break;
 
-       case LOC_METHOD_REQUESTED_NONE:
+       case LOC_MGR_STATE_IDLE:
        // follow through
        default:
                SysLog(NID_LOC, "Location updates not running.");
                return null;
        }
 
-       SysLog(NID_LOC, "Returning null as none of the conditions are satsfied.");
+       SysLog(NID_LOC, "Returning null as none of the conditions are satisfied.");
        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;
+       location_accuracy_level_e accuracy_level;
        int res = -1;
-       int satellitesInViewCount = 0;
-       int satellitesInUseCount = 0;
-       time_t timestampSatellite = 0;
-       String satInfo = L"";
+       time_t timestamp = 0;
        long long timeDiff = 0;
+       double altitude = NaN;
+       double latitude = NaN;
+       double longitude = NaN;
+       double climb = NaN;
+       double direction = NaN;
+       double speed = NaN;
+       double horizontal_acc = NaN;
+       double vertical_acc = NaN;
        location_manager_h nativeHandle = null;
        Location* pLocation = null;
 
@@ -1027,15 +910,15 @@ _LocationManager::GetLocation(location_method_e nativeLocMethod)
        {
        case LOCATIONS_METHOD_GPS:
        {
-               nativeHandle = __gpsHandler.handle;
-               pLocation = __gpsHandler.pLocation.get();
+               nativeHandle = __locMgrStatus.gpsHandler.handle;
+               pLocation = __locMgrStatus.gpsHandler.pLocation.get();
        }
        break;
 
        case LOCATIONS_METHOD_WPS:
        {
-               nativeHandle = __wpsHandler.handle;
-               pLocation = __wpsHandler.pLocation.get();
+               nativeHandle = __locMgrStatus.wpsHandler.handle;
+               pLocation = __locMgrStatus.wpsHandler.pLocation.get();
        }
        break;
 
@@ -1043,179 +926,829 @@ _LocationManager::GetLocation(location_method_e nativeLocMethod)
                break;
        }
 
-       res = location_manager_get_position(nativeHandle, &altitude, &latitude, &longitude, &timestamp);
+       res = location_manager_get_location(nativeHandle, &altitude, &latitude, &longitude, &climb, &direction, &speed, &accuracy_level, &horizontal_acc, &vertical_acc, &timestamp);
        SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM, "Failed to obtain the natvie location information for the method (%x)", nativeLocMethod);
+       SysSecureLog(NID_LOC, "Location details: Lat(%lf), Long(%lf), Alt(%lf), Climb (%lf), Direction (%lf), Speed (%lf), Accuracy Level(%d), HAcc (%lf), VAcc (%lf), timestamp (%ld).",
+                                latitude, longitude, altitude, climb, direction, speed, accuracy_level, horizontal_acc, vertical_acc, timestamp);
 
        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");
-               }
+               Location locationData = _LocationImpl::GetLocationInstance();
+               _LocationImpl* pLocDataImpl = _LocationImpl::GetInstance(locationData);
+
+               horizontal_acc = ConvertToNativeFormat(horizontal_acc);
+               vertical_acc = ConvertToNativeFormat(vertical_acc);
+               Coordinates coordinates;
+               coordinates.Set(latitude, longitude, altitude);
+               pLocDataImpl->SetCoordinates(coordinates);
+               pLocDataImpl->SetHorizontalAccuracy(horizontal_acc);
+               pLocDataImpl->SetVerticalAccuracy(vertical_acc);
+               pLocDataImpl->SetTimestamp((long long) timestamp * 1000);
+               pLocDataImpl->SetCourse(direction);
+               pLocDataImpl->SetSpeed(speed);
+               pLocDataImpl->SetValidity(true);
 
                if (nativeLocMethod == LOCATIONS_METHOD_GPS)
                {
-                       res = gps_status_get_satellite(__gpsHandler.handle, &satellitesInUseCount, &satellitesInViewCount, &timestampSatellite);
+                       const int MAX_VALID_TIME_DIFFERENCE = 2000;
+                       int satellitesInViewCount = 0;
+                       int satellitesInUseCount = 0;
+                       time_t timestampSatellite = 0;
+                       String satInfo = L"";
+
+                       __locMgrStatus.gpsFailCount = 0;
+                       pLocDataImpl->SetExtraInfo(L"location_method", L"gps");
+                       res = gps_status_get_satellite(nativeHandle, &satellitesInUseCount, &satellitesInViewCount, &timestampSatellite);
 
-                       timeDiff = abs(timestamp - timestampSatellite);
+                       timeDiff = Math::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);
+                               res = gps_status_foreach_satellites_in_view(__locMgrStatus.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);
+                       pLocDataImpl->SetExtraInfo(L"satellite", satInfo);
+               }
+               else if (nativeLocMethod == LOCATIONS_METHOD_WPS)
+               {
+                       pLocDataImpl->SetExtraInfo(L"location_method", L"network");
                }
+               *pLocation = locationData;
        }
 
        return E_SUCCESS;
 }
 
-bool
-_LocationManager::OnStart(void)
+void
+_LocationManager::HandleBothGpsWpsState(void)
 {
-       SysTryReturn(NID_LOC, __pInitMonitor, false, E_INVALID_STATE, "[E_INVALID_STATE] __pInitMonitor must not be null.");
+       bool isGpsAccMet = false;
+       bool isWpsAccMet = false;
+       bool isGpsTimeUpdated = false;
+       bool isWpsTimeUpdated = false;
 
-       int res = -1;
+       IsGpsLocationUpdated(isGpsTimeUpdated, isGpsAccMet);
+       IsWpsLocationUpdated(isWpsTimeUpdated, isWpsAccMet);
 
-       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.");
+       if (isWpsAccMet)
+       {
+               StopSubStateTimer();
+               SysLog(NID_LOC, "WPS accuracy is met during LOC_MGR_STATE_BOTH_GPS_WPS state.");
+               location_manager_stop(__locMgrStatus.gpsHandler.handle);
+               __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY;
+               __locMgrStatus.locMgrSubState = LM_SS_SETTLED;
+       }
+       else if (isGpsAccMet)
+       {
+               SysLog(NID_LOC, "GPS accuracy is met during LOC_MGR_STATE_BOTH_GPS_WPS state. Wait for 10 more seconds to give WPS a chance.");
 
-       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.");
+               if (__locMgrStatus.locMgrSubState != LM_SS_BOTH_SETTLED_WAITING)
+               {
+                       const int SUB_STATE_TIMER_VALUE = 10;
+                       result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                       if (!IsFailed(r))
+                       {
+                               SysLog(NID_LOC, "Started a timer for 10 seconds to give WPS a chance in the state LOC_MGR_STATE_BOTH_GPS_WPS.");
+                               __locMgrStatus.locMgrSubState = LM_SS_BOTH_SETTLED_WAITING;
+                       }
+               }
+       }
+       else if (isWpsTimeUpdated || isGpsTimeUpdated)
+       {
+               SysLog(NID_LOC, "GPS accuracy and WPS accuracy not met during LOC_MGR_STATE_BOTH_GPS_WPS state. Wait for 20 seconds.");
 
-       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.");
+               if (__locMgrStatus.locMgrSubState != LM_SS_BOTH_SENSING)
+               {
+                       const int SUB_STATE_TIMER_VALUE = 20;
+                       result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                       if (!IsFailed(r))
+                       {
+                               SysLog(NID_LOC, "Started a timer for 20 seconds as the accuracy is not met in state LOC_MGR_STATE_BOTH_GPS_WPS.");
+                               __locMgrStatus.locMgrSubState = LM_SS_BOTH_SENSING;
+                       }
+               }
+       }
+       else
+       {
+               SysLog(NID_LOC, "Position not obtained by either GPS or WPS.");
+               StopSubStateTimer();
+               __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+       }
+}
 
-       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));
+void
+_LocationManager::HandleGpsOnlyState(void)
+{
+       bool isGpsAccMet = false;
+       bool isTimeUpdated = false;
+       double minAccRequested = ConvertLocationAccuracyToDouble(__minRequestedAccuracy);
 
-       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.");
+       IsGpsLocationUpdated(isTimeUpdated, isGpsAccMet);
 
-       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.");
+       if (!__wpsEnabled && isGpsAccMet)
+       {
+               StopSubStateTimer();
+               __locMgrStatus.locMgrSubState = LM_SS_SETTLED;
+               return;
+       }
 
-       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.");
+       if (__wpsEnabled)
+       {
+               SysLog(NID_LOC, "WPS setting is enabled.");
+               if (isGpsAccMet)    //Location available with requested accuracy.
+               {
+                       if (minAccRequested > ConvertLocationAccuracyToDouble(LOC_ACCURACY_TEN_METERS))
+                       {
+                               if (__locMgrStatus.locMgrSubState != LM_SS_GPS_ONLY_SETTLED)
+                               {
+                                       const int SUB_STATE_TIMER_VALUE = 120;
+                                       result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                                       if (!IsFailed(r))
+                                       {
+                                               SysLog(NID_LOC, "Started the sub state timer of 120 seconds in LOC_MGR_STATE_GPS_ONLY state.");
+                                               __locMgrStatus.locMgrSubState = LM_SS_GPS_ONLY_SETTLED;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               __locMgrStatus.locMgrSubState = LM_SS_SETTLED;
+                       }
+               }
+               else if (isTimeUpdated) //GPS Location available with less accuracy.
+               {
+                       if (__locMgrStatus.locMgrSubState != LM_SS_GPS_ONLY_SENSING)
+                       {
+                               const int SUB_STATE_TIMER_VALUE = 40;
+                               result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                               if (!IsFailed(r))
+                               {
+                                       SysLog(NID_LOC, "Started the sub state timer of 40 seconds in LOC_MGR_STATE_GPS_ONLY state.");
+                                       __locMgrStatus.locMgrSubState = LM_SS_GPS_ONLY_SENSING;
+                               }
+                       }
+               }
+               else    //Location not available
+               {
+                       if (__locMgrStatus.locMgrSubState != LM_SS_GPS_ONLY_NO_FIX)
+                       {
+                               const int SUB_STATE_TIMER_VALUE = 10;
+                               result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                               if (!IsFailed(r))
+                               {
+                                       SysLog(NID_LOC, "Started the sub state timer of 10 seconds in LOC_MGR_STATE_GPS_ONLY state.");
+                                       __locMgrStatus.locMgrSubState = LM_SS_GPS_ONLY_NO_FIX;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               StopSubStateTimer();
 
-       __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);
+               if (isTimeUpdated)
+               {
+                       SysLog(NID_LOC, "GPS position available with less accuracy in LOC_MGR_STATE_GPS_ONLY state.");
+                       __locMgrStatus.locMgrSubState = LM_SS_SENSING;
+               }
+               else
+               {
+                       SysLog(NID_LOC, "GPS position not available in LOC_MGR_STATE_GPS_ONLY state.");
+                       __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+               }
+       }
+}
 
-       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));
+void
+_LocationManager::HandleWpsOnlyState(void)
+{
+       bool isWpsAccMet = false;
+       bool isTimeUpdated = false;
+       double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy();
 
-       SysLog(NID_LOC, "All the resources for location manager successfully created.");
-       return true;
+       IsWpsLocationUpdated(isTimeUpdated, isWpsAccMet);
 
-CATCH:
-       if (__gpsHandler.handle)
+       if (isWpsAccMet)
        {
-               location_manager_destroy(__gpsHandler.handle);
+               StopSubStateTimer();
+               __locMgrStatus.locMgrSubState = LM_SS_SETTLED;
+               return;
        }
 
-       if (__wpsHandler.handle)
+       if (__gpsEnabled)
+       {
+               SysLog(NID_LOC, "GPS is enabled.");
+               if (isTimeUpdated)  // WPS location available with less accuracy
+               {
+                       SysLog(NID_LOC, "WPS position available with less accuracy in LOC_MGR_STATE_WPS_ONLY state.");
+                       if (__locMgrStatus.gpsFailCount == 0)
+                       {
+                               if (__minRequestedAccuracy > LOC_ACCURACY_TEN_METERS)
+                               {
+                                       if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_LESS_ACC_SENSING)
+                                       {
+                                               double currAccDiff = wpsAccuracy - ConvertLocationAccuracyToDouble(__minRequestedAccuracy);
+                                               int subStateTimerValue = 0;
+
+                                               if (currAccDiff < 100)
+                                               {
+                                                       subStateTimerValue = 15;
+                                               }
+                                               else
+                                               {
+                                                       subStateTimerValue = 10;
+                                               }
+                                               result r = RestartSubStateTimer(subStateTimerValue * 1000);
+                                               if (!IsFailed(r))
+                                               {
+                                                       SysLog(NID_LOC, "Started the sub state timer for (%d) seconds in LOC_MGR_STATE_WPS_ONLY as WPS accuracy not met.", subStateTimerValue);
+                                                       __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_LESS_ACC_SENSING;
+                                               }
+                                       }
+                               }
+                               else if (__minRequestedAccuracy == LOC_ACCURACY_FINEST || __minRequestedAccuracy == LOC_ACCURACY_TEN_METERS)
+                               {
+                                       if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_FINE_ACC_SENSING)
+                                       {
+                                               const int SUB_STATE_TIMER_VALUE = 5;
+                                               result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                                               if (!IsFailed(r))
+                                               {
+                                                       SysLog(NID_LOC, "Started the sub state timer for 5 seconds in LOC_MGR_STATE_WPS_ONLY as WPS accuracy not met.");
+                                                       __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_FINE_ACC_SENSING;
+                                               }
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_SENSING)
+                               {
+                                       SysLog(NID_LOC, "The number of GPS failures is (%d)", __locMgrStatus.gpsFailCount);
+                                       double timerVal = Math::Pow(2, (__locMgrStatus.gpsFailCount - 1)) * 10;
+                                       if (timerVal > MAX_TIMER_VALUE_DURING_WPS_POSITIONING)
+                                       {
+                                               timerVal = MAX_TIMER_VALUE_DURING_WPS_POSITIONING;
+                                       }
+                                       const int SUB_STATE_TIMER_VALUE = (int) timerVal;
+                                       result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                                       if (!IsFailed(r))
+                                       {
+                                               SysLog(NID_LOC, "Started the sub state timer for (%d) seconds in LOC_MGR_STATE_WPS_ONLY mode when last GPS session has failed.");
+                                               __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_SENSING;
+                                       }
+                               }
+                       }
+               }
+               else
+               {
+                       if (__locMgrStatus.locMgrSubState != LM_SS_WPS_ONLY_NO_FIX)
+                       {
+                               const int SUB_STATE_TIMER_VALUE = 10;
+                               SysLog(NID_LOC, "WPS position not available in LOC_MGR_STATE_WPS_ONLY state.");
+                               result r = RestartSubStateTimer(SUB_STATE_TIMER_VALUE);
+                               if (!IsFailed(r))
+                               {
+                                       SysLog(NID_LOC, "Started the sub state timer for 10 seconds in LOC_MGR_STATE_WPS_ONLY state when GPS is enabled and WPS no fix.");
+                                       __locMgrStatus.locMgrSubState = LM_SS_WPS_ONLY_NO_FIX;
+                               }
+                       }
+               }
+       }
+       else
        {
-               location_manager_destroy(__wpsHandler.handle);
+               StopSubStateTimer();
+               if (isTimeUpdated)
+               {
+                       SysLog(NID_LOC, "WPS position available with less accuracy in LOC_MGR_STATE_WPS_ONLY state.");
+                       __locMgrStatus.locMgrSubState = LM_SS_SENSING;
+               }
+               else
+               {
+                       SysLog(NID_LOC, "WPS position not available in LOC_MGR_STATE_WPS_ONLY state.");
+                       __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+               }
        }
-       return false;
 }
 
 void
-_LocationManager::OnStop(void)
+_LocationManager::IsGpsLocationUpdated(bool& isTimeUpdated, bool& isAccMet)
 {
-       delete __pInitMonitor;
-       __pInitMonitor = null;
+       double minAccRequested = ConvertLocationAccuracyToDouble(__minRequestedAccuracy);
 
-       if (__gpsHandler.handle)
+       if (__locMgrStatus.gpsHandler.pLocation->GetTimestamp() > __locMgrStatus.gpsHandler.oldTimeStamp)
        {
-               location_manager_destroy(__gpsHandler.handle);
-       }
-       if (__wpsHandler.handle)
-       {
-               location_manager_destroy(__wpsHandler.handle);
+               double gpsAccuracy = __locMgrStatus.gpsHandler.pLocation->GetHorizontalAccuracy();
+               isTimeUpdated = true;
+               if (!Double::IsNaN(gpsAccuracy) && gpsAccuracy <= minAccRequested)
+               {
+                       isAccMet = true;
+               }
+               __locMgrStatus.gpsHandler.oldTimeStamp = __locMgrStatus.gpsHandler.pLocation->GetTimestamp();
        }
 }
 
 void
-_LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
+_LocationManager::IsWpsLocationUpdated(bool& isTimeUpdated, bool& isAccMet)
 {
-       const int ARRAY_LIST_CAPACITY = 1;
+       double minAccRequested = ConvertLocationAccuracyToDouble(__minRequestedAccuracy);
 
-       switch (requestId)
-       {
-       case REQ_ID_START_LOC_UPDATES:
+       if (__locMgrStatus.wpsHandler.pLocation->GetTimestamp() > __locMgrStatus.wpsHandler.oldTimeStamp)
        {
-               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.");
+               double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy();
+               isTimeUpdated = true;
+               if (!Double::IsNaN(wpsAccuracy) && wpsAccuracy <= minAccRequested)
+               {
+                       isAccMet = true;
+               }
+               __locMgrStatus.wpsHandler.oldTimeStamp = __locMgrStatus.wpsHandler.pLocation->GetTimestamp();
+       }
+}
 
-               AddToLocRequestInfoList(pLocRequestInfo);
+double
+_LocationManager::ConvertLocationAccuracyToDouble(LocationAccuracy locAcc)
+{
+       SysAssertf((locAcc > LOC_ACCURACY_INVALID && locAcc <= LOC_ACCURACY_ANY), "The accuracy value is not valid.");
+
+       static int accArray[] = {NaN, ACCURACY_FINEST, ACCURACY_TEN_MTRS, ACCURACY_HUNDRED_MTRS, ACCURACY_ONE_KILOMETER, ACCURACY_ANY};
+
+       return accArray[locAcc];
+}
+
+result
+_LocationManager::RestartSubStateTimer(int timeout)
+{
+       result r = E_SUCCESS;
+
+       StopSubStateTimer();
+       r = __locMgrStatus.pLocMgrSubStateTimer->Start(timeout * 1000);
+       SysTryReturnResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the sub state timer with timer value (%d) seconds.", GetErrorMessage(r), timeout);
+       __locMgrStatus.isSubStateTimerStarted = true;
+       // Make a note of the GPS time stamp when sub state timer started. This is used to identify GPS fail case.
+       __locMgrStatus.gpsTimeAtSubstateTimerStart = __locMgrStatus.gpsHandler.pLocation->GetTimestamp();
+       return E_SUCCESS;
+}
+
+void
+_LocationManager::StopSubStateTimer(void)
+{
+       if (__locMgrStatus.isSubStateTimerStarted)
+       {
+               result r = __locMgrStatus.pLocMgrSubStateTimer->Cancel();
+               SysTryLog(NID_LOC, r == E_SUCCESS, "[%s] Failed to stop the sub state timer.", GetErrorMessage(r));
+               __locMgrStatus.isSubStateTimerStarted = false;
+       }
+}
+
+void
+_LocationManager::HandleSubStateTimerExpiry(void)
+{
+       SysLog(NID_LOC, "The substate timer expired for the State (%d) with sub state (%d).", __locMgrStatus.locMgrState, __locMgrStatus.locMgrSubState);
+
+       switch (__locMgrStatus.locMgrState)
+       {
+       case LOC_MGR_STATE_BOTH_GPS_WPS:
+       {
+               switch (__locMgrStatus.locMgrSubState)
+               {
+               case LM_SS_BOTH_SENSING:
+               // follow through
+               case LM_SS_BOTH_SETTLED_WAITING:
+               {
+                       enum nextState
+                       {
+                               SWITCH_STATE_NONE,
+                               SWITCH_STATE_WPS_ONLY,
+                               SWITCH_STATE_GPS_ONLY
+                       };
+
+                       nextState nxtState = SWITCH_STATE_NONE;
+                       double gpsAccuracy = __locMgrStatus.gpsHandler.pLocation->GetHorizontalAccuracy();
+                       double wpsAccuracy = __locMgrStatus.wpsHandler.pLocation->GetHorizontalAccuracy();
+
+                       long long wpsTimestamp = __locMgrStatus.wpsHandler.pLocation->GetTimestamp().GetTicks();
+                       long long gpsTimestamp = __locMgrStatus.gpsHandler.pLocation->GetTimestamp().GetTicks();
+
+                       long long timeDiff = Math::Abs(wpsTimestamp - gpsTimestamp);
+                       SysLog(NID_LOC, "Accuracy values are, GPS (%lf) and WPS (%lf). Time difference is (%lld).", gpsAccuracy, wpsAccuracy, timeDiff);
+
+                       if (timeDiff <= 1)
+                       {
+                               SysLog(NID_LOC, "Both GPS and WPS position available.");
+                               if (!Double::IsNaN(wpsAccuracy) && wpsAccuracy <= gpsAccuracy)
+                               {
+                                       SysLog(NID_LOC, "WPS accuracy is better than or equal to GPS.");
+                                       nxtState = SWITCH_STATE_WPS_ONLY;
+                               }
+                               else
+                               {
+                                       SysLog(NID_LOC, "GPS accuracy is better than WPS.");
+                                       nxtState = SWITCH_STATE_GPS_ONLY;
+                               }
+                       }
+                       else
+                       {
+                               SysLog(NID_LOC, "WPS and GPS timestamp is not similar.");
+                               if (wpsTimestamp > gpsTimestamp)
+                               {
+                                       SysLog(NID_LOC, "WPS timestamp is better than GPS.");
+                                       nxtState = SWITCH_STATE_WPS_ONLY;
+                               }
+                               else
+                               {
+                                       SysLog(NID_LOC, "GPS timestamp is better than WPS.");
+                                       nxtState = SWITCH_STATE_GPS_ONLY;
+                               }
+                       }
+
+                       switch(nxtState)
+                       {
+                       case SWITCH_STATE_WPS_ONLY:
+                       {
+                               location_manager_stop(__locMgrStatus.gpsHandler.handle);
+                               __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY;
+                               __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+                       }
+                       break;
+
+                       case SWITCH_STATE_GPS_ONLY:
+                       {
+                               location_manager_stop(__locMgrStatus.wpsHandler.handle);
+                               __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY;
+                               __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+                       }
+                       break;
+
+                       case SWITCH_STATE_NONE:
+                       // follow through
+                       default:
+                               SysAssertf(false, "This state cannot happen.");
+                       break;
+                       }
+
+                       if (__locMgrStatus.locMgrSubState == LM_SS_BOTH_SENSING)
+                       {
+                               long long diff = gpsTimestamp - __locMgrStatus.gpsTimeAtSubstateTimerStart.GetTicks();
+                               if (diff < 0)   // Considered to be GPS fail.
+                               {
+                                       __locMgrStatus.gpsFailCount++;
+                               }
+                       }
+               }
+               break;
+
+               case LM_SS_IDLE:
+               // follow through
+               case LM_SS_SETTLED:
+               // follow through
+               case LM_SS_SENSING:
+               // follow through
+               case LM_SS_NO_FIX:
+               // follow through
+               case LM_SS_GPS_ONLY_SETTLED:
+               // follow through
+               case LM_SS_GPS_ONLY_SENSING:
+               // follow through
+               case LM_SS_GPS_ONLY_NO_FIX:
+               // follow through
+               case LM_SS_WPS_ONLY_LESS_ACC_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_FINE_ACC_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_NO_FIX:
+               // follow through
+               default:
+                       SysLog(NID_LOC, "The sub state timer expired in wrong location manager sub state.");
+                       break;
+               }
        }
        break;
 
-       case REQ_ID_STOP_LOC_UPDATES:
+       case LOC_MGR_STATE_GPS_ONLY:
        {
-               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.");
+               switch (__locMgrStatus.locMgrSubState)
+               {
+               case LM_SS_GPS_ONLY_SETTLED:
+               // follow through
+               case LM_SS_GPS_ONLY_SENSING:
+               // follow through
+               case LM_SS_GPS_ONLY_NO_FIX:
+               {
+                       if (__wpsEnabled)
+                       {
+                               SysLog(NID_LOC, "WPS setting is enabled. Start WPS now.");
+                               int res = location_manager_start(__locMgrStatus.wpsHandler.handle);
+                               SysTryLog(NID_LOC, res == 0, "Failed to start the core WPS location manager. So continue with GPS only.");
+                               if (res == 0)
+                               {
+                                       __locMgrStatus.locMgrState = LOC_MGR_STATE_BOTH_GPS_WPS;
+                               }
+                       }
+                       __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+               }
+               break;
 
-               RemoveFromLocRequestInfoList(static_cast< long >(pReqId->ToInt()));
+               case LM_SS_IDLE:
+               // follow through
+               case LM_SS_SETTLED:
+               // follow through
+               case LM_SS_SENSING:
+               // follow through
+               case LM_SS_NO_FIX:
+               // follow through
+               case LM_SS_BOTH_SENSING:
+               // follow through
+               case LM_SS_BOTH_SETTLED_WAITING:
+               // follow through
+               case LM_SS_WPS_ONLY_LESS_ACC_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_FINE_ACC_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_NO_FIX:
+               // follow through
+               default:
+                       SysLog(NID_LOC, "The sub state timer expired in wrong location manager sub state.");
+                       break;
+               }
+       }
+       break;
+
+       case LOC_MGR_STATE_WPS_ONLY:
+       {
+               switch (__locMgrStatus.locMgrSubState)
+               {
+               case LM_SS_WPS_ONLY_LESS_ACC_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_FINE_ACC_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_SENSING:
+               // follow through
+               case LM_SS_WPS_ONLY_NO_FIX:
+               {
+                       if (__gpsEnabled)
+                       {
+                               SysLog(NID_LOC, "GPS setting is enabled and WPS could not fix the location with requested accuracy. Start GPS now.");
+                               int res = location_manager_start(__locMgrStatus.gpsHandler.handle);
+                               SysTryLog(NID_LOC, res == 0, "Failed to start the core GPS location provider. So continue with WPS only.");
+                               if (res == 0)
+                               {
+                                       __locMgrStatus.locMgrState = LOC_MGR_STATE_BOTH_GPS_WPS;
+                               }
+                       }
+                       __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+               }
+               break;
+
+               case LM_SS_IDLE:
+               // follow through
+               case LM_SS_SETTLED:
+               // follow through
+               case LM_SS_SENSING:
+               // follow through
+               case LM_SS_NO_FIX:
+               // follow through
+               case LM_SS_BOTH_SENSING:
+               // follow through
+               case LM_SS_BOTH_SETTLED_WAITING:
+               // follow through
+               case LM_SS_GPS_ONLY_SETTLED:
+               // follow through
+               case LM_SS_GPS_ONLY_SENSING:
+               // follow through
+               case LM_SS_GPS_ONLY_NO_FIX:
+               // follow through
+               default:
+                       SysLog(NID_LOC, "The sub state timer expired in wrong location manager sub state.");
+                       break;
+               }
+       }
+       break;
+
+       case LOC_MGR_STATE_IDLE:
+       // follow through
+       case LOC_MGR_STATE_PASSIVE_IDLE:
+       // follow through
+       default:
+               SysLog(NID_LOC, "The sub state timer expired in wrong location manager state.");
+       break;
+       }
+
+       __locMgrStatus.isSubStateTimerStarted = false;
+}
+
+void
+_LocationManager::HandleLocationCheckTimerExpiry(void)
+{
+       SysLog(NID_LOC, "Location check timer expired.");
+       const int LOC_CHECK_TIMER_VALUE = 1000;
+
+       switch (__locMgrStatus.locMgrState)
+       {
+       case LOC_MGR_STATE_BOTH_GPS_WPS:
+       {
+               if (__locMgrStatus.wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
+               {
+                       result gpsRes = GetLocation(LOCATIONS_METHOD_WPS);
+                       SysTryLog(NID_LOC, gpsRes == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information.");
+               }
+               else
+               {
+                       SysLog(NID_LOC, "WPS Location not available at the Native side.");
+               }
+
+               if (__locMgrStatus.gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
+               {
+                       result wpsRes = GetLocation(LOCATIONS_METHOD_GPS);
+                       SysTryLog(NID_LOC, wpsRes == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information.");
+               }
+               else
+               {
+                       SysLog(NID_LOC, "GPS Location not available at the Native side.");
+               }
+               HandleBothGpsWpsState();
        }
        break;
 
-       case REQ_ID_RESTART_LOC_UPDATES:
+       case LOC_MGR_STATE_GPS_ONLY:
        {
-               SysLog(NID_LOC, "REQ_ID_RESTART_LOC_UPDATES.");
-               RestartLocationUpdates();
+               if (__locMgrStatus.gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
+               {
+                       result res = GetLocation(LOCATIONS_METHOD_GPS);
+                       SysTryLog(NID_LOC, res == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information.");
+               }
+               else
+               {
+                       SysLog(NID_LOC, "GPS Location not available at the Native side.");
+               }
+               HandleGpsOnlyState();
+       }
+       break;
+
+       case LOC_MGR_STATE_WPS_ONLY:
+       {
+               if (__locMgrStatus.wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
+               {
+                       result res = GetLocation(LOCATIONS_METHOD_WPS);
+                       SysTryLog(NID_LOC, res == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information.");
+               }
+               else
+               {
+                       SysLog(NID_LOC, "WPS Location not available at the Native side.");
+               }
+               HandleWpsOnlyState();
        }
        break;
 
-       case REQ_ID_SUSTAIN_GPS:
+       case LOC_MGR_STATE_IDLE:
+       //follow through
+       case LOC_MGR_STATE_PASSIVE_IDLE:
+       //follow through
+       default:
+               SysLog(NID_LOC, "The timer expiry called in wrong location manager state.");
+               return;
+       }
+
+       __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE);
+}
+
+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< 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< 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< 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< 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 update timer.");
+       std::unique_ptr< Timer > pLocCheckTimer(new (std::nothrow) Timer());
+       r = pLocCheckTimer->Construct(*this);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location chek timer.");
+       std::unique_ptr< Timer > pLocMgrSubstateTimer(new (std::nothrow) Timer());
+       r = pLocMgrSubstateTimer->Construct(*this);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the location manager sub state timer.");
+
+       r = SettingInfo::AddSettingEventListener(*this);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to set the setting event listener.");
+
+       res = location_manager_create(LOCATIONS_METHOD_GPS, &__locMgrStatus.gpsHandler.handle);
+       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native GPS Location provider.");
+       res = location_manager_set_service_state_changed_cb(__locMgrStatus.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, &__locMgrStatus.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(__locMgrStatus.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);
+       __pLocCallbackTimer = std::move(pLocUpdateTimer);
+       __pLocCheckTimer = std::move(pLocCheckTimer);
+       __locMgrStatus.pLocMgrSubStateTimer = std::move(pLocMgrSubstateTimer);
+       __locMgrStatus.gpsHandler.pLocation = std::move(pGpsLocation);
+       __locMgrStatus.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 (__locMgrStatus.gpsHandler.handle)
+       {
+               location_manager_destroy(__locMgrStatus.gpsHandler.handle);
+       }
+
+       if (__locMgrStatus.wpsHandler.handle)
+       {
+               location_manager_destroy(__locMgrStatus.wpsHandler.handle);
+       }
+       SettingInfo::RemoveSettingEventListener(*this);
+
+       return false;
+}
+
+void
+_LocationManager::OnStop(void)
+{
+       delete __pInitMonitor;
+       __pInitMonitor = null;
+
+       if (__locMgrStatus.gpsHandler.handle)
+       {
+               location_manager_destroy(__locMgrStatus.gpsHandler.handle);
+       }
+       if (__locMgrStatus.wpsHandler.handle)
+       {
+               location_manager_destroy(__locMgrStatus.wpsHandler.handle);
+       }
+       SettingInfo::RemoveSettingEventListener(*this);
+}
+
+void
+_LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
+{
+       const int ARRAY_LIST_CAPACITY = 1;
+
+       switch (requestId)
        {
-               SysLog(NID_LOC, "REQ_ID_SUSTAIN_GPS.");
-               location_manager_stop(__wpsHandler.handle);
-               __locMethodRequested = LOC_METHOD_REQUESTED_GPS;
+       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_SUSTAIN_WPS:
+       case REQ_ID_STOP_LOC_UPDATES:
        {
-               SysLog(NID_LOC, "REQ_ID_SUSTAIN_WPS.");
-               location_manager_stop(__gpsHandler.handle);
-               __locMethodRequested = LOC_METHOD_REQUESTED_WPS;
+               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;
 
@@ -1272,7 +1805,7 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
                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());
+               UpdateLocRequestInterval(static_cast< long >(pReqId->ToInt()), pInterval->ToInt());
        }
        break;
 
@@ -1320,87 +1853,180 @@ CATCH:
 void
 _LocationManager::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
 {
-       if (__pLocUpdateTimer->Equals(timer))
+       if (__pLocCheckTimer->Equals(timer))
+       {
+               HandleLocationCheckTimerExpiry();
+       }
+       else if (__pLocCallbackTimer->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:
+               __pLocCallbackTimer->Start(__timerInterval * 1000);
+               SendLocationCallbacks();
+       }
+       else if (__locMgrStatus.pLocMgrSubStateTimer.get()->Equals(timer))
+       {
+               SysLog(NID_LOC, "Substate timer expired.");
+               HandleSubStateTimerExpiry();
+       }
+       else
+       {
+               int count = __pSyncLocRequestInfoList->GetCount();
+               for (int i = 0; i < count; i++)
                {
-                       r = GetLocation(LOCATIONS_METHOD_GPS);
-                       SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information");
-                       if (IsFailed(r))
+                       _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i));
+                       if (pSyncLocRequestInfo != null && pSyncLocRequestInfo->Equals(timer))
                        {
-                               SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null);
+                               SysLog(NID_LOC, "Timer expired for the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId());
+
+                               HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo);
+                               break;
                        }
                }
-               break;
+       }
+       return;
+}
+
+void
+_LocationManager::OnSettingChanged(Tizen::Base::String& key)
+{
+       const String GPS_STRING(L"http://tizen.org/setting/location.gps");
+       const String WPS_STRING(L"http://tizen.org/setting/location.wps");
+
+       SysLog(NID_LOC, "The setting value is changed for (%ls) setting.", key.GetPointer());
+
+       if (!((key.Equals(GPS_STRING, false)) || (key.Equals(WPS_STRING, false))))
+       {
+               return;
+       }
+
+       bool gpsEnabled = false;
+       bool wpsEnabled = false;
+       result gps = _SettingInfoImpl::GetValue(GPS_STRING, gpsEnabled);
+       SysTryReturnVoidResult(NID_LOC, gps == E_SUCCESS, gps, "[%s] Failed to get the setting value for GPS.", GetErrorMessage(gps));
+       result wps = _SettingInfoImpl::GetValue(WPS_STRING, wpsEnabled);
+       SysTryReturnVoidResult(NID_LOC, wps == E_SUCCESS, wps, "[%s] Failed to get the setting value for WPS.", GetErrorMessage(wps));
 
-               case LOC_METHOD_REQUESTED_WPS:
+       SysLog(NID_LOC, "The current GPS setting value is (%d) and WPS setting value is (%d).", __gpsEnabled, __wpsEnabled);
+       SysLog(NID_LOC, "The changed GPS setting value is (%d) and WPS setting value is (%d).", gpsEnabled, wpsEnabled);
+
+       switch (__locMgrStatus.locMgrState)
+       {
+       case LOC_MGR_STATE_PASSIVE_IDLE:
+       {
+               if (gpsEnabled && !wpsEnabled)
                {
-                       r = GetLocation(LOCATIONS_METHOD_WPS);
-                       SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information");
-                       if (IsFailed(r))
+                       SysLog(NID_LOC, "GPS setting enabled during the LOC_MGR_STATE_PASSIVE_IDLE.");
+                       int res = location_manager_start(__locMgrStatus.gpsHandler.handle);
+                       SysTryLog(NID_LOC, res == 0, "Failed to start the GPS location updates in Passive Idle mode.");
+                       if (res == 0)
                        {
-                               SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null);
+                               const int LOC_CHECK_TIMER_VALUE = 1;
+                               __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY;
+                               __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+                               __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE * 1000);
                        }
                }
-               break;
-
-               case LOC_METHOD_REQUESTED_ALL:
+               else if (!gpsEnabled && wpsEnabled)
                {
-                       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 setting enabled during the LOC_MGR_STATE_PASSIVE_IDLE.");
+                       int res = location_manager_start(__locMgrStatus.wpsHandler.handle);
+                       SysTryLog(NID_LOC, res == 0, "Failed to start the WPS location updates in Passive Idle mode.");
+                       if (res == 0)
                        {
-                               SysLog(NID_LOC, "WPS Location not available at the Native side.");
+                               const int LOC_CHECK_TIMER_VALUE = 1;
+                               __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY;
+                               __locMgrStatus.locMgrSubState = LM_SS_NO_FIX;
+                               __pLocCheckTimer->Start(LOC_CHECK_TIMER_VALUE * 1000);
                        }
+               }
+       }
+       break;
+
+       case LOC_MGR_STATE_BOTH_GPS_WPS:
+       {
+               if (!gpsEnabled)
+               {
+                       SysLog(NID_LOC, "GPS setting turned off during LOC_MGR_STATE_BOTH_GPS_WPS.");
+                       location_manager_stop(__locMgrStatus.gpsHandler.handle);
+                       __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY;
+               }
 
-                       if (__gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
+               if (!wpsEnabled)
+               {
+                       SysLog(NID_LOC, "WPS setting turned off during LOC_MGR_STATE_BOTH_GPS_WPS.");
+                       location_manager_stop(__locMgrStatus.wpsHandler.handle);
+                       __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY;
+               }
+       }
+       break;
+
+       case LOC_MGR_STATE_GPS_ONLY:
+       {
+               if (!gpsEnabled)
+               {
+                       int res = -1;
+                       if (wpsEnabled)
                        {
-                               r = GetLocation(LOCATIONS_METHOD_GPS);
-                               SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information");
+                               SysLog(NID_LOC, "The WPS setting is enabled. So starting WPS now.");
+                               res = location_manager_start(__locMgrStatus.wpsHandler.handle);
+                               SysTryLog(NID_LOC, res == 0, "Failed to start the location updates for WPS. Return value is (%d).", res);
+                               if (res == 0)
+                               {
+                                       __locMgrStatus.locMgrState = LOC_MGR_STATE_WPS_ONLY;
+                               }
                        }
-                       else
+                       if (!wpsEnabled || res != 0)
                        {
-                               SysLog(NID_LOC, "GPS Location not available at the Native side.");
+                               __locMgrStatus.locMgrState = LOC_MGR_STATE_PASSIVE_IDLE;
+                               StopSubStateTimer();
+                               __pLocCheckTimer->Cancel();
                        }
-               }
-               break;
 
-               case LOC_METHOD_REQUESTED_NONE:
-               // follow through
-               default:
-                       SysLog(NID_LOC, "Timer expired when no location update is called.");
-                       return;
+                       SysLog(NID_LOC, "GPS setting turned off during LOC_MGR_STATE_GPS_ONLY.");
+                       location_manager_stop(__locMgrStatus.gpsHandler.handle);
                }
-
-               __pLocUpdateTimer->Start(__timerInterval * 1000);
-               SendLocationCallbacks();
        }
-       else
+       break;
+
+       case LOC_MGR_STATE_WPS_ONLY:
        {
-               int count = __pSyncLocRequestInfoList->GetCount();
-               for (int i = 0; i < count; i++)
+               if (!wpsEnabled)
                {
-                       _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i));
-                       if (pSyncLocRequestInfo != null && pSyncLocRequestInfo->Equals(timer))
+                       int res = -1;
+                       if (gpsEnabled)
                        {
-                               SysLog(NID_LOC, "Timer expired for the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId());
-
-                               HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo);
-                               break;
+                               SysLog(NID_LOC, "The GPS setting is enabled. So starting GPS now.");
+                               res = location_manager_start(__locMgrStatus.gpsHandler.handle);
+                               SysTryLog(NID_LOC, res == 0, "Failed to start the location updates for GPS. Return value is (%d).", res);
+                               if (res == 0)
+                               {
+                                       __locMgrStatus.locMgrState = LOC_MGR_STATE_GPS_ONLY;
+                               }
                        }
+                       if (!gpsEnabled || res != 0)
+                       {
+                               __locMgrStatus.locMgrState = LOC_MGR_STATE_PASSIVE_IDLE;
+                               StopSubStateTimer();
+                               __pLocCheckTimer->Cancel();
+                       }
+
+                       SysLog(NID_LOC, "WPS setting turned off during LOC_MGR_STATE_WPS_ONLY.");
+                       location_manager_stop(__locMgrStatus.wpsHandler.handle);
                }
        }
+       break;
 
-       return;
+       case LOC_MGR_STATE_IDLE:
+       // follow through
+       default:
+               SysLog(NID_LOC, "GPS setting changed when there is no active location request. (%d),", __locMgrStatus.locMgrState);
+       break;
+       }
+
+       __gpsEnabled = gpsEnabled;
+       __wpsEnabled = wpsEnabled;
 }
 
 bool
@@ -1441,7 +2067,7 @@ _LocationManager::GpsServiceUpdateCallback(location_service_state_e state, void*
        }
 
        _LocationManager* pThis = static_cast< _LocationManager* >(user_data);
-       pThis->__gpsHandler.serviceState = state;
+       pThis->__locMgrStatus.gpsHandler.serviceState = state;
 }
 
 void
@@ -1455,7 +2081,7 @@ _LocationManager::WpsServiceUpdateCallback(location_service_state_e state, void*
        }
 
        _LocationManager* pThis = static_cast< _LocationManager* >(user_data);
-       pThis->__wpsHandler.serviceState = state;
+       pThis->__locMgrStatus.wpsHandler.serviceState = state;
 }
 
 int
@@ -1467,7 +2093,6 @@ _LocationManager::AlarmExpiryCallback(alarm_id_t alarm_id, void* user_param)
                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();
 
index 4194035..04de9d6 100644 (file)
 #include <alarm.h>
 #include <location/locations.h>
 #include <FBaseColAllElementsDeleter.h>
+#include <FBaseDateTime.h>
 #include <FBaseRtEventDrivenThread.h>
 #include <FLocLocation.h>
+#include <FSysISettingEventListener.h>
 #include "FLoc_ILocationManagerListener.h"
 #include "FLoc_Types.h"
 
 namespace Tizen { namespace Locations
 {
-
 class _AlarmRequestInfo;
 class _LocationMonitor;
 class _LocationRequestInfo;
@@ -45,6 +46,7 @@ class _SyncLocationRequestInfo;
 class _LocationManager
        : public Tizen::Base::Runtime::EventDrivenThread
        , public Tizen::Base::Runtime::ITimerEventListener
+       , public Tizen::System::ISettingEventListener
 {
 public:
        // This method adds the location request into the list of requests and requests for location updates from core location provider.
@@ -162,29 +164,29 @@ private:
        //
        void RemoveFromAlarmRequestInfoList(RequestId reqId);
 
-       // The method restarts both GPS and WPS native location providers.
+       // The method updates the minimum accuracy required.
        //
-       // @since 2.0
+       // @since 2.2
        //
-       void RestartLocationUpdates(void);
+       void UpdateMinimunAccuracy(void);
 
-       // The method restarts the update timer after calculating the GCD of the timeout values requested by each location provider.
+       // The method starts the core location provider when the location is requested during Location manager idle state.
        //
-       // @since 2.0
+       // @since 2.2
        //
-       void RestartUpdateTimer(void);
+       void InitiateLocationRequest(void);
 
-       // The method is called everytime the sync retrieval timer is expired.
+       // The method restarts the callback timer after calculating the GCD of the timeout values requested by each location provider.
        //
-       // @since 2.0
+       // @since 2.2
        //
-       void HandleSyncRetrievalTimerExpiry(_SyncLocationRequestInfo& syncLocRequestInfo);
+       void RestartCallbackTimer(void);
 
-       // The method is called everytime the Async update timer is expired to set the location information.
+       // The method is called everytime the sync retrieval timer is expired.
        //
        // @since 2.0
        //
-       result SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod, Location* pLocation);
+       void HandleSyncRetrievalTimerExpiry(_SyncLocationRequestInfo& syncLocRequestInfo);
 
        // The method is called to send back the callbacks in case of async location updates.
        //
@@ -226,7 +228,7 @@ private:
        //
        // @since 2.0
        //
-       void UpdateLocRequestInfoList(RequestId reqId, int interval);
+       void UpdateLocRequestInterval(RequestId reqId, int interval);
 
        // This method gets the better location among the three location providers.
        //
@@ -240,22 +242,73 @@ private:
        //
        result GetLocation(location_method_e nativeLocMethod);
 
-       // This method Covert error code for native error.
+       // This method handles the location information obtained from core location provider/s when the location manager state is LOC_MGR_STATE_BOTH_GPS_WPS.
        //
-       // @since 2.1
+       // @since 2.2
        //
-       inline double ConvertToNativeFormat(double value)
-       {
-               return value < 0.0 ? Tizen::Locations::NaN : value;
-       }
+       void HandleBothGpsWpsState(void);
+
+       // This method handles the location information obtained from core GPS location provider when the location manager state is LOC_MGR_STATE_GPS_ONLY.
+       //
+       // @since 2.2
+       //      
+       void HandleGpsOnlyState(void);
+
+       // This method handles the location information obtained from core WPS location provider when the location manager state is LOC_MGR_STATE_WPS_ONLY.
+       //
+       // @since 2.2
+       //
+       void HandleWpsOnlyState(void);
+
+       // This method checks the validity of location updated by GPS core provider is valid or not.
+       //
+       // @since 2.2
+       //
+       void IsGpsLocationUpdated(bool& isTimeUpdated, bool& isAccMet);
+
+       // This method checks the validity of location updated by WPS core provider is valid or not.
+       //
+       // @since 2.2
+       //
+       void IsWpsLocationUpdated(bool& isTimeUpdated, bool& isAccMet); 
+
+       // This method converts the LocationAccuracy enum variable to corresponding double value.
+       //
+       // @since 2.2
+       //
+       double ConvertLocationAccuracyToDouble(LocationAccuracy locAcc);
+
+       // This method stops if timer is running and starts the sub state timer for the given interval.
+       //
+       // @since 2.2
+       //
+       result RestartSubStateTimer(int timeout);
+
+       // This method stops the sub state timer if it is running.
+       //
+       // @since 2.2
+       //
+       void StopSubStateTimer(void);   
 
-       // This method Covert error code for native altitude error.
+       // This method handles the expiry of the sub state.
+       //
+       // @since 2.2
+       //
+       void HandleSubStateTimerExpiry(void);
+
+       // This method handles the expiry of the location check timer.
+       //
+       // @since 2.2
+       //
+       void HandleLocationCheckTimerExpiry(void);      
+
+       // This method Covert error code for native error.
        //
        // @since 2.1
        //
-       inline double ConvertToNativeFormatAltitude(double value)
+       inline double ConvertToNativeFormat(double value)
        {
-               return value == -1.0 ? Tizen::Locations::NaN : value;
+               return value < 0.0 ? Tizen::Locations::NaN : value;
        }
 
        // @see @ref Tizen::Base::Runtime::EventDrivenThread::OnStart()
@@ -282,6 +335,12 @@ private:
        //
        virtual void OnTimerExpired(Tizen::Base::Runtime::Timer& timer);
 
+       // @see @ref Tizen::System::ISettingEventListener::OnSettingChanged()
+       //
+       // @since 2.1
+       //
+       virtual void OnSettingChanged(Tizen::Base::String& key);
+
        // This callback is recieved from native location manager for satellite information.
        //
        // @since 2.0
@@ -321,31 +380,37 @@ private:
 private:
        const static RequestId REQ_ID_START_LOC_UPDATES = 1;
        const static RequestId REQ_ID_STOP_LOC_UPDATES = 2;
-       const static RequestId REQ_ID_RESTART_LOC_UPDATES = 3;
-       const static RequestId REQ_ID_SUSTAIN_GPS = 4;
-       const static RequestId REQ_ID_SUSTAIN_WPS = 5;
-       const static RequestId REQ_ID_SYNC_LOC_RETRIEVAL = 6;
-       const static RequestId REQ_ID_GET_LAST_LOCATION = 7;
-       const static RequestId REQ_ID_UPDATE_INTERVAL = 8;
-       const static RequestId REQ_ID_START_ALARM = 9;
-       const static RequestId REQ_ID_STOP_ALARM = 10;
-
-       enum _LocationMethodRequested
-       {
-               LOC_METHOD_REQUESTED_NONE,
-               LOC_METHOD_REQUESTED_GPS,
-               LOC_METHOD_REQUESTED_WPS,
-               LOC_METHOD_REQUESTED_ALL,
-       }
-       __locMethodRequested;
+       const static RequestId REQ_ID_SYNC_LOC_RETRIEVAL = 3;
+       const static RequestId REQ_ID_GET_LAST_LOCATION = 4;
+       const static RequestId REQ_ID_UPDATE_INTERVAL = 5;
+       const static RequestId REQ_ID_START_ALARM = 6;
+       const static RequestId REQ_ID_STOP_ALARM = 7;
 
        enum _LocationManagerState
        {
                LOC_MGR_STATE_IDLE,
-               LOC_MGR_STATE_FAST_SENSING,
-               LOC_MGR_STATE_FAST_SENSING_SETTLED
-       }
-       __locationMgrState;
+               LOC_MGR_STATE_PASSIVE_IDLE,
+               LOC_MGR_STATE_BOTH_GPS_WPS,
+               LOC_MGR_STATE_GPS_ONLY,
+               LOC_MGR_STATE_WPS_ONLY
+       };
+
+       enum _LocationManagerSubState
+       {
+               LM_SS_IDLE,
+               LM_SS_SETTLED,
+               LM_SS_SENSING,
+               LM_SS_NO_FIX,
+               LM_SS_BOTH_SENSING,
+               LM_SS_BOTH_SETTLED_WAITING,
+               LM_SS_GPS_ONLY_SETTLED,
+               LM_SS_GPS_ONLY_SENSING,
+               LM_SS_GPS_ONLY_NO_FIX,
+               LM_SS_WPS_ONLY_LESS_ACC_SENSING,
+               LM_SS_WPS_ONLY_FINE_ACC_SENSING,
+               LM_SS_WPS_ONLY_SENSING,
+               LM_SS_WPS_ONLY_NO_FIX
+       };
 
        class _LocationManagerHandle
        {
@@ -355,6 +420,7 @@ private:
                        , handle(null)
                        , pLocation(null)
                {
+                       oldTimeStamp.SetValue(1970, 1, 1);
                }
 
                ~_LocationManagerHandle(void)
@@ -364,20 +430,48 @@ private:
        public:
                location_service_state_e serviceState;
                location_manager_h handle;
+               Tizen::Base::DateTime oldTimeStamp;
                std::unique_ptr< Tizen::Locations::Location > pLocation;
        };
 
+       class _LocationManagerStatus
+       {
+       public:
+               _LocationManagerStatus(void)
+                       : isSubStateTimerStarted(false)
+                       , locMgrState(LOC_MGR_STATE_IDLE)
+                       , locMgrSubState(LM_SS_IDLE)
+                       , gpsFailCount(0)
+               {
+               }
+               ~_LocationManagerStatus(void)
+               {
+               }
+
+       public:
+               bool isSubStateTimerStarted;
+               _LocationManagerState locMgrState;
+               _LocationManagerSubState locMgrSubState;
+               int gpsFailCount;
+               Tizen::Base::DateTime gpsTimeAtSubstateTimerStart;
+               std::unique_ptr< Tizen::Base::Runtime::Timer > pLocMgrSubStateTimer;
+               _LocationManagerHandle gpsHandler;
+               _LocationManagerHandle wpsHandler;
+       };
+
+       bool __gpsEnabled;
+       bool __wpsEnabled;
+       _LocationManagerStatus __locMgrStatus;
        LocationAccuracy __minRequestedAccuracy;
        int __timerInterval;
        int __timerTicks;
-       _LocationManagerHandle __gpsHandler;
-       _LocationManagerHandle __wpsHandler;
        std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > __pLocRequestInfoList;
        std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > __pSyncLocRequestInfoList;
        std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > __pAlarmRequestInfoList;
-       std::unique_ptr< Tizen::Base::Runtime::Timer > __pLocUpdateTimer;
-       static _LocationManager* __pUniqueInstance;
+       std::unique_ptr< Tizen::Base::Runtime::Timer > __pLocCallbackTimer;
+       std::unique_ptr< Tizen::Base::Runtime::Timer > __pLocCheckTimer;
        Tizen::Base::Runtime::Monitor* __pInitMonitor;
+       static _LocationManager* __pUniqueInstance;
 
        friend class std::default_delete< _LocationManager >;
 };      // class _LocationManager
index dcb75da..f37894a 100644 (file)
@@ -39,6 +39,7 @@
 #include <FLocTypes.h>
 #include <FSysPowerManager.h>
 #include <FSysSystemTime.h>
+#include <FSec_AccessController.h>
 #include <FSys_SettingInfoImpl.h>
 #include "FLoc_LocationImpl.h"
 #include "FLoc_LocationManager.h"
@@ -53,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
@@ -68,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();
@@ -88,17 +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(SingleObjectDeleter));
+       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));
 
-       UiApp* pAppInstance = Tizen::App::UiApp::GetInstance();
+       UiApp* pAppInstance = UiApp::GetInstance();
        if (pAppInstance != null)
        {
                _AppManagerImpl* pAppManager = _AppManagerImpl::GetInstance();
@@ -180,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);
@@ -427,6 +429,7 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::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;
@@ -453,6 +456,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.");
@@ -462,13 +470,14 @@ _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);
 
@@ -479,18 +488,17 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location
                                *__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);
                }
        }
 
@@ -521,7 +529,7 @@ 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());
 
@@ -555,8 +563,7 @@ 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
@@ -577,7 +584,7 @@ _LocationProviderImpl::StartLocationUpdates(LocationUpdateType updateType, int i
 
        if (!__locationUpdater.awakeEnabled)
        {
-               UiApp* pAppInstance = Tizen::App::UiApp::GetInstance();
+               UiApp* pAppInstance = UiApp::GetInstance();
                if (pAppInstance == null)
                {
                        startUpdate = false;
@@ -690,23 +697,23 @@ _LocationProviderImpl::FireImpl(Tizen::Base::Runtime::IEventListener& listener,
 }
 
 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
@@ -746,17 +753,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
        {
@@ -770,12 +777,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
@@ -829,7 +840,12 @@ _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());
@@ -937,6 +953,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;
 }
 
index 450380b..5cdd1e8 100644 (file)
@@ -221,13 +221,13 @@ private:
        //
        // @since 2.0
        //
-       void HandleLocationUpdate(Tizen::Locations::Location& location, bool isLocationValid);
+       void HandleLocationUpdate(Tizen::Locations::Location& location, bool isLocationValid, bool isPrivilegeDenied);
 
        // This method handles the region monitoring.
        //
        // @since 2.0
        //
-       void HandleRegionMonitoring(Tizen::Locations::Location& location, bool isLocationValid);
+       void HandleRegionMonitoring(Tizen::Locations::Location& location, bool isLocationValid, bool isPrivilegeDenied, bool isAccuracyMet);
 
        // This method sends the callbacks to the applications regarding the Region events.
        // @since 2.0
index e7b72cb..d5b99c6 100644 (file)
@@ -31,7 +31,6 @@
 #include <FBaseRtTimer.h>
 #include <FBaseRtITimerEventListener.h>
 #include <FLocTypes.h>
-#include <FSysSystemTime.h>
 
 namespace Tizen { namespace Locations
 {