omadrm/drmengine/drmclock/Src/GPSWatcher.cpp
changeset 31 908beac81e0a
parent 23 493788a4a8a4
--- a/omadrm/drmengine/drmclock/Src/GPSWatcher.cpp	Mon May 03 12:46:34 2010 +0300
+++ b/omadrm/drmengine/drmclock/Src/GPSWatcher.cpp	Fri May 14 16:07:34 2010 +0300
@@ -26,8 +26,6 @@
 #include "drmlog.h"
 
 // Wait time in microseconds: wait 5 minutes
-const TInt KGpsDefaultWaitTime = 300000000;
-const TInt KMaxRetryCounter = 20;
 
 // ============================ MEMBER FUNCTIONS ===============================
 
@@ -41,7 +39,8 @@
 CGPSWatcher::CGPSWatcher( CDRMClock* aClock ) :
 	CTimer(EPriorityHigh),
 	iClock( aClock ),
-	iRetryCounter( 0 )
+	iStatusUpdater( NULL ),
+	iGpsStatus( CPosIntGpsHwStatus::EStatusUnknown )
 	{
 	CActiveScheduler::Add(this);
 	}
@@ -55,10 +54,10 @@
 	{
 	Cancel();
 
-	delete iTimeUpdater; 
-	iTimeUpdater = 0; 
-	
-	iPosServer.Close();
+    iTimeUpdaters.ResetAndDestroy();
+	iActiveSatelliteModules.ResetAndDestroy();
+    
+    delete iStatusUpdater;
 	}
 
 // -----------------------------------------------------------------------------
@@ -84,28 +83,42 @@
 //
 void CGPSWatcher::ConstructL()
 	{
+    TRequestStatus* status = &iStatus;    	    
 	CTimer::ConstructL();
 
-	User::LeaveIfError(iPosServer.Connect());
-	
-	// Immediately subscribe for module status events
-	iStatusEvent.SetRequestedEvents(TPositionModuleStatusEventBase::EEventDeviceStatus);
-	Subscribe();
-
-	// Check initial state
-	CheckModules();
+    // Create the status updater
+    iStatusUpdater = CPosIntGpsHwStatus::NewL(*this);
+        
+    // Get the status manually, if we can, it's ok if we cant
+    TRAP_IGNORE( iStatusUpdater->GetStatusL( iGpsStatus ) );
+    
+    if( !IsActive() )
+        {
+        SetActive();    
+        }
+        
+    User::RequestComplete(status, KErrNone);   
 	}
 
 // -----------------------------------------------------------------------------
-// CGPSWatcher::Subscribe
-// Subscribe to position events
+// CGPSWatcher::OnStatusUpdateEvent
+// Inherited from MPosIntGpsHwStatusObserver
 // -----------------------------------------------------------------------------
 //
-void CGPSWatcher::Subscribe()
-	{
-	iPosServer.NotifyModuleStatusEvent(iStatusEvent, iStatus);
-	SetActive();
-	}
+void CGPSWatcher::OnStatusUpdateEvent(CPosIntGpsHwStatus::TIntGpsHwStatus aStatus, TInt aError)
+    {
+    TRequestStatus* status = &iStatus;    
+    
+    // store the status from the Gps:
+    iGpsStatus = aStatus;
+        
+    User::RequestComplete(status, aError);
+
+    if( !IsActive() )
+        {        
+        SetActive();
+        }    
+    }
 
 // -----------------------------------------------------------------------------
 // CGPSWatcher::RunL
@@ -114,41 +127,53 @@
 //
 void CGPSWatcher::RunL()
 	{
+    TInt error = KErrNone;
+    
 	// If there are errors just leave and stop watching:    
-	DRMLOG2(_L("CGPSWatcher::RunL: error: '%d'"), iStatus.Int());   
-    	        
-	// If we already updated the time:
-	if( iTimeUpdater && iTimeUpdater->TimeReceived() )
-	    {
-	    DRMLOG( _L("CGPSWatcher::RunL: time updater exists, time received, deleting"));    
-	    iClock->Notify( CDRMClock::ENotifyGPSTimeReceived );    
-	    DRMLOG( _L("CGPSWatcher::RunL: object deleted, returning"));
-	    return;    
-	    }
+	DRMLOG2(_L("CGPSWatcher::RunL: status: '%d'"), iStatus.Int());   
 
-	// The server was killed:
-    if( iStatus.Int() == KErrServerTerminated )
+    switch( iGpsStatus )
         {
-        if( iRetryCounter > KMaxRetryCounter )
-            {
-            DRMLOG( _L("CGPSWatcher::RunL: Maximum retries reached, stopping watcher.") );    
-            iClock->Notify( CDRMClock::ENotifyGPSTimeReceived );
-            return;         
-            }    
-	    // If there are errors just leave and stop watching:    
-	    DRMLOG2(_L("CGPSWatcher::RunL: server terminated, waiting '%d' microseconds"), KGpsDefaultWaitTime);               
-        After( TTimeIntervalMicroSeconds32(KGpsDefaultWaitTime) );
-        return;    
-        }	  
-	    
-	Subscribe();
-	TPositionModuleStatusEventBase::TModuleEvent occurredEvents = iStatusEvent.OccurredEvents();
-	DRMLOG2(_L("CGPSWatcher::RunL: occurredEvents = 0x%X"), occurredEvents);
-	
-	
-	// If time updater is not running, check module statuses
-	if(!iTimeUpdater)
-		CheckModules();
+        // GPS HW is used and is receiving location fixes.
+        case CPosIntGpsHwStatus::EStatusOn:
+            DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Checking modules"));
+            // No active modules, check again:
+            if( !iActiveSatelliteModules.Count() )
+                {
+                DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: No active modules in list Checking modules"));    
+                error = CheckModules();    
+                }
+            
+            // if we have some or found some check the satellites for updates:    
+            if( !error && iActiveSatelliteModules.Count() )
+                {
+                DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Active modules available (%d), check satellites"), iActiveSatelliteModules.Count());                     
+                // Get the time update:
+                CheckSatellites();   
+                }
+            else
+                {
+                DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Still no active modules in list or error (%d) occurred"), error);                     
+                }        
+            break;  
+        // GPS HW is used and is searching for location.
+        case CPosIntGpsHwStatus::EStatusActive:
+            // Get a list of active GPS modules:
+            DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusActive: Checking modules"));
+            
+            // return value not important:
+            CheckModules();
+            break;
+        case CPosIntGpsHwStatus::EStatusUnknown:
+        case CPosIntGpsHwStatus::EStatusOff:
+            // Clear the list of modules:
+            DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusUnknown,Off or default: (%d) Checking modules"), iGpsStatus);            
+            iActiveSatelliteModules.ResetAndDestroy();  
+            iTimeUpdaters.ResetAndDestroy();         
+        default:
+            // Do nothing    
+            break;   
+        }		
 	}
 
 
@@ -159,7 +184,6 @@
 //
 void CGPSWatcher::DoCancel()
 	{
-	iPosServer.CancelRequest(EPositionServerNotifyModuleStatusEvent);
 	}
 
 // -----------------------------------------------------------------------------
@@ -178,36 +202,54 @@
 // Check what modules are present and act accordingly
 // -----------------------------------------------------------------------------
 //
-void CGPSWatcher::CheckModules()
+TInt CGPSWatcher::CheckModules()
 	{
-	// Get number of modules
-	TUint numModules;
-	if(iPosServer.GetNumModules(numModules)!=KErrNone || !numModules)
-		return;
+	TUint numModules = 0;
+	TPositionModuleInfo* moduleInfo = NULL;
+	TInt error = KErrNone;
+	RPositionServer posServer;
 	
-	// Collect all active and satellite capable modules
-	TFullName moduleName;
-	RPointerArray<TPositionModuleInfo> satelliteModules;
-	
-	TPositionModuleInfo *moduleInfo(0);
-	
-	for(TUint i=0; i<numModules; i++)
+	// Destroy the old list:
+	iActiveSatelliteModules.ResetAndDestroy();
+		    
+	// open connection to the positioning server:	    
+    error = posServer.Connect();		    
+	if( error )
+	    {
+	    return error;    
+	    }	    
+		    
+    error = posServer.GetNumModules( numModules );		    
+		    
+	if(error || !numModules)
+	    {
+        DRMLOG2(_L("CheckModules: modules available (%d)"), numModules);	  
+        DRMLOG2(_L("CheckModules: error code (%d)"), error);	          
+      
+		return KErrNotFound;
+        }
+        
+	for( TUint i = 0; i < numModules; i++)
 		{
 		if(!moduleInfo)
 			{
 			moduleInfo = new TPositionModuleInfo;
-			if(!moduleInfo)
-			    {   
-				continue;
-			    }
+            if( !moduleInfo )
+                {
+                // in practice OOM situation
+                posServer.Close();    
+                return KErrNoMemory;    
+                }
 			}
 		
 		// Get module info from the server
-		if(iPosServer.GetModuleInfoByIndex(i, *moduleInfo) != KErrNone)
+		if(posServer.GetModuleInfoByIndex(i, *moduleInfo) != KErrNone)
 		    {
 			continue;
             }
-            
+
+        DRMLOG(_L("CheckModules: Checking for internal & satellite capable"));	
+                        
 		// Check if the module is internal and satellite capable		
 		if(! (moduleInfo->DeviceLocation() & TPositionModuleInfo::EDeviceInternal) ||
 		   ! (moduleInfo->Capabilities() & TPositionModuleInfo::ECapabilitySatellite) )
@@ -216,47 +258,75 @@
 			continue;
 			}
 		
-		// Get module status
+		// Get module status and check if the module is actually active:
+
+
+        DRMLOG(_L("CheckModules: Checking module status"));	
+        		
 		TPositionModuleStatus moduleStatus;
-		if(iPosServer.GetModuleStatus(moduleStatus, moduleInfo->ModuleId()) != KErrNone)
+		
+		if(posServer.GetModuleStatus(moduleStatus, moduleInfo->ModuleId()) != KErrNone)
 		    {
 			continue;
 		    }
-		// Check if the module is active
-		if(moduleStatus.DeviceStatus() != TPositionModuleStatus::EDeviceActive) 
+
+		// Check if the module is active or ready as all might not use the active state:
+		if(!(moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceActive ||
+		     moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceReady) ) 
 		    {
 			continue;
 		    }
 
-		moduleInfo->GetModuleName(moduleName);
-		
-		DRMLOG6( _L("Module %d: id=0x%08X, name = %S, cap=0x%08X, status=%d"), i, moduleInfo->ModuleId().iUid, &moduleName, moduleInfo->Capabilities(), moduleStatus.DeviceStatus());
+
+        DRMLOG(_L("CheckModules: Module is ready or active"));	
 			
 		// Active internal satellite device, try to append in the array
-		if(satelliteModules.Append(moduleInfo) == KErrNone)
+		if(iActiveSatelliteModules.Append(moduleInfo) == KErrNone)
 		    {
+		    // Set this to 0 so that on the next round a new one will be created
+		    // old one will be in the list:   
+            DRMLOG2(_L("CheckModules: Appended modules to list available (%d) active now available"), iActiveSatelliteModules.Count());		     
 			moduleInfo = 0;
 		    }
 		}
 	
-	delete moduleInfo;
+	// There is a module created which was not added, delete it.	
+	if( moduleInfo )
+	    {
+	    delete moduleInfo;
+	    moduleInfo = NULL;    
+	    }	
 	
-	if(satelliteModules.Count())
-		{
-		DRMLOG( _L("Active satellite module available") );    
-		// We have an active satellite module available
-		TPositionModuleId moduleId = satelliteModules[0]->ModuleId();
-		
-		// Just allocating/deleting the time updater will do the trick
-		iTimeUpdater = CGPSTimeUpdater::New(iPosServer, moduleId, iClock);
-		}
-	else
-		{
-		DRMLOG( _L("No active satellite modules available") );    
-		// Delete time updater since no active GPS anymore
-		delete iTimeUpdater; iTimeUpdater = 0;
-		}
-	
-	satelliteModules.ResetAndDestroy();
-	satelliteModules.Close();
+	// close connection to the positioning server:    
+	posServer.Close();
+	return KErrNone;
 	}
+
+
+// -----------------------------------------------------------------------------
+// CGPSWatcher::CheckSatellites()
+// Check what modules are present and act accordingly
+// -----------------------------------------------------------------------------
+//
+void CGPSWatcher::CheckSatellites()
+    {
+    CGPSTimeUpdater* updater = NULL;
+        
+    iTimeUpdaters.ResetAndDestroy();
+        
+    // Start as many updaters as needed:    
+    for( TInt i = 0; i < iActiveSatelliteModules.Count(); i++ )
+        {
+        updater = CGPSTimeUpdater::New( iActiveSatelliteModules[i]->ModuleId(), iClock );
+        if( updater )
+            {
+            if( iTimeUpdaters.Append(updater) ) 
+                {
+                delete updater;
+                updater = NULL;    
+                }
+            }
+        }    
+    }
+    
+// End of File