merge with master
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:16:58 +0000 (01:16 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:16:58 +0000 (01:16 +0900)
13 files changed:
CMakeLists.txt
inc/FLocLocationProvider.h [changed mode: 0755->0644]
packaging/osp-locations.spec
src/FLoc_Config.h
src/FLoc_LocationImpl.cpp
src/FLoc_LocationManager.cpp
src/FLoc_LocationManager.h
src/FLoc_LocationProviderImpl.cpp
src/FLoc_LocationProviderImpl.h
src/FLoc_LocationRequestInfo.h
src/FLoc_MathUtils.cpp
src/FLoc_MathUtils.h
src/FLoc_SyncLocationRequestInfo.h

index 49827e9..9697a40 100755 (executable)
@@ -11,6 +11,7 @@ INCLUDE_DIRECTORIES (
        /usr/include/osp
        /usr/include/osp/app
        /usr/include/osp/base
+       /usr/include/osp/io
        /usr/include/osp/system
        /usr/include/osp/security
        )
old mode 100755 (executable)
new mode 100644 (file)
index 33a6c60..9b88f1b
@@ -114,7 +114,8 @@ public:
        * the location provider cancels the prior request and restarts the updates with the specified parameter.
        *
        * @since 2.0
-       * @privilege %http://tizen.org/privilege/location
+       * @privlevel    public
+       * @privilege http://tizen.org/privilege/location
        *
        * @return       An error code
        * @param[in]    interval        The update interval in seconds
@@ -149,7 +150,8 @@ public:
        * the location provider cancels the prior request and restarts the updates with the specified parameter.
        *
        * @since 2.0
-       * @privilege %http://tizen.org/privilege/location
+       * @privlevel    public
+       * @privilege http://tizen.org/privilege/location
        *
        * @return       An error code
        * @param[in]    distance        The distance in meters
@@ -188,7 +190,8 @@ public:
        * during the location updates.
        *
        * @since 2.0
-       * @privilege %http://tizen.org/privilege/location and %http://tizen.org/privilege/power @n
+       * @privlevel    public
+       * @privilege http://tizen.org/privilege/location and http://tizen.org/privilege/power @n
        *                               Both privileges are required.
        *
        * @return       An error code
@@ -218,7 +221,8 @@ public:
        * Note that, the monitoring service can sometimes makes the system awake by running costly positioning devices.
        *
        * @since 2.0
-       * @privilege %http://tizen.org/privilege/location and %http://tizen.org/privilege/power @n
+       * @privlevel    public
+       * @privilege http://tizen.org/privilege/location and http://tizen.org/privilege/power @n
        *                               Both privileges are required.
        *
        * @return       An error code
@@ -303,7 +307,8 @@ public:
        * an invalid location with an @c E_LOCATION_UNAVAILABLE error.
        *
        * @since 2.0
-       * @privilege %http://tizen.org/privilege/location
+       * @privlevel    public
+       * @privilege http://tizen.org/privilege/location
        *
        * @return       The current location
        * @param[in]    criteria        The desired location criteria
@@ -313,11 +318,7 @@ public:
        * @exception    E_USER_NOT_CONSENTED    The user blocks an application from using the location information.
        * @exception    E_SYSTEM        A system error has occurred.
        * @remarks      This method call takes time as the location provider runs and waits for positioning system.
-       *                       If the method is called from the application's main thread, it makes the application unresponsive until it returns.
-       *                       If an application wants to be responsive, especially within the user interaction, it should use this method
-       *                       in a separated thread using Tizen::Base::Runtime::Thread class,
-       *                       rather than in the application's main thread which handles the ui events.
-       * @remarks      The specific error code can be accessed using the GetLastResult() method.
+       * @remarks     The specific error code can be accessed using the GetLastResult() method.
        */
        static Location GetLocation(const LocationCriteria& criteria);
 
@@ -329,7 +330,8 @@ public:
        * since using the last location preserves the location provider from running costly positioning systems.
        *
        * @since 2.0
-       * @privilege %http://tizen.org/privilege/location
+       * @privlevel    public
+       * @privilege http://tizen.org/privilege/location
        *
        * @return       The last location
        * @exception    E_SUCCESS       The method is successful.
index 29333a0..24f9170 100755 (executable)
@@ -3,7 +3,7 @@
 
 Name:          osp-locations
 Summary:       osp locations library
-Version:       1.2.0.0
+Version:       1.2.1.0
 Release:       2
 Group:         System/Libraries
 License:       TO_BE/FILLED_IN
index 83d336a..819d1a1 100644 (file)
 //
 
 /**
- * @file       FLoc_Config.h\r
- * @brief      This header file contains the constants used in the location namespace internally.\r
+ * @file       FLoc_Config.h
+ * @brief      This header file contains the constants used in the location namespace internally.
  *
- */\r
-\r
-#ifndef _FLOC_INTERNAL_CONFIG_H_\r
-#define _FLOC_INTERNAL_CONFIG_H_\r
-\r
-namespace Tizen { namespace Locations\r
-{\r
-\r
-const int MAX_WAIT_TIME_FOR_SYNC_LOC = 5;\r
-\r
-}} // Tizen::Locations\r
-#endif //_FLOC_INTERNAL_CONFIG_H_
\ No newline at end of file
+ */
+
+#ifndef _FLOC_INTERNAL_CONFIG_H_
+#define _FLOC_INTERNAL_CONFIG_H_
+
+namespace Tizen { namespace Locations
+{
+
+const int MAX_WAIT_TIME_FOR_SYNC_LOC = 5;
+const int MIN_LOCATION_UPDATE_INTERVAL = 1;
+const int DEFAULT_WAITING_TIME_FOR_FIXING_LOCATION = 40;
+const int DEFAULT_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;
+
+}} // Tizen::Locations
+#endif //_FLOC_INTERNAL_CONFIG_H_
index b072933..56791ed 100644 (file)
@@ -41,8 +41,6 @@ _LocationImpl::_LocationImpl(void)
        , __horizontalAccuracy(Tizen::Locations::NaN)
        , __verticalAccuracy(Tizen::Locations::NaN)
        , __timestamp(0)
-       , __locationMethod("")
-       , __satelliteInformation("")
        , __isLocationValid(false)
        , __isDenied(false)
 {
index 6c1002d..cb7d55e 100644 (file)
@@ -32,6 +32,7 @@
 #include <FBaseRtMutex.h>
 #include <FBaseRtTimer.h>
 #include <FBaseRtMonitor.h>
+#include <FBaseRtWaitingLoop.h>
 #include <FBaseSysLog.h>
 #include <FLocCoordinates.h>
 #include <FSysSystemTime.h>
@@ -60,15 +61,8 @@ _LocationManager::_LocationManager(void)
        , __locMethodRequested(LOC_METHOD_REQUESTED_NONE)
        , __locationMgrState(LOC_MGR_STATE_IDLE)
        , __minRequestedAccuracy(LOC_ACCURACY_INVALID)
-       , __nativeGPSServiceState(LOCATIONS_SERVICE_DISABLED)
-       , __nativeWPSServiceState(LOCATIONS_SERVICE_DISABLED)
-       , __nativeCPSServiceState(LOCATIONS_SERVICE_DISABLED)
        , __timerInterval(0)
        , __timerTicks(0)
-       , __gpsHandler(null)
-       , __wpsHandler(null)
-       , __cpsHandler(null)
-       , __pCurrentLocation(null)
        , __pLocRequestInfoList(null)
        , __pSyncLocRequestInfoList(null)
        , __pLocUpdateTimer(null)
@@ -145,6 +139,44 @@ _LocationManager::StopLocationUpdates(RequestId reqId)
 }
 
 result
+_LocationManager::ChangeUpdateInterval(RequestId reqId, int interval)
+{
+       SysLog(NID_LOC, "Interval update requested for request ID (%d).", reqId);
+
+       result r = E_SUCCESS;
+       const int ARRAY_LIST_CAPACITY = 2;
+
+       std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::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));
+
+       r = pArgList->Construct(ARRAY_LIST_CAPACITY);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Array Construct failed. Propogating.", GetErrorMessage(r));
+
+       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));
+
+       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));
+       SysTryReturn(NID_LOC, pInterval, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       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;
+}
+
+result
 _LocationManager::RegisterLocationMonitor(_LocationMonitor* pLocationMonitor)
 {
        RequestId reqId;
@@ -194,18 +226,18 @@ _LocationManager::GetLastKnownLocation(void)
        SysTryReturn(NID_LOC, r == E_SUCCESS, location, r, "[%s] Propogating.", GetErrorMessage(r));
 
        r = pArgList->Add(location);
-       SysTryReturn(NID_LOC, r == E_SUCCESS, location, r, "[%s] Propogating.", GetErrorMessage(r));
+       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Propogating", GetErrorMessage(r));
        r = pArgList->Add(synchronizer);
-       SysTryCatch(NID_LOC, r == E_SUCCESS, pArgList->RemoveAll(false), r, "[%s] Propogating", GetErrorMessage(r));
+       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Propogating", GetErrorMessage(r));
 
        r = synchronizer.Enter();
-       SysTryCatch(NID_LOC, r == E_SUCCESS, pArgList->RemoveAll(false), r, "[%s] Propogating", GetErrorMessage(r));
+       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Propogating", GetErrorMessage(r));
 
        r = SendUserEvent(REQ_ID_GET_LAST_LOCATION, pArgList.get());
-       SysTryCatch(NID_LOC, r == E_SUCCESS, pArgList->RemoveAll(false); synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r));
+       SysTryCatch(NID_LOC, r == E_SUCCESS, synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r));
        pArgList.release();
 
-       SysLog(NID_LOC, "Wait the location manager to get the last location.");
+       SysLog(NID_LOC, "Wait till location manager gets the last location.");
        r = synchronizer.Wait();
        SysTryCatch(NID_LOC, r == E_SUCCESS, synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r));
        synchronizer.Exit();
@@ -216,6 +248,7 @@ _LocationManager::GetLastKnownLocation(void)
        return location;
 
 CATCH:
+       pArgList->RemoveAll(false);
        return location;
 }
 
@@ -273,7 +306,7 @@ _LocationManager::IsAppEnabled(void)
        SysTryCatch(NID_LOC, r == E_SUCCESS, synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r));
        pArgList.release();
 
-       SysLog(NID_LOC, "Wait the location manager to check the app is allowed to use location.");
+       SysLog(NID_LOC, "Wait till location manager checks if the app is allowed to use location.");
        r = synchronizer.Wait();
        SysTryCatch(NID_LOC, r == E_SUCCESS, synchronizer.Exit(), r, "[%s] Propogating", GetErrorMessage(r));
        SysLog(NID_LOC, "Application setting state is '%ls'.", enable.ToString().GetPointer());
@@ -347,9 +380,9 @@ _LocationManager::RemoveFromLocRequestInfoList(RequestId reqId)
                _PowerManagerImpl::PowerControl(1, 0);
 
                __pLocUpdateTimer->Cancel();
-               location_manager_stop(__gpsHandler);
-               location_manager_stop(__wpsHandler);
-               location_manager_stop(__cpsHandler);
+               location_manager_stop(__gpsHandler.handle);
+               location_manager_stop(__wpsHandler.handle);
+               location_manager_stop(__cpsHandler.handle);
 
                Reset();
        }
@@ -364,13 +397,38 @@ void
 _LocationManager::AddToSyncLocationRequestInfoList(_SyncLocationRequestInfo& syncLocRequestInfo)
 {
        result r = E_SUCCESS;
-
-       r = syncLocRequestInfo.StartTimer(*this);
-       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the sync timer.", GetErrorMessage(r));
+       static bool hasRetrievalStarted = false;
 
        r = __pSyncLocRequestInfoList->Add(syncLocRequestInfo);
        SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to add the sync request into the list.", GetErrorMessage(r));
 
+       if (hasRetrievalStarted == true)
+       {
+               SysLog(NID_LOC, "The retrieval under process.");
+               return;
+       }
+
+       while (__pSyncLocRequestInfoList->GetCount() != 0)
+       {
+               hasRetrievalStarted = true;
+               const int WAIT_TIME = 1000;
+               WaitingLoop::GetInstance()->Wait(WAIT_TIME);
+
+               int count = __pSyncLocRequestInfoList->GetCount();
+               for (int i = 0; i < count; i++)
+               {
+                       _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i));
+                       if (pSyncLocRequestInfo != null)
+                       {
+                               SysLog(NID_LOC, "Handle the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId());
+
+                               HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo);
+                       }
+               }
+       }
+
+       hasRetrievalStarted = false;
+
        return;
 
 CATCH:
@@ -410,25 +468,65 @@ _LocationManager::RestartLocationUpdates(void)
 
        SysLog(NID_LOC, "Location updates are restarted and new minimum requested Accuracy is (%d).", __minRequestedAccuracy);
 
-       __pLocUpdateTimer->Cancel();
+       switch (__locMethodRequested)
+       {
+       case LOC_METHOD_REQUESTED_NONE:
+       {
+               SysLog(NID_LOC, "None of the methods running. Start all");
+
+               result = location_manager_start(__gpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS.");
+
+               result = location_manager_start(__wpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS.");
+
+               result = location_manager_start(__cpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for CPS.");
+       }
+       break;
+
+       case LOC_METHOD_REQUESTED_GPS:
+       {
+               SysLog(NID_LOC, "GPS Running. Start other two.");
 
-       location_manager_stop(__gpsHandler);
-       location_manager_stop(__wpsHandler);
-       location_manager_stop(__cpsHandler);
+               result = location_manager_start(__wpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS.");
 
-       __nativeGPSServiceState = LOCATIONS_SERVICE_DISABLED;
-       __nativeWPSServiceState = LOCATIONS_SERVICE_DISABLED;
-       __nativeCPSServiceState = LOCATIONS_SERVICE_DISABLED;
+               result = location_manager_start(__cpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for CPS.");
+       }
+       break;
+
+       case LOC_METHOD_REQUESTED_WPS:
+       {
+               SysLog(NID_LOC, "WPS Running. Start other two.");
+
+               result = location_manager_start(__gpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS.");
+
+               result = location_manager_start(__cpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for CPS.");
+       }
+       break;
 
+       case LOC_METHOD_REQUESTED_CPS:
+       {
+               SysLog(NID_LOC, "CPS Running. Start other two.");
 
-       result = location_manager_start(__gpsHandler);
-       SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS.");
+               result = location_manager_start(__gpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for GPS.");
 
-       result = location_manager_start(__wpsHandler);
-       SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS.");
+               result = location_manager_start(__wpsHandler.handle);
+               SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for WPS.");
+       }
+       break;
 
-       result = location_manager_start(__cpsHandler);
-       SysTryLog(NID_LOC, result == 0, "Failed to start the location updates for CPS.");
+       case LOC_METHOD_REQUESTED_ALL:
+       {
+               SysLog(NID_LOC, "All the providers are already started.");
+       }
+       break;
+       }
 
        __locationMgrState = LOC_MGR_STATE_FAST_SENSING;
        __locMethodRequested = LOC_METHOD_REQUESTED_ALL;
@@ -442,6 +540,8 @@ _LocationManager::RestartUpdateTimer(void)
        int count = __pLocRequestInfoList->GetCount();
        result r = E_SUCCESS;
 
+       __pLocUpdateTimer->Cancel();
+
        if (count > 0)
        {
                const _LocationRequestInfo* pLocRequestInfo = static_cast< _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(0));
@@ -523,7 +623,7 @@ _LocationManager::HandleSyncRetrievalTimerExpiry(_SyncLocationRequestInfo& syncL
        }
 
        SysLog(NID_LOC, "Wait for next location(Tick: %d).", syncLocRequestInfo.GetTickCount());
-       syncLocRequestInfo.StartTimer(*this);
+       syncLocRequestInfo.IncrementTickCount();
        return;
 
 NOTIFY:
@@ -532,7 +632,7 @@ NOTIFY:
 }
 
 result
-_LocationManager::SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod)
+_LocationManager::SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod, Location* pLocation)
 {
        SysLog(NID_LOC, "Location Information is: Latitude (%lf), Longitude (%lf), Altitude (%lf), TimeStamp (%ld), Location method (%d)", latitude, longitude, altitude, timestamp, locMethod);
 
@@ -560,11 +660,11 @@ _LocationManager::SetLocationInformation(double latitude, double longitude, doub
        {
        case LOCATIONS_METHOD_GPS:
        {
-               res = location_manager_get_accuracy(__gpsHandler, &accLevel, &horAcc, &verAcc);
+               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, &climb, &direction, &speed, &time_stamp);
+               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.");
 
@@ -575,11 +675,11 @@ _LocationManager::SetLocationInformation(double latitude, double longitude, doub
 
        case LOCATIONS_METHOD_WPS:
        {
-               res = location_manager_get_accuracy(__wpsHandler, &accLevel, &horAcc, &verAcc);
+               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, &climb, &direction, &speed, &time_stamp);
+               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");
@@ -589,7 +689,7 @@ _LocationManager::SetLocationInformation(double latitude, double longitude, doub
 
        case LOCATIONS_METHOD_CPS:
        {
-               res = location_manager_get_accuracy(__cpsHandler, &accLevel, &horAcc, &verAcc);
+               res = location_manager_get_accuracy(__cpsHandler.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.");
 
@@ -612,7 +712,7 @@ _LocationManager::SetLocationInformation(double latitude, double longitude, doub
        pLocDataImpl->SetCourse(direction);
        pLocDataImpl->SetSpeed(speed);
        pLocDataImpl->SetValidity(true);
-       *__pCurrentLocation = locationData;
+       *pLocation = locationData;
 
        requiredAcc = __minRequestedAccuracy;
        switch (requiredAcc)
@@ -662,9 +762,10 @@ void
 _LocationManager::SendLocationCallbacks(void)
 {
        bool isAllowed = GetAppAccessibility();
-       SysLog(NID_LOC, "Send location(validity: %x) and accessibility(%x) through the callback.", __pCurrentLocation->IsValid(), isAllowed);
+       const Location* pBestLocation = FindBestLocation();
 
-       unique_ptr< Location > pLocation(new (std::nothrow) Location(*__pCurrentLocation));
+       SysLog(NID_LOC, "Send location(validity: %x) and accessibility(%x) through the callback.", pBestLocation->IsValid(), isAllowed);
+       unique_ptr< Location > pLocation(new (std::nothrow) Location(*pBestLocation));
        SysTryReturnVoidResult(NID_LOC, pLocation != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
        int interval = __timerTicks * __timerInterval;
@@ -690,9 +791,6 @@ _LocationManager::Reset(void)
        __minRequestedAccuracy = LOC_ACCURACY_INVALID;
        __timerInterval = 0;
        __timerTicks = 0;
-       __nativeGPSServiceState = LOCATIONS_SERVICE_DISABLED;
-       __nativeWPSServiceState = LOCATIONS_SERVICE_DISABLED;
-       __nativeCPSServiceState = LOCATIONS_SERVICE_DISABLED;
 }
 
 result
@@ -701,131 +799,474 @@ _LocationManager::Construct()
        return EventDrivenThread::Construct();
 }
 
-bool
-_LocationManager::OnStart(void)
+Location
+_LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
 {
-       int res = -1;
-       result r = E_SUCCESS;
-
-       unique_ptr< Mutex > pMutex(new (std::nothrow) Mutex());
-       SysTryReturn(NID_LOC, pMutex != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
-
-       r = pMutex->Create();
-       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the mutex.");
-
-       std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pLocInfoRequestList(new (std::nothrow) ArrayList());
-       SysTryReturn(NID_LOC, pLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
-
-       r = pLocInfoRequestList->Construct();
-       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Location Request list.");
+       String locationMethod;
+       location_manager_h nativeHandle = null;
+       switch (nativeLocMethod)
+       {
+       case LOCATIONS_METHOD_GPS:
+               nativeHandle = __gpsHandler.handle;
+               locationMethod = L"gps";
+               break;
+       case LOCATIONS_METHOD_WPS:
+               nativeHandle = __wpsHandler.handle;
+               locationMethod = L"network";
+               break;
+       case LOCATIONS_METHOD_CPS:
+               nativeHandle = __cpsHandler.handle;
+               locationMethod = L"network";
+               break;
+       default:
+               break;
+       }
+       SysLog(NID_LOC, "Last location requested(method: %x, handle: %x).", nativeLocMethod, nativeHandle);
 
-       std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pSyncLocInfoRequestList(new (std::nothrow) ArrayList());
-       SysTryReturn(NID_LOC, pSyncLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+       Location location = _LocationImpl::GetLocationInstance();
+       if (nativeHandle != null)
+       {
+               _LocationImpl* pLocationImpl = _LocationImpl::GetInstance(location);
 
-       r = pSyncLocInfoRequestList->Construct();
-       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Sync Location Request list.");
+               double altitude = Tizen::Locations::NaN;
+               double latitude = Tizen::Locations::NaN;
+               double longitude = Tizen::Locations::NaN;
+               time_t timestampPosition = 0;
 
-       unique_ptr< Tizen::Locations::Location > pLocation(_LocationImpl::GetLocationInstanceN());
-       SysTryReturn(NID_LOC, pLocation != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+               int res = location_manager_get_last_position(nativeHandle, &altitude, &latitude, &longitude, &timestampPosition);
+               SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to fetch last position from nativeHandle(%x).", nativeHandle);
+               SysLog(NID_LOC, "Last position(latitude: %lf, longitude: %lf, altitude: %lf, timestamp: %ld",
+                       latitude, longitude, altitude, timestampPosition);
 
-       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.");
+               Coordinates coord;
+               coord.Set(latitude, longitude, altitude);
+               pLocationImpl->SetCoordinates(coord);
 
-       res = location_manager_create(LOCATIONS_METHOD_GPS, &__gpsHandler);
-       SysTryReturn(NID_LOC, res == 0, false, E_SYSTEM, "[E_SYSTEM] Failed to create Native GPS Location provider.");
+               double horAcc = Tizen::Locations::NaN;
+               double verAcc = Tizen::Locations::NaN;
+               location_accuracy_level_e level;
+               res = location_manager_get_last_accuracy(nativeHandle, &level, &horAcc, &verAcc);
+               if (res == 0)
+               {
+                       SysLog(NID_LOC, "Last accuracy(horAcc: %lf, vAcc: %lf, level: %x)", horAcc, verAcc, level);
+                       pLocationImpl->SetHorizontalAccuracy(horAcc);
+                       pLocationImpl->SetVerticalAccuracy(verAcc);
+               }
 
-       res = location_manager_set_service_state_changed_cb(__gpsHandler, GpsServiceUpdateCallback, this);
-       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native GPS Location provider.");
+               double climb = Tizen::Locations::NaN;
+               double direction = Tizen::Locations::NaN;
+               double speed = Tizen::Locations::NaN;
+               time_t timestampVelocity = 0;
+               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);
+                       pLocationImpl->SetCourse(direction);
+                       pLocationImpl->SetSpeed(speed);
+               }
 
-       res = location_manager_create(LOCATIONS_METHOD_WPS, &__wpsHandler);
-       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native WPS Location provider.");
+               if (nativeLocMethod == LOCATIONS_METHOD_GPS)
+               {
+                       int satUsedCount = 0;
+                       int satViewCount = 0;
+                       time_t timestampSatellite = 0;
+                       String satInfo = L"";
+                       res = gps_status_get_last_satellite(nativeHandle, &satUsedCount, &satViewCount, &timestampSatellite);
+                       if (res == 0)
+                       {
+                               long timeDiff = 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);
 
-       res = location_manager_set_service_state_changed_cb(__wpsHandler, WpsServiceUpdateCallback, this);
-       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native WPS Location provider.");
+                               satInfo.Trim();
+                               SysLog(NID_LOC, "Last satellite(info: %ls)", satInfo.GetPointer());
+                               pLocationImpl->SetExtraInfo(L"satellite", satInfo);
+                       }
+               }
 
-       res = location_manager_create(LOCATIONS_METHOD_CPS, &__cpsHandler);
-       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native CPS Location provider.");
+               pLocationImpl->SetTimestamp(((long long)timestampPosition) * 1000); // in milliseconds
+               pLocationImpl->SetValidity(true);
+               pLocationImpl->SetExtraInfo(L"location_method", locationMethod);
+       }
 
-       res = location_manager_set_service_state_changed_cb(__cpsHandler, CpsServiceUpdateCallback, this);
-       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native CPS Location provider.");
+       ClearLastResult();
+       return location;
 
-       __pLocRequestInfoList = std::move(pLocInfoRequestList);
-       __pSyncLocRequestInfoList = std::move(pSyncLocInfoRequestList);
-       __pLocUpdateTimer = std::move(pLocUpdateTimer);
-       __pCurrentLocation = std::move(pLocation);
+CATCH:
+       return location;
+}
 
-       return true;
+Location
+_LocationManager::GetRecentLocationAvailable(void)
+{
+       long long gpsTimestamp = 0;
+       long long wpsTimestamp = 0;
+       long long cpsTimestamp = 0;
 
-CATCH:
-       if (__gpsHandler)
+       Location lastGpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_GPS);
+       if (lastGpsLocation.IsValid())
        {
-               location_manager_destroy(__gpsHandler);
+               gpsTimestamp = _LocationImpl::GetInstance(lastGpsLocation)->GetTimestampInMs();
        }
 
-       if (__wpsHandler)
+       Location lastWpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_WPS);
+       if (lastWpsLocation.IsValid())
        {
-               location_manager_destroy(__wpsHandler);
+               wpsTimestamp = _LocationImpl::GetInstance(lastWpsLocation)->GetTimestampInMs();
        }
 
-       if (__cpsHandler)
+       Location lastCpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_CPS);
+       if (lastCpsLocation.IsValid())
        {
-               location_manager_destroy(__cpsHandler);
+               cpsTimestamp = _LocationImpl::GetInstance(lastCpsLocation)->GetTimestampInMs();
        }
-       return false;
-}
 
-void
-_LocationManager::OnStop(void)
-{
-       if (__gpsHandler)
+       SysLog(NID_LOC, "Compare timestamp(gps: %lld, wps: %lld, cps: %lld) for recent location.", 
+               gpsTimestamp, wpsTimestamp, cpsTimestamp);
+
+       if (gpsTimestamp >= wpsTimestamp && gpsTimestamp >= cpsTimestamp)
        {
-               location_manager_destroy(__gpsHandler);
+               return lastGpsLocation;
        }
-
-       if (__wpsHandler)
+       else if (wpsTimestamp > gpsTimestamp && wpsTimestamp > cpsTimestamp)
        {
-               location_manager_destroy(__wpsHandler);
+               return lastWpsLocation;
        }
-
-       if (__cpsHandler)
+       else
        {
-               location_manager_destroy(__cpsHandler);
+               return lastCpsLocation;
        }
 }
 
-void
-_LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
+void 
+_LocationManager::UpdateLocRequestInfoList(RequestId reqId, int interval)
 {
-       const int ARRAY_LIST_CAPACITY = 1;
+       int count = __pLocRequestInfoList->GetCount();
 
-       switch (requestId)
-       {
-       case REQ_ID_START_LOC_UPDATES:
+       for (int i = 0; i < count; i++)
        {
-               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);
+               _LocationRequestInfo* pLocRequestInfo = static_cast< _LocationRequestInfo* >(__pLocRequestInfoList->GetAt(i));
+               if (reqId == pLocRequestInfo->GetRequestId())
+               {
+                       pLocRequestInfo->SetInterval(interval);
+                       RestartUpdateTimer();
+                       break;
+               }
        }
-       break;
+}
 
-       case REQ_ID_STOP_LOC_UPDATES:
+const Location*
+_LocationManager::FindBestLocation(void)
+{
+       switch (__locMethodRequested)
        {
-               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.");
+       case LOC_METHOD_REQUESTED_GPS:
+               SysLog(NID_LOC, "GPS location provider running.");
+               return __gpsHandler.pLocation.get();
+               break;
 
-               RemoveFromLocRequestInfoList(static_cast< long >(pReqId->ToInt()));
-       }
-       break;
+       case LOC_METHOD_REQUESTED_WPS:
+               SysLog(NID_LOC, "WPS location provider running.");
+               return __wpsHandler.pLocation.get();
+               break;
+
+       case LOC_METHOD_REQUESTED_CPS:
+               SysLog(NID_LOC, "CPS location provider running.");
+               return __cpsHandler.pLocation.get();
+               break;
+
+       case LOC_METHOD_REQUESTED_ALL:
+       {
+               SysLog(NID_LOC, "All the methods are running. Get the best location among all the providers.");
+
+               long long gpsTimestamp = 0;
+               long long wpsTimestamp = 0;
+               long long cpsTimestamp = 0;
+
+               if (__gpsHandler.pLocation->IsValid() && !_LocationImpl::GetInstance(*__gpsHandler.pLocation)->IsDenied())
+               {
+                       gpsTimestamp = _LocationImpl::GetInstance(*__gpsHandler.pLocation)->GetTimestampInMs();
+               }
+               if (__wpsHandler.pLocation->IsValid() && !_LocationImpl::GetInstance(*__wpsHandler.pLocation)->IsDenied())
+               {
+                       wpsTimestamp = _LocationImpl::GetInstance(*__wpsHandler.pLocation)->GetTimestampInMs();
+               }
+               if (__cpsHandler.pLocation->IsValid() && !_LocationImpl::GetInstance(*__cpsHandler.pLocation)->IsDenied())
+               {
+                       cpsTimestamp = _LocationImpl::GetInstance(*__cpsHandler.pLocation)->GetTimestampInMs();
+               }
+
+               SysLog(NID_LOC, "Compare timestamp(gps: %lld, wps: %lld, cps: %lld) of different locations.", gpsTimestamp, wpsTimestamp, cpsTimestamp);
+
+               if (gpsTimestamp > wpsTimestamp && gpsTimestamp > cpsTimestamp)
+               {
+                       SysLog(NID_LOC, "GPS time stamp is greater than WPS and CPS.");
+                       return __gpsHandler.pLocation.get();
+               }
+               else if (wpsTimestamp > gpsTimestamp && wpsTimestamp > cpsTimestamp)
+               {
+                       SysLog(NID_LOC, "WPS time stamp is greater than GPS and CPS.");
+                       return __wpsHandler.pLocation.get();
+               }
+               else if (cpsTimestamp > gpsTimestamp && cpsTimestamp > wpsTimestamp)
+               {
+                       SysLog(NID_LOC, "CPS time stamp is greater than GPS and WPS.");
+                       return __cpsHandler.pLocation.get();
+               }
+               else if (gpsTimestamp == wpsTimestamp)
+               {
+                       if (__gpsHandler.pLocation->GetHorizontalAccuracy() <= __wpsHandler.pLocation->GetHorizontalAccuracy())
+                       {
+                               SysLog(NID_LOC, "GPS time stamp is equal to WPS and GPS accuracy is better than WPS.");
+                               return __gpsHandler.pLocation.get();
+                       }
+                       else
+                       {
+                               SysLog(NID_LOC, "GPS time stamp is equal to WPS but GPS accuracy is worse than WPS.");
+                               return __wpsHandler.pLocation.get();
+                       }
+               }
+               else if (gpsTimestamp == cpsTimestamp)
+               {
+                       if (__gpsHandler.pLocation->GetHorizontalAccuracy() <= __cpsHandler.pLocation->GetHorizontalAccuracy())
+                       {
+                               SysLog(NID_LOC, "GPS time stamp is equal to CPS and GPS accuracy is better than CPS.");
+                               return __gpsHandler.pLocation.get();
+                       }
+                       else
+                       {
+                               SysLog(NID_LOC, "GPS time stamp is equal to CPS but GPS accuracy is worse than CPS.");
+                               return __cpsHandler.pLocation.get();
+                       }
+               }
+               else if (wpsTimestamp == cpsTimestamp)
+               {
+                       if (__wpsHandler.pLocation->GetHorizontalAccuracy() <= __cpsHandler.pLocation->GetHorizontalAccuracy())
+                       {
+                               SysLog(NID_LOC, "WPS time stamp is equal to CPS and WPS accuracy is better than CPS.");
+                               return __wpsHandler.pLocation.get();
+                       }
+                       else
+                       {
+                               SysLog(NID_LOC, "WPS time stamp is equal to CPS but WPS accuracy is worse than CPS.");
+                               return __cpsHandler.pLocation.get();
+                       }
+               }
+       }
+               break;
+
+       case LOC_METHOD_REQUESTED_NONE:
+       // follow through
+       default:
+               SysLog(NID_LOC, "Location updates not running.");
+               return null;
+       }
+
+       SysLog(NID_LOC, "Returning null as none of the conditions are satsfied.");
+       return null;
+}
+
+result
+_LocationManager::GetLocation(location_method_e nativeLocMethod)
+{
+       const int MAX_VALID_TIME_DIFFERENCE = 2000;
+       result r = E_SUCCESS;
+       double altitude = 0.0;
+       double latitude = 0.0;
+       double longitude = 0.0;
+       time_t timestamp;
+       int res = -1;
+       int satellitesInViewCount = 0;
+       int satellitesInUseCount = 0;
+       time_t timestampSatellite = 0;
+       String satInfo = L"";
+       long long timeDiff = 0;
+       location_manager_h nativeHandle = null;
+       Location* pLocation = null;
+
+       switch (nativeLocMethod)
+       {
+       case LOCATIONS_METHOD_GPS:
+               nativeHandle = __gpsHandler.handle;
+               pLocation = __gpsHandler.pLocation.get();
+               break;
+       case LOCATIONS_METHOD_WPS:
+               nativeHandle = __wpsHandler.handle;
+               pLocation = __wpsHandler.pLocation.get();
+               break;
+       case LOCATIONS_METHOD_CPS:
+               nativeHandle = __cpsHandler.handle;
+               pLocation = __cpsHandler.pLocation.get();
+               break;
+       default:
+               break;
+       }
+
+       res = location_manager_get_position(nativeHandle, &altitude, &latitude, &longitude, &timestamp);
+       SysTryReturnResult(NID_LOC, res == 0, E_SYSTEM,  "[E_SYSTEM] Failed to obtain the natvie location information for the method (%x)", nativeLocMethod);
+
+       if (res == 0)
+       {
+               r = SetLocationInformation(latitude, longitude, altitude, timestamp, nativeLocMethod, pLocation);
+               if (r != E_SUCCESS)
+               {
+                       SysLog(NID_LOC, "Failed to set the location information");
+               }
+
+               if (nativeLocMethod == LOCATIONS_METHOD_GPS)
+               {
+                       res = gps_status_get_satellite(__gpsHandler.handle, &satellitesInUseCount, &satellitesInViewCount, &timestampSatellite);
+
+                       timeDiff = 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);
+                       }
+
+                       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);
+               }
+       }
+
+       return E_SUCCESS;
+}
+
+bool
+_LocationManager::OnStart(void)
+{
+       int res = -1;
+       result r = E_SUCCESS;
+
+       std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pLocInfoRequestList(new (std::nothrow) ArrayList());
+       SysTryReturn(NID_LOC, pLocInfoRequestList != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       r = pLocInfoRequestList->Construct();
+       SysTryReturn(NID_LOC, r == E_SUCCESS, false, E_SYSTEM, "[E_SYSTEM] Failed to construct the Location Request list.");
+
+       std::unique_ptr< Tizen::Base::Collection::ArrayList, AllElementsDeleter > pSyncLocInfoRequestList(new (std::nothrow) ArrayList());
+       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.");
+
+       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));
+
+       unique_ptr< Tizen::Locations::Location > pCpsLocation(_LocationImpl::GetLocationInstanceN());
+       SysTryReturn(NID_LOC, pCpsLocation != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));        
+
+       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.");
+
+       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.");
+
+       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.");
+
+       res = location_manager_create(LOCATIONS_METHOD_CPS, &__cpsHandler.handle);
+       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to create Native CPS Location provider.");
+
+       res = location_manager_set_service_state_changed_cb(__cpsHandler.handle, CpsServiceUpdateCallback, this);
+       SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to register service callback for Native CPS Location provider.");
+
+       __pLocRequestInfoList = std::move(pLocInfoRequestList);
+       __pSyncLocRequestInfoList = std::move(pSyncLocInfoRequestList);
+       __pLocUpdateTimer = std::move(pLocUpdateTimer);
+       __gpsHandler.pLocation= std::move(pGpsLocation);
+       __wpsHandler.pLocation= std::move(pWpsLocation);
+       __cpsHandler.pLocation= std::move(pCpsLocation);
+
+       SysLog(NID_LOC, "All the resources for location manager successfully created.");
+
+       return true;
+
+CATCH:
+       if (__gpsHandler.handle)
+       {
+               location_manager_destroy(__gpsHandler.handle);
+       }
+
+       if (__wpsHandler.handle)
+       {
+               location_manager_destroy(__wpsHandler.handle);
+       }
+
+       if (__cpsHandler.handle)
+       {
+               location_manager_destroy(__cpsHandler.handle);
+       }
+       return false;
+}
+
+void
+_LocationManager::OnStop(void)
+{
+       if (__gpsHandler.handle)
+       {
+               location_manager_destroy(__gpsHandler.handle);
+       }
+
+       if (__wpsHandler.handle)
+       {
+               location_manager_destroy(__wpsHandler.handle);
+       }
+
+       if (__cpsHandler.handle)
+       {
+               location_manager_destroy(__cpsHandler.handle);
+       }
+}
+
+void
+_LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
+{
+       const int ARRAY_LIST_CAPACITY = 1;
+
+       switch (requestId)
+       {
+       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_STOP_LOC_UPDATES:
+       {
+               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;
 
        case REQ_ID_RESTART_LOC_UPDATES:
        {
@@ -837,8 +1278,8 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
        case REQ_ID_SUSTAIN_GPS:
        {
                SysLog(NID_LOC, "REQ_ID_SUSTAIN_GPS.");
-               location_manager_stop(__wpsHandler);
-               location_manager_stop(__cpsHandler);
+               location_manager_stop(__wpsHandler.handle);
+               location_manager_stop(__cpsHandler.handle);
                __locMethodRequested = LOC_METHOD_REQUESTED_GPS;
        }
        break;
@@ -846,8 +1287,8 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
        case REQ_ID_SUSTAIN_WPS:
        {
                SysLog(NID_LOC, "REQ_ID_SUSTAIN_WPS.");
-               location_manager_stop(__gpsHandler);
-               location_manager_stop(__cpsHandler);
+               location_manager_stop(__gpsHandler.handle);
+               location_manager_stop(__cpsHandler.handle);
                __locMethodRequested = LOC_METHOD_REQUESTED_WPS;
        }
        break;
@@ -855,8 +1296,8 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
        case REQ_ID_SUSTAIN_CPS:
        {
                SysLog(NID_LOC, "REQ_ID_SUSTAIN_CPS.");
-               location_manager_stop(__gpsHandler);
-               location_manager_stop(__wpsHandler);
+               location_manager_stop(__gpsHandler.handle);
+               location_manager_stop(__wpsHandler.handle);
                __locMethodRequested = LOC_METHOD_REQUESTED_CPS;
        }
        break;
@@ -921,6 +1362,27 @@ _LocationManager::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
                pArgs->RemoveAt(0);
        }
        break;
+
+       case REQ_ID_UPDATE_INTERVAL:
+       {
+               const int ARRAY_LIST_LENGTH = 2;
+
+               SysLog(NID_LOC, "REQ_ID_UPDATE_INTERVAL");
+               SysTryReturnVoidResult(NID_LOC, pArgs, E_INVALID_ARG, "[E_INVALID_ARG] Null argument encountered. Ignored.");
+               SysTryCatch(NID_LOC, pArgs->GetCount() == ARRAY_LIST_LENGTH, pArgs->RemoveAll(true), E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored.");
+
+               Integer* pReqId = null;
+               pReqId = static_cast< Integer* >(pArgs->GetAt(0));
+               SysTryCatch(NID_LOC, pReqId, , E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument encountered. Ignored.");
+
+               Integer* pInterval = null;
+               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());
+       }
+       break;
+
        }
 
        if (pArgs)
@@ -939,159 +1401,69 @@ CATCH:
 void
 _LocationManager::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
 {
-       const int MAX_VALID_TIME_DIFFERENCE = 2000;
-
        if (__pLocUpdateTimer->Equals(timer))
        {
                __timerTicks++;
                SysLog(NID_LOC, "LocationManager update timer expired. Timer Tick value is (%d).", __timerTicks);
                result r = E_SUCCESS;
-               double altitude = 0.0;
-               double latitude = 0.0;
-               double longitude = 0.0;
-               time_t timestamp;
-
-               int res = -1;
-               int satellitesInViewCount = 0;
-               int satellitesInUseCount = 0;
-               time_t timestampSatellite = 0;
-               String satInfo = L"";
-               long long timeDiff = 0;
 
                switch (__locMethodRequested)
                {
                case LOC_METHOD_REQUESTED_GPS:
-                       res = location_manager_get_position(__gpsHandler, &altitude, &latitude, &longitude, &timestamp);
-                       SysTryLog(NID_LOC, res == 0, "[E_SYSTEM] Failed to obtain the GPS location information");
+                       r = GetLocation(LOCATIONS_METHOD_GPS);
+                       SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information");
 
-                       if (res == 0)
-                       {
-                               r = SetLocationInformation(latitude, longitude, altitude, timestamp, LOCATIONS_METHOD_GPS);
-                               if (r != E_SUCCESS)
-                               {
-                                       SysLog(NID_LOC, "Failed to set the location information");
-                               }
-
-                               res = gps_status_get_satellite(__gpsHandler, &satellitesInUseCount, &satellitesInViewCount, &timestampSatellite);
-
-                               timeDiff = 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, SatelliteInfoUpdated, &satInfo);
-                               }
-                               SysLog(NID_LOC, "Result of get satellite is (%d) and satelliteInfo string representation is (%ls)", res, satInfo.GetPointer());
-
-                               _LocationImpl::GetInstance(*__pCurrentLocation.get())->SetExtraInfo(L"satellite", satInfo);
-                       }
-                       else
+                       if (IsFailed(r))
                        {
                                SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null);
-                               return;
                        }
                        break;
 
                case LOC_METHOD_REQUESTED_WPS:
-                       res = location_manager_get_position(__wpsHandler, &altitude, &latitude, &longitude, &timestamp);
-                       SysTryLog(NID_LOC, res == 0, "[E_SYSTEM] Failed to obtain the WPS location information");
-                       if (res == 0)
-                       {
-                               r = SetLocationInformation(latitude, longitude, altitude, timestamp, LOCATIONS_METHOD_WPS);
-                               if (r != E_SUCCESS)
-                               {
-                                       SysLog(NID_LOC, "Failed to set the location information");
-                               }
-                       }
-                       else
+                       r = GetLocation(LOCATIONS_METHOD_WPS);
+                       SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the WPS location information");
+
+                       if (IsFailed(r))
                        {
                                SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null);
-                               return;
                        }
                        break;
 
                case LOC_METHOD_REQUESTED_CPS:
-                       res = location_manager_get_position(__cpsHandler, &altitude, &latitude, &longitude, &timestamp);
-                       SysTryLog(NID_LOC, res == 0, "[E_SYSTEM] Failed to obtain the CPS location information");
-                       if (res == 0)
-                       {
-                               r = SetLocationInformation(latitude, longitude, altitude, timestamp, LOCATIONS_METHOD_CPS);
-                               if (r != E_SUCCESS)
-                               {
-                                       SysLog(NID_LOC, "Failed to set the location information");
-                               }
-                       }
-                       else
+                       r = GetLocation(LOCATIONS_METHOD_CPS);
+                       SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the CPS location information");
+
+                       if (IsFailed(r))
                        {
                                SendUserEvent(REQ_ID_RESTART_LOC_UPDATES, null);
-                               return;
                        }
                        break;
 
                case LOC_METHOD_REQUESTED_ALL:
-                       if (__nativeCPSServiceState == LOCATIONS_SERVICE_ENABLED)
+                       if (__cpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
                        {
-                               res = location_manager_get_position(__cpsHandler, &altitude, &latitude, &longitude, &timestamp);
-                               SysTryLog(NID_LOC, res == 0, "[E_SYSTEM] Failed to obtain the CPS location information");
-                               if (res == 0)
-                               {
-                                       r = SetLocationInformation(latitude, longitude, altitude, timestamp, LOCATIONS_METHOD_CPS);
-                                       if (r != E_SUCCESS)
-                                       {
-                                               SysLog(NID_LOC, "Failed to set the location information");
-                                       }
-                               }
+                               r = GetLocation(LOCATIONS_METHOD_CPS);
+                               SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the CPS location information");
                        }
                        else
                        {
                                SysLog(NID_LOC, "CPS Location not available at the Native side.");
                        }
 
-                       if (__nativeWPSServiceState == LOCATIONS_SERVICE_ENABLED)
+                       if (__wpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
                        {
-                               res = location_manager_get_position(__wpsHandler, &altitude, &latitude, &longitude, &timestamp);
-                               SysTryLog(NID_LOC, res == 0, "[E_SYSTEM] Failed to obtain the WPS location information");
-                               if (res == 0)
-                               {
-                                       r = SetLocationInformation(latitude, longitude, altitude, timestamp, LOCATIONS_METHOD_WPS);
-                                       if (r != E_SUCCESS)
-                                       {
-                                               SysLog(NID_LOC, "Failed to set the location information");
-                                       }
-                               }
+                               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 Location not available at the Native side.");
                        }
 
-                       if (__nativeGPSServiceState == LOCATIONS_SERVICE_ENABLED)
+                       if (__gpsHandler.serviceState == LOCATIONS_SERVICE_ENABLED)
                        {
-                               res = location_manager_get_position(__gpsHandler, &altitude, &latitude, &longitude, &timestamp);
-                               SysTryLog(NID_LOC, res == 0, "[E_SYSTEM] Failed to obtain the GPS location information");
-                               if (res == 0)
-                               {
-                                       r = SetLocationInformation(latitude, longitude, altitude, timestamp, LOCATIONS_METHOD_GPS);
-                                       if (r != E_SUCCESS)
-                                       {
-                                               SysLog(NID_LOC, "Failed to set the location information");
-                                       }
-
-                                       res = gps_status_get_satellite(__gpsHandler, &satellitesInUseCount, &satellitesInViewCount, &timestampSatellite);
-
-                                       timeDiff = 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, SatelliteInfoUpdated, &satInfo);
-                                       }
-                                       SysLog(NID_LOC, "Result of get satellite is (%d) and satelliteInfo string representation is (%ls)", res, satInfo.GetPointer());
-
-                                       _LocationImpl::GetInstance(*__pCurrentLocation.get())->SetExtraInfo(L"satellite", satInfo);
-                               }
+                               r = GetLocation(LOCATIONS_METHOD_GPS);
+                               SysTryLog(NID_LOC, r == E_SUCCESS, "[E_SYSTEM] Failed to obtain the GPS location information");
                        }
                        else
                        {
@@ -1109,21 +1481,6 @@ _LocationManager::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
                __pLocUpdateTimer->Start(__timerInterval * 1000);
                SendLocationCallbacks();
        }
-       else
-       {
-               int count = __pSyncLocRequestInfoList->GetCount();
-               for (int i = 0; i < count; i++)
-               {
-                       _SyncLocationRequestInfo* pSyncLocRequestInfo = static_cast< _SyncLocationRequestInfo* >(__pSyncLocRequestInfoList->GetAt(i));
-                       if (pSyncLocRequestInfo != null && pSyncLocRequestInfo->Equals(timer))
-                       {
-                               SysLog(NID_LOC, "Timer expired for the sync location request with request ID (%ld)", pSyncLocRequestInfo->GetRequestId());
-
-                               HandleSyncRetrievalTimerExpiry(*pSyncLocRequestInfo);
-                               break;
-                       }
-               }
-       }
 
        return;
 }
@@ -1167,7 +1524,7 @@ _LocationManager::GpsServiceUpdateCallback(location_service_state_e state, void*
        }
 
        _LocationManager* pThis = static_cast< _LocationManager* >(user_data);
-       pThis->__nativeGPSServiceState = state;
+       pThis->__gpsHandler.serviceState = state;
 }
 
 void
@@ -1181,7 +1538,7 @@ _LocationManager::WpsServiceUpdateCallback(location_service_state_e state, void*
        }
 
        _LocationManager* pThis = static_cast< _LocationManager* >(user_data);
-       pThis->__nativeWPSServiceState = state;
+       pThis->__wpsHandler.serviceState = state;
 }
 
 void
@@ -1195,7 +1552,7 @@ _LocationManager::CpsServiceUpdateCallback(location_service_state_e state, void*
        }
 
        _LocationManager* pThis = static_cast< _LocationManager* >(user_data);
-       pThis->__nativeCPSServiceState = state;
+       pThis->__cpsHandler.serviceState = state;
 }
 
 void
@@ -1223,104 +1580,6 @@ _LocationManager::DestroyLocationManager(void)
        delete __pUniqueInstance;
 }
 
-Location
-_LocationManager::GetLastKnownLocation(location_method_e nativeLocMethod)
-{
-       String locationMethod;
-       location_manager_h nativeHandle = null;
-       switch (nativeLocMethod)
-       {
-       case LOCATIONS_METHOD_GPS:
-               nativeHandle = __gpsHandler;
-               locationMethod = L"gps";
-               break;
-       case LOCATIONS_METHOD_WPS:
-               nativeHandle = __wpsHandler;
-               locationMethod = L"network";
-               break;
-       case LOCATIONS_METHOD_CPS:
-               nativeHandle = __cpsHandler;
-               locationMethod = L"network";
-               break;
-       default:
-               break;
-       }
-       SysLog(NID_LOC, "Last location requested(method: %x, handle: %x).", nativeLocMethod, nativeHandle);
-
-       Location location = _LocationImpl::GetLocationInstance();
-       if (nativeHandle != null)
-       {
-               _LocationImpl* pLocationImpl = _LocationImpl::GetInstance(location);
-
-               double altitude = Tizen::Locations::NaN;
-               double latitude = Tizen::Locations::NaN;
-               double longitude = Tizen::Locations::NaN;
-               time_t timestampPosition = 0;
-
-               int res = location_manager_get_last_position(nativeHandle, &altitude, &latitude, &longitude, &timestampPosition);
-               SysTryCatch(NID_LOC, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to fetch last position from nativeHandle(%x).", nativeHandle);
-               SysLog(NID_LOC, "Last position(latitude: %lf, longitude: %lf, altitude: %lf, timestamp: %lld",
-                       latitude, longitude, altitude, timestampPosition);
-               
-               Coordinates coord;
-               coord.Set(latitude, longitude, altitude);
-               pLocationImpl->SetCoordinates(coord);
-
-               double horAcc = Tizen::Locations::NaN;
-               double verAcc = Tizen::Locations::NaN;
-               location_accuracy_level_e level;
-               res = location_manager_get_last_accuracy(nativeHandle, &level, &horAcc, &verAcc);
-               if (res == 0)
-               {
-                       SysLog(NID_LOC, "Last accuracy(horAcc: %lf, vAcc: %lf, level: %x)", horAcc, verAcc, level);
-                       pLocationImpl->SetHorizontalAccuracy(horAcc);
-                       pLocationImpl->SetVerticalAccuracy(verAcc);
-               }
-               
-               double climb = Tizen::Locations::NaN;
-               double direction = Tizen::Locations::NaN;
-               double speed = Tizen::Locations::NaN;
-               time_t timestampVelocity = 0;
-               res = location_manager_get_last_velocity(nativeHandle, &climb, &direction, &speed, &timestampVelocity);
-               if (res == 0)
-               {
-                       SysLog(NID_LOC, "Last velocity(climb: %lf, direction: %lf, speed: %x, timestamp: %lld)",
-                               climb, direction, speed, timestampVelocity);
-                       pLocationImpl->SetCourse(direction);
-                       pLocationImpl->SetSpeed(speed);
-               }
-
-               if (nativeLocMethod == LOCATIONS_METHOD_GPS)
-               {
-                       int satUsedCount = 0;
-                       int satViewCount = 0;
-                       time_t timestampSatellite = 0;
-                       String satInfo = L"";
-                       res = gps_status_get_last_satellite(nativeHandle, &satUsedCount, &satViewCount, &timestampSatellite);
-                       if (res == 0)
-                       {
-                               long timeDiff = 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: %lld, timeDiff: %ld)",
-                                       res, satUsedCount, satViewCount, timestampSatellite, timeDiff);
-                               
-                               SysLog(NID_LOC, "Last satellite(info: %ls)", satInfo.GetPointer());
-                               pLocationImpl->SetExtraInfo(L"satellite", satInfo);
-                       }
-               }
-
-               pLocationImpl->SetTimestamp(((long long)timestampPosition) * 1000); // in milliseconds
-               pLocationImpl->SetValidity(true);
-               pLocationImpl->SetExtraInfo(L"location_method", locationMethod);
-       }
-
-       ClearLastResult();
-       return location;
-
-CATCH:
-       return location;
-}
-
 bool
 _LocationManager::GetAppAccessibility(void)
 {
@@ -1348,46 +1607,4 @@ _LocationManager::GetAppAccessibility(void)
 
        return (accessState == LOCATIONS_ACCESS_STATE_ALLOWED) ? true : false;
 }
-
-Location
-_LocationManager::GetRecentLocationAvailable(void)
-{
-       long long gpsTimestamp = 0;
-       long long wpsTimestamp = 0;
-       long long cpsTimestamp = 0;
-
-       Location lastGpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_GPS);
-       if (lastGpsLocation.IsValid())
-       {
-               gpsTimestamp = _LocationImpl::GetInstance(lastGpsLocation)->GetTimestampInMs();
-       }
-
-       Location lastWpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_WPS);
-       if (lastWpsLocation.IsValid())
-       {
-               wpsTimestamp = _LocationImpl::GetInstance(lastWpsLocation)->GetTimestampInMs();
-       }
-
-       Location lastCpsLocation = GetLastKnownLocation(LOCATIONS_METHOD_CPS);
-       if (lastCpsLocation.IsValid())
-       {
-               cpsTimestamp = _LocationImpl::GetInstance(lastCpsLocation)->GetTimestampInMs();
-       }
-
-       SysLog(NID_LOC, "Compare timestamp(gps: %lld, wps: %lld, cps: %lld) for recent location.", 
-               gpsTimestamp, wpsTimestamp, cpsTimestamp);
-
-       if (gpsTimestamp >= wpsTimestamp && gpsTimestamp >= cpsTimestamp)
-       {
-               return lastGpsLocation;
-       }
-       else if (wpsTimestamp > gpsTimestamp && wpsTimestamp > cpsTimestamp)
-       {
-               return lastWpsLocation;
-       }
-       else
-       {
-               return lastCpsLocation;
-       }
-}
 }}
index 531eabb..75c5d97 100644 (file)
@@ -57,6 +57,12 @@ public:
        //
        result StopLocationUpdates(RequestId reqId);
 
+       // This method updates the requested interval from the location provider.
+       //
+       // @since 2.0
+       //
+       result ChangeUpdateInterval(RequestId reqId, int interval);
+
        // This method initiates the synchronous location retrieval. The location monitor instance provided is used to intimate back the location.
        //
        // @since 2.0
@@ -158,7 +164,7 @@ private:
        //
        // @since 2.0
        //
-       result SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod);
+       result SetLocationInformation(double latitude, double longitude, double altitude, time_t timestamp, location_method_e locMethod, Location* pLocation);
 
        // The method is called to send back the callbacks in case of async location updates.
        //
@@ -184,6 +190,30 @@ private:
        //
        Location GetLastKnownLocation(location_method_e nativeLocMethod);
 
+       // This method returns the most recent location among available last known locations.
+       //
+       // @since 2.0
+       //
+       Location GetRecentLocationAvailable(void);
+
+       // This method updates the timer interval for a particular request Id.
+       //
+       // @since 2.0
+       //
+       void UpdateLocRequestInfoList(RequestId reqId, int interval);
+
+       // This method gets the better location among the three location providers.
+       //
+       // @since 2.0
+       //
+       const Location* FindBestLocation(void);
+
+       // This method gets the location from the native side depending on the location handle.
+       //
+       // @since 2.0
+       //
+       result GetLocation(location_method_e nativeLocMethod);
+
        // @see @ref Tizen::Base::Runtime::EventDrivenThread::OnStart()
        //
        // @since 2.0
@@ -251,12 +281,6 @@ private:
        //
        static bool GetAppAccessibility(void);
 
-       // This method returns the most recent location among available last known locations.
-       //
-       // @since 2.0
-       //
-       Location GetRecentLocationAvailable(void);
-
 private:
        const static RequestId REQ_ID_START_LOC_UPDATES = 1;
        const static RequestId REQ_ID_STOP_LOC_UPDATES = 2;
@@ -267,6 +291,7 @@ private:
        const static RequestId REQ_ID_SYNC_LOC_RETRIEVAL = 7;
        const static RequestId REQ_ID_GET_APP_ACCESSIBILITY = 8;
        const static RequestId REQ_ID_GET_LAST_LOCATION = 9;
+       const static RequestId REQ_ID_UPDATE_INTERVAL = 10;
 
        enum _LocationMethodRequested
        {
@@ -286,19 +311,34 @@ private:
        }
        __locationMgrState;
 
+       class __LocationManagerHandle
+       {
+       public:
+               __LocationManagerHandle(void)
+                       : serviceState(LOCATIONS_SERVICE_DISABLED)
+                       , handle(null)
+                       , pLocation(null)
+               {
+               }
+
+               ~__LocationManagerHandle(void)
+               {
+               }
+               
+       public:
+               location_service_state_e serviceState;
+               location_manager_h handle;
+               std::unique_ptr< Tizen::Locations::Location > pLocation;
+       };
+
        LocationAccuracy __minRequestedAccuracy;
-       location_service_state_e __nativeGPSServiceState;
-       location_service_state_e __nativeWPSServiceState;
-       location_service_state_e __nativeCPSServiceState;
        int __timerInterval;
        int __timerTicks;
-       location_manager_h __gpsHandler;
-       location_manager_h __wpsHandler;
-       location_manager_h __cpsHandler;
-       std::unique_ptr< Tizen::Locations::Location > __pCurrentLocation;
+       __LocationManagerHandle __gpsHandler;
+       __LocationManagerHandle __wpsHandler;
+       __LocationManagerHandle __cpsHandler;
        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::Runtime::Mutex > __pLocMgrMutex;
        std::unique_ptr< Tizen::Base::Runtime::Timer > __pLocUpdateTimer;
        static _LocationManager* __pUniqueInstance;
 
index 02a1229..bccc8a3 100644 (file)
@@ -39,7 +39,9 @@
 #include <FLocTypes.h>
 #include <FSysPowerManager.h>
 #include <FSysSystemTime.h>
+#include <FSys_AlarmImpl.h>
 #include <FSys_SettingInfoImpl.h>
+#include "FLoc_Config.h"
 #include "FLoc_LocationImpl.h"
 #include "FLoc_LocationManager.h"
 #include "FLoc_LocationMonitor.h"
@@ -60,21 +62,9 @@ namespace Tizen { namespace Locations
 
 _LocationProviderImpl::_LocationProviderImpl(void)
        : Tizen::Base::Runtime::_Event()
-       , __firstLocationUpdate(true)
-       , __regionMonitoringActive(false)
-       , __awakeEnabled(false)
-       , __updateInterval(0)
-       , __locationUpdateType(_LOCATION_UPDATE_TYPE_NONE)
-       , __locationUpdateStatus(LOC_SVC_STATUS_IDLE)
-       , __regionMonitorStatus(LOC_SVC_STATUS_IDLE)
        , __lastLocationAccuracy(LOC_ACCURACY_INVALID)
-       , __reqId(-1)
-       , __regionReqId(-1)
-       , __distanceThreshold(0.0)
        , __pLocationListener(null)
        , __pLocationManager(null)
-       , __pLastLocation(null)
-       , __pRegionList(null)
 {
 }
 
@@ -109,6 +99,18 @@ _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProv
        r = pRegionList->Construct();
        SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the list. Propagating.", GetErrorMessage(r));
 
+       std::unique_ptr< Tizen::Base::Runtime::Timer> pTimer (new (std::nothrow) Timer());
+       SysTryReturn(NID_LOC, pTimer != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       r = pTimer->Construct(*this);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the timer. Propagating.", GetErrorMessage(r));
+
+       std::unique_ptr< Tizen::System::Alarm> pAlarm (new (std::nothrow) Alarm());
+       SysTryReturn(NID_LOC, pAlarm != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       r = pAlarm->Construct(*this);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the alarm. Propagating.", GetErrorMessage(r));
+
        UiApp* pAppInstance = Tizen::App::UiApp::GetInstance();
        if (pAppInstance != null)
        {
@@ -119,14 +121,21 @@ _LocationProviderImpl::Construct(const LocationCriteria& criteria, ILocationProv
                SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Error occured during adding the event listener to app manager. Propagating.", GetErrorMessage(r));
        }
 
-       std::unique_ptr< Tizen::Locations::Location > pLocation(_LocationImpl::GetLocationInstanceN());
-       SysTryReturn(NID_LOC, pLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+       std::unique_ptr< Tizen::Locations::Location > pLastLocation(_LocationImpl::GetLocationInstanceN());
+       SysTryReturn(NID_LOC, pLastLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
+
+       std::unique_ptr<Tizen::Locations::Location> pLastRegionLocation (_LocationImpl::GetLocationInstanceN());
+       SysTryReturn(NID_LOC, pLastRegionLocation != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
        _Event::Initialize();
        _Event::AddListener(*this);
 
-       __pRegionList = std::move(pRegionList);
-       __pLastLocation = std::move(pLocation);
+       __regionMonitor.pRegionList = std::move(pRegionList);
+       __regionMonitor.pTimer = std::move(pTimer);
+       __regionMonitor.pAlarm = std::move(pAlarm);
+       __regionMonitor.pLocation = std::move(pLastRegionLocation);
+       __locationUpdater.pLocation = std::move(pLastLocation);
+       
        __criteria = criteria;
        __pLocationListener = &listener;
        __pLocationManager = pLocationManager;
@@ -144,15 +153,10 @@ _LocationProviderImpl::StartLocationUpdatesByInterval(int interval)
 
        SysTryReturn(NID_LOC, interval >= 1, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The interval(%d) should be greater than or equal to 1", interval);
 
-       if (__locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL && __updateInterval == interval)
+       if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_INTERVAL && __locationUpdater.updateInterval == interval)
        {
                return E_SUCCESS;
        }
-       else if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE || __locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL)
-       {
-               __pLocationManager->StopLocationUpdates(__reqId);
-               __locationUpdateStatus = LOC_SVC_STATUS_IDLE;
-       }
 
        const double INVALID_DISTANCE_THRESHOLD = 0.0;
        return StartLocationUpdates(_LOCATION_UPDATE_TYPE_INTERVAL, interval, INVALID_DISTANCE_THRESHOLD);
@@ -168,15 +172,10 @@ _LocationProviderImpl::StartLocationUpdatesByDistance(double distance)
 
        SysTryReturn(NID_LOC, Double::IsNaN(distance) == false, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The distance is NaN.");
 
-       if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE && (Double::Compare(__distanceThreshold, distance) == 0))
+       if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_DISTANCE && (Double::Compare(__locationUpdater.distanceThreshold, distance) == 0))
        {
                return E_SUCCESS;
        }
-       else if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE || __locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL)
-       {
-               __pLocationManager->StopLocationUpdates(__reqId);
-               __locationUpdateStatus = LOC_SVC_STATUS_IDLE;
-       }
 
        const int INVALID_INTERVAL = 0;
        return StartLocationUpdates(_LOCATION_UPDATE_TYPE_DISTANCE, INVALID_INTERVAL, distance);
@@ -185,11 +184,11 @@ _LocationProviderImpl::StartLocationUpdatesByDistance(double distance)
 result
 _LocationProviderImpl::StopLocationUpdates(void)
 {
-       SysLog(NID_LOC, "Stopping the location updates for the request ID (%ld)", __reqId);
+       SysLog(NID_LOC, "Stopping the location updates for the request ID (%ld)", __locationUpdater.reqId);
 
-       SysTryReturn(NID_LOC, __locationUpdateType != _LOCATION_UPDATE_TYPE_NONE, E_INVALID_OPERATION, E_INVALID_OPERATION, "[E_INVALID_OPERATION] Location update has not been requested.");
+       SysTryReturn(NID_LOC, __locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE, E_INVALID_OPERATION, E_INVALID_OPERATION, "[E_INVALID_OPERATION] Location update has not been requested.");
 
-       result r = __pLocationManager->StopLocationUpdates(__reqId);
+       result r = __pLocationManager->StopLocationUpdates(__locationUpdater.reqId);
 
        ResetLocationUpdates();
 
@@ -199,11 +198,11 @@ _LocationProviderImpl::StopLocationUpdates(void)
 void
 _LocationProviderImpl::KeepLocationUpdateAwake(bool enable)
 {
-       if (__awakeEnabled == enable)
+       if (__locationUpdater.awakeEnabled == enable)
        {
                return;
        }
-       __awakeEnabled = enable;
+       __locationUpdater.awakeEnabled = enable;
 
        UiApp* appInstance = Tizen::App::UiApp::GetInstance();
        if (appInstance == null)        // This is service APP. So should be handled now.
@@ -211,24 +210,24 @@ _LocationProviderImpl::KeepLocationUpdateAwake(bool enable)
                SysLog(NID_LOC, "Handling the request awake mode(%d) for the service application.", enable);
                if (enable == true)
                {
-                       if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus == LOC_SVC_STATUS_PAUSED)
+                       if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status == LOC_SVC_STATUS_PAUSED)
                        {
-                               SysLog(NID_LOC, "Requesting to start the location updates as the update type is (%x)", __locationUpdateType);
-                               __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
-                               __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
+                               SysLog(NID_LOC, "Requesting to start the location updates as the update type is (%x)", __locationUpdater.type);
+                               __locationUpdater.status = LOC_SVC_STATUS_NOT_FIXED;
+                               __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __locationUpdater.updateInterval, this, __locationUpdater.reqId);
 
-                               NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdateStatus);
+                               NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdater.status);
                        }
                }
                else
                {
-                       if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && (__locationUpdateStatus == LOC_SVC_STATUS_RUNNING || __locationUpdateStatus == LOC_SVC_STATUS_NOT_FIXED))
+                       if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && (__locationUpdater.status == LOC_SVC_STATUS_RUNNING || __locationUpdater.status == LOC_SVC_STATUS_NOT_FIXED))
                        {
-                               SysLog(NID_LOC, "Requesting to stop the location updates as the update type is (%x)", __locationUpdateType);
-                               __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
-                               __pLocationManager->StopLocationUpdates(__reqId);
+                               SysLog(NID_LOC, "Requesting to stop the location updates as the update type is (%x)", __locationUpdater.type);
+                               __locationUpdater.status = LOC_SVC_STATUS_PAUSED;
+                               __pLocationManager->StopLocationUpdates(__locationUpdater.reqId);
 
-                               NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdateStatus);
+                               NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdater.status);
                        }
                }
        }
@@ -247,50 +246,51 @@ _LocationProviderImpl::AddMonitoringRegion(const Coordinates& regionCenter, doub
 
        SysLog(NID_LOC, "Requested to add the monitoring region with center (Latitude: %lf, Longitude %lf) and radius (%lf).", regionCenter.GetLatitude(), regionCenter.GetLongitude(), radius);
 
-       const int DEAULT_REGION_MONITOR_INTERVAL = 5;
        static int nextRegionId = 0;
        result r = E_SUCCESS;
 
        std::unique_ptr< _RegionInfo > pRegionInfo(new (std::nothrow) _RegionInfo(regionCenter, radius, nextRegionId));
        SysTryReturn(NID_LOC, pRegionInfo != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
-       r = __pRegionList->Add(*pRegionInfo.get());
+       r = __regionMonitor.pRegionList->Add(*pRegionInfo.get());
        SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to add the Region info into the list. Propogated.", GetErrorMessage(r));
 
        pRegionInfo.release();
        regionId = nextRegionId;
        nextRegionId++;
 
-       if (__regionMonitoringActive == true)
+       if (__regionMonitor.status != LOC_SVC_STATUS_IDLE)
        {
                return E_SUCCESS;
        }
 
-       r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), DEAULT_REGION_MONITOR_INTERVAL, this, __regionReqId);
-       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the location updates. Propogating.", GetErrorMessage(r));
+       r = ActivateRegionMonitoring();
+       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r));
 
-       __regionMonitoringActive = true;
-       __regionMonitorStatus = LOC_SVC_STATUS_NOT_FIXED;
-       NotifyServiceStatus(_LOC_PRV_EVENT_SEND_MONITOR_SVC_CB, __regionMonitorStatus);
+       __regionMonitor.status = LOC_SVC_STATUS_NOT_FIXED;
+       NotifyServiceStatus(_LOC_PRV_EVENT_SEND_MONITOR_SVC_CB, __regionMonitor.status);
 
        return E_SUCCESS;
+
+CATCH:
+       __regionMonitor.pRegionList->RemoveAt(0);
+       return r;
 }
 
 result
 _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
 {
-       int count = __pRegionList->GetCount();
-       result r = E_SUCCESS;
+       int count = __regionMonitor.pRegionList->GetCount();
        bool isIdValid = false;
 
        SysLog(NID_LOC, "Total regions currently monitored is (%d).", count);
 
        for (int i = 0; i < count; i++)
        {
-               _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__pRegionList->GetAt(i));
+               _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__regionMonitor.pRegionList->GetAt(i));
                if (regionId == pRegionInfo->GetRegionId())
                {
-                       __pRegionList->RemoveAt(i, true);
+                       __regionMonitor.pRegionList->RemoveAt(i, true);
                        isIdValid = true;
                        break;
                }
@@ -298,16 +298,14 @@ _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
 
        SysTryReturn(NID_LOC, isIdValid == true, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The region ID is invalid.");
 
-       if (__pRegionList->GetCount() == 0)
+       if (__regionMonitor.pRegionList->GetCount() == 0)
        {
-               __regionMonitoringActive = false;
-               __regionMonitorStatus = LOC_SVC_STATUS_IDLE;
-               if (__locationUpdateStatus == LOC_SVC_STATUS_IDLE)  // As we are using the same variable for both region monitoring and location updates, this set is required here.
+               __regionMonitor.status = LOC_SVC_STATUS_IDLE;
+               if (__locationUpdater.status == LOC_SVC_STATUS_IDLE)  // As we are using the same variable for both region monitoring and location updates, this set is required here.
                {
                        __lastLocationAccuracy = LOC_ACCURACY_INVALID;
                }
-               r = __pLocationManager->StopLocationUpdates(__regionReqId);
-               SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] All regions are removed but failed to stop the location updates. Propagating.", GetErrorMessage(r));
+               StopRegionMonitoring();
        }
 
        return E_SUCCESS;
@@ -316,20 +314,16 @@ _LocationProviderImpl::RemoveMonitoringRegion(RegionId regionId)
 void
 _LocationProviderImpl::RemoveAllMonitoringRegions(void)
 {
-       result r = E_SUCCESS;
+       __regionMonitor.pRegionList->RemoveAll(true);
 
-       __pRegionList->RemoveAll(true);
-
-       if (__regionMonitoringActive == true)
+       if (__regionMonitor.status != LOC_SVC_STATUS_IDLE)
        {
-               __regionMonitoringActive = false;
-               __regionMonitorStatus = LOC_SVC_STATUS_IDLE;
-               if (__locationUpdateStatus == LOC_SVC_STATUS_IDLE)  // As we are using the same variable for both region monitoring and location updates, this set is required here.
+               __regionMonitor.status = LOC_SVC_STATUS_IDLE;
+               if (__locationUpdater.status == LOC_SVC_STATUS_IDLE)  // As we are using the same variable for both region monitoring and location updates, this set is required here.
                {
                        __lastLocationAccuracy = LOC_ACCURACY_INVALID;
                }
-               r = __pLocationManager->StopLocationUpdates(__regionReqId);
-               SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] All regions are removed but failed to stop the location updates. Ignored.", GetErrorMessage(r));
+               StopRegionMonitoring();
        }
 
        return;
@@ -338,13 +332,13 @@ _LocationProviderImpl::RemoveAllMonitoringRegions(void)
 LocationServiceStatus
 _LocationProviderImpl::GetLocationUpdateStatus(void) const
 {
-       return __locationUpdateStatus;
+       return __locationUpdater.status;
 }
 
 LocationServiceStatus
 _LocationProviderImpl::GetRegionMonitoringStatus(void) const
 {
-       return __regionMonitorStatus;
+       return __regionMonitor.status;
 }
 
 LocationAccuracy
@@ -464,12 +458,19 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location
 
        Location* pLocation = &location;
        _LocationImpl* pLocationImpl = _LocationImpl::GetInstance(*pLocation);
-       if (__pLastLocation)
+
+       if (reqId == __locationUpdater.reqId)
        {
-               lastLocationTime = _LocationImpl::GetInstance(*__pLastLocation.get())->GetTimestampInMs();
+               SysLog(NID_LOC, "The location is updated for Location request.");
+               lastLocationTime = _LocationImpl::GetInstance(*__locationUpdater.pLocation.get())->GetTimestampInMs();
+       }
+       else if (reqId == __regionMonitor.reqId)
+       {
+               SysLog(NID_LOC, "The location is updated for Region monitoring.");
+               lastLocationTime = _LocationImpl::GetInstance(*__regionMonitor.pLocation.get())->GetTimestampInMs();
        }
 
-       long long timeDifference = abs(pLocationImpl->GetTimestampInMs() - lastLocationTime);
+       long long timeDifference = pLocationImpl->GetTimestampInMs() - lastLocationTime;
        SysLog(NID_LOC, "Time difference between last location timestamp (%lld) and current location timestamp (%lld) is (%lld).", lastLocationTime, pLocationImpl->GetTimestampInMs(), timeDifference);
        if (timeDifference > 0)
        {
@@ -484,13 +485,31 @@ _LocationProviderImpl::OnLocationEventReceivedN(RequestId reqId, Tizen::Location
                __pLocationListener->OnAccuracyChanged(currentAccuracy);
        }
 
-       if (reqId == __reqId)
+       if (reqId == __locationUpdater.reqId)
        {
                HandleLocationUpdate(location, isNew);
        }
-       else if (reqId == __regionReqId)
+       else if (reqId == __regionMonitor.reqId)
        {
-               HandleRegionMonitoring(location, isNew);
+               if (isNew)      // Copy the location only if it is new.
+               {
+                       *__regionMonitor.pLocation = location;
+               }
+
+               if (currentAccuracy != LOC_ACCURACY_INVALID && currentAccuracy <= __criteria.GetAccuracy())
+               {
+                       SysLog(NID_LOC, "Location criteria (accuracy: %ld) is met for handling region monitoring.", currentAccuracy);
+                       result r = __regionMonitor.pTimer->Cancel();
+                       SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to cancel the timer.");
+
+                       r = __pLocationManager->StopLocationUpdates(__regionMonitor.reqId);
+                       SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to stop the location updates.");
+                       HandleRegionMonitoring(location, isNew);
+               }
+               else
+               {
+                       SysLog(NID_LOC, "Location criteria (accuracy: %ld) is not met for handling region monitoring.", currentAccuracy);
+               }
        }
 
        delete pLocation;
@@ -520,81 +539,111 @@ _LocationProviderImpl::OnActiveAppChanged(const Tizen::App::AppId& appId)
        {
                SysLog(NID_LOC, "Application is active.");
 
-               if (__locationUpdateStatus == LOC_SVC_STATUS_PAUSED)
+               if (__locationUpdater.status == LOC_SVC_STATUS_PAUSED)
                {
                        SysLog(NID_LOC, "Start the location updates as the location update status is PAUSED.");
-                       __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
-                       __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
-                       __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdateStatus);
+                       __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __locationUpdater.updateInterval, this, __locationUpdater.reqId);
+                       __locationUpdater.status = LOC_SVC_STATUS_NOT_FIXED;
+                       __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdater.status);
                }
        }
        else
        {
                SysLog(NID_LOC, "Application is not active.");
-               if (__awakeEnabled == false && (__locationUpdateStatus == LOC_SVC_STATUS_RUNNING || __locationUpdateStatus == LOC_SVC_STATUS_NOT_FIXED))
+               
+               if (__locationUpdater.awakeEnabled == false && (__locationUpdater.status == LOC_SVC_STATUS_RUNNING || __locationUpdater.status == LOC_SVC_STATUS_NOT_FIXED))
                {
-                       SysLog(NID_LOC, "Stop the location updates as application is not active with awake mode as (%d) and location update state as (%x).", __awakeEnabled, __locationUpdateStatus);
-                       __pLocationManager->StopLocationUpdates(__reqId);
-                       __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
-                       __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdateStatus);
+                       SysLog(NID_LOC, "Stop the location updates as application is not active with awake mode as (%d) and location update state as (%x).", __locationUpdater.awakeEnabled, __locationUpdater.status);
+                       __pLocationManager->StopLocationUpdates(__locationUpdater.reqId);
+                       __locationUpdater.status = LOC_SVC_STATUS_PAUSED;
+                       __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdater.status);
                }
        }
 }
 
+void
+_LocationProviderImpl::OnAlarmExpired(Alarm& alarm)
+{
+       SysLog(NID_LOC, "Region Monitor Alarm expired.");
+       
+       result r = ActivateRegionMonitoring();
+       SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to start the region monitoring. Propogating.", GetErrorMessage(r));
+}
+
+void
+_LocationProviderImpl::OnTimerExpired(Timer& timer)
+{
+       SysLog(NID_LOC, "Region Monitor timer expired due to unavailability of location information.");
+       __pLocationManager->StopLocationUpdates(__regionMonitor.reqId);
+       HandleRegionMonitoring(*__regionMonitor.pLocation, __regionMonitor.pLocation->IsValid());
+}
+
 result
 _LocationProviderImpl::StartLocationUpdates(LocationUpdateType updateType, int interval, double distance)
 {
        result r = E_SUCCESS;
-       const int CHECKING_INTERVAL = 10;
+       bool startUpdate = true;
 
        if (updateType == _LOCATION_UPDATE_TYPE_INTERVAL)
        {
-               __updateInterval = interval;
+               __locationUpdater.updateInterval = interval;
        }
        else if (updateType == _LOCATION_UPDATE_TYPE_DISTANCE)
        {
-               __updateInterval = CHECKING_INTERVAL;
-               __distanceThreshold = distance;
+               __locationUpdater.updateInterval = DEFAULT_DISTANCE_CHECKING_INTERVAL;
+               __locationUpdater.distanceThreshold = distance;
        }
 
-       __locationUpdateType = updateType;
-
-       if (__awakeEnabled == true)
-       {
-               r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
-               SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the Native location updates.", GetErrorMessage(r));
-               __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
-       }
-       else
+       if  (!__locationUpdater.awakeEnabled)
        {
                UiApp* pAppInstance = Tizen::App::UiApp::GetInstance();
                if (pAppInstance == null)
                {
-                       __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
+                       startUpdate = false;
                }
-               else
+               else 
                {
                        AppUiState appUiState = pAppInstance->GetAppUiState();
-                       if (appUiState == APP_UI_STATE_FOREGROUND || appUiState == APP_UI_STATE_PARTIAL_BACKGROUND)
-                       {
-                               r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __updateInterval, this, __reqId);
-                               SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the location updates. Propagating.", GetErrorMessage(r));
-                               __locationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
-                       }
-                       else
+               
+                       if (appUiState == APP_UI_STATE_BACKGROUND)
                        {
-                               __locationUpdateStatus = LOC_SVC_STATUS_PAUSED;
+                               SysLog(NID_LOC, "App is background.");
+                               startUpdate = false;
                        }
                }
        }
 
-       SysLog(NID_LOC, "Update type is (%x). The request Id is (%ld) and the update status is (%x).", __locationUpdateType, __reqId, __locationUpdateStatus);
-       NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdateStatus);
+       if (startUpdate)
+       {
+               if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE)
+               {
+                       SysLog(NID_LOC, "Update session already running. Updating the interval to %d seconds", __locationUpdater.updateInterval);
+                       r = __pLocationManager->ChangeUpdateInterval(__locationUpdater.reqId, __locationUpdater.updateInterval);
+                       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to update the request interval. Propagating.", GetErrorMessage(r));
+                       __locationUpdater.type = updateType;
+                       return E_SUCCESS;
+               }
+               else
+               {
+                       r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), __locationUpdater.updateInterval, this, __locationUpdater.reqId);
+                       SysTryCatch(NID_LOC, r == E_SUCCESS, , r, "[%s] Failed to start the Native location updates. Propagating.", GetErrorMessage(r));
+                       __locationUpdater.status = LOC_SVC_STATUS_NOT_FIXED;
+               }       
+       }
+       else
+       {
+               __locationUpdater.status = LOC_SVC_STATUS_PAUSED;       
+       }
+
+       __locationUpdater.type = updateType;
+
+       SysLog(NID_LOC, "Update type is (%x). The request Id is (%ld) and the update status is (%x).", __locationUpdater.type, __locationUpdater.reqId, __locationUpdater.status);
+       NotifyServiceStatus(_LOC_PRV_EVENT_SEND_LOC_SVC_CB, __locationUpdater.status);
 
        return E_SUCCESS;
 
 CATCH:
-       __locationUpdateType = _LOCATION_UPDATE_TYPE_NONE;
+       __locationUpdater.type = _LOCATION_UPDATE_TYPE_NONE;
        return r;
 }
 
@@ -605,28 +654,28 @@ _LocationProviderImpl::CheckDistanceThreshold(const Location& oldPosition, const
        const Coordinates coordOld = oldPosition.GetCoordinates();
        const Coordinates coordNew = newPosition.GetCoordinates();
 
-       if (__firstLocationUpdate)
+       if (__locationUpdater.firstLocationUpdate)
        {
                SysLog(NID_LOC, "First location update. So send true.");
-               __firstLocationUpdate = false;
+               __locationUpdater.firstLocationUpdate = false;
                return true;
        }
 
        displacement = coordOld.GetDistanceTo(coordNew);
        SysLog(NID_LOC, "Displacement is (%lf)", displacement);
-       return ((displacement > __distanceThreshold) ? true : false);
+       return ((displacement > __locationUpdater.distanceThreshold) ? true : false);
 }
 
 void
 _LocationProviderImpl::ResetLocationUpdates(void)
 {
-       __firstLocationUpdate = true;
-       __reqId = -1;
+       __locationUpdater.firstLocationUpdate = true;
+       __locationUpdater.reqId = -1;
        __lastLocationAccuracy = LOC_ACCURACY_INVALID;
-       __locationUpdateType = _LOCATION_UPDATE_TYPE_NONE;
-       __locationUpdateStatus = LOC_SVC_STATUS_IDLE;
-       __updateInterval = 0;
-       __distanceThreshold = 0.0;
+       __locationUpdater.type = _LOCATION_UPDATE_TYPE_NONE;
+       __locationUpdater.status = LOC_SVC_STATUS_IDLE;
+       __locationUpdater.updateInterval = 0;
+       __locationUpdater.distanceThreshold = 0.0;
 }
 
 void
@@ -659,11 +708,11 @@ _LocationProviderImpl::FireImpl(Tizen::Base::Runtime::IEventListener& listener,
 void
 _LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location, bool isNew)
 {
-       LocationServiceStatus newLocationUpdateStatus = __locationUpdateStatus;
+       LocationServiceStatus newLocationUpdateStatus = __locationUpdater.status;
 
        if (isNew)
        {
-               if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus != LOC_SVC_STATUS_PAUSED)
+               if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
                {
                        newLocationUpdateStatus = LOC_SVC_STATUS_RUNNING;
                }
@@ -671,7 +720,7 @@ _LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location
        else if (_LocationImpl::GetInstance(location)->IsDenied())
        {
                SysLog(NID_LOC, "User consent not available.");
-               if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus != LOC_SVC_STATUS_PAUSED)
+               if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
                {
                        newLocationUpdateStatus = LOC_SVC_STATUS_DENIED;
                }
@@ -679,35 +728,35 @@ _LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location
        else
        {
                SysLog(NID_LOC, "Invalid Location Update.");
-               if (__locationUpdateType != _LOCATION_UPDATE_TYPE_NONE && __locationUpdateStatus != LOC_SVC_STATUS_PAUSED)
+               if (__locationUpdater.type != _LOCATION_UPDATE_TYPE_NONE && __locationUpdater.status != LOC_SVC_STATUS_PAUSED)
                {
                        newLocationUpdateStatus = LOC_SVC_STATUS_NOT_FIXED;
                }
        }
 
-       if (newLocationUpdateStatus != __locationUpdateStatus)
+       if (newLocationUpdateStatus != __locationUpdater.status)
        {
                SysLog(NID_LOC, "Location Update Satus changed to (%x). Notify the status.", newLocationUpdateStatus);
-               __locationUpdateStatus = newLocationUpdateStatus;
-               __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdateStatus);
+               __locationUpdater.status = newLocationUpdateStatus;
+               __pLocationListener->OnLocationUpdateStatusChanged(__locationUpdater.status);
        }
 
        if (newLocationUpdateStatus == LOC_SVC_STATUS_RUNNING)
        {
-               if (__locationUpdateType == _LOCATION_UPDATE_TYPE_DISTANCE)
+               if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_DISTANCE)
                {
-                       if (CheckDistanceThreshold(*__pLastLocation.get(), location) == true)
+                       if (CheckDistanceThreshold(*__locationUpdater.pLocation.get(), location) == true)
                        {
-                               SysLog(NID_LOC, "Location displacement exceeds the distance threshold (%lf). Notify the location.", __distanceThreshold);
+                               SysLog(NID_LOC, "Location displacement exceeds the distance threshold (%lf). Notify the location.", __locationUpdater.distanceThreshold);
                                __pLocationListener->OnLocationUpdated(location);
-                               *__pLastLocation.get() = location;
+                               *__locationUpdater.pLocation.get() = location;
                        }
                }
-               else if (__locationUpdateType == _LOCATION_UPDATE_TYPE_INTERVAL)
+               else if (__locationUpdater.type == _LOCATION_UPDATE_TYPE_INTERVAL)
                {
                        SysLog(NID_LOC, "Location time interval expired. Notify the location.");
                        __pLocationListener->OnLocationUpdated(location);
-                       *__pLastLocation.get() = location;
+                       *__locationUpdater.pLocation.get() = location;
                }
        }
 }
@@ -715,7 +764,7 @@ _LocationProviderImpl::HandleLocationUpdate(Tizen::Locations::Location& location
 void
 _LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& location, bool isNew)
 {
-       LocationServiceStatus newRegionMonitorStatus = __regionMonitorStatus;
+       LocationServiceStatus newRegionMonitorStatus = __regionMonitor.status;
 
        if (isNew)
        {
@@ -730,30 +779,31 @@ _LocationProviderImpl::HandleRegionMonitoring(Tizen::Locations::Location& locati
                newRegionMonitorStatus = LOC_SVC_STATUS_NOT_FIXED;
        }
 
-       if (newRegionMonitorStatus != __regionMonitorStatus)
+       if (newRegionMonitorStatus != __regionMonitor.status)
        {
                SysLog(NID_LOC, "Region Monitoring Satus changed to (%x). Notify the status.", newRegionMonitorStatus);
-               __regionMonitorStatus = newRegionMonitorStatus;
-               __pLocationListener->OnRegionMonitoringStatusChanged(__regionMonitorStatus);
+               __regionMonitor.status = newRegionMonitorStatus;
+               __pLocationListener->OnRegionMonitoringStatusChanged(__regionMonitor.status);
        }
 
        if (newRegionMonitorStatus == LOC_SVC_STATUS_RUNNING)
        {
                NotifyRegionCrossedStatus(location);
-               *__pLastLocation.get() = location;
        }
+
+       SetNextRegionMonitoringTime();
 }
 
 void
 _LocationProviderImpl::NotifyRegionCrossedStatus(const Tizen::Locations::Location& location)
 {
-       int count = __pRegionList->GetCount();
+       int count = __regionMonitor.pRegionList->GetCount();
 
        SysLog(NID_LOC, "Number of regions currently monitored is (%d)", count);
 
        for (int i = 0; i < count; i++)
        {
-               _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__pRegionList->GetAt(i));
+               _RegionInfo* pRegionInfo = static_cast< _RegionInfo* >(__regionMonitor.pRegionList->GetAt(i));
 
                if (pRegionInfo)
                {
@@ -920,4 +970,66 @@ _LocationProviderImpl::GetUserPrivilege(void)
 
        return true;
 }
+
+result
+_LocationProviderImpl::ActivateRegionMonitoring(void)
+{
+       long long currentTime;
+       SystemTime::GetTicks(currentTime);
+
+       SysLog(NID_LOC, "Current system time is %lld", currentTime);
+       
+       _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetValidity(false);
+       _LocationImpl::GetInstance(*__regionMonitor.pLocation)->SetTimestamp(currentTime);
+       
+       result r = __regionMonitor.pTimer->Start(DEFAULT_WAITING_TIME_FOR_FIXING_LOCATION * 1000);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the timer. Propogating.", GetErrorMessage(r));
+
+       r = __pLocationManager->StartLocationUpdates(__criteria.GetAccuracy(), MIN_LOCATION_UPDATE_INTERVAL, this, __regionMonitor.reqId);
+       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the location updates. Propogating.", GetErrorMessage(r));
+
+       SysLog(NID_LOC, "Timer & Location updates are started.");
+       return E_SUCCESS;
+}
+
+void
+_LocationProviderImpl::StopRegionMonitoring(void)
+{
+       result r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Cancel();
+       SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to stop the alarm. Ignored.", GetErrorMessage(r));
+
+       r = __regionMonitor.pTimer->Cancel();
+       SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] Failed to stop the timer. Ignored.", GetErrorMessage(r));
+
+       r = __pLocationManager->StopLocationUpdates(__regionMonitor.reqId);
+       SysTryReturnVoidResult(NID_LOC, r == E_SUCCESS, r, "[%s] All regions are removed but failed to stop the location updates. Ignored.", GetErrorMessage(r));
+}
+
+void
+_LocationProviderImpl::SetNextRegionMonitoringTime(void)
+{
+       DateTime alarmDateTime;
+       long long alarmTime = DEFAULT_REGION_MONITORING_CYCLE_INTERVAL;
+       SystemTime::GetCurrentTime(TIME_MODE_WALL, alarmDateTime);
+
+       SysLog(NID_LOC, "Current System Time is %ls", alarmDateTime.ToString().GetPointer());
+
+       if (__regionMonitor.pLocation->IsValid())
+       {
+               const int bufferTime = 5;   //Buffer of 5 seconds for determining the alarmTime;
+               double minDistance = _MathUtils::GetShortestDistance(*__regionMonitor.pLocation, *__regionMonitor.pRegionList);
+               long long newAlarmTime = ((int) minDistance / DEFAULT_AVG_SPEED) - bufferTime;  //Calculate the alarm time based on the shortest distance between current location and nearest region boundary.
+
+               if (newAlarmTime > alarmTime)
+               {
+                       alarmTime = newAlarmTime;
+               }
+       }
+
+       alarmDateTime.AddSeconds(alarmTime);
+       result r = _AlarmImpl::GetInstance(__regionMonitor.pAlarm.get())->Set(alarmDateTime, 0, null);  
+       SysTryLog(NID_LOC, r == E_SUCCESS, "Failed to set the alarm for next cycle.");
+       
+       SysLog(NID_LOC, "Next alarm expires after %ld seconds.", alarmTime);
+}
 }}
index 3b78e53..cc23a48 100644 (file)
 #include <unique_ptr.h>
 #include <FAppIActiveAppEventListener.h>
 #include <FBaseColAllElementsDeleter.h>
-#include <FBaseRtTimer.h>
 #include <FBaseRtIEventListener.h>
+#include <FBaseRtITimerEventListener.h>
+#include <FBaseRtTimer.h>
 #include <FLocLocationCriteria.h>
+#include <FSysAlarm.h>
+#include <FSysIAlarmEventListener.h>
 #include <FBaseRt_Event.h>
 #include "FLoc_ILocationManagerListener.h"
 #include "FLoc_ILocProviderEventListener.h"
@@ -56,6 +59,8 @@ class _LocationProviderImpl
        , public Tizen::Locations::_ILocationManagerListener
        , public Tizen::Locations::_ILocProviderEventListener
        , public Tizen::App::IActiveAppEventListener
+       , public Tizen::Base::Runtime::ITimerEventListener
+       , public Tizen::System::IAlarmEventListener
 {
 public:
        /**
@@ -175,6 +180,16 @@ private:
         */
        virtual void OnActiveAppChanged(const Tizen::App::AppId& appId);
 
+       /**
+        * @see @ref Tizen::System::IAlarmEventListener::OnAlarmExpired()
+        */
+       virtual void OnAlarmExpired(Tizen::System::Alarm& alarm);
+
+       /**
+        * @see @ref Tizen::Base::Runtime::ITimerEventListener::OnTimerExpired()
+        */
+       virtual void OnTimerExpired(Tizen::Base::Runtime::Timer& timer);
+
        // This method requests the location update to the Location Manager.
        //
        // @since 2.0
@@ -226,29 +241,92 @@ private:
        //
        void NotifyServiceStatus(_LocProviderEventType eventType, LocationServiceStatus svcStatus);
 
-       // This method is returns the bool value depicting the privilege details depending on the location settings.
+       // This method returns the bool value depicting the privilege details depending on the location settings.
        //
        // @since 2.0
        //
        static bool GetUserPrivilege(void);
 
+       // This method starts the location updates and the timer for region monitoring.
+       //
+       // @since 2.0
+       //
+       result ActivateRegionMonitoring(void);
+
+       // This method stops the location updates and cancels the timer and alarm set for the area monitoring.
+       //
+       // @since 2.0
+       //
+       void StopRegionMonitoring(void);
+
+       // This method determines the time for the alarm to be set for next cycle of region monitoring.
+       //
+       // @since 2.0
+       //
+       void SetNextRegionMonitoringTime(void);
+
 private:
-       bool __firstLocationUpdate;
-       bool __regionMonitoringActive;
-       bool __awakeEnabled;
-       int __updateInterval;
-       LocationUpdateType __locationUpdateType;
-       LocationServiceStatus __locationUpdateStatus;
-       LocationServiceStatus __regionMonitorStatus;
+       class _LocationUpdater
+       {
+       public:
+               _LocationUpdater(void)
+                       : firstLocationUpdate(true)
+                       , awakeEnabled(false)
+                       , updateInterval(0)
+                       , status(LOC_SVC_STATUS_IDLE)
+                       , type(_LOCATION_UPDATE_TYPE_NONE)                      
+                       , reqId(-1)
+                       , distanceThreshold(0.0)
+                       , pLocation(null)
+               {
+               }
+
+               ~_LocationUpdater(void)
+               {
+               }
+               
+       public:
+               bool firstLocationUpdate;
+               bool awakeEnabled;
+               int updateInterval;
+               LocationServiceStatus status;
+               LocationUpdateType type;
+               RequestId reqId;
+               double distanceThreshold;
+               std::unique_ptr<Tizen::Locations::Location> pLocation;
+       }__locationUpdater;
+       
+       class _RegionMonitor
+       {
+       public:
+               _RegionMonitor(void)
+                       : reqId(-1)
+                       , status(LOC_SVC_STATUS_IDLE)
+                       , pTimer(null)
+                       , pAlarm(null)
+                       , pLocation(null)
+                       , pRegionList(null)
+               {
+               }
+
+               ~_RegionMonitor(void)
+               {
+               }
+               
+       public:
+               RequestId reqId;
+               LocationServiceStatus status;
+               std::unique_ptr<Tizen::Base::Runtime::Timer> pTimer;
+               std::unique_ptr<Tizen::System::Alarm> pAlarm;
+               std::unique_ptr<Tizen::Locations::Location> pLocation;
+               std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > pRegionList;
+       }__regionMonitor;
+
        LocationAccuracy __lastLocationAccuracy;
-       RequestId __reqId;
-       RequestId __regionReqId;
-       double __distanceThreshold;
        LocationCriteria __criteria;
        ILocationProviderListener* __pLocationListener;
        _LocationManager* __pLocationManager;
-       std::unique_ptr< Tizen::Locations::Location > __pLastLocation;
-       std::unique_ptr< Tizen::Base::Collection::ArrayList, Tizen::Base::Collection::AllElementsDeleter > __pRegionList;
+
 }; // _LocationProviderImpl
 }}  // Tizen::Locations
 
index de3602c..ef3046c 100644 (file)
@@ -67,6 +67,8 @@ public:
 
        RequestId GetRequestId(void) const {return __reqId;}
 
+       void SetInterval(int interval) { __interval = interval;}
+
 private:
        _LocationRequestInfo(void);
 
index 25c2b6a..dc6042b 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <math.h>
+#include <FBaseDouble.h>
 #include <FBaseSysLog.h>
 #include <FBaseUtilMath.h>
 #include <FLocLocation.h>
@@ -30,7 +31,7 @@
 #include "FLoc_RegionInfo.h"
 
 using namespace Tizen::Base::Utility;
-
+using namespace Tizen::Base;
 
 namespace Tizen { namespace Locations
 {
@@ -70,4 +71,30 @@ _MathUtils::CalculateOverlapRegion(const _RegionInfo& region, const Location& lo
        return overlapArea;
 }
 
+double
+_MathUtils::GetShortestDistance(const Location& location, const Tizen::Base::Collection::IList& regionList)
+{
+       double minDistance = Double::GetMaxValue();
+       int count = regionList.GetCount();
+
+       for (int i = 0; i < count; i++)
+       {
+               const _RegionInfo* pRegionInfo = static_cast<const _RegionInfo*> (regionList.GetAt(i));
+
+               if (pRegionInfo)
+               {
+                       Coordinates regionCoordinate = pRegionInfo->GetCoordinate();
+                       double distance = abs(regionCoordinate.GetDistanceTo(location.GetCoordinates()) - pRegionInfo->GetRadius());
+
+                       if (minDistance > distance)
+                       {
+                               minDistance = distance;
+                       }
+               }
+       }
+
+       SysLog(NID_LOC, "Shortest distance from location (lat: %lf and lon: %lf) to the nearest region boundary is (%lf) meters", location.GetCoordinates().GetLatitude(), location.GetCoordinates().GetLongitude(), minDistance);
+
+       return minDistance;
+}
 } } // Tizen::Locations
index 082de85..7459b2d 100644 (file)
 #ifndef _FLOC_INTERNAL_MATH_UTILS_H_
 #define _FLOC_INTERNAL_MATH_UTILS_H_
 
+namespace Tizen { namespace Base { namespace Collection
+{
+       class IList;
+}}}
+
 namespace Tizen { namespace Locations
 {
 
@@ -48,6 +53,12 @@ public:
        //
        static double CalculateOverlapRegion(const _RegionInfo& region, const Location& location);
 
+       // This method returns the distance between the user's current location and the the nearest boundary among the added monitoring regions.
+       // @since 2.0
+       //
+       static double GetShortestDistance(const Location& location, const Tizen::Base::Collection::IList& regionList);
+
+
 public:
        static const double PI;
        static const double PI2;
index 0b22c78..f286707 100644 (file)
@@ -45,7 +45,6 @@ public:
        _SyncLocationRequestInfo(_LocationMonitor* pLocMonitor, RequestId reqId)
                : Tizen::Base::Object()
                , __pLocMonitor(pLocMonitor)
-               , __pTimer(null)
                , __reqId(reqId)
                , __tickCount(0)
        {
@@ -56,34 +55,12 @@ public:
 
        _LocationMonitor* GetLocationMonitor(void) const {return __pLocMonitor;}
 
-       result StartTimer(Tizen::Base::Runtime::ITimerEventListener& listener)
-       {
-               result r = E_SUCCESS;
-
-               if (__pTimer == null)
-               {
-                       std::unique_ptr< Tizen::Base::Runtime::Timer > pTimer(new (std::nothrow) Tizen::Base::Runtime::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(listener);
-                       SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to construct the timer.", GetErrorMessage(r));
-
-                       __pTimer = std::move(pTimer);
-               }
-
-               const int DEFAULT_TIME_OUT = 1000;
-               r = __pTimer->Start(DEFAULT_TIME_OUT);
-               SysTryReturn(NID_LOC, r == E_SUCCESS, r, r, "[%s] Failed to start the timer.", GetErrorMessage(r));
-               __tickCount++;
-               return E_SUCCESS;
-       }
-
-       bool Equals(const Tizen::Base::Runtime::Timer& timer) {return __pTimer->Equals(timer);}
-
        RequestId GetRequestId(void) const {return __reqId;}
 
        int GetTickCount(void) const {return __tickCount;}
 
+       void IncrementTickCount(void) { __tickCount++;}
+
        bool IsInTime(const Tizen::Base::DateTime& timestamp)
        {
                return (timestamp > __requestTime) ? true : false;
@@ -109,7 +86,6 @@ private:
 private:
        Tizen::Base::DateTime __requestTime;
        _LocationMonitor* __pLocMonitor;
-       std::unique_ptr< Tizen::Base::Runtime::Timer > __pTimer;
        RequestId __reqId;
        int __tickCount;
 }; //_SyncLocationRequestInfo