dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpClipManager.cpp
branchRCL_3
changeset 47 826cea16efd9
parent 45 798ee5f1972c
child 48 13a33d82ad98
equal deleted inserted replaced
45:798ee5f1972c 47:826cea16efd9
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    Help methods for propriatary RTP format.*
       
    15 */
       
    16 
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <pathinfo.h>
       
    22 #include <ipvideo/CRtpClipManager.h>
       
    23 #include "CRtpClipRepairer.h"
       
    24 #include <BaUtils.h>
       
    25 #include "videoserviceutilsLogger.h"
       
    26 
       
    27 // CONSTANTS
       
    28 const TInt EContentRightsRecordingAllowed( 0 );
       
    29 const TInt EContentRightsLockToDevice( 2 );
       
    30 const TInt KMaxProgramChars( 8 );
       
    31 const TInt KFirstFileIndex( 1 );
       
    32 const TInt KMaxFileIndex( 99 );
       
    33 _LIT( KDvrClipExtension, ".rtp" );
       
    34 _LIT( KIndexFormat, "(%02d)" );
       
    35 
       
    36 // ============================ MEMBER FUNCTIONS ===============================
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CRtpClipManager::NewL
       
    40 // Static two-phased constructor.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 EXPORT_C CRtpClipManager* CRtpClipManager::NewL()
       
    44     {
       
    45     CRtpClipManager* self = CRtpClipManager::NewLC();
       
    46     CleanupStack::Pop( self );
       
    47     return self;
       
    48     }
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // CRtpClipManager::NewLC
       
    52 // Static two-phased constructor.
       
    53 // -----------------------------------------------------------------------------
       
    54 //
       
    55 EXPORT_C CRtpClipManager* CRtpClipManager::NewLC()
       
    56     {
       
    57     CRtpClipManager* self = new( ELeave ) CRtpClipManager();
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL();
       
    60     return self;
       
    61     }
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CRtpClipManager::CRtpClipManager
       
    65 //
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 CRtpClipManager::CRtpClipManager()
       
    69     {
       
    70     // None
       
    71     }
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CRtpClipManager::ConstructL
       
    75 // Symbian 2nd phase constructor can leave.
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 void CRtpClipManager::ConstructL()
       
    79     {
       
    80     LOG( "CRtpClipManager::ConstructL() in" );
       
    81     
       
    82     // IMEI
       
    83     TName buf( KNullDesC );
       
    84     CRtpUtil::GetImeiL( buf );
       
    85     iImei = buf.AllocL();
       
    86     LOG1( "CRtpClipManager::ConstructL(), IMEI: %S", &*iImei );
       
    87 
       
    88     // File server
       
    89     User::LeaveIfError( iFs.Connect() );
       
    90 
       
    91     LOG( "CRtpClipManager::ConstructL() out" );
       
    92     }
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // CRtpClipManager::~CRtpClipManager
       
    96 //
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 EXPORT_C CRtpClipManager::~CRtpClipManager()
       
   100     {
       
   101     LOG( "CRtpClipManager::~CRtpClipManager()" );
       
   102 
       
   103     delete iImei;
       
   104     iRepairQueue.ResetAndDestroy();
       
   105     delete iClipRepairer;
       
   106     iFile.Close();
       
   107     iFs.Close();
       
   108     }
       
   109 
       
   110 // -----------------------------------------------------------------------------
       
   111 // CRtpClipManager::GetClipDetailsL
       
   112 // Getter for clip details.
       
   113 // -----------------------------------------------------------------------------
       
   114 //
       
   115 EXPORT_C void CRtpClipManager::GetClipDetailsL(
       
   116     const TDesC& aClipPath,
       
   117     SRtpClipDetails& aDetails )
       
   118     {
       
   119     iFile.Close();
       
   120     TBool clipOpen( EFalse );
       
   121     iFs.IsFileOpen( aClipPath, clipOpen );
       
   122     User::LeaveIfError( iFile.Open( iFs, aClipPath,
       
   123                         EFileShareAny | EFileStream | EFileRead ) );
       
   124     CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC( 
       
   125                                  iFile, CRtpMetaHeader::EMetaRead );
       
   126     // Attributes
       
   127     CRtpMetaHeader::SAttributes att;
       
   128     metaheader->ReadAttributesL( att );
       
   129 
       
   130     // Under version 2 clips not work any longer
       
   131     // Recording ongoing without file open indicates interrupted recording
       
   132     if ( att.iVersion < 2 || ( att.iOngoing && !clipOpen ) )
       
   133         {
       
   134         LOG3( "CRtpClipManager::GetClipDetailsL(), iVersion: %d, iOngoing: %d, clipOpen: %d",
       
   135                                                    att.iVersion, att.iOngoing, clipOpen );
       
   136         iFile.Close();
       
   137         User::Leave( KErrGeneral ); 
       
   138         }
       
   139     
       
   140     // Details
       
   141     GetDetailsL( att, aDetails, metaheader );
       
   142     CleanupStack::PopAndDestroy( metaheader );
       
   143     iFile.Close();
       
   144     }
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CRtpClipManager::GetClipDetailsL
       
   148 // Getter for clip details.
       
   149 // -----------------------------------------------------------------------------
       
   150 //
       
   151 EXPORT_C void CRtpClipManager::GetClipDetailsL(
       
   152     RFile& aFile,
       
   153     SRtpClipDetails& aDetails )
       
   154     {
       
   155     CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC( 
       
   156                                  aFile, CRtpMetaHeader::EMetaRead );
       
   157     // Attributes
       
   158     CRtpMetaHeader::SAttributes att;
       
   159     metaheader->ReadAttributesL( att );
       
   160     
       
   161     // Details
       
   162     GetDetailsL( att, aDetails, metaheader );
       
   163     CleanupStack::PopAndDestroy( metaheader );
       
   164     }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 // CRtpClipManager::ProtectClipL
       
   168 // Protects clip from deleting automatically during recording.
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 EXPORT_C void CRtpClipManager::ProtectClipL(
       
   172     const TDesC& aClipPath,
       
   173     const TBool aProtected )
       
   174     {
       
   175     LOG1( "CRtpClipManager::ProtectClipL(), aClipPath: %S", &aClipPath );
       
   176     LOG1( "CRtpClipManager::ProtectClipL(), aProtected: %d", aProtected );
       
   177     
       
   178     iFile.Close();
       
   179     User::LeaveIfError( iFile.Open( iFs, aClipPath,
       
   180                         EFileShareExclusive | EFileStream | EFileWrite ) );
       
   181     CRtpMetaHeader* metaheader = CRtpMetaHeader::NewLC( 
       
   182                                  iFile, CRtpMetaHeader::EMetaUpdate );
       
   183     // Read Attributes
       
   184     CRtpMetaHeader::SAttributes att;
       
   185     metaheader->ReadAttributesL( att );
       
   186     // Update protected attribute
       
   187     if ( aProtected != att.iProtected )
       
   188         {
       
   189         att.iProtected = aProtected;
       
   190         metaheader->WriteAttributesL( att );
       
   191         }
       
   192     
       
   193     CleanupStack::PopAndDestroy( metaheader );
       
   194     iFile.Close();
       
   195     }
       
   196     
       
   197 // -----------------------------------------------------------------------------
       
   198 // CRtpClipManager::FixMetaHeaderL
       
   199 // Fixes corrupted clip's meta header.
       
   200 // -----------------------------------------------------------------------------
       
   201 //
       
   202 EXPORT_C void CRtpClipManager::FixMetaHeaderL(
       
   203     MRtpClipRepairObserver* aObs,
       
   204     const TDesC& aClipPath )
       
   205     {
       
   206     LOG( "RM-CRtpClipManager::FixMetaHeaderL()" );
       
   207 
       
   208     iFile.Close();
       
   209     if ( !iClipRepairer )
       
   210         {
       
   211         LOG1( "CRtpClipManager::FixMetaHeaderL(), Fix started: %S", &aClipPath );
       
   212         AddClipToRepairQueueL( aClipPath );
       
   213         iClipRepairer = CRtpClipRepairer::NewL( aObs );
       
   214         iClipRepairer->CheckMetaHeaderL( aClipPath );
       
   215         }
       
   216     else
       
   217         {
       
   218         // Verify that not exist in queue
       
   219         TInt loop( iRepairQueue.Count() - 1 );
       
   220         for ( ; loop >= 0; loop-- )
       
   221             {
       
   222             if ( !aClipPath.CompareC( iRepairQueue[loop]->Des() ) )
       
   223                 {
       
   224                 break;
       
   225                 }
       
   226             }
       
   227 
       
   228         // Add to queue
       
   229         if ( loop < 0 )
       
   230             {
       
   231             LOG1( "CRtpClipManager::FixMetaHeaderL(), Fix queued: %S", &aClipPath );
       
   232             AddClipToRepairQueueL( aClipPath );
       
   233             }
       
   234         }
       
   235     }
       
   236     
       
   237 // -----------------------------------------------------------------------------
       
   238 // CRtpClipManager::FixMetaHeaderL
       
   239 // Fixes corrupted clip's meta header syncronously.
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 EXPORT_C void CRtpClipManager::FixMetaHeaderL( const TDesC& aClipPath )
       
   243     {
       
   244     LOG1( "CRtpClipManager::FixMetaHeaderL(), aClipPath: %S", &aClipPath );
       
   245 
       
   246     iFile.Close();
       
   247     delete iClipRepairer; iClipRepairer = NULL;
       
   248     iClipRepairer = CRtpClipRepairer::NewL( NULL );
       
   249     iClipRepairer->CheckMetaHeaderL( aClipPath );
       
   250     }
       
   251     
       
   252 // -----------------------------------------------------------------------------
       
   253 // CRtpClipManager::DeleteRtpRepairer
       
   254 // Kills clip repairer after work done.
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 EXPORT_C void CRtpClipManager::DeleteRtpRepairer( MRtpClipRepairObserver* aObs )
       
   258     {
       
   259     // Remove handled name from the queue first
       
   260     iFile.Close();
       
   261     TInt last( iRepairQueue.Count() - 1 );
       
   262     if ( last > KErrNotFound && iClipRepairer &&
       
   263          !iRepairQueue[last]->Des().Compare( iClipRepairer->CurrentClipName() ) )
       
   264         {
       
   265         delete iRepairQueue[last];
       
   266         iRepairQueue[last] = NULL;
       
   267         iRepairQueue.Remove( last );
       
   268         }
       
   269 
       
   270     // Repairer must be deleted in any case
       
   271     delete iClipRepairer; iClipRepairer = NULL;
       
   272     TInt err( KErrNotFound );
       
   273     last = iRepairQueue.Count() - 1;
       
   274     LOG1( "CRtpClipManager::DeleteRtpRepairer(), queue count: %d", iRepairQueue.Count() );
       
   275     
       
   276     while ( last > KErrNotFound && err )
       
   277         {
       
   278         // Create new repairer and start it
       
   279         TPath path( iRepairQueue[last]->Des() );
       
   280         TRAP( err, iClipRepairer = CRtpClipRepairer::NewL( aObs ) );
       
   281         if ( !err )
       
   282             {
       
   283             TRAP( err, iClipRepairer->CheckMetaHeaderL( path ) );
       
   284             if ( err )
       
   285                 {
       
   286                 LOG1( "CRtpClipManager::DeleteRtpRepairerL(), CheckMetaHeaderL Leaved: %d", err );
       
   287 
       
   288                 // Remove clip which can't be repaired from the queue
       
   289                 delete iRepairQueue[last];
       
   290                 iRepairQueue[last] = NULL;
       
   291                 iRepairQueue.Remove( last );
       
   292                 
       
   293                 // Ready for the next clip
       
   294                 last = iRepairQueue.Count() - 1;
       
   295                 delete iClipRepairer; iClipRepairer = NULL;
       
   296                 }
       
   297             }
       
   298         else
       
   299             {
       
   300             LOG1( "CRtpClipManager::DeleteRtpRepairerL(), No memory for new repairer: %d", err );
       
   301             break;
       
   302             }
       
   303         }
       
   304     }
       
   305     
       
   306 // -----------------------------------------------------------------------------
       
   307 // CRtpClipManager::VerifyPostRuleL
       
   308 // Verifies post acqusition rule of clip.
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 TInt CRtpClipManager::VerifyPostRuleL(
       
   312     const TUint8 aPostRule,
       
   313     CRtpMetaHeader* aMetaHeader )
       
   314     {
       
   315     LOG( "CRtpClipManager::VerifyPostRule()" );
       
   316 
       
   317     switch ( aPostRule )
       
   318         {
       
   319         case EContentRightsRecordingAllowed:
       
   320             LOG( "CRtpClipManager::VerifyPostRule(), EContentRightsRecordingAllowed !" );
       
   321             break;
       
   322         
       
   323         case EContentRightsLockToDevice:
       
   324             {
       
   325             TName imei( KNullDesC );
       
   326             aMetaHeader->ReadDeviceInfoL( imei );
       
   327             if ( !iImei || imei.Compare( iImei->Des() ) )
       
   328                 {
       
   329                 LOG( "CRtpClipManager::VerifyPostRule(), EContentRightsLockToDevice" );
       
   330                 LOG1( "CRtpClipManager::VerifyPostRule(), ERmPlayDeviceLockError: %S", &imei );
       
   331                 LOG1( "CRtpClipManager::VerifyPostRule(), Phone's IMEI: %S", &*iImei );
       
   332                 return KErrAccessDenied;
       
   333                 }
       
   334             }
       
   335             break;
       
   336         
       
   337         default:
       
   338             LOG1( "RM-CRtpClipManager::VerifyPostRule(), Default case: %d", aPostRule );
       
   339             break;
       
   340         }
       
   341     
       
   342     return KErrNone;
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CRtpClipManager::GetDetailsL
       
   347 // Updates details from meta header attributes.
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 void CRtpClipManager::GetDetailsL(
       
   351     const CRtpMetaHeader::SAttributes& aAttributes,
       
   352     SRtpClipDetails& aDetails,
       
   353     CRtpMetaHeader* aMetaHeader )
       
   354     {
       
   355     aDetails.iRecOngoing = aAttributes.iOngoing;
       
   356     aDetails.iCompleted = aAttributes.iCompleted;
       
   357     aDetails.iProtected = aAttributes.iProtected;
       
   358     aDetails.iFailed = aAttributes.iFailed;
       
   359     aDetails.iQuality = aAttributes.iQuality;
       
   360     aDetails.iPlayCount = aAttributes.iPlayCount;
       
   361     aDetails.iPlaySpot = aAttributes.iPlaySpot;
       
   362     aDetails.iParental = aAttributes.iParental;
       
   363     
       
   364     LOG1( "CRtpClipManager::GetDetailsL(), iRecOngoing: %d", aDetails.iRecOngoing );
       
   365     LOG1( "CRtpClipManager::GetDetailsL(), iCompleted: %d", aDetails.iCompleted );
       
   366     LOG1( "CRtpClipManager::GetDetailsL(), iProtected: %d", aDetails.iProtected );
       
   367     LOG1( "CRtpClipManager::GetDetailsL(), iFailed: %d", aDetails.iFailed );
       
   368     LOG1( "CRtpClipManager::GetDetailsL(), iQuality: %d", aDetails.iQuality );
       
   369     LOG1( "CRtpClipManager::GetDetailsL(), iPlayCount: %d", aDetails.iPlayCount );
       
   370     LOG1( "CRtpClipManager::GetDetailsL(), iPlaySpot: %d", aDetails.iPlaySpot );
       
   371     LOG1( "CRtpClipManager::GetDetailsL(), iParental: %d", aDetails.iParental );
       
   372 
       
   373     // ESG
       
   374     aMetaHeader->ReadEsgDataL( aDetails.iService, aDetails.iProgram );
       
   375     LOG1( "CRtpClipManager::GetDetailsL(), iService: %S", &aDetails.iService );
       
   376     LOG1( "CRtpClipManager::GetDetailsL(), iProgram: %S", &aDetails.iProgram );
       
   377     
       
   378     // Start time
       
   379     aMetaHeader->ReadStartTimeL( aDetails.iStartTime );
       
   380     
       
   381     // End time
       
   382     aMetaHeader->ReadEndTimeL( aDetails.iEndTime );
       
   383 
       
   384 #if defined( LIVE_TV_RDEBUG_TRACE ) || defined( LIVE_TV_FILE_TRACE )
       
   385     TName time( KNullDesC ); aDetails.iEndTime.FormatL( time, KTimeDateFormat );
       
   386     LOG1( "CRtpClipManager::GetDetailsL(), End time: %S", &time );
       
   387 #endif // LIVE_TV_RDEBUG_TRACE || LIVE_TV_FILE_TRACE
       
   388 
       
   389     // Duration
       
   390     aMetaHeader->ReadDurationL( aDetails.iDuration );
       
   391     LOG1( "CRtpClipManager::GetDetailsL(), iDuration: %d", aDetails.iDuration );
       
   392     aDetails.iDuration/= 1000; // convert to seconds
       
   393 
       
   394     // Post acquisition
       
   395     aDetails.iPostRuleOk = !VerifyPostRuleL( aAttributes.iPostRule, aMetaHeader );
       
   396     LOG1( "CRtpClipManager::GetDetailsL(), iPostRuleOk: %d", aDetails.iPostRuleOk );
       
   397     }
       
   398 
       
   399 // -----------------------------------------------------------------------------
       
   400 // CRtpClipManager::NewClipRootL
       
   401 // Root path of the new clip, depends on user media setting.
       
   402 // If memory card is selected, but not available, default saving to phone memory.
       
   403 // -----------------------------------------------------------------------------
       
   404 //
       
   405 void CRtpClipManager::NewClipRootL( TDes& aClipPath, const TDriveNumber aDrive )
       
   406     {
       
   407     // Begin of the save path
       
   408     if ( aDrive == EDriveC )
       
   409         {
       
   410         aClipPath = PathInfo::PhoneMemoryRootPath();
       
   411         aClipPath.Append( PathInfo::VideosPath() );
       
   412         }
       
   413     else
       
   414         {
       
   415         aClipPath = PathInfo::MemoryCardRootPath();
       
   416         aClipPath.Append( PathInfo::VideosPath() );
       
   417         }
       
   418     
       
   419     // Verify and create path if not exist
       
   420     if ( !BaflUtils::PathExists( iFs, aClipPath ) )
       
   421         {
       
   422         TInt err( iFs.MkDirAll( aClipPath ) );
       
   423         if ( err && aDrive != EDriveC )
       
   424             {
       
   425             LOG1( "CRtpClipManager::NewClipRootL(), Forced to Use Phone Memory !", err );
       
   426 
       
   427             // Memorycard not acceptable -> Use phone memory
       
   428             err = KErrNone;
       
   429             aClipPath = PathInfo::PhoneMemoryRootPath();
       
   430             aClipPath.Append( PathInfo::VideosPath() );
       
   431             BaflUtils::EnsurePathExistsL( iFs, aClipPath );
       
   432             }
       
   433         
       
   434         User::LeaveIfError( err );
       
   435         }
       
   436     }
       
   437 
       
   438 // -----------------------------------------------------------------------------
       
   439 // CRtpClipManager::NewIndexNameL
       
   440 // Creates new clip name from program name (eigth first letters + index).
       
   441 // If program name allready in use, adds indexing to the end of name.
       
   442 // -----------------------------------------------------------------------------
       
   443 //
       
   444 void CRtpClipManager::NewIndexNameL( TDes& aClipPath, const TDesC& aProgram )
       
   445     {
       
   446     LOG1( "CRtpClipManager::NewIndexNameL(), aClipPath  : %S", &aClipPath );
       
   447     LOG1( "CRtpClipManager::NewIndexNameL(), aProgram   : %S", &aProgram );
       
   448 
       
   449     // Remove special characters
       
   450     TBuf<KMaxProgramChars> program( aProgram.Left( KMaxProgramChars ) );
       
   451     for ( TInt i( program.Length() - 1 ); i >= 0; i-- )
       
   452         {
       
   453         TChar letter( program[i] );
       
   454         // Remove if not alpha nor space
       
   455         if ( !letter.IsAlphaDigit() && !letter.IsSpace() )
       
   456             {
       
   457             program.Delete( i, 1 );
       
   458             }
       
   459         }
       
   460     program.TrimRight();
       
   461     
       
   462     TInt index( KFirstFileIndex );
       
   463     
       
   464     // Test name for existing clip check
       
   465     TPath testName( aClipPath );
       
   466     if ( program.Length() )
       
   467         {
       
   468         testName.Append( program );
       
   469         }
       
   470     else
       
   471         {
       
   472         // Zero length program name, start from "(01).rtp"
       
   473         testName.AppendFormat( KIndexFormat, index++ );        
       
   474         }
       
   475 
       
   476     // Name already used ?
       
   477     testName.Append( KDvrClipExtension );
       
   478     if ( BaflUtils::FileExists( iFs, testName ) )
       
   479         {
       
   480         do
       
   481             {
       
   482             LOG1( "CRtpClipManager::NewIndexNameL(), Clip exist: %S", &testName );
       
   483             
       
   484             // Abort if file index exceeds "(99)"
       
   485             User::LeaveIfError( ( index > KMaxFileIndex ) * KErrOverflow );
       
   486             
       
   487             // New test name
       
   488             testName.Copy( aClipPath );
       
   489             testName.Append( program );
       
   490             testName.AppendFormat( KIndexFormat, index++ );
       
   491             testName.Append( KDvrClipExtension );
       
   492             }
       
   493             while ( BaflUtils::FileExists( iFs, testName ) );
       
   494         }
       
   495     
       
   496     // Return suitable filename
       
   497     aClipPath.Copy( testName );
       
   498     }
       
   499     
       
   500 // -----------------------------------------------------------------------------
       
   501 // CRtpClipManager::AddClipToRepairQueueL
       
   502 // Inserts new clip name to the first in queue.
       
   503 // -----------------------------------------------------------------------------
       
   504 //
       
   505 void CRtpClipManager::AddClipToRepairQueueL( const TDesC& aClipPath )
       
   506     {
       
   507     HBufC* clip = aClipPath.AllocLC();
       
   508     User::LeaveIfError( iRepairQueue.Insert( clip, 0 ) );
       
   509     CleanupStack::Pop( clip );
       
   510     }
       
   511 
       
   512 // End of File
       
   513