diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/agentv2/src/Oma2AgentContent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/agentv2/src/Oma2AgentContent.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,742 @@ +/* +* Copyright (c) 2002-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: OMA DRM ContentAccess::CContent implementation +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include + + +#include + + +#include "oma2agentcontent.h" +#include "oma2agentattributes.h" +#include "oma1dcf.h" +#include "oma2dcf.h" +#include "symmetric.h" +#include "DrmRights.h" +#include "Oma2DcfPartInfo.h" +#include "DrmProtectedRoParser.h" + +using namespace ContentAccess; + +// LOCAL FUNCTION PROTOTYPES +LOCAL_C TInt MapContentShareMode(TContentShareMode aMode); +template +LOCAL_C void PointerArrayResetDestroyAndClose(TAny* aPtr); + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// MapContentShareMode +// Maps the CAF specific file share mode to the RFs/RFile sharing mode +// ----------------------------------------------------------------------------- +// +TInt MapContentShareMode(TContentShareMode aMode) + { + TInt r = EFileRead | EFileShareAny; + + switch (aMode) + { + case EContentShareReadOnly: + r = EFileRead | EFileShareReadersOnly; + break; + case EContentShareReadWrite: + r = EFileRead | EFileShareReadersOrWriters; + break; + case EContentShareExclusive: + r = EFileRead | EFileShareExclusive; + break; + } + return r; + } + +// ----------------------------------------------------------------------------- +// PointerArrayResetDestroyAndClose +// Template method used to push RPointerArrays to the cleanup stack. Takes +// care of deleting all pointers in the array. +// ----------------------------------------------------------------------------- +// +template +void PointerArrayResetDestroyAndClose(TAny* aPtr) + { + (reinterpret_cast*>(aPtr))->ResetAndDestroy(); + (reinterpret_cast*>(aPtr))->Close(); + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// COma2AgentContent::COma2AgentContent +// Reset all member variables +// ----------------------------------------------------------------------------- +// +COma2AgentContent::COma2AgentContent(void): + iDcf(NULL), + iFilePosition(0), + iDataPosition(0), + iUri(NULL), + iCurrentContainer(NULL), + iNotifier(NULL), + iWatchedId(NULL) + { + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::ConstructL +// Initialize the agent from a URI (file name) and file mode, opens the +// the file and takes membership of the handle +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::ConstructL( + const TDesC& aUri, + TContentShareMode aShareMode) + { + iUri = aUri.AllocL(); + User::LeaveIfError(iRdb.Connect()); + User::LeaveIfError(iFs.Connect()); + User::LeaveIfError(iFs.ShareAuto()); + User::LeaveIfError(iFile.Open(iFs, aUri, MapContentShareMode(aShareMode))); + iDcf = CDcfCommon::NewL(iFile); + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::ConstructL +// Initialize the agent from a file handle, duplicates the handle +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::ConstructL(RFile& aFile) + { + TFileName name; + User::LeaveIfError(iRdb.Connect()); + User::LeaveIfError(iFile.Duplicate(aFile)); + User::LeaveIfError(iFs.Connect()); + User::LeaveIfError(iFs.ShareAuto()); + iFile.Name(name); + iUri = name.AllocL(); + iDcf = CDcfCommon::NewL(iFile); + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::NewL +// Two-phased constructors +// ----------------------------------------------------------------------------- +// +COma2AgentContent* COma2AgentContent::NewL( + const TDesC& aUri, + TContentShareMode aShareMode) + { + COma2AgentContent* self = NewLC(aUri, aShareMode); + CleanupStack::Pop(self); + return self; + } + +COma2AgentContent* COma2AgentContent::NewLC( + const TDesC& aUri, + TContentShareMode aShareMode) + { + COma2AgentContent* self=new(ELeave) COma2AgentContent(); + CleanupStack::PushL(self); + self->ConstructL(aUri, aShareMode); + return self; + } + +COma2AgentContent* COma2AgentContent::NewL(RFile& aFile) + { + COma2AgentContent* self = NewLC(aFile); + CleanupStack::Pop(self); + return self; + } + +COma2AgentContent* COma2AgentContent::NewLC(RFile& aFile) + { + COma2AgentContent* self=new(ELeave) COma2AgentContent(); + CleanupStack::PushL(self); + self->ConstructL(aFile); + return self; + } + + +// Destructor +COma2AgentContent::~COma2AgentContent() + { + iRdb.Close(); + iFile.Close(); + iFs.Close(); + delete iDcf; + delete iUri; + delete iCurrentContainer; + if (iNotifier != NULL) + { + if( iWatchedId ) + { + + TRAP_IGNORE( iNotifier->UnRegisterEventObserverL(*this, KEventAddRemove, *iWatchedId) ); + TRAP_IGNORE( iNotifier->UnRegisterEventObserverL(*this, KEventModify, *iWatchedId) ); + + } + + delete iNotifier; + } + delete iWatchedId; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::OpenContainer +// Checks if the part ID is valid and sets the current ID to the part ID +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::OpenContainer( + const TDesC& aUniqueId) + { + TInt r = KErrNotFound; + TInt err = KErrNone; + + // Only the outermost file can be opened, parts within the file don't have + // subparts, only attributes. + if (iCurrentContainer == NULL) + { + r = iDcf->CheckUniqueId(aUniqueId); + if (r == KErrNone) + { + + TRAP(err, iCurrentContainer = aUniqueId.AllocL() ); + if(err) + { + return err; + } + } + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::CloseContainer +// Resets the current part ID +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::CloseContainer() + { + TInt r = KErrNone; + + if (iCurrentContainer != NULL) + { + delete iCurrentContainer; + iCurrentContainer = NULL; + } + else + { + r = KErrNotFound; + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::GetEmbeddedObjectsL +// Returns all parts embedded in the current part +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::GetEmbeddedObjectsL( + RStreamablePtrArray& aArray) + { + TInt i; + CEmbeddedObject* part = NULL; + HBufC* id = NULL; + COma2Dcf* dcf2 = NULL; + + aArray.ResetAndDestroy(); + if (iCurrentContainer == NULL) + { + if (iDcf->iVersion == EOma2Dcf) + { + dcf2 = static_cast(iDcf); + for (i = 0; i < dcf2->iParts.Count(); i++) + { + id = CnvUtfConverter::ConvertToUnicodeFromUtf8L( + *dcf2->iParts[i]->iContentId); + CleanupStack::PushL(id); + part = CEmbeddedObject::NewL(*id, *dcf2->iParts[i]->iMimeType, + EContentObject); + CleanupStack::PopAndDestroy(id); + aArray.AppendL(part); + } + } + else + { + id = CnvUtfConverter::ConvertToUnicodeFromUtf8L( + *iDcf->iContentID); + CleanupStack::PushL(id); + part = CEmbeddedObject::NewL(*id, *iDcf->iMimeType, + EContentObject); + CleanupStack::PopAndDestroy(id); + aArray.AppendL(part); + } + } + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::GetEmbeddedObjectsL +// Returns all parts embedded in the current part, filtered by type +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::GetEmbeddedObjectsL( + RStreamablePtrArray& aArray, + TEmbeddedType aType) + { + if (aType == EContentObject) + { + GetEmbeddedObjectsL(aArray); + } + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::Search +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::Search( + RStreamablePtrArray& aArray, + const TDesC8& aMimeType, + TBool /*aRecursive*/) + { + TInt i; + TInt r = KErrNone; + RStreamablePtrArray parts; + CEmbeddedObject* item = NULL; + + TRAP(r, GetEmbeddedObjectsL(parts)); + for (i = 0; r == KErrNone && i < parts.Count(); i++) + { + if (parts[i]->MimeType().CompareF(aMimeType) == 0) + { + + TRAP_IGNORE( item = CEmbeddedObject::NewL( + parts[i]->UniqueId(), parts[i]->Name(), + parts[i]->MimeType(), parts[i]->Type()) ); + + TRAP(r, aArray.AppendL(item)); + } + } + parts.ResetAndDestroy(); + parts.Close(); + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::GetAttribute +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::GetAttribute( + TInt aAttribute, + TInt& aValue, + const TDesC& aUniqueId) + { + TInt r; + + r = iDcf->OpenPart(aUniqueId); + if (r == KErrNone) + { + TRAP(r,aValue = TOma2AgentAttributes::GetAttribute(*iDcf, aAttribute, + TVirtualPathPtr(*iUri, aUniqueId), &iRdb)); + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::GetAttributeSet +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::GetAttributeSet( + RAttributeSet& aAttributeSet, + const TDesC& aUniqueId) + { + TInt r; + TInt err = KErrNone; + + r = iDcf->OpenPart(aUniqueId); + if (r == KErrNone) + { + TRAP(err,r = TOma2AgentAttributes::GetAttributeSet(*iDcf, aAttributeSet, + TVirtualPathPtr(*iUri, aUniqueId), &iRdb)); + if (err != KErrNone) + { + return err; + } + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::GetStringAttribute +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::GetStringAttribute( + TInt aAttribute, + TDes& aValue, + const TDesC& aUniqueId) + { + TInt r = KErrNone; + TInt err = KErrNone; + + r = iDcf->OpenPart(aUniqueId); + if (r == KErrNone) + { + TRAP(err, r = TOma2AgentAttributes::GetStringAttribute(*iDcf, aAttribute, + aValue, TVirtualPathPtr(*iUri, aUniqueId), &iRdb)); + if(err != KErrNone) + { + return err; + } + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::GetStringAttributeSet +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::GetStringAttributeSet( + RStringAttributeSet& aStringAttributeSet, + const TDesC& aUniqueId) + { + TInt r; + TInt err = KErrNone; + + r = iDcf->OpenPart(aUniqueId); + if (r == KErrNone) + { + TRAP(err, r = TOma2AgentAttributes::GetStringAttributeSet(*iDcf, + aStringAttributeSet, TVirtualPathPtr(*iUri, aUniqueId), &iRdb)); + if(err != KErrNone) + { + return err; + } + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::AgentSpecificCommand +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::AgentSpecificCommand( + TInt aCommand, + const TDesC8& /*aInputBuffer*/, + TDes8& /*aOutputBuffer*/) + { + TInt r = KErrCANotSupported; + + if (aCommand == EEmbedDomainRo) + { + TRAP(r, EmbedDomainRoL()); + } + return r; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::AgentSpecificCommand +// +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::AgentSpecificCommand( + TInt aCommand, + const TDesC8& aInputBuffer, + TDes8& aOutputBuffer, + TRequestStatus& aStatus) + { + TRequestStatus *ptr = &aStatus; + User::RequestComplete(ptr, AgentSpecificCommand(aCommand, aInputBuffer, + aOutputBuffer)); + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::NotifyStatusChange +// +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::NotifyStatusChangeL( + TEventMask aEventMask, + TRequestStatus& aStatus, + const TDesC& aUniqueId) + { + TInt r = KErrNone; + TInt i; + TInt part = KErrNotFound; + COma2Dcf* dcf2 = NULL; + HBufC8* uniqueId = NULL; + + iStatus = &aStatus; + iWatchedEvents = aEventMask; + if (iWatchedId != NULL) + { + if( iNotifier ) + { + iNotifier->UnRegisterEventObserverL(*this, KEventAddRemove, *iWatchedId); + iNotifier->UnRegisterEventObserverL(*this, KEventModify, *iWatchedId); + } + delete iWatchedId; + iWatchedId = NULL; + } + if (iDcf->iVersion == EOma1Dcf || aUniqueId.Compare(KDefaultContentObject) == 0) + { + iWatchedId = iDcf->iContentID->AllocL(); + } + else + { + dcf2 = static_cast(iDcf); + uniqueId = CnvUtfConverter::ConvertFromUnicodeToUtf8L(aUniqueId); + CleanupStack::PushL(uniqueId); + for (i = 0; part == KErrNotFound && i < dcf2->iParts.Count(); i++) + { + if (dcf2->iParts[i]->iContentId->CompareF(*uniqueId) == 0) + { + iWatchedId = dcf2->iParts[i]->iContentId->AllocL(); + } + } + CleanupStack::PopAndDestroy(); + } + if (iWatchedId != NULL) + { + if (iNotifier == NULL) + { + iNotifier = CDRMNotifier::NewL(); + } + if (iNotifier != NULL) + { + iNotifier->RegisterEventObserverL(*this, KEventAddRemove, *iWatchedId); + iNotifier->RegisterEventObserverL(*this, KEventModify, *iWatchedId); + *iStatus = KRequestPending; + } + else + { + User::Leave(r); + } + } + else + { + User::Leave(KErrNotFound); + } + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::NotifyStatusChange +// +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::NotifyStatusChange( + TEventMask aEventMask, + TRequestStatus& aStatus, + const TDesC& aUniqueId) + { + TInt err = KErrNone; + TRequestStatus *status = 0; + TRAP(err, NotifyStatusChangeL( aEventMask, + aStatus, + aUniqueId )); + if(err) + { + status = &aStatus; + User::RequestComplete(status, err); + } + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::CancelNotifyStatusChange +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::CancelNotifyStatusChange( + TRequestStatus& aStatus, + const TDesC& /*aUniqueId*/) + { + iStatus = &aStatus; + if(iNotifier == NULL) + { + User::RequestComplete(iStatus, KErrNotFound); + return KErrNotFound; + } + + TRAP_IGNORE( iNotifier->UnRegisterEventObserverL(*this, KEventAddRemove, *iWatchedId) ); + TRAP_IGNORE( iNotifier->UnRegisterEventObserverL(*this, KEventModify, *iWatchedId) ); + + if (iWatchedId != NULL) + { + delete iWatchedId; + iWatchedId = NULL; + } + User::RequestComplete(iStatus, KErrCancel); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::RequestRights +// Opens the browser with the rights issuer URL +// ----------------------------------------------------------------------------- +// + +void COma2AgentContent::RequestRights( + TRequestStatus& aStatus, + const TDesC& aUniqueId) + { + TRequestStatus *ptr = &aStatus; + TInt r; + HBufC* b = NULL; + CSchemeHandler* handler = NULL; + + r = iDcf->OpenPart(aUniqueId); + if (r == KErrNone && iDcf->iRightsIssuerURL != NULL) + { + TRAP(r, b = CnvUtfConverter::ConvertToUnicodeFromUtf8L( + *iDcf->iRightsIssuerURL)); + if (b != NULL) + { + TRAP(r, handler = CSchemeHandler::NewL(*b)); + if (handler != NULL) + { + TRAP(r, handler->HandleUrlStandaloneL()); + delete handler; + } + delete b; + } + } + User::RequestComplete(ptr, r); + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::CancelRequestRights +// Not supported, getting rights is handled outside the scope of the agent and +// cannot be cancelled +// ----------------------------------------------------------------------------- +// + +TInt COma2AgentContent::CancelRequestRights( + TRequestStatus& aStatus, + const TDesC& /*aUniqueId*/) + { + TRequestStatus *ptr = &aStatus; + User::RequestComplete(ptr, KErrNone); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::DisplayInfoL +// +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::DisplayInfoL( + TDisplayInfo /*aDisplayInfo*/, + const TDesC& /*aUniqueId*/) + { + User::Leave(KErrCANotSupported); + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::SetProperty +// +// ----------------------------------------------------------------------------- +// +TInt COma2AgentContent::SetProperty( + TAgentProperty /*aProperty*/, + TInt /*aValue*/) + { + return KErrCANotSupported; + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::EmbedDomainRoL +// +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::EmbedDomainRoL() + { + RPointerArray roList; + TCleanupItem listCleanup(PointerArrayResetDestroyAndClose, + &roList); + COma2Dcf* dcf; + CDrmProtectedRoParser* parser = NULL; + RPointerArray rights; + + if (iDcf->iVersion == EOma2Dcf) + { + dcf = static_cast(iDcf); + + __UHEAP_MARK; + for (TInt i = 0; i < dcf->iRightsObjects.Count(); i++) + { + parser = CDrmProtectedRoParser::NewL(); + CleanupStack::PushL(parser); + TRAP_IGNORE( parser->ParseAndStoreL(*dcf->iRightsObjects[i], + rights)); + CleanupStack::PopAndDestroy(); // parser + rights.ResetAndDestroy(); + rights.Close(); + } + __UHEAP_MARKEND; + + iRdb.GetDomainRosForCidL(*dcf->iContentID, roList); + CleanupStack::PushL(listCleanup); + if(roList.Count()) + { + // this is not replaceable in UHEAP_MARK delimiters + dcf->SetRightsObjectsL(roList); + } + CleanupStack::PopAndDestroy(); // listCleanup + } + else + { + User::Leave(KErrArgument); + } + } + +// ----------------------------------------------------------------------------- +// COma2AgentContent::HandleEventL +// Handle notifier events here. Not much logic, consider all events as rights +// changes. +// ----------------------------------------------------------------------------- +// +void COma2AgentContent::HandleEventL( + MDRMEvent* /*aEvent*/) + { + TInt r; + TUint32 reason = 0; + + if ( iWatchedId != NULL) + { + r = iRdb.CheckRights(EUnknown, *iWatchedId, reason); + if (r == KErrNone && (iWatchedEvents & ERightsAvailable) || + r != KErrNone && (iWatchedEvents & ERightsExpired)) + { + iNotifier->UnRegisterEventObserverL(*this, KEventAddRemove, *iWatchedId); + iNotifier->UnRegisterEventObserverL(*this, KEventModify, *iWatchedId); + delete iWatchedId; + iWatchedId = NULL; + User::RequestComplete(iStatus, KErrNone); + } + } + } + +// End of File