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 +*/