brandingserver/bsserver/cbsserver.cpp
changeset 0 e6b17d312c8b
child 21 cfd5c2994f10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/brandingserver/bsserver/cbsserver.cpp	Thu Dec 17 08:54:49 2009 +0200
@@ -0,0 +1,664 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: cbsserver.cpp
+*
+*/
+
+
+//  INCLUDE FILES
+
+#define __INCLUDE_CAPABILITY_NAMES__
+#define __INCLUDE_ALL_SUPPORTED_CAPABILITIES__
+
+#include "cbsserver.h"
+#include "cbssession.h"
+#include "bsserverdefs.h"
+#include "debugtrace.h"
+#include "cbsstoragemanager.h"
+#include "cbsinstallhandler.h"
+#include "cbsbackupobserver.h"
+
+// CBSFileMapping
+
+CBSServer::CBSFileMapping* CBSServer::CBSFileMapping::NewL( CBSSession* aSession,
+				    									    const TDesC& aFile,
+				    									    TBool aVersioned )
+	{
+	CBSFileMapping* self = new( ELeave ) CBSFileMapping( aVersioned );
+	CleanupStack::PushL( self );
+	self->ConstructL( aSession, aFile );
+	CleanupStack::Pop( self );
+	return self;
+	}
+void CBSServer::CBSFileMapping::ConstructL(  CBSSession* aSession,
+    									     const TDesC& aFile )
+	{
+	iSession = aSession;
+	iFile = aFile.AllocL();
+	}
+CBSServer::CBSFileMapping::CBSFileMapping( TBool aVersioned )
+: iVersioned( aVersioned )
+	{
+	}
+CBSServer::CBSFileMapping::~CBSFileMapping()
+	{
+	delete iFile;
+	}
+
+CBSSession* CBSServer::CBSFileMapping::Session()
+	{
+	return iSession;
+	}
+const TDesC& CBSServer::CBSFileMapping::File()
+	{
+	return *iFile;
+	}
+TBool CBSServer::CBSFileMapping::Versioned()
+	{
+	return iVersioned;
+	}
+
+
+// ==============================================================
+// =============== PLATSEC POLICY CONFIGURATION =================
+// ==============================================================
+
+static const TInt KBSPlatSecRangeCount = 2;
+
+//Ranges for the Request values
+static const TInt KBSPlatSecRanges[ KBSPlatSecRangeCount ] =
+    {
+    0,
+    EBSOperationLast
+    };
+
+
+// Element indexes for the defined ranges
+static const TUint8 KBSPlatSecElementsIndex[ KBSPlatSecRangeCount ] =
+    {
+    0,
+    CPolicyServer::ENotSupported
+    };
+
+
+// Policy elements
+static const CPolicyServer::TPolicyElement KBSPlatSecElements[] =
+    {
+        {
+        _INIT_SECURITY_POLICY_C2( ECapabilityReadUserData,
+                                  ECapabilityWriteUserData ),
+        -5 //CPolicyServer::EFailClient
+        }
+    };
+
+
+// The platsec policy
+static const CPolicyServer::TPolicy KBSPlatSecPolicy =
+    {
+    // Shortcut to the index into Elements,that is used to check a connection attempt
+    0,
+
+    // Number of ranges in the iRanges array
+    KBSPlatSecRangeCount,
+
+    // A pointer to an array of ordered ranges of request numbers
+    KBSPlatSecRanges,
+
+    // A pointer to an array of TUint8 values specifying
+    // the appropriate action to take for each range in iRanges
+    KBSPlatSecElementsIndex,
+
+    // A pointer to an array of distinct policy elements
+    KBSPlatSecElements
+    };
+
+
+
+// ==============================================================
+// ======================= SERVER  ==============================
+// ==============================================================
+void CBSServer::ExecuteL()
+    {
+    TRACE( T_LIT( "CBrandingServer::ExecuteL() begin") );
+    // start scheduler
+    CActiveScheduler* pA = new( ELeave )CActiveScheduler;
+    CleanupStack::PushL( pA );
+    CActiveScheduler::Install( pA );
+
+
+    // create server
+    CBSServer* server = new( ELeave ) CBSServer();
+    CleanupStack::PushL( server );
+    server->InitializeL();
+    server->StartL( KBSServerName );
+
+
+    //Signal client that we are started
+    RProcess().Rendezvous( KErrNone );
+
+    //Execute the server
+    // Codescanner warning: using CActiveScheduler::Start (id:3)
+    // this has to be called for server starting.
+    CActiveScheduler::Start(); // CSI: 3 # See above
+
+
+    //Cleanup
+    CleanupStack::PopAndDestroy( server );//server
+    CleanupStack::PopAndDestroy( pA );
+    CActiveScheduler::Install( NULL );
+    TRACE( T_LIT( "CBrandingServer::ExecuteL() end") );
+    }
+
+
+
+CBSServer::~CBSServer()
+    {
+    TRACE( T_LIT( "CBrandingServer::~CBSServer() begin") );
+    delete iBackupObserver;
+    delete iInstallHandler;
+    iSessions.Close();
+    iFileMapping.Close();
+    delete iStorageManager;
+
+#if _BullseyeCoverage
+    cov_write();
+#endif
+    TRACE( T_LIT( "CBrandingServer::~CBSServer() end") );
+    }
+
+
+
+CBSServer::CBSServer()
+    : CPolicyServer( CActive::EPriorityStandard,
+                     KBSPlatSecPolicy )
+    {
+    }
+
+
+
+CSession2* CBSServer::NewSessionL( const TVersion &aVersion,
+                                          const RMessage2& /*aMessage*/ ) const
+    {
+    TRACE( T_LIT( "CBrandingServer::NewSessionL() begin") );
+    TVersion srvVersion( KBSVersionMajor,
+                         KBSVersionMinor,
+                         KBSVersionBuild );
+
+
+    if( !User::QueryVersionSupported( aVersion, srvVersion ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    CBSSession* session = CBSSession::NewL();
+    //enable backup observer
+    iBackupObserver->RegisterObserver( session );
+    
+    TRACE( T_LIT( "CBrandingServer::NewSessionL() end session[%d] created"), session );
+    return session;
+    }
+
+
+CPolicyServer::TCustomResult
+    CBSServer::CustomFailureActionL( const RMessage2& aMsg,
+                                            TInt /*aAction*/,
+                                            const TSecurityInfo& aMissing )
+    {
+    TRACE( T_LIT( "CBrandingServer::CustomFailureActionL() Request %d to session [%d] failed."),
+                   aMsg.Function(), aMsg.Session() );
+
+    TBuf<512> diagnosticMsg;
+    _LIT( KDetails, "Failure details: ");
+    diagnosticMsg.Append( KDetails );
+    _LIT( KFormat, "SecureId[%d] VendorId[%d] Missing caps[" );
+    diagnosticMsg.AppendFormat( KFormat,
+                                aMissing.iSecureId.iId, aMissing.iVendorId.iId );
+
+    const SCapabilitySet& missingCaps = (const SCapabilitySet&) aMissing.iCaps;
+    TBuf<1> separator;
+    _LIT( KSeparator, "]" );
+	for( TInt ix = 0; ix < ECapability_Limit; ix++ )
+		{
+		if( missingCaps[ix>>5] &(1<<(ix&31)))
+			{
+            diagnosticMsg.Append( separator );
+
+            const char* capName = CapabilityNames[ ix ];
+		    while( *capName )
+		        {
+                TUint16 c = *capName;
+                diagnosticMsg.Append( &c, 1 );
+                ++capName;
+                }
+			
+            separator = KSeparator;
+    		}
+		}
+
+    diagnosticMsg.Append( KSeparator );
+    TRACE( T_LIT( "%S"), &diagnosticMsg );
+
+    return CPolicyServer::EFail;
+    }
+
+void CBSServer::HandleBackupStateL( TBackupState aState )
+    {
+    switch( aState )
+        {
+        case EBackupNotActive: // backup has completed
+            {
+            // restart install handler and check for brand changes
+            iInstallHandler->InstallNewFilesL();
+            iInstallHandler->StartObservingL();
+            
+            //notify clients that we're back in business
+            break;
+            }
+        case EBackupActive: // backup activated
+            {
+            // stop install handler 
+            iInstallHandler->StopObserving();
+            
+            // Notify clients that branding data is not currently 
+            //       available
+            break;
+            }
+        default:
+            {
+            // unknown state
+            }
+        }
+    }
+
+void CBSServer::SessionCreatedL( CBSSession* aSession )
+    {
+    TRACE( T_LIT( "CBSServer::SessionCreatedL begin aSession[%d]"),aSession );
+    iSessionCount++;
+    iSessions.AppendL( aSession );
+    }
+
+
+void CBSServer::SessionDied( CBSSession* aSession )
+    {
+    TInt count = iSessions.Count();
+	for( TInt i = 0; i < count; i++ )
+		{
+		if( iSessions[i] == aSession )
+			{
+			iSessions.Remove( i );
+			break;
+			}
+		}
+	TInt ignore = 0;
+	TRAP( ignore, UnRegisterSessionL( aSession ) );
+	
+    //enable backup observer
+	iBackupObserver->UnregisterObserver( aSession );
+    
+    iSessionCount--;
+    if( iSessionCount == 0 )
+        {
+        // Codescanner warning: using CActiveScheduler::Stop ( Id: 4)
+        // it is required to stop the server
+        CActiveScheduler::Stop(); // CSI: 4 # See above
+        }
+    }
+
+
+
+TBool CBSServer::MatchSessionL( const TDesC& aApplicationId,
+							    const TDesC& aBrandId,
+							    TLanguage aLanguageId,
+							 	CBSSession* aSession,
+							 	TInt aReserved  )
+	{
+	TInt sessionCount = iSessions.Count();
+	TBool returnValue = EFalse;
+	for( TInt i = 0; i < sessionCount; i++ )
+		{
+		if( iSessions[i] == aSession )
+			{
+			// we don't want to report the querying session itself
+			continue;
+			}
+		if( iSessions[i]->MatchSessionL( aApplicationId,
+										 aBrandId,
+										 aLanguageId,
+										 aReserved ) )
+			{
+			// even one match is enough for us
+			returnValue = ETrue;
+			break;
+			}
+		}
+	return returnValue;
+	}
+
+TBool CBSServer::MatchSessionUninstallL( const TDesC& aApplicationId,
+								 const TDesC& aBrandId, CBSSession* aSession)
+{
+	TInt sessionCount = iSessions.Count();
+	TBool returnValue = EFalse;
+	for( TInt i = 0; i < sessionCount; i++ )
+		{
+		if( iSessions[i] == aSession )
+			{
+			// we don't want to report the querying session itself
+			continue;
+			}
+		if( iSessions[i]->MatchSessionUninstallL( aApplicationId,
+										 aBrandId ))
+			{
+			// even one match is enough for us
+			returnValue = ETrue;
+			break;
+			}
+		}
+	return returnValue;
+	
+}
+
+void CBSServer::RegisterFileForSessionL( CBSSession* aSession, 
+										 const TDesC& aFile,
+										 TBool aVersioned )
+	{
+	TRACE( T_LIT( "CBSServer::RegisterFileForSessionL begin aSession[%d],aFile[%S]"),aSession,&aFile );
+	TBool found  = EFalse;
+	TInt count = iFileMapping.Count();		
+	for( TInt i = 0; i < count; i ++ )
+		{		
+		if( iFileMapping[i]->Session() == aSession && iFileMapping[i]->File() == aFile &&
+				iFileMapping[i]->Versioned() == aVersioned)
+			{
+				found = ETrue; 			
+			}			
+		}
+	
+	if(!found)
+		{			
+		
+		CBSFileMapping* fileMapping = CBSFileMapping::NewL( aSession, aFile, aVersioned );
+		CleanupStack::PushL( fileMapping );
+		iFileMapping.AppendL( fileMapping );
+		CleanupStack::Pop( fileMapping );
+		}
+	TRACE( T_LIT( "CBSServer::RegisterFileForSessionL end") );
+	}
+
+void CBSServer::UnRegisterSessionL( CBSSession* aSession )
+	{
+	TRACE( T_LIT( "CBSServer::RegisterFileForSessionL begin aSession[%d]"),aSession );
+	TInt count = iFileMapping.Count();
+	for( TInt i = 0; i < count; i ++ )
+		{
+		if( iFileMapping[i]->Session() == aSession )
+			{
+
+			if( !iStorageManager )
+				{
+				iStorageManager = CBSStorageManager::NewL( aSession, KNullDesC );	
+				}
+			if( !FileStillInUse( aSession, iFileMapping[i]->File() ) )
+				{
+				TPtrC baseFile = KNullDesC();
+				if( iFileMapping[i]->Versioned() )
+					{
+					baseFile.Set( iStorageManager->FilenameWithoutVersion( iFileMapping[i]->File() ) );
+					}
+				else
+					{
+					baseFile.Set( iFileMapping[i]->File() );
+					}
+				// we found the session, now check if any other
+				// session is using the same file
+				if( !FileStillInUse( aSession, baseFile ) )
+					{
+					// no other sessions using the file
+					// cleanup versioned file
+					CleanupFileL( iFileMapping[i]->File() );
+					}					
+
+				}
+			CBSFileMapping* fileMapping = iFileMapping[i];
+			iFileMapping.Remove( i );
+			delete fileMapping;
+			break;
+			}
+		}
+	TRACE( T_LIT( "CBSServer::RegisterFileForSessionL end") );
+	}
+
+TBool CBSServer::FileStillInUse( CBSSession* aSession,
+								 const TDesC& aFile )
+	{
+	TBool returnValue = EFalse;
+	TInt count = iFileMapping.Count();
+	for( TInt i = 0; i < count; i ++ )
+		{
+		if( 0 == iFileMapping[i]->File().Compare( aFile ) )
+			{
+			// file found, check that it's not the same sesion
+			if( iFileMapping[i]->Session() != aSession )
+				{
+
+				// it's not the same session
+				// so the file is still in use, we can
+				// return ETrue
+				returnValue = ETrue;
+				break;
+				}
+			}
+		}
+	return returnValue;
+	}
+		
+void CBSServer::CleanupFileL( const TDesC& aFile )
+	{
+	if( !iStorageManager )
+		{
+		iStorageManager = CBSStorageManager::NewL( NULL, KNullDesC);	
+		}
+	iStorageManager->CleanupFileL( aFile ); 
+	}
+
+TArray<CBSServer::CBSFileMapping*> CBSServer::RegisteredFiles()
+	{
+	return iFileMapping.Array();
+	}
+
+void CBSServer::InitializeL()
+    {
+    TRACE( T_LIT( "CBSServer::InitializeL begin") );
+    // Initialize brand install handler
+    iInstallHandler = CBSInstallHandler::NewL();
+    iInstallHandler->InstallNewFilesL();
+    iInstallHandler->StartObservingL();
+    
+    //to enable backup observer
+    // Initialize backup and restore observer
+    CBSBackupObserver* tmp = CBSBackupObserver::NewL();
+    delete iBackupObserver;
+    iBackupObserver = tmp;
+    User::LeaveIfError( iBackupObserver->RegisterObserver( this ) );
+    TRACE( T_LIT( "CBSServer::InitializeL end") );
+    }
+
+void CBSServer::BrandUpdatedL( const TDesC& aApplicationId,
+							   const TDesC& aBrandId,
+							   TLanguage aLanguageId,
+							   CBSSession* aSession,
+							   TInt aReserved )
+	{
+	TRACE( T_LIT( "CBSServer::BrandUpdatedL begin aAppid[%S],aBrandId[%S]"),&aApplicationId, &aBrandId );
+	TInt sessionCount = iSessions.Count();
+	for( TInt i = 0; i < sessionCount; i++ )
+		{
+		if( iSessions[i] == aSession )
+			{
+			// we don't want to report the querying session itself
+			continue;
+			}
+		iSessions[i]->BrandUpdatedL( aApplicationId,
+									 aBrandId,
+									 aLanguageId,
+									 aReserved );
+		}
+	TRACE( T_LIT( "CBSServer::BrandUpdatedL end") );
+	}
+
+
+
+// ---------------------------------------------------------------------------
+// CBSServer::DisplaySessionInfoL display the info for each open session,
+// except for the one that called this method
+// ---------------------------------------------------------------------------
+//
+void CBSServer::DisplaySessionInfoL( CBSSession* aSession, TInt aErrorCode )
+	{
+    TRACE( T_LIT( "CBSServer::DisplaySessionInfoL() begin aSession[%d], aErrorCode[%d]"),aSession,aErrorCode );
+
+    User::LeaveIfNull( aSession );
+    // some constants
+    const TInt KStringLength = 512;
+    const TInt KNumberLength = 16;
+    _LIT( KMessage0,"Operation failed.Errorcode:");    
+    _LIT( KMessage1," Info on open sessions [ProcessFileName|ThreadId|ProcessId|Caption]:");
+    _LIT( KBracketOpen, " [");
+    _LIT( KBracketClose, "]");
+    _LIT( KSeparator, "|");
+    
+
+    HBufC* outputString = HBufC::NewLC( KStringLength );
+    TPtr outputStringPtr( outputString->Des() );
+
+    TBuf<KNumberLength> number;
+    number.Num( aErrorCode );
+    
+    //make sure the string is long enough
+    TInt newLength = outputString->Length() +
+                     KMessage0().Length() +
+                     number.Length() + 
+                     KMessage1().Length();
+    
+    //reallocate if necessary
+    if ( outputStringPtr.MaxLength() < newLength )
+        {
+        CleanupStack::Pop( outputString );
+        outputString = outputString->ReAllocL( newLength );
+        outputStringPtr.Set( outputString->Des() );
+        CleanupStack::PushL( outputString );
+        }    
+        
+    outputStringPtr.Append( KMessage0 );
+    outputStringPtr.Append( number );
+    outputStringPtr.Append( KMessage1 );
+    
+        
+    TInt count = iSessions.Count();
+	TRACE( T_LIT( "CBSServer::DisplaySessionInfoL() numberSessions=%d"),count );
+	CBSSession* currentSession;
+	for( TInt i = 0; i < count; i++ )
+		{		
+		currentSession = iSessions[i];
+        TRACE( T_LIT( "CBSServer::DisplaySessionInfoL() iteration=%d session=%d"),i,currentSession );
+    	if ( currentSession 
+    	     && currentSession->InfoAvailable()
+    	     && currentSession != aSession )
+    	    {
+    		TBuf<KNumberLength> threadIdStr;
+    		TThreadId threadId;
+    		if ( KErrNone == currentSession->ThreadId( threadId ) )
+    		    {
+    		    threadIdStr.NumUC( threadId.Id(), EDecimal );
+    		    }    		
+    		TBuf<KNumberLength> processIdStr;
+    		TProcessId processId;
+    		if ( KErrNone == currentSession->ProcessId( processId ) )
+    		    {
+    		    processIdStr.NumUC( processId.Id(), EDecimal );
+    		    }
+            
+            //make sure the string is long enough
+            newLength = outputString->Length() +
+                        KBracketOpen().Length() +
+                        currentSession->FileName().Length() + 
+                        threadIdStr.Length() + 
+                        processIdStr.Length() +
+                        currentSession->Caption().Length() +                        
+                        ( 3 * KSeparator().Length() ) +                        
+                        KBracketClose().Length();
+
+            //reallocate if necessary
+            if ( outputStringPtr.MaxLength() < newLength )
+                {
+                CleanupStack::Pop( outputString );
+                outputString = outputString->ReAllocL( newLength );
+                outputStringPtr.Set( outputString->Des() );
+                CleanupStack::PushL( outputString );
+                }
+
+  		    outputStringPtr.Append( KBracketOpen );
+    		
+    		//processfilename
+    		outputStringPtr.Append( currentSession->FileName() );
+    		outputStringPtr.Append( KSeparator );
+    		    		
+    		//threadid    		
+    		outputStringPtr.Append( threadIdStr );
+    		outputStringPtr.Append( KSeparator );
+    		
+    		//processid    		
+    		outputStringPtr.Append( processIdStr );
+    		outputStringPtr.Append( KSeparator );	
+    		
+    		//caption
+    		outputStringPtr.Append( currentSession->Caption() );    		
+
+    		outputStringPtr.Append( KBracketClose );
+    	    }
+		}     
+	
+	TRACE( T_LIT( "CBSServer::DisplaySessionInfoL() string creation OK") );
+	TRACE( T_LIT( "%S"), outputString );
+	CleanupStack::PopAndDestroy( outputString );
+	TRACE( T_LIT( "CBSServer::DisplaySessionInfoL() end") );
+	}
+	
+// ==============================================================
+// ====================== ENTRY POINT ===========================
+// ==============================================================
+GLDEF_C TInt E32Main()
+    {
+    TRACE( T_LIT("E32Main - enter") );
+
+    User::RenameThread( KBSServerName );
+
+    CTrapCleanup* tc = CTrapCleanup::New();
+    if( !tc )
+        {
+        return KErrNoMemory;
+        }
+
+    TRAPD( err, CBSServer::ExecuteL() );
+    delete tc;
+
+    TRACE( T_LIT("E32Main - exit: %d"), err );
+    return err;
+    }
+
+
+
+//  END OF FILE
+
+