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: // The Supplier API allows agents to publicise the MIME types they are sl@0: // interested in. When those files arrive on the device, message handling sl@0: // applications can check these MIME types and import the file sl@0: // into CAF. The agent transforms the file into a different format sl@0: // for use within the device. sl@0: // In most cases this won't be necessary, since the files will arrive in the sl@0: // same format that they will be used in. However, some agents require the device sl@0: // to protect (encrypt) the content at the moment it arrives; the Supplier sl@0: // API fulfills that role. sl@0: // The classes used in the supply operation are: sl@0: // ContentAccess::CSupplier and instances of ContentAccess::CImportFile. sl@0: //
sl@0: // The ContentAccess::CSupplier is designed to allow several unrelated files to be imported sl@0: // into CAF. It uses its ContentAccess::CAgentResolver member to determine sl@0: // which CA agent should be used to import each file. The CAgentResolver builds sl@0: // a list of all agents when it is created and updates the list if new agents sl@0: // are installed. sl@0: // A typical import session will start with the creation of a CSupplier, e.g., sl@0: // //Create Supplier sl@0: // CSupplier *mySupplier = CSupplier::NewL(); sl@0: // Most applications will have a preference for the directory where output files sl@0: // are to be stored. Usually the first thing to do with the new CSupplier instance sl@0: // is to set the output path. sl@0: // //Set output path for DRM protected content sl@0: // _LIT(KPath,"C:\myOutputFiles"); sl@0: // mySupplier->SetOutputDirectoryL(KPath()); sl@0: // It is not necessary to set the output path if the application sl@0: // provides output file handles to the agent. sl@0: //
sl@0: // Check that the MIME type is supported sl@0: // Before importing a file into the content access framework, an application sl@0: // should check that the MIME type of the file is supported. Each agent publishes a sl@0: // list of the MIME types it supports. The list is configured in the agent's sl@0: // resource file and can be checked using ContentAccess::CSupplier::IsImportSupported() sl@0: // if(!mySupplier->IsImportSupported(myMimeType)) sl@0: // return; sl@0: // Create a CMetaDataList object sl@0: // The CMetaDataList object is used to store any information associated with the import file that sl@0: // may be useful for the agent. These values will be passed to the agent. sl@0: // For example OMA DRM 1.0 files sometimes arrive with the HTTP header sl@0: // X-Oma-Drm-Separate-Delivery. This informs the agent how long before rights are expected sl@0: // for the content. If the rights were expected in 12 seconds it would be something like sl@0: // the following: sl@0: // // Create meta-data array sl@0: // CMetaDataArray *metaDataArray = new (ELeave) CMetaDataArray(); sl@0: // CleanupStack::PushL(metaDataArray); sl@0: // // Add any useful information we can think of.... sl@0: // metaDataArray->AddL(_L("Content Type"), _L("application/vnd.oma.drm.dm")); sl@0: // metaDataArray->AddL(_L("X-Oma-Drm-Separate-Delivery"), _L("12")); sl@0: // The file is 'written' to CAF using a ContentAccess::CImportFile object. sl@0: // ContentAccess::CSupplier::ImportFile() creates an CImportFile object for importing a file. sl@0: // The parameters supplied indicate whether the agent will create the output files or whether sl@0: // the application using CAF will generate output files for the agent on demand. sl@0: // // Create the import object, passing in the metaDataArray created earlier sl@0: // // The application will supply the output files sl@0: // CImportFile *import = mySupplier->ImportFileL(sourceMimeType, *metaDataArray); sl@0: // The application should now transfer the file to CAF using the CImportFile object. sl@0: // Only one file can be transferred by each instance although several output files sl@0: // may be produced. Applications should create new CImportFile objects in order to import more files. sl@0: // Agents Generating the Output files sl@0: // If the application wants the agent to generate the output files, it should supply a suggested sl@0: // file name in the call to CSupplier::ImportFile(). Even if this parameter is a zero length sl@0: // descriptor, it still indicates that the agent is responsible for generating output files. sl@0: // Agents will create the output files in a directory nominated by the application when it called sl@0: // CSupplier::SetOutputDirectoryL() or they may decide to store the output files in their private sl@0: // directory. sl@0: // Applications should check at the end of the import to find out how many output files were created sl@0: // and where they are stored. sl@0: // Application generating the Output files sl@0: // If no suggested file name is passed to the agent, the application will provide output files for sl@0: // the agent to use. This mechanism allows applications to open files in their own private directory and sl@0: // ask the CAF agent to store the output in those files. sl@0: // The way it works is the same as an any other import operation, the difference is that the call sl@0: // to CImportFile::WriteData() or CImportFile::WriteComplete() may return an error code of sl@0: // KErrCANewFileHandleRequired. sl@0: // This error code indicates that the agent needs a new output file handle in order to continue. The sl@0: // application should open a new output file with write access and call CImportFile::ContinueWithNewOutputFile() sl@0: // to supply the new handle to the agent. It is possible that further handles may be needed, if so sl@0: // CImportFile::ContinueWithNewOutputFile() will return KErrCANewFileHandleRequired and the application should sl@0: // repeat the procedure with another file. sl@0: // The agent must cache its state before returning KErrCANewFileHandleRequired. The application MUST NOT resend sl@0: // the same WriteData() or WriteComplete() command. sl@0: // At the end of the import operation the output files will still be listed regardless of whether sl@0: // they were supplied by the application or the agent. sl@0: //
sl@0: // ContentAccess::CImportFile is the class used to write the file data to CAF. sl@0: // It is created by ContentAccess::CSupplier and can only be used to import a single file. sl@0: // An application should call WriteData() to transfer a field in 'chunks' to the Content sl@0: // Access Framework. Usually this would be something like the following: sl@0: // TFileName fileName; sl@0: // TBuf8<128> data; sl@0: // TInt err = KErrNone; sl@0: // // start importing content sl@0: // while( (source still has data) && (err==KErrNone) ) sl@0: // source.read(data); sl@0: // err = import->WriteData(data); sl@0: // // need to supply new file to import to ? sl@0: // while (err == KErrCANewFileHandleRequired) sl@0: // // supply new file in order to continue writing sl@0: // RFile newFile; sl@0: // import->GetSuggestedOutputFileName(fileName); sl@0: // newFile.Open(fileName, EFileWrite); sl@0: // err = import->ContinueWithNewOutputFile(newFile, fileName); sl@0: // newFile.Close(); sl@0: //
sl@0: // When all the data is written, the application should call ContentAccess::CImportFile::WriteComplete(), this will sl@0: // let the agent know that all the data has been transferred and allow it to perform any final processing. sl@0: // err = import->WriteComplete(); sl@0: // // When application supplies file handles it must always check to see if sl@0: // // the agent needs a new file handle sl@0: // while(err == KErrCANewFileHandleRequired) sl@0: // RFile newFile; sl@0: // import->GetSuggestedOutputFileName(fileName); sl@0: // newFile.Open(fileName, EFileWrite); sl@0: // err = import->ContinueWithNewOutputFile(newFile, filename); sl@0: // // It is possible that the agent needs yet another file handle sl@0: // newFile.Close(); // agent makes a copy so we don't need to keep our file handle sl@0: // At this stage all the agent's work is done, the CImportFile object can be deleted. sl@0: //
sl@0: // When the import is finished the application may wish to check if any output files have sl@0: // been produced. The list of output files is accessed using ContentAccess::CImportFile::OutputFileL(). sl@0: // // loop over all the output files produced sl@0: // for(TInt i =0; i < import->OutputFileCountL(); i++) sl@0: // // Can now retrieve filename, type of file (receipt or content) and sl@0: // // MIME type for the file produced sl@0: // TPtr filename = import->OutputFileL(i).FileName(); sl@0: // TOutputType type = import->OutputFileL(i).OutputType(); sl@0: // TPtr8 mimetype = import->OutputFileL(i).MimeType(); sl@0: // The output files can be either content files or receipts for DRM rights. It is possible that no output sl@0: // files will be generated and the file will be "absorbed" into the agent. sl@0: // Also, it is important to remember that the MIME type and most likely the file extension of the output files are sl@0: // almost certainly different to the MIME type and file extension of the imported file. sl@0: //
sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @page CSupplierAPI Importing files into the Content Access Framework sl@0: - @ref SupplierAPI sl@0: - @ref ImportSession sl@0: - @ref ImportCAF sl@0: - @ref Importfile sl@0: - @ref ImportComplete sl@0: - @ref ImportOutput sl@0: code examples given below. For examples with error checking see @ref ExampleSupplier2. sl@0: @section SupplierAPI Supplier API sl@0: @section ImportSession Starting a new import session sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: @section ImportCAF Preparing to import the file sl@0: @code sl@0: @endcode sl@0: @code sl@0: @endcode sl@0: @section ImportFile Creating the CImportFile object sl@0: @code sl@0: @endcode sl@0: @section Importfile Transferring the file to the Content Access Agent sl@0: @code sl@0: @endcode sl@0: @section ImportComplete Completing the Import sl@0: @code sl@0: @endcode sl@0: @section ImportOutput Output files produced sl@0: @code sl@0: @endcode sl@0: */