sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // NOTE: For the purpose of clarity we have ommitted full error checking in the sl@0: //
sl@0: // An example content file is given below. It has a number of content objects sl@0: // and a number of containers with other containers and content objects inside. sl@0: // It is likely that each container will have information or meta-data related sl@0: // to the collection of objects it holds. sl@0: //
sl@0: // The ContentAccess::CContent object encapsulates a single file. It allows an application to look sl@0: // at the structure of the objects within the file and the attributes of those objects. sl@0: // There a two ways to create a \c CContent object. The application can specify the URI of the sl@0: // content or it can supply an open file handle. sl@0: // // Create a CContent with a URI sl@0: // CContent* content = CContent::NewL(uri); sl@0: // // Create a CContent with an existing file handle sl@0: // CContent* content = CContent::NewL(aFs, aFile); sl@0: // Upon creation, \c CContent selects the agent that will handle the file. For sl@0: //
sl@0: // ContentAccess::CContent acts like a cursor, only able to list the contents of one container sl@0: // object at any one time. When \c CContent is first opened it views the top level sl@0: // container within the file. The top level container is actually the file itself. sl@0: // This top level container concept applies to all files, regardless of how many sl@0: // content or container objects are inside. sl@0: // Even a content file such as a JPEG image is a container, it's just that sl@0: // the file only has the "DEFAULT" object embedded inside. sl@0: // So when the example file shown earlier is opened the following objects can be seen sl@0: // by the \c CContent: sl@0: // In this top level container there is only one embedded content object visible (the .jpg file) and two sl@0: // embedded container objects. sl@0: // // Create an array to store the results of CContent::GetEmbeddedObjectsL() sl@0: // RStreamablePtrArray myArray; sl@0: // CleanupClosePushL(myArray); sl@0: // // Get the embedded content objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContentObject); sl@0: // i = myArray.Count(); // One content object sl@0: // // clear the contents of the array sl@0: // myArray.ResetAndDestroy(); sl@0: // // Get the number of container objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContainerObject); sl@0: // i = myArray.Count(); // Two container objects sl@0: // // clear the contents of the array sl@0: // myArray->ResetAndDestroy(); sl@0: //
sl@0: // To investigate the objects inside a container \c CContent must first open the container. sl@0: // This changes CContent's focus from the current container to the container specified in sl@0: // the ContentAccess::CContent::OpenContainer() function. sl@0: // Opening Container 1 from the top level of the file sl@0: // // Get the container objects in the top level of the file sl@0: // content->GetEmbeddedObjectsL(myArray, EContainerObject); sl@0: // // Find the Unique Id of the first container sl@0: // TPtrC UniqueId = myArray[0]->UniqueId(); sl@0: // // Open the first container sl@0: // content->OpenContainer(UniqueId); sl@0: // Now \c CContent can see the contents of Container 1: sl@0: // At this point, listing the objects that \c CContent can see gives six MP3 sl@0: // files and one container object. sl@0: // // Get the embedded content objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContentObject); sl@0: // i = myArray.Count(); // Six content objects sl@0: // myArray.ResetAndDestroy(); sl@0: // // Get the number of container objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContainerObject); sl@0: // i = myArray.Count(); // One container object sl@0: // myArray.ResetAndDestroy(); sl@0: // Opening Container 1.1 from Container 1 sl@0: // The same process can be followed again to see the contents of Container 1.1 sl@0: // // Get the array of container objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContainerObject); sl@0: // // Find the Unique Id of the first container within Container 1 sl@0: // TPtrC UniqueId = myArray[0]->UniqueId(); sl@0: // // Open Container 1.1 sl@0: // content->OpenContainer(UniqueId); sl@0: // myArray.ResetAndDestroy(); sl@0: // // Can now see two content objects (the MOV file and the TXT file) sl@0: // content->GetEmbeddedObjectsL(myArray, EContentObject); sl@0: // i = myArray.Count(); sl@0: // myArray.ResetAndDestroy(); sl@0: // // Zero container objects sl@0: // content->GetEmbeddedObjectsL(myArray, EContentObject); sl@0: // i = myArray.Count(); sl@0: // myArray.ResetAndDestroy(); sl@0: //
sl@0: // To look once more at the contents of the container that encloses the current container sl@0: // the ContentAccess::CContent::CloseContainer() function should be used. sl@0: // Continuing our example, if we close the Container 1.1 we are left viewing sl@0: // Container 1 again. sl@0: // // Close Container 1.1 sl@0: // Econtent->CloseContainer(); sl@0: // // Get the embedded content objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContentObject); sl@0: // i = myArray.Count(); // Six content objects sl@0: // myArray.ResetAndDestroy(); sl@0: // // Get the number of container objects in the current container sl@0: // content->GetEmbeddedObjectsL(myArray, EContainerObject); sl@0: // i = myArray.Count(); // One container object sl@0: // myArray.ResetAndDestroy(); sl@0: //
sl@0: // If an application wants to find all the content with a particular MIME sl@0: // type within a file it should use ContentAccess::CContent::Search(). sl@0: // This function will produce a list of all content objects with the specified sl@0: // MIME type that are stored under the current container. sl@0: // // Create an array for storing the result of the search sl@0: // RStreamablePtrArray myArray; sl@0: // CleanupClosePushL(myArray); sl@0: // // Get all MP3 files in Container 1 sl@0: // content->Search(myArray, _L("mpeg/audio"), EFalse); sl@0: // // Do something with results sl@0: // // Cleanup sl@0: // CleanupStack::PopAndDestroy(1); sl@0: //
sl@0: // The functions described earlier can be used to locate a particular content sl@0: // object within a file. ContentAccess::CContent::OpenContentL() can be used to sl@0: // read the content object. The \c UniqueId parameter can be used to identify sl@0: // a particular object within the file. sl@0: // The call to ContentAccess::CContent::OpenContentL() will leave if the intent sl@0: // is not permitted. This could occur if the file is DRM protected but no sl@0: // rights are present. sl@0: // If the file is DRM protected and the call to OpenContentL() succeeds, the rights sl@0: // are not consumed at this point. CAF just checks that it is possible to use the sl@0: // content. sl@0: // // Open the content object specified by uniqueId with the EPlay Intent sl@0: // CData* data = content->OpenContentL(EPlay, uniqueId); sl@0: // If the application already knows the URI and unique Id of the content object sl@0: // it wants to read from, it can create a \c CData object directly. sl@0: // CData* data = CData::NewL(TVirtualPathPtr(uri, uniqueId), EPlay, EContentShareReadOnly); sl@0: // Once the \c CData object has been constructed, it allows the content object to be used sl@0: // as if it were a standalone unprotected file. The client must call ContentAccess::CData::ExecuteIntent() sl@0: // when the rights should be consumed. If the file is not DRM protected, the call sl@0: // will be ignored by the agent handling the file. sl@0: // TBuf8 <256> buf; sl@0: // data->ExecuteIntent(EPlay); sl@0: // data->Seek(SomePosition,ESEEK_START); sl@0: // data->Read(buf); sl@0: // There are several overloaded versions of the ContentAccess::CData::Read() function. Only one is illustrated sl@0: // above for example purposes. sl@0: //
sl@0: // The \c CContent interface supports notification requests for content objects within files. The sl@0: // events for which an application can request notification are given by the enumeration ContentAccess::TEventMask. sl@0: // The following example requests and cancels notification for rights becoming available: sl@0: // // Request notification when rights become available for a particular content object sl@0: // content->NotifyStatusChange(ERightsAvailable, status, uniqueId); sl@0: // // Cancel notification request sl@0: // content->CancelNotifyStatusChange(status, uniqueId); sl@0: //
sl@0: // There are two functions available that give the application some control over the rights: sl@0: // - Request Rights sl@0: // \n\n sl@0: // ContentAccess::CContent::RequestRights() allows the application to ask the agent to undertake sl@0: // whatever steps are necessary to obtain rights for the given content object. Some agents sl@0: // may not support this mechanism, in which case they will return KErrCANotSupported. sl@0: // \n\n sl@0: // The request rights call includes an \c TRequestStatus parameter, which allows the application to sl@0: // be notified of the outcome of the rights request. sl@0: // content->RequestRights(status, uniqueId); sl@0: // \n\n sl@0: // - Display Info sl@0: // \n\n sl@0: // ContentAccess::CContent::DisplayInfoL() allows the application to ask the agent to display sl@0: // the file and/or rights information for the given content object. The call returns when sl@0: // the display is dismissed. sl@0: // \n\n sl@0: // Some agents may not support this mechanism, in which case they will leave with KErrCANotSupported. sl@0: // \n\n sl@0: // content->DisplayInfoL(EFileProperties, uniqueId); sl@0: //
sl@0: //
sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @page CContentAPI Consumer API (Browsing and reading from content files) sl@0: - @ref ExampleFile sl@0: - @ref CreatingCContent sl@0: - @ref Listing sl@0: - @ref OpeningContainer sl@0: - @ref ClosingContainer sl@0: - @ref Searching sl@0: - @ref CAFCData sl@0: - @ref ContentNotification sl@0: - @ref ContentRights sl@0: - @ref AgentResolution sl@0: code examples given below. For examples with error checking see @ref ExampleReadWithErrCheck. sl@0: @section ExampleFile An Example Content File sl@0: @image html DRMFile1.gif sl@0: @section CreatingCContent Creating a CContent Object sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: details on how this selection is done see @ref AgentResolution. sl@0: @section Listing Listing objects within a container sl@0: @image html DRMFile2.gif sl@0: @code sl@0: @endcode sl@0: @section OpeningContainer Opening a container sl@0: @code sl@0: @endcode sl@0: @image html DRMFile3.gif sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: @image html DRMFile4.gif sl@0: @section ClosingContainer Closing a Container sl@0: @code sl@0: @endcode sl@0: @image html DRMFile3.gif sl@0: @section Searching Searching for a MIME type within a file sl@0: @code sl@0: @endcode sl@0: @section CAFCData Reading data from a content object sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: @section ContentNotification Content Object Notifications sl@0: @code sl@0: @endcode sl@0: @section ContentRights Handling Rights for DRM content sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: @section AgentResolution Agent resolution during CContent object creation sl@0: @li During the creation of a CContent object an instance of the internal object CAgentResolver is created. sl@0: @li CAgentResolver uses ECOM to identifier all the Content Access Agents (CAAs) on the system. An instance of CAgentInfo is created for each CAA found. CAgentInfo contains supplier and consumer MIME types as well as the CAA plug-in details. sl@0: @li When a URI is supplied to CContent::NewL() and it contains a path for the private directory of one of the agent's then that CAA is used. For RFile no private directory exists so this check cannot be performed. sl@0: @li If a private directory cannot be obtained from the URI or an RFile was supplied to CContent::NewL() each CAA plug-in identified by CAgentResolver is loaded in turn. sl@0: @li CAgentResolver obtains a CAgentManager object from each CAA in turn and calls IsRecognized() allowing the agent implementation to determine if it can support the file. sl@0: @li If no CAA responds the default F32 CAA is used in to open the file as it is assumed to be unprotected content. sl@0: @li Note: The MIME types loaded into CAgentInfo are not used for Agent Resolution but are utilized in file type recognition under Application Architecture recognizer framework. sl@0: */