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