Profiles Engine Wrapper API: Using the Profiles Engine Wrapper API

Initialization

When using Profiles Engine Wrapper API, the first step is to create the engine by using ProEngFactory::NewEngineLC. It should be noted, that for all operations that modifies Profiles data, the client process must have WriteDeviceData capability. For reading Profiles data, no capabilities are needed.

Below is an example of the initialization process of the Profiles Engine Wrapper API.

// Create an engine instance:
MProEngEngine* engine = ProEngFactory::NewEngineLC();

Getting the Active Profile ID

After the engine has been created, the ID of the active profile can be got (Use case 1.) like below.

// Get the ID of the active profile
TInt activeId( engine->ActiveProfileId() );

Setting the Active Profile ID

Changing the active profile (Use case 2.) can be done as in the code snippet below.

// Change the active profile to Off-line
engine->SetActiveProfileL( KProfileOfflineId );

Accessing the Settings of a Profile

The class MProEngEngine offers methods to get the settings of any profile. MProEngEngine::ActiveProfileLC() returns the settings of the profile which is active by the time of the method call. MProEngEngine::ProfileLC( TInt aId ) returns the settings of the profile with the ID aId. Both of those methods have also versions that don’t leave pointers to the cleanup stack.

The settings returned by MProEngEngine are contained in an object of a class implementing the MProEngProfile interface. This interface offers methods to get and set the so called “Alert For” groups for the profile. “Alert For” groups are Contact groups for which an audible alert should be played if a call comes in from a person who belongs in such a group in the contacts database. If no groups are set in a profile, it means that all the calls must be alerted according to the settings of the profile. MProEngProfile interface contains also a method for checking the silent status of the profile. This service is needed for example by the component updating the silent indicator in the navi pane. Other settings of the profile can be got by using MProEngProfileName, MProEngTones and MProEngToneSettings interfaces. The references to these interfaces are acquired from the MProEngProfile interface.

After the client has updated the desired settings of a profile, the changes has to be committed in by using the method MProEngProfile::CommitChangeL(). This method does the actual committing of the changes in the Profiles data repository.

Below is an example code snippet which reads and modifies some the settings (Use cases 3. and 4.) of the current active profile.

// Get the settings of the active profile:
MProEngProfile* activeProfile = engine->ActiveProfileLC();
MProEngToneSettings& ts = activeProfile->ToneSettings();
TBool ringingType( ts.RingingType() );
TProfileRingingVolume volume( ts.RingingVolume() );
// Make sure that the vibrating alert is enabled, if the ringing type
// or volume is such that I might not hear the alert:
if( ( ringingType == EProfileRingingTypeSilent ) ||
    ( ringingType == EProfileRingingTypeBeepOnce ) ||
    ( ringingVolume < EProfileRingingVolumeLevel3 ) )
    {
    ts.SetVibratingAlert( ETrue );
    }
// Commit the change in Profiles Data:
activeProfile->CommitChangeL();
// Release the resources used:
CleanupStack::PopAndDestroy(2); // activeProfile,engine

Getting the Profile Name Array

The names and the IDs of all the profiles can be received in a form of MProEngProfileNameArray by calling MProEngEngine::ProfileNameArrayLC(). Below is an example code snippet for this use case (Use case 5.).

// Get the list of existing profiles:
MProEngProfileNameArray* profileNames( engine->ProfileNameArrayLC() );

Receiving Change Notifications

Notifications about changes in the Profiles data can be received by implementing the appropriate Observer interface and by using MProEngNotifyHandler interface. A Notify Handler can be created with the factory method ProEngFactory::NewNotifyHandlerL().

There are 4 Observer interfaces that the client can implement. The interface to be implemented depends on the type of changes that the client is interested in. All the observer interfaces follows the same pattern; they have one method for handling the notification and one for handling errors. In addition for implementing the appropriate interface, client must also register for the corresponding type of notifications through MProEngNotifyHandler. When the client does not need notifications anymore it should cancel them through the Notification Handler. There are cancellation methods for each type of the notifications and also one method which cancels all the notifications previously requested from the particular Notification Handler instance.

The notifications about profile changes (in other words, about the event when someone has called SetActiveProfileL() from Profiles Engine) is received through the MProEngProfileActivationObserver interface. The registration for these notifications is done by calling MProEngNotifyHandler:: RequestProfileActivationNotificationsL( MProEngProfileActivationObserver& aObserver ).

The notifications about the active profile modifications (in other words, a setting in the current active profile is modified) is received through the MProEngActiveProfileObserver interface. A client that needs these notifications will probably need also the profile activation notifications. However the interfaces are separated because a client needing activation notifications is not necessarily interested in the active profile modification notifications.

The notifications about the changes that relates to the contents of a Profile Name Array can be received through the MProEngProfileNameArrayObserver interface. The events that trigger these notifications comprise a profile has been created, a profile has been deleted and the name of a profile has been changed.

The notifications about the modifications of a specific profile can be received through the MProEngProfileObserver interface. These notifications are tied to the certain profile which ID is given as a parameter in the registration method. Note however, that the notifications are sent only about the modifications of the settings in the given profile. So the activation notification should be received via MProEngProfileActivationObserver though.

The standard protocol for notification handler usage is:

  1. Create instances of MProEngEngine, MProEngNotifyHandler and the observer implemented by the client

  2. Register for the notifications through MProEngNotifyHandler giving a reference to the client-implemented observer as a parameter

  3. Read the Profiles data of interest by using MProEngEngine

  4. Everytime a notification is received re-read the Profiles data of interest by using MProEngEngine.

The last item in the list above is important. The data does not get updated automatically to the MProEngProfile or MProEngProfileNameArray objects once created by the client. It must always be re-read by recreating the object in question through MProEngEngine after the notification is received.

It should also be taken into account when using the notification handler that only one observer of each type can be attached to one notification handler instance. The only exception is MProEngProfileObserver, the instances of which there can be registered as many as there are profiles in the device (this means: there can be one MProEngProfileObserver per profile registered through the same Notification Handler instance).

Below is an example code of getting notifications of changes (Use case 6.) that have influence on name array contents.

// From CMyProfileNameArrayObserver.h:
class CMyProfileNameArrayObserver :
public CBase, 
public MProEngProfileNameArrayObserver
{
    .
    .
    .
    public:  /// from MProEngProfileNameArrayObserver
        void HandleProfileNameArrayModificationL();
        void HandleProfileNameArrayNotificationError(TInt aError);
    .
    .
    .
    private:  /// data
        MProEngProfileEngine* iEngine;
        MProEngNotifyHandler* iNotifyHandler;
        MProEngProfileNameArray* iProfileNames;
};
// From CMyProfileNameArrayObserver.cpp:
void CMyProfileNameArrayObserver::ConstructL()
    {
    iEngine = ProEngFactory::NewEngineL();
    iNotifyHandler = ProEngFactory::NewNotifyHandlerL();
    User::LeaveIfError( iNotifyHandler->
        RequestProfileNameArrayNotificationsL( *this ));
    iProfileNames = iEngine->ProfileNameArrayLC();
    CleanupStack::Pop(); // iProfileNames
    }
void CMyProfileNameArrayObserver::HandleProfileNameArrayModificationL()
    {
    // Name array data changed, re-read the name array:
    MProEngProfileNameArray* tmpNames = iEngine->ProfileNameArrayLC();
    // Succeeded to read new names, delete the old array object:
    delete iProfileNames;
    iProfileNames = tmpNames;
    CleanupStack::Pop(); // tmpNames
    }
void CMyProfileNameArrayObserver::HandleProfileNameArrayNotificationError(TInt     aError)
    {
    // Error handling here
    }

Getting the List of the Alert Tone Candidates

There is one service more offered by Profiles Engine Wrapper API, it can be used for searching the device (and the memory card) for files that are suitable to be set as alert tones. This service is provided by MProEngAlertToneSeeker interface, which has two methods. FetchAlertToneListL(MProEngAlertToneSeekerObserver& aObserver) is used for starting the asynchronous search operation. This operation may take really long time depending on the amount of tones in the device. The operation can be cancelled by calling CancelFetch(). To use the service, client has to implement the MProEngAlertToneSeekerObserver interface. This interface contains a method for receiving a notification when the search has completed. The array of the path names of the tones is delivered as a parameter in this method to the caller. The ownership of the array is also transferred to the client. The other method in this interface is for error handling. The code snippet below shows an example usage of Alert Tone Seeker (Use case 7.).

// Client-implemented observer for getting the list of tone files:
class CClientImplementedAlertToneSeekerObserver :
public CBase, 
public MProEngAlertToneSeekerObserver
{
    .
    .
    .
    public:  /// from MProEngAlertToneSeekerObserver
        void HandleAlertToneListCompletedL(MDesCArray* aToneList);
        void HandleError(TInt aError);
    .
    .
    .
    private:  /// data
        .
        .
        .
        MProEngAlertToneSeeker* iSeeker;
        MDesCArray* iToneList;
};
// :
void CClientImplementedAlertToneSeekerObserver::ConstructL()
   {
   .
   .
   .
    iSeeker = ProEngFactory::NewAlertToneSeekerL();
    // start the asynchronous fetch operation
    iSeeker->FetchAlertToneListL( *this );
    }
// Alert tone fetch has completed:
void 
CClientImplementedAlertToneSeekerObserver::HandleAlertToneListCompletedL(
MDesCArray* aToneList)
    {
    iToneList = aToneList;
    // Use the tone list here, for example delegate it to a list box etc.
    }
// An error occurred during fetch operation or in the client-implemented handler
// method above:
void 
CClientImplementedAlertToneSeekerObserver::HandleError( TInt aError )
    {
    // handle errors here
    .
    .
    .
    }

Releasing the Resources

Releasing the resources used by MProEngEngine is done with Release() method. Below is an example code snippet of the usage.

// Release the resources:
if( iProfileEngine )
    {
    iProfileEngine->Release();
    } 

Error handling

Profiles Engine Wrapper API uses standard Symbian error reporting mechanism. It does not define any panic codes of its own, since all the data received from the client is delivered in object references instead of pointers. Leaves and system wide error codes as function return values are used if the error is recoverable. A client application can handle these errors similarly as a normal Symbian platform application.

Memory overhead

Memory consumption of Profiles Engine Wrapper API is directly proportional to the number of profiles read by the client (if the client does not destroy them in between). Also if there are huge amount of alert tones in the device then the list returned by MProEngAlertToneSeeker may take a lot of memory.

Limitations of the API

This API cannot be used by a server component which needs to set a DRM-protected tone as an alert tone. This is because the DRM library used by this API launches some UI notes that are not global. Launching a non-global UI note in a server process will result in a panic.


Copyright © Nokia Corporation 2001-2008
Back to top