Location Settings API

The Location Settings API allows an application to get and set the properties of a PSY.

Purpose

The Location Settings API is an interface for managing the settings of the Location Framework and of Positioning Plug-ins (PSYs). The settings consist of the relative priorities of PSYs installed on the mobile device and modifiable and read-only attributes of PSYs.

API description

This API is intended for use by a system application (such as a settings UI) that allows the user of a phone to view and edit settings that affect the behaviour of the Location Framework. The API allows a user to manage the priority ordering of PSYs and to access their modifiable and non-modifiable attributes

The priority ordering of PSYs is used when a client of the Location Acquisition API uses the RPositioner class without specifying particular positioning module ID (by calling RPositioner::Open() without parameters). The Location Server uses the PSY with the highest priority if possible and falls back to next one in the priority list in case of failure.

PSY attributes

PSY attributes can be grouped by type:

Non-modifiable attributes

These properties include a descriptive name, UID, positioning plug-in version, positioning technology, capabilities, time to first fix, positioning accuracy, power consumption etc.

For more information about non-modifiable attributes see Positioning Plug-in Information API.

Non-modifiable attributes are read from each PSY's repository file,. The PSY name is read from a resource file, which should be referenced by the repository file. If the resource file is not referenced in the repository file then the PSY name is taken from ECOM attributes of the PSY plug-in (which means that the name cannot be localized).

Modifiable attributes

These attributes include the availability status of the PSY (enabled or disabled), the cost of using the PSY and its visibility.

Modifiable attributes are stored in the Central Repository.

Table 1 describes the modifiable PSY attributes:

Attribute Description

Cost

User-defined runtime setting for the cost of using a specific positioning technology. Possible values are defined by TPositionQuality::TCostIndicator from Location Acquisition API.

The cost attribute is modifiable because in some cases the cost of using a PSY can be dependent on the user’s subscription model.

Availability

Determines whether a PSY is enabled to be used through Location Acquisition API (RPositioner) or not.

Visibility

Determines whether a PSY needs to be listed by the CPosModules class of this API.

Table 1. Modifiable PSY attributes.

Positioning plug-in specific settings

Each PSY can have any number of attributes that are specific for the positioning technology it encapsulates (for example, baud rate for external GPS). The Location Settings API does not provide access to these settings.

API summary

Figure 1 shows public classes of the Location Settings API.

Figure 1. Figure 1. Location Settings API class diagram

Table 1 lists the classes and types of the API.

Class Name Description Header file

CPosModules

The main class of the Location Settings API. It is used for accessing PSY attributes and managing priority list of PSYs. A client can also register to listen for changes in the settings.

EPos_CPosModuleIdList.h

CPosModuleUpdate

Represents an update of the modifiable attributes of a PSY. An update is committed by calling CPosModules::UpdateModuleL().

EPos_CPosModuleUpdate.h

CPosModuleIdList

Represents a list of PSY IDs. Used to get and set the priority list of PSYs. It contains methods for appending, inserting, removing and finding PSY IDs in the list.

EPos_CPosModuleIdList.h

MPosModulesObserver

The interface that is implemented by clients in order to receive notifications of changes in the PSY settings. A client subscribes for notifications through the CPosModules class.

Notification event information is given in a TPosModulesEvent structure.

Typedef TPosModulesEventType defines possible event types.

EPos_MPosModulesObserver.h

Table 1. Classes and types of the Location Settings API.

Libraries

API classes are packaged in eposmodset.dll. Clients link with eposmodset.lib.

Capabilities

API clients require WriteDeviceData capability to update modifiable settings (PSY priority order, modifiable PSY attributes).

API clients require no capabilities to read PSY settings.

Using the API

Uses cases for the API are:

Retrieving information about installed PSYs

A client can read ordered list of PSYs by using CPosModules::ModuleIdListL() or CPosModules::ModuleIdListLC(). These methods return a list of IDs for the currently installed PSYs in priority order. Only the PSYs which have visibility attribute set to 1 (ETrue) are listed.

The client may request information from a specific PSY by providing its ID to CPosModules::GetModuleInfoL(). If a PSY with the specified ID is found in the system, its data is returned in the TPositionModuleInfoBase derived object, supplied by client. Currently, the only supported subclass is TPositionModuleInfo. For more information, see Location Acquisition API.

Figure 2 shows the client listing all available PSYs and retrieving their attributes:

Figure 2. Figure 2. Retrieving PSY information

The following example shows the client getting list of names of enabled plug-ins:

void ListEnabledPluginsL( CDesCArray& aNames )
{
// Open the storage
CPosModules* db = CPosModules::OpenL();
CleanupStack::PushL( db );

// List entries
CPosModuleIdList* idList = db->ModuleIdListLC();

// Get the display name and status of each installed positioning plug-in
for (TInt I = 0; I < idList->Count(); I++)
    {
    // get PSY info
    TPositionModuleInfo moduleInfo;
    db->GetModuleInfoL( (*idList)[I], moduleInfo );

    if ( moduleInfo.IsAvailable() )
        {
        // read PSY’s name
        TBuf<KPositionMaxModuleName> moduleName;
        moduleInfo.GetModuleName( moduleName );
        aNames.AppendL( moduleName );
        }
    }

CleanupStack::PopAndDestroy( idList );
CleanupStack::PopAndDestroy( db );
}

Modifying PSY attributes

In order to modify PSY attributes, the client sets values in a CPosModuleUpdate object and sends it to CPosModules::UpdateModuleL(). The CPosModuleUpdate class allows a client to change the cost, availability, and visibility attributes of a PSY.

Figure 3 shows the steps to change the modifiable attributes of PSY.

Figure 3. Figure 3. Modifying PSY attributes

PSY visibility and availability

The visibility attribute only defines whether a PSY is listed when a client asks for a list of all available PSYs. Turning this attribute off for a specific PSY does not prevents client applications (which know its module ID) from using this PSY through Location Acquisition API. The client can still specify PSY’s module ID as a parameter for RPositioner::Open() and connection to that PSY is granted.

The availability attribute defines if a PSY is totally hidden from the system and its use through the Location Acquisition API is disabled.

The following code example shows how to hide the PSY from the PSY list and prevent its use:

// Open the storage
CPosModules* db = CPosModules::OpenL();
CleanupStack::PushL( db );

// Assuming the positioning plug-in UID is known
const TPositionModuleId id = {0x12345678};

// Disable the PSY and hide it from the list
CPosModuleUpdate* updateParams = CPosModuleUpdate::NewLC();
updateParams->SetUpdateAvailability( EFalse );
updateParams->SetUpdateVisibility( EFalse );

// Commit changes
db->UpdateModuleL( id, *updateParams );

CleanupStack::PopAndDestroy( updateParams );
CleanupStack::PopAndDestroy( db );

Changing the priority order of PSYs

The client application can retrieve and change the priority order of installed PSYs using methods from the CPosModules class. The priority of a single PSY is retrieved using CPosModules::PriorityL(). The whole priority list is returned by CPosModules::ModuleIdListL().

There are several methods to change positioning plug-in priorities:

The following example code demonstrates how a client can upgrade a PSY to the highest priority.

void MakePluginTopmostPriorityL( TPositionModuleId aModuleId )
{
// Open the storage
CPosModules* db = CPosModules::OpenL();
CleanupStack::PushL( db );

const TInt KTopMostPriority = 0;
db->SetModulePriorityL( aModuleId, KTopMostPriority );

CleanupStack::PopAndDestroy( updateParams );
CleanupStack::PopAndDestroy( db );
}

CPosModules::SetModulePrioritiesL() allows a client to set the order of all PSYs immediately by supplying a list of plug-in IDs in the required order. Note that all the visible plug-ins must be declared in the supplied list: it is required that the list contains the same set of PSY IDs as it would be returned by CPosModules::ModuleIdListL().

Note: Invisible PSYs are not ordered, i.e. they do not have any priority. When an invisible PSY is made visible, it will be assigned a priority according to its preference (defined in Positioning Plug-In Information API) and an internal sorting algorithm of the Location Framework.

The following example shows how the client could move a PSY to the first place in priority order by specifying a whole new priority list:

void MakePluginTopmostPriority2L( TPositionModuleId aModuleId )
{
// Open the storage
CPosModules* db = CPosModules::OpenL();
CleanupStack::PushL( db );

// Get current list first
CPosModuleIdList* idList = db->ModuleIdListLC();
TInt currentPriority = idList->Find( aModuleId );
idList->MoveL( currentPriority, 0 );

// Save new order
db->SetModulePrioritiesL( *idList );

CleanupStack::PopAndDestroy( idList );
CleanupStack::PopAndDestroy( db );
}

Listening to settings change events

A client can register an observer to listen for changes in the location settings. The observer is notified when any change occurs. The observer is set by calling CPosModules::SetObserverL(). The observer must implement the MPosModulesObserver interface to receive settings change notifications. The observer can be removed by calling CPosModules::RemoveObserver().

The event information is defined by TPosModulesEvent , which contains the ID of the affected module (if the event is associated with a single module) and type of the event. Event types are defined by TPosModulesEventType.

Note: Events are reported as detected by comparing current global settings with their local copy created for the observer. This copy is created when event observer is set by CPosModules::SetObserverL(). It is updated whenever changes are detected. This means that no events will be reported to the observer if no changes have happened since the observer was set.

Many events imply changes in priority order. If the client is interested in priority order it should reload the list of PSYs by calling CPosModules::ModuleIdListL() whenever such an event is reported.

Table 2 describes possible events.

Event type _TPosModulesEventType Is module ID set in TPosModulesEvent object ? Description

EPosModulesEventUnspecified

No

Many changes in settings are detected, which affect priority order and PSY attributes. The client should reload the priority list and PSYs attributes.

EPosModulesEventModuleInstalled

Yes

New PSY is installed and priority list is updated accordingly. The client can get PSYs attributes.

EPosModulesEventModuleRemoved

Yes

A PSY is uninstalled and the priority list is updated accordingly. The client can no longer use the PSY.

EPosModulesEventPrioritiesChanged

No

Changes in PSY priority order have occurred (PSYs reordered). No PSY attributes have changed.

EPosModulesEventCostChanged

Yes

The cost indicator of a PSY has been changed.

EPosModulesEventAvailabilityChanged

Yes

The availability status of a PSY has been changed.

EPosModulesEventVisibilityChanged

Yes

The visibility status of a PSY has been changed and priority list is updated accordingly.

Table 2. Settings event types and their meaning.

Figure 4 shows basic steps that a client takes to listen for changes in location settings:

Figure 4. Figure 4. Listening to change events

This example shows how a client can listen for PSY events:

class CModuleEventListener : public CBase, public MPosModulesObserver
    {
    public:
        CModuleEventListener( CPosModules& aSettings );
        // Starts observing change events
        void StartObservingL();
        // Stops observing change events
        void StopObservingL();

    public: // from MPosModulesObserver
        void HandleSettingsChangeL( TPosModulesEvent aEvent );
        ...

    private:
        CPosModules& iSettings;
    };

// Constructor stores reference to CPosModules
CModuleEventListener::CModuleEventListener( CPosModules& aSettings )
: iSettings( aSettings )
    {
    }

void CMyEventListener::StartObservingL()
    {
    iSettings.SetObserverL( *this );
    }

void CMyEventListener::StopObserving()
    {
    iSettings.RemoveObserver();
    }

// Called whenever change in location settings is detected
void CMyEventListener::HandleSettingsChangeL( TPosModulesEvent aEvent )
    {
    switch ( aEvent.iType )
        {
        case EPosModulesEventModuleInstalled:
            // new PSY installed, add to UI
            break;
        case EPosModulesEventModuleRemoved:
            // remove PSY from UI
            break;
        case EPosModulesEventPrioritiesChanged:
            // reload PSY list and update UI
            break;
        case EPosModulesEventCostChanged:
            // check new state and update UI, if needed
            break;
        case EPosModulesEventAvailabilityChanged:
            // check new state and update UI, if needed
            break;
        case EPosModulesEventVisibilityChanged:
            // check new state and update UI, as needed
            break;
        case EPosModulesEventUnspecified:
        default:
            // reload PSY list and update UI, many changes happened
            break;
        }
    }

Error handling

Accessing location settings can fail with error code KErrLocked. Read operations fail if some other client is modifying the settings at the same time. Writing operation fails if any other client is reading settings at the same time. The client should retry the failed operation.

The interface uses the system-wide error codes of the Symbian platform and defines its own panic codes, defined in following table. A panic is used to detect programming errors. Panic category is LocationSettings.

Panic code Panic name Description

0

EPosLocSetPanicParameterOutOfRange

An invalid value has been passed to a function.

1

EPosLocSetPanicObserverIsAlreadySet

The client tried to set an observer in CPosModules even though an observer had already been set. CPosModules::RemoveObserver() must be called before the new observer is set.

2

EPosLocSetPanicObserverNotStopped

The client tries to destroy CPosModules while the observer is still set.

Memory overhead

Over the cost of allocating API classes, the only additional memory required is used by the API for its internal cache of PSY attributes. This is less than 200 bytes per installed PSY.