Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



Using the Feature Registry


Identifying optional features

Each optional or managed feature on Symbian OS is given a 32-bit unique identifier and represented by a TUid. The names of Symbian OS features and their UID assignments are defined in the featureUIDs.h header file. For example:

namespace NFeature
    {
    const TUid KFax = {0x10279806};         // Sample only! Refer to true
    const TUid KPrint = {0x10279807};       // featureUIDs.h header file for
    const TUid KBluetooth = {0x10279808};   // actual names and UIDs (plus
    const TUid KInfrared = {0x10279809};    // proper in-code documentation
    const TUid KMmc = {0x1027980a};         // about each feature).
    const TUid KUsb = {0x1027980b};
    // . . .
    }

These names or UIDs are the argument values for the Feature Registry query functions. The granularity of features is generally quite coarse. Seldom will a feature correspond to a single API method or aspect of its behaviour. Other approaches (beyond what is provided by the Feature Registry) are generally required to detect these minor variations. Strong guarantees of backward compatibility mean that existing functionality associated with a feature or identifier may not change or be removed where the feature is supported at all. Functionality can, however, grow in later releases.

It is recommended that licensees define their feature IDs in a similarly way i.e. in a file named UIxFeatureUIDs.h containing a namespace for their platform features.

[Top]


How to obtain a feature ID

A feature ID is a globally unique identifier (UID) consisting of a 32-bit number. The UID can be allocated on behalf of licensees and third parties from Symbian Signed. There are two steps in setting up a a Feature ID:

For new features designed to be optional, and introduced into Symbian OS from version 9.3 onwards, obtain a new UID from Symbian Signed.

To maintain forward compatibility, there is a small range of IDs that represent features that are considered to be supported on the platform by default. Such features are always present but may be removed. The feature IDs in this range are controlled by the System Design Authority group within Symbian.

The Feature and UID must then be defined in a number of ROM-build files and header files to complete the introduction of the managed feature. The procedure is managed by the handset vendors.

[Top]


Query API for users of optional features


Interface class and linkage

Feature queries are made using the RFeatureRegistry class declared in the header file featreg.h, supplied by featreg.dll and linked through featreg.lib.


Single feature queries

A single feature Query API is provided by class RFeatureRegistryNotify, declared in featreg.h, supplied by featreg.dll and linked through featreg.lib.

To inquire whether a single feature is supported on the device, use the following static function of class RFeatureRegistry:

static TInt QuerySupportS(TUid aFeatureUid);

This function returns a positive value if the feature is supported, zero if the feature is not supported, otherwise (in the exceptional case) a negative, system-wide error code if support cannot be determined.

You can choose to deal with the error returns locally. For example, by considering the feature not supported:

TBool haveUsb = RFeatureRegistry::QuerySupportS(NFeature::KUsb) > 0;

Alternatively you can choose to Leave on exceptional error returns:

TBool haveUsb =
              User::LeaveIfError(RFeatureRegistry::QuerySupportS(NFeature::KUsb)) > 0;

The Feature Registry maintains an additional 32-bit data word per feature, which can be obtained using an overload of the QuerySupportS function:

static TInt QuerySupportS(TUid aFeatureUid, TUint32& aInfo);

The contents of this extra word are reserved for future use.


Multiple feature queries

The most efficient way to find out if more than one function is supported is to open and query an instance of the RFeatureRegistry class using the following non-static methods of the RFeatureRegistry class:

inline RFeatureRegistry();
TInt Open();
TInt QuerySupport(TUid aFeatureUid);
TInt QuerySupport(TUid aFeatureUid, TUint32& aInfo);
void Close();

To query several features in a non-leaving context (and treating exceptional results as if the feature is not supported):

TBool iHaveUsb;
TBool iHaveBluetooth;
...
RFeatureRegistry featReg;
const TBool opened = (featReg.Open() == KErrNone);
iHaveUsb = opened && (featReg.QuerySupport(NFeature::KUsb) > 0);
iHaveBluetooth = opened && (featReg.QuerySupport(NFeature::KBluetooth) > 0);
// can always call Close(), even if Open() failed:
featReg.Close();

Or if choosing to Leave on exceptional returns:

RFeatureRegistry featReg;
User::LeaveIfError(featReg.Open());
CleanupClosePushL(featReg);               // don’t forget this
iHaveUsb = User::LeaveIfError(featReg.QuerySupport(NFeature::KUsb)) > 0;
iHaveBluetooth =
    User::LeaveIfError(featReg.QuerySupport(NFeature::KBluetooth)) > 0;
CleanupStack::PopAndDestroy(&featReg);    // this calls Close()

RFeatureRegistry also has an overload of non-static QuerySupport, which can return the extra word of data stored with each feature.

An important point about the above non-static APIs is that they only guarantee to return the state of features at the time Open() was called. To ensure that future run-time feature changes are detected, close the instance immediately after querying it, and re-open it next time queries are to be made. This also frees up resources held by the open instance.

Note: Querying features can have an impact on performance. Therefore, if you are querying frequently (for example, in a loop) it is recommended that you cache the query return. However, if the feature is seldom used (once or twice between switching the device on and off), caching is unnecessary.


Frequently asked questions

When should I query features?

When deciding when and how often to query, you must plan carefully as feature queries will result in a performance overhead. It is recommended that you always query and cache the return value if it is to be used many times in quick succession, particularly in loops. However, if the feature is seldom used (once or twice between switching the device on and off), caching is unnecessary.

Why do I get panic “FeatReg 1” when I call RFeatureRegistry functions?

This issue only occurs within Symbian and licensee organisations, and does not apply to external developers. This issue only happens in debug builds; in release builds, the error value KErrCorrupt is returned instead of a panic. “1” is the enumeration for EFeatRegBadConfig, declared in the exported header file featregpan.h.

The configuration file is missing or invalid

This is a serious problem. Your UI-provider or system integration team must ensure that the Feature Registry has a valid configuration file for the environment you are using, be it an emulator or a target device or reference board.

Why do RFeatureRegistry Open or Query methods return an error?

If the error KErrNoMemory is returned, this means there is insufficient memory to complete the query. If more memory becomes available subsequent queries may succeed.

If the error KErrCorrupt is returned, this is serious. Your UI-provider or system integration team must ensure that the Feature Registry has a valid configuration file for the environment you are using, be it an emulator or a target device or reference board. Refer to the Single feature queries and Multiple feature queries sections for example code on how to allow client programs to continue under such circumstances.

What happens if I attempt to use an unsupported feature?

Where optional features are removed from a device, all effort is made to make the failure of any attempt to use the missing features as graceful as possible. Unless individual features are documented to give particular, safe responses when not supported by a device (through a stub DLL, for example), their use as a means to discover the feature cannot be considered safe unless expressly documented as such. In addition, optional features supplied as plug-ins may be more efficiently detected using the Feature Registry. Finally, even if it works now, there is no guarantee that attempts to use a removed feature in future will not have serious consequences including exceptions, leaves or panics.

[Top]


Notification API for users of optional features


Interface class and linkage

A Notify API is provided by the RFeatureRegistryNotify class, declared in featreg.h, supplied by featreg.dll and linked through featreg.lib.


Subscribing for notification of feature changes

The RFeatureRegistryNotify class has the following member functions that allow you to subscribe for notification of changes in the Feature Registry:

inline RFeatureRegistryNotify();
TInt Open();
void Subscribe(TRequestStatus &aNotifyStatus);
void Cancel();
void Close();
    

To use the API requires an instance of the RFeatureRegistryNotify class to be Opened and Subscribed to. It will usually be employed in Active Objects in an Active Scheduler. At any time while the instance is open, call Cancel() to ensure the object is not subscribed for notification. If it previously was subscribed, the asynchronous Subscribe() request is completed with KErrCancel.

When a Subscribe() request completes successfully, will know that the Feature Registry has changed. You must re-query the features you are interested in, to determine whether the change affected affects you.

To ensure changes are not missed, always re-subscribe before querying the Feature Registry.

Note:

[Top]


Frequently asked questions


Who requires notification?

It is not expected that many clients will require run-time notification of feature changes. The vast majority of features are not removable, and most applications can be restarted if a feature needs to be rediscovered. This API is likely to be used by long-running system tasks that monitor a variety of features, and applications that use software that becomes supported or unsupported as add-on devices are attached and detached (that is, plug and play devices).


Can I just request notification of change in status of a particular feature?

No. Notification is for any change in the Feature Registry. The recipient must determine if the status of any feature they are interested in has changed.


Can notification occur (yet)?

No. The current implementation of Feature Registry is a constant ROM-based configuration file. The API is provided for forward compatibility. Applications can be written now anticipating run-time feature changes in a future implementation. Alternatively, applications can be written in the future once run-time updates do occur, and the API will be present – but will never notify – on older devices so there will be no compatibility issues.


Can I force notification for testing purposes?

This information only applies to Symbian and licensees. Yes, but it is a side-effect of the current implementation, is @internalComponent and not guaranteed to work into the future. Running featregsetup.exe (a binary included with the component) currently forces notification.