Accessing System Capabilities

When developing for Series 60, there are APIs available to query the system capabilities, share state data with other applications and register for notification of changes to system states. These APIs are implemented in two main components: the Hardware Abstraction Layer (HAL) and System Agent (SA) components .

The example applications HalView and SystemAgent described in this section show further use of these two components.

Hardware Abstraction Layer

HAL provides you with a very simple-to-use API, which can query attributes of the device. The API itself is very small, with only three functions, all provided by the class HAL :

 static TInt Get(TAttribute anAttribute, TInt& aValue); static TInt Set(TAttribute anAttribute, TInt aValue); static TInt GetAll(TInt& aNumEntries, SEntry*& aData); 

The class HAL ( hal.h ) derives from HALData (hal_data.h) , which contains the definition of the enumeration TAttribute . This simply defines 70+ attributes that can be queried, covering such information as device manufacturer, battery status, available memory and so on. You will need to include the hal.h header file in your code and add hal.lib library into your project ( .mmp ) file to get it to link correctly.

Note that the simplicity of the API restricts its use to that of state information, as the value returned is purely an integer value. Note also that the degree to which each device supports all of these fields depends on the manufacturer.

Two of the API methods allow you to retrieve information from HAL. Either an array containing all of the entries, or a single specific entry, can be retrieved. In this example, all of the states are read in one call, plus the amount of RAM in the device is read directly:

 TInt numHalEntries; HAL::SEntry* halEntries; HAL::GetAll(numHalEntries, halEntries); // All entries TInt ram; HAL::Get(HAL::EMemoryRam, ram); // Get one specific entry 

Some of the fields are recognized as being dynamic; in other words, their value may change each time they are queried. This can be determined by the status of the iProperties attribute of an SEntry structure returned from HAL::GetAll() . If this equals HAL::EEntryDynamic ( 0x2 ), then the field is dynamic; however, this does not immediately mean it is settable.

To find out if a field is settable, an attempt must be made to set it through the HAL::Set() method. If a field is not settable, then the return value from the call will be one of the standard system error codes, typically KErrNotSupported . For example:

 TInt err = HAL::Set(HAL::ECaseSwitchDisplayOn, 1); 

The attribute HALData::EMachineUid can be used to identify the phone model that your application is installed on at runtime ”see Table 12-2. This makes it possible to customize the behavior of the application to use any licensee-specific APIs that may be available. Getting this ID is illustrated next .

A call to the HAL::Get() function will return a unique code identifying the Series 60 product at runtime.

 #include <hal.h> // also link to hal.lib ... TInt mUid = 0; HAL::Get(HALData::EMachineUid, mUid); 

Be aware, however, that the machine UID is no guarantee of the software version on the device ”you need to use SysUtil::GetSWVersion(TDes &aValue) to get the software version. See the SysUtil class in the Series 60 SDK documentation for more details of this and many other useful methods.

Table 12-2. Machine IDs


Machine UID

Nokia 7650


Nokia 3650


Nokia N-Gage


Nokia 6600


Siemens SX1


Sendo X


Series 60 1.2 emulator


Phone IMEI Number

Another class related to HAL is PlpVariant , which is most commonly used to access the IMEI number of a phone. The IMEI, or International Mobile Equipment Identity , number is a unique 15-digit code assigned to each GSM ( Global System for Mobile ) mobile device. This number can be retrieved manually from a Series 60 device by entering the sequence " *#06# " into the Phone application. It is also printed on the compliance plate, which is usually located under the battery. Programmatically, this number can be accessed by the following code, which returns a string containing the IMEI number:

 // A typedef for a TBuf TPlpVariantMachineId machineId; PlpVariant::GetMachineIdL(machineId); 

Note that this will work only on target ”the emulator will not return a valid value. Also, do not forget to #include <plpvariant.h> in your code and link against plpvariant.lib .

System Agent

System Agent is a Symbian OS component designed to allow a generic framework of notifications and system event state monitoring. System Agent is a Symbian OS Server, providing clients with access to the information through client-side handles.

The two main classes involved are RSystemAgent and RSAVarChangeNotify . RSystemAgent is used to get data and also to register interest in a change to a value. RSAVarChangeNotify is used to tell System Agent that a state has changed. Once System Agent is notified of a change, it pushes this information out to all parties who have registered an interest in that state.

All System Agent information is stored via a UID . The System Agent values that are supported by default are stored in sacls.h . The list includes KUidPhonePwr , KUidSIMStatus , KUidNetworkStatus , KUidNetworkStrength , KUidChargerStatus , KUidBatteryStrength , KUidCurrentCall , KUidDataPort , KUidInboxStatus , KUidOutboxStatus , KUidClock , KUidAlarm and KUidIrdaStatus .

The following example code shows how System Agent could be used inside an active object:

 RSystemAgent sysAgent; TSysAgentEvent sysAgentEvent; sysAgent.Connect(); sysAgentEvent.SetRequestStatus(iStatus); // aUid is the UID we want to monitor. sysAgentEvent.SetUid(aUid); sysAgent.NotifyOnEvent(sysAgentEvent); 

The example shows the connection to the System Agent server, and the call to NotifyOnEvent tells System Agent that you wish to be notified when the value of the item associated to aUid changes. The application will be notified through the completion of the request associated with the trequestStatus , which is set in the TSysAgentEvent . This will result in the RunL on the active object to be invoked. The SystemAgent example that accompanies this chapter monitors several values, one of which is identified through the UID KUidInboxStatus from the include file sacls.h . This enables the application to monitor when new unread messages are available in the Messaging Inbox.

More advanced monitoring of system data can be achieved through the use of TSysAgentCondition , which allows for notification when one of the conditions ESysAgentEquals , ESysAgentNotEquals , ESysAgentGreaterThan or ESysAgentLessThan is met. In this case, RSystemAgent::NotifyOnCondition() is used.

It is also possible to add your own data to System Agent by passing a unique UID to the RSAVarChangeNotify::NotifySaVarChangeL() method:

 const TUid KUidSystemAgentStateVariable = { 0x101F6119 }; ... iSAVarChangeNotify.NotifySaVarChangeL(KUidSystemAgentStateVariable, iSystemAgentState); 

This will notify all other System Agent clients who have shown an interest in monitoring this data. When there is no longer a need for System Agent to store this value, it can be released via the following call:


Vibration API Support

Introduced in Series 60 2.x, this public interface allows you to control the device vibration feature. Vibration might be used in an application such as a game to signal a collision or an explosion, or for giving tactile feedback to other game events, such as resonance when a ball hits an object such as a racquet or a bat.

To use this API, include the vibractrl.h header in the source code and the vibractrl.lib in the .mmp file. The factory functions to construct an instance of the control object are:

 CVibraControl* NewL() CVibraControl* NewL(MVibraControlObserver *aCallback) CVibraControl* NewLC(MVibraControlObserver *aCallback) 

Some key methods are:

 virtual TInt StartVibra(TUint16 aDuration) = 0 virtual TInt StopVibra(void) = 0 virtual TVibraModeState VibraSettings(void) const = 0 

StartVibra() initiates the device vibration feedback, where aDuration is the interval in milliseconds . A value of specifies that the vibration should continue indefinitely. Vibration can be stopped before the specified duration has elapsed with a call to StopVibra() .

The StartVibra() method does not block, but returns immediately, so that the vibration happens simultaneously as the application continues to run. If StartVibra() is called again, before the first vibration completes, then the first vibration is interrupted and the second vibrations starts immediately ”the periods of vibration are not cumulative.

The vibration settings in the user profile must be active for the vibration to be activated via this API. Also, specific Series 60 devices may have implementation-defined or hardware-imposed limits to the duration of the vibration feature (to conserve power). In such circumstances any vibration will cut off at that limit, even if the duration parameter is greater than the limit.

Use VibraSettings() to retrieve the current vibration settings from the current user profile. Then, if vibration is not active but is needed by the application ”typically a game ”the user could be informed and offered the option to enable the vibration feature for the duration of the game. This method returns TVibraModeState with the possible states of EVibraModeON , EVibraModeOFF or, if an error occurs, EVibraModeUnknown .

The mixin interface MVibraControlObserver class declares:

 virtual void VibraModeStatus(CVibraControl::TVibraModeState aStatus) = 0 virtual void VibraRequestStatus(CVibraControl::TVibraRequestStatus aStatus) = 0 

VibraModeStatus() is called when the vibration setting in the user profile is changed, so your application can be aware of changes the user makes. VibraRequestStatus() is called when the device vibration feature is requested .

The argument aStatus is a TVibraRequestStatus and indicates the current VibraControl request status. In addition to the return value supplied by the StartVibra() method (Symbian OS standard error codes), more detailed status information is returned by the callback method MVibraControlObserver::VibraRequestStatus() . Possible values for aStatus are EVibraRequestOK , EVibraRequestFail , EVibraRequestNotAllowed , EVibraRequestStopped , VibraRequestUnableToStop and EVibraRequestUnknown .

Developing Series 60 Applications. A Guide for Symbian OS C++ Developers
Developing Series 60 Applications: A Guide for Symbian OS C++ Developers: A Guide for Symbian OS C++ Developers
ISBN: 0321227220
EAN: 2147483647
Year: 2003
Pages: 139 © 2008-2017.
If you may any questions please contact us: