Essential ECom Monday, October 12, 2009

TOPIC:
1. overview of ECom framework
2.  key functions of ECom framework
3. plug-in files
4. extend a exsiting interface


ECom is the abbreviation of Echo Component Object Model. The main idea is that you can change or update the implementation of an interface independent of the main application. It meets the software development principle: Program to an interface, NOT an implementation. In fact, ECom is typical a plug-in system. If you have mastered COM on Windows OS, it’s observable that ECom is different from COM. The purpose of COM is across various platforms and networks, so it has some special items, for example, IDL and apartment etc. ECom is not ‘reduced’ COM, ECom is just ECom.
Here all description is based on PLUGIN3

1.     Overview

The UML diagram below is from Symbian SDK. If you understanded the technology about plug-in, pls skip this chapter.




There are four clearly-defined roles in such a system.
1.         The client that wishes to instantiate the processing unit.
2.         The interface API that provides the known general functionality via a generalized set of processing tasks, whose details are determined at run-time.
3.         The instantiation mechanism or framework.
4.         The interface implementation that provides the correct processing.

From the point of view of client, a interface is a set of actions and these actions have a well-defined boundary i.e. a interface extracts some common features and these features are enough to fulfill the function required by client. After a interface is released, from the view of client it’s never changed. So a interface is not only a restriction on semantics but also a restriction on the binary structure. Chapter4 will explain how to extend a existing interface but not to destroy the binary structure of interface.

2.     Key functions of ECom framework

ECom framework is the core to provide the correct implementation of interface which the client required at run-time. Its key functions involve:
1.       To register interface implementations with ECom framework via scanning drivers. (The registry information is defined in a rss file)
2.       To keep the registry information of all plug-ins in the form of tree, which are used to resolve implementation
3.       To search and resolve the correct implementation of interface that client’s requiring.
4.       To load and unload plug-in
5.       To instance the correct implementation
ECom framework is a typical client-server architecture. Item 1~Item 3 above runs on server side. Other items run on client side. They interact with each other via REComSession.

3.     Plug-in files

Two files, plug-in dll and rsc file will be delivered after you create a plug-in. I illustrate both files in bellowing picture.



The rsc file is a registration detail file for plug-in dll type, which ECom framework utilizes to registry your plug-in to help client to search and resolve the correct interface implementation. RegistryInfo.rh, RegistryInfov2.rh and ResistryInfov3.rh define the detailed structures. Here’s a impartment notice that the source file name(the rss file name) must match the 3rd UID of dll file. On PLUGIN3, rsc file name need not match the 3rd UID, but it must match the dll file name.
Dll plug-in file provides one or more interface implementations and one proxy table. The proxy table looks like
const TImplementationProxy ImplementationTable[] =
            {
                           IMPLEMENTATION_PROXY_ENTRY(0x2000F5F4,                CImplementationClassOne::NewL),
                           IMPLEMENTATION_PROXY_ENTRY(0x20011F39, CImplementationClassTwo::NewL),
                           IMPLEMENTATION_PROXY_ENTRY(0x20011F42, CExampleResolver::NewL)
            };

EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
            {
            aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
            return ImplementationTable;
            }
It’s responsible to instance the correct implementation. A interface can be implemented by more than one implementation. And how to get the ‘correct’ interface implementation? When client wishes a interface implementation, it must provide some ‘cue’, which is some description information, then ECom framework will search and resolve a ‘correct’ implementation for client. It’s ‘correct’ because it’s the most suited one.

4.     Extend a existing interface

Assumed there is a interface CAudioPlay and the interface has been delivered.
class CAudioPlay:public CBase
{
public:
            CAudioPlay();
            virtual ~CAudioPlay();
public:
            virtual void Play() = 0;
            virtual void Stop() = 0;
};
Now a new requirement comes, a new function, void FastForword() need be inserted. If you add it into the existing interface, the integrality of binary structure of interface will be destroyed. When a client which called the function FastFowrod meets the older plug-in, which does not define this function, the client will crash. So it’s the best way to define another interface to extend the existing interface.
On PLUGIN3, there’s a extended interface mechanism. The bellowing session is from RegistryInfov3.rh.
STRUCT IMPLEMENTATION_INFO
            {
            ...
            LONG                                   extended_interfaces[];
           
            }
There are the UIDs of extended interface in the array, extended_interfaces. You can define maximum 8 extended interfaces.
For this example, you can do as bellowing. Here a extended interface is defined.
extended_interfaces = { 0x20009E4F };
Now we define the extended interface.
class MAudioPlayExtend
{
public:
            virtual void FastForword() = 0;
};
The implementation class looks like
class CImplementationClassOne: public CAudioPlay, public MAudioPlayExtend
{
...
// from CAudioPlay
public:
            virtual void Play();
            virtual void Stop();
// from MAudioPlayExtend
public:
            virtual void FastForword();
...
// to support extended interface
public:
            static TAny* GetExtendedInterfaceL(TAny* aObject,const TUid& aExtendedInterface,TUint32& aBitFlags,TAny*& releaseObject);
            static void ReleaseExtendedInterface(TAny* aObject,const TUid& aInterface);
}
The proxy table will be modified to support the extended interface as bellowing. Pay attention on the bold line.
const TImplementationProxy ImplementationTable[] =
            {
                           IMPLEMENTATION_PROXY_ENTRY3(0x2000F5F4,            CImplementationClassOne::NewL, CImplementationClassOne::GetExtendedInterfaceL,CImplementationClassOne::ReleaseExtendedInterface),
                           IMPLEMENTATION_PROXY_ENTRY(0x20011F39, CImplementationClassTwo::NewL),
                           IMPLEMENTATION_PROXY_ENTRY(0x20011F42, CExampleResolver::NewL)
            };

EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
            {
            aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
            return ImplementationTable;
            }

0 comments: