Changes

This is a new API.

Purpose

The HS External Rendering Plug-in API is a domain API that allows the widget developer to create an own rendering plug-in by inheriting the provided ECom base class. The custom rendering plug-in can be taken into use by referring the plug-in name from the widget's XML declaration. The API is meant for the advanced widget development when the default rendering plug-ins do not provide sufficient functionality.

S60 or Symbian OS exceptions

This API is valid for all platforms running on S60 release 5.2 or later.

Emulator support

This API is fully supported in the WINSCW emulator environment.

API description

Home screen provides a drawing rectangle where the plug-in can draw anything using system drawing functions. The plug-in is a normal CCoeControl and thus it must follow all the existing conventions. In addition, the API introduces new Home screen specific functionality, which can be implemented if appropriate. The most important addition is the Power Save mode, which has to be obeyed by every plug-in. All the activity, such as outstanding requests, timer and animations must be canceled in the Power Save mode in order to maximize the device stand by time.

The HS External Rendering Plug-in API is a framework API. The deriving class must be an ECom plug-in so that Home screen can dynamically load the DLL when needed. ECom plug-in loading is implemented in the base class. The deriving class must provide the ECom implementation information.

The rendering plug-in must not act as data source. It should not connect to any server nor fetch data from any source. A flexible interface is provided so that data can be given to the rendering plug-in. The plug-in stores only the data, which is drawn or about to be drawn to the screen. It does not handle the user actions for the data, for example launch external application after the user selects an item. All the events are forwarded to a specific component, which is typically implemented at the same time with the rendering plug-in.

Use cases

The purpose of the API is to enable widget developers to implement widgets with advanced graphical features. In many cases the functionality provided by the default rendering plug-ins is not enough.

API class structure


In the above diagram, MyRenderingPlugin is derived from the External Rendering Plug-in API, which in turn is derived from CCoeControl. Derived class can implement the virtual functions from the base class if appropriate. Typically, the publisher plug-in is implemented at the same time with the rendering plug-in and a data protocol has been agreed between those. Publisher uses the Publish methods from the MAiContentObserver interface to deliver the data to the rendering side. Content observer is passed to the publisher plug-in by calling the Subscribe method. The XMLUiRendering component provides also a reference to data event handler by calling the SetEventHandler method after the construction phase. The rendering plug-in must store the reference and deliver the user-initiated actions to the publisher plug-in with the agreed event handling protocol.

Related APIs
  • CCoeControl
  • MAiContentObserver
  • MyRenderingPlugin
  • SetEventHandler
  • XMLUiRendering
Related APIs
  • CCoeControl

Using the External Rendering Plug-in API

Functions that need to be implemented

// External rendering plug-in mandatory functions
T_RenderingPlugin* T_RenderingPlugin::NewL()  
      {  
      T_RenderingPlugin* self = T_RenderingPlugin::NewLC();  
      CleanupStack::Pop( self );  
      return self;  
      }  
  //  
  T_RenderingPlugin* T_RenderingPlugin::NewLC()  
      {  
      T_RenderingPlugin* self = new( ELeave ) T_RenderingPlugin();  
      CleanupStack::PushL( self );  
      self->ConstructL();  
      return self;  
      }  
  //  
  T_RenderingPlugin::~T_RenderingPlugin()  
      {  
      }  
 //  
  T_RenderingPlugin::T_RenderingPlugin()  
      {  
      // Do nothing  
      }  
  //  
  void T_RenderingPlugin::ConstructL()  
      {  
      }  
  //  
  const TImplementationProxy KImplementationTable[] =  
     {  
  #ifdef __EABI__  
      IMPLEMENTATION_PROXY_ENTRY( 0x22334455, T_RenderingPlugin::NewL ) 
  #else  
      { { 0x22334455 }, T_RenderingPlugin::NewL }  
  #endif  
     };  
  //  
  EXPORT_C const TImplementationProxy* ImplementationGroupProxy(  
      TInt& aTableCount )  
      {  
      aTableCount = sizeof( KImplementationTable ) / sizeof( TImplementationProxy );  
      return KImplementationTable;  
      }

ECom resource

RESOURCE REGISTRY_INFO theInfo
{
dll_uid = RENDERING_PLUGIN_UID;
interfaces =
    {
    INTERFACE_INFO
        {
        interface_uid = 0x200286DF; // External rendering plugin interface uid

        implementations =
            {
            IMPLEMENTATION_INFO
                {
                implementation_uid = RENDERING_PLUGIN_IMPLEMENTATION_UID;
                version_no = 1;
                display_name = "My Renderer";
                default_data = "myrenderer"; // matches with XML element name
                opaque_data = "";
                }
            };
        }
    };
}

Declaration in widget


Data Interface

The SetDataL method is very flexible. The idea is that data is delivered as an 8 bit descriptor stream from the publisher and internalized into class structure in the rendering side. Because the publisher and renderer run in the same process, it is enough to package the pointer with the TPckgC class.MAiContentObserver provides a PublishPtr method, which packages the pointer and delivers the data to the rendering side.

// Publisher
::PublishL(...)
    {
    ...
    CPublishItem* pItem = new CPublishItem;
    aObserver.PublishPtr( *this, aContent, pItem, aIndex );
    ...
    }

//Renderer
::SetDataL( const TDesC8& aData, const TDesC& aType, TInt aIndex )
    {
    CPublishItem* pitem( UnpackPtr<CPublishItem>( aData ) );
    ...
    }

// Unpacking helper
template< class PtrT > inline PtrT* UnpackPtr( 
    const TDesC8& aBuf )
    {
    TAny* result( NULL );
    
    if ( aBuf.Size() == sizeof( TAny* ) )
        {
        // Effectively writes aBuf contents to result
        TPckg< TAny* >( result ).Copy( aBuf ); 
        }        
    return static_cast< PtrT* >( result );
    }
Related APIs
  • MAiContentObserver
  • PublishPtr
  • SetDataL
  • TPckgC

Event Handling

Rendering plug-in does not handle the user events, which require launching of an external application. Instead, MXnExtEventHandler::HandleEventL is used to deliver the event to the publisher. The publisher is able to interpret the aEvent because of the agreed event protocol.

// Destination matches with contentsource id
iEventHandler->HandleEventL( _L8(LaunchItem(1), _L8("MyPublisher"));
Related APIs
  • MXnExtEventHandler::HandleEventL
  • aEvent

Error handling

There are no methods in the API that return an error code. This API uses only standard Symbian OS leave codes.

Memory overhead

Base class hardly reserves any memory and, therefore, memory overhead depends on the plug-in implementation. The rendering plug-in is always loaded in the memory when it is added into any Home screen page. If the plug-in is heavy in RAM-wise (consumes a lot of RAM), then it is advisable to free memory when CXnExtRenderingPluginAdapter::EnterPowerSaveModeL() is called.

Related APIs
  • CXnExtRenderingPluginAdapter::EnterPowerSaveModeL()

Extensions to the API

External Rendering plug-in can be self-sufficient, but it is recommended that a data publishing plug-in is implemented at the same time or the existing publishing plug-in is used. The CXnExtRenderingPluginAdapter::SetDataL() method is used to deliver data to the rendering side.

The MXnEventHandler extension is used to deliver user-initiated events to the publisher plug-in, which in turn handles the events, for example launches the appropriate application.

Related APIs
  • CXnExtRenderingPluginAdapter::SetDataL()
  • MXnEventHandler

Limitations of the API

There are no limitations in the API.