Week 28 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 1897 and Bug 1522.
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --><!-- This component and the accompanying materials are made available under the terms of the License "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: --><!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"><concept id="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C" xml:lang="en"><title>HandlingDRM Content</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>Content Access Framework (CAF) provides services that enable agents topublish content in a generic manner that is easy for applications to use.Applications use the Consumer API to render a content and multimedia plug-ins. </p><p> <b>Note:</b> Rendering is a process of reading data from a file, transformingit, then playing or displaying it on the device. </p><p><b>Access to content within archive files </b> </p><p>An archive file contains content objects and other containers within thefile. Each container within the file may contain more content objects or furthercontainers. Common examples of archive files are zip and tar files. </p><p>CAF allows applications to open archive files and read content from insidethem. The content objects and containers inside the file can be traversedusing the <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-FC40011B-32D3-328B-BB59-35BEF46A215A"><apiname>ContentAccess::CContent</apiname></xref> class. The class allowsapplications to use the content within these container files without needingto understand any specifics of the compression or storage mechanism used bythe archive. </p><section><title>Required background</title> <p>Before you start, you mustunderstand: </p> <ul><li id="GUID-099EC8EB-0A45-5FBF-9F55-B38D9C0AFCA8"><p><xref href="GUID-84B6389A-55CC-53EB-8725-65F753FD7217.dita"> ContentAccess Framework for DRM</xref> </p> </li><li id="GUID-16D006BB-3D7E-5439-BFFC-727EFF82D40E"><p><xref href="GUID-B5CC77D2-5871-51D8-B359-77EFC081B423.dita">FilesContaining Multiple Content Objects</xref> </p> </li><li id="GUID-7029E2F7-A26A-5EC7-A435-0984C2CEE717"><p><xref href="GUID-B6912FE7-4C2A-5FC7-BDA8-702CA2C0214A.dita">ContentObject Attributes</xref> </p> </li></ul> </section><section><title>Introduction</title> <p>Content Access Framework also allowsapplications to open archive files and read content from inside them. Thecontent objects and containers inside the file can be traversed using the <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-FC40011B-32D3-328B-BB59-35BEF46A215A"><apiname>ContentAccess::CContent</apiname></xref> class.This class allows applications to use the content within the container fileswithout needing to understand any specifics of the compression or storagemechanism used by the archive. See <xref href="GUID-B5CC77D2-5871-51D8-B359-77EFC081B423.dita">FilesContaining Multiple Content Objects</xref> for more information. </p> <p>Thefollowing diagram is an example of a content file. The same diagram is usedin the procedure to illustrate the implementation of Consumer API. </p> <fig id="GUID-BA86F65C-C34B-57C3-8FD5-A76C61EDF035"><title> Example content file </title><image href="GUID-1467745D-7C3F-52EC-8C1E-7E2F505B7313_d0e588963_href.png" placement="inline"/></fig> </section><section><title>Procedure</title> <ol id="GUID-FE716629-86BE-513F-82F5-89107FB41F0E"><li id="GUID-BD7166E0-7D9C-5F55-9DF3-1DE17AEBB80B"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-09F7434B-318B-5084-8E8B-54FA0ED48031">Create a content object</xref>. </p> </li><li id="GUID-2BADD3D3-D167-5212-942C-3A3CF4B7D25F"><p>Perform one or moreof the following tasks as per your requirement: </p> <ul><li id="GUID-8DFAF3E7-DC67-51E2-B609-85975BD6A564"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-26189931-0BE0-5BB7-98F1-9B7DF08C6C8F">List objects within a container</xref>. </p> </li><li id="GUID-74B9014B-EFCA-5BFA-8E15-286E837D832C"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-03355CA5-D049-5625-9187-2E91FFAF703A">Open a container</xref>. </p> </li><li id="GUID-ACC262EF-BBD6-5811-9EE3-A346FE600694"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-71C5AA3E-9C4B-5F77-B6D8-D09E00593EB8">Open the metadata specific to an agent</xref>. </p> </li><li id="GUID-34F3E3F3-816A-5B92-8772-05AD72910F56"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-5B42E479-D3F1-5B2A-8B6F-4841E49E4B3D">Display content object information</xref>. </p> </li><li id="GUID-5EC62609-8B8E-549A-806F-628C64FBE81B"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-20F9B6AC-F2B1-5E8E-93F2-8AE4AD0ED1F6">Retrieve the attributes of a content</xref>. </p> </li><li id="GUID-C5F1A5F7-D83B-5FD1-814C-4B0E9416C815"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-8D6C9025-7409-5019-88B2-A99A8E020443">Search for a MIME type within a file</xref>. </p> </li><li id="GUID-12C912EE-4195-5B3C-82C6-007E76629156"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-447A73D2-AF49-598E-865E-C2CEF1958C14">Read data from a content object</xref>. </p> </li><li id="GUID-A9FB0738-754E-5879-A2F5-E88C5F4C7751"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-AAFE84D9-01AF-5F27-9BC2-064A565F3D53">Handle data corruption</xref>. </p> </li><li id="GUID-E57145C0-DF25-5F32-9368-D86627E97B05"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-15A1A9B3-BB5D-5677-BFE9-47EABD4064BF">Handle errors</xref>. </p> </li><li id="GUID-935D7FB6-15EB-5DFB-89A0-58C0C29E736D"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-6A50AE44-E618-5D99-B5D8-7BBA8FE7948A">Handle rights for DRM content</xref>. </p> </li><li id="GUID-BEA5163A-5A5E-510B-AD36-313CC820DDBD"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-635EE5EF-469D-5FD3-9400-25DF95FD2E96">Get content object notifications</xref>. </p> </li><li id="GUID-2828C1A0-8E91-5B46-88FD-09CF0C36F40B"><p><xref href="GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C.dita#GUID-09A760FD-4C2A-5F79-91F2-DCC25A63699C/GUID-DDAE0B57-B296-58E8-8220-AE5AA9BF7B8D">Close a container</xref>. </p> </li></ul> </li></ol> <p id="GUID-09F7434B-318B-5084-8E8B-54FA0ED48031"><b>Create a CContentobject</b> </p> <p>The <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-FC40011B-32D3-328B-BB59-35BEF46A215A"><apiname>ContentAccess::CContent</apiname></xref> object encapsulatesa single file. It allows an application to look at the structure of the objectswithin the file and the attributes of those objects. </p> <p>There are twoways to create a <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> object. The application can specifythe URI of the content or it can supply an open file handle, see <xref href="GUID-B5CC77D2-5871-51D8-B359-77EFC081B423.dita#GUID-B5CC77D2-5871-51D8-B359-77EFC081B423/GUID-28BE6074-E800-5320-89DD-D047F5C0FD86">Objects used to identify a content object within a file</xref>. </p> <codeblock id="GUID-AAF09718-0FF4-544F-B5B1-3202C58ABC95" xml:space="preserve">// Create a CContent with a URI CContent *content = CContent::NewL(uri); // Create a CContent with an existing file handleCContent *content = CContent::NewL(aFs, aFile);</codeblock> <p>Upon creation, <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> selectsthe agent that handles the file. </p> <p id="GUID-26189931-0BE0-5BB7-98F1-9B7DF08C6C8F"><b>Listobjects within a container</b> </p> <p> <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-FC40011B-32D3-328B-BB59-35BEF46A215A"><apiname>ContentAccess::CContent</apiname></xref> actslike a cursor, only able to list the contents of one container object at anyone time. When <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> is first opened, it views the top-levelcontainer within the file. The top level container is actually the file itself.This top level container concept applies to all files, regardless of how manycontent or container objects are inside. </p> <p>Even a content file suchas a jpeg image is a container, it's just that the file only has the <codeph>"DEFAULT"</codeph> objectembedded inside. </p> <p>So, when the example file shown earlier is opened,the following objects can be seen by the <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref>: </p> <fig id="GUID-EC064DCF-FC5D-59AC-BF5F-378A57808A47"><image href="GUID-518FC822-AF10-57E8-990E-BB03C2D6ACBE_d0e589136_href.png" placement="inline"/></fig> <p>In this top level container, there is only one embedded contentobject visible (the <filepath>.jpg</filepath> file) and two embedded containerobjects. </p> <codeblock id="GUID-87F01EE6-EDEC-584B-844C-1DDB939FB5B3" xml:space="preserve">// Create an array to store the results of CContent::GetEmbeddedObjectsL() RStreamablePtrArray<CEmbeddedObject> myArray; CleanupClosePushL(myArray); // Get the embedded content objects in the current container content->GetEmbeddedObjectsL(myArray, EContentObject); i = myArray.Count(); // One content object // clear the contents of the array myArray.ResetAndDestroy(); // Get the number of container objects in the current containercontent->GetEmbeddedObjectsL(myArray, EContainerObject); i = myArray.Count(); // Two container objects // clear the contents of the array myArray->ResetAndDestroy();</codeblock> <p id="GUID-03355CA5-D049-5625-9187-2E91FFAF703A"><b>Opena container</b> </p> <p>To investigate the objects inside a container, <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> mustfirst open the container. This changes <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref>'s focusfrom the current container to the container specified in the <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-BB793B8F-1A01-3169-99E6-4630E9B5581C"><apiname>ContentAccess::CContent::OpenContainer()</apiname></xref> function. </p> <p><i>Opencontainer 1 from the top level of the file</i> </p> <codeblock id="GUID-7239CC22-292D-54BD-A50B-76413A887AD7" xml:space="preserve">// Get the container objects in the top level of the file content->GetEmbeddedObjects(myArray, EContainerObject); // Find the Unique Id of the first container TPtrC UniqueId = myArray[0]->UniqueId() // Open the first container content->OpenContainer(UniqueId);</codeblock> <p>Now <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> cansee the contents of Container 1: </p> <fig id="GUID-2A67C29A-FBF3-553E-B653-462F5128B2F4"><image href="GUID-DC7E3634-9762-542F-BDAE-AC1F2D03F55D_d0e589185_href.png" placement="inline"/></fig> <p>At this point, listing the objects that <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> cansee gives six MP3 files and one container object. </p> <codeblock id="GUID-F1A7C149-9AB1-5DD2-BE20-280431DBAF40" xml:space="preserve">// Get the embedded content objects in the current container content->GetEmbeddedObjectsL(myArray, EContentObject); i = myArray.Count(); // Six content objectsmyArray.ResetAndDestroy(); // Get the number of container objects in the current container content->GetEmbeddedObjectsL(myArray, EContainerObject);i = myArray.Count(); // One container object myArray.ResetAndDestroy();</codeblock> <p> <b> Note: </b> The same processcan be followed again to see the contents of Container 1.1. </p> <p id="GUID-71C5AA3E-9C4B-5F77-B6D8-D09E00593EB8"><b>Openthe metadata specific to an agent</b> </p> <p>Some agents may expose metadataso they can be read using a <xref href="GUID-136D0282-4C73-33E9-B9D4-9CE92A33BF75.dita"><apiname>CData</apiname></xref> object. The format ofthese meta-data objects is not specified by the Content Access Framework butcan be useful for applications familiar with the agent to read meta data thisway. </p> <p> <codeph>CData</codeph> objects for agent specific metadata canbe opened in the same way content objects are opened, using the <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-32BA0116-1D7F-31B1-B80E-32E1F55803C3"><apiname>ContentAccess::CContent::OpenContentL()</apiname></xref> function. </p> <codeblock id="GUID-62EB232A-E9D6-5151-A69B-87CA26E97A9D" xml:space="preserve">// Create an array to store the embedded objects ...// Get the embedded "Agent Specific" objects in the current containercontent->GetEmbeddedObjectsL(myArray, EAgentSpecificObject); // Get the unique Id of the first meta-data object TPtrC uniqueId = myArray[0]->UniqueId();// create a CData object to read the meta data CData *myMetaData = content->OpenContent(EPeek, uniqueId);</codeblock> <p id="GUID-5B42E479-D3F1-5B2A-8B6F-4841E49E4B3D"><b>Display content object information</b> </p> <p>The <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita#GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A/GUID-79E768C6-D63E-303F-943C-022F5A04AB08"><apiname>CContent::DisplayInfoL()</apiname></xref> functionallows the application to display file information, such as last modificationdate and DRM rights information. </p> <codeblock id="GUID-62A01A68-2479-515C-B74D-C48721870F1D" xml:space="preserve">...content->DisplayInfoL(TDisplayInfo aInfo);...</codeblock> <p id="GUID-20F9B6AC-F2B1-5E8E-93F2-8AE4AD0ED1F6"><b>Retrievethe attributes of a content</b> </p> <p>Content and container objects haveproperties or attributes associated with it. Applications can retrieve singleor mulitple attributes using the <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-4FA0F8A6-7F9A-3AE6-BDEE-B3C8A53B0207"><apiname>ContentAccess::TAttributeCAF</apiname></xref> enumerationand the <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-BC242813-E0F0-3DFE-AF97-6BE808D570DE"><apiname>ContentAccess::TStringAttribute</apiname></xref> enumeration. See <xref href="GUID-B6912FE7-4C2A-5FC7-BDA8-702CA2C0214A.dita">Content Object Attributes</xref> fordetails on implementing different methods of retrieving attributes. </p> <p>Thefollowing example finds the author attribute of a content object. </p> <codeblock id="GUID-5FB7E26E-E8CF-5A10-8B22-06FA45A69721" xml:space="preserve">// define a buffer to store the attribute value string TBuf <100> buf; // retrieve the attribute err = content->GetAttribute(EAuthor, buf, uniqueId); // Display the author's name on screen DisplayAuthor(buf);</codeblock> <p id="GUID-8D6C9025-7409-5019-88B2-A99A8E020443"><b>Search fora MIME type within a file</b> </p> <p>If an application wants to find allthe content with a particular MIME type within a file, it must use <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-FA4BB868-3297-39F0-BAB8-C4BF4F5A2B60"><apiname>ContentAccess::CContent::Search()</apiname></xref>.This function produces a list of all content objects with the specified MIMEtype that are stored under the current container. </p> <codeblock id="GUID-BD3FEDFD-DA3E-5491-BF97-60CFC9252935" xml:space="preserve">// Create an array for storing the result of the search RStreamablePtrArray<CEmbeddedObject> myArray; // Find how many MP3 files are in Container 1 TInt numMp3 = content->Search(myArray, _L("mpeg/audio"), EFalse);</codeblock> <p id="GUID-447A73D2-AF49-598E-865E-C2CEF1958C14"><b>Read data from a contentobject</b> </p> <p>The functions described earlier can be used to locate aparticular content object within a file. <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-32BA0116-1D7F-31B1-B80E-32E1F55803C3"><apiname>ContentAccess::CContent::OpenContentL()</apiname></xref> canbe used to read the content object. The <codeph>UniqueId</codeph> parametercan be used to identify a particular object within the file. </p> <p>The callto <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-32BA0116-1D7F-31B1-B80E-32E1F55803C3"><apiname>ContentAccess::CContent::OpenContentL()</apiname></xref> leaves if theintent is not permitted. This could occur if the file is DRM-protected butno rights are present. </p> <p>If the file is DRM protected and the call to <xref href="GUID-63702251-43C2-3A2C-B884-A865BB539B5C.dita"><apiname>OpenContentL()</apiname></xref> succeeds,the rights are not consumed at this point. CAF just checks that it is possibleto use the content. </p> <codeblock id="GUID-DCA8F01C-9657-5F54-881E-0A297DD652AC" xml:space="preserve">// Open the content object specified by uniqueId with the EPlay intent CData* data = content->OpenContentL(EPlay, uniqueId);</codeblock> <p>If theapplication already knows the URI and unique ID of the content object it wantsto read from, it can create a <codeph>CData</codeph> object directly. </p> <codeblock id="GUID-09916FE1-A7A6-5012-8057-ACC0BFB49EDC" xml:space="preserve">CData* data = CData::NewL(TVirtualPathPtr(uri, uniqueId), EPlay, EContentShareReadOnly);</codeblock> <p>Once the <codeph>CData</codeph> object has been constructed, it allowsthe content object to be used as if it were a standalone unprotected file.The client must call <xref href="GUID-B54C8391-FE69-324C-AC0A-1E88C2555F00.dita#GUID-B54C8391-FE69-324C-AC0A-1E88C2555F00/GUID-3E5B2A86-A06B-3710-99C9-FA205E99088F"><apiname>ContentAccess::CData::ExecuteIntent()</apiname></xref> whenthe rights must be consumed. If the file is not DRM-protected, the call isignored by the agent handling the file. </p> <codeblock id="GUID-81167DB6-CD1B-5F19-88D2-ED6D5C66B5AA" xml:space="preserve">TBuf8 <256> buf; data->ExecuteIntent(EPlay); data->Seek(ESEEK_START,SomePosition); data->Read(buf);</codeblock> <p>There are several overloaded versions of the <xref href="GUID-B54C8391-FE69-324C-AC0A-1E88C2555F00.dita#GUID-B54C8391-FE69-324C-AC0A-1E88C2555F00/GUID-B6146300-5578-39D2-B7E2-19309B76A7F6"><apiname>ContentAccess::CData::Read()</apiname></xref> function.Only one is illustrated above for example purposes. </p> <p id="GUID-AAFE84D9-01AF-5F27-9BC2-064A565F3D53"><b>Handledata corruption</b> </p> <p>When consuming content it is possible that thecontent data and rights data can be corrupted. This may be due to variousreasons including file or disk corruption, transmission errors and so on. </p> <p>Ifan agent detects corruption in a content object or in a rights object, itends the current DRM operation. The <codeph>KErrCACorruptContent</codeph>, <codeph>KErrCACorruptRights</codeph> or <codeph>KErrCorrupt</codeph> errorcode is sent to clients, depending on the type of corruption detected andhow the client chooses to handle it. </p> <p> <b>Note:</b> It is recommendedthat clients be designed to handle such an error if received, as it can usuallybe considered a fatal error. </p> <codeblock id="GUID-24C1BC9E-786E-5C1F-AA27-839B3DC9369F" xml:space="preserve">// Create a CData object to read the content...TRAP(err, data = content->OpenContentLC(EDisplay));if (err != KErrNone) { if (err == KErrCACorruptRights) { //Agent may have performed some error handling. //Client may need to perform some client specific operations(e.g. cleanup). } else if (err == KErrCorrupt) { DisplayErrorMsg('Unable to decode rights because it is corrupt!'); } else if (err == ...) ... } ...</codeblock> <p id="GUID-15A1A9B3-BB5D-5677-BFE9-47EABD4064BF"><b>Handle errors</b> </p> <p>Agentsdisplay the errors on screen when they occur. Once the error has been acknowledgedby the user, the agent returns the error code to the client application. Ifa client application does not want errors displayed on screen, it can requestto disable the agent UI using the <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita#GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A/GUID-4F452F1F-FFDA-34F4-9625-0A047CF44DE1"><apiname>CContent::SetProperty()</apiname></xref> function. </p> <codeblock id="GUID-20598B16-CC87-5BE1-8B7D-CF612A2150FB" xml:space="preserve">// Disable UIcontent->SetProperty(EAgentPropertyAgentUI , 0);</codeblock> <p>Some agents may present confirmation dialogs to the user beforeallowing them to perform certain operations. For example, when a user inadvertentlytries to delete a DRM-protected file. The agent can present a dialog asking"are you sure?". The agent can then return the outcome of the delete to theapplication, that is <codeph>KErrCancel</codeph>, if the user presses cancel.The <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita#GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A/GUID-4F452F1F-FFDA-34F4-9625-0A047CF44DE1"><apiname>CContent::SetProperty()</apiname></xref> function can also be used todisable the confirmation dialogs. </p> <p id="GUID-6A50AE44-E618-5D99-B5D8-7BBA8FE7948A"><b>Handlerights for DRM content</b> </p> <p>There are two functions available thatgive the application some control over the rights: </p> <p><i>Request rights</i> </p> <p> <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-BF3DA6BD-A779-3BD8-B668-DB8E900F9053"><apiname> ContentAccess::CContent::RequestRights()</apiname></xref> allows the application to ask the agent to undertake whatever steps arenecessary to obtain rights for the given content object. Some agents may notsupport this mechanism, in which case they returns <codeph>KErrCANotSupported</codeph>. </p> <p>Therequest rights call includes a <codeph>TRequestStatus</codeph> parameter,which allows the application to be notified of the outcome of the rights request. </p> <codeblock id="GUID-FEA60E64-1735-5D3D-8D14-6BA3E6F8A54E" xml:space="preserve">content->RequestRights(status, uniqueId);</codeblock> <p><i>Displayinformation</i></p> <p> <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-6613813A-5621-3F0F-B64F-DA2E1F89D7E7"><apiname>ContentAccess::CContent::DisplayInfoL()</apiname></xref> allowsthe application to ask the agent to display the file and/or rights informationfor the given content object. The call returns when the display is dismissed. </p> <p>Someagents may not support this mechanism, in which case they return <codeph>KErrCANotSupported</codeph>. </p> <codeblock id="GUID-8B96985A-4810-5CE1-9561-0C8BC5D725C0" xml:space="preserve">content->DisplayInfoL(EFileProperties, uniqueId);</codeblock> <p id="GUID-635EE5EF-469D-5FD3-9400-25DF95FD2E96"><b>Get content object notifications</b> </p> <p>The <xref href="GUID-EF3C33C0-F02E-3C35-B289-3800631EDC3A.dita"><apiname>CContent</apiname></xref> interfacesupports notification requests for content objects within files. The eventsfor which an application can request notification are given by the enumeration <xref href="GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601.dita#GUID-0F5CE9B5-E674-3962-8376-CFB1ECB2F601/GUID-20035389-F839-3ACF-B892-B6A58A13460A"><apiname>ContentAccess::TEventMask</apiname></xref>. </p> <p>Thefollowing example requests and cancels notification for rights becoming available: </p> <codeblock id="GUID-81C47EF6-AF59-59AC-B07F-D190ABE89973" xml:space="preserve">// Request notification when rights become available for a particular content objectcontent->NotifyStatusChange(ERightsAvailable, status, uniqueId);// Cancel notification requestcontent->CancelNotifyStatusChange(status, uniqueId);</codeblock> <p id="GUID-DDAE0B57-B296-58E8-8220-AE5AA9BF7B8D"><b>Closea container</b> </p> <p>To close a container, use the <xref href="GUID-FC40011B-32D3-328B-BB59-35BEF46A215A.dita#GUID-FC40011B-32D3-328B-BB59-35BEF46A215A/GUID-E4CAB325-A0BC-3A43-A1CD-F099B478B188"><apiname>ContentAccess::CContent::CloseContainer()</apiname></xref> function. </p> <p>Forexample, Container 1.1 is closed and Container 1 is still open: </p> <codeblock id="GUID-FDDCBB26-6FA6-5B1C-87EA-EE32182A97C1" xml:space="preserve">//Close Container 1.1 content->CloseContainer(); // Get the embedded content objects in the current container content->GetEmbeddedObjectsL(myArray, EContentObject);i = myArray.Count(); // Six content objects myArray.ResetAndDestroy(); // Get the number of container objects in the current container content->GetEmbeddedObjectsL(myArray, EContainerObject); i = myArray.Count(); // One container object myArray.ResetAndDestroy();</codeblock> <fig id="GUID-F3A1B237-A07C-5AE7-82F1-5DAA3BA65553"><image href="GUID-DC7E3634-9762-542F-BDAE-AC1F2D03F55D_d0e589493_href.png" placement="inline"/></fig> </section></conbody></concept>