os/security/contentmgmt/contentaccessfwfordrm/engineering/dox/Examples.dox
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Some of the examples below do not include fully comprehensive error checking. They are written this way to simplify the 
    15 // understanding of the basic steps involved. All errors should be handled appropriately in production code.
    16 // <b>Consumer API </b>
    17 // <b>Supplier API </b>
    18 // <hr>
    19 // This example function takes the URI of a file and displays the plaintext version of that content on screen.
    20 // If anything goes wrong, for instance the file does not exist or there are no valid rights
    21 // that will allow the file to be displayed, the function will just leave.
    22 // It's important to notice the call to <code>ContentAccess::CData::ExecuteIntent()</code>, this should always be called, even if you
    23 // think it's unlikely you will open DRM content.
    24 // class CContentViewer : public CBase
    25 // public:
    26 // static CContentViewer* NewL();
    27 // static CContentViewer* NewLC();
    28 // // Display given content.
    29 // void DisplayContent(const TDesC& aUri, TRequestStatus& aStatus)
    30 // TRAPD(err, DisplayContentL(aUri));
    31 // User::RequestComplete(aStatus, err);
    32 // private:
    33 // CContentViewer() : CBase() {}
    34 // ~CContentViewer() {} 
    35 // void DisplayContentL(const TDesC& aUri)
    36 // TInt size = 0;
    37 // TInt i = 0;
    38 // // Create a CContent object
    39 // // CAF will figure out the appropriate agent
    40 // CContent *content = CContent::NewLC(aUri);
    41 // // Create a CData object to read the content
    42 // // Tell the agent we are planning to display the content
    43 // CData *data = content->OpenContentLC(EDisplay);
    44 // // Don't need content object any more
    45 // CleanupStack::PopAndDestroy(content);
    46 // // get the size of the plaintext content
    47 // data->DataSizeL(size);
    48 // // Execute the intent, tell the agent that we plan to display the content
    49 // // It is at this point that any stateful rights will be decremented
    50 // data->ExecuteIntentL(EDisplay);
    51 // // read and display the file until we reach the end of the file
    52 // TBuf <128> buffer;		
    53 // while(i < size)
    54 // // read from the file
    55 // User::LeaveIfError(data->Read(buffer));
    56 // i += buffer.Length();
    57 // // display on screen
    58 // printf(buffer);
    59 // // finished with Data object
    60 // CleanupStack::PopAndDestroy(data);
    61 // <hr>
    62 // This example is the same as before except it attempts to obtain or wait for rights
    63 // to become available rather than just leaving if access to the content is restricted.
    64 // class CContentViewer : public CActive
    65 // public:
    66 // static CContentViewer* NewL();
    67 // static CContentViewer* NewLC();
    68 // // Display given content.
    69 // void DisplayContent(const TDesC& aUri, TRequestStatus& aStatus)
    70 // iUri = aUri;
    71 // iClientStatus = &aStatus;
    72 // iClientStatus = KRequestPending;
    73 // iCurrentState = EOpenFile;
    74 // // trigger our RunL
    75 // iStatus = KRequestPending;
    76 // SetActive();
    77 // User::RequestComplete(iStatus, KErrNone);
    78 // void RunL()
    79 // TInt err = iStatus.Int();
    80 // switch (iCurrentState)
    81 // case EOpenFile:
    82 // iContent = CContent::NewL(aUri);
    83 // TRAP(err, iData = iContent->OpenContentL(EDisplay));
    84 // iCurrentState = EReadAndDisplay;	// follow through...
    85 // case EReadAndDisplay:
    86 // if(err == KErrNone)
    87 // TRAP(err, DisplayFile());
    88 // iCurrentState = EFinished;
    89 // // tell client iStatus that we have finished
    90 // User::RequestComplete(*iClientStatus, err);
    91 // return;
    92 // else if(err == KErrCANoRights)
    93 // // we don't have rights so we need to wait for them
    94 // iCurrentState = EWaitingForRights;
    95 // // ask CAF to initiate download of rights
    96 // iContent->RequestRights(iStatus);
    97 // else if(err == KErrCAPendingRights)
    98 // // waiting for rights to arrive, expected any minute now
    99 // iCurrentState = EWaitingForRights;
   100 // // ask CAF to notify us when they arrive
   101 // iContent->NotifyStatusChange(ERightsAvailable , iStatus);
   102 // // wait for CAF to complete our request 
   103 // iLastError = err;
   104 // iStatus = KRequestPending;
   105 // SetActive();
   106 // break;
   107 // case EWaitingForRights:
   108 // if(ret == KErrNone)
   109 // // change the state to try and display content again
   110 // iCurrentState = EReadAndDisplay;
   111 // // trigger our RunL
   112 // iLastError = err;
   113 // iStatus = KRequestPending;
   114 // SetActive();
   115 // User::RequestComplete(iStatus, KErrNone);
   116 // else
   117 // // couldn't get rights, tell parent active object we're finished
   118 // User::RequestComplete(iClientStatus, err);
   119 // return;
   120 // break;
   121 // protected:		
   122 // void DoCancel()
   123 // if (iLastError == KErrCAPendingRights)
   124 // iContent->CancelNotifyStatusChange(iStatus);
   125 // else if (iLastError == KErrCANoRights)
   126 // iContent->CancelRequestRights(iStatus);
   127 // private:
   128 // CContentViewer() : CActive(EPriorityStandard)
   129 // CActiveScheduler::Add(this); 
   130 // ~CContentViewer() 
   131 // Cancel();
   132 // if (iData) delete iData; 
   133 // if (iContent) delete iContent;
   134 // // Display the content, if any error occurs then leave
   135 // void DisplayContentL();
   136 // TInt size = 0;
   137 // TInt i = 0;
   138 // TBuf <128> buffer;
   139 // // Execute the intent, tell the agent that we plan to display the content
   140 // // It is at this point that any stateful rights will be decremented
   141 // iData->ExecuteIntentL(EDisplay);
   142 // // get the size of the plaintext content
   143 // iData->DataSizeL(size);
   144 // // read and display the file until we reach the end of the file
   145 // while(i < size)
   146 // // read from the file
   147 // User::LeaveIfError(iData->Read(buffer));
   148 // i += buffer.Length();
   149 // // Display on screen
   150 // printf(buffer);
   151 // private:
   152 // enum TState
   153 // EOpenFile = 0,
   154 // EReadAndDisplay,
   155 // EWaitingForRights,
   156 // EFinished
   157 // CContent*	iContent;
   158 // CData* 		iData;
   159 // TDesC		iUri;
   160 // TState			iCurrentState;
   161 // TInt 			iLastError;
   162 // TRequestStatus*		iClientStatus;
   163 // <hr>
   164 // Some servers may wish to prevent access to DRM content by untrusted clients, even if
   165 // the server itself has DRM capability.
   166 // To achieve this the server should use the <code>ContentAccess::TIntent::EUnknown</code> intent when 
   167 // accessing content. Content files that are not DRM protected will still work normally, but
   168 // access to DRM protected content will be blocked.
   169 // // Tell the agent we have no idea what the application plans to do
   170 // CData *data = content->OpenContentL(EUnknown);
   171 // // Execute the intent, tell the agent that we have no idea what the content will be used for
   172 // data->ExecuteIntentL(EUnknown);
   173 // <hr>
   174 // When reading from a particular content object within a file the application must supply
   175 // the \c UniqueId of the object when calling <code>ContentAccess::CContent::OpenContentL()</code>.
   176 // void DisplayTextFileL(const TDesC& aUri)
   177 // TInt size = 0;
   178 // TInt i = 0;
   179 // TBuf <128> buffer;
   180 // // Create a CContent object
   181 // // CAF will figure out the appropriate agent
   182 // CContent *content = CContent::NewLC(aUri);
   183 // // Find the objects in the file with MIME type image/jpeg
   184 // RStreamablePtrArray<CEmbeddedObject> myArray;
   185 // CleanupClosePushL(myArray);
   186 // User::LeaveIfError(content->Search(myArray, _L("image/jpeg"), EFalse));
   187 // // Get the virtual path of the first image/jpeg we find
   188 // TVirtualPathPtr picture = *myArray[0];
   189 // // Tell the agent to open the object with the given UniqueId
   190 // CData *data = content->OpenContentLC(EDisplay, picture.UniqueId());
   191 // // Don't need content object or array any more
   192 // CleanupStack::PopAndDestroy(2);	// content, myArray
   193 // // get the size of the plaintext content
   194 // data->DataSizeL(size);
   195 // // Execute the intent, tell the agent that we plan to display the content
   196 // // It is at this point that any stateful rights will be decremented
   197 // data->ExecuteIntentL(EDisplay);
   198 // // read and display the file until we reach the end of the file
   199 // while(i < size)
   200 // // read from the file
   201 // User::LeaveIfError(data->Read(buffer));
   202 // i += buffer.Length();
   203 // // display on screen
   204 // printf(buffer);
   205 // // finished with Data object
   206 // CleanupStack::PopAndDestroy(data);
   207 // <hr>
   208 // This example shows how a messaging application that has just received
   209 // a message attachment from a mail server can offer the attachment
   210 // to CAF for processing. The output files will be saved in <code>C:\\files\\</code>.
   211 // void CMyApp::ReceiveMessageAttachment(const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   212 // // Create supplier object
   213 // CSupplier* supplier = CSupplier::NewLC();
   214 // // Tell the agent where we would like the output files to be written
   215 // supplier->SetOutputDirectoryL(_L("C:\\files"));
   216 // // Check if CAF can import this attachment we just received
   217 // if(supplier->IsImportSupported(aContentType))
   218 // ProcessAttachmentL(supplier, aContentType, aMessageAttachment);	
   219 // else
   220 // // just save the message to a file in its current form
   221 // RFile theFile;
   222 // theFile.Open(iFs, "myFile");
   223 // theFile.Write(aMessageAttachment);
   224 // theFile.Close();
   225 // // Add the file to the list of attachments
   226 // AddAttachment("myFile");
   227 // void CMyApp::ProcessAttachmentL(CSupplier* aSupplier, const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   228 // TInt err = KErrNone;
   229 // TBuf <128> buf;
   230 // // Create meta-data array
   231 // CMetaDataArray* metaDataArray = new (ELeave) CMetaDataArray();
   232 // CleanupStack::PushL(metaDataArray);
   233 // // Add any useful information we can think of....
   234 // // Obviously these would not be hardcoded this way in a real import
   235 // metaDataArray->AddL(_L("Content Type"), _L("application/vnd.oma.drm.dm"));
   236 // metaDataArray->AddL(_L("Content Length"), _L("1201"));
   237 // metaDataArray->AddL(_L("X-Oma-Drm-Separate-Delivery"), _L("6"));
   238 // // Create the import object
   239 // CImportFile* import = aSupplier->ImportFileL(aContentType, *metaDataArray, _L("myfile"));
   240 // CleanupStack::PushL(import);
   241 // // import the attachment
   242 // err = import->WriteData(aMessageText);
   243 // // tell CAF (and hence the agent) it's now got the entire file
   244 // if (err == KErrNone)
   245 // err = import->WriteDataComplete();
   246 // if (err == KErrNone)
   247 // // Look at the output of the import operation
   248 // for(TInt i = 0; i < import->OutputFileCountL(); i++)
   249 // // for this example only add content output files
   250 // // (absorb any rights in the original attachment 'silently')
   251 // if(import->OutputFilesL(i).OutputType == EContent)
   252 // // Add file to list of attachments for this message
   253 // AddAttachment(import->OutputFilesL(i).FileName());
   254 // // Error handling
   255 // if (err != KErrNone)
   256 // if (err == KErrNotReady)	
   257 // DisplayErrorMsg("Agent not ready for import");
   258 // else if (err == KErrCACorruptContent)
   259 // DisplayErrorMsg("Content data is corrupt");
   260 // else
   261 // DisplayErrorMsg("Unexpected error: %d", err);
   262 // // Finished
   263 // CleanupStack::PopAndDestroy(2);		// metaDataArray, import
   264 // <hr>
   265 // This example shows how a messaging application that has just received
   266 // a message attachment from a mail server can offer the attachment
   267 // to CAF for processing and store the file in its own private directory.
   268 // void CMyApp::ReceiveMessageAttachment(const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   269 // // Create supplier object
   270 // CSupplier* supplier = CSupplier::NewLC();
   271 // // Check if CAF can import this attachment we just received
   272 // if(supplier->IsImportSupported(aContentType))
   273 // ProcessAttachmentL(supplier, aContentType, aMessageAttachment);	
   274 // else
   275 // // just save the message to a file in its current form
   276 // RFile theFile;
   277 // theFile.Open(iFs, "myFile");
   278 // theFile.Write(aMessageAttachment);
   279 // theFile.Close();
   280 // // Add the file to the list of attachments
   281 // AddAttachment("myFile");
   282 // void CMyApp::ProcessAttachmentL(CSupplier* aSupplier, const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   283 // TInt err = KErrNone;
   284 // TBuf <128> buf;
   285 // TBuf <4> fileExtension;
   286 // _LIT(KOutputFileName, "\\private\\12345678\\outputfile.");
   287 // TFileName fileName(KOutputFileExtension);
   288 // RFile file;
   289 // // Create meta-data array
   290 // CMetaDataArray* metaDataArray = CMetaDataArray::NewLC();
   291 // // Add any useful information we can think of....
   292 // // Obviously these would not be hardcoded this way in a real import
   293 // metaDataArray->AddL(_L("Content Type"), _L("application/vnd.oma.drm.dm"));
   294 // metaDataArray->AddL(_L("Content Length"), _L("1201"));
   295 // metaDataArray->AddL(_L("X-Oma-Drm-Separate-Delivery"), _L("6"));
   296 // // Create the import object, no suggested file name implies the application will supply output files
   297 // CImportFile* import = aSupplier->ImportFileL(aContentType, *metaDataArray);
   298 // CleanupStack::PushL(import);
   299 // // Start importing the attachment
   300 // // (if the agent needs one or more output files, continue looping until 
   301 // // the agent finishes the previous)
   302 // TInt err = import->WriteData(aMessageText);
   303 // while(err == KErrCANewFileHandleRequired)
   304 // import->GetSuggestedOutputFileExtension(fileExtension);
   305 // filName.Append(fileExtension);
   306 // User::LeaveIfError(file.Open(iFs, fileName));
   307 // err = import->ContinueWithNewOutputFile(file);
   308 // file.Close();
   309 // if (err == KErrNone)
   310 // // Complete the import process
   311 // err = import->WriteDataComplete();
   312 // while(err == KErrCANewFileHandleRequired)
   313 // import->GetSuggestedOutputFileExtension(fileExtension);
   314 // filName.Append(fileExtension);
   315 // User::LeaveIfError(file.Open(iFs, fileName));
   316 // err = import->ContinueWithNewOutputFile(file);
   317 // file.Close();
   318 // if (err == KErrNone)
   319 // // Look at the output of the import operation
   320 // for(TInt i = 0; i < import->OutputFileCountL(); i++)
   321 // // for this example only add content output files
   322 // // (absorb any rights in the original attachment 'silently')
   323 // if(import->OutputFilesL(i).OutputType == EContent)
   324 // // Add file to list of attachments for this message
   325 // AddAttachment(import->OutputFilesL(i).FileName());
   326 // // Error handling
   327 // if (err != KErrNone)
   328 // if (err == KErrNotReady)	
   329 // DisplayErrorMsg("Agent not ready for import");
   330 // else if (err == KErrCACorruptContent)
   331 // DisplayErrorMsg("Content data is corrupt");
   332 // else
   333 // DisplayErrorMsg("Unexpected error: %d", err);
   334 // // Finshed
   335 // CleanupStack::PopAndDestroy(2);		// metaDataArray, import
   336 // 
   337 //
   338 
   339 /**
   340  @page CAFExamples Example source code using CAF
   341  - @ref ExampleRead1
   342  - @ref ExampleReadWithErrCheck
   343  - @ref PlayingUnprotectedOnly 
   344  - @ref MultipleContentExample
   345  - @ref ExampleSupplier1
   346  - @ref ExampleSupplier2
   347  @section ExampleRead1 Reading from a file, no error checking
   348  @code
   349  @endcode
   350  @section ExampleReadWithErrCheck Reading from a file, with error checking
   351  @code
   352  @endcode
   353  @section PlayingUnprotectedOnly Preventing access to DRM content
   354  @code
   355  @endcode
   356  @section MultipleContentExample File containing several content objects
   357  @code
   358  @endcode
   359  @section ExampleSupplier1 Importing a content file, agent provides output files
   360  @code
   361  @endcode
   362  @section ExampleSupplier2 Importing a content file, application provides output files
   363  @code
   364  @endcode
   365 */