Interface Extensibility

Symbian^3 onwards, the plug-in framework supports interface extensibility. An extended interface extends the existing functionality of the original interface (instantiation interface). By extending interfaces, the framework developers need not change the existing interface specifications to support new requirements.

Framework developers who build the frameworks on top of the plug-in framework, define and publish extension interfaces to the existing interfaces used in the framework. Once an interface extension is published by the framework developer, the plug-in developers implement the extensions if required.

Introduction

By extending interfaces, the framework developers need not change their interface specifications to support new requirements.

Changing interface specifications is a complex activity in the below listed scenarios:

  • The framework developer is not the only supplier of plug-in implementation.

  • The framework also needs to support plug-ins implementing the original interface.

The interface extensions allows framework developers to publish discrete, identifiable extensions to the existing interface classes. The extension interfaces supported by each plug-in can be determined and used appropriately.

The images below illustrate how the interface extensibility feature works.

The class diagram shows the implementation of the original interface.

Figure 1. Class diagram of the original interface

The next class diagram shows an example of the original class CImplementationClass supporting two extensions . The extensions have been added to the CExampleInterface each using a different implementation methodology .

CExampleInterfaceExtended requires no data and so has been added to the inheritance of the original plug-in CImplementationClass object. MExampleInterfaceExtended2 shows how extensions can be realized in separate objects with their own data.

Figure 2. Class diagram of the extended interface

The extended interfaces should maintain the binary compatibility by not changing the original interface class definition. The functional compatibility should be maintained by incorporating interface extensions as optional. This allows the framework to function with original and extended plug-in implementations.

To accommodate interface extensibility, the following changes are applied to the plug-in framework.

  • A new resource file format to allow plug-in providers to register interface with extensions (Resource file format version 3).

  • A new targettype PLUGIN3.

  • New APIs accommodated in the framework to search for plug-ins supporting desired interface extensions.

  • A new proxy table for the plug-in implementations to export factory methods to instantiate the extended interface objects and a method to manually release the objects after use.

Accommodation of interface extensibility still allows the default resolvers and custom resolution of implementations.

Interface extensibility example

The code below shows the definition of an extended class:


class CExampleInterface : public CBase
{
public:
    virtual void DoMethodL() = 0;
};

// Extended Interface 0x10009E44

class MExampleInterfaceExtended
{
public:
    virtual void DoMethodExtended() = 0;
};

// Extended Interface 0x10009E45

class MExampleInterfaceExtended2
{
public:
    virtual void DoMethodExtended2() = 0;
};

The code below shows the instantiation of extended functions:

// the Instantiation Interface

const TUid KExampleInterfaceUid = {0x10009DBB}; 
const TUid KExtendedInterfaceUid1 = {0x10009E44};
const TUid KExtendedInterfaceUid2 = {0x10009E45};

// Set up extended interfaces UID list which form part of the resolution criteria.
RArray<TUid> extendedInterfaces;
CleanupClosePushL(extendedInterfaces);
extendedInterfaces.AppendL(KExtendedInterfaceUid1);
extendedInterfaces.AppendL(KExtendedInterfaceUid2);

// set up resolve parameter
_LIT8 (KExampleImplementationData,"Extended Interface Example");
TEComResolverParams ResolverParams;
ResolverParams.SetDataType(KExampleImplementationData());
ResolverParams.SetGenericMatch(ETrue);

TUid instanceKey;
CExampleInterface* instantiateIf = static_cast<CExampleInterface*>
(REComSession::CreateImplementationL(KExampleInterfaceUid,
                                       extendedInterfaces,
                                       instanceKey,
                                       ResolverParams) );
CleanupStack::PopAndDestroy(&extendedInterfaces);

CleanupStack::PushL(instantiateIf);

// May want to TRAP here if KErrNotSupported is handled, i.e. extension optional
MExampleInterfaceExtended2* ext2 = static_cast<MExampleInterfaceExtended2*>(
  REComSession::GetExtendedInterfaceL(instanceKey, KExtendedInterfaceUid2));

// access old interface function
instantiateIf->DoMethodL(); 

// access extension function 
ext2->DoMethodExtended2();