omadrm/drmengine/drmclock/Src/GPSWatcher.cpp
branchRCL_3
changeset 32 457cd4423b8c
parent 20 a20e54f39dd4
equal deleted inserted replaced
25:04da681812a9 32:457cd4423b8c
    24 #include "GPSTimeUpdater.h"
    24 #include "GPSTimeUpdater.h"
    25 #include "DRMClock.h"
    25 #include "DRMClock.h"
    26 #include "drmlog.h"
    26 #include "drmlog.h"
    27 
    27 
    28 // Wait time in microseconds: wait 5 minutes
    28 // Wait time in microseconds: wait 5 minutes
    29 const TInt KGpsDefaultWaitTime = 300000000;
       
    30 const TInt KMaxRetryCounter = 20;
       
    31 
    29 
    32 // ============================ MEMBER FUNCTIONS ===============================
    30 // ============================ MEMBER FUNCTIONS ===============================
    33 
    31 
    34 
    32 
    35 // -----------------------------------------------------------------------------
    33 // -----------------------------------------------------------------------------
    39 // -----------------------------------------------------------------------------
    37 // -----------------------------------------------------------------------------
    40 //   
    38 //   
    41 CGPSWatcher::CGPSWatcher( CDRMClock* aClock ) :
    39 CGPSWatcher::CGPSWatcher( CDRMClock* aClock ) :
    42 	CTimer(EPriorityHigh),
    40 	CTimer(EPriorityHigh),
    43 	iClock( aClock ),
    41 	iClock( aClock ),
    44 	iRetryCounter( 0 )
    42 	iStatusUpdater( NULL ),
       
    43 	iGpsStatus( CPosIntGpsHwStatus::EStatusUnknown )
    45 	{
    44 	{
    46 	CActiveScheduler::Add(this);
    45 	CActiveScheduler::Add(this);
    47 	}
    46 	}
    48 
    47 
    49 // -----------------------------------------------------------------------------
    48 // -----------------------------------------------------------------------------
    53 // 
    52 // 
    54 CGPSWatcher::~CGPSWatcher()
    53 CGPSWatcher::~CGPSWatcher()
    55 	{
    54 	{
    56 	Cancel();
    55 	Cancel();
    57 
    56 
    58 	delete iTimeUpdater; 
    57     iTimeUpdaters.ResetAndDestroy();
    59 	iTimeUpdater = 0; 
    58 	iActiveSatelliteModules.ResetAndDestroy();
    60 	
    59     
    61 	iPosServer.Close();
    60     delete iStatusUpdater;
    62 	}
    61 	}
    63 
    62 
    64 // -----------------------------------------------------------------------------
    63 // -----------------------------------------------------------------------------
    65 // CGPSWatcher::NewL
    64 // CGPSWatcher::NewL
    66 // Two-phased constructor
    65 // Two-phased constructor
    82 // Symbian 2nd phase constructor can leave.
    81 // Symbian 2nd phase constructor can leave.
    83 // -----------------------------------------------------------------------------
    82 // -----------------------------------------------------------------------------
    84 //
    83 //
    85 void CGPSWatcher::ConstructL()
    84 void CGPSWatcher::ConstructL()
    86 	{
    85 	{
       
    86     TRequestStatus* status = &iStatus;    	    
    87 	CTimer::ConstructL();
    87 	CTimer::ConstructL();
    88 
    88 
    89 	User::LeaveIfError(iPosServer.Connect());
    89     // Create the status updater
    90 	
    90     iStatusUpdater = CPosIntGpsHwStatus::NewL(*this);
    91 	// Immediately subscribe for module status events
    91         
    92 	iStatusEvent.SetRequestedEvents(TPositionModuleStatusEventBase::EEventDeviceStatus);
    92     // Get the status manually, if we can, it's ok if we cant
    93 	Subscribe();
    93     TRAP_IGNORE( iStatusUpdater->GetStatusL( iGpsStatus ) );
    94 
    94     
    95 	// Check initial state
    95     if( !IsActive() )
    96 	CheckModules();
    96         {
    97 	}
    97         SetActive();    
    98 
    98         }
    99 // -----------------------------------------------------------------------------
    99         
   100 // CGPSWatcher::Subscribe
   100     User::RequestComplete(status, KErrNone);   
   101 // Subscribe to position events
   101 	}
   102 // -----------------------------------------------------------------------------
   102 
   103 //
   103 // -----------------------------------------------------------------------------
   104 void CGPSWatcher::Subscribe()
   104 // CGPSWatcher::OnStatusUpdateEvent
   105 	{
   105 // Inherited from MPosIntGpsHwStatusObserver
   106 	iPosServer.NotifyModuleStatusEvent(iStatusEvent, iStatus);
   106 // -----------------------------------------------------------------------------
   107 	SetActive();
   107 //
   108 	}
   108 void CGPSWatcher::OnStatusUpdateEvent(CPosIntGpsHwStatus::TIntGpsHwStatus aStatus, TInt aError)
       
   109     {
       
   110     TRequestStatus* status = &iStatus;    
       
   111     
       
   112     // store the status from the Gps:
       
   113     iGpsStatus = aStatus;
       
   114         
       
   115     User::RequestComplete(status, aError);
       
   116 
       
   117     if( !IsActive() )
       
   118         {        
       
   119         SetActive();
       
   120         }    
       
   121     }
   109 
   122 
   110 // -----------------------------------------------------------------------------
   123 // -----------------------------------------------------------------------------
   111 // CGPSWatcher::RunL
   124 // CGPSWatcher::RunL
   112 // Inherited from CActive
   125 // Inherited from CActive
   113 // -----------------------------------------------------------------------------
   126 // -----------------------------------------------------------------------------
   114 //
   127 //
   115 void CGPSWatcher::RunL()
   128 void CGPSWatcher::RunL()
   116 	{
   129 	{
       
   130     TInt error = KErrNone;
       
   131     
   117 	// If there are errors just leave and stop watching:    
   132 	// If there are errors just leave and stop watching:    
   118 	DRMLOG2(_L("CGPSWatcher::RunL: error: '%d'"), iStatus.Int());   
   133 	DRMLOG2(_L("CGPSWatcher::RunL: status: '%d'"), iStatus.Int());   
   119     	        
   134 
   120 	// If we already updated the time:
   135     switch( iGpsStatus )
   121 	if( iTimeUpdater && iTimeUpdater->TimeReceived() )
       
   122 	    {
       
   123 	    DRMLOG( _L("CGPSWatcher::RunL: time updater exists, time received, deleting"));    
       
   124 	    iClock->Notify( CDRMClock::ENotifyGPSTimeReceived );    
       
   125 	    DRMLOG( _L("CGPSWatcher::RunL: object deleted, returning"));
       
   126 	    return;    
       
   127 	    }
       
   128 
       
   129 	// The server was killed:
       
   130     if( iStatus.Int() == KErrServerTerminated )
       
   131         {
   136         {
   132         if( iRetryCounter > KMaxRetryCounter )
   137         // GPS HW is used and is receiving location fixes.
   133             {
   138         case CPosIntGpsHwStatus::EStatusOn:
   134             DRMLOG( _L("CGPSWatcher::RunL: Maximum retries reached, stopping watcher.") );    
   139             DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Checking modules"));
   135             iClock->Notify( CDRMClock::ENotifyGPSTimeReceived );
   140             // No active modules, check again:
   136             return;         
   141             if( !iActiveSatelliteModules.Count() )
   137             }    
   142                 {
   138 	    // If there are errors just leave and stop watching:    
   143                 DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: No active modules in list Checking modules"));    
   139 	    DRMLOG2(_L("CGPSWatcher::RunL: server terminated, waiting '%d' microseconds"), KGpsDefaultWaitTime);               
   144                 error = CheckModules();    
   140         After( TTimeIntervalMicroSeconds32(KGpsDefaultWaitTime) );
   145                 }
   141         return;    
   146             
   142         }	  
   147             // if we have some or found some check the satellites for updates:    
   143 	    
   148             if( !error && iActiveSatelliteModules.Count() )
   144 	Subscribe();
   149                 {
   145 	TPositionModuleStatusEventBase::TModuleEvent occurredEvents = iStatusEvent.OccurredEvents();
   150                 DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Active modules available (%d), check satellites"), iActiveSatelliteModules.Count());                     
   146 	DRMLOG2(_L("CGPSWatcher::RunL: occurredEvents = 0x%X"), occurredEvents);
   151                 // Get the time update:
   147 	
   152                 CheckSatellites();   
   148 	
   153                 }
   149 	// If time updater is not running, check module statuses
   154             else
   150 	if(!iTimeUpdater)
   155                 {
   151 		CheckModules();
   156                 DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusOn: Still no active modules in list or error (%d) occurred"), error);                     
       
   157                 }        
       
   158             break;  
       
   159         // GPS HW is used and is searching for location.
       
   160         case CPosIntGpsHwStatus::EStatusActive:
       
   161             // Get a list of active GPS modules:
       
   162             DRMLOG(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusActive: Checking modules"));
       
   163             
       
   164             // return value not important:
       
   165             CheckModules();
       
   166             break;
       
   167         case CPosIntGpsHwStatus::EStatusUnknown:
       
   168         case CPosIntGpsHwStatus::EStatusOff:
       
   169             // Clear the list of modules:
       
   170             DRMLOG2(_L("CGPSWatcher::RunL: CPosIntGpsHwStatus::EStatusUnknown,Off or default: (%d) Checking modules"), iGpsStatus);            
       
   171             iActiveSatelliteModules.ResetAndDestroy();  
       
   172             iTimeUpdaters.ResetAndDestroy();         
       
   173         default:
       
   174             // Do nothing    
       
   175             break;   
       
   176         }		
   152 	}
   177 	}
   153 
   178 
   154 
   179 
   155 // -----------------------------------------------------------------------------
   180 // -----------------------------------------------------------------------------
   156 // CGPSWatcher::DoCancel
   181 // CGPSWatcher::DoCancel
   157 // Inherited from CActive
   182 // Inherited from CActive
   158 // -----------------------------------------------------------------------------
   183 // -----------------------------------------------------------------------------
   159 //
   184 //
   160 void CGPSWatcher::DoCancel()
   185 void CGPSWatcher::DoCancel()
   161 	{
   186 	{
   162 	iPosServer.CancelRequest(EPositionServerNotifyModuleStatusEvent);
       
   163 	}
   187 	}
   164 
   188 
   165 // -----------------------------------------------------------------------------
   189 // -----------------------------------------------------------------------------
   166 // CGPSWatcher::RunError
   190 // CGPSWatcher::RunError
   167 // Inherited from CActive
   191 // Inherited from CActive
   176 // -----------------------------------------------------------------------------
   200 // -----------------------------------------------------------------------------
   177 // CGPSWatcher::CheckModules
   201 // CGPSWatcher::CheckModules
   178 // Check what modules are present and act accordingly
   202 // Check what modules are present and act accordingly
   179 // -----------------------------------------------------------------------------
   203 // -----------------------------------------------------------------------------
   180 //
   204 //
   181 void CGPSWatcher::CheckModules()
   205 TInt CGPSWatcher::CheckModules()
   182 	{
   206 	{
   183 	// Get number of modules
   207 	TUint numModules = 0;
   184 	TUint numModules;
   208 	TPositionModuleInfo* moduleInfo = NULL;
   185 	if(iPosServer.GetNumModules(numModules)!=KErrNone || !numModules)
   209 	TInt error = KErrNone;
   186 		return;
   210 	RPositionServer posServer;
   187 	
   211 	
   188 	// Collect all active and satellite capable modules
   212 	// Destroy the old list:
   189 	TFullName moduleName;
   213 	iActiveSatelliteModules.ResetAndDestroy();
   190 	RPointerArray<TPositionModuleInfo> satelliteModules;
   214 		    
   191 	
   215 	// open connection to the positioning server:	    
   192 	TPositionModuleInfo *moduleInfo(0);
   216     error = posServer.Connect();		    
   193 	
   217 	if( error )
   194 	for(TUint i=0; i<numModules; i++)
   218 	    {
       
   219 	    return error;    
       
   220 	    }	    
       
   221 		    
       
   222     error = posServer.GetNumModules( numModules );		    
       
   223 		    
       
   224 	if(error || !numModules)
       
   225 	    {
       
   226         DRMLOG2(_L("CheckModules: modules available (%d)"), numModules);	  
       
   227         DRMLOG2(_L("CheckModules: error code (%d)"), error);	          
       
   228       
       
   229 		return KErrNotFound;
       
   230         }
       
   231         
       
   232 	for( TUint i = 0; i < numModules; i++)
   195 		{
   233 		{
   196 		if(!moduleInfo)
   234 		if(!moduleInfo)
   197 			{
   235 			{
   198 			moduleInfo = new TPositionModuleInfo;
   236 			moduleInfo = new TPositionModuleInfo;
   199 			if(!moduleInfo)
   237             if( !moduleInfo )
   200 			    {   
   238                 {
   201 				continue;
   239                 // in practice OOM situation
   202 			    }
   240                 posServer.Close();    
       
   241                 return KErrNoMemory;    
       
   242                 }
   203 			}
   243 			}
   204 		
   244 		
   205 		// Get module info from the server
   245 		// Get module info from the server
   206 		if(iPosServer.GetModuleInfoByIndex(i, *moduleInfo) != KErrNone)
   246 		if(posServer.GetModuleInfoByIndex(i, *moduleInfo) != KErrNone)
   207 		    {
   247 		    {
   208 			continue;
   248 			continue;
   209             }
   249             }
   210             
   250 
       
   251         DRMLOG(_L("CheckModules: Checking for internal & satellite capable"));	
       
   252                         
   211 		// Check if the module is internal and satellite capable		
   253 		// Check if the module is internal and satellite capable		
   212 		if(! (moduleInfo->DeviceLocation() & TPositionModuleInfo::EDeviceInternal) ||
   254 		if(! (moduleInfo->DeviceLocation() & TPositionModuleInfo::EDeviceInternal) ||
   213 		   ! (moduleInfo->Capabilities() & TPositionModuleInfo::ECapabilitySatellite) )
   255 		   ! (moduleInfo->Capabilities() & TPositionModuleInfo::ECapabilitySatellite) )
   214 			{
   256 			{
   215 			// Not internal or satellite capable
   257 			// Not internal or satellite capable
   216 			continue;
   258 			continue;
   217 			}
   259 			}
   218 		
   260 		
   219 		// Get module status
   261 		// Get module status and check if the module is actually active:
       
   262 
       
   263 
       
   264         DRMLOG(_L("CheckModules: Checking module status"));	
       
   265         		
   220 		TPositionModuleStatus moduleStatus;
   266 		TPositionModuleStatus moduleStatus;
   221 		if(iPosServer.GetModuleStatus(moduleStatus, moduleInfo->ModuleId()) != KErrNone)
   267 		
       
   268 		if(posServer.GetModuleStatus(moduleStatus, moduleInfo->ModuleId()) != KErrNone)
   222 		    {
   269 		    {
   223 			continue;
   270 			continue;
   224 		    }
   271 		    }
   225 		// Check if the module is active
   272 
   226 		if(moduleStatus.DeviceStatus() != TPositionModuleStatus::EDeviceActive) 
   273 		// Check if the module is active or ready as all might not use the active state:
       
   274 		if(!(moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceActive ||
       
   275 		     moduleStatus.DeviceStatus() == TPositionModuleStatus::EDeviceReady) ) 
   227 		    {
   276 		    {
   228 			continue;
   277 			continue;
   229 		    }
   278 		    }
   230 
   279 
   231 		moduleInfo->GetModuleName(moduleName);
   280 
   232 		
   281         DRMLOG(_L("CheckModules: Module is ready or active"));	
   233 		DRMLOG6( _L("Module %d: id=0x%08X, name = %S, cap=0x%08X, status=%d"), i, moduleInfo->ModuleId().iUid, &moduleName, moduleInfo->Capabilities(), moduleStatus.DeviceStatus());
       
   234 			
   282 			
   235 		// Active internal satellite device, try to append in the array
   283 		// Active internal satellite device, try to append in the array
   236 		if(satelliteModules.Append(moduleInfo) == KErrNone)
   284 		if(iActiveSatelliteModules.Append(moduleInfo) == KErrNone)
   237 		    {
   285 		    {
       
   286 		    // Set this to 0 so that on the next round a new one will be created
       
   287 		    // old one will be in the list:   
       
   288             DRMLOG2(_L("CheckModules: Appended modules to list available (%d) active now available"), iActiveSatelliteModules.Count());		     
   238 			moduleInfo = 0;
   289 			moduleInfo = 0;
   239 		    }
   290 		    }
   240 		}
   291 		}
   241 	
   292 	
   242 	delete moduleInfo;
   293 	// There is a module created which was not added, delete it.	
   243 	
   294 	if( moduleInfo )
   244 	if(satelliteModules.Count())
   295 	    {
   245 		{
   296 	    delete moduleInfo;
   246 		DRMLOG( _L("Active satellite module available") );    
   297 	    moduleInfo = NULL;    
   247 		// We have an active satellite module available
   298 	    }	
   248 		TPositionModuleId moduleId = satelliteModules[0]->ModuleId();
   299 	
   249 		
   300 	// close connection to the positioning server:    
   250 		// Just allocating/deleting the time updater will do the trick
   301 	posServer.Close();
   251 		iTimeUpdater = CGPSTimeUpdater::New(iPosServer, moduleId, iClock);
   302 	return KErrNone;
   252 		}
   303 	}
   253 	else
   304 
   254 		{
   305 
   255 		DRMLOG( _L("No active satellite modules available") );    
   306 // -----------------------------------------------------------------------------
   256 		// Delete time updater since no active GPS anymore
   307 // CGPSWatcher::CheckSatellites()
   257 		delete iTimeUpdater; iTimeUpdater = 0;
   308 // Check what modules are present and act accordingly
   258 		}
   309 // -----------------------------------------------------------------------------
   259 	
   310 //
   260 	satelliteModules.ResetAndDestroy();
   311 void CGPSWatcher::CheckSatellites()
   261 	satelliteModules.Close();
   312     {
   262 	}
   313     CGPSTimeUpdater* updater = NULL;
       
   314         
       
   315     iTimeUpdaters.ResetAndDestroy();
       
   316         
       
   317     // Start as many updaters as needed:    
       
   318     for( TInt i = 0; i < iActiveSatelliteModules.Count(); i++ )
       
   319         {
       
   320         updater = CGPSTimeUpdater::New( iActiveSatelliteModules[i]->ModuleId(), iClock );
       
   321         if( updater )
       
   322             {
       
   323             if( iTimeUpdaters.Append(updater) ) 
       
   324                 {
       
   325                 delete updater;
       
   326                 updater = NULL;    
       
   327                 }
       
   328             }
       
   329         }    
       
   330     }
       
   331     
       
   332 // End of File