filemanager/bkupchecker/src/filemanagerbkupchecker.cpp
changeset 0 6a9f87576119
equal deleted inserted replaced
-1:000000000000 0:6a9f87576119
       
     1 /*
       
     2 * Copyright (c) 2006-2008 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:  Rule based application launch during backup and restore.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include <bautils.h>
       
    21 #include <barsc2.h>
       
    22 #include <barsread2.h>
       
    23 #include <e32property.h>
       
    24 #include <data_caging_path_literals.hrh>
       
    25 #include <filemanagerbkupchecker.rsg>
       
    26 #include <AknGlobalNote.h>
       
    27 #include <AknSgcc.h>
       
    28 #include <ecom/implementationproxy.h>
       
    29 
       
    30 #include "FileManagerDebug.h"
       
    31 #include "filemanagerprivatepskeys.h"
       
    32 #include "FileManagerUID.h"
       
    33 #include "filemanagerbkupchecker.h"
       
    34 
       
    35 // CONSTANTS
       
    36 _LIT(KMsengRscFilePath,"filemanagerbkupchecker.rsc");
       
    37 _LIT(KThreadName,"BkupCheckerThread"); 
       
    38 
       
    39 #ifdef __SKIP_PS_IN_TEST_
       
    40 // Controlling of KUidBackupRestoreKey only possible with SID 0x10202D56
       
    41 // That is why we have to variate running of test code using testVariable
       
    42 extern TInt testVariable;
       
    43 #endif
       
    44 
       
    45 // Define the interface UIDs.
       
    46 const TImplementationProxy ImplementationTable[] =
       
    47     {
       
    48     IMPLEMENTATION_PROXY_ENTRY( 0x1020508A, CFileManagerBkupChecker::NewL )
       
    49     };
       
    50 
       
    51 
       
    52 // ======== LOCAL FUNCTIONS ========
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // ProcessExists
       
    56 // ---------------------------------------------------------------------------
       
    57 //
       
    58 static TBool ProcessExists( const TSecureId& aSecureId )
       
    59     {
       
    60     _LIT( KFindPattern, "*" );
       
    61     TFindProcess finder(KFindPattern);
       
    62     TFullName processName;
       
    63     while( finder.Next( processName ) == KErrNone )
       
    64         {
       
    65         RProcess process;
       
    66         if ( process.Open( processName ) == KErrNone )
       
    67             {
       
    68             TSecureId processId( process.SecureId() );
       
    69             process.Close();
       
    70             if( processId == aSecureId )
       
    71                 {
       
    72                 return ETrue;
       
    73                 }
       
    74             }
       
    75         }
       
    76     return EFalse;
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // GetFileManagerBurStatus
       
    81 // ---------------------------------------------------------------------------
       
    82 //
       
    83 static TInt GetFileManagerBurStatus()
       
    84     {
       
    85     TInt status( EFileManagerBkupStatusUnset );
       
    86     TInt err( RProperty::Get(
       
    87         KPSUidFileManagerStatus, KFileManagerBkupStatus, status ) );
       
    88     if ( err != KErrNone )
       
    89         {
       
    90         status = EFileManagerBkupStatusUnset;
       
    91         }
       
    92     else if( status == EFileManagerBkupStatusBackup || 
       
    93              status == EFileManagerBkupStatusRestore )
       
    94         {
       
    95         const TSecureId KFileManagerUid(KFileManagerUID3);
       
    96         // Check file manager process just if bur state detected
       
    97         if( !ProcessExists( KFileManagerUid ) )
       
    98             {
       
    99             status = EFileManagerBkupStatusUnset;
       
   100             }
       
   101         }
       
   102 
       
   103     INFO_LOG2( "GetFileManagerBurStatus, status %d, err %d", status, err )
       
   104 
       
   105     return status;
       
   106     }
       
   107 
       
   108 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // ImplementationGroupProxy.
       
   112 //
       
   113 // -----------------------------------------------------------------------------
       
   114 //
       
   115 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
       
   116     {
       
   117     aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy );
       
   118     return ImplementationTable;
       
   119     }
       
   120 
       
   121 
       
   122 // ======== MEMBER FUNCTIONS ========
       
   123 
       
   124 // ---------------------------------------------------------------------------
       
   125 // CFileManagerBkupChecker::CFileManagerBkupChecker
       
   126 //
       
   127 // ---------------------------------------------------------------------------
       
   128 //
       
   129 CFileManagerBkupChecker::CFileManagerBkupChecker()
       
   130     {
       
   131     }
       
   132 
       
   133 // ---------------------------------------------------------------------------
       
   134 // CFileManagerBkupChecker::NewL
       
   135 //
       
   136 // ---------------------------------------------------------------------------
       
   137 //
       
   138 CFileManagerBkupChecker* CFileManagerBkupChecker::NewL()
       
   139 	{
       
   140 	CFileManagerBkupChecker* self = new (ELeave) CFileManagerBkupChecker();
       
   141     CleanupStack::PushL( self );
       
   142     self->ConstructL();
       
   143     CleanupStack::Pop( self );
       
   144     return self;
       
   145 	}
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 // CFileManagerBkupChecker::ConstructL
       
   149 //
       
   150 // ---------------------------------------------------------------------------
       
   151 //
       
   152 void CFileManagerBkupChecker::ConstructL()
       
   153     {
       
   154     FUNC_LOG
       
   155     RFs fsSession;
       
   156     
       
   157     // Connect to File Server
       
   158     User::LeaveIfError(fsSession.Connect());
       
   159     CleanupClosePushL(fsSession);
       
   160     
       
   161     // Get resource drive from dll location
       
   162     TFileName dllFileName;
       
   163     Dll::FileName( dllFileName );
       
   164     TParsePtrC dllParse( dllFileName );
       
   165     TFileName fileName;
       
   166 #ifdef __SKIP_PS_IN_TEST_
       
   167     _LIT(KDriveZ,"Z:");
       
   168     fileName.Copy( KDriveZ );
       
   169 #else
       
   170     // Drive is parsed normally from dll-location in order to support
       
   171     // installing/patching of component.
       
   172     fileName.Copy( dllParse.Drive() );
       
   173 #endif
       
   174     fileName.Append( KDC_RESOURCE_FILES_DIR );
       
   175     fileName.Append( KMsengRscFilePath );
       
   176     BaflUtils::NearestLanguageFile( fsSession, fileName );
       
   177     //
       
   178     TEntry entry;
       
   179     User::LeaveIfError( fsSession.Entry( fileName, entry ) );
       
   180     // if file does not exist, leaves with KErrNotFound
       
   181     
       
   182     CResourceFile *resFile;
       
   183     resFile = CResourceFile::NewLC( fsSession, fileName, 0, entry.iSize );
       
   184     
       
   185     resFile->ConfirmSignatureL();
       
   186     
       
   187     /////////////////////////////////////////////////////////
       
   188     //Initialize white-list of applications from resource file
       
   189 
       
   190     RResourceReader theReader;
       
   191     theReader.OpenLC( resFile, ALLOWEDUIDS );
       
   192     
       
   193     //the first WORD contains the number of elements in the resource
       
   194     TInt numberOfUIDs = theReader.ReadInt16L();
       
   195     
       
   196     for( TInt i = 0; i < numberOfUIDs; i++)
       
   197         {
       
   198         TUint32 uid = theReader.ReadInt32L();
       
   199         iUids.Append(uid);
       
   200         INFO_LOG1( "CFileManagerBkupChecker::ConstructL, Application 0x%x added in white-list", iUids[i] )
       
   201         }
       
   202     CleanupStack::PopAndDestroy( &theReader );
       
   203     
       
   204     //Initialize information note texts from resource file
       
   205     theReader.OpenLC( resFile, R_QTN_FMGR_BACKUP_APPLAUNCH_PREVENTED );
       
   206     iBackupNote = theReader.ReadHBufCL();
       
   207     CleanupStack::PopAndDestroy( &theReader );
       
   208     
       
   209     theReader.OpenLC( resFile, R_QTN_FMGR_RESTORE_APPLAUNCH_PREVENTED );
       
   210     iRestoreNote = theReader.ReadHBufCL();
       
   211     CleanupStack::PopAndDestroy( &theReader );
       
   212     
       
   213     CleanupStack::PopAndDestroy( resFile );
       
   214     CleanupStack::PopAndDestroy( &fsSession );
       
   215     }
       
   216 
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 // CFileManagerBkupChecker::~CFileManagerBkupChecker
       
   220 //
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 CFileManagerBkupChecker::~CFileManagerBkupChecker()
       
   224     {
       
   225     delete iBackupNote;
       
   226     delete iRestoreNote;
       
   227     iUids.Close();
       
   228     }
       
   229 
       
   230 // ---------------------------------------------------------------------------
       
   231 // CFileManagerBkupChecker::OkayToLaunchL
       
   232 //
       
   233 // ---------------------------------------------------------------------------
       
   234 //
       
   235 CAppLaunchChecker::TAppLaunchCode CFileManagerBkupChecker::OkayToLaunchL(const TUid aAppToLaunch, 
       
   236     TApaTaskList& /* aTaskList */)
       
   237 	{ 
       
   238     FUNC_LOG
       
   239 	CAppLaunchChecker::TAppLaunchCode launch = CAppLaunchChecker::EAppLaunchIndifferent;
       
   240 	
       
   241 	TInt burState( 0 );
       
   242 	TInt burErr = RProperty::Get( KUidSystemCategory, KUidBackupRestoreKey, burState ); 
       
   243 	
       
   244 	if(burErr == KErrNone)
       
   245 	    {
       
   246 	    INFO_LOG2
       
   247 	    ( 
       
   248 	    "CFileManagerBkupChecker::OkayToLaunchL, Application 0x%x, KUidBackupRestoreKey status %d",
       
   249 	    aAppToLaunch.iUid, burState 
       
   250 	    )
       
   251 	    
       
   252 	    TBURPartType burType = static_cast< TBURPartType >( burState & KBURPartTypeMask );
       
   253 	    TInt fmBurStatus( GetFileManagerBurStatus() );
       
   254         
       
   255         // We can't rely on just p&s value. Additional check is carried out in ValidateBUROngoing.
       
   256 #ifdef __SKIP_PS_IN_TEST_
       
   257         // Run additional validation check in test mode just to cover all use cases
       
   258         ValidateBUROngoing();
       
   259 #else
       
   260 	    if( fmBurStatus == EFileManagerBkupStatusBackup ||
       
   261 	        fmBurStatus == EFileManagerBkupStatusRestore ||
       
   262 	        ( ( burType == EBURBackupPartial || burType == EBURBackupFull ||
       
   263 	            burType == EBURRestorePartial || burType == EBURRestoreFull ) &&
       
   264 	            ValidateBUROngoing() ) )
       
   265 #endif
       
   266 	        {
       
   267 	        launch = CAppLaunchChecker::EAppLaunchDecline;
       
   268 	        
       
   269 	        TInt count( iUids.Count() );
       
   270 	        
       
   271         	for( TInt i = 0; i < count; i++ )
       
   272         	    {
       
   273         	    if(iUids[i] == aAppToLaunch.iUid)
       
   274                     {
       
   275                     INFO_LOG1
       
   276                     ( 
       
   277                     "CFileManagerBkupChecker::OkayToLaunchL, Application 0x%x in white-list", 
       
   278                     iUids[i] 
       
   279                     )
       
   280                     launch = CAppLaunchChecker::EAppLaunchIndifferent;
       
   281                     break;
       
   282                     }
       
   283         	    }
       
   284             
       
   285             if( launch == CAppLaunchChecker::EAppLaunchDecline )
       
   286                 {
       
   287                 INFO_LOG1
       
   288                 (
       
   289                 "CFileManagerBkupChecker::OkayToLaunchL, Application 0x%x launch prevented", 
       
   290                 aAppToLaunch.iUid 
       
   291                 )
       
   292 
       
   293                 iIsBackup = ( fmBurStatus == EFileManagerBkupStatusBackup ||
       
   294                               burType == EBURBackupPartial ||
       
   295                               burType == EBURBackupFull );
       
   296 
       
   297                 RThread thread;
       
   298                 
       
   299                 TInt err = thread.Create(
       
   300                     KThreadName, ThreadFunction, KDefaultStackSize, NULL, this );
       
   301                     
       
   302                 INFO_LOG1("CFileManagerBkupChecker::OkayToLaunchL, thread err %d", err)
       
   303 
       
   304                 if ( err == KErrNone )
       
   305                     {
       
   306                     TRequestStatus status;
       
   307                     
       
   308                     thread.Rendezvous( status );
       
   309                     thread.Resume();
       
   310                     
       
   311                     // Wait until thread has copy of note text.
       
   312                     User::WaitForRequest( status );
       
   313 
       
   314                     INFO_LOG1("CFileManagerBkupChecker::OkayToLaunchL, thread exit %d", status.Int())
       
   315                     }
       
   316                 
       
   317                 thread.Close();
       
   318                 }
       
   319 	        }
       
   320 	    }
       
   321 
       
   322 	return launch;
       
   323 	}
       
   324 
       
   325 // ---------------------------------------------------------------------------
       
   326 // CFileManagerBkupChecker::ValidateBUROngoing
       
   327 //
       
   328 // ---------------------------------------------------------------------------
       
   329 //
       
   330 TBool CFileManagerBkupChecker::ValidateBUROngoing()
       
   331     {
       
   332     TBool err(EFalse);
       
   333     _LIT( KFindPattern, "*" );
       
   334     const TSecureId KSBEUid(0x10202D56);
       
   335     const TSecureId KFileManagerUid(KFileManagerUID3);
       
   336     const TSecureId KPCConnectivityUid(0x101F99F6);
       
   337     TBool serverRunning(EFalse);
       
   338     TBool client1Running(EFalse);
       
   339     TBool client2Running(EFalse);
       
   340     
       
   341     // If SBE panics, File Manager and PC-connectivity server are supposed to 
       
   342     // re-establish connection to server and set BUR-mode back to normal.
       
   343     // If SBE client panics, server is supposed to set BUR-mode back to normal.
       
   344     // However, it might be reasonable to validate also that BUR client is
       
   345     // up and running. E.g. if both server and client panic in sequence, BUR
       
   346     // state might stay as backup or restore and we never let application run.
       
   347     // We have to search by UID, because process can have localized name
       
   348     TFindProcess finder( KFindPattern );
       
   349     TFullName processName;
       
   350 
       
   351     while( finder.Next( processName ) == KErrNone )
       
   352         {
       
   353         RProcess process;
       
   354         const TInt r = process.Open( processName );
       
   355         if  ( r == KErrNone )
       
   356             {
       
   357             const TSecureId processId = process.SecureId();
       
   358             process.Close();
       
   359             
       
   360             if( processId == KSBEUid )
       
   361                 {
       
   362                 serverRunning = ETrue;
       
   363                 }
       
   364             else if( processId == KFileManagerUid )
       
   365                 {
       
   366                 client1Running = ETrue;
       
   367                 }
       
   368             else if( processId == KPCConnectivityUid )
       
   369                 {
       
   370                 client2Running = ETrue;
       
   371                 }
       
   372             }
       
   373         }
       
   374 
       
   375     INFO_LOG2("CFileManagerBkupChecker::ValidateBUROngoing, %x status %d", 
       
   376         KSBEUid.iId, serverRunning);
       
   377     INFO_LOG2("CFileManagerBkupChecker::ValidateBUROngoing, %x status %d", 
       
   378         KFileManagerUid.iId, client1Running);
       
   379     INFO_LOG2("CFileManagerBkupChecker::ValidateBUROngoing, %x status %d", 
       
   380         KPCConnectivityUid.iId, client2Running);
       
   381 
       
   382     if( serverRunning && (client1Running || client2Running) )
       
   383         {
       
   384         err = ETrue;
       
   385         }
       
   386 
       
   387     return err;
       
   388     }
       
   389 
       
   390 // ----------------------------------------------------------------------------
       
   391 // CFileManagerBkupChecker::ThreadFunction()
       
   392 //
       
   393 // ----------------------------------------------------------------------------
       
   394 TInt CFileManagerBkupChecker::ThreadFunction( TAny* ptr )
       
   395     {
       
   396     FUNC_LOG
       
   397 
       
   398     CFileManagerBkupChecker* self =
       
   399         static_cast< CFileManagerBkupChecker* >( ptr );
       
   400 
       
   401     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   402     if ( !cleanupStack )
       
   403         {
       
   404         return KErrNoMemory;
       
   405         }
       
   406         
       
   407     TRAPD( err, self->ThreadFunctionL() );
       
   408     
       
   409     INFO_LOG1("CFileManagerBkupChecker::ThreadFunction, ThreadFunctionL err %d", err)
       
   410 
       
   411     delete cleanupStack;
       
   412 
       
   413     return err;
       
   414     }
       
   415 
       
   416 // ----------------------------------------------------------------------------
       
   417 // CFileManagerBkupChecker::ThreadFunctionL()
       
   418 //
       
   419 // ----------------------------------------------------------------------------
       
   420 void CFileManagerBkupChecker::ThreadFunctionL( )
       
   421     {
       
   422     FUNC_LOG
       
   423 
       
   424     HBufC* note = NULL;
       
   425     
       
   426 #ifdef __SKIP_PS_IN_TEST_
       
   427     if(!testVariable)
       
   428         {
       
   429         note = iBackupNote->AllocLC();
       
   430         }
       
   431     else
       
   432         {
       
   433         note = iRestoreNote->AllocLC();
       
   434         }
       
   435 #else
       
   436     if( iIsBackup )
       
   437 	    {
       
   438 	    note = iBackupNote->AllocLC();
       
   439 	    }
       
   440 	else
       
   441 	    {
       
   442 	    note = iRestoreNote->AllocLC();
       
   443 	    }
       
   444 #endif
       
   445 
       
   446     // Once we have locally allocated note string, we can signal main thread.
       
   447     RThread::Rendezvous( KErrNone );
       
   448     
       
   449     RAknUiServer aknSrv;
       
   450     TInt err( aknSrv.Connect() );
       
   451     INFO_LOG1("CFileManagerBkupChecker::ThreadFunctionL, connect err %d", err)
       
   452     User::LeaveIfError( err );
       
   453     CleanupClosePushL( aknSrv );
       
   454 	
       
   455     aknSrv.ShowGlobalNoteL( *note, EAknGlobalInformationNote );
       
   456 
       
   457     CleanupStack::PopAndDestroy( &aknSrv );
       
   458     CleanupStack::PopAndDestroy( note );
       
   459     }
       
   460