--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AknGlobalUI/AknCapServer/src/AknCapServerEntry.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1483 @@
+/*
+* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefconst.h>
+#include <uikon/eikenvinterface.h>
+#endif
+#include <eikstart.h>
+#include <AknDef.h>
+#include <barsread.h>
+#include <bautils.h>
+#include <e32std.h>
+#include <e32property.h>
+#include <UikonInternalPSKeys.h> // KUikLayoutState, KPSUidUikon, KUikAppHiddenList
+#include <AknFepInternalCRKeys.h> // KAknFepHashKeySelection, KAknFepEditTextSubmenu
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+#include <AknFepInternalPSKeys.h> // KAknFepFnKeyState
+#endif
+#include "avkoninternalpskeys.h" // KAknIdleAppWindowGroupId
+#include <AknCapServerDefs.h>
+#include <activeidle2domainpskeys.h>
+#include <eikpriv.rsg>
+#include <coedef.h>
+#include <eiksvdef.h>
+#include <aknconsts.h>
+#include <AknsConstants.h>
+#include <apgwgnam.h>
+
+#include "AknCapServerDefs.h"
+#include "AknCapServerEntry.h"
+#include "AknCapServer.h"
+#include "AknFastswapWindowControl.h"
+#include "AknMemoryCardDialogImpl.h"
+#include "oommonitor.h"
+#include "AknKeyFilter.h"
+#include <AknWsEventObserver.h>
+
+#include <PtiEngine.h>
+#include <PtiKeyMappings.h>
+#include <PtiDefs.h>
+
+// For Gs to initiate OFN status
+#include <settingsinternalcrkeys.h>
+
+#include <aknenv.h>
+#include <AknSettingCache.h>
+#include <eikspane.h>
+#include "aknstatuspanedatapublisher.h"
+
+#include <syslangutil.h> // SysLangUtil::GetInstalledLanguages
+#include <featmgr.h>
+#include <centralrepository.h>
+#include "aknmessagereaderlongpressdetector.h" // MAknMessageReaderLongPressDetector
+
+#include <akncapserveralternatefsplugin.h>
+#include <akncapserveralternatefspluginconst.hrh>
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LAYOUT_SWITCH
+ #include <gfxtranseffect/gfxtranseffect.h>
+ #include <akntranseffect.h> // for Transition effect enumerations
+#endif
+
+#ifdef SYMBIAN_BUILD_GCE
+ #include <alf/alfclientbase.h>
+#endif
+
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+#include <AvkonInternalCRKeys.h>
+
+#include "akncapserverdiscreetpopuphandler.h"
+
+const TUid KPtiEnginePSUid = {0x101F8610}; // Same as PtiEngine dll
+
+enum TPtiEnginePSKeys
+ {
+ EKeyMapPropertyCount,
+ EKeyMapPropertyData,
+ EKeyMapPropertyCount2,
+ EKeyMapPropertyData2,
+ EKeyMapPropertyCount3,
+ EKeyMapPropertyData3
+ };
+
+ // Read capability: AlwaysPass.
+_LIT_SECURITY_POLICY_PASS( KCapServerPtiEngineAlwaysPass );
+_LIT_SECURITY_POLICY_S1( KCapServerPtiEngineWritePolicy, 0x10207218, ECapabilityWriteDeviceData);
+#endif
+
+// External keyboard modifier
+const TUint KModifierExternalKeyboard = 0x00200000;
+
+const TInt KWgPriorityCoverEverything = 10000;
+const TInt KKeyEventICodeThreshold = 0x001f;
+const TInt KMaxLanguageCodeLength = 6; // 5 digits + separator
+
+
+
+_LIT(KEikSrvUIResFileName, "z:\\resource\\eiksrvui.rsc");
+_LIT_SECURITY_POLICY_PASS(KPassReadPolicy);
+_LIT_SECURITY_POLICY_C1(KWriteDDPolicy, ECapabilityWriteDeviceData);
+_LIT_SECURITY_POLICY_C1(KReadPolicy, ECapability_None);
+_LIT( KSeparator, " " );
+
+CAknCapServerApplication::CAknCapServerApplication()
+ {
+ }
+
+void CAknCapServerApplication::NewAppServerL(CApaAppServer*& aAppServer)
+ {
+ CAknCapServer* server = new (ELeave) CAknCapServer();
+
+ CleanupStack::PushL(server);
+ server->CreateDynamicSoftNoteEventManagerL();
+ CleanupStack::Pop(server);
+
+ server->SetPriority(EActivePriorityIpcEventsHigh);
+ aAppServer=&*server;
+ iCapServer = server;
+ }
+
+CApaDocument* CAknCapServerApplication::CreateDocumentL()
+ {
+ return new (ELeave) CAknCapAppServerDocument(*this);
+ }
+
+CEikAppUi* CAknCapAppServerDocument::CreateAppUiL()
+ {
+ CAknCapServerApplication* app = static_cast<CAknCapServerApplication*>(iApp);
+ CAknCapServer* server = app->CapServer();
+ CAknCapAppServerAppUi* ret = new (ELeave) CAknCapAppServerAppUi( server );
+ return ret;
+ }
+
+CAknCapAppServerAppUi::CAknCapAppServerAppUi( CAknCapServer* aCapServer ) : iCapServer( aCapServer )
+ {
+ iIdleActive = ETrue;
+ }
+
+CAknCapAppServerAppUi::~CAknCapAppServerAppUi()
+ {
+ delete iAlternateFS;
+ delete iTelephonyIdleUidSubscriber;
+ delete iGlobalNotesAllowedSubscriber;
+
+ if (iKeyCaptureControl)
+ {
+ RemoveFromStack(iKeyCaptureControl); // ownership in stack
+ }
+
+ delete iFSControl;
+
+ if (iResourceFileOffset)
+ {
+ iCoeEnv->DeleteResourceFile(iResourceFileOffset);
+ }
+
+ delete iHiddenList;
+ delete iMMCUnlock;
+ delete iIdler;
+ iEikSrv.Close(); // this shouldn't be connected here anyway
+ delete iPtiEngine;
+ }
+
+_LIT(KProductSpecificHalFile, "z:\\system\\data\\ProductSpecificHalParams.txt");
+
+void DoProductSpecificHalFunction()
+ {
+ RFs& fs = CCoeEnv::Static()->FsSession();
+ RFile file;
+ if (fs.Handle() && file.Open(fs,KProductSpecificHalFile, EFileRead)==KErrNone)
+ {
+ TBuf8<30> desc;
+ file.Read(desc);
+ TLex8 lex(desc);
+ TInt i[4];
+ TInt ii = 0;
+ for (;ii < 4; ii++)
+ {
+ if (lex.Val(i[ii]))
+ {
+ ii = KErrArgument;
+ break;
+ }
+ lex.SkipSpace();
+ }
+ if (ii != KErrArgument)
+ {
+ UserSvr::HalFunction(i[0], i[1], &i[2], &i[3]);
+ }
+ file.Close();
+ }
+ }
+
+TInt StartOOM(TAny* aThis)
+ {
+ // By running idle priority active object twice, we allow idle priority objects
+ // scheduled after AppUi::ConstructL() run at least once.
+ CAknCapAppServerAppUi* me = (CAknCapAppServerAppUi*)aThis;
+ if (!me->iHasRunOnce)
+ {
+ DoProductSpecificHalFunction();
+
+ me->iHasRunOnce = ETrue;
+ me->iIdler->Start(TCallBack(StartOOM, aThis));
+ return KErrNone;
+ }
+
+ // free resources of idler
+ delete me->iIdler;
+ me->iIdler = 0;
+
+ // do the actual startup
+ TRAPD( err, CreateOOMWatcherThreadL());
+ // we panic here if something goes wrong as startup will fail anyway.
+ __ASSERT_ALWAYS(err==KErrNone, User::Invariant());
+
+ me->iEikSrv.AllowNotifierAppServersToLoad();
+ me->iEikSrv.Close(); // currently there is no use to keep this session alive.
+
+#ifdef SYMBIAN_BUILD_GCE
+ TRAP(err, CAlfAsynchStartup::StartL());
+#endif
+
+ return err;
+ }
+
+void CAknCapAppServerAppUi::LoadAlternateFsPlugin()
+ {
+ // List all plugins
+ RImplInfoPtrArray implInfoArray;
+ TRAPD( error, REComSession::ListImplementationsL(
+ TUid::Uid( KAknCapServerAlternateFsPluginInterfaceUid ), implInfoArray ) );
+
+ if ( error == KErrNone && implInfoArray.Count() )
+ {
+ TUid uid = implInfoArray[0]->ImplementationUid();
+ TRAP_IGNORE( iAlternateFS = CAknCapAppServerAlternateFs::NewL( uid ) );
+ }
+
+ implInfoArray.ResetAndDestroy();
+ }
+
+void CAknCapAppServerAppUi::ShowOrDismissAlternateFs()
+ {
+ if ( !iAlternateFS )
+ {
+ return;
+ }
+
+ if ( iAlternateFS->IsVisible() )
+ {
+ iAlternateFS->HandleLongAppKeyPress();
+ }
+ else
+ {
+ iAlternateFS->Show();
+ }
+ }
+
+void CAknCapAppServerAppUi::ConstructL()
+ {
+ User::SetCritical(User::ESystemCritical);
+
+ InitiateOFNStatus();
+
+ // install default FEP if none set before
+ if (iEikonEnv->FepUid() == KNullUid)
+ {
+ iEikonEnv->InstallFepL(TUid::Uid(0x101FD65A));
+ }
+
+ // define and set the PS key listing installed languages
+ PublishInstalledLanguagesL();
+
+ TInt value = 1;
+ if ( FeatureManager::FeatureSupported( KFeatureIdEditKey ) )
+ {
+ // The edit key exists in the device. Hash-key selection disabled and
+ // edit text sub-menu removed from the options menu
+ value = 0;
+ }
+ CRepository* repository = CRepository::NewL(KCRUidAknFep);
+ // Return value of repository->Set() ignored.
+ repository->Set(KAknFepHashKeySelection, value);
+ repository->Set(KAknFepEditTextSubmenu, value);
+ delete repository;
+ repository = NULL;
+
+ // kick eikon server in (in case it is not running yet)
+ TInt error = iEikSrv.Connect();
+ __ASSERT_ALWAYS(error == KErrNone, User::Invariant());
+
+ // base call
+ CAknNotifierAppServerAppUi::ConstructL();
+
+ RWsSession& wsSession=iEikonEnv->WsSession();
+ iBackdropWindowGroup=RWindowGroup(wsSession);
+ User::LeaveIfError(iBackdropWindowGroup.Construct((TUint32)&iBackdropWindowGroup, EFalse));
+ iBackdropWindowGroup.AutoForeground(EFalse);
+
+ CApaWindowGroupName* apaName =
+ CApaWindowGroupName::NewLC(wsSession, (TUint32)&iBackdropWindowGroup);
+
+ apaName->SetHidden(ETrue);
+ apaName->SetSystem(ETrue);
+
+ apaName->SetCaptionL(EIKON_SERVER_BACKDROP_WINDOW_GROUP_NAME);
+ User::LeaveIfError(apaName->SetWindowGroupName(iBackdropWindowGroup));
+ CleanupStack::PopAndDestroy(); //apaName
+ iBackdropWindowGroup.SetOrdinalPosition(1, ECoeWinPriorityNormal);
+
+ // to make sure that wserv does not change our priority even we lose foreground
+ wsSession.ComputeMode(RWsSession::EPriorityControlDisabled);
+
+ wsSession.SetDoubleClick(KTimeBetweenClicks,KDoubleClickDistance);
+
+ // AKNLAF
+ wsSession.SetKeyboardRepeatRate(KAknKeyboardRepeatInitialDelay, KAknStandardKeyboardRepeatRate);
+
+ // Disable some of wserv hotkeys if not in RnD mode.
+ if (!BaflUtils::FileExists( iEikonEnv->FsSession(), KRDSupport ))
+ {
+ User::LeaveIfError(wsSession.ClearHotKeys(EHotKeyOfDeath));
+ // Symbian already protects this in urel mode, but just to play it safe
+ User::LeaveIfError(wsSession.ClearHotKeys(EHotKeyShutDown));
+ User::LeaveIfError(wsSession.ClearHotKeys(EHotKeyOff));
+ }
+
+ // Create statuspane & SGcs
+ if (iEikonEnv->StatusPaneCoreResId())
+ {
+ iStatusPane = CEikServStatusPane::NewL(
+ *iEikonEnv,
+ &iBackdropWindowGroup,
+ iEikonEnv->StatusPaneCoreResId());
+ }
+
+ iSgcs = CEikSgcServer::NewL();
+ iSgcs->SetStatusPane(iStatusPane);
+ iSgcs->SetAknCapAppServerAppUi(this);
+
+ RWindowGroup& rootWin = iCoeEnv->RootWin();
+ rootWin.EnableGroupListChangeEvents();
+ rootWin.EnableScreenChangeEvents();
+ rootWin.EnableFocusChangeEvents (); // For cover UI/status pane refresh problems
+
+ iSgcs->HandleWindowGroupParamChangeL(rootWin.Identifier(), EFalse, 0, 0, KAknScreenModeUnset);
+
+ // create a high priority key filter
+ // i.e. capture Apps-Key
+ iKeyCaptureControl=new(ELeave) CAknServKeyFilter();
+ iKeyCaptureControl->ConstructL(*this);
+
+ TFileName fileName(KEikSrvUIResFileName);
+ BaflUtils::NearestLanguageFile(iEikonEnv->FsSession(),fileName);
+ iResourceFileOffset=iCoeEnv->AddResourceFileL(fileName);
+
+ // Create FSW
+ iFSControl= new (ELeave) CAknFastSwapWindowControl(*this);
+ iFSControl->ConstructL();
+
+ // MMC unlocker
+ iMMCUnlock = CAknMMCPasswordRequester::NewL();
+
+ // Boost our priority similar to eikon server.
+ RThread thread;
+#if defined(__EPOC32__)
+ thread.SetProcessPriority(EPriorityHigh);
+#else
+ thread.SetPriority(EPriorityAbsoluteForeground);
+#endif
+
+ // Start OOM watcher thread when scheduler is running
+ // effectively this frees eikon server thread also.
+ iIdler = CIdle::NewL(CActive::EPriorityIdle);
+ iIdler->Start(TCallBack(StartOOM, this));
+ SetAliasKeyCodeResolverL(this);
+
+ // Define the property for Idle application window group id. This cannot be done in AknIcon,
+ // because the property is internal in classicui domain.
+ TInt err = RProperty::Define(
+ KPSUidAvkonInternal,
+ KAknIdleAppWindowGroupId,
+ RProperty::EInt,
+ KPassReadPolicy, // None
+ KWriteDDPolicy); // WriteDeviceData
+
+ if (err != KErrAlreadyExists)
+ {
+ User::LeaveIfError(err);
+ }
+
+ // Define a PubSub key indicate menu option has the task swapper item or not
+ err = RProperty::Define(
+ KPSUidAvkonInternal,
+ KAknMenuOptionNoTaskSwapper,
+ RProperty::EInt);
+
+ if ( err != KErrNone && err != KErrAlreadyExists )
+ {
+ User::LeaveIfError( err );
+ }
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ // Define the property for Idle application window group id. This cannot be done in AknIcon,
+ // because the property is internal in classicui domain.
+ err = RProperty::Define(
+ KPSUidAknFep,
+ KAknFepFnKeyState,
+ RProperty::EInt,
+ KPassReadPolicy, // None
+ KWriteDDPolicy); // WriteDeviceData
+
+ if (err != KErrAlreadyExists)
+ {
+ User::LeaveIfError(err);
+ }
+#endif
+
+ // Start listening "global notes allowed" property. When global notes are allowed,
+ // we know that the boot is finished and the Idle app window group id can be fetched.
+ User::LeaveIfError(iGlobalNotesAllowedProperty.Attach(
+ KPSUidUikon,
+ KUikGlobalNotesAllowed));
+
+ iGlobalNotesAllowedSubscriber = new (ELeave) CPropertySubscriber(
+ TCallBack(GlobalNotesAllowedCallBack, this),
+ iGlobalNotesAllowedProperty);
+
+ iGlobalNotesAllowedSubscriber->Subscribe();
+
+ // Start listening "telephony idle uid" property.
+ User::LeaveIfError(iTelephonyIdleUidProperty.Attach(
+ KPSUidAiInformation,
+ KActiveIdleUid));
+
+ iTelephonyIdleUidSubscriber = new (ELeave) CPropertySubscriber(
+ TCallBack(TelephonyIdleUidCallBack, this),
+ iTelephonyIdleUidProperty);
+
+ iTelephonyIdleUidSubscriber->Subscribe();
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+
+ TInt err1 = 0;
+
+ err1 = RProperty::Define(KPtiEnginePSUid, EKeyMapPropertyCount, RProperty::EInt,
+ KCapServerPtiEngineAlwaysPass, KCapServerPtiEngineWritePolicy);
+ err1 |= RProperty::Set(KPtiEnginePSUid, EKeyMapPropertyCount, 0);
+ err1 |= RProperty::Define(KPtiEnginePSUid, EKeyMapPropertyData, RProperty::EByteArray,
+ KCapServerPtiEngineAlwaysPass, KCapServerPtiEngineWritePolicy);
+
+ err1 |= RProperty::Define(KPtiEnginePSUid, EKeyMapPropertyData2, RProperty::EByteArray,
+ KCapServerPtiEngineAlwaysPass, KCapServerPtiEngineWritePolicy);
+ err1 |= RProperty::Define(KPtiEnginePSUid, EKeyMapPropertyCount2, RProperty::EInt,
+ KCapServerPtiEngineAlwaysPass, KCapServerPtiEngineWritePolicy);
+ err1 |= RProperty::Set(KPtiEnginePSUid, EKeyMapPropertyCount2, 0);
+
+ err1 |= RProperty::Define(KPtiEnginePSUid, EKeyMapPropertyData3, RProperty::EByteArray,
+ KCapServerPtiEngineAlwaysPass, KCapServerPtiEngineWritePolicy);
+ err1 |= RProperty::Define(KPtiEnginePSUid, EKeyMapPropertyCount3, RProperty::EInt,
+ KCapServerPtiEngineAlwaysPass, KCapServerPtiEngineWritePolicy);
+ err1 |= RProperty::Set(KPtiEnginePSUid, EKeyMapPropertyCount3, 0);
+
+ // Create ptiengine instance for key code resolver.
+ if (err1 == KErrNone && !iPtiEngine)
+ {
+ // create PtiEngine already here because only cap server process has write rights to
+ // above properties and several PtiEngine cores want to cache language
+ // bindings to those properties.
+ TRAP_IGNORE(iPtiEngine = CPtiEngine::NewL(ETrue));
+ }
+#endif
+
+ // Create capserver discreetpopuphandler
+ CAknCapServerDiscreetPopupHandler::CreateDiscreetPopupHandlerL();
+ LoadAlternateFsPlugin();
+
+ ProcessInitFlipStatus();
+ }
+
+TKeyResponse CAknCapAppServerAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
+ {
+ return CAknNotifierAppServerAppUi::HandleKeyEventL(aKeyEvent, aType);
+ }
+
+// This must not leave if aAddCount == 0.
+void CAknCapAppServerAppUi::SuppressAppSwitchingL(TInt aAddCount, TInt aClientId)
+ {
+ TInt index = KErrNotFound;
+ for (TInt ii=0;ii<iAppsKeyArray.Count();ii++)
+ {
+ if (iAppsKeyArray[ii].iUid == aClientId)
+ {
+ index = ii;
+ }
+ }
+
+ if (aAddCount == EAknAppsKeyBlockRemoveClient && aClientId) // client is exiting
+ {
+ if (index != KErrNotFound)
+ {
+ iAppsKeyArray.Remove(index);
+ }
+ return;
+ }
+
+ // create client entry (did not previosly exist)
+ if (index == KErrNotFound)
+ {
+ __ASSERT_DEBUG(aAddCount == EAknAppsKeyBlockAddCount, User::Invariant());
+ SSuppressInfo info = SSuppressInfo(aClientId);
+ User::LeaveIfError(iAppsKeyArray.Insert(info,0));
+ index = 0;
+ }
+ // Add aAddcount to client data
+ iAppsKeyArray[index].iReferenceCount += aAddCount;
+ if ( IsAppsKeySuppressed() )
+ {
+ TInt err = RProperty::Set(
+ KPSUidAvkonInternal,
+ KAknMenuOptionNoTaskSwapper, ENoTaskSwapper );
+ if ( err!=KErrNone )
+ {
+ User::LeaveIfError( err );
+ }
+ }
+ else
+ {
+ TInt err = RProperty::Set(
+ KPSUidAvkonInternal,
+ KAknMenuOptionNoTaskSwapper, ETaskSwapper );
+ if ( err!=KErrNone )
+ {
+ User::LeaveIfError( err );
+ }
+ }
+ }
+
+void CAknCapAppServerAppUi::KillAppL(const RMessage2& aMessage)
+ {
+ aMessage.Complete(KErrNotSupported);
+ }
+
+void CAknCapAppServerAppUi::DoTaskListCommandL(const RMessage2& aMessage)
+ {
+ switch (aMessage.Function())
+ {
+ case EAknSEnableTaskList:
+ {
+ TInt err = EnableTaskList(aMessage.Int0());
+ aMessage.Complete(err);
+ break;
+ }
+ case EAknsLaunchTaskList:
+ {
+ if (iTaskListEnabled)
+ {
+ if ( iAlternateFS && iAlternateFS->IsReady() )
+ {
+ if ( aMessage.Int0() )
+ {
+ iAlternateFS->Show();
+ }
+ else
+ {
+ iAlternateFS->Dismiss();
+ }
+ }
+ else
+ {
+ if ( aMessage.Int0() )
+ {
+ TInt err = KErrNone;
+ TRAP( err, iFSControl->InitializeWindowGroupListL( EFalse ));
+ if ( !err )
+ {
+ iFSControl->RunFastSwapL();
+ }
+ }
+ else
+ {
+ iFSControl->CloseFastSwap();
+ }
+ }
+ }
+ aMessage.Complete(KErrNone);
+ break;
+ }
+ case EAknSRefreshTaskList:
+ {
+ TInt err = UpdateTaskListL( ETrue );
+ if ( err != KErrNone )
+ {
+ iFSControl->CloseFastSwap();
+ }
+ aMessage.Complete(err);
+ break;
+ }
+ default:
+ {
+ aMessage.Complete(KErrNotSupported);
+ break;
+ }
+ }
+ }
+
+TBool CAknCapAppServerAppUi::IsAppsKeySuppressed()
+ {
+ if (!iTaskListEnabled)
+ {
+ return ETrue;
+ }
+
+ for(TInt ii = 0; ii < iAppsKeyArray.Count(); ii++)
+ {
+ if (iAppsKeyArray[ii].iReferenceCount)
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+void CAknCapAppServerAppUi::HideApplicationFromFswL(TInt aUid,TBool aDisable)
+ {
+ if (!iHiddenList)
+ {
+ iHiddenList = new (ELeave) CArrayFixFlat<TInt>(1); // This won't grow very big I hope
+ // the appui server reserves a property where it stores the hidden list.
+ RProperty::Define(KPSUidUikon, KUikAppHiddenList, RProperty::ELargeByteArray);
+ }
+ TBool foundUid( EFalse );
+
+ for (TInt i = 0; i < iHiddenList->Count(); i++)
+ {
+ if (aUid == iHiddenList->At(i))
+ {
+ iHiddenList->Delete(i);
+ foundUid = ETrue;
+ break;
+ }
+ }
+
+ if (aDisable)
+ {
+ iHiddenList->AppendL(aUid);
+ // visible uid hidden -> refresh tasklist
+ if ( !foundUid )
+ {
+ UpdateTaskListL( ETrue );
+ }
+ }
+ else
+ {
+ // hidden uid set to visible -> refresh tasklist
+ if ( foundUid )
+ {
+ UpdateTaskListL( ETrue );
+ }
+ }
+
+ // when the hidden list is ready it get's published to P&S service
+ PublishHiddenList();
+ }
+
+void CAknCapAppServerAppUi::ProcessInitFlipStatus()
+ {
+ // we remove the definition from hal_switch.h
+ enum
+ {
+ ECoverSwitch,
+ EHalGroupSwitch = 29
+ };
+
+ const TInt KFeatureIdFfSliderLandscapeStartsApp_LocalDefinition = 5126; //we have to define it here because of some header exporting problem
+ if (FeatureManager::FeatureSupported(KFeatureIdFfSliderLandscapeStartsApp_LocalDefinition))
+ {
+ // check the state of phone slide, if it is open during startup,
+ // we enable the landscape orientation
+ TBool flipStatus(EFalse); // flipStatus true : flip open / false : flip close
+ TInt err = UserSvr::HalFunction(EHalGroupSwitch, ECoverSwitch, &flipStatus, reinterpret_cast<TAny*>(EFalse));
+ if (KErrNone == err && flipStatus)
+ {
+ TRAP_IGNORE(RotateScreenL());
+ }
+ }
+ }
+
+// For Gs to initiate OFN status
+void CAknCapAppServerAppUi::InitiateOFNStatus()
+ {
+ // For Gs to initiate OFN status
+ enum TFidOFNFunctionForGs
+ {
+ EOFNSetPowerON, // OFN Powering (ON/OFF)
+ EHalGroupOFN = 28
+ };
+
+ const TInt KFeatureId_Ff_Ofn_Feature = 193;
+ const TInt KSettingsOptical_Joystick_Status = 0x00000019;
+
+ // For Gs to initiate OFN status
+ if( FeatureManager::FeatureSupported( KFeatureId_Ff_Ofn_Feature ) )
+ {
+ CRepository* personalizationRepository = NULL;
+ TRAPD( errCode, personalizationRepository = CRepository::NewL( KCRUidPersonalizationSettings ) );
+ if (errCode == KErrNone)
+ {
+ TInt ofnStatus = 0;
+ personalizationRepository->Get( KSettingsOptical_Joystick_Status, ofnStatus );
+ delete personalizationRepository;
+
+ UserSvr::HalFunction( EHalGroupOFN, EOFNSetPowerON, reinterpret_cast<TAny*>( ofnStatus ),
+ reinterpret_cast<TAny*>( ofnStatus ) );
+ }
+ }
+ }
+
+void CAknCapAppServerAppUi::PublishHiddenList()
+ {
+ // 1. the creation of hidden list array
+ TBuf16 <2*KMaxHiddenApps> hiddenList;
+ TInt i;
+ TUint16 upperBits;
+ // the limit of hidden application uids
+ TInt hiddenCount = ( iHiddenList->Count() > KMaxHiddenApps ) ?
+ KMaxHiddenApps : iHiddenList->Count();
+
+ for ( i = 0; i < hiddenCount; i++)
+ {
+ // 32-bit integer is appended in two parst to 16-bit buffer
+ upperBits = iHiddenList->At(i) >> 16;
+ hiddenList.Append( upperBits );
+ // upper values are automatically truncated
+ hiddenList.Append( iHiddenList->At(i) );
+ }
+
+ // the end of hidden list is marked null (0x00000000)
+ if ( i < KMaxHiddenApps )
+ {
+ hiddenList.Append( 0x0000 );
+ hiddenList.Append( 0x0000 );
+ }
+
+ // 2. setting the property value
+ RProperty::Set(KPSUidUikon, KUikAppHiddenList, hiddenList);
+ }
+
+TBool CAknCapAppServerAppUi::HiddenFromFSW( TInt aUid )
+ {
+ if ( iHiddenList )
+ {
+ for ( TInt i = 0; i < iHiddenList->Count(); i++)
+ {
+ if (aUid == iHiddenList->At(i))
+ {
+ return ETrue;
+ }
+ }
+ }
+
+ return EFalse;
+ }
+
+TInt CAknCapAppServerAppUi::EnableTaskList(TBool aEnable)
+ {
+ TInt err = KErrNone;
+
+ iTaskListEnabled = aEnable;
+
+ if ( IsAppsKeySuppressed() )
+ {
+ err = RProperty::Set(KPSUidAvkonInternal, KAknMenuOptionNoTaskSwapper, ENoTaskSwapper);
+ }
+ else
+ {
+ err = RProperty::Set(KPSUidAvkonInternal, KAknMenuOptionNoTaskSwapper, ETaskSwapper);
+ }
+ return err;
+ }
+
+TBool CAknCapAppServerAppUi::HandleShortAppsKeyPressL()
+ {
+ if(iAlternateFS && iAlternateFS->IsReady() && iAlternateFS->IsVisible())
+ {
+ iAlternateFS->HandleShortAppKeyPress();
+ return ETrue;
+ }
+ if (iFSControl->IsVisible())
+ {
+ iFSControl->HandleShortAppsKeyPressL();
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+TBool CAknCapAppServerAppUi::HandleLongAppsKeyPressL()
+ {
+ if (iTaskListEnabled)
+ {
+ if ( iAlternateFS && iAlternateFS->IsReady() )
+ {
+ ShowOrDismissAlternateFs();
+ }
+ else
+ {
+ if (iFSControl->IsVisible())
+ {
+ iFSControl->HandleLongAppsKeyPressL();
+ }
+ else
+ {
+ if (iFSControl->VisibleWindowGroupsCountL()<1)
+ {
+ return EFalse;
+ }
+ else
+ {
+ iFSControl->RunFastSwapL();
+ }
+ }
+ }
+ }
+ return ETrue;
+ }
+
+void CAknCapAppServerAppUi::SetStatusPaneFlags(TInt aFlags)
+ {
+ if (iStatusPane)
+ {
+ iStatusPane->SetFlags(aFlags);
+ }
+ }
+
+void CAknCapAppServerAppUi::SetStatusPaneLayoutL(TInt aLayoutResId)
+ {
+ if (iStatusPane)
+ {
+ iStatusPane->SwitchLayoutL(aLayoutResId);
+ }
+ }
+
+void CAknCapAppServerAppUi::BlankScreenL(TBool aBlank, TBool aToForeground)
+ {
+ if (aBlank)
+ {
+ if (++iBlankWinRefCount == 1)
+ {
+ ASSERT(!iBlankWin);
+ if (aToForeground)
+ {
+ iBackdropWindowGroup.SetOrdinalPosition(0, KWgPriorityCoverEverything);
+ }
+ else
+ {
+ iBackdropWindowGroup.SetOrdinalPosition(1, ECoeWinPriorityNormal);
+ }
+ iBlankWin = CAknServBlankWin::NewL(iBackdropWindowGroup, iStatusPane);
+ iForegroundBlankScreen = aToForeground;
+ }
+ }
+ else if (--iBlankWinRefCount <= 0)
+ {
+ iBlankWinRefCount = 0;
+ if (iForegroundBlankScreen)
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LAYOUT_SWITCH
+ CWsScreenDevice* screen = iEikonEnv->ScreenDevice();
+ /*
+ RWsSession& ws = iEikonEnv->WsSession();
+ TInt wgId = ws.GetFocusWindowGroup();
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewL(ws, wgId);
+ CleanupStack::PushL( wgName );
+ TUid appUid = wgName->AppUid();
+ CleanupStack::PopAndDestroy( wgName );
+ */
+ //GfxTransEffect::BeginFullScreen( AknTransEffect::ELayoutSwitch,
+ // TRect( screen->SizeInPixels() ),
+ // AknTransEffect::EParameterType,
+ // AknTransEffect::GfxTransParam( KTfxServerUid )
+ // );
+
+ GfxTransEffect::EndFullScreen();
+#endif
+ iBackdropWindowGroup.SetOrdinalPosition(1, ECoeWinPriorityNormal);
+ }
+ delete iBlankWin;
+ iBlankWin = 0;
+ iForegroundBlankScreen = EFalse;
+ }
+ }
+
+void CAknCapAppServerAppUi::SwapLayoutSwitchBlankScreenL()
+ {
+ if (iBlankWin)
+ {
+ if (!iForegroundBlankScreen)
+ {
+ iBackdropWindowGroup.SetOrdinalPosition(0, KWgPriorityCoverEverything);
+ }
+ iForegroundBlankScreen = ETrue;
+ CAknServBlankWin* newBlankWin = CAknServBlankWin::NewL(iBackdropWindowGroup, iStatusPane);
+ newBlankWin->SetLayoutBlank(ETrue);
+ delete iBlankWin;
+ iBlankWin = newBlankWin;
+ }
+ }
+
+TBool CAknCapAppServerAppUi::IsDisplayingForegroundBlankScreen() const
+ {
+ return iForegroundBlankScreen;
+ }
+
+void CAknCapAppServerAppUi::HandleResourceChangeL(TInt aType)
+ {
+ if (aType == KAknInternalFSWClose) // for notifiers running inside this thread
+ {
+ if (iFSControl)
+ {
+ iFSControl->CloseFastSwap();
+
+ // This cancels power menu when keys are locked / soft note accepted.
+ Manager()->CancelNotifier(KAknGlobalListQueryUid);
+ }
+ return; // don't pass this outside this class
+ }
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ iCapServer->RefreshLongTapAnimation();
+ }
+
+ CAknNotifierAppServerAppUi::HandleResourceChangeL(aType);
+ if (iFSControl)
+ {
+ if ( aType == KAknsMessageSkinChange )
+ {
+ UpdateTaskListL( ETrue );
+ }
+ iFSControl->HandleResourceChange(aType);
+ }
+ if (iStatusPane)
+ {
+ iStatusPane->HandleResourceChange(aType);
+ }
+ if (aType == KAknsMessageSkinChange )
+ {
+ iSgcs->FadeBitmapGenerationL();
+ iSgcs->FadeColorGenerationL();
+ }
+ }
+
+void CAknCapAppServerAppUi::HandleWsEventL(const TWsEvent& aEvent,CCoeControl* aDestination)
+ {
+ if ( iMessageReaderLongPressDetector && !IsAppsKeySuppressed() && !iFSControl->IsDisplayed() )
+ {
+ // Message Reader can be launched by long pressing left soft key
+ // events need to be intercepted/consumed before they are forwarded to cba
+ if ( iMessageReaderLongPressDetector->HandleWsEventL( aEvent, aDestination ) )
+ {
+ return;
+ }
+ }
+ switch( aEvent.Type() )
+ {
+ case EEventFocusGroupChanged: // For cover UI/status pane refresh problems
+ case EEventWindowGroupListChanged:
+ {
+ // only updated if application has informed about it's intentions to exit
+ UpdateTaskListL( EFalse );
+ iSgcs->HandleWindowGroupListChangeL();
+ break;
+ }
+ case KUidValueAknsSkinChangeEvent:
+ {
+ HandleResourceChangeL(KAknsMessageSkinChange);
+ HandleStackedControlsResourceChange(KAknsMessageSkinChange);
+ break;
+ }
+ default:
+ {
+ CAknNotifierAppServerAppUi::HandleWsEventL(aEvent, aDestination);
+ if (EventMonitor())
+ {
+ EventMonitor()->HandleWsEventL(aEvent, aDestination); // for ecs
+ }
+ }
+ }
+ }
+
+void CAknCapAppServerAppUi::SetCurrentAppStatuspaneResourceIdL(TInt aResourceId)
+ {
+ iStatusPane->SetCurrentAppStatuspaneResourceId(aResourceId);
+ }
+
+TInt CAknCapAppServerAppUi::CurrentAppStatuspaneResourceIdL()
+ {
+ return iStatusPane->CurrentAppStatuspaneResourceId();
+ }
+
+void CAknCapAppServerAppUi::RotateScreenL()
+ {
+ iSgcs->RotateScreenL();
+ }
+
+// ---------------------------------------------------------
+// CAknCapAppServerAppUi::UpdateTaskListL
+// Tasklist will be updated when its visible and when
+// when the old tasklist is no longer valid
+// ---------------------------------------------------------
+//
+TInt CAknCapAppServerAppUi::UpdateTaskListL( TBool aTaskListRefreshNeeded )
+ {
+ TInt err = KErrNone;
+ if ( iFSControl->IsDisplayed() )
+ {
+ // update window group list (task list)
+ TInt windowGroupListChanged = ETrue;
+
+ TRAP( err, windowGroupListChanged = iFSControl->InitializeWindowGroupListL(
+ !aTaskListRefreshNeeded ) );
+
+ if ( windowGroupListChanged || aTaskListRefreshNeeded )
+ {
+ TRAP( err, iFSControl->HandleChangeInWindowGroupListL() );
+ }
+ }
+ return err;
+ }
+
+LOCAL_C TBool IsQwertyKey(TPtiKey aKey)
+ {
+ if ((aKey >= EPtiKeyQwertyA && aKey <= EPtiKeyQwertyZ) ||
+ (aKey >= EPtiKeyQwerty0 && aKey <= EPtiKeyQwerty9) ||
+ aKey == EPtiKeyQwertyPlus ||
+ aKey == EPtiKeyQwertyMinus ||
+ aKey == EPtiKeyQwertyComma ||
+ aKey == EPtiKeyQwertySemicolon ||
+ aKey == EPtiKeyQwertyFullstop ||
+ aKey == EPtiKeyQwertyHash ||
+ aKey == EPtiKeyQwertySlash ||
+ aKey == EPtiKeyQwertyApostrophe
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ || aKey == EPtiKeyQwertySpace
+ || aKey == EPtiKeyQwertyAtCharacter
+#endif
+ )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+TBool CAknCapAppServerAppUi::IsCharacterCategoryNumber(TUint aChar) const
+{
+ TChar::TBdCategory numCategory;
+ TBool isNumber = EFalse;
+ numCategory = (TChar(aChar)).GetBdCategory();
+ isNumber = ((numCategory == TChar::EEuropeanNumber) || (numCategory == TChar::EArabicNumber) ||
+ (numCategory == TChar::EEuropeanNumberTerminator) || (aChar == 0x2E) ||
+ (aChar == 0x2A) || (aChar == 0x3D) || (aChar == 0x2F));
+ return isNumber;
+}
+#endif
+
+TInt CAknCapAppServerAppUi::GetAliasKeyCode(TUint& aCode, const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
+ {
+ aCode = aKeyEvent.iCode;
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ TKeyEvent keyEventLocal = aKeyEvent;
+
+ #if defined(__WINS__)
+ if ( keyEventLocal.iScanCode == EStdKeyNkpPlus )
+ {
+ // Workaround solution for the qwerty '+' key in emulator environment.
+ // I did not find a way how to to configure epoc_352x416_Qwerty.ini to send '+' keyevent.
+ keyEventLocal.iScanCode = 0x2b; // '+' key.
+ }
+ #endif
+
+#endif
+ if (!iQwertyStatus || (aKeyEvent.iModifiers & EModifierSpecial) != 0)
+ {
+ // Only qwerty events are converted. Coversion is also rejected if EModifierSpecial
+ // bit is set. That can be used for disabling conversion for simulated
+ // key events.
+ return KErrNone;
+ }
+
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ if (IsQwertyKey((TPtiKey)keyEventLocal.iScanCode))
+#else
+ if (IsQwertyKey((TPtiKey)aKeyEvent.iScanCode))
+#endif
+ {
+ // We know in advance that iCode values below this threshold are not
+ // going to be converted, so just return.
+ if (aCode <= KKeyEventICodeThreshold)
+ {
+ return KErrNone;
+ }
+
+ if (aKeyEvent.iModifiers & KModifierExternalKeyboard)
+ {
+ // The event is coming from external keyboard, do not convert.
+ return KErrNone;
+ }
+
+ TInt err = KErrNone;
+
+ if (!iPtiEngine)
+ {
+ TRAP(err, iPtiEngine = CPtiEngine::NewL(ETrue));
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ }
+
+ CAknSettingCache& settingsCache = CAknEnv::Static()->SettingCache();
+
+ const TInt KMaxNumCharsPerCase = 50;
+ TBuf<KMaxNumCharsPerCase> keys;
+
+ const TBool shifted = (aKeyEvent.iModifiers & EModifierLeftShift) ||
+ (aKeyEvent.iModifiers & EModifierRightShift);
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+
+ TInt fnState;
+ RProperty::Get(KPSUidAknFep,KAknFepFnKeyState, fnState);
+ const TBool functionized = (keyEventLocal.iModifiers & EModifierRightFunc) ;
+ //|| (fnState == 6);
+
+ const TBool isCtrl = (aKeyEvent.iModifiers & EModifierLeftCtrl) ||
+ (aKeyEvent.iModifiers & EModifierRightCtrl);
+ if(isCtrl)
+ return KErrNone;
+#endif
+ CPtiCoreLanguage* lang = static_cast<CPtiCoreLanguage*>(iPtiEngine->GetLanguage(
+ settingsCache.InputLanguage()));
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ // Qwerty Keyboard layout
+ TInt keyboardLayout = 0;
+ RProperty::Get(KCRUidAvkon, KAknKeyBoardLayout, keyboardLayout);
+
+ TPtiKeyboardType keyboardType = (TPtiKeyboardType) keyboardLayout ;
+#endif
+
+ if (lang)
+ {
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ CPtiQwertyKeyMappings* maps;
+ if(keyboardType != EPtiKeyboardHalfQwerty)
+ maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ else
+ maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetHalfQwertyKeymappings());
+
+#else
+ CPtiQwertyKeyMappings* maps =
+ static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+#endif
+
+ if (maps)
+ {
+#ifdef RD_INTELLIGENT_TEXT_INPUT
+ maps->SetKeyboardType(keyboardType);
+ if(functionized)
+ {
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseFnLower);
+ if( !(keys.Length() && IsCharacterCategoryNumber(keys[0])))
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseFnUpper);
+ if(!keys.Length())
+ {
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseFnLower);
+ }
+ }
+ else if(shifted)
+ {
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseUpper);
+ }
+ else
+ {
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseFnLower);
+ if( !(keys.Length() && IsCharacterCategoryNumber(keys[0])))
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseFnUpper);
+ if( !(keys.Length() && IsCharacterCategoryNumber(keys[0])))
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseLower);
+ if( !(keys.Length() && IsCharacterCategoryNumber(keys[0])))
+ maps->GetDataForKey((TPtiKey)keyEventLocal.iScanCode, keys, EPtiCaseUpper);
+ if( !(keys.Length() && IsCharacterCategoryNumber(keys[0])))
+ keys.SetLength(0);
+ }
+
+#else
+ if (shifted)
+ {
+ maps->GetDataForKey((TPtiKey)aKeyEvent.iScanCode, keys, EPtiCaseUpper);
+ }
+ else
+ {
+ maps->GetDataForKey((TPtiKey)aKeyEvent.iScanCode, keys, EPtiCaseLower);
+ }
+#endif
+ }
+ }
+
+ if ( keys.Length() > 0 )
+ {
+ switch (keys[0])
+ {
+ case KPtiPinyinMarker:
+ case KPtiStrokeMarker:
+ case KPtiZhuyinMarker:
+ case KPtiCangjieMarker:
+ case KPtiGetAllMarker:
+ if (keys.Length() > 1)
+ {
+ aCode = keys[1];
+ }
+ break;
+ default:
+ aCode = keys[0];
+ }
+ }
+ }
+
+ return KErrNone;
+ }
+
+void CAknCapAppServerAppUi::ForwardKeyToPhoneAppL(const TKeyEvent& aKeyEvent)
+ {
+ if (iScanCodeCaptureHandle)
+ {
+ return;
+ }
+ iPhoneKey = aKeyEvent; // reset
+
+ iScanCodeCaptureHandle = CCoeEnv::Static()->RootWin().CaptureKeyUpAndDowns(
+ aKeyEvent.iScanCode,0,0 );
+
+ if (!iIdler)
+ {
+ iIdler = CIdle::NewL(CActive::EPriorityStandard);
+ }
+ iIdler->Start(TCallBack(AknPhoneKeyForwarder::ForwardKeyToPhoneApp, &iPhoneKey));
+ iUpReceived = EFalse;
+ }
+
+
+
+void CAknCapAppServerAppUi::PhoneKeyUpReceived()
+ {
+ if (iScanCodeCaptureHandle)
+ {
+ CCoeEnv::Static()->RootWin().CancelCaptureKeyUpAndDowns(iScanCodeCaptureHandle);
+ }
+ iScanCodeCaptureHandle = 0;
+ iUpReceived = ETrue;
+ if (!iIdler->IsActive()) // callback already triggered
+ { // direct call
+ AknPhoneKeyForwarder::ForwardUpEventToPhoneApp(&iPhoneKey);
+ }
+ }
+
+void CAknCapAppServerAppUi::SetFgSpDataSubscriberIdL(TInt aId)
+ {
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ if (statusPane)
+ {
+ CEikServStatusPane* ssp = static_cast<CEikServStatusPane*>(statusPane);
+ CAknStatusPaneDataPublisher* publisher = ssp->iDataPublisher;
+ if (publisher)
+ {
+ publisher->SetForegroundSubscriberId(aId);
+ publisher->PublishDataL();
+ }
+ }
+ }
+
+void CAknCapAppServerAppUi::CloseFSW()
+ {
+ if (iFSControl)
+ {
+ iFSControl->CloseFastSwap();
+ }
+ }
+
+void CAknCapAppServerAppUi::SetIdleActive( TBool bActive )
+ {
+ iIdleActive = bActive;
+ }
+
+TBool CAknCapAppServerAppUi::IsIdelActive( )
+ {
+ return iIdleActive;
+ }
+
+void CAknCapAppServerAppUi::PublishInstalledLanguagesL()
+ {
+ User::LeaveIfError( RProperty::Define(
+ KPSUidUikon,
+ KUikInstalledLanguages,
+ RProperty::EText,
+ KReadPolicy, // None
+ KWriteDDPolicy ) ); // WriteDeviceData
+
+ CArrayFixFlat<TInt>* installedLanguages = 0;
+
+ User::LeaveIfError( SysLangUtil::GetInstalledLanguages( installedLanguages ) );
+
+ CleanupStack::PushL( installedLanguages );
+
+ TInt nbrOfLanguages = installedLanguages->Count();
+
+ // This is a bit more than enough buffer in most cases
+ // Add one just for the space at the beginning of the data.
+ TInt bufferLength = nbrOfLanguages * KMaxLanguageCodeLength + 1;
+
+ HBufC8* languages = HBufC8::NewLC( bufferLength );
+ TPtr8 ptr( languages->Des() );
+
+ if ( nbrOfLanguages > 0 )
+ {
+ ptr.Append( KSeparator ); // Add space at the beginning of the data
+ }
+
+ for ( TInt i = 0; i < nbrOfLanguages; i++ )
+ {
+ ptr.AppendNum( installedLanguages->At(i) ); // Add language ID to data
+ ptr.Append( KSeparator );// Space is also added as the last character
+ }
+
+ RProperty::Set( KPSUidUikon, KUikInstalledLanguages, ptr );
+
+ CleanupStack::PopAndDestroy( 2, installedLanguages );
+ }
+
+TInt CAknCapAppServerAppUi::GlobalNotesAllowedCallBack(TAny* aPtr)
+ {
+ CAknCapAppServerAppUi* self = static_cast<CAknCapAppServerAppUi*>(aPtr);
+ if (self)
+ {
+ self->HandlePropertyChange(KUikGlobalNotesAllowed);
+ }
+ return KErrNone;
+ }
+
+TInt CAknCapAppServerAppUi::TelephonyIdleUidCallBack(TAny* aPtr)
+ {
+ CAknCapAppServerAppUi* self = static_cast<CAknCapAppServerAppUi*>(aPtr);
+ if (self)
+ {
+ self->HandlePropertyChange(KActiveIdleUid);
+ }
+ return KErrNone;
+ }
+
+void CAknCapAppServerAppUi::HandlePropertyChange(const TInt aProperty)
+ {
+ switch(aProperty)
+ {
+ case KUikGlobalNotesAllowed:
+ {
+ TInt globalNotesAllowed = 0;
+ TInt err = iTelephonyIdleUidProperty.Get(globalNotesAllowed);
+ if(!err && globalNotesAllowed)
+ {
+ // Global notes allowed, so the boot is finished. Now the idle app uid and its
+ // window group id can be fetched.
+ HandlePropertyChange(KActiveIdleUid);
+ }
+ }
+ break;
+ case KActiveIdleUid:
+ {
+ TInt idleAppUid = 0;
+ TInt err = iTelephonyIdleUidProperty.Get(idleAppUid);
+ if(!err)
+ {
+ // Fetch the Idle application window group id.
+ TApaTaskList taskList(CEikonEnv::Static()->WsSession());
+ TApaTask task = taskList.FindApp(TUid::Uid(idleAppUid));
+ TInt wgId = task.WgId();
+
+ // Save the window group id to PubSub.
+ RProperty::Set(KPSUidAvkonInternal, KAknIdleAppWindowGroupId, wgId);
+ }
+ }
+ break;
+ default:
+ break;
+ };
+ }
+
+// -----------------------------------------------------------------------------
+// C++ constructor can NOT contain any code, that might leave.
+// -----------------------------------------------------------------------------
+//
+CPropertySubscriber::CPropertySubscriber(TCallBack aCallBack, RProperty& aProperty)
+ : CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CPropertySubscriber::~CPropertySubscriber()
+ {
+ Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// Starts to listen for changes.
+// -----------------------------------------------------------------------------
+//
+void CPropertySubscriber::Subscribe()
+ {
+ if (!IsActive())
+ {
+ iProperty.Subscribe(iStatus);
+ SetActive();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Stops listening for changes.
+// -----------------------------------------------------------------------------
+//
+void CPropertySubscriber::StopSubscribe()
+ {
+ Cancel();
+ }
+
+// -----------------------------------------------------------------------------
+// When active object fires, call callback and continue listening.
+// -----------------------------------------------------------------------------
+//
+void CPropertySubscriber::RunL()
+ {
+ if (iStatus.Int() == KErrNone)
+ {
+ iCallBack.CallBack();
+ Subscribe();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Cancel.
+// -----------------------------------------------------------------------------
+//
+void CPropertySubscriber::DoCancel()
+ {
+ iProperty.Cancel();
+ }
+
+// Actual entry point.
+LOCAL_C CApaApplication* NewApplication()
+ {
+ return new CAknCapServerApplication();
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ return EikStart::RunApplication(NewApplication);
+ }
+
+// End of file