--- a/commondrm/drmrightsmanagerui/src/DRMRightsMgrAppUi.cpp Fri Apr 16 15:14:55 2010 +0300
+++ b/commondrm/drmrightsmanagerui/src/DRMRightsMgrAppUi.cpp Mon May 03 12:46:34 2010 +0300
@@ -58,7 +58,70 @@
_LIT8( Kflk, "flk:" );
_LIT8( Kldf, "ldf:" );
-// ================= MEMBER FUNCTIONS =======================
+// ============================= LOCAL FUNCTIONS ===============================
+
+// ----------------------------------------------------------------------------
+// DoResetAndDestroy
+// Does RPointerArray< >->ResetAndDestroy() for the given array aPtr.
+// ----------------------------------------------------------------------------
+//
+LOCAL_C void DoResetAndDestroyPermission( TAny* aPtr )
+ {
+ ( reinterpret_cast< RPointerArray< CDRMPermission >* >( aPtr ) )->
+ ResetAndDestroy();
+ }
+
+// ----------------------------------------------------------------------------
+// PrepareRightsObjectL
+// Creates rights object based on the given permission.
+// ----------------------------------------------------------------------------
+//
+LOCAL_C void PrepareRightsObjectL( CDRMRights*& aRights,
+ CDRMPermission* aPermission )
+ {
+ CDRMAsset* asset( NULL );
+
+ if ( !aPermission )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ aRights = CDRMRights::NewL();
+ CleanupStack::PushL( aRights );
+ aRights->SetPermissionL( *aPermission );
+
+ asset = CDRMAsset::NewLC();
+ aRights->SetAssetL( *asset );
+ CleanupStack::PopAndDestroy( asset );
+ CleanupStack::Pop( aRights );
+
+ // Content URI and Local Id are not set
+ }
+
+// ----------------------------------------------------------------------------
+// EndTime
+// Calculate the true end time: pick the smaller one of aTime1 & aTime2,
+// but ignore Time::NullTTime anyhow.
+// ----------------------------------------------------------------------------
+//
+LOCAL_C TTime EndTime( const TTime& aTime1, const TTime& aTime2 )
+ {
+ TTime nullTime = Time::NullTTime();
+
+ if ( aTime1 == nullTime )
+ {
+ return aTime2;
+ }
+
+ if ( aTime2 == nullTime )
+ {
+ return aTime1;
+ }
+
+ return Min( aTime1, aTime2 );
+ }
+
+// ================= MEMBER FUNCTIONS ==========================================
//
// -----------------------------------------------------------------------------
// CDRMRightsMgrAppUi::CDRMRightsMgrAppUi
@@ -92,6 +155,7 @@
EAknEnableMSK | EAknSingleClickCompatible );
User::LeaveIfError( iRightsClient.Connect() );
+ User::LeaveIfError( iClockClient.Connect() );
iDRMCommon = DRMCommon::NewL();
if ( !iDRMCommon )
{
@@ -129,6 +193,8 @@
delete iDRMCommon;
iRightsClient.Close();
+
+ iClockClient.Close();
if ( iStartEmbedded && iDoorObserver )
{
@@ -557,8 +623,8 @@
// from the background to the foreground.
if ( iForegroundHasBeenActive && iContentURI )
{
- StartOnlyForDetailsL( iContentURI->Des(), iLocalID,
- iStartEmbedded, iDrmScheme );
+ TRAP_IGNORE( StartOnlyForDetailsL( iContentURI->Des(), iLocalID,
+ iStartEmbedded, iDrmScheme ) );
}
}
@@ -739,7 +805,10 @@
{
TBool listable( EFalse ), sendable( EFalse );
TBool individualConstraint( EFalse ), usageAllowed( EFalse );
+ TInt err( KErrNone );
+
+ aStatus = KErrNone;
CDcfRep* dcfRep = CDcfRep::NewL();
CleanupStack::PushL( dcfRep );
@@ -798,23 +867,32 @@
{
aStatus = iDRMCommon->GetSingleRightsObject( aContentURI,
aLocalID, aRights );
- if ( aStatus )
- {
- aRights = NULL;
- }
+ CheckIndividualConstraint( aContentURI, individualConstraint, usageAllowed );
+ SetSelectedIndividualConstraint( individualConstraint );
+ SetSelectedUsageAllowed( usageAllowed );
}
else
{
- aStatus = iDRMCommon->GetActiveRights( aContentURI, 0, aRights );
+ SetSelectedIndividualConstraint( EFalse );
+ SetSelectedUsageAllowed( ETrue );
+
+ // Get active rights if available
+ err = iDRMCommon->GetActiveRights( aContentURI, 0, aRights );
+
+ if ( err < 0 )
+ {
+ // Find out the best composition of rights that should be shown in the
+ // details view. Checks also individual constraint.
+ TRAP( aStatus, FindBestCompositionRightsL( aContentURI, aRights ) );
+ }
+ }
+
+ if ( aStatus )
+ {
+ aRights = NULL;
}
- CheckIndividualConstraint( aContentURI, individualConstraint, usageAllowed );
- SetSelectedIndividualConstraint( individualConstraint );
- SetSelectedUsageAllowed( usageAllowed );
-
CleanupStack::PopAndDestroy( dcfRep );
-
- // Do not show the note, show license information in the details view.
}
// ---------------------------------------------------------
@@ -880,23 +958,18 @@
TBool& aIndividualConstraint,
TBool& aUsageAllowed )
{
+
+ TTime time;
+ RPointerArray<HBufC8> individuals;
+
RPointerArray<CDRMRights>* uriList = NULL;
TInt r = KErrNone;
TUint32 retval(0);
+ TInt timeZone(0);
DRMClock::ESecurityLevel secLevel = DRMClock::KInsecure;
CDRMRightsConstraints* constraint = NULL;
- RDRMClockClient client;
- RDRMRightsClient rclient;
- TTime time;
- RPointerArray<HBufC8> individuals;
-
- r = client.Connect();
- if ( r == KErrNone )
- {
- TTime time;
- TInt timeZone(0);
- client.GetSecureTime(time, timeZone, secLevel);
- }
+
+ iClockClient.GetSecureTime(time, timeZone, secLevel);
r = iDRMCommon->GetDetailedContentRights(aContentURI, uriList);
if ( r )
@@ -909,19 +982,13 @@
if ( !uriList || !uriList->Count() )
{
// no rights found
- client.Close();
delete uriList;
uriList = NULL;
}
else
{
// supported IMSI information is provided by rights client
- r = rclient.Connect();
- if( r == KErrNone)
- {
- TRAP( r, r = rclient.GetSupportedIndividualsL( individuals ) );
- rclient.Close();
- }
+ TRAP( r, r = iRightsClient.GetSupportedIndividualsL( individuals ) );
// Check only the first entry in the list. This is to be expanded to check
// all the entries in the list.
@@ -959,7 +1026,6 @@
constraint = NULL;
}
- client.Close();
uriList->ResetAndDestroy();
delete uriList;
@@ -969,4 +1035,498 @@
}
}
+// ---------------------------------------------------------
+// CDRMRightsMgrAppUi::FindBestCompositionRightsL
+// ---------------------------------------------------------
+//
+void CDRMRightsMgrAppUi::FindBestCompositionRightsL( const TDesC8& aContentURI,
+ CDRMRights*& aRights )
+ {
+ TInt i, j, k;
+ RPointerArray<CDRMPermission> permissionList;
+ RPointerArray<CDRMPermission> permissionTempList;
+ RPointerArray<HBufC8> parentUidList;
+ RPointerArray<HBufC8> individuals;
+
+ TInt count( 0 );
+ TInt status( KErrNone );
+ TTime time( Time::NullTTime() );
+ TInt err( KErrNone );
+ TUint32 reason( EConstraintNone );
+ TBool individualConstraintFound( EFalse );
+
+ // Composition object of best rights to be shown in the
+ // details view
+ CDRMPermission* perm( NULL );
+
+ TCleanupItem cleanupPerm( DoResetAndDestroyPermission, &permissionList );
+ CleanupStack::PushL( cleanupPerm );
+
+ TCleanupItem cleanupPerm2( DoResetAndDestroyPermission,
+ &permissionTempList );
+ CleanupStack::PushL( cleanupPerm2 );
+
+ CleanupClosePushL( parentUidList );
+
+ // First get list of child ROs with the given Content URI
+ iRightsClient.GetDBEntriesL( aContentURI, permissionList );
+
+ if ( permissionList.Count() > 0 )
+ {
+ // Check the UIDs of the possible parent rights objects
+ // and store the found ones to another pointer array for evaluation
+ for ( i = 0; i < permissionList.Count(); i++ )
+ {
+ if ( permissionList[i]->iParentUID )
+ {
+ if ( i == 0 )
+ {
+ // No need to check if the parent UID is a duplicate
+ parentUidList.Append( permissionList[i]->iParentUID );
+ }
+ else
+ {
+ // Check parent UID list whether we have already stored the
+ // UID or not
+ for( j = 0; j < parentUidList.Count(); j++ )
+ {
+ if ( parentUidList[j]->Des().Compare(
+ permissionList[i]->iParentUID->Des() ) != 0 )
+ {
+ parentUidList.Append(
+ permissionList[i]->iParentUID );
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Get the list of parent rights objects based on the parent UID
+ // and store the pointers from temporary array to the main list
+ for ( j = 0; j < parentUidList.Count(); j++ )
+ {
+ // We do not want to leave if nothing is found from the database
+ TRAP( status, iRightsClient.GetDBEntriesL( parentUidList[j]->Des(),
+ permissionTempList ) );
+
+ if ( status )
+ {
+ continue;
+ }
+
+ for ( k = 0; k < permissionTempList.Count(); k++ )
+ {
+ // Store the pointer to the main list of permissions
+ permissionList.Append( permissionTempList[k] );
+ }
+
+ // Close the temporary pointer array so that the referenced
+ // objects of it will not be deleted in the next round of the
+ // loop because the method for getting database entries deletes
+ // also the objects (by calling reset and destroy to the given
+ // pointer array) by default.
+ permissionTempList.Close();
+ }
+
+ parentUidList.Close();
+ time.HomeTime();
+
+ // supported IMSI information is provided by rights client
+ TRAP( err, err = iRightsClient.GetSupportedIndividualsL( individuals ) );
+
+ // Filter expired parent and child rights from the list
+ // Index defines the index of the list to be operated (next)
+ for ( count = permissionList.Count() ; count > 0; count-- )
+ {
+ if ( permissionList[count - 1]->Expired( time ) )
+ {
+ permissionList.Remove( count - 1 );
+ }
+ else if ( !( permissionList[count - 1]->Valid(
+ time, individuals, reason ) ) )
+ {
+ if ( reason & EConstraintIndividual )
+ {
+ individualConstraintFound = ETrue;
+ permissionList.Remove( count - 1 );
+ }
+ }
+ }
+
+ individuals.ResetAndDestroy();
+ individuals.Close();
+
+ if ( permissionList.Count() == 0 )
+ {
+ if ( individualConstraintFound )
+ {
+ SetSelectedIndividualConstraint( ETrue );
+ SetSelectedUsageAllowed( EFalse );
+ }
+ User::Leave( KErrNotFound );
+ }
+ else if ( permissionList.Count() == 1 )
+ {
+ // Keep this permission because it is the only valid (left)
+ PrepareRightsObjectL( aRights, permissionList[0] );
+ }
+ else if ( permissionList.Count() > 1 )
+ {
+ // Compare constraints from successive items of the
+ // permission list and update the composition permission
+ // accordingly.
+ CheckBetterPermissionsAndStoreCompositionLC( perm, permissionList );
+
+ // Prepare the rights object with the composition permission
+ PrepareRightsObjectL( aRights, perm );
+ CleanupStack::PopAndDestroy( perm );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 3, &permissionList ); // cleanupPerm,
+ // cleanupPerm2,
+ // parentUidList
+ }
+
+// -------------------------------------------------------------------
+// CDRMRightsMgrAppUi::CheckBetterPermissionsAndStoreCompositionLC
+// -------------------------------------------------------------------
+//
+void CDRMRightsMgrAppUi::CheckBetterPermissionsAndStoreCompositionLC(
+ CDRMPermission*& aCompositionPermission,
+ RPointerArray<CDRMPermission>& aList )
+ {
+
+ TBool firstBetter( EFalse );
+ TUint i, j;
+
+ if ( aList.Count() <= 0 )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ // create permission if needed and set the first item
+ // in the permission list as the reference permission.
+ if ( !aCompositionPermission )
+ {
+ aCompositionPermission = CDRMPermission::NewL();
+ }
+
+ CleanupStack::PushL( aCompositionPermission );
+ aCompositionPermission->DuplicateL( *aList[0] );
+
+ // The double loop goes through the permissions and associated
+ // constraints beginning from the second entry in the permission list.
+ for ( i = 1; i < aList.Count(); i++ )
+ {
+ // Enumeration for TIntent from Content Access Framework used
+ for ( j = EPlay; j < EPause; j++ )
+ {
+ switch ( j )
+ {
+ case EPlay:
+ {
+ // The constraint from the permission in the list
+ // is set to composition permission if it is better
+ // than the "old" best or reference permission.
+ firstBetter = BetterPermission( *aList[i]->iPlay,
+ *aCompositionPermission->iPlay );
+ if ( firstBetter )
+ {
+ aCompositionPermission->iPlay->DuplicateL(
+ *aList[i]->iPlay );
+ }
+ break;
+ }
+ case EView:
+ {
+ firstBetter = BetterPermission( *aList[i]->iDisplay,
+ *aCompositionPermission->iDisplay );
+ if ( firstBetter )
+ {
+ aCompositionPermission->iDisplay->DuplicateL(
+ *aList[i]->iDisplay );
+ }
+ break;
+ }
+ case EExecute:
+ {
+ firstBetter = BetterPermission( *aList[i]->iExecute,
+ *aCompositionPermission->iExecute );
+ if ( firstBetter )
+ {
+ aCompositionPermission->iExecute->DuplicateL(
+ *aList[i]->iExecute );
+ }
+ break;
+ }
+ case EPrint:
+ {
+ firstBetter = BetterPermission( *aList[i]->iPrint,
+ *aCompositionPermission->iPrint );
+ if ( firstBetter )
+ {
+ aCompositionPermission->iPrint->DuplicateL(
+ *aList[i]->iPrint );
+ }
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CDrmRightsMgrAppUi::BetterPermission
+// -----------------------------------------------------------------------------
+TBool CDRMRightsMgrAppUi::BetterPermission( const CDRMConstraint& aNewOne,
+ const CDRMConstraint& aOldOne )
+ {
+ // Check Order:
+ // 1. Full
+ // 2. Start End, closest end time first
+ // 3. Interval, shortest first
+ // 4. Accumulated, shortest first
+ // 5. Timed Counter, least counters first, longest time first
+ // 6. Counter, least counters first or the first one found
+
+ const TTime nullTime = Time::NullTTime();
+ TTime oldTime = nullTime;
+ TTime newTime = nullTime;
+ TTime oldTimePos = nullTime;
+ TTime newTimePos = nullTime;
+ TTime trustedTime = nullTime;
+
+ // 1. Full
+ // If the old or new one is the ultimate one, don't bother to
+ // check anything else.
+ if ( aOldOne.iActiveConstraints == EConstraintNone )
+ {
+ return EFalse;
+ }
+
+ if ( aNewOne.iActiveConstraints == EConstraintNone )
+ {
+ return ETrue;
+ }
+
+ // 2. Start & End Time
+ // Choose the one with the closest end time first
+ // All RO's to this check are already checked to be valid
+ // ActiveIntervals Also hit this spot
+
+ trustedTime.HomeTime();
+
+ // First get the start and end times from the intervals if they are active or inactive:
+ if ( aOldOne.iActiveConstraints & EConstraintInterval )
+ {
+ if( aOldOne.iIntervalStart == nullTime )
+ {
+ oldTimePos = trustedTime;
+ oldTimePos += TTimeIntervalSeconds( aOldOne.iInterval );
+ }
+ else
+ {
+ oldTime = aOldOne.iIntervalStart;
+ oldTime += TTimeIntervalSeconds( aOldOne.iInterval );
+ }
+ }
+
+ if( aNewOne.iActiveConstraints & EConstraintInterval )
+ {
+ if( aNewOne.iIntervalStart == nullTime )
+ {
+ newTimePos = trustedTime;
+ newTimePos += TTimeIntervalSeconds( aNewOne.iInterval );
+ }
+ else
+ {
+ newTime = aNewOne.iIntervalStart;
+ newTime += TTimeIntervalSeconds( aNewOne.iInterval );
+ }
+ }
+
+ if ( aOldOne.iActiveConstraints & EConstraintEndTime || oldTime != nullTime )
+ {
+ oldTime = EndTime( oldTime, aOldOne.iEndTime );
+
+ if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime )
+ {
+ newTime = EndTime( newTime, aNewOne.iEndTime );
+
+ if( newTime != oldTime )
+ {
+ return ( newTime < oldTime );
+ }
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ else if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime )
+ {
+ return ETrue;
+ }
+
+ // 3. Inactive Intervals:
+ // Choose the one with the interval ending first:
+ // Continue here if the no SE's exist or SE's are the same
+ if( aOldOne.iActiveConstraints & EConstraintInterval )
+ {
+ if( aNewOne.iActiveConstraints & EConstraintInterval )
+ {
+ oldTimePos = EndTime( oldTime, oldTimePos );
+ newTimePos = EndTime( newTime, newTimePos );
+
+ if( oldTimePos != newTimePos )
+ {
+ return ( newTimePos < oldTimePos );
+ }
+ }
+ else
+ {
+ if( aNewOne.iActiveConstraints & EConstraintAccumulated ||
+ aNewOne.iActiveConstraints & EConstraintTimedCounter ||
+ aNewOne.iActiveConstraints & EConstraintCounter )
+ {
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ }
+ else if( aNewOne.iActiveConstraints & EConstraintInterval )
+ {
+ if( aOldOne.iActiveConstraints & EConstraintAccumulated ||
+ aOldOne.iActiveConstraints & EConstraintTimedCounter ||
+ aOldOne.iActiveConstraints & EConstraintCounter )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ // 4. Accumulated:
+ // Choose the shortest accumulated first
+ // Continue here if SE's or intervals do not exist or they are the same
+ if( aOldOne.iActiveConstraints & EConstraintAccumulated )
+ {
+ if( aNewOne.iActiveConstraints & EConstraintAccumulated )
+ {
+ if( aNewOne.iAccumulatedTime != aOldOne.iAccumulatedTime )
+ {
+ return ( aNewOne.iAccumulatedTime < aOldOne.iAccumulatedTime );
+ }
+ }
+ else
+ {
+ if( aNewOne.iActiveConstraints & EConstraintTimedCounter ||
+ aNewOne.iActiveConstraints & EConstraintCounter )
+ {
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ }
+ else if( aNewOne.iActiveConstraints & EConstraintAccumulated )
+ {
+ if( aOldOne.iActiveConstraints & EConstraintTimedCounter ||
+ aOldOne.iActiveConstraints & EConstraintCounter )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+
+ // 5. Timed Counter
+ // Choose the one with least counters first. If there is an equal number of counters
+ // left, use the one with the longest time
+ // Continue here if SE's or intervals or accumulateds do not exist or they are the same
+ if( aOldOne.iActiveConstraints & EConstraintTimedCounter )
+ {
+ if( aNewOne.iActiveConstraints & EConstraintTimedCounter )
+ {
+ if( aNewOne.iTimedCounter == aOldOne.iTimedCounter )
+ {
+ if( aNewOne.iTimedInterval != aOldOne.iTimedInterval )
+ {
+ return ( aNewOne.iTimedInterval < aOldOne.iTimedInterval );
+ }
+ else
+ {
+ if( aNewOne.iActiveConstraints & EConstraintCounter )
+ {
+
+ }
+ }
+ }
+ else
+ {
+ return ( aNewOne.iTimedCounter < aOldOne.iTimedCounter );
+ }
+
+ }
+ else
+ {
+ if( aNewOne.iActiveConstraints & EConstraintCounter )
+ {
+ return EFalse;
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+ }
+ else if( aNewOne.iActiveConstraints & EConstraintTimedCounter )
+ {
+ if( aOldOne.iActiveConstraints & EConstraintCounter )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ // 6. Counter
+ // Choose the one with least counters:
+ // if they are the same choose the first one.
+ // Continue here if SE's or intervals or accumulateds or timed counters
+ // do not exist or they are the same
+ if( aOldOne.iActiveConstraints & EConstraintCounter )
+ {
+ if( aNewOne.iActiveConstraints & EConstraintCounter )
+ {
+ return ( aNewOne.iCounter < aOldOne.iCounter );
+ }
+ else
+ {
+ return ETrue;
+ }
+ }
+
+ // If all else fails use the old one:
+ return EFalse;
+ }
+
// End of File