idlefw/plugins/devicestatus/src/ainetworkinfolistener.cpp
branchRCL_3
changeset 30 a5a39a295112
child 31 8baec10861af
equal deleted inserted replaced
29:0efa10d348c0 30:a5a39a295112
       
     1 /*
       
     2 * Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Network info listener.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <NetworkHandlingProxy.h>
       
    20 #include <CNWSession.h>
       
    21 #include "ainetworkinfolistener.h"
       
    22 #include "ainetworkinfoobserver.h"
       
    23 #include "debug.h"
       
    24 #include <exterror.h>      // for KErrGsmMMNetworkFailure
       
    25 #include <featmgr.h>       // for FeatureManager
       
    26 
       
    27 const TInt KAiMessageCacheGranularity = 4;
       
    28 
       
    29 // ======== MEMBER FUNCTIONS ========
       
    30 
       
    31 CAiNetworkInfoListener::CAiNetworkInfoListener()
       
    32 : iKeyProperties( 0, ECmpTInt )
       
    33     {
       
    34     }
       
    35 
       
    36 
       
    37 void CAiNetworkInfoListener::ConstructL()
       
    38     {
       
    39 	//Store pointer in TLS
       
    40     User::LeaveIfError( Dll::SetTls( this ) );
       
    41 
       
    42     //Create network handling engine session.
       
    43     iSession = CreateL( *this, iInfo );
       
    44     iShowOpInd = EFalse;
       
    45     //Create message cache
       
    46     iMessageCache = new( ELeave )CArrayFixFlat
       
    47         <MNWMessageObserver::TNWMessages>( KAiMessageCacheGranularity );
       
    48     }
       
    49 
       
    50 
       
    51 CAiNetworkInfoListener* CAiNetworkInfoListener::InstanceL()
       
    52     {
       
    53     CAiNetworkInfoListener* self = static_cast<CAiNetworkInfoListener*>( Dll::Tls() );
       
    54 
       
    55     if( !self )
       
    56         {
       
    57 		//If instance of network listener is not already constructed, create it
       
    58         self = new( ELeave ) CAiNetworkInfoListener;
       
    59         CleanupStack::PushL( self );
       
    60         self->ConstructL();
       
    61         CleanupStack::Pop( self );
       
    62         }
       
    63 
       
    64 	//increase access count
       
    65     self->IncAccessCount();
       
    66     return self;
       
    67     }
       
    68 
       
    69 
       
    70 void CAiNetworkInfoListener::Release()
       
    71     {
       
    72 	//Decrease access count, if it goes to zero, delete object.
       
    73     if( !DecAccessCount() )
       
    74         {
       
    75         delete this;
       
    76         }
       
    77     }
       
    78 
       
    79 
       
    80 CAiNetworkInfoListener::~CAiNetworkInfoListener()
       
    81     {
       
    82 	//Remove object from TLS
       
    83     Dll::SetTls( NULL );
       
    84     iObservers.Reset();
       
    85     delete iSession;
       
    86     delete iMessageCache;
       
    87     }
       
    88 
       
    89 
       
    90 TInt CAiNetworkInfoListener::IncAccessCount()
       
    91     {
       
    92     return iAccessCount++;
       
    93     }
       
    94 
       
    95 TInt CAiNetworkInfoListener::DecAccessCount()
       
    96     {
       
    97     return --iAccessCount;
       
    98     }
       
    99 
       
   100 
       
   101 void CAiNetworkInfoListener::AddObserverL( MAiNetworkInfoObserver& aObserver )
       
   102     {
       
   103 	//Removing observer doesn't remove slots from array, removed observers are only
       
   104 	//set to NULL. Reason for this is found out later on the code. Adding observer
       
   105 	//first tries to find free slot, if it is not found, observer is appended to the
       
   106 	//array.
       
   107     TInt freeSlot = iObservers.Find( NULL );
       
   108 
       
   109     if( freeSlot == KErrNotFound )
       
   110         {
       
   111         User::LeaveIfError( iObservers.Append( &aObserver ) );
       
   112         }
       
   113     else
       
   114         {
       
   115         User::LeaveIfError( iObservers.Insert( &aObserver, freeSlot ) );
       
   116         }
       
   117     }
       
   118 
       
   119 void CAiNetworkInfoListener::RemoveObserver( MAiNetworkInfoObserver& aObserver )
       
   120     {
       
   121 	//Remove observer, removing is done by replacing it with NULL pointer.
       
   122     const TInt count( iObservers.Count() );
       
   123 
       
   124     for( TInt i( 0 ); i < count; i++ )
       
   125         {
       
   126         if( iObservers[i] == &aObserver )
       
   127             {
       
   128             //replace it with NULL
       
   129             iObservers.Remove( i );
       
   130             iObservers.Insert( NULL, i );
       
   131             break;
       
   132             }
       
   133         }
       
   134     }
       
   135 
       
   136 
       
   137 const TNWInfo& CAiNetworkInfoListener::NetworkInfo() const
       
   138     {
       
   139     return iInfo;
       
   140     }
       
   141 
       
   142 TBool CAiNetworkInfoListener::IsOperatorIndicatorAllowed() const
       
   143     {
       
   144     return iShowOpInd;
       
   145     }
       
   146 
       
   147 TBool CAiNetworkInfoListener::MessageReceived( MNWMessageObserver::TNWMessages aMessage )
       
   148     {
       
   149 	//check if the message is in message cache.
       
   150     TInt index( KErrNotFound );
       
   151     TBool found = ( iMessageCache->FindIsq( aMessage, iKeyProperties, index ) == 0 );
       
   152     return found;
       
   153     }
       
   154 
       
   155 
       
   156 void CAiNetworkInfoListener::HandleNetworkMessage( const TNWMessages aMessage )
       
   157     {
       
   158     __PRINT(__DBG_FORMAT("XAI: Handle NW message %d"), aMessage );
       
   159     //Insert message into the message cache. Only one messsage of one type.
       
   160     TRAPD( err, iMessageCache->InsertIsqL( aMessage, iKeyProperties ) );
       
   161     if( err == KErrAlreadyExists )
       
   162         {
       
   163         err = KErrNone;
       
   164         }
       
   165     if( err != KErrNone )
       
   166         {
       
   167         return;
       
   168         }
       
   169 
       
   170 	iShowOpInd 		= !NotAllowedToDisplayOperatorIndicator( aMessage );
       
   171 
       
   172 	TBool hasNetInfoChanged = HasNetworkInfoChanged( aMessage );
       
   173 	if ( !hasNetInfoChanged )
       
   174 		{
       
   175 		return;
       
   176 		}
       
   177 	__PRINT(__DBG_FORMAT("XAI: Show operator indicator %d, info changed %d"), iShowOpInd, hasNetInfoChanged );
       
   178     const TInt count( iObservers.Count() );
       
   179 
       
   180 
       
   181     for( TInt i( 0 ); i < count; i++ )
       
   182         {
       
   183 		//Observer might be NULL. When HandleNetworkInfoChange is called, it may
       
   184 		//cause deleting of the publisher which means that observer is removed from listener.
       
   185 		//This is the reason why observer pointers are replaced by NULL when it is removed
       
   186 		//from this listener. If the slot would be removed, it would easily cause index overflow
       
   187 		//or missing HandleNetworkInfoChange calls.
       
   188 		//For example lets assume that we have 5 observers, we are going in loop 3, so variable i
       
   189 		//has value 2. When third call is done, it would cause two publishers to be deleted and
       
   190 		//observers removed. Lets assume that these observers are in place 0 and 1. So now we have
       
   191 		//only 3 observers and the count is still 2. So we miss a call to a observers in index 3 and 4.
       
   192 
       
   193         if( iObservers[i] )
       
   194             {
       
   195             iObservers[i]->HandleNetworkInfoChange( aMessage, iInfo, iShowOpInd );
       
   196             }
       
   197         }
       
   198     }
       
   199 
       
   200 
       
   201 void CAiNetworkInfoListener::HandleNetworkError( const TNWOperation aOperation, TInt aErrorCode )
       
   202     {
       
   203     __PRINT(__DBG_FORMAT("XAI: Error code %d"), aErrorCode );
       
   204 
       
   205     TNWMessages errorCode = TNWMessages( KErrGeneral );
       
   206 
       
   207     switch ( aOperation )
       
   208         {
       
   209         case MNWMessageObserver::ENWGetNetworkProviderName:
       
   210             iReceivedMessageFlags |= ENetworkProviderNameReceived;
       
   211             iReceivedMessageFlags &= ~ENetworkProviderNameOk;
       
   212             iInfo.iNPName.Zero();
       
   213             __PRINTS("XAI: NPN error received");
       
   214             break;
       
   215         case MNWMessageObserver::ENWGetProgrammableOperatorName:
       
   216             iReceivedMessageFlags |= EProgrammableOperatorInfoReceived;
       
   217             iReceivedMessageFlags &= ~EProgrammableOperatorInfoReceivedOk;
       
   218             iInfo.iOperatorNameInfo.iName.Zero();
       
   219             __PRINTS("XAI: PON error received");
       
   220             break;
       
   221         case MNWMessageObserver::ENWGetServiceProviderName:
       
   222             iReceivedMessageFlags |= EServiceProviderNameReceived;
       
   223             iReceivedMessageFlags &= ~EServiceProviderNameOk;
       
   224             iInfo.iServiceProviderNameDisplayReq = RMobilePhone::KDisplaySPNNotRequired;
       
   225             iInfo.iSPName.Zero();
       
   226             iInfo.iPLMNField.Zero();
       
   227             __PRINTS("XAI: SPN error received");
       
   228             break;
       
   229         case MNWMessageObserver::ENWNotifyNetworkRegistrationStatusChange:
       
   230             if ( FeatureManager::FeatureSupported( KFeatureIdFfManualSelectionPopulatedPlmnList )
       
   231                  && ( KErrGsmMMNetworkFailure == aErrorCode ) )
       
   232                 {
       
   233                 errorCode = static_cast<TNWMessages>( aErrorCode );
       
   234                 }
       
   235             __PRINTS("XAI: ENWNotifyNetworkRegistrationStatusChange error received");
       
   236 
       
   237         break;
       
   238         default:
       
   239             break;
       
   240         }
       
   241 
       
   242     HandleNetworkMessage( errorCode );
       
   243     }
       
   244 
       
   245 TBool CAiNetworkInfoListener::NotAllowedToDisplayOperatorIndicator( const TNWMessages aMessage )
       
   246 	{
       
   247 	// Service provider name must have been fetched.
       
   248     // Network provider name must have been fetched.
       
   249     // Registration status and network information must have been received.
       
   250     // Operator name information must have been received.
       
   251     // Device must be camped to a network.
       
   252     // CS registration should be completed (only valid in AT&T NW)
       
   253 
       
   254 	switch ( aMessage )
       
   255     	{
       
   256         case MNWMessageObserver::ENWMessageNetworkInfoChange:
       
   257             iReceivedMessageFlags |= ENetworkInfoChangeReceived;
       
   258             break;
       
   259         case MNWMessageObserver::ENWMessageNetworkRegistrationStatusChange:
       
   260             iReceivedMessageFlags |= ERegistrationStatusReceived;
       
   261             break;
       
   262         case MNWMessageObserver::ENWMessageNetworkProviderNameChange:
       
   263             iReceivedMessageFlags |= 
       
   264                 ( ENetworkProviderNameReceived + ENetworkProviderNameOk );
       
   265             break;
       
   266         case MNWMessageObserver::ENWMessageServiceProviderNameChange:
       
   267             iReceivedMessageFlags |= 
       
   268                 ( EServiceProviderNameReceived + EServiceProviderNameOk );
       
   269             break;
       
   270         case MNWMessageObserver::ENWMessageProgrammableOperatorInfoChange:
       
   271             iReceivedMessageFlags |= 
       
   272                 ( EProgrammableOperatorInfoReceived + 
       
   273                   EProgrammableOperatorInfoReceivedOk );
       
   274             break;
       
   275         case MNWMessageObserver::ENWMessageNetworkProviderNameUpdating:
       
   276             iReceivedMessageFlags &= 
       
   277                 ~( ENetworkProviderNameReceived + ENetworkProviderNameOk );
       
   278             break;
       
   279         case MNWMessageObserver::ENWMessageServiceProviderNameUpdating:
       
   280             iReceivedMessageFlags &= 
       
   281                 ~( EServiceProviderNameReceived + EServiceProviderNameOk );
       
   282             break;
       
   283         case MNWMessageObserver::ENWMessageProgrammableOperatorInfoUpdating:
       
   284             iReceivedMessageFlags &= 
       
   285                 ~( EProgrammableOperatorInfoReceived + 
       
   286                    EProgrammableOperatorInfoReceivedOk );
       
   287             break;
       
   288         case MNWMessageObserver::ENWMessageDynamicCapsChange:
       
   289             TRAPD(fmerr, FeatureManager::InitializeLibL());
       
   290             if ( fmerr == KErrNone )
       
   291                 {
       
   292                 if( FeatureManager::FeatureSupported( 
       
   293                     KFeatureIdFfDisplayNetworkNameAfterCsRegistration ))
       
   294                     {
       
   295                     // CS flag is EFalse, alpha tag should not be shown.
       
   296                     if ( !( RPacketService::KCapsRxCSCall & 
       
   297                             iInfo.iDynamicCapsFlags ) )
       
   298                         {
       
   299                         __PRINTS("XAI: CS registration failed");
       
   300                         iReceivedMessageFlags |= ECSRegistrationNotOk;
       
   301                         }
       
   302                     else
       
   303                         {
       
   304                         __PRINTS("XAI: CS registration ok");
       
   305                         iReceivedMessageFlags &= ~ECSRegistrationNotOk;
       
   306                         }
       
   307                     }
       
   308                 FeatureManager::UnInitializeLib();
       
   309                 }
       
   310             break;
       
   311         default:
       
   312             break;
       
   313         }
       
   314     
       
   315     TBool serviceProviderNameFetched( EServiceProviderNameReceived & iReceivedMessageFlags );
       
   316     TBool networkProviderNameFetched( ENetworkProviderNameReceived & iReceivedMessageFlags );
       
   317     TBool registrationStatusReceived( ERegistrationStatusReceived & iReceivedMessageFlags );
       
   318     TBool networkInformationReceived( ENetworkInfoChangeReceived & iReceivedMessageFlags );
       
   319     TBool operatorNameInformationReceived(
       
   320     	 EProgrammableOperatorInfoReceived & iReceivedMessageFlags );  
       
   321     TBool currentNetworkOk( 
       
   322     	( ENetworkInfoChangeReceived  & iReceivedMessageFlags ) && 
       
   323         ( ERegistrationStatusReceived & iReceivedMessageFlags ) &&
       
   324         ( iInfo.iStatus == ENWStatusCurrent ) );  
       
   325     TBool csAlphaFlag( ECSRegistrationNotOk & iReceivedMessageFlags );
       
   326       
       
   327   	return
       
   328         !serviceProviderNameFetched ||
       
   329         !networkProviderNameFetched ||
       
   330         !( registrationStatusReceived && networkInformationReceived 
       
   331         	&& operatorNameInformationReceived ) ||
       
   332         !currentNetworkOk || csAlphaFlag;
       
   333 	}
       
   334 
       
   335 
       
   336 TBool CAiNetworkInfoListener::HasNetworkInfoChanged( const TNWMessages aMessage )
       
   337     {
       
   338     TBool result = ETrue;
       
   339     
       
   340     // pass through
       
   341    	if ( aMessage == MNWMessageObserver::ENWMessageCurrentHomeZoneMessage 	||
       
   342    	 	 aMessage == MNWMessageObserver::ENWMessageNetworkConnectionFailure	||
       
   343    	 	 aMessage == MNWMessageObserver::ENWMessageCurrentCellInfoMessage ||
       
   344    	 	 aMessage == static_cast<TNWMessages>( KErrGsmMMNetworkFailure )
       
   345        )
       
   346    		{
       
   347    		return result;
       
   348    		}
       
   349     
       
   350     result = ( iReceivedMessageFlags != iOldReceivedMessageFlags );
       
   351     
       
   352     if ( !result )
       
   353         {
       
   354         // Check if contents of iInfo has changed. Most probable to the 
       
   355         // beginning of the expression.
       
   356         result = 
       
   357             iInfo.iRegistrationStatus != iOldInfo.iRegistrationStatus ||
       
   358             iInfo.iStatus != iOldInfo.iStatus ||
       
   359             iInfo.iCountryCode != iOldInfo.iCountryCode ||
       
   360             iInfo.iNetworkId != iOldInfo.iNetworkId ||
       
   361             iInfo.iOperatorNameInfo.iType != 
       
   362                 iOldInfo.iOperatorNameInfo.iType ||
       
   363             iInfo.iOperatorNameInfo.iName != 
       
   364                 iOldInfo.iOperatorNameInfo.iName ||
       
   365             iInfo.iDisplayTag != iOldInfo.iDisplayTag ||
       
   366             iInfo.iShortName != iOldInfo.iShortName ||
       
   367             iInfo.iLongName != iOldInfo.iLongName ||
       
   368             iInfo.iSPName != iOldInfo.iSPName ||
       
   369             iInfo.iServiceProviderNameDisplayReq != 
       
   370                 iOldInfo.iServiceProviderNameDisplayReq ||
       
   371             iInfo.iNPName != iOldInfo.iNPName ||
       
   372             iInfo.iPLMNField != iOldInfo.iPLMNField;
       
   373         TRAPD(fmerr, FeatureManager::InitializeLibL());
       
   374         if ( fmerr == KErrNone )
       
   375             {
       
   376             if( FeatureManager::FeatureSupported( 
       
   377                 KFeatureIdFfDisplayNetworkNameAfterCsRegistration ))
       
   378                 {
       
   379                     result = result || 
       
   380                         iInfo.iDynamicCapsFlags != iOldInfo.iDynamicCapsFlags;
       
   381                 }
       
   382             FeatureManager::UnInitializeLib();
       
   383             }
       
   384         }
       
   385 
       
   386     iOldReceivedMessageFlags = iReceivedMessageFlags;
       
   387     iOldInfo = iInfo;
       
   388 
       
   389     return result;
       
   390     }
       
   391