usbengines/usbwatcher/src/cusbwatcher.cpp
changeset 0 1e05558e2206
child 3 47c263f7e521
equal deleted inserted replaced
-1:000000000000 0:1e05558e2206
       
     1 /*
       
     2 * Copyright (c) 2006-2009 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:  This implements CUsbWatcher class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <ecom/ecom.h>
       
    20 #include <utf.h>
       
    21 #include <coreapplicationuisdomainpskeys.h>
       
    22 //CleanupResetAndDestroyPushL
       
    23 #include <mmf/common/mmfcontrollerpluginresolver.h>
       
    24 #include <UsbWatcherInternalCRKeys.h>
       
    25 #include <cusbpersonalitynotifier.h>
       
    26 #include <UsbWatcherInternalPSKeys.h>
       
    27 #include <e32property.h>
       
    28 #include <startupdomainpskeys.h> //for global system state
       
    29 
       
    30 #include "cusbwatcher.h"
       
    31 #include "cusbactivestate.h"
       
    32 #include "cusbactivepersonalityhandler.h"
       
    33 #include "cusbwatchersession.h"
       
    34 #include "cusbdevicelock.h"
       
    35 #include "cusbdevconstarter.h"
       
    36 #include "cusbglobalsystemstateobserver.h"
       
    37 #include "cusbotgwatcher.h"
       
    38 
       
    39 _LIT_SECURITY_POLICY_PASS( KAlwaysPassPolicy );
       
    40 _LIT_SECURITY_POLICY_C1( KLocalServicesPolicy, ECapabilityLocalServices );
       
    41 
       
    42 const TUint32 KUsbWatcherUseSerialNumber = 0x80000000;
       
    43 const TUint32 KUsbWatcherPersonalityIdMask = 0x0000FFFF;
       
    44 
       
    45 // ============================ MEMBER FUNCTIONS ==============================
       
    46 
       
    47 // ----------------------------------------------------------------------------
       
    48 // C++ default constructor can NOT contain any code, that might leave.
       
    49 // ----------------------------------------------------------------------------
       
    50 //
       
    51 CUsbWatcher::CUsbWatcher()
       
    52     : CActive( EPriorityStandard )
       
    53     {
       
    54     LOG_FUNC
       
    55 
       
    56     CActiveScheduler::Add( this );
       
    57     }
       
    58 
       
    59 // ----------------------------------------------------------------------------
       
    60 // Symbian 2nd phase constructor can leave.
       
    61 // ----------------------------------------------------------------------------
       
    62 //
       
    63 void CUsbWatcher::ConstructL()
       
    64     {
       
    65     LOG_FUNC
       
    66 
       
    67     LEAVEIFERROR( RProperty::Define( KPSUidUsbWatcher,
       
    68             KUsbWatcherSelectedPersonality, RProperty::EInt, KAlwaysPassPolicy,
       
    69             KLocalServicesPolicy ) );
       
    70 
       
    71     LEAVEIFERROR( RProperty::Set( KPSUidUsbWatcher,
       
    72             KUsbWatcherSelectedPersonality,
       
    73             KUsbWatcherSelectedPersonalityNone ) );
       
    74 
       
    75     iPersonalityRepository = CRepository::NewL( KCRUidUsbWatcher );
       
    76 
       
    77     LEAVEIFERROR( iPersonalityRepository->Get( KUsbWatcherPersonality,
       
    78             iPersonalityId ) );
       
    79     LOG1( "iPersonalityId from CenRep = %d", iPersonalityId );
       
    80     iPrevPersonalityId = iPersonalityId;
       
    81     iOldPrevPersonalityId = iPersonalityId;
       
    82     LEAVEIFERROR( iUsbMan.Connect() );
       
    83 
       
    84     TInt ret = iUsbMan.SetCtlSessionMode( ETrue );
       
    85     if( KErrNone == ret )
       
    86         {
       
    87         LOG( "Creating CUsbOtgWatcher..."  );
       
    88         iOtgWatcher = CUsbOtgWatcher::NewL( iUsbMan );
       
    89         }
       
    90     else if( KErrNotSupported == ret )
       
    91         {
       
    92         LOG( "Non-OTG configuration detected!"  );
       
    93         }
       
    94     else
       
    95         {
       
    96         LOG( "ERROR: is there another USB Control process? LEAVE" );
       
    97         LEAVE( ret );
       
    98         }
       
    99 
       
   100     iPersonalityHandler
       
   101         = CUsbActivePersonalityHandler::NewL( iUsbMan, *this );
       
   102 
       
   103     GetPersonalityPluginsL();
       
   104     iUsbDeviceLock = CUsbDeviceLock::NewL( *this );
       
   105     iUsbDeviceLock->Subscribe();
       
   106     iGlobalStateObserver = CUsbGlobalSystemStateObserver::NewL( *this );
       
   107     iUsbDevConStarter = CUsbDevConStarter::NewL();
       
   108     iActiveState = CUsbActiveState::NewL( iUsbMan, *this );
       
   109     }
       
   110 
       
   111 // ----------------------------------------------------------------------------
       
   112 // Two-phased constructor.
       
   113 // ----------------------------------------------------------------------------
       
   114 //
       
   115 CUsbWatcher* CUsbWatcher::NewL()
       
   116     {
       
   117     LOG_FUNC
       
   118 
       
   119     CUsbWatcher* self = new ( ELeave ) CUsbWatcher();
       
   120     CleanupStack::PushL( self );
       
   121     self->ConstructL();
       
   122     CleanupStack::Pop(); // pop self
       
   123     return self;
       
   124     }
       
   125 
       
   126 // ----------------------------------------------------------------------------
       
   127 // Destructor.
       
   128 // ----------------------------------------------------------------------------
       
   129 //
       
   130 CUsbWatcher::~CUsbWatcher()
       
   131     {
       
   132     LOG_FUNC
       
   133 
       
   134     RProperty::Delete( KPSUidUsbWatcher, KUsbWatcherSelectedPersonality );
       
   135 
       
   136     iUsbMan.Close();
       
   137     iObservers.Reset();
       
   138     if( iUsbDeviceLock )
       
   139         {
       
   140         iUsbDeviceLock->Cancel();
       
   141         }
       
   142     delete iActiveState;
       
   143     delete iUsbDevConStarter;
       
   144     delete iPersonalityHandler;
       
   145     delete iPersonalityRepository;
       
   146     delete iOtgWatcher;
       
   147     delete iUsbDeviceLock;
       
   148     delete iGlobalStateObserver;
       
   149     iSupportedPersonalities.Close();
       
   150     }
       
   151 
       
   152 // ----------------------------------------------------------------------------
       
   153 // Get personality plugins. Note that this is done only in normal mode.
       
   154 // ----------------------------------------------------------------------------
       
   155 //
       
   156 void CUsbWatcher::GetPersonalityPluginsL()
       
   157     {
       
   158     LOG_FUNC
       
   159     
       
   160     // Get personality plugins
       
   161     RImplInfoPtrArray implementations;
       
   162     CleanupResetAndDestroyPushL( implementations );
       
   163 
       
   164     const TEComResolverParams noResolverParams;
       
   165 
       
   166     REComSession::ListImplementationsL( KUidPersonalityPlugIns,
       
   167             noResolverParams, KRomOnlyResolverUid, implementations );
       
   168     TInt personalityNum = implementations.Count();
       
   169     LOG1( "Number of PersonalityPlugin(s): %d", personalityNum );
       
   170     
       
   171     if( personalityNum < 1 )
       
   172         {
       
   173         LOG( "No PersonalityPlugin available. LEAVE" );
       
   174         LEAVE( KErrGeneral );
       
   175         }
       
   176 
       
   177     for( TInt i = 0; i < personalityNum; i++ )
       
   178         {
       
   179         TUsbSupportedPersonalityInf inf;
       
   180         TLex8 lex;
       
   181         TUint32 confValue;
       
   182 
       
   183         // save implementation uid
       
   184         inf.iPersonalityUid = implementations[i]->ImplementationUid();
       
   185         lex.Assign( implementations[i]->DataType() );
       
   186 
       
   187         if( lex.Val( confValue, EHex ) != KErrNone )
       
   188             {
       
   189             CleanupStack::PopAndDestroy( &implementations );
       
   190             iSupportedPersonalities.Close();
       
   191             LEAVE( KErrGeneral );
       
   192             }
       
   193 
       
   194         // check whether personality requires serial number
       
   195         if( confValue & KUsbWatcherUseSerialNumber )
       
   196             {
       
   197             inf.iUseSerialNumber = ETrue;
       
   198             }
       
   199         else
       
   200             {
       
   201             inf.iUseSerialNumber = EFalse;
       
   202             }
       
   203 
       
   204         // save personality id
       
   205         inf.iPersonalityId = static_cast<TInt>( ( KUsbWatcherPersonalityIdMask
       
   206                 & confValue ) );
       
   207 
       
   208         LOG1( "PersonalityId = %d" , inf.iPersonalityId );
       
   209 
       
   210         iSupportedPersonalities.AppendL( inf );
       
   211         }
       
   212 
       
   213     CleanupStack::PopAndDestroy( &implementations );
       
   214     }
       
   215 
       
   216 // ----------------------------------------------------------------------------
       
   217 // This method notifies CUsbWatcher class about USB state changes.
       
   218 // ----------------------------------------------------------------------------
       
   219 //
       
   220 void CUsbWatcher::StateChangeNotify( TUsbDeviceState aStateOld,  
       
   221         TUsbDeviceState aStateNew )
       
   222     {
       
   223     LOG_FUNC
       
   224 
       
   225     if( IsDeviceA() ) // Will be handled by UsbOtgWatcher
       
   226         {
       
   227         LOG( "Device state change ignored by UsbWatcher in A-device state" );
       
   228         return;
       
   229         }
       
   230 
       
   231     LOG1( "WatcherState = %d", iState );
       
   232         
       
   233     // Notify personality handler first
       
   234     switch( aStateNew )
       
   235         {
       
   236         case EUsbDeviceStatePowered:
       
   237             // Case for Attached state missed 
       
   238             // NO break here;
       
   239         case EUsbDeviceStateAttached:
       
   240             {
       
   241             if( EUsbDeviceStateUndefined != aStateOld )
       
   242                 {
       
   243                 LOG1( "Not starting personality, previous state: %d", 
       
   244                     aStateOld);
       
   245                 break;
       
   246                 }
       
   247 			LOG1( "Starting USB personality in device state: %d", aStateNew );
       
   248             iPersonalityHandler->StateChangeNotify( aStateOld, aStateNew );
       
   249             // Check AskOnConnection setting every time
       
   250             if( ( iSupportedPersonalities.Count() > 1 ) &&
       
   251                     !IsAskOnConnectionSuppression() )
       
   252                 {
       
   253                 // read setting if there is more than one personality
       
   254                 iPersonalityRepository->Get(
       
   255                         KUsbWatcherChangeOnConnectionSetting,
       
   256                         iAskOnConnectionSetting );
       
   257                 }
       
   258 
       
   259             if( ( iState == EUsbIdle ) && !iPersonalityChangeOngoing )
       
   260                 {
       
   261                 Start();
       
   262                 }
       
   263             else if( ( iState != EUsbStarted ) && !iPersonalityChangeOngoing )
       
   264                 {
       
   265                 Cancel();
       
   266                 Start();
       
   267                 }
       
   268 
       
   269             // Let's turn ask on connection off after start cause we will
       
   270             // issue it only when cable is connected
       
   271             iAskOnConnectionSetting = KUsbWatcherChangeOnConnectionOff;
       
   272 
       
   273             //start usbdevcon only in normal global state
       
   274             TInt globalState =
       
   275                     CUsbGlobalSystemStateObserver::GlobalSystemState();
       
   276             if( ( ESwStateNormalRfOn == globalState ) ||
       
   277                     ( ESwStateNormalRfOff == globalState ) ||
       
   278                     ( ESwStateNormalBTSap == globalState ) )
       
   279                 {
       
   280                 iUsbDevConStarter->Start();
       
   281                 }
       
   282             }
       
   283             break;
       
   284 
       
   285         case EUsbDeviceStateUndefined:
       
   286             {
       
   287             iGlobalStateObserver->Cancel();
       
   288             // Notify clients currently loaded personality will be unloaded
       
   289             iPersonalityHandler->StateChangeNotify( aStateOld, aStateNew );
       
   290             iUsbDevConStarter->StopRestarting();
       
   291             // This must be done before Notify()
       
   292             if( iSetPreviousPersonalityOnDisconnect )
       
   293                 {
       
   294                 TInt temp = iPersonalityId;
       
   295                 iPersonalityId = iPrevPersonalityId;
       
   296                 iPrevPersonalityId = temp;
       
   297                 WritePersonalityId( iPersonalityId );
       
   298                 iSetPreviousPersonalityOnDisconnect = EFalse;
       
   299                 }
       
   300 
       
   301             Notify( KErrCancel );
       
   302             if (iState == EUsbStarting)
       
   303                 {
       
   304                 LOG( "StartCancel USB" );
       
   305                 Cancel();
       
   306                 }
       
   307             else
       
   308                 {
       
   309                 LOG( "Stop USB" );
       
   310                 
       
   311                 if( EUsbConfirmStop == iState )
       
   312                     {
       
   313                     // We have request pending on personality handler
       
   314                     Cancel();
       
   315                     }
       
   316                 
       
   317                     Stop();
       
   318                     }
       
   319             }
       
   320             break;
       
   321 
       
   322         default:
       
   323             if ( EUsbStarted == iState )
       
   324                 {
       
   325                 iPersonalityHandler->StateChangeNotify( aStateOld, aStateNew );
       
   326                 }
       
   327             break;
       
   328         }
       
   329     }
       
   330 
       
   331 // ----------------------------------------------------------------------------
       
   332 // From class CActive.
       
   333 // This method cancels any outstanding request.
       
   334 // ----------------------------------------------------------------------------
       
   335 //
       
   336 void CUsbWatcher::DoCancel()
       
   337     {
       
   338     LOG_FUNC
       
   339 
       
   340     LOG1( "WatcherState = %d", iState );
       
   341     if( ( EUsbStarting == iState ) || ( EUsbStopping == iState ) )
       
   342         {
       
   343         iPersonalityHandler->Cancel();
       
   344 
       
   345         RProperty::Set( KPSUidUsbWatcher,
       
   346                 KUsbWatcherSelectedPersonality,
       
   347                 KUsbWatcherSelectedPersonalityNone );
       
   348         LOG( "personality set to none" );
       
   349 
       
   350         iState = EUsbIdle;
       
   351         }
       
   352     else if( EUsbConfirmStop == iState )
       
   353         {
       
   354         iPersonalityHandler->Cancel();
       
   355         iState = EUsbStarted;
       
   356         }
       
   357     else
       
   358         {
       
   359         LOG( "Nothingh to cancel" );
       
   360         }
       
   361     }
       
   362 
       
   363 // ----------------------------------------------------------------------------
       
   364 // This method implements state machine for personality start and stop.
       
   365 // ----------------------------------------------------------------------------
       
   366 //
       
   367 void CUsbWatcher::RunL()
       
   368     {
       
   369     LOG_FUNC
       
   370 
       
   371     LOG1( "WatcherState = %d", iState );
       
   372     TInt ret = iStatus.Int();
       
   373     if ( KErrNone != ret  )
       
   374         {
       
   375         LOG1( "ERROR: CUsbWatcher::RunL iStatus = %d", ret );
       
   376         }
       
   377 
       
   378     switch ( iState )
       
   379         {
       
   380         case EUsbStarting:
       
   381             LOG( "Personality started" );
       
   382             Notify( ret );
       
   383             iState = EUsbStarted;
       
   384             if( iStopStartScenario )
       
   385                 {
       
   386                 iStopStartScenario = EFalse;
       
   387                 }
       
   388             break;
       
   389 
       
   390         case EUsbStopping:
       
   391             LOG( "Personality stopped" );
       
   392             iState = EUsbIdle;
       
   393             if( iStopStartScenario )
       
   394                 {
       
   395                 Start();
       
   396                 }
       
   397             else
       
   398                 {
       
   399                 RProperty::Set( KPSUidUsbWatcher,
       
   400                     KUsbWatcherSelectedPersonality,
       
   401                     KUsbWatcherSelectedPersonalityNone );
       
   402                 }
       
   403             break;
       
   404 
       
   405         case EUsbStarted:
       
   406             if( iStopStartScenario )
       
   407                 {
       
   408                 break;
       
   409                 }
       
   410 
       
   411             iPersonalityHandler->StopPersonality( iStatus );
       
   412             SetActive();
       
   413             iState = EUsbStopping;
       
   414             break;
       
   415 
       
   416         case EUsbIdle:
       
   417             if( iStopStartScenario )
       
   418                 {
       
   419                 Start();
       
   420                 }
       
   421             break;
       
   422 
       
   423         case EUsbConfirmStop:
       
   424             if( iStatus == KErrNone )
       
   425                 {
       
   426                 iStopStartScenario = ETrue;
       
   427                 iPersonalityHandler->StopPersonality( iStatus );
       
   428                 SetActive();
       
   429                 iState = EUsbStopping;
       
   430                 }
       
   431             else
       
   432                 {
       
   433                 Notify( ret );
       
   434                 iState = EUsbStarted;
       
   435                 }
       
   436             break;
       
   437 
       
   438         default:
       
   439             LOG( "ERROR: unexpected state" );
       
   440             PANIC( KErrGeneral );
       
   441             break;
       
   442         }
       
   443     }
       
   444 
       
   445 // ----------------------------------------------------------------------------
       
   446 // This method is not called cause RunL() never leaves.
       
   447 // ----------------------------------------------------------------------------
       
   448 //
       
   449 TInt CUsbWatcher::RunError(TInt /*aError*/)
       
   450     {
       
   451     LOG_FUNC
       
   452     // Left empty cause this can't happend
       
   453     return KErrNone;
       
   454     }
       
   455 
       
   456 // ----------------------------------------------------------------------------
       
   457 // Function is called when state of the device is locked.
       
   458 // ----------------------------------------------------------------------------
       
   459 //
       
   460 void CUsbWatcher::Lock()
       
   461     {
       
   462     LOG_FUNC
       
   463 
       
   464     if( IsDeviceA() ) // Not applicable in case of A-device
       
   465         {
       
   466         LOG( "Lock ignored in A-device state" );
       
   467         return;
       
   468         }
       
   469 
       
   470     
       
   471     TUsbDeviceState state = iActiveState->CurrentState();
       
   472 
       
   473     LOG1( "USB device state after lock: %d", state );
       
   474 
       
   475     if( EUsbDeviceStateUndefined != state ) // Stop personality
       
   476         {
       
   477         LOG( "Stopping USB persoanlity on device remote-lock" );
       
   478 
       
   479         iPersonalityHandler->CancelCableConnectedNotifier();
       
   480 
       
   481         if( iState != EUsbStarted )
       
   482             {
       
   483             Cancel();
       
   484             }
       
   485         else
       
   486             {
       
   487             Stop();
       
   488             }
       
   489         }
       
   490     }
       
   491 
       
   492 // ----------------------------------------------------------------------------
       
   493 // Function is called when state of the device is unlocked.
       
   494 // ----------------------------------------------------------------------------
       
   495 //
       
   496 void CUsbWatcher::Unlock()
       
   497     {
       
   498     LOG_FUNC
       
   499 
       
   500     if( IsDeviceA() ) // Not applicable in case of A-device
       
   501         {
       
   502         LOG( "Unlock ignored in A-device state" );
       
   503         return;
       
   504         }
       
   505 
       
   506     TUsbDeviceState state = iActiveState->CurrentState();
       
   507 
       
   508     LOG1( "USB device state after unlock: %d", state );
       
   509     if( EUsbDeviceStateAttached == state || EUsbDeviceStatePowered == state)
       
   510         {
       
   511         LOG( "Starting USB personality" );
       
   512         TInt err = iPersonalityRepository->Get(
       
   513            KUsbWatcherChangeOnConnectionSetting, iAskOnConnectionSetting );
       
   514         if( KErrNone == err )
       
   515             {
       
   516             Start();
       
   517             iAskOnConnectionSetting = KUsbWatcherChangeOnConnectionOff;
       
   518             }
       
   519         else
       
   520             {
       
   521             LOG1( "Error: CRepository::Get = %d", err );
       
   522             }
       
   523         }
       
   524     }
       
   525 
       
   526 // ----------------------------------------------------------------------------
       
   527 // This method is called when client wants to set new personality.
       
   528 // ----------------------------------------------------------------------------
       
   529 //
       
   530 void CUsbWatcher::SetPersonality( TInt aPersonalityId, TBool aNonBlocking )
       
   531     {
       
   532     LOG_FUNC
       
   533 
       
   534     LOG2( "aPersonalityId=%d, aNonBlocking=%d", aPersonalityId, aNonBlocking );
       
   535 
       
   536     if( IsDeviceA() ) 
       
   537         {
       
   538         LOG( "SetPersonality not allowed in A-device state" );
       
   539         Notify( KErrAccessDenied );
       
   540         return;
       
   541         }
       
   542     
       
   543     // Check if personality is exist
       
   544     TBool found = EFalse;
       
   545 
       
   546     for( TInt i = 0; i < iSupportedPersonalities.Count(); i++ )
       
   547         {
       
   548         if( iSupportedPersonalities[i].iPersonalityId == aPersonalityId )
       
   549             {
       
   550             found = ETrue;
       
   551             }
       
   552         }
       
   553 
       
   554     if( !found )
       
   555         {
       
   556         Notify( KErrNotFound );
       
   557         return;
       
   558         }
       
   559 
       
   560     iSetPersonalityOngoing = ETrue;
       
   561     iPersonalityChangeOngoing = ETrue;
       
   562 
       
   563     //The previous personality is not changed, if the client wanted the
       
   564     //previous personality change to be temporary. The client has to call
       
   565     //SetPreviousPersonalityOnDisconnect after each SetPersonality to be
       
   566     //intended as temporary.
       
   567     if( iSetPreviousPersonalityOnDisconnect )
       
   568         {
       
   569         iSetPreviousPersonalityOnDisconnect = EFalse;
       
   570         }
       
   571     else
       
   572         {
       
   573         iOldPrevPersonalityId = iPrevPersonalityId;
       
   574         iPrevPersonalityId = iPersonalityId;
       
   575         LOG( "CUsbWatcher::SetPersonality setting previous" );
       
   576         }
       
   577     LOG1( " iPrevPersonalityId = %d", iPrevPersonalityId );
       
   578     if( iPersonalityId != aPersonalityId )
       
   579         {
       
   580         iPersonalityId = aPersonalityId;
       
   581         SwitchPersonality( aNonBlocking );
       
   582         }
       
   583     else
       
   584         {
       
   585         Notify( KErrNone );
       
   586         }
       
   587     }
       
   588 
       
   589 // ----------------------------------------------------------------------------
       
   590 // This method is called when client wants to cancel set personality.
       
   591 // ----------------------------------------------------------------------------
       
   592 //
       
   593 void CUsbWatcher::CancelSetPersonality()
       
   594     {
       
   595     LOG_FUNC
       
   596 
       
   597     Notify( KErrCancel );
       
   598     iPersonalityChangeOngoing = ETrue;
       
   599     iStopStartScenario = EFalse;
       
   600     SwitchPersonality();
       
   601     }
       
   602 
       
   603 // ----------------------------------------------------------------------------
       
   604 // This method is called when client wants to set previous personality.
       
   605 // ----------------------------------------------------------------------------
       
   606 //
       
   607 void CUsbWatcher::SetPreviousPersonality()
       
   608     {
       
   609     LOG_FUNC
       
   610 
       
   611     if( IsDeviceA() ) 
       
   612         {
       
   613         LOG( "SetPreviousPersonality not allowed in A-device state" );
       
   614         Notify( KErrAccessDenied );
       
   615         return;
       
   616         }
       
   617     
       
   618     TInt temp = iPersonalityId;
       
   619     iSetPreviousPersonalityOnDisconnect = EFalse;
       
   620 
       
   621     iPersonalityId = iPrevPersonalityId;
       
   622     iPrevPersonalityId = temp;
       
   623     iSetPreviousPersonalityOngoing = ETrue;
       
   624     iPersonalityChangeOngoing = ETrue;
       
   625 
       
   626     if( iPersonalityId != iPrevPersonalityId )
       
   627         {
       
   628         SwitchPersonality();
       
   629         }
       
   630     else
       
   631         {
       
   632         Notify( KErrNone );
       
   633         }
       
   634     }
       
   635 
       
   636 // ----------------------------------------------------------------------------
       
   637 // This method is called when client wants to cancel set previous personality.
       
   638 // ----------------------------------------------------------------------------
       
   639 //
       
   640 void CUsbWatcher::CancelSetPreviousPersonality()
       
   641     {
       
   642     LOG_FUNC
       
   643 
       
   644     Notify( KErrCancel );
       
   645     iPersonalityChangeOngoing = ETrue;
       
   646     iStopStartScenario = EFalse;
       
   647     SwitchPersonality();
       
   648     }
       
   649 
       
   650 // ----------------------------------------------------------------------------
       
   651 // This method is called when client wants to set previous personality on
       
   652 // disconnect.
       
   653 // ----------------------------------------------------------------------------
       
   654 //
       
   655 void CUsbWatcher::SetPreviousPersonalityOnDisconnect()
       
   656     {
       
   657     LOG_FUNC
       
   658 
       
   659     if( IsDeviceA() ) 
       
   660         {
       
   661         LOG( "Not allowed in A-device state" );
       
   662         Notify( KErrAccessDenied );
       
   663         return;
       
   664         }
       
   665 
       
   666     TUsbDeviceState state = iActiveState->CurrentState();
       
   667     LOG1( "Device state : %d", state );
       
   668     if( state != EUsbDeviceStateUndefined )
       
   669         {
       
   670         iSetPreviousPersonalityOnDisconnect = ETrue;
       
   671         }
       
   672     }
       
   673 
       
   674 // ----------------------------------------------------------------------------
       
   675 // This method starts personality change, if there is cable connected.
       
   676 // ----------------------------------------------------------------------------
       
   677 //
       
   678 void CUsbWatcher::SwitchPersonality( TBool aNonBlocking )
       
   679     {
       
   680     LOG_FUNC
       
   681 
       
   682     if( IsDeviceA() ) 
       
   683         {
       
   684         LOG( "Not allowed in A-device state" );
       
   685         Notify( KErrAccessDenied );
       
   686         return;
       
   687         }
       
   688 
       
   689     TUsbDeviceState state = iActiveState->CurrentState();
       
   690     LOG1( "Device state : %d", state );
       
   691 
       
   692     if( state != EUsbDeviceStateUndefined )
       
   693         {
       
   694         switch ( iState )
       
   695             {
       
   696             case EUsbStopping:
       
   697             case EUsbStarting:
       
   698                 {
       
   699                 LOG( "CUsbWatcher::SwitchPersonality: Cancel & Start USB" );
       
   700                 Cancel();
       
   701                 Start();
       
   702                 }
       
   703                 break;
       
   704             case EUsbConfirmStop:
       
   705                 {
       
   706                 Cancel();
       
   707                 iState = EUsbStarted;
       
   708                 StopStart( aNonBlocking );
       
   709                 }
       
   710                 break;
       
   711             case EUsbStarted:
       
   712                 {
       
   713                 LOG( "CUsbWatcher::SwitchPersonality: Stop & Start USB" );
       
   714                 StopStart( aNonBlocking );
       
   715                 }
       
   716                 break;
       
   717             default:
       
   718                 {
       
   719                 LOG( "CUsbWatcher::SwitchPersonality: Start USB" );
       
   720                 Start();
       
   721                 }
       
   722                 break;
       
   723             }
       
   724         }
       
   725     else
       
   726         {
       
   727         // if no connection -> just save the setting
       
   728         LOG( "CUsbWatcher::SwitchPersonality: Notify" );
       
   729         Notify( KErrNone );
       
   730         }
       
   731     }
       
   732 
       
   733 // ----------------------------------------------------------------------------
       
   734 // This method starts personality loading or continues stop start scenario.
       
   735 // ----------------------------------------------------------------------------
       
   736 //
       
   737 void CUsbWatcher::Start()
       
   738     {
       
   739     LOG_FUNC
       
   740 
       
   741     TInt globalState = CUsbGlobalSystemStateObserver::GlobalSystemState();
       
   742 
       
   743     if( iState == EUsbIdle )
       
   744         {
       
   745         iStarted = EFalse;
       
   746         if( globalState == ESwStateCharging )
       
   747             {
       
   748             LOG( "Global state: charging" );
       
   749             iGlobalStateObserver->Subscribe();
       
   750             iPrevPersonalityId=iPersonalityId;
       
   751             TInt ret = GetChargingPersonalityId( iPersonalityId );
       
   752             //do not start if charging personality not assigned
       
   753             if( KErrNone == ret )
       
   754                 {
       
   755                 RProperty::Set( KPSUidUsbWatcher,
       
   756                         KUsbWatcherSelectedPersonality, iPersonalityId );
       
   757                 iStarted = ETrue;
       
   758                 iPersonalityHandler->StartPersonality( iPersonalityId,
       
   759                     KUsbWatcherChangeOnConnectionOff, iStatus );
       
   760                 }
       
   761             else
       
   762                 {
       
   763                 LOG1( "GetChargingPersonalityId = %d. Not started", ret );
       
   764                 }
       
   765             }
       
   766         else if( ( ( ESwStateNormalRfOn == globalState ) ||
       
   767                    ( ESwStateNormalRfOff == globalState ) ||
       
   768                    ( ESwStateNormalBTSap == globalState ) ))
       
   769             {
       
   770             LOG( "Global state: normal" );
       
   771             if( ! iUsbDeviceLock->Locked() )
       
   772                 {
       
   773                 iGlobalStateObserver->Cancel();
       
   774                 RProperty::Set( KPSUidUsbWatcher,
       
   775                             KUsbWatcherSelectedPersonality, iPersonalityId );
       
   776                 iStarted = ETrue;
       
   777                 iPersonalityHandler->StartPersonality( iPersonalityId,
       
   778                         iAskOnConnectionSetting, iStatus );
       
   779                 }
       
   780             else
       
   781                 {
       
   782                 LOG( "Device LOCKED, USB personality NOT start" );
       
   783                 }
       
   784             }
       
   785         else
       
   786             {
       
   787             LOG1( "Global state: = %d", globalState );
       
   788             //Cable connected in e.g. ChargingToNormal state and
       
   789             // personality started later in a normal state.
       
   790             iGlobalStateObserver->Subscribe();
       
   791             }
       
   792         if( iStarted )
       
   793             {
       
   794             SetActive();
       
   795             iState = EUsbStarting;
       
   796             }
       
   797         }
       
   798     else
       
   799         {
       
   800         LOG( "Tryign to call CUsbWatcher::Start in non-idle state " );
       
   801         PANIC( KErrGeneral );
       
   802         }
       
   803     }
       
   804 
       
   805 // ----------------------------------------------------------------------------
       
   806 // This method starts personality unloading or cancels personality start.
       
   807 // ----------------------------------------------------------------------------
       
   808 //
       
   809 void CUsbWatcher::Stop()
       
   810     {
       
   811     LOG_FUNC
       
   812 
       
   813     LOG1( "WatcherState = %d", iState );
       
   814     if( EUsbStarted == iState )
       
   815         {
       
   816         iPersonalityHandler->StopPersonality( iStatus );
       
   817         SetActive();
       
   818         iState = EUsbStopping;
       
   819         
       
   820         }
       
   821     else if( EUsbStarting  == iState )
       
   822         {
       
   823         LOG( "Cancel ongoing start." );
       
   824         Cancel();
       
   825         }
       
   826     
       
   827     else
       
   828         {
       
   829         LOG( "Wrong state for Stop" );
       
   830         }
       
   831     }
       
   832 
       
   833 // ----------------------------------------------------------------------------
       
   834 // This method is used when there is need to change currently loaded
       
   835 // personality.
       
   836 // ----------------------------------------------------------------------------
       
   837 //
       
   838 void CUsbWatcher::StopStart( TBool aNonBlocking )
       
   839     {
       
   840     LOG_FUNC
       
   841 
       
   842     LOG1( "WatcherState = %d", iState );
       
   843     if( iState == EUsbStarted )
       
   844         {
       
   845         iState = EUsbConfirmStop;
       
   846         if( !aNonBlocking )
       
   847             {
       
   848             iPersonalityHandler->ConfirmPersonalityUnload( iStatus );
       
   849             SetActive();
       
   850             }
       
   851         else
       
   852             {
       
   853             LOG( "CUsbWatcher::StopStart not confirming" );
       
   854             SetActive();
       
   855             TRequestStatus* status = &iStatus;
       
   856             User::RequestComplete( status, KErrNone );
       
   857             }
       
   858         }
       
   859     else
       
   860         {
       
   861         LOG( "Wrong state to StopStart" );
       
   862         }
       
   863     }
       
   864 
       
   865 // ----------------------------------------------------------------------------
       
   866 // CUsbWatcherSession uses this method to register observer.
       
   867 // ----------------------------------------------------------------------------
       
   868 //
       
   869 void CUsbWatcher::RegisterObserverL( MUsbWatcherNotify* aObserver )
       
   870     {
       
   871     LOG_FUNC
       
   872 
       
   873     TInt index = iObservers.Find( aObserver );
       
   874     if( index < 0 )
       
   875         {
       
   876         iObservers.AppendL( aObserver );
       
   877         }
       
   878     }
       
   879 
       
   880 // ----------------------------------------------------------------------------
       
   881 // CUsbWatcherSession uses this method to deregister observer.
       
   882 // ----------------------------------------------------------------------------
       
   883 //
       
   884 void CUsbWatcher::DeRegisterObserver( MUsbWatcherNotify* aObserver )
       
   885     {
       
   886     LOG_FUNC
       
   887 
       
   888     TInt index = iObservers.Find( aObserver );
       
   889 
       
   890     if( index >= 0 )
       
   891         {
       
   892         iObservers.Remove( index );
       
   893         }
       
   894     }
       
   895 
       
   896 // ----------------------------------------------------------------------------
       
   897 // This method is used to complete any outstanding request.
       
   898 // ----------------------------------------------------------------------------
       
   899 //
       
   900 void CUsbWatcher::Notify( TInt aStatus )
       
   901     {
       
   902     LOG_FUNC
       
   903 
       
   904     LOG1( "aStatus = %d", aStatus );
       
   905     TInt status = aStatus;
       
   906 
       
   907     // clear every time when notified
       
   908     iPersonalityChangeOngoing = EFalse;
       
   909 
       
   910     if( iSetPersonalityOngoing || iChangePersonalityOngoing )
       
   911         {
       
   912         iSetPersonalityOngoing = EFalse;
       
   913         iChangePersonalityOngoing = EFalse;
       
   914 
       
   915         if( status == KErrNone )
       
   916             {
       
   917             status = WritePersonalityId( iPersonalityId );
       
   918             }
       
   919         else
       
   920             {
       
   921             // in case of error return to state before SetPersonality
       
   922             iPersonalityId = iPrevPersonalityId;
       
   923             iPrevPersonalityId = iOldPrevPersonalityId;
       
   924             }
       
   925         }
       
   926 
       
   927     if( iSetPreviousPersonalityOngoing )
       
   928         {
       
   929         iSetPreviousPersonalityOngoing = EFalse;
       
   930 
       
   931         if( status == KErrNone )
       
   932             {
       
   933             WritePersonalityId( iPersonalityId );
       
   934             }
       
   935         else
       
   936             {
       
   937             // in case of error return to state before SetPreviousPersonality
       
   938             TInt temp = iPrevPersonalityId;
       
   939 
       
   940             iPrevPersonalityId = iPersonalityId;
       
   941             iPersonalityId = temp;
       
   942             }
       
   943         }
       
   944 
       
   945     for( TInt i = 0; i < iObservers.Count(); i++ )
       
   946         {
       
   947         iObservers[i]->Notify( iPersonalityId, status );
       
   948         }
       
   949     }
       
   950 
       
   951 // ----------------------------------------------------------------------------
       
   952 // Stop loaded personality. Called from global state handler
       
   953 // ----------------------------------------------------------------------------
       
   954 //
       
   955 void CUsbWatcher::StopPersonality()
       
   956     {
       
   957     LOG_FUNC
       
   958     // restore settings
       
   959     iPersonalityId = iPrevPersonalityId;
       
   960 
       
   961     Stop();
       
   962     iStarted = EFalse;
       
   963     }
       
   964 
       
   965 // ----------------------------------------------------------------------------
       
   966 // Start personality. Called from global state handler
       
   967 // ----------------------------------------------------------------------------
       
   968 //
       
   969 void CUsbWatcher::StartPersonality()
       
   970     {
       
   971     LOG_FUNC
       
   972 
       
   973     if( !iStarted )
       
   974         {
       
   975         Start();
       
   976         }
       
   977 
       
   978     //start usbdevcon only in normal global state
       
   979     TInt globalState = CUsbGlobalSystemStateObserver::GlobalSystemState();
       
   980     if( ( globalState == ESwStateNormalRfOn ) ||
       
   981             ( globalState == ESwStateNormalRfOff ) ||
       
   982             ( globalState == ESwStateNormalBTSap ) )
       
   983         {
       
   984         iUsbDevConStarter->Start();
       
   985         }
       
   986     }
       
   987 
       
   988 // ----------------------------------------------------------------------------
       
   989 // Read default personality from ini file. Used in charging mode
       
   990 // ----------------------------------------------------------------------------
       
   991 //
       
   992 TInt CUsbWatcher::GetChargingPersonalityId( TInt& aPersonalityId )
       
   993     {
       
   994     LOG_FUNC
       
   995 
       
   996     TInt ret = iPersonalityRepository->Get(
       
   997             KUsbWatcherChargingDefaultPersonality, aPersonalityId );
       
   998     return ret;
       
   999     }
       
  1000 
       
  1001 // ----------------------------------------------------------------------------
       
  1002 // Check if there is an observer with ask on connection suppression
       
  1003 // ----------------------------------------------------------------------------
       
  1004 //
       
  1005 TBool CUsbWatcher::IsAskOnConnectionSuppression()
       
  1006     {
       
  1007     LOG_FUNC
       
  1008     
       
  1009     TBool ret( EFalse );
       
  1010     for( TInt i = 0; i < iObservers.Count(); i++ )
       
  1011         {
       
  1012         if( iObservers[i]->IsAskOnConnectionSuppressed() )
       
  1013             {
       
  1014             ret = ETrue;
       
  1015             break;
       
  1016             }
       
  1017         }
       
  1018     LOG1( "Return = %d", ret );
       
  1019     return ret;
       
  1020     }
       
  1021 
       
  1022 // ----------------------------------------------------------------------------
       
  1023 // Check current A or B device state
       
  1024 // ----------------------------------------------------------------------------
       
  1025 //
       
  1026 TBool CUsbWatcher::IsDeviceA()
       
  1027     {
       
  1028     //NOT LOGGED
       
  1029     // return EFalse in non-OTG configuration otherwise ask UsbOtgWatcher
       
  1030     return iOtgWatcher ? iOtgWatcher->IsDeviceA() : EFalse;
       
  1031     }
       
  1032 
       
  1033 // End of file