--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/location/position/src/clocationprovider.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,442 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Handles LocationProvider operations
+ *
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <f32file.h>
+#include "clocationprovider.h"
+#include "cpositioner.h"
+#include "ctrackingpositioner.h"
+#include "cdelaystatechangetimer.h"
+#include "javax_microedition_location_LocationProvider.h"
+#include "javax_microedition_location_Location.h"
+#include "com_nokia_mj_impl_location_LocationProviderImpl.h"
+#include "locationfunctionserver.h"
+#include "fs_methodcall.h"
+#include "logger.h"
+
+using namespace java::location;
+
+// CONSTANTS
+const TInt KAvailable =
+ com_nokia_mj_impl_location_LocationProviderImpl_AVAILABLE;
+const TInt KTemporarilyUnavailable =
+ com_nokia_mj_impl_location_LocationProviderImpl_TEMPORARILY_UNAVAILABLE;
+const TInt KOutOfService =
+ com_nokia_mj_impl_location_LocationProviderImpl_OUT_OF_SERVICE;
+
+const TInt KAddressInfo =
+ com_nokia_mj_impl_location_LocationProviderImpl_ADDRESS_REQUIRED;
+const TInt KCostAllowed =
+ com_nokia_mj_impl_location_LocationProviderImpl_COST_ALLOWED;
+const TInt KAltitude =
+ com_nokia_mj_impl_location_LocationProviderImpl_ALTITUDE_REQUIRED;
+const TInt KSpeedAndCourse =
+ com_nokia_mj_impl_location_LocationProviderImpl_SPEED_AND_COURSE_REQUIRED;
+
+const TInt KMteSatellite = javax_microedition_location_Location_MTE_SATELLITE;
+const TInt KMtyTerminalbased =
+ javax_microedition_location_Location_MTY_TERMINALBASED;
+const TInt KMtyNetworkbased =
+ javax_microedition_location_Location_MTY_NETWORKBASED;
+const TInt KMtaAssisted = javax_microedition_location_Location_MTA_ASSISTED;
+const TInt KMtaUnassisted = javax_microedition_location_Location_MTA_UNASSISTED;
+
+const TInt KAvailableToTempUnavailableDelay = 5000000; // 5 seconds
+const TInt KTempUnavailableToAvailableDelay = 2000000; // 2 seconds
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::CLocationProvider
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CLocationProvider::CLocationProvider(LocationFunctionServer* aFunctionSource) :
+ CActive(EPriorityNormal), mFunctionServer(aFunctionSource), iStatusEvent(
+ TPositionModuleStatusEvent::EEventAll), iState(KAvailable)
+{
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::ConstructL()
+{
+ CActiveScheduler::Add(this);
+ JELOG2(EJavaLocation);
+ User::LeaveIfError(iPositionServer.Connect());
+ iStateTimer = CDelayStateChangeTimer::NewL(this);
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::NewL(LocationFunctionServer* aFunctionSource,
+ TInt* aHandle)
+{
+ JELOG2(EJavaLocation);
+
+ CLocationProvider* self = new(ELeave) CLocationProvider(aFunctionSource);
+
+ CleanupStack::PushL(self);
+ CallMethodL(self, &CLocationProvider::ConstructL, self->mFunctionServer);
+ CleanupStack::Pop(self);
+
+ *aHandle = reinterpret_cast<TInt>(self);
+}
+
+// Destructor
+CLocationProvider::~CLocationProvider()
+{
+ JELOG2(EJavaLocation);
+ Cancel();
+ delete iStateTimer;
+ delete iTrackingPositioner;
+ iPositionServer.Close();
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::StaticCreatePositionerL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::StaticCreatePositionerL(JNIEnv* aJni,
+ jobject aJavaPositioner, CLocationProvider* aSelf, TInt* aHandle,
+ LocationFunctionServer* aFunctionSource)
+{
+ JELOG2(EJavaLocation);
+
+ CPositioner* positioner = NULL;
+ TRAPD(error, CallMethodL(positioner, aSelf,
+ &CLocationProvider::CreatePositionerL, aFunctionSource));
+
+ if ((error != KErrNone) || (positioner == NULL))
+ {
+ ELOG1(EJavaLocation, "StaticCreatePositionerL - error=%d", error);
+ *aHandle = error;
+ return;
+ }
+
+ // Positioner takes ownership of the event since it is reusable
+ positioner->SetCallBackData(aJavaPositioner, aJni);
+
+ *aHandle = reinterpret_cast<TInt>(positioner);
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::RunL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::RunL()
+{
+ JELOG2(EJavaLocation);
+ if (iStatus == KErrNone)
+ {
+ iStateTimer->Cancel();
+
+ TPositionModuleStatus moduleStatus;
+ iStatusEvent.GetModuleStatus(moduleStatus);
+ TInt newState = StatusToState(moduleStatus);
+
+ if (newState == KTemporarilyUnavailable && iState == KAvailable)
+ {
+ iStateTimer->ChangeStateAfter(KAvailableToTempUnavailableDelay,
+ newState);
+ }
+ else if (newState == KAvailable && iState == KTemporarilyUnavailable)
+ {
+ iStateTimer->ChangeStateAfter(KTempUnavailableToAvailableDelay,
+ newState);
+ }
+ else
+ {
+ ChangeState(newState);
+ }
+ }
+
+ RequestModuleStatus();
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::DoCancel
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::DoCancel()
+{
+ JELOG2(EJavaLocation);
+ iStateTimer->Cancel();
+ iPositionServer.CancelRequest(EPositionServerNotifyModuleStatusEvent);
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::CreatePositionerL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CPositioner* CLocationProvider::CreatePositionerL()
+{
+ JELOG2(EJavaLocation);
+ CPositioner* positioner = CPositioner::NewL(mFunctionServer,
+ iPositionServer, iModuleId, iCapabilities);
+ return positioner;
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::SelectModuleL
+//
+// Selects a positioning module. Prefers modules in AVAILABLE state.
+// Leaves with KErrNotSupported if no module match the requirements.
+// Leaves with KErrNotFound if no modules are available.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::SelectModuleL(TInt aHacc, TInt aVacc, TInt aRespTime,
+ TInt aPower, TInt aRequiredFlags, TInt* aMethodTimeout)
+{
+ JELOG2(EJavaLocation);
+ mJni = mFunctionServer->getValidJniEnv();
+ mPeer = mFunctionServer->getPeer();
+
+ jclass peerClass = (*mJni).GetObjectClass(mPeer);
+
+ //Get Method ID of Azimuth Data Callback
+ mStateChangMethod = mJni->GetMethodID(peerClass, "stateChange", "(I)V");
+
+ if (AllLocationRequestsDeniedL())
+ {
+ User::Leave(KErrNotFound); // Location is off, no modules can be used
+ }
+
+ TBool allModulesOutOfService(ETrue);
+ TPositionModuleInfo modInfo;
+
+ // Check if requirements are met for available modules
+ TUint numModules(0);
+ User::LeaveIfError(iPositionServer.GetNumModules(numModules));
+
+ for (TUint i = 0; i < numModules; ++i)
+ {
+ User::LeaveIfError(iPositionServer.GetModuleInfoByIndex(i, modInfo));
+
+ if (modInfo.IsAvailable())
+ {
+ TPositionQuality moduleQuality;
+ modInfo.GetPositionQuality(moduleQuality);
+ if (CheckRequirements(moduleQuality, modInfo.Capabilities(), aHacc,
+ aVacc, aRespTime, aPower, aRequiredFlags))
+ {
+ iModuleId = modInfo.ModuleId();
+ break;
+ }
+
+ allModulesOutOfService = EFalse;
+ }
+ }
+
+ if (iModuleId == KPositionNullModuleId) // No module found
+ {
+ User::Leave(allModulesOutOfService ? KErrNotFound : KErrNotSupported);
+ }
+
+ RequestModuleStatus();
+
+ iCapabilities = modInfo.Capabilities();
+
+ iTrackingPositioner = CTrackingPositioner::NewL(mFunctionServer,
+ iPositionServer, iModuleId, iCapabilities);
+
+ TInt locationMethod = (iCapabilities
+ & TPositionModuleInfo::ECapabilitySatellite) ? KMteSatellite : 0;
+
+ TInt tech = modInfo.TechnologyType();
+ TBool networkBased = EFalse;
+
+ if (tech & TPositionModuleInfo::ETechnologyTerminal)
+ {
+ locationMethod |= KMtyTerminalbased;
+ }
+ if (tech & TPositionModuleInfo::ETechnologyNetwork)
+ {
+ locationMethod |= KMtyNetworkbased;
+ networkBased = ETrue;
+ }
+
+ TPositionQuality quality;
+ modInfo.GetPositionQuality(quality);
+ iTrackingPositioner->SetDefaultValues(quality.TimeToNextFix(), networkBased);
+
+ locationMethod
+ |= (tech & TPositionModuleInfo::ETechnologyAssisted) ? KMtaAssisted
+ : KMtaUnassisted;
+
+ aMethodTimeout[0] = locationMethod;
+ // Default timeout is set to TTFF * 2
+ aMethodTimeout[1] = (I64INT(quality.TimeToFirstFix().Int64()) * 2)
+ / 1000000;
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::CheckRequirements
+//
+// Returns ETrue if requirements are met, EFalse otherwise.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CLocationProvider::CheckRequirements(const TPositionQuality& aQuality,
+ TPositionModuleInfo::TCapabilities aCaps, TInt aHacc, TInt aVacc,
+ TInt aRespTime, TInt aPower, TInt aRequiredFlags)
+{
+ JELOG2(EJavaLocation);
+ if ((aRequiredFlags & KAddressInfo) && !(aCaps
+ & (TPositionModuleInfo::ECapabilityAddress
+ | TPositionModuleInfo::ECapabilityBuilding
+ | TPositionModuleInfo::ECapabilityMedia)))
+ {
+ return EFalse;
+ }
+ if ((aRequiredFlags & KAltitude) && !(aCaps
+ & TPositionModuleInfo::ECapabilityVertical))
+ {
+ return EFalse;
+ }
+ if ((aRequiredFlags & KSpeedAndCourse) && !((aCaps
+ & TPositionModuleInfo::ECapabilitySpeed) && (aCaps
+ & TPositionModuleInfo::ECapabilityDirection)))
+ {
+ return EFalse;
+ }
+ if (!(aRequiredFlags & KCostAllowed) && aQuality.CostIndicator()
+ != TPositionQuality::ECostZero)
+ {
+ return EFalse;
+ }
+ if (aHacc != 0 && aQuality.HorizontalAccuracy() > aHacc)
+ {
+ return EFalse;
+ }
+ if (aVacc != 0 && aQuality.VerticalAccuracy() > aVacc)
+ {
+ return EFalse;
+ }
+ if (aRespTime != 0 && (aQuality.TimeToNextFix().Int64() / 1000) > aRespTime)
+ {
+ return EFalse;
+ }
+
+ if (aPower > 0 && aPower < 3) // LOW or MEDIUM
+ {
+ switch (aQuality.PowerConsumption())
+ {
+ case TPositionQuality::EPowerHigh: // Fall through
+ case TPositionQuality::EPowerUnknown:
+ return EFalse;
+ case TPositionQuality::EPowerMedium:
+ if (aPower == 1)
+ {
+ return EFalse;
+ }
+ default:
+ break;
+ }
+ }
+
+ return ETrue;
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::RequestModuleStatus
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::RequestModuleStatus()
+{
+ JELOG2(EJavaLocation);
+ iPositionServer.NotifyModuleStatusEvent(iStatusEvent, iStatus, iModuleId);
+ SetActive();
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::StatusToState
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CLocationProvider::StatusToState(TPositionModuleStatus& aStatus)
+{
+ JELOG2(EJavaLocation);
+ switch (aStatus.DeviceStatus())
+ {
+ case TPositionModuleStatus::EDeviceUnknown: // Illegal state => Out of service
+ case TPositionModuleStatus::EDeviceError:
+ case TPositionModuleStatus::EDeviceDisabled:
+ return KOutOfService;
+ case TPositionModuleStatus::EDeviceInactive:
+ case TPositionModuleStatus::EDeviceInitialising:
+ return KAvailable;
+ case TPositionModuleStatus::EDeviceStandBy:
+ case TPositionModuleStatus::EDeviceReady:
+ case TPositionModuleStatus::EDeviceActive:
+ if (aStatus.DataQualityStatus()
+ == TPositionModuleStatus::EDataQualityLoss)
+ {
+ return KTemporarilyUnavailable;
+ }
+ else
+ {
+ return KAvailable;
+ }
+ default:
+ return KOutOfService;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::ChangeState
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CLocationProvider::ChangeState(TInt aState)
+{
+ if (aState != iState)
+ {
+ mJni = mFunctionServer->getValidJniEnv();
+ mPeer = mFunctionServer->getPeer();
+
+ (*mJni).CallVoidMethod(mPeer, mStateChangMethod, aState);
+ iState = aState;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CLocationProvider::AllLocationRequestsDeniedL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CLocationProvider::AllLocationRequestsDeniedL()
+{
+ // Global privacy not used anymore
+ return EFalse;
+}
+