os/security/contentmgmt/contentaccessfwfordrm/engineering/dox/Examples.dox
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/contentmgmt/contentaccessfwfordrm/engineering/dox/Examples.dox	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,365 @@
     1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Some of the examples below do not include fully comprehensive error checking. They are written this way to simplify the 
    1.18 +// understanding of the basic steps involved. All errors should be handled appropriately in production code.
    1.19 +// <b>Consumer API </b>
    1.20 +// <b>Supplier API </b>
    1.21 +// <hr>
    1.22 +// This example function takes the URI of a file and displays the plaintext version of that content on screen.
    1.23 +// If anything goes wrong, for instance the file does not exist or there are no valid rights
    1.24 +// that will allow the file to be displayed, the function will just leave.
    1.25 +// It's important to notice the call to <code>ContentAccess::CData::ExecuteIntent()</code>, this should always be called, even if you
    1.26 +// think it's unlikely you will open DRM content.
    1.27 +// class CContentViewer : public CBase
    1.28 +// public:
    1.29 +// static CContentViewer* NewL();
    1.30 +// static CContentViewer* NewLC();
    1.31 +// // Display given content.
    1.32 +// void DisplayContent(const TDesC& aUri, TRequestStatus& aStatus)
    1.33 +// TRAPD(err, DisplayContentL(aUri));
    1.34 +// User::RequestComplete(aStatus, err);
    1.35 +// private:
    1.36 +// CContentViewer() : CBase() {}
    1.37 +// ~CContentViewer() {} 
    1.38 +// void DisplayContentL(const TDesC& aUri)
    1.39 +// TInt size = 0;
    1.40 +// TInt i = 0;
    1.41 +// // Create a CContent object
    1.42 +// // CAF will figure out the appropriate agent
    1.43 +// CContent *content = CContent::NewLC(aUri);
    1.44 +// // Create a CData object to read the content
    1.45 +// // Tell the agent we are planning to display the content
    1.46 +// CData *data = content->OpenContentLC(EDisplay);
    1.47 +// // Don't need content object any more
    1.48 +// CleanupStack::PopAndDestroy(content);
    1.49 +// // get the size of the plaintext content
    1.50 +// data->DataSizeL(size);
    1.51 +// // Execute the intent, tell the agent that we plan to display the content
    1.52 +// // It is at this point that any stateful rights will be decremented
    1.53 +// data->ExecuteIntentL(EDisplay);
    1.54 +// // read and display the file until we reach the end of the file
    1.55 +// TBuf <128> buffer;		
    1.56 +// while(i < size)
    1.57 +// // read from the file
    1.58 +// User::LeaveIfError(data->Read(buffer));
    1.59 +// i += buffer.Length();
    1.60 +// // display on screen
    1.61 +// printf(buffer);
    1.62 +// // finished with Data object
    1.63 +// CleanupStack::PopAndDestroy(data);
    1.64 +// <hr>
    1.65 +// This example is the same as before except it attempts to obtain or wait for rights
    1.66 +// to become available rather than just leaving if access to the content is restricted.
    1.67 +// class CContentViewer : public CActive
    1.68 +// public:
    1.69 +// static CContentViewer* NewL();
    1.70 +// static CContentViewer* NewLC();
    1.71 +// // Display given content.
    1.72 +// void DisplayContent(const TDesC& aUri, TRequestStatus& aStatus)
    1.73 +// iUri = aUri;
    1.74 +// iClientStatus = &aStatus;
    1.75 +// iClientStatus = KRequestPending;
    1.76 +// iCurrentState = EOpenFile;
    1.77 +// // trigger our RunL
    1.78 +// iStatus = KRequestPending;
    1.79 +// SetActive();
    1.80 +// User::RequestComplete(iStatus, KErrNone);
    1.81 +// void RunL()
    1.82 +// TInt err = iStatus.Int();
    1.83 +// switch (iCurrentState)
    1.84 +// case EOpenFile:
    1.85 +// iContent = CContent::NewL(aUri);
    1.86 +// TRAP(err, iData = iContent->OpenContentL(EDisplay));
    1.87 +// iCurrentState = EReadAndDisplay;	// follow through...
    1.88 +// case EReadAndDisplay:
    1.89 +// if(err == KErrNone)
    1.90 +// TRAP(err, DisplayFile());
    1.91 +// iCurrentState = EFinished;
    1.92 +// // tell client iStatus that we have finished
    1.93 +// User::RequestComplete(*iClientStatus, err);
    1.94 +// return;
    1.95 +// else if(err == KErrCANoRights)
    1.96 +// // we don't have rights so we need to wait for them
    1.97 +// iCurrentState = EWaitingForRights;
    1.98 +// // ask CAF to initiate download of rights
    1.99 +// iContent->RequestRights(iStatus);
   1.100 +// else if(err == KErrCAPendingRights)
   1.101 +// // waiting for rights to arrive, expected any minute now
   1.102 +// iCurrentState = EWaitingForRights;
   1.103 +// // ask CAF to notify us when they arrive
   1.104 +// iContent->NotifyStatusChange(ERightsAvailable , iStatus);
   1.105 +// // wait for CAF to complete our request 
   1.106 +// iLastError = err;
   1.107 +// iStatus = KRequestPending;
   1.108 +// SetActive();
   1.109 +// break;
   1.110 +// case EWaitingForRights:
   1.111 +// if(ret == KErrNone)
   1.112 +// // change the state to try and display content again
   1.113 +// iCurrentState = EReadAndDisplay;
   1.114 +// // trigger our RunL
   1.115 +// iLastError = err;
   1.116 +// iStatus = KRequestPending;
   1.117 +// SetActive();
   1.118 +// User::RequestComplete(iStatus, KErrNone);
   1.119 +// else
   1.120 +// // couldn't get rights, tell parent active object we're finished
   1.121 +// User::RequestComplete(iClientStatus, err);
   1.122 +// return;
   1.123 +// break;
   1.124 +// protected:		
   1.125 +// void DoCancel()
   1.126 +// if (iLastError == KErrCAPendingRights)
   1.127 +// iContent->CancelNotifyStatusChange(iStatus);
   1.128 +// else if (iLastError == KErrCANoRights)
   1.129 +// iContent->CancelRequestRights(iStatus);
   1.130 +// private:
   1.131 +// CContentViewer() : CActive(EPriorityStandard)
   1.132 +// CActiveScheduler::Add(this); 
   1.133 +// ~CContentViewer() 
   1.134 +// Cancel();
   1.135 +// if (iData) delete iData; 
   1.136 +// if (iContent) delete iContent;
   1.137 +// // Display the content, if any error occurs then leave
   1.138 +// void DisplayContentL();
   1.139 +// TInt size = 0;
   1.140 +// TInt i = 0;
   1.141 +// TBuf <128> buffer;
   1.142 +// // Execute the intent, tell the agent that we plan to display the content
   1.143 +// // It is at this point that any stateful rights will be decremented
   1.144 +// iData->ExecuteIntentL(EDisplay);
   1.145 +// // get the size of the plaintext content
   1.146 +// iData->DataSizeL(size);
   1.147 +// // read and display the file until we reach the end of the file
   1.148 +// while(i < size)
   1.149 +// // read from the file
   1.150 +// User::LeaveIfError(iData->Read(buffer));
   1.151 +// i += buffer.Length();
   1.152 +// // Display on screen
   1.153 +// printf(buffer);
   1.154 +// private:
   1.155 +// enum TState
   1.156 +// EOpenFile = 0,
   1.157 +// EReadAndDisplay,
   1.158 +// EWaitingForRights,
   1.159 +// EFinished
   1.160 +// CContent*	iContent;
   1.161 +// CData* 		iData;
   1.162 +// TDesC		iUri;
   1.163 +// TState			iCurrentState;
   1.164 +// TInt 			iLastError;
   1.165 +// TRequestStatus*		iClientStatus;
   1.166 +// <hr>
   1.167 +// Some servers may wish to prevent access to DRM content by untrusted clients, even if
   1.168 +// the server itself has DRM capability.
   1.169 +// To achieve this the server should use the <code>ContentAccess::TIntent::EUnknown</code> intent when 
   1.170 +// accessing content. Content files that are not DRM protected will still work normally, but
   1.171 +// access to DRM protected content will be blocked.
   1.172 +// // Tell the agent we have no idea what the application plans to do
   1.173 +// CData *data = content->OpenContentL(EUnknown);
   1.174 +// // Execute the intent, tell the agent that we have no idea what the content will be used for
   1.175 +// data->ExecuteIntentL(EUnknown);
   1.176 +// <hr>
   1.177 +// When reading from a particular content object within a file the application must supply
   1.178 +// the \c UniqueId of the object when calling <code>ContentAccess::CContent::OpenContentL()</code>.
   1.179 +// void DisplayTextFileL(const TDesC& aUri)
   1.180 +// TInt size = 0;
   1.181 +// TInt i = 0;
   1.182 +// TBuf <128> buffer;
   1.183 +// // Create a CContent object
   1.184 +// // CAF will figure out the appropriate agent
   1.185 +// CContent *content = CContent::NewLC(aUri);
   1.186 +// // Find the objects in the file with MIME type image/jpeg
   1.187 +// RStreamablePtrArray<CEmbeddedObject> myArray;
   1.188 +// CleanupClosePushL(myArray);
   1.189 +// User::LeaveIfError(content->Search(myArray, _L("image/jpeg"), EFalse));
   1.190 +// // Get the virtual path of the first image/jpeg we find
   1.191 +// TVirtualPathPtr picture = *myArray[0];
   1.192 +// // Tell the agent to open the object with the given UniqueId
   1.193 +// CData *data = content->OpenContentLC(EDisplay, picture.UniqueId());
   1.194 +// // Don't need content object or array any more
   1.195 +// CleanupStack::PopAndDestroy(2);	// content, myArray
   1.196 +// // get the size of the plaintext content
   1.197 +// data->DataSizeL(size);
   1.198 +// // Execute the intent, tell the agent that we plan to display the content
   1.199 +// // It is at this point that any stateful rights will be decremented
   1.200 +// data->ExecuteIntentL(EDisplay);
   1.201 +// // read and display the file until we reach the end of the file
   1.202 +// while(i < size)
   1.203 +// // read from the file
   1.204 +// User::LeaveIfError(data->Read(buffer));
   1.205 +// i += buffer.Length();
   1.206 +// // display on screen
   1.207 +// printf(buffer);
   1.208 +// // finished with Data object
   1.209 +// CleanupStack::PopAndDestroy(data);
   1.210 +// <hr>
   1.211 +// This example shows how a messaging application that has just received
   1.212 +// a message attachment from a mail server can offer the attachment
   1.213 +// to CAF for processing. The output files will be saved in <code>C:\\files\\</code>.
   1.214 +// void CMyApp::ReceiveMessageAttachment(const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   1.215 +// // Create supplier object
   1.216 +// CSupplier* supplier = CSupplier::NewLC();
   1.217 +// // Tell the agent where we would like the output files to be written
   1.218 +// supplier->SetOutputDirectoryL(_L("C:\\files"));
   1.219 +// // Check if CAF can import this attachment we just received
   1.220 +// if(supplier->IsImportSupported(aContentType))
   1.221 +// ProcessAttachmentL(supplier, aContentType, aMessageAttachment);	
   1.222 +// else
   1.223 +// // just save the message to a file in its current form
   1.224 +// RFile theFile;
   1.225 +// theFile.Open(iFs, "myFile");
   1.226 +// theFile.Write(aMessageAttachment);
   1.227 +// theFile.Close();
   1.228 +// // Add the file to the list of attachments
   1.229 +// AddAttachment("myFile");
   1.230 +// void CMyApp::ProcessAttachmentL(CSupplier* aSupplier, const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   1.231 +// TInt err = KErrNone;
   1.232 +// TBuf <128> buf;
   1.233 +// // Create meta-data array
   1.234 +// CMetaDataArray* metaDataArray = new (ELeave) CMetaDataArray();
   1.235 +// CleanupStack::PushL(metaDataArray);
   1.236 +// // Add any useful information we can think of....
   1.237 +// // Obviously these would not be hardcoded this way in a real import
   1.238 +// metaDataArray->AddL(_L("Content Type"), _L("application/vnd.oma.drm.dm"));
   1.239 +// metaDataArray->AddL(_L("Content Length"), _L("1201"));
   1.240 +// metaDataArray->AddL(_L("X-Oma-Drm-Separate-Delivery"), _L("6"));
   1.241 +// // Create the import object
   1.242 +// CImportFile* import = aSupplier->ImportFileL(aContentType, *metaDataArray, _L("myfile"));
   1.243 +// CleanupStack::PushL(import);
   1.244 +// // import the attachment
   1.245 +// err = import->WriteData(aMessageText);
   1.246 +// // tell CAF (and hence the agent) it's now got the entire file
   1.247 +// if (err == KErrNone)
   1.248 +// err = import->WriteDataComplete();
   1.249 +// if (err == KErrNone)
   1.250 +// // Look at the output of the import operation
   1.251 +// for(TInt i = 0; i < import->OutputFileCountL(); i++)
   1.252 +// // for this example only add content output files
   1.253 +// // (absorb any rights in the original attachment 'silently')
   1.254 +// if(import->OutputFilesL(i).OutputType == EContent)
   1.255 +// // Add file to list of attachments for this message
   1.256 +// AddAttachment(import->OutputFilesL(i).FileName());
   1.257 +// // Error handling
   1.258 +// if (err != KErrNone)
   1.259 +// if (err == KErrNotReady)	
   1.260 +// DisplayErrorMsg("Agent not ready for import");
   1.261 +// else if (err == KErrCACorruptContent)
   1.262 +// DisplayErrorMsg("Content data is corrupt");
   1.263 +// else
   1.264 +// DisplayErrorMsg("Unexpected error: %d", err);
   1.265 +// // Finished
   1.266 +// CleanupStack::PopAndDestroy(2);		// metaDataArray, import
   1.267 +// <hr>
   1.268 +// This example shows how a messaging application that has just received
   1.269 +// a message attachment from a mail server can offer the attachment
   1.270 +// to CAF for processing and store the file in its own private directory.
   1.271 +// void CMyApp::ReceiveMessageAttachment(const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   1.272 +// // Create supplier object
   1.273 +// CSupplier* supplier = CSupplier::NewLC();
   1.274 +// // Check if CAF can import this attachment we just received
   1.275 +// if(supplier->IsImportSupported(aContentType))
   1.276 +// ProcessAttachmentL(supplier, aContentType, aMessageAttachment);	
   1.277 +// else
   1.278 +// // just save the message to a file in its current form
   1.279 +// RFile theFile;
   1.280 +// theFile.Open(iFs, "myFile");
   1.281 +// theFile.Write(aMessageAttachment);
   1.282 +// theFile.Close();
   1.283 +// // Add the file to the list of attachments
   1.284 +// AddAttachment("myFile");
   1.285 +// void CMyApp::ProcessAttachmentL(CSupplier* aSupplier, const TDesC8& aContentType, const TDesC8& aMessageAttachment)
   1.286 +// TInt err = KErrNone;
   1.287 +// TBuf <128> buf;
   1.288 +// TBuf <4> fileExtension;
   1.289 +// _LIT(KOutputFileName, "\\private\\12345678\\outputfile.");
   1.290 +// TFileName fileName(KOutputFileExtension);
   1.291 +// RFile file;
   1.292 +// // Create meta-data array
   1.293 +// CMetaDataArray* metaDataArray = CMetaDataArray::NewLC();
   1.294 +// // Add any useful information we can think of....
   1.295 +// // Obviously these would not be hardcoded this way in a real import
   1.296 +// metaDataArray->AddL(_L("Content Type"), _L("application/vnd.oma.drm.dm"));
   1.297 +// metaDataArray->AddL(_L("Content Length"), _L("1201"));
   1.298 +// metaDataArray->AddL(_L("X-Oma-Drm-Separate-Delivery"), _L("6"));
   1.299 +// // Create the import object, no suggested file name implies the application will supply output files
   1.300 +// CImportFile* import = aSupplier->ImportFileL(aContentType, *metaDataArray);
   1.301 +// CleanupStack::PushL(import);
   1.302 +// // Start importing the attachment
   1.303 +// // (if the agent needs one or more output files, continue looping until 
   1.304 +// // the agent finishes the previous)
   1.305 +// TInt err = import->WriteData(aMessageText);
   1.306 +// while(err == KErrCANewFileHandleRequired)
   1.307 +// import->GetSuggestedOutputFileExtension(fileExtension);
   1.308 +// filName.Append(fileExtension);
   1.309 +// User::LeaveIfError(file.Open(iFs, fileName));
   1.310 +// err = import->ContinueWithNewOutputFile(file);
   1.311 +// file.Close();
   1.312 +// if (err == KErrNone)
   1.313 +// // Complete the import process
   1.314 +// err = import->WriteDataComplete();
   1.315 +// while(err == KErrCANewFileHandleRequired)
   1.316 +// import->GetSuggestedOutputFileExtension(fileExtension);
   1.317 +// filName.Append(fileExtension);
   1.318 +// User::LeaveIfError(file.Open(iFs, fileName));
   1.319 +// err = import->ContinueWithNewOutputFile(file);
   1.320 +// file.Close();
   1.321 +// if (err == KErrNone)
   1.322 +// // Look at the output of the import operation
   1.323 +// for(TInt i = 0; i < import->OutputFileCountL(); i++)
   1.324 +// // for this example only add content output files
   1.325 +// // (absorb any rights in the original attachment 'silently')
   1.326 +// if(import->OutputFilesL(i).OutputType == EContent)
   1.327 +// // Add file to list of attachments for this message
   1.328 +// AddAttachment(import->OutputFilesL(i).FileName());
   1.329 +// // Error handling
   1.330 +// if (err != KErrNone)
   1.331 +// if (err == KErrNotReady)	
   1.332 +// DisplayErrorMsg("Agent not ready for import");
   1.333 +// else if (err == KErrCACorruptContent)
   1.334 +// DisplayErrorMsg("Content data is corrupt");
   1.335 +// else
   1.336 +// DisplayErrorMsg("Unexpected error: %d", err);
   1.337 +// // Finshed
   1.338 +// CleanupStack::PopAndDestroy(2);		// metaDataArray, import
   1.339 +// 
   1.340 +//
   1.341 +
   1.342 +/**
   1.343 + @page CAFExamples Example source code using CAF
   1.344 + - @ref ExampleRead1
   1.345 + - @ref ExampleReadWithErrCheck
   1.346 + - @ref PlayingUnprotectedOnly 
   1.347 + - @ref MultipleContentExample
   1.348 + - @ref ExampleSupplier1
   1.349 + - @ref ExampleSupplier2
   1.350 + @section ExampleRead1 Reading from a file, no error checking
   1.351 + @code
   1.352 + @endcode
   1.353 + @section ExampleReadWithErrCheck Reading from a file, with error checking
   1.354 + @code
   1.355 + @endcode
   1.356 + @section PlayingUnprotectedOnly Preventing access to DRM content
   1.357 + @code
   1.358 + @endcode
   1.359 + @section MultipleContentExample File containing several content objects
   1.360 + @code
   1.361 + @endcode
   1.362 + @section ExampleSupplier1 Importing a content file, agent provides output files
   1.363 + @code
   1.364 + @endcode
   1.365 + @section ExampleSupplier2 Importing a content file, application provides output files
   1.366 + @code
   1.367 + @endcode
   1.368 +*/