Supplier API Tutorial

The Supplier API handles the delivery and transformation of Digital Rights Management (DRM) protected content. It transforms imported DRM content in a device into a secure format for storage.

Supplier API comprises of ContentAccess::CSupplier and ContentAccess::CImportFile.

Introduction

The Supplier API allows Content Access (CA) agents to publish the supported content MIME types that can be handled by Content Access Framework (CAF). When a file arrive on a device (for example, through a browser), applications check for its MIME types and import the file into CAF. The agent transforms the file into a secure format for using it in the device.

The transformation may not be required because the files arrive in a format fit for use in the device. However, some agents might require to protect (encrypt) the content at the moment it arrives, and Supplier API manages this protection.

Start a new import session

Use ContentAccess::CSupplier to import files into CAF.

Create an instance of CSupplier to start an import session and set the output path according to an application's requirements.

// Create Supplier 
CSupplier *mySupplier = CSupplier::NewL(); 

// Set output path for DRM protected content 
_LIT(KPath,"C:\\myOutputFiles");
mySupplier->SetOutputDirectoryL(KPath());
Note:

Prepare to import the file

Preparing to import a DRM protected file includes the following steps:

  1. Checking for supported MIME types

  2. Creating a CMetaDataList object

Checking for supported MIME types

Before importing a file into the content access framework, an application must check if the MIME type of the file is supported. Each agent publishes a list of supported MIME types and the list is configured in the agent's resource file. Use ContentAccess::CSupplier::IsImportSupported() to check the list of supported MIME type of files.

if(!mySupplier->IsImportSupported(myMimeType)) 
    { 
    return; 
    }

Creating a CMetaDataList object

The CMetaDataList object stores information associated with an import file, and it is passed to the CA agent. For example, OMA DRM 1.0 files might contain HTTP header X-Oma-Drm-Separate-Delivery, which informs the agent about the time duration within which rights are expected for the content.

The following code snippet shows creating a CMetaDataList object and information about the duration (for example, 12 seconds) in which rights are expected

// Create meta-data array 
CMetaDataArray *metaDataArray = new (ELeave) CMetaDataArray(); 
CleanupStack::PushL(metaDataArray);

// Add any useful information we can think of.... 
metaDataArray->AddL(_L("Content Type"),_L("application/vnd.oma.drm.dm")); 
metaDataArray->AddL(_L("X-Oma-Drm-Separate-Delivery"),_L("12"));

Import a file

  1. Create the CImportFile object

  2. Generate output files

Creating the CImportFile object

ContentAccess::CImportFile() allows to write a file to CAF. Use ContentAccess::CSupplier::ImportFileL() to create a CImportFile object for importing a file. The parameters supplied must indicate whether the agent generates the output files or if the application generates the output files for the agents on demand.

// Create the import object, passing in the metaDataArray created earlier 
// The application must supply the output files 
            
CImportFile *import = mySupplier->ImportFileL(sourceMimeType, *metaDataArray);

Applications use the CImportFile object to transfer the content to CAF.

Note:

  • You must create new CImportFile objects to import multiple files.

  • You can transfer only one file in an instance, even if multiple output files are produced.

Generating output files

Use CSupplier::ImportFileL() to generate the output files and specify the appropriate parameters. By default, application generates the output file. Otherwise, the agent or application can generate the output file based on the specified parameters.

Agents generating output files

Applications must specify the following information if they require agents to generate the output files:

  • Specify the file name in CSupplier::ImportFileL() indicating that agent must generate output files.

  • Use CSupplier::SetOutputDirectoryL() to specify the directory for the files to be generated. Optionally, applications can decide to store the output files in their private directory.

  • Check for the number of generated output files and their stored location, when the import operation is complete.

Applications generating output files

If the filename is not passed to the agent, applications provide output files to the agents. This allows applications to open files in their own private directory and ask the CAF agent to store the output in those files. This involves the following considerations:

Note: At the end of the import operation the output files are listed irrespective of whether they were supplied by the application or the agent.

Transfer the file to the Content Access Agent

Use ContentAccess::CImportFile to write the file data to CAF. ContentAccess::CSupplier creates ContentAccess::CImportFile which only imports a single file. An application must call WriteData() to transfer a field in chunks to the CAF.

The following code snippet explains this.

// importing the file data
ImportFile *import; 
TFileName fileName; 
TPath outputfileName; 
TBuf8 data <128> 
_LIT(KDirectoryPath, "C:\\private\\12345678\\");
... 

while(!endofsource) 
    {
    source.read(data); 
    err = import->WriteData(data); 

    // When application supplies file handles it must always check to see if 
    // the agent needs a new file handle 

    while(err == KErrCANewFileHandleRequired) 
        {               
        RFile newFile; 
        import->GetSuggestedOutputFileName(fileName); 
        outputFileName.Copy(KDirectoryPath); 
        outputFileName.Append(fileName);
        newFile.Open(outputFileName, EFileWrite); 
        err = import->ContinueWithNewOutputFile(newFile, outputFileName); 

        // It is possible that the agent needs yet another file handle
        newFile.Close(); // agent makes a copy so we don't need to keep our file handle 
        }
    }

Complete the import

When the data is written, use ContentAccess::CImportFile::WriteDataComplete() to inform the agent that data transfer is complete, allowing it to perform any final processing.

The following code snippet explains this step:

err = import->WriteDataComplete(); 

// When the application supplies file handles it must always check to see if 
// the agent needs a new file handle 
while(err == KErrCANewFileHandleRequired) 
    {
    RFile newFile; 
    import->GetSuggestedOutputFileName(fileName); 
    outputFileName.Copy(KDirectoryPath); 
    outputFileName.Append(fileName);  
    newFile.Open(outputFileName, EFileWrite);  
    err = import->ContinueWithNewOutputFile(newFile, outputFileName);
    // It is possible that the agent needs yet another file handle 
    newFile.Close(); // agent makes a copy so we don't need to keep our file handle
    }

// Finished
//At this stage all the agent's work is done and the CImportFile object can be deleted. 

Check the output file

When import is complete, use ContentAccess::CImportFile::OutputFileL() to list all the output files produced. The output files can be either content files or receipts for DRM rights.

// loop over all the output files produced 
for(TInt I =0; I < import->OutputFileCountL(); I++) 
    {
    // Can now retrieve filename, type of file (receipt or content) and MIME type for the file produced
    TPtr filename = import->OutputFileL(I).FileName(); 
    TOutputType type = import->OutputFileL(I).OutputType();
    TPtr8 mimetype = import->OutputFileL(I).MimeType(); 
    }

Note:

The MIME type and the file extension of the output files can be different to the MIME type and file extension of the imported file.

Related concepts
CAF Overview