--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmhelper/drmhelperserver/src/DRMHelperServer.cpp Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,1445 @@
+/*
+* Copyright (c) 2004-2009 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: Implementation of the Helper Server functionality
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <DRMPermission.h> // CDRMPermission
+#include <DRMConstraint.h> // CDRMConstraint
+#include <s32file.h>
+#include <DRMNotifier.h>
+#include <DRMEventAddRemove.h>
+#include <DRMTypes.h>
+#include <bacntf.h> //CEnvironmentChangeNotifier
+#include <centralrepository.h> // link against centralrepository.lib
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <DriveInfo.h>
+#endif
+
+#include "DRMEventModify.h"
+#include "DRMHelperServerInternalCRKeys.h"
+#include "DRMHelperCommon.h"
+#include "DRMHelperServer.h"
+#include "DRMHelperSession.h"
+#include "EndTimeFactory.h"
+#include "EndTimeBased.h"
+#include "IdleObserver.h"
+
+
+
+
+
+// LOCAL CONSTANTS AND MACROS
+_LIT8(KExpiredMark , "E");
+
+#ifdef RD_MULTIPLE_DRIVE
+_LIT( KHelperServerDataStorage , "%c:DRMHS.dat" );
+#else
+_LIT( KHelperServerDataStorage , "c:DRMHS.dat" );
+#endif
+
+// #define _MEM_HEAP_USAGE
+
+
+// ============================ LOCAL FUNCTIONS ===============================
+#ifdef _DRM_TESTING
+LOCAL_C void WriteLogL( const TDesC8& text , RFs &aFs );
+LOCAL_C void WriteFileL( const TDesC8& text , RFs &aFs , const TDesC& aName );
+LOCAL_C void CreateLogL();
+LOCAL_C void WriteL( const TDesC8& aText );
+LOCAL_C void WriteTimeL( TTime aTime );
+LOCAL_C void WriteCurrentTimeL();
+LOCAL_C void WriteL( const TDesC8& aText , TInt aErr );
+
+#ifdef _MEM_HEAP_USAGE
+LOCAL_C void WriteHeapAllocL();
+#endif //_MEM_HEAP_USAGE
+
+#endif
+
+// -----------------------------------------------------------------------------
+// Testing stuff
+// -----------------------------------------------------------------------------
+//
+#ifdef _DRM_TESTING
+LOCAL_C void WriteLogL( const TDesC8& text , RFs &aFs )
+ {
+ _LIT( KLogFile , "c:\\HSLog.txt" );
+ WriteFileL( text , aFs , KLogFile );
+ }
+
+LOCAL_C void WriteFileL( const TDesC8& text , RFs &aFs , const TDesC& aName )
+ {
+ RFile file;
+ TInt size;
+ User::LeaveIfError( file.Open( aFs, aName , EFileWrite ) );
+ CleanupClosePushL( file );
+ User::LeaveIfError( file.Size( size ) );
+ User::LeaveIfError( file.Write( size, text ) );
+ CleanupStack::PopAndDestroy(&file); //file
+ }
+
+LOCAL_C void CreateLogL()
+ {
+ RFs fs;
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ RFile file;
+ TInt err = file.Open( fs , _L("c:\\HSLog.txt") , EFileWrite );
+ if (err)
+ {
+ err = file.Replace( fs , _L("c:\\HSLog.txt") , EFileWrite );
+ }
+ file.Close();
+ CleanupStack::PopAndDestroy(&fs); //fs
+ }
+
+LOCAL_C void WriteL( const TDesC8& aText )
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL(fs);
+ HBufC8* text = HBufC8::NewLC(1000);
+ TPtr8 textptr(text->Des() );
+ textptr.Append( aText );
+ textptr.Append( _L8("\r\n") );
+ WriteLogL(textptr , fs);
+ CleanupStack::PopAndDestroy(text);
+ CleanupStack::PopAndDestroy(&fs); //fs
+ WriteCurrentTimeL();
+#ifdef _MEM_HEAP_USAGE
+ WriteHeapAllocL();
+#endif //_MEM_HEAP_USAGE
+ }
+
+LOCAL_C void WriteTimeL( TTime aTime )
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL(fs);
+ HBufC8* text = HBufC8::NewLC(100);
+ TPtr8 textptr(text->Des() );
+// Date and Time display
+ TBuf<256> dateString;
+ _LIT(KDate,"%*E%*D%X%*N%*Y %1 %2 '%3");
+ aTime.FormatL(dateString,KDate);
+ textptr.Append(_L( "\r\n\t\t\t\tData:\t" ) );
+ textptr.Append( dateString );
+ _LIT(KTime,"%-B%:0%J%:1%T%:2%S%:3%+B");
+ aTime.FormatL(dateString,KTime);
+ textptr.Append(_L( "\r\n\t\t\t\tTime:\t" ) );
+ textptr.Append( dateString );
+ textptr.Append(_L( "\r\n" ) );
+ textptr.Append(_L( "\r\n" ) );
+ WriteLogL(textptr , fs);
+ CleanupStack::PopAndDestroy(text);
+ CleanupStack::PopAndDestroy(&fs); //fs
+ }
+
+LOCAL_C void WriteCurrentTimeL()
+ {
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL(fs);
+ HBufC8* text = HBufC8::NewLC(100);
+ TPtr8 textptr(text->Des() );
+// Date and Time display
+ TTime time;
+ time.HomeTime();
+ TBuf<256> dateString;
+ _LIT(KDate,"%*E%*D%X%*N%*Y %1 %2 '%3");
+ time.FormatL(dateString,KDate);
+ textptr.Append(_L( "\r\n\t\tData:\t" ) );
+ textptr.Append( dateString );
+ _LIT(KTime,"%-B%:0%J%:1%T%:2%S%:3%+B");
+ time.FormatL(dateString,KTime);
+ textptr.Append(_L( "\r\n\t\tTime:\t" ) );
+ textptr.Append( dateString );
+ textptr.Append(_L( "\r\n" ) );
+ textptr.Append(_L( "\r\n" ) );
+ WriteLogL(textptr , fs);
+ CleanupStack::PopAndDestroy(text);
+ CleanupStack::PopAndDestroy(&fs); //fs
+ }
+
+LOCAL_C void WriteL( const TDesC8& aText , TInt aErr )
+ {
+ _LIT8(KErr,": %d");
+ HBufC8* text = HBufC8::NewLC(1000+20);
+ TBuf8<20> num;
+ TPtr8 textptr(text->Des());
+ textptr.Append(aText);
+ num.Format(KErr(),aErr);
+ textptr.Append(num);
+ WriteL(textptr);
+ CleanupStack::PopAndDestroy(text);
+#ifdef _MEM_HEAP_USAGE
+ WriteHeapAllocL();
+#endif //_MEM_HEAP_USAGE
+ }
+
+#ifdef _MEM_HEAP_USAGE
+LOCAL_C void WriteHeapAllocL()
+ {
+ _LIT8(KHeapUsage,"\r\n***** Heap cells allocated: %d *****\r\n");
+ TBuf8<256> string;
+ TInt size = 0;
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL(fs);
+ User::Heap().AllocSize(size);
+ string.Format(KHeapUsage(),size);
+ WriteLogL(string , fs);
+ CleanupStack::PopAndDestroy(&fs); //fs
+ }
+#endif //_MEM_HEAP_USAGE
+
+#endif //_DRM_TESTING
+
+
+
+// -----------------------------------------------------------------------------
+// DataFileL
+// return data filename as a TParse
+// -----------------------------------------------------------------------------
+//
+LOCAL_C TParse DataFileL(RFs& aFs)
+ {
+ TBuf<256> path;
+ TParse p;
+ User::LeaveIfError(aFs.PrivatePath(path));
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ p.Set(KHelperServerDataStorage,&path,NULL);
+
+#else //RD_MULTIPLE_DRIVE
+
+ TInt driveNumber( -1 );
+ TChar driveLetter;
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+ aFs.DriveToChar( driveNumber, driveLetter );
+
+ TFileName helperServerDataStorage;
+ helperServerDataStorage.Format(
+ KHelperServerDataStorage, (TUint)driveLetter );
+
+ p.Set( helperServerDataStorage, &path, NULL );
+
+#endif
+
+ return p;
+ }
+
+// -----------------------------------------------------------------------------
+// CreatePrivatePathL
+// Create private path
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void CreatePrivatePathL(RFs& aFs)
+ {
+#ifdef _DRM_TESTING
+ TRAPD( r , WriteL(_L8("CreatePrivatePathL")) );
+#endif
+
+#ifndef RD_MULTIPLE_DRIVE
+
+ TInt err = aFs.CreatePrivatePath(EDriveC);
+
+#else //RD_MULTIPLE_DRIVE
+
+ TInt driveNumber( -1 );
+ DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+
+ TInt err = aFs.CreatePrivatePath(driveNumber);
+
+#endif
+
+ if (err == KErrAlreadyExists)
+ {
+ err = KErrNone;
+ }
+ User::LeaveIfError(err);
+
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("CreatePrivatePathL->End")) );
+#endif
+ return;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CreateCRKeyL
+// Create CenRep Key
+// -----------------------------------------------------------------------------
+//
+LOCAL_C void CreateCRKeyL()
+ {
+#ifdef _DRM_TESTING
+ TRAPD( r , WriteL(_L8("CreateCRKeyL")) );
+#endif
+
+ CRepository* repository = CRepository::NewL(KCRUidDRMHelperServer);
+ CleanupStack::PushL( repository );
+ TInt err = repository->Create(KDRMHelperServerNotification, KNullDesC8);
+ if (err == KErrAlreadyExists)
+ {
+ err = KErrNone;
+ }
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("CreateCRKeyL->Create1"),err) );
+#endif
+
+ User::LeaveIfError(err);
+ err = repository->Create(KDRMHelperServerNotificationPassive, KNullDesC8);
+ if (err == KErrAlreadyExists)
+ {
+ err = KErrNone;
+ }
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("CreateCRKeyL->Create2"),err) );
+#endif
+ User::LeaveIfError(err);
+ CleanupStack::PopAndDestroy(repository); // repository
+
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("CreateCRKeyL->End")) );
+#endif
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::CDRMHelperServer
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CDRMHelperServer::CDRMHelperServer() :
+ CServer2( EPriorityStandard ) ,
+ iEndTimeFactory(NULL) ,
+ iNotifier(NULL),
+ iIdleObserver(NULL) ,
+ iUiTimeNotifier(NULL)
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CDRMHelperServer* CDRMHelperServer::NewLC()
+ {
+
+#ifdef _DRM_TESTING
+ CreateLogL();
+ TRAPD( err , WriteL(_L8("NewLC")) );
+#endif
+ CDRMHelperServer* self = new(ELeave) CDRMHelperServer;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ };
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::ConstructL()
+ {
+ TInt err = 0;
+
+#ifdef _DRM_TESTING
+ TRAPD( r , WriteL(_L8("ConstructL")) );
+#endif
+
+
+ TUint8 waitCount = 0;
+ User::LeaveIfError(iFs.Connect());
+ User::LeaveIfError(iDrm.StartServer());
+ User::LeaveIfError(iDrm.Connect());
+ StartL(KDRMHelperServerName);
+ //ignore errors
+ err = User::RenameProcess( KDRMHSServerFileName );
+ err = User::RenameThread(KDRMHSServerFileName);
+
+
+ CreatePrivatePathL(iFs); // create path for internal data file
+ iEndTimeFactory = CEndTimeFactory::NewL( *this );
+ err = KErrNotFound;
+ while( err!=0 && waitCount < 30 ) // wait maximum of 6s
+ {
+ TRAP( err , iNotifier = CDRMNotifier::NewL() );
+ if ( err ) // wait only if the server isn't running
+ {
+ User::After(200000); // 0.2s
+ waitCount++;
+ }
+ if (iNotifier)
+ {
+ iNotifier->RegisterEventObserverL( *this , KEventTimeChange );
+ }
+ }
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("ConstructL->Notifier")) );
+#endif
+ User::LeaveIfError( err ); // None can do, throw an exception.
+
+ iUiTimeNotifier = CEnvironmentChangeNotifier::NewL(
+ EPriorityHigh,
+ TCallBack(UiTimeChanged,this)
+ );
+ iUiTimeNotifier->Start();
+
+ iIdleObserver = CIdleObserver::NewL( *this );
+
+ iIdleObserver->StartL();
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("ConstructL->IdleObserver")) );
+#endif
+
+ CreateCRKeyL();
+ RestoreL();
+
+ iEndTimeFactory->HandleExpiredL();
+
+#ifdef _DRM_TESTING
+ TRAP( r , WriteL(_L8("ConstructL->End")) );
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::~CDRMHelperServer
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CDRMHelperServer::~CDRMHelperServer()
+ {
+#ifdef _DRM_TESTING
+ TRAPD( err , WriteL(_L8("destructor")) );
+#endif
+
+
+ if ( iEndTimeFactory )
+ {
+ TRAPD( error , StoreL() );
+ TRAP( error , RemoveAllL() );
+ }
+ delete iEndTimeFactory;
+ if (iNotifier)
+ {
+ TRAP_IGNORE( iNotifier->UnRegisterEventObserverL( *this , KEventTimeChange ) );
+ }
+ delete iNotifier;
+ if(iUiTimeNotifier)
+ {
+ iUiTimeNotifier->Cancel();
+ delete iUiTimeNotifier;
+ }
+ delete iIdleObserver;
+ iFs.Close();
+ iDrm.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::NewSessionL
+// Called when a client requires a new instance.
+// -----------------------------------------------------------------------------
+CSession2* CDRMHelperServer::NewSessionL(const TVersion &aVersion,
+ const RMessage2& /*aMessage*/ ) const
+ {
+ // check we're the right version
+ if (!User::QueryVersionSupported(TVersion(KDRMHSMajorVersionNumber,
+ KDRMHSMinorVersionNumber,
+ KDRMHSBuildVersionNumber),
+ aVersion))
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ // make new session
+ return CDRMHelperSession::NewL();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::StartupL().
+// This function starts the actual DRM Helper server after initializing
+// the cleanup stack and active scheduler.
+// Returns: TInt: Symbian OS error code.
+// -----------------------------------------------------------------------------
+//
+
+void CDRMHelperServer::StartupL()
+ {
+ // Construct active scheduler
+ CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL(activeScheduler) ;
+
+ // Install active scheduler
+ // We don't need to check whether an active scheduler is already installed
+ // as this is a new thread, so there won't be one
+ CActiveScheduler::Install(activeScheduler);
+
+ // Construct our server
+ CDRMHelperServer::NewLC();
+
+ RSemaphore semaphore;
+ User::LeaveIfError(semaphore.OpenGlobal(KDRMHelperServerSemaphoreName));
+
+ // Semaphore opened ok
+ semaphore.Signal();
+ semaphore.Close();
+
+ // Start handling requests
+ CActiveScheduler::Start();
+
+ CleanupStack::PopAndDestroy(2, activeScheduler); // anonymous CDRMHelperServer
+ }
+
+
+void CDRMHelperServer::PanicServer(TDRMHelperServPanic aPanic)
+ {
+ User::Panic(KDRMHSServer, aPanic);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::Startup().
+// This function starts the actual DRM Rights server after initializing
+// the cleanup stack and active scheduler.
+// Returns: TInt: Symbian OS error code.
+// -----------------------------------------------------------------------------
+//
+
+TInt CDRMHelperServer::Startup()
+ {
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ if (!cleanupStack)
+ {
+ PanicServer(ECreateTrapCleanup);
+ }
+ TRAPD(err, StartupL());
+ if (err != KErrNone)
+ {
+ PanicServer(ESrvCreateServer);
+ }
+ delete cleanupStack;
+ cleanupStack = NULL;
+
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::RunError().
+// This function handle errors from CActive
+// -----------------------------------------------------------------------------
+//
+TInt CDRMHelperServer::RunError(TInt aError)
+ {
+#ifdef _DRM_TESTING
+ TRAPD( err , WriteL(_L8("RunError")) );
+#endif
+
+
+ Message().Complete(aError);
+ //
+ // The leave will result in an early return from CServer::RunL(), skipping
+ // the call to request another message. So do that now in order to keep the
+ // server running.
+ ReStart();
+ return KErrNone; // handled the error fully
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::HandleExpiredL().
+// This function send expiration info out through CenRep
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::HandleExpiredL( CEndTimeBased*& aItem )
+ {
+#ifdef _DRM_TESTING
+ //test
+ _LIT8(KShowTimes , "Informed Times: %d");
+ TBuf8<40> timesBuf;
+ timesBuf.Format(KShowTimes , aItem->Count());
+ WriteL(_L8("HandleExpiredL"));
+ WriteL(aItem->Uri()->Des());
+ WriteL(timesBuf);
+#endif
+
+ HBufC8* buf = NULL;
+ TPtr8 ptr(NULL,0);
+ FormatKeyValueLC( buf , aItem , KExpiredMark ); // buf get pushed into cleanupstack
+ SetKeyValueL( *buf , aItem->RegType() );
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::FormatKeyValueLC().
+// This function format key for CenRep
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::FormatKeyValueLC(
+ HBufC8*& aBuf ,
+ CEndTimeBased*& aItem ,
+ const TDesC8& aMark )
+ {
+ TPtr8 ptr(NULL,0,0);
+
+ aBuf = HBufC8::NewLC( aItem->Uri()->Des().Length() + 4 );
+ ptr.Set(aBuf->Des());
+ ptr.Append(aItem->Count());
+ ptr.Append( aMark );
+ ptr.Append(aItem->PermType());
+ ptr.Append(aItem->AutoType());
+ ptr.Append( aItem->Uri()->Des() );
+
+ // a walk around for the symbian bugs in cenrep
+ TInt length = ptr.Length();
+ if (length&1)
+ {
+ ptr.SetLength(length+1);
+ ptr[length] = 0;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::HandleIdleL().
+// This function is called when phone enter idle status
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::HandleIdleL()
+ {
+#ifdef _DRM_TESTING
+ //test
+ WriteL(_L8("HandleIdleL"));
+#endif
+ iEndTimeFactory->HandleIdleL();
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::RegisterL().
+// This function register a item
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::RegisterL(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType ,
+ const TUint8& aAutoType )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("RegisterL"));
+ WriteL(aUri);
+#endif
+ TTime endTime = Time::MinTTime();
+ CheckExpirationL( aUri , aPermType , aRegType , endTime );
+ iEndTimeFactory->AddL( aUri , endTime , aPermType , aRegType , aAutoType );
+ GetNotificationL( aUri );
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::IsRegistered().
+// This function check if item is registered
+// -----------------------------------------------------------------------------
+//
+TBool CDRMHelperServer::IsRegistered(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType ,
+ const TUint8& aAutoType )
+ {
+#ifdef _DRM_TESTING
+ TRAPD(err,WriteL(_L8("IsRegisteredL(uri,perm,reg,auto)")));
+ TRAP(err,WriteL(aUri));
+#endif
+
+ return iEndTimeFactory->IsRegistered( aUri , aPermType , aRegType , aAutoType );
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::IsRegistered().
+// This function check if item is registered
+// -----------------------------------------------------------------------------
+//
+TBool CDRMHelperServer::IsRegistered(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType )
+ {
+#ifdef _DRM_TESTING
+ TRAPD(err,WriteL(_L8("IsRegisteredL(uri,perm,reg)")));
+ TRAP(err,WriteL(aUri));
+#endif
+
+ return iEndTimeFactory->IsRegistered( aUri , aPermType , aRegType );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::IsRegistered().
+// This function check if item is registered
+// -----------------------------------------------------------------------------
+//
+TBool CDRMHelperServer::IsRegistered2(
+ const TDesC8& aUri ,
+ const TUint8& aRegType,
+ const TUint8& aAutoType )
+ {
+#ifdef _DRM_TESTING
+ TRAPD(err,WriteL(_L8("IsRegisteredL(uri,reg,auto)")));
+ TRAP(err,WriteL(aUri));
+#endif
+
+ return iEndTimeFactory->IsRegistered2( aUri, aRegType, aAutoType );
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::UpdateL().
+// This function update all items
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::UpdateL()
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("UpdateL(all)"));
+#endif
+
+ iEndTimeFactory->UpdateL();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::UpdateL().
+// This function update items with a URI
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::UpdateL( const TDesC8& aUri )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("UpdateL(aUri)"));
+ WriteL(aUri);
+#endif
+
+ UpdateL( aUri , ContentAccess::EView);
+ UpdateL( aUri , ContentAccess::EPlay);
+ UpdateL( aUri , ContentAccess::EExecute);
+ UpdateL( aUri , ContentAccess::EPrint);
+
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::UpdateL().
+// This function update items with a URI and a permission type
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::UpdateL(
+ const TDesC8& aUri ,
+ const TUint8& aPermType )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("UpdateL(aUri,aPerm)"));
+ WriteL(aUri);
+#endif
+
+ UpdateL( aUri , aPermType , CDRMHelperServer::EActive );
+ UpdateL( aUri , aPermType , CDRMHelperServer::EPassive );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::UpdateL().
+// This function update items with a URI, a permission type and a register type
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::UpdateL(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("UpdateL(aUri,aPerm,aReg)"));
+ WriteL(aUri);
+#endif
+
+ TTime endTime;
+ TBool reg = IsRegistered(aUri , aPermType , aRegType);
+ if (reg)
+ {
+ CheckExpirationL( aUri , aPermType , aRegType , endTime );
+ iEndTimeFactory->UpdateEndTimeL( aUri , endTime , aPermType , aRegType );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::UpdateL().
+// This function update items with a URI, a permission type and a register type
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::UpdateL(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType ,
+ const TUint8& aAutoType )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("UpdateL(aUri,aPerm,aReg,aAutoType)"));
+ WriteL(aUri);
+#endif
+
+ TTime endTime;
+ CheckExpirationL( aUri , aPermType , aRegType , endTime );
+ iEndTimeFactory->UpdateEndTimeL( aUri , endTime , aPermType , aRegType , aAutoType );
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::RemoveL().
+// This function update an item
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::RemoveL(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType ,
+ const TUint8& aAutoType )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("RemoveL"));
+ WriteL(aUri);
+#endif
+
+ TBool found = iEndTimeFactory->IsRegistered( aUri , aPermType , aRegType , aAutoType );
+ if (found)
+ {
+ iEndTimeFactory->Remove( aUri , aPermType , aRegType , aAutoType );
+ iEndTimeFactory->ResetAlarm();
+ if ( !iEndTimeFactory->IsRegistered( aUri ) )
+ {
+ RemoveNotificationL( aUri );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::RemoveAllL().
+// This function removes all items
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::RemoveAllL()
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("RemoveAllL"));
+#endif
+
+ iEndTimeFactory->RemoveAllL();
+ }
+
+
+ContentAccess::TIntent CDRMHelperServer::MapPermissionType(TUint8 aPermType)
+ {
+ switch(aPermType)
+ {
+ case ContentAccess::EPlay:
+ return ContentAccess::EPlay;
+ case ContentAccess::EView:
+ return ContentAccess::EView;
+ case ContentAccess::EExecute:
+ return ContentAccess::EExecute;
+ case ContentAccess::EPrint:
+ return ContentAccess::EPrint;
+ default:
+ break;
+ }
+ return ContentAccess::EUnknown;
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::CheckPermission().
+// This function check timebased contraints for a permission
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::CheckPermission(
+ CDRMPermission* aPermission ,
+ const TUint8& aPermType ,
+ TTimeBased& aTime ,
+ TTimeIntervalSeconds& aInterval,
+ const RPointerArray<HBufC8>& aIndividual )
+ {
+#ifdef _DRM_TESTING
+ TRAPD(err,WriteL(_L8("CheckPermission")));
+#endif
+
+ CDRMConstraint* c = NULL;
+ ContentAccess::TIntent type = MapPermissionType(aPermType);
+ TTime temp;
+ temp.HomeTime();
+ TUint32 reason( 0 );
+ TBool validity = EFalse;
+
+ aTime.SetStart(Time::MinTTime());
+ aTime.SetEnd(Time::MinTTime());
+ if (aPermission->iAvailableRights & type)
+ {
+ c = aPermission->ConstraintForIntent(type);
+ if (!c)
+ {
+ return;
+ }
+ if (aPermission->iAvailableRights & ERightsTopLevel)
+ {
+ CDRMConstraint* temp = aPermission->TopLevelConstraint();
+ c->Merge(*temp);
+ }
+
+ validity = c->Valid( temp, aIndividual, reason );
+ if ( !validity && reason & EConstraintIndividual )
+ {
+ return;
+ }
+ if (c->iActiveConstraints==EConstraintNone ||
+ c->iActiveConstraints == EConstraintIndividual )
+ {
+ aTime.SetStart(Time::MinTTime());
+ aTime.SetEnd(Time::MaxTTime());
+ return;
+ }
+ if (c->iActiveConstraints & EConstraintInterval)
+ {
+ if (c->iIntervalStart == Time::NullTTime())
+ {
+ aInterval = c->iInterval;
+ }
+ else
+ {
+ aTime.SetStart(c->iIntervalStart);
+ aTime.SetEnd(c->iIntervalStart + c->iInterval);
+ }
+ }
+ if (c->iActiveConstraints & EConstraintStartTime)
+ {
+ if ( !(c->iActiveConstraints & EConstraintInterval ) )
+ {
+ aTime.SetStart( c->iStartTime );
+ if (c->iActiveConstraints&EConstraintEndTime)
+ {
+ aTime.SetEnd( c->iEndTime );
+ }
+ else
+ {
+ aTime.SetEnd( Time::MaxTTime() );
+ }
+ }
+ else
+ {
+ aTime.SetStart( aTime.StartTime() > c->iStartTime ? aTime.StartTime() : c->iStartTime );
+ if (c->iActiveConstraints&EConstraintEndTime)
+ {
+ aTime.SetEnd( aTime.EndTime() < c->iEndTime ? aTime.EndTime() : c->iEndTime );
+ }
+ }
+ }
+ else
+ {
+ if (c->iActiveConstraints==EConstraintEndTime)
+ {
+ if ( !(c->iActiveConstraints & EConstraintInterval ) )
+ {
+ aTime.SetStart(Time::MinTTime());
+ aTime.SetEnd( c->iEndTime );
+ }
+ else
+ {
+ aTime.SetEnd( aTime.EndTime() < c->iEndTime ? aTime.EndTime() : c->iEndTime );
+ }
+ }
+ }
+ }
+#ifdef _DRM_TESTING
+ TRAP(err,WriteL(_L8("Start Time:")));
+ TRAP(err,WriteTimeL(aTime.StartTime()));
+ TRAP(err,WriteL(_L8("End Time:")));
+ TRAP(err,WriteTimeL(aTime.EndTime()));
+#endif
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::CheckExpirationL().
+// This function check the time for rights to expire
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::CheckExpirationL(
+ const TDesC8& aUri ,
+ const TUint8& aPermType ,
+ const TUint8& aRegType ,
+ TTime& aEndTime )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("CheckExpiration"));
+#endif
+
+
+ RPointerArray<CDRMPermission> rights;
+ RArray<TTimeBased> timeList;
+ TBool stop = EFalse;
+ TInt i = 0;
+ TInt err = 0;
+ TTimeIntervalYears years(KTimeIntervalYears);
+ TTime time = Time::MinTTime();
+ TTimeBased item;
+ TTimeIntervalSeconds interval = 0;
+ RPointerArray<HBufC8> imsi;
+
+ aEndTime = Time::MinTTime();
+
+
+ TRAP( err , iDrm.GetDBEntriesL(aUri, rights) );
+ CleanupClosePushL(rights);
+ if ( err == KErrCANoRights || err == KErrCANoPermission )
+ {
+ aEndTime = Time::MinTTime();
+ err = KErrNone;
+ stop = ETrue;
+ }
+ User::LeaveIfError(err);
+
+ TRAP( err, iDrm.GetSupportedIndividualsL( imsi ) );
+
+ if ( err )
+ {
+ imsi.ResetAndDestroy();
+ }
+
+ time.HomeTime();
+ // Goes through all the rights associated to this specific URI
+ CleanupClosePushL(timeList);
+
+ for (i = 0; i < rights.Count() && !stop; i++)
+ {
+ CheckPermission( rights[i], aPermType, item, interval ,imsi );
+ if (interval.Int()>0 ||
+ (item.StartTime()==Time::MinTTime()&&item.EndTime()==Time::MaxTTime()))
+ {
+ stop = ETrue;
+ aEndTime = Time::MaxTTime();
+ }
+ else
+ {
+ if (aRegType == CDRMHelperServer::EActive && item.StartTime()>time)
+ {
+ // dont count future time for active usage
+ }
+ else
+ {
+ err = timeList.Append( item );
+ if ( err )
+ {
+ rights.ResetAndDestroy();
+ imsi.ResetAndDestroy();
+ }
+ User::LeaveIfError(err);
+ }
+ }
+ }
+ rights.ResetAndDestroy();
+ imsi.ResetAndDestroy();
+
+ // if there were no inactivated interval- or full-rights then calculate the expiration date
+ // based on what we stored to timeList
+ if( !stop )
+ {
+ time.HomeTime(); // preset time to current time. This is what we compare against.
+ TTime temp;
+ TTime pastTime;
+ temp = time;
+ pastTime = Time::MinTTime();
+
+ TBool action = ETrue;
+
+ // Loop while there are still items in the list and we have done something
+ while( action && timeList.Count() > 0 )
+ {
+ action = EFalse;
+ for ( i = 0 ; i < timeList.Count() ; i++ ) // go through the whole timeList
+ {
+#ifdef _DRM_TESTING
+ _LIT8(KCount , "time list count: %d");
+ TBuf8<40> buf;
+ buf.Format( KCount , timeList.Count());
+ WriteL( buf );
+#endif
+ if ( timeList[i].StartTime() <= time && timeList[i].EndTime() > time )
+ {
+ // Case1: valid rights
+ time = timeList[i].EndTime();
+ timeList.Remove(i);
+ action = ETrue;
+#ifdef _DRM_TESTING
+ WriteL(_L8("case 1:"));
+ WriteTimeL( time );
+#endif
+ }
+ else if ( timeList[i].StartTime() <= time && timeList[i].EndTime() <= time )
+ {
+ // Case2: expired rights
+ if (timeList[i].EndTime()>pastTime) // just in case there is no valid rights
+ {
+ pastTime = timeList[i].EndTime(); // save the latest end time from the expired rights
+ }
+ timeList.Remove(i);
+ action = ETrue;
+#ifdef _DRM_TESTING
+ WriteL(_L8("case 2:"));
+#endif
+ }
+ else if ( timeList[i].StartTime() > time && timeList[i].EndTime() <= time )
+ {
+ // Case3: Illegal case. Start time after end-time.
+ timeList.Remove(i);
+ action = ETrue;
+#ifdef _DRM_TESTING
+ WriteL(_L8("case 3:"));
+#endif
+ }
+ else
+ {
+ // Case4: Only thing left is the not yet valid -rights
+#ifdef _DRM_TESTING
+ WriteL(_L8("case 4:"));
+#endif
+ }
+ }
+ }
+
+ if (temp<time)
+ {
+ aEndTime = time; // time has been changed, so we use it, otherwise it means there is no valid rights
+ }
+ else
+ {
+ aEndTime = pastTime;
+ }
+
+
+#ifdef _DRM_TESTING
+ WriteL(_L8("expiration date:"));
+ WriteTimeL( aEndTime );
+#endif
+ }
+
+#ifdef _DRM_TESTING
+ WriteL(_L8("Endtime calculation is done:"));
+ WriteTimeL( aEndTime );
+#endif
+
+ timeList.Reset();
+ CleanupStack::PopAndDestroy(&timeList); // timeList
+ CleanupStack::PopAndDestroy(&rights); // rights
+ }
+
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::SetKeyValueL().
+// This function set CenRep key value
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::SetKeyValueL( const TDesC8& aKeyValue , const TUint8& aRegType )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("SetKeyValueL"));
+ WriteL( aKeyValue );
+#endif
+
+ // Connecting and initialization:
+ CRepository* repository = CRepository::NewL(KCRUidDRMHelperServer);
+ CleanupStack::PushL( repository );
+ if ( aRegType == CDRMHelperServer::EActive )
+ {
+ User::LeaveIfError(repository->Set(KDRMHelperServerNotification, aKeyValue));
+ }
+ else if ( aRegType == CDRMHelperServer::EPassive )
+ {
+ User::LeaveIfError(repository->Set(KDRMHelperServerNotificationPassive, aKeyValue));
+ }
+ CleanupStack::PopAndDestroy(repository); // repository
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::StoreL().
+// This function store internal list into data file
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::StoreL()
+ {
+
+#ifdef _DRM_TESTING
+ WriteL(_L8("StoreL"));
+#endif
+
+ RFileWriteStream file;
+ User::LeaveIfError(file.Replace( iFs , DataFileL(iFs).FullName() , EFileWrite ));
+ file.PushL();
+ ExternalizeL(file);
+ file.CommitL();
+ CleanupStack::PopAndDestroy(&file);//file
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::RestoreL().
+// This function restore internal list from data file
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::RestoreL()
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("RestoreL"));
+#endif
+
+ TInt err = 0;
+ RFileReadStream file;
+
+ RFile test;
+ err = test.Open( iFs , DataFileL(iFs).FullName() , EFileRead );
+ if ( !err )
+ {
+ CleanupClosePushL(test);
+ TInt size = 0;
+ err = test.Size(size);
+ User::LeaveIfError(err);
+ CleanupStack::PopAndDestroy(&test); //test
+ if (size == 0)
+ {
+ StoreL();
+ }
+ }
+ else if ( err == KErrNotFound )
+ {
+ StoreL();
+ }
+ else
+ {
+ User::Leave(err);
+ }
+
+ User::LeaveIfError(file.Open( iFs , DataFileL(iFs).FullName() , EFileRead ));
+ file.PushL();
+ InternalizeL(file);
+ CleanupStack::PopAndDestroy(&file); //file
+
+#ifdef _DRM_TESTING
+ WriteL(_L8("RestoreL->End"));
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::ExternalizeL().
+// This function externalize internal list
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::ExternalizeL(RWriteStream& aStream) const
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("ExternalizeL"));
+#endif
+ aStream << *iEndTimeFactory;
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::InternalizeL().
+// This function internalizeL internal list
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::InternalizeL(RReadStream& aStream)
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("InternalizeL"));
+#endif
+ iEndTimeFactory->InternalizeL(aStream);
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::GetNotificationL().
+// This function register event listening to DRM notifier
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::GetNotificationL(const TDesC8& aUri)
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("GetNotificationL"));
+#endif
+ iNotifier->RegisterEventObserverL( *this , KEventAddRemove , aUri );
+ iNotifier->RegisterEventObserverL( *this , KEventModify , aUri );
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::RemoveNotificationL().
+// This function remove event listening to DRM notifier
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::RemoveNotificationL(const TDesC8& aUri)
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("RemoveNotificationL"));
+#endif
+ iNotifier->UnRegisterEventObserverL( *this , KEventAddRemove , aUri );
+ iNotifier->UnRegisterEventObserverL( *this , KEventModify , aUri );
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::HandleEventL().
+// This function handle event from DRM notifier
+// -----------------------------------------------------------------------------
+//
+void CDRMHelperServer::HandleEventL( MDRMEvent* aEvent )
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("HandleEventL"));
+#endif
+
+ HBufC8* contentID = 0;
+ TDRMEventType event;
+
+ aEvent->GetEventType(event);
+
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier:"),event);
+#endif
+ switch(event)
+ {
+ case KEventAddRemove:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: EventAddRemove"));
+#endif
+ contentID = REINTERPRET_CAST( CDRMEventAddRemove* , aEvent )->GetContentIDL();
+ CleanupStack::PushL( contentID );
+#ifdef _DRM_TESTING
+ WriteL(contentID->Des());
+#endif
+ switch( REINTERPRET_CAST( CDRMEventAddRemove* , aEvent )->Status() )
+ {
+ case ERightsObjectRecieved:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: RightsObjectRecieved"));
+#endif
+ UpdateL( contentID->Des() );
+ }
+ break;
+ case ERightsObjectDeleted:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: RightsObjectDeleted"));
+#endif
+ UpdateL( contentID->Des() );
+ }
+ break;
+ case ERightsObjectDeletedAll:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: RightsObjectDeletedAll"));
+#endif
+ UpdateL( contentID->Des() );
+ }
+ break;
+ default:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: Unknown event"));
+#endif
+ }
+ break;
+ }
+ CleanupStack::PopAndDestroy( contentID );
+ }
+ break;
+ case KEventModify:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: EventModify"));
+#endif
+ contentID = REINTERPRET_CAST( CDRMEventModify* , aEvent )->GetContentIDL();
+ CleanupStack::PushL( contentID );
+#ifdef _DRM_TESTING
+ WriteL(contentID->Des());
+#endif
+ UpdateL( contentID->Des() );
+ CleanupStack::PopAndDestroy( contentID );
+ }
+ break;
+ case KEventTimeChange:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: EventTimeChange"));
+#endif
+ UpdateL();
+ }
+ break;
+ default:
+ {
+#ifdef _DRM_TESTING
+ WriteL(_L8("Notifier: Unknown event"));
+#endif
+ }
+ break;
+
+ }
+ return;
+ }
+
+// -----------------------------------------------------------------------------
+// CDRMHelperServer::UiTimeChanged
+// CPeriodic callback function to update the clock
+// -----------------------------------------------------------------------------
+//
+TInt CDRMHelperServer::UiTimeChanged(void* aPointer)
+ {
+#ifdef _DRM_TESTING
+ TRAPD(r,WriteL(_L8("UiTimeChanged")));
+#endif
+ CDRMHelperServer* current = static_cast<CDRMHelperServer*>(aPointer);
+ TInt err = 0;
+ if(current)
+ {
+ if(current->iUiTimeNotifier->Change() & EChangesSystemTime)
+ {
+ TRAP_IGNORE( current->UpdateL() );
+ }
+ if(current->iUiTimeNotifier->Change() & EChangesLocale)
+ {
+ // time zone is changed
+ }
+ }
+#ifdef _DRM_TESTING
+ TRAP(r,WriteL(_L8("UiTimeChanged:->End"),current->iUiTimeNotifier->Change()));
+#endif
+ return err;
+ };
+
+
+TInt E32Main()
+ {
+ return CDRMHelperServer::Startup();
+ }
+// End of File