Detect if Idle screen is active on Belle
This article explains how to detect when Idle screen is active / in foreground on Nokia Belle.
Article Metadata
Tested with
Compatibility
Article
Introduction
Pre-Nokia Belle the Home-screen (Idle Screen) and Menu screen has their own UID, but since Nokia Belle they both have the same UID [0x102750F0]. So you can't count on CApaWindowGroupName to detect if Idle screen is active or not.
Instead, in this case we monitor publisher and subscribe keys for the idle state using an active object.
Source Code
The Publisher/Subscribe keys that store the value of '0' when Idle screen is not active, and '1' when it is active are listed below:
const TUid KPSUidAiInformation = {0x101FD657};
const TUint KActiveIdleState = 0x00000002; // Contains one value from following emuneration
Header file:
By implementing the virtual functions PsValueChangedL(), the various states of Idle screen can be monitored.
#ifndef __CALLOBSERVER_H__
#define __CALLOBSERVER_H__
#include <e32base.h>
#include <e32property.h>
class MMyPsObsCallBack
{
public:
virtual void PsValueChangedL(const TUint& aKey, TInt aValue,TInt aError)=0;
};
class CmyPsObserver : public CActive
{
public:
static CmyPsObserver* NewLC(MMyPsObsCallBack &aCallBack,const TUid& aCategory, TUint aKey);
static CmyPsObserver* NewL(MMyPsObsCallBack &aCallBack,const TUid& aCategory, TUint aKey);
~CmyPsObserver();
TInt SetPropertyL(TInt aValue);
TInt GetPropertyL(TInt& aValue);
protected:
void DoCancel();
void RunL();
private:
void ConstructL();
CmyPsObserver(MMyPsObsCallBack &aCallBack,const TUid& aCategory, TUint aKey);
private:
MMyPsObsCallBack& iCallBack;
TUid iCategory;
TUint iKey;
RProperty iProperty;
};
#endif //__CALLOBSERVER_H__
Source file:
#include "Ps_Observer.h"
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
CmyPsObserver* CmyPsObserver::NewLC(MMyPsObsCallBack &aCallBack,const TUid& aCategory, TUint aKey)
{
CmyPsObserver* self = new (ELeave) CmyPsObserver(aCallBack,aCategory,aKey);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
CmyPsObserver* CmyPsObserver::NewL(MMyPsObsCallBack &aCallBack,const TUid& aCategory, TUint aKey)
{
CmyPsObserver* self = CmyPsObserver::NewLC(aCallBack,aCategory,aKey);
CleanupStack::Pop(self);
return self;
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
CmyPsObserver::CmyPsObserver(MMyPsObsCallBack &aCallBack,const TUid& aCategory, TUint aKey)
:CActive(EPriorityStandard),iCallBack(aCallBack),iCategory(aCategory),iKey(aKey)
{
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
CmyPsObserver::~CmyPsObserver()
{
Cancel();
iProperty.Close();
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
void CmyPsObserver::ConstructL()
{
CActiveScheduler::Add(this);
User::LeaveIfError( iProperty.Attach( iCategory, iKey ) );
iProperty.Subscribe( iStatus );
SetActive();
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
TInt CmyPsObserver::SetPropertyL(TInt aValue)
{
TInt err(KErrNone);
Cancel();
err = iProperty.Set(aValue);
iProperty.Subscribe( iStatus );
SetActive();
return err;
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
TInt CmyPsObserver::GetPropertyL(TInt& aValue)
{
TInt err(KErrNone);
Cancel();
err = iProperty.Get(aValue);
iProperty.Subscribe( iStatus );
SetActive();
return err;
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
void CmyPsObserver::RunL()
{
iProperty.Subscribe( iStatus );
SetActive();
TInt valValue(0);
TInt err = GetPropertyL(valValue); /// check this againn
iCallBack.PsValueChangedL(iKey,valValue,err);
}
/*
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
*/
void CmyPsObserver::DoCancel()
{
iProperty.Cancel();
}
Example:
// Note that the owner of the Active Object that monitors the Pub/Sub key is derived from MMyPsObsCallBack class and implemented PsValueChangedL() function,
// and so we send it as the first parameter (*this).
CmyPsObserver* imyPsObserver; = CmyPsObserver::NewL(*this, KPSUidAiInformation, KActiveIdleState );
Summary
Sometimes you need to show an "Indicator" on the idle screen only for a specific reasons, and so the need exist to detect when the Idle screen gets de/activated to show/hide the Indicator.


Hamishwillee - Subedited
Useful article. I've subedited and added the Nokia Belle version category.
Would be useful to cross link to other articles which show how to do this before Nokia Belle in a Template:SeeAlso (if this exists). Also possibly link to key article on active objects - e-g- Fundamentals of Symbian C++/Active Objects.
A zip file containing a buildable example demonstrating this would also be useful.
hamishwillee 05:37, 8 August 2012 (EEST)