Central repository

You can use the Central Repository API to read many common settings from Central Repository. The following is an example of reading the Bluetooth power state:

CRepository *crep = CRepository::NewL(KCRUidBluetoothPowerState);
TInt value=0;
User::LeaveIfError( crep->Get(KBTPowerState, value) );

Access to a repository is done using the CRepository class, which is defined in centralrepository.h. To gain access to a repository, a CRepository object is created with the repository UID:

#include < centralrepository.h>
//some unique UID
static const TUid KSomeRepository = { 0x00001234 };
const TUint32 KOldKey = 1234;
const TUint32 KNewKey = 4321;
_LIT(KHelloWorld, "HelloWorld!\n");
//Here is the actual creation
CRepository *repository =
         CRepository::NewL( KSomeRepository );

Getting the published value from Central Repository is done with one of the Get() functions:

TBuf <KKeyValueMaxSize> buffer;
User::LeaveIfError( repository->Get( KOldKey, buffer ) );
//if no errors occurred then the buffer contains the key value

Values for existing keys can be set by using the set function:

User::LeaveIfError ( iRepository->Set(KOldKey, KHelloWorld) );

Keys can also be created at run time:

//create a new key/setting
User::LeaveIfError(
        repository->Create( KNewKey, KHelloWorld )
        );
//…
delete repository;

Deletion can be done (if the application has the required capabilities and the key can be deleted) by calling the Delete() function and passing the key as parameter:

User::LeaveIfError( iRepository->Delete(KNewKey) );

Settings and values can be searched with a set of Find() functions. Find parameters can be partial. Central Repository offers a notification services API through NotifyRequest() functions:

repository->NotifyRequest( KNewKey, iStatus );
...
// Notification requests are canceled with
// TInt error = repository->NotifyCancelAll();
// which cancels all requests or
TInt error = repository->NotifyCancel( KNewKey );

Notification observers are commonly implemented as active objects. In the example code below, the observer is set to get notified if the current Active profile setting is changed. The profile settings repository identifier is KCRUidProfileEngine and the key for active profile is KProEngActiveProfile. Values are integers, starting at 0. The following is a simple observer interface used to notify the observer when the profile has changed:

class CRepository; //forward declaration
//a observer interface for profile change
class MProfileWatcher
       {
       public:
               virtual void ProfileChanged(TInt aProfile) = 0;
        };
//These active objects observe the changing of the profile
//and notify the observer when the change has occured
class CProfileNotifyHandler : public CActive
       {
       public:
               static CProfileNotifyHandler* NewL( MProfileWatcher& aObserver);
               static CProfileNotifyHandler* NewLC(MProfileWatcher& aObserver);
                void StartObservingL();
                void StopObserving();
                virtual ~CProfileNotifyHandler();
                void RunL();
                void RunErrorL(TInt aError);
                void DoCancel();
       protected:
                CProfileNotifyHandler(MProfileWatcher& aObserver);
                void ConstructL();
       private:
              CRepository* iRepository;
              TUint32 iKey;
              TUid iUid;
              MProfileWatcher& iObserver; //class using the observer
        };

Function implementations are shown below. Notice the creation of the CRepository class and its usage through NotifyRequest() and NotifyCancel() functions. Also note that the observed value (in this case, the profile) does not really have to change. A notification also occurs when the same value is set again; this functionality could easily be coded to the active object's RunL function, if needed.

#include < profileenginesdkcrkeys.h>
#include < centralrepository.h>
//trivial NewL and NewLC have been omitted.
void CProfileNotifyHandler::ConstructL()
        {
        iUid = KCRUidProfileEngine; //observe profile engine to
        iKey = KProEngActiveProfile; //see which profile is active
        iRepository = CRepository::NewL( iUid );
        CActiveScheduler::Add(this);
         }
         CProfileNotifyHandler::CProfileNotifyHandler(MProfileWatcher& aObserver) : iObserver(aObserver), CActive (EPriorityLow)
         {
         //do nothing
         }
CProfileNotifyHandler::~CProfileNotifyHandler()
         {
         Cancel(); //first cancel because iRepository is used there
         delete iRepository;
         iRepository=NULL;
         }
void CProfileNotifyHandler::StartObservingL()
         {
         if( IsActive() )
         {
         return; //do nothing if allready observing
         }
         User::LeaveIfError(
                        iRepository->NotifyRequest( iKey, iStatus ) );
         SetActive();
          }
void CProfileNotifyHandler::StopObserving()
          {
          Cancel();
          }
void CProfileNotifyHandler::DoCancel()
          {
          iRepository->NotifyCancel(iKey);
          }
void CProfileNotifyHandler::RunL()
          {
          TInt value = 0;
          TInt error = iRepository->Get( iKey, value);
          //always check the error code
          if( error == KErrNone )
                 {
                 //observer received the profile value as integer
                 //this happens even if the value hasn’t really changed
                 //some application may have set the same value again
                 iObserver.ProfileChanged(value);
                 }
          // Re-subscribe
          error = iRepository->NotifyRequest( iKey, iStatus );
          if( error == KErrNone )
               {
               //
               SetActive();
                }
          else
                {
                //todo: error handling
                }
           }
//The observer has implemented MProfileWatcher interface.
void CMyAppEngine::ProfileChanged(TInt aProfile)
          {
          switch ( aProfile )
                  {
                  case 0: // General profile
                         {
                         // do something
                         break;
                         }
                   case 1: // Silent profile
                         {
                         // do something
                         break;
                          }
                   case 2: // Meeting profile
                          {
                          // do something
                          break;
                           }
                   case 3: // Outdoor profile
                           {
                           // do something
                           break;
                            }
                   default:
                            {
                             // unknown´profile;
                            break;
                             }
                    }
}

Before using the repository, the data to be stored in it must be defined. Of course this is not necessary if the only values read are those stored by other applications (as was the case above, with the Bluetooth power state).

The repository definition file is a text file with a Unicode format and it is required for persistent data. Definition files are located on the c: or z: drive; the c: drive is searched through first. The file path is \system\data\cenrep for nondata caged platforms and \private\10202be9 for those that are data caged.

#
# 00001234.txt
# Test config file for central repository
#
# goes to \private\10202be9
cenrep
version 1
[platsec]
# default capabilities for this repository
cap_rd=ReadDeviceData cap_wr = WriteDeviceData
[main]
#
1234 string value 2

The created keys are stored in a file named <repository_UID>.cre. After creating or deleting keys, the original text file is deleted and only the <repository_UID>.cre remains.

Note: As mentioned earlier, the definition file has to be in the private directory - it cannot be in the import directory. Currently repositories can only be added during image creation. Due to this restriction, it is recommended that Central Repository be used only for reading published key values and receiving change notifications.