uifw/AknGlobalUI/AknCapServer/src/AknEikSgcs.cpp
changeset 0 2f259fa3e83a
child 9 aabf2c525e0f
child 21 558113899881
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Server side implementation of AVKON System
       
    15 *                Graphics Coordinator.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "AknEikSgcs.h"
       
    21 #include <eikenv.h>
       
    22 #include "eiksrvsp.h"
       
    23 #include <AknSgcc.h>
       
    24 #include <aknenv.h>
       
    25 #include <AknDef.h>
       
    26 #include <aknappui.h>
       
    27 #include <e32property.h>
       
    28 #include <UikonInternalPSKeys.h>
       
    29 #include <avkondomainpskeys.h>
       
    30 #include <AknSettingCache.h>
       
    31 #include "AknCapServerEntry.h"
       
    32 #include <aknconsts.h>
       
    33 #include "winchangemonitor.h"
       
    34 #include "akncapserverdebug.h"
       
    35 #include "akncompaif.h"
       
    36 
       
    37 #include <AknsConstants.h>
       
    38 #include <AknsUtils.h>
       
    39 #include <AknIconUtils.h>
       
    40 #include <AknUtils.h>
       
    41 #include <aknlayoutscalable_avkon.cdl.h>
       
    42 #include "avkoninternalpskeys.h"
       
    43 #include <layoutmetadata.cdl.h>
       
    44 #include <AknTaskList.h>
       
    45 #ifdef RD_UI_TRANSITION_EFFECTS_LAYOUT_SWITCH
       
    46 #include <akntranseffect.h>
       
    47 #include <akntransitionutils.h>
       
    48 #endif
       
    49 
       
    50 #include <LayoutPack.cdl.h>
       
    51 #include <CdlRefs.h>
       
    52 const TInt KCdlEComInterfaceId = 0x101f8243;
       
    53 
       
    54 const TInt KLayoutChangeTimeout = 2000000; // 2s
       
    55 const TInt KWgStatesGranularity = 4;
       
    56 const TInt KRelinquishedThreadListGranularity = 4;
       
    57 const TInt KRemoveBlankDelay = 200000; // 0.2s
       
    58 // Drawing is slower when transparency is enabled. The time needs to be
       
    59 // big enough to account for slowest drawing application.
       
    60 const TInt KRemoveBlankDelayTransparency = 1500000; // 1.5s
       
    61 
       
    62 // 4s should be enough for foreground app's operations to complete.
       
    63 const TInt KRestoreThreadPriorityDelay = 4000000; 
       
    64 
       
    65 // Screensaver application UID
       
    66 const TUid KScreensaverAppUid = { 0x100056CF };
       
    67 
       
    68 // Read pass policy
       
    69 _LIT_SECURITY_POLICY_PASS(KPassReadPolicy);    
       
    70 
       
    71 // Policy requiring write device data capability.
       
    72 _LIT_SECURITY_POLICY_C1(KWriteDDPolicy, ECapabilityWriteDeviceData);
       
    73 
       
    74 enum TWgStateFlags
       
    75     {
       
    76     EWgStateFullScreen,
       
    77     EWgStatePartialForeground,
       
    78     EWgStateUnderstandsPartialForeground,
       
    79     EWgStateLegacyLayout,
       
    80     EWgStateOrientationSpecified,
       
    81     EWgStateOrientationLandscape
       
    82     };
       
    83 
       
    84 enum TSetLayoutBlankStep
       
    85 	{
       
    86 	ESetLayoutBlankBeforeLayoutLoad,
       
    87 	ESetLayoutBlankBetweenLayoutLoadAndScreenRotate,
       
    88 	ESetLayoutBlankAfterScreenRotate,
       
    89 	ESetLayoutBlankNever
       
    90 	};
       
    91 
       
    92 NONSHARABLE_CLASS(CAknSgcServerImpl) : public CAknSgcImpl
       
    93 	{
       
    94 public:
       
    95 	CAknSgcServerImpl(CEikSgcServer* aServer);
       
    96     void MoveApp(TInt aAppWindowGroupId, TSgcMoveAppToWhere aWhere);
       
    97     
       
    98 private:
       
    99 	CEikSgcServer* iServer;
       
   100 	};
       
   101 
       
   102 
       
   103 class CLayoutChangeCallBack : public CActive
       
   104     {
       
   105 public:
       
   106     CLayoutChangeCallBack(CEikSgcServer* aSgc);
       
   107     void ConstructL();
       
   108     ~CLayoutChangeCallBack();
       
   109     
       
   110     void RestartTimerL();
       
   111 
       
   112 private:
       
   113     void DoCancel();
       
   114     void RunL();
       
   115 
       
   116     static TInt ThreadFunc(TAny* aStat);
       
   117 
       
   118     static TInt TimeoutCallback(TAny* aThis);
       
   119     void DoTimeout();
       
   120 
       
   121 private:
       
   122     CEikSgcServer* iSgc;
       
   123     RThread iThread;
       
   124     TThreadId iMain;
       
   125     CPeriodic* iTimeout;
       
   126     };
       
   127 
       
   128 CLayoutChangeCallBack::CLayoutChangeCallBack(CEikSgcServer* aSgc)
       
   129 : CActive(CActive::EPriorityLow), iSgc(aSgc), iMain(RThread().Id())
       
   130     {
       
   131     CActiveScheduler::Add(this);
       
   132     }
       
   133 
       
   134 void CLayoutChangeCallBack::ConstructL()
       
   135     {
       
   136     // Create the thread.
       
   137     User::LeaveIfError(iThread.Create(KNullDesC, ThreadFunc, 0x400, NULL, this));
       
   138     iThread.SetPriority(EPriorityAbsoluteBackground);
       
   139     
       
   140     // Set the active status & start the thread.
       
   141     iStatus = KRequestPending;
       
   142     SetActive();
       
   143     iThread.Resume();
       
   144     
       
   145     RestartTimerL();
       
   146     }
       
   147     
       
   148 void CLayoutChangeCallBack::RestartTimerL()
       
   149     {
       
   150     delete iTimeout;
       
   151     iTimeout = NULL;
       
   152     iTimeout = CPeriodic::NewL(CActive::EPriorityStandard);
       
   153     iTimeout->Start(KLayoutChangeTimeout, KLayoutChangeTimeout, TCallBack(TimeoutCallback, this));
       
   154     }
       
   155 
       
   156 CLayoutChangeCallBack::~CLayoutChangeCallBack()
       
   157     {   
       
   158     Cancel();
       
   159     iThread.Close();
       
   160     delete iTimeout;
       
   161     }
       
   162 
       
   163 void CLayoutChangeCallBack::DoCancel()
       
   164     {
       
   165     iThread.Terminate(0);
       
   166     
       
   167     // Only complete the request if not yet completed by the background thread.
       
   168     if ( iStatus == KRequestPending )
       
   169         {
       
   170         TRequestStatus* pStatus = &iStatus;
       
   171         User::RequestComplete(pStatus, KErrCancel);     
       
   172         }
       
   173     }
       
   174 
       
   175 void CLayoutChangeCallBack::RunL()
       
   176     {
       
   177     iSgc->HandleLayoutChangeCallBackL();
       
   178     }
       
   179 
       
   180 
       
   181 // ---------------------------------------------------------------------------
       
   182 // CLayoutChangeCallBack::ThreadFunc
       
   183 // Thread entry point function.
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 TInt CLayoutChangeCallBack::ThreadFunc( TAny* aLayoutChangeCallBack )
       
   187     {
       
   188     CLayoutChangeCallBack* self =
       
   189         static_cast<CLayoutChangeCallBack*>(aLayoutChangeCallBack);
       
   190     RThread main;
       
   191     if (KErrNone == main.Open(self->iMain))
       
   192         {
       
   193         TRequestStatus* pStatus = &self->iStatus;
       
   194         main.RequestComplete(pStatus, KErrNone);
       
   195         main.Close();
       
   196         }
       
   197     return KErrNone;
       
   198     }
       
   199 
       
   200 TInt CLayoutChangeCallBack::TimeoutCallback( TAny* aThis )
       
   201     {
       
   202     static_cast<CLayoutChangeCallBack*>( aThis )->DoTimeout();
       
   203     return EFalse;
       
   204     }
       
   205     
       
   206 void CLayoutChangeCallBack::DoTimeout()
       
   207     {
       
   208     TRAP_IGNORE( iSgc->HandleLayoutChangeCallBackL() );
       
   209     }
       
   210 
       
   211 
       
   212 CEikSgcServer::TWgState::TWgState()
       
   213 : iWgId(0), iSpLayout(0), iSpFlags(0), iAppScreenMode(KAknScreenModeUnset)
       
   214     {
       
   215     // Default state for window groups is full screen - handles non
       
   216     // avkon apps.
       
   217     iFlags.Set(EWgStateFullScreen);
       
   218     }
       
   219 
       
   220 CEikSgcServer::TWgState::TWgState(TInt aWgId)
       
   221 : iWgId(aWgId), iSpLayout(0), iSpFlags(0), iAppScreenMode(KAknScreenModeUnset)
       
   222     {
       
   223     // Default state for window groups is full screen - handles non
       
   224     // avkon apps.
       
   225     iFlags.Set(EWgStateFullScreen);
       
   226     }
       
   227 
       
   228 inline TInt CEikSgcServer::TWgState::WgId() const
       
   229     {
       
   230     return iWgId;
       
   231     }
       
   232 
       
   233 inline void CEikSgcServer::TWgState::SetWgId(TInt aWgId)
       
   234     {
       
   235     iWgId = aWgId;
       
   236     }
       
   237 
       
   238 inline TInt CEikSgcServer::TWgState::SpLayout() const
       
   239     {
       
   240     return iSpLayout;
       
   241     }
       
   242 
       
   243 inline void CEikSgcServer::TWgState::SetSpLayout(TInt aSpLayout)
       
   244     {
       
   245     iSpLayout = aSpLayout;
       
   246     }
       
   247 
       
   248 inline TInt CEikSgcServer::TWgState::SpFlags() const
       
   249     {
       
   250     return iSpFlags;
       
   251     }
       
   252 
       
   253 inline void CEikSgcServer::TWgState::SetSpFlags(TInt aSpFlags)
       
   254     {
       
   255     iSpFlags = aSpFlags;
       
   256     }
       
   257 
       
   258 inline TBool CEikSgcServer::TWgState::IsFullScreen() const
       
   259     {
       
   260     return iFlags[EWgStateFullScreen];
       
   261     }
       
   262 
       
   263 inline void CEikSgcServer::TWgState::SetFullScreen(TBool aFullScreen)
       
   264     {
       
   265     iFlags.Assign(EWgStateFullScreen, aFullScreen);
       
   266     }
       
   267 
       
   268 inline TBool CEikSgcServer::TWgState::IsPartialForeground() const
       
   269     {
       
   270     return iFlags[EWgStatePartialForeground];
       
   271     }
       
   272 
       
   273 inline void CEikSgcServer::TWgState::SetPartialForeground(TBool aPartialForeground)
       
   274     {
       
   275     iFlags.Assign(EWgStatePartialForeground, aPartialForeground);
       
   276     }
       
   277 
       
   278 inline TBool CEikSgcServer::TWgState::UnderstandsPartialForeground() const
       
   279     {
       
   280     return iFlags[EWgStateUnderstandsPartialForeground];
       
   281     }
       
   282 
       
   283 inline void CEikSgcServer::TWgState::SetUnderstandsPartialForeground(TBool aPartialForeground)
       
   284     {
       
   285     iFlags.Assign(EWgStateUnderstandsPartialForeground, aPartialForeground);
       
   286     }
       
   287 
       
   288 inline TBool CEikSgcServer::TWgState::IsLegacyLayout() const
       
   289     {
       
   290     return iFlags[EWgStateLegacyLayout];
       
   291     }
       
   292 
       
   293 inline void CEikSgcServer::TWgState::SetLegacyLayout(TBool aLegacyLayout)
       
   294     {
       
   295     iFlags.Assign(EWgStateLegacyLayout, aLegacyLayout);
       
   296     }
       
   297 
       
   298 inline TBool CEikSgcServer::TWgState::IsOrientationSpecified() const
       
   299     {
       
   300     return iFlags[EWgStateOrientationSpecified];
       
   301     }
       
   302 
       
   303 inline void CEikSgcServer::TWgState::SetOrientationSpecified(TBool aOrientationSpecified)
       
   304     {
       
   305     iFlags.Assign(EWgStateOrientationSpecified, aOrientationSpecified);
       
   306     }
       
   307 
       
   308 inline TBool CEikSgcServer::TWgState::IsOrientationLandscape() const
       
   309     {
       
   310     return iFlags[EWgStateOrientationLandscape];
       
   311     }
       
   312 
       
   313 inline void CEikSgcServer::TWgState::SetOrientationLandscape(TBool aOrientationLandscape)
       
   314     {
       
   315     iFlags.Assign(EWgStateOrientationLandscape, aOrientationLandscape);
       
   316     }
       
   317 
       
   318 inline TInt CEikSgcServer::TWgState::AppScreenMode() const
       
   319     {
       
   320     return iAppScreenMode;
       
   321     }
       
   322 
       
   323 inline void CEikSgcServer::TWgState::SetAppScreenMode(TInt aAppScreenMode)
       
   324     {
       
   325     iAppScreenMode = aAppScreenMode;
       
   326     }
       
   327 
       
   328 CEikSgcServer* CEikSgcServer::NewL()
       
   329     {
       
   330     CEikSgcServer* self = new(ELeave) CEikSgcServer();
       
   331     CleanupStack::PushL(self);
       
   332     self->ConstructL();
       
   333     CleanupStack::Pop(self);
       
   334     return self;
       
   335     }
       
   336 
       
   337 CEikSgcServer::CEikSgcServer()
       
   338 : iWs(CEikonEnv::Static()->WsSession()),
       
   339   iLastScreenModeSet(-1), 
       
   340   iRelinquishedThreads(KRelinquishedThreadListGranularity),
       
   341   iSetLayoutBlankStep(ESetLayoutBlankBeforeLayoutLoad)
       
   342     {
       
   343     }
       
   344 
       
   345 void CEikSgcServer::ConstructL()
       
   346     {
       
   347     iWgStates = new(ELeave) CWgStates(KWgStatesGranularity);
       
   348     
       
   349     TInt err = RProperty::Define(KPSUidUikon, KUikPreferredOrientation, RProperty::EInt);
       
   350     User::LeaveIfError(err);
       
   351     
       
   352     err = RProperty::Define(
       
   353         KPSUidAvkonDomain, 
       
   354         KAknNotificationsInIdleAllowed, 
       
   355         RProperty::EInt,
       
   356         KPassReadPolicy,
       
   357         KWriteDDPolicy);
       
   358     User::LeaveIfError(err);
       
   359 #if FADE_BITMAP
       
   360 
       
   361 	err = RProperty::Define(KPSUidAvkonInternal, KAknFadeBitmapHandle,
       
   362 							RProperty::EInt,
       
   363 							KPassReadPolicy,
       
   364 							KWriteDDPolicy);
       
   365 	User::LeaveIfError(err);
       
   366 	err = RProperty::Define(KPSUidAvkonInternal, KAknFadeMaskHandle,
       
   367 							RProperty::EInt,
       
   368 							KPassReadPolicy,
       
   369 							KWriteDDPolicy);
       
   370 	User::LeaveIfError(err);
       
   371 #endif
       
   372 	
       
   373 	err = RProperty::Define(KPSUidAvkonInternal, KAknFadeColorHandle,
       
   374 							RProperty::EInt,
       
   375 							KPassReadPolicy,
       
   376 							KWriteDDPolicy);
       
   377 	User::LeaveIfError(err);
       
   378 
       
   379 	err = RProperty::Define(KPSUidAvkonInternal, KAknFadeBlackMapHandle,
       
   380 							RProperty::EInt,
       
   381 							KPassReadPolicy,
       
   382 							KWriteDDPolicy);
       
   383 	User::LeaveIfError(err);
       
   384 	err = RProperty::Define(KPSUidAvkonInternal, KAknFadeWhiteMapHandle,
       
   385 							RProperty::EInt,
       
   386 							KPassReadPolicy,
       
   387 							KWriteDDPolicy);
       
   388 	User::LeaveIfError(err);
       
   389 
       
   390 	
       
   391 		
       
   392     
       
   393 #ifndef TFX_USE_WCHANGE_EVENT
       
   394     iWinChange = CWindowChangeMonitor::NewL(iWs);
       
   395 #endif
       
   396 
       
   397 	CAknSgcServerImpl* sgcImpl = new(ELeave) CAknSgcServerImpl(this);
       
   398 	// CAknSgcClient takes ownership of sgcImpl and replaces
       
   399 	// existing client impl with it.
       
   400 	CAknSgcClient::SetImpl(sgcImpl);	
       
   401 
       
   402     // Touch compatibility mode
       
   403     iAvkonAppUiBase->MopGetObjectNoChaining(iTouchCompaModeIf);
       
   404     iTouchCompaScreenMode = KErrNotFound;
       
   405     if (iTouchCompaModeIf)
       
   406         {
       
   407         iTouchCompaScreenMode = iTouchCompaModeIf->FindCompaScreenMode();
       
   408         }
       
   409 
       
   410     // ECom notifier for ILD installations
       
   411 	TCallBack callback(CEikSgcServer::LayoutInstallationCallBack, this);
       
   412 	iLayoutNotifier = CEComPluginNotifier::NewL(KNullUid, callback);
       
   413 	iLayoutNotifier->Start();
       
   414 	EComPluginUtils::GetInfoArrayL(TUid::Uid(KCdlEComInterfaceId), iPrevPluginInfo);
       
   415     }
       
   416 
       
   417 TInt CEikSgcServer::LayoutInstallationCallBack(TAny* aPtr)
       
   418 	{
       
   419 	return ((CEikSgcServer*)aPtr)->RefreshLayoutIfRequiredL();
       
   420 	}
       
   421  
       
   422 TInt CEikSgcServer::RefreshLayoutIfRequiredL()
       
   423 	{
       
   424 	REComPluginInfoArray newPlugins;
       
   425 	EComPluginUtils::GetInfoArrayL(TUid::Uid(KCdlEComInterfaceId), newPlugins);
       
   426 	REComPluginInfoArray newPluginsCopy = newPlugins;
       
   427 	
       
   428 	// Remove any plugins that haven't changed from the arrays
       
   429 	TInt prevCount = iPrevPluginInfo.Count();
       
   430 	while(prevCount > 0)
       
   431 		{
       
   432 		prevCount--;
       
   433 		TUid prevUid = (iPrevPluginInfo[prevCount]).iUid;
       
   434 		TInt prevVer = (iPrevPluginInfo[prevCount]).iVersion;
       
   435 		TInt newCount = newPlugins.Count();
       
   436 		while(newCount > 0)
       
   437 			{
       
   438 			newCount--;
       
   439 			TUid newUid = (newPlugins[newCount]).iUid;
       
   440 			TInt newVer = (newPlugins[newCount]).iVersion;
       
   441 			if(prevUid == newUid && prevVer == newVer)
       
   442 				{
       
   443 				newPlugins.Remove(newCount);
       
   444 				iPrevPluginInfo.Remove(prevCount);
       
   445 				break;
       
   446 				}
       
   447 			}
       
   448 		}
       
   449 	
       
   450 	TBool refreshRequired = EFalse;
       
   451 	if(iPrevPluginInfo.Count() > 0)
       
   452 		{
       
   453 		// A plugin has been removed, but we can't check what it contained.
       
   454 		refreshRequired = ETrue;
       
   455 		}
       
   456 	else
       
   457 		{
       
   458 		// Check through the changed plugins to see whether any contain layout packs
       
   459 		_LIT(KLitDllPath, "%S%08x.dll");
       
   460 		const TInt KPathLength = 14;	// Drive letter + ":" + UID + ".dll"
       
   461 		for(TInt i=0; i<newPlugins.Count(); i++)
       
   462 			{
       
   463 			TEComPluginInfo imp = newPlugins[i];
       
   464 			TBuf<KPathLength> buf;
       
   465 			TDriveName drive(imp.iDrive.Name());
       
   466 			buf.Format(KLitDllPath, &drive, imp.iUid.iUid);
       
   467 			
       
   468 			CCdlRefCollection* refsInFile = CdlEngine::FileContentsLC(buf);
       
   469 			CCdlRefs* refs = CCdlRefs::NewLC();
       
   470 			refs->AppendL(*refsInFile);
       
   471 			CCdlRefs* layoutsInFile = refs->SubsetByUidLC(LayoutPack::KCdlInterfaceUid);
       
   472 			TInt numLayouts = layoutsInFile->CountRefs();
       
   473 			CleanupStack::PopAndDestroy(3, refsInFile);
       
   474 			
       
   475 			if(numLayouts > 0)
       
   476 				{
       
   477 				// Plugin added with layouts, refresh required
       
   478 				refreshRequired = ETrue;
       
   479 				break;
       
   480 				}
       
   481 			}
       
   482 		}
       
   483 
       
   484 	// Send the event if it's needed
       
   485 	TInt result = KErrNone;
       
   486 	if(refreshRequired)
       
   487 		{
       
   488 		RWsSession session;
       
   489 		TInt err = session.Connect();
       
   490         if ( err == KErrNone )
       
   491             {
       
   492             TWsEvent event;
       
   493             event.SetType(KAknILDInstallationLayoutSwitch);
       
   494             result = session.SendEventToAllWindowGroups(event);
       
   495             session.Close();
       
   496             }
       
   497 		}
       
   498 
       
   499 	// Store the copy of the new list of plugins for next time
       
   500 	iPrevPluginInfo.Reset();
       
   501 	iPrevPluginInfo = newPluginsCopy;
       
   502 	
       
   503 	return result;
       
   504     }
       
   505 
       
   506 CEikSgcServer::~CEikSgcServer()
       
   507     {
       
   508 	delete iFadeBitmap;
       
   509 	delete iFadeMask;
       
   510 
       
   511     delete iWinChange;
       
   512     delete iLayoutChangeCallBack;
       
   513     delete iWgStates;
       
   514     delete iRemoveBlankCallBack;
       
   515     delete iLayoutNotifier;
       
   516     }
       
   517 
       
   518 void CEikSgcServer::HandleWindowGroupListChangeL()
       
   519     {
       
   520     CWgIds* wgIds = CreateWgIdListLC();
       
   521     if (!TestWgListOrderOk(wgIds))
       
   522         {
       
   523         ReOrderWgStatesL(wgIds);
       
   524         PostChangeRecalcL();
       
   525         UpdateNotificationsInIdleAllowedKey();
       
   526         }
       
   527     CleanupStack::PopAndDestroy( wgIds );
       
   528     }
       
   529 
       
   530 void CEikSgcServer::HandleWindowGroupParamChangeL(TInt aWgId, TBitFlags aAppFlags, TInt aSpLayout, 
       
   531     TInt aSpFlags, TInt aAppScreenMode)
       
   532     {
       
   533     LOGTEXT0("CEikSgcServer::HandleWindowGroupParamChangeL - ENTER");
       
   534     
       
   535     TBool understandsPartialForegroundChanged = EFalse;
       
   536     TBool fullScreenChanged = EFalse;
       
   537     
       
   538     TWgState& state = GetWgStateL(aWgId);
       
   539 
       
   540     const TBool wasFullScreen = state.IsFullScreen();
       
   541     state.SetFullScreen(aAppFlags[CAknSgcClient::EFullScreen]);
       
   542     const TBool isFullScreen = state.IsFullScreen();
       
   543     
       
   544     state.SetLegacyLayout(aAppFlags[CAknSgcClient::ELegacyLayout]);
       
   545     state.SetSpLayout(aSpLayout);
       
   546     state.SetSpFlags(aSpFlags);
       
   547     
       
   548     // Check whether understands partial foreground is changed. 
       
   549     if (!state.UnderstandsPartialForeground())
       
   550         {
       
   551         understandsPartialForegroundChanged = ETrue;
       
   552         }
       
   553     state.SetUnderstandsPartialForeground(ETrue);
       
   554     
       
   555     state.SetOrientationSpecified(aAppFlags[CAknSgcClient::EOrientationSpecified]);
       
   556     state.SetOrientationLandscape(aAppFlags[CAknSgcClient::EOrientationLandscape]);
       
   557     state.SetAppScreenMode(aAppScreenMode);
       
   558     PostChangeRecalcL();
       
   559     
       
   560     // Check whether full screen mode has been changed.
       
   561     fullScreenChanged = (wasFullScreen && !isFullScreen) || (!wasFullScreen && isFullScreen);
       
   562     
       
   563     if (understandsPartialForegroundChanged || fullScreenChanged)
       
   564         {
       
   565         LOGTEXT1("  understandsPartialForegroundChanged: %d", understandsPartialForegroundChanged);
       
   566         LOGTEXT1("  fullScreenChanged: %d",                   fullScreenChanged);        
       
   567         
       
   568         UpdateNotificationsInIdleAllowedKey();
       
   569         }
       
   570     
       
   571     LOGTEXT0("CEikSgcServer::HandleWindowGroupParamChangeL - EXIT");
       
   572     }
       
   573 
       
   574 CEikSgcServer::TWgState& CEikSgcServer::GetWgStateL(TInt aWgId)
       
   575     {
       
   576     TInt index = WgStateIndex(aWgId);
       
   577     if (index == KErrNotFound)
       
   578         {
       
   579         iWgStates->AppendL(TWgState(aWgId));
       
   580         index = iWgStates->Count()-1;
       
   581         }
       
   582     return iWgStates->At(index);
       
   583     }
       
   584 
       
   585 TInt CEikSgcServer::WgStateIndex(TInt aWgId) const
       
   586     {
       
   587     TInt count = iWgStates->Count();
       
   588     for (TInt ii=0; ii<count; ii++)
       
   589         {
       
   590         if (iWgStates->At(ii).WgId() == aWgId)
       
   591             {
       
   592             return ii;
       
   593             }
       
   594         }
       
   595     return KErrNotFound;
       
   596     }
       
   597 
       
   598 CEikSgcServer::CWgIds* CEikSgcServer::CreateWgIdListLC() const
       
   599     {
       
   600     CWgIds* wgIds = new(ELeave) CWgIds(1);
       
   601     CleanupStack::PushL(wgIds);
       
   602     iWs.WindowGroupList(wgIds);
       
   603     return wgIds;
       
   604     }
       
   605 
       
   606 void CEikSgcServer::ReOrderWgStatesL(CWgIds* aWgIds)
       
   607     {
       
   608     CWgStates* newStates = new(ELeave) CWgStates(KWgStatesGranularity);
       
   609     CleanupStack::PushL(newStates);
       
   610     TInt count = aWgIds->Count();
       
   611     newStates->ResizeL(count);
       
   612     for (TInt ii=0; ii<count; ii++)
       
   613         {
       
   614         newStates->At(ii) = GetWgStateL(aWgIds->At(ii));
       
   615         }
       
   616     CleanupStack::Pop(newStates);
       
   617     delete iWgStates;
       
   618     iWgStates = newStates;
       
   619     }
       
   620 
       
   621 void CEikSgcServer::SetStatusPaneShapeAndFlagsL(TInt aSpIndex)
       
   622     {
       
   623     if (aSpIndex == KErrNotFound)
       
   624         {
       
   625         return;
       
   626         }
       
   627     TWgState& topState = iWgStates->At(aSpIndex);
       
   628 
       
   629     TInt layout = topState.SpLayout();
       
   630     if (iLayout != layout)
       
   631         {
       
   632         iSp->SwitchLayoutL(layout);
       
   633         iLayout = layout;
       
   634         }
       
   635 
       
   636     TInt flags = topState.SpFlags();
       
   637     if (iFlags != flags)
       
   638         {
       
   639         iSp->SetFlags(flags);
       
   640         iFlags = flags;
       
   641         }
       
   642     }
       
   643 
       
   644 #ifndef TFX_USE_WCHANGE_EVENT   
       
   645 void CEikSgcServer::ActivateEffectL()
       
   646     {
       
   647     if(iWinChange == NULL)
       
   648         {
       
   649         return; // nobody there
       
   650         }
       
   651     
       
   652 //  CWindowChangeMonitor::TWinGroupEvent event =
       
   653 //   iWinChange->WinGroupEvent();   
       
   654         
       
   655     const TInt index = FocusWgIndex();
       
   656     //WgStateIndex(iWinChange-> GetFocusWg());  
       
   657         
       
   658     const TInt focusWgIndex = index < 0 ? 0 : index;
       
   659     
       
   660     const TInt count = iWgStates->Count();
       
   661     
       
   662     for (TInt i = focusWgIndex; i < count; i++)
       
   663         {
       
   664         const TWgState& state = iWgStates->At(focusWgIndex);
       
   665         const TInt wgId = state.WgId();
       
   666     
       
   667         if(state.UnderstandsPartialForeground())
       
   668             {
       
   669             if(wgId != iFirstFullScreenWg)
       
   670                 {
       
   671                 iWinChange->WgChangeL(wgId);
       
   672                 }
       
   673 
       
   674             // Note that exits also for non fullscreen (unlike SetPartialForegroundStatusesL).
       
   675             return; 
       
   676             }   
       
   677         }
       
   678     }
       
   679 #endif
       
   680 
       
   681 void CEikSgcServer::SetPartialForegroundStatusesL()
       
   682     {
       
   683     TInt count = iWgStates->Count();
       
   684     TInt ii;
       
   685     TBool partialFg = EFalse;
       
   686     for (ii = FocusWgIndex(); ii < count; ii++)
       
   687         {
       
   688         TWgState& state = iWgStates->At(ii);
       
   689         if (state.UnderstandsPartialForeground())
       
   690             {
       
   691             if (partialFg)
       
   692                 {
       
   693                 SetWgPartialFg(state);
       
   694                 }
       
   695             if (!state.IsFullScreen())
       
   696                 {
       
   697                 partialFg = ETrue;
       
   698                 }
       
   699             else
       
   700                 {
       
   701                 // Notify first full-screen app that it is topmost application though does not 
       
   702                 // have kb focus.
       
   703                 if (iFirstFullScreenWg != iWgStates->At(ii).WgId() )
       
   704                     { 
       
   705                     // same event instance will be recycled for both of events...
       
   706                     TWsEvent event;
       
   707                     event.SetTimeNow();
       
   708                     
       
   709                     if (iFirstFullScreenWg) // notify old that it has lost its focus
       
   710                         {
       
   711                         event.SetType(KAknFullOrPartialForegroundLost); 
       
   712                         iWs.SendEventToWindowGroup(iFirstFullScreenWg, event);
       
   713                         }
       
   714                     
       
   715                     iFirstFullScreenWg = iWgStates->At(ii).WgId();
       
   716                     event.SetType(KAknFullOrPartialForegroundGained);
       
   717                     iWs.SendEventToWindowGroup(iFirstFullScreenWg, event);
       
   718                     }
       
   719                 break;                   
       
   720                 }
       
   721             }
       
   722         }
       
   723     for (++ii; ii<count; ii++)
       
   724         {
       
   725         TWgState& state = iWgStates->At(ii);
       
   726         if (state.UnderstandsPartialForeground())
       
   727             {
       
   728             ClearWgPartialFg(state);
       
   729             }
       
   730         }
       
   731         
       
   732 #ifndef TFX_USE_WCHANGE_EVENT   
       
   733     if(iWinChange != NULL)
       
   734         {
       
   735         iWinChange->SetWgL(iFirstFullScreenWg); 
       
   736         }
       
   737 #endif
       
   738     }
       
   739 
       
   740 void CEikSgcServer::PostChangeRecalcL()
       
   741     {
       
   742 #ifndef TFX_USE_WCHANGE_EVENT
       
   743     ActivateEffectL();
       
   744 #endif
       
   745 
       
   746     TInt topSp = TopSpIndex();
       
   747     SetLayoutL(topSp);
       
   748     SetStatusPaneShapeAndFlagsL(topSp);
       
   749     SetPartialForegroundStatusesL();
       
   750     }
       
   751 
       
   752 TBool CEikSgcServer::TestWgListOrderOk(CWgIds* aWgIds) const
       
   753     {
       
   754     TInt count = aWgIds->Count();
       
   755     if (count != iWgStates->Count())
       
   756         {
       
   757         return EFalse;
       
   758         }
       
   759     for (TInt ii = 0; ii < count; ii++)
       
   760         {
       
   761         if (aWgIds->At(ii) != iWgStates->At(ii).WgId())
       
   762             {
       
   763             return EFalse;
       
   764             }
       
   765         }
       
   766     return ETrue;
       
   767     }
       
   768 
       
   769 TInt CEikSgcServer::FocusWgIndex() const
       
   770     {
       
   771     TInt index = WgStateIndex(iWs.GetFocusWindowGroup());
       
   772     if (index == KErrNotFound)
       
   773         {
       
   774         index = 0;
       
   775         }
       
   776     return index;
       
   777     }
       
   778 
       
   779 void CEikSgcServer::SetWgPartialFg(TWgState& aWgState)
       
   780     {
       
   781     if (!aWgState.IsPartialForeground())
       
   782         {
       
   783         aWgState.SetPartialForeground(ETrue);
       
   784         }
       
   785     }
       
   786 
       
   787 void CEikSgcServer::ClearWgPartialFg(TWgState& aWgState)
       
   788     {
       
   789     if (aWgState.IsPartialForeground())
       
   790         {
       
   791         aWgState.SetPartialForeground(EFalse);
       
   792         }
       
   793     }
       
   794 
       
   795 void CEikSgcServer::SetStatusPane(CEikServStatusPane* aSp)
       
   796     {
       
   797     ASSERT(aSp);
       
   798     iSp = aSp;
       
   799     iSpWg = aSp->WindowGroup();
       
   800     }
       
   801 
       
   802 TInt CEikSgcServer::TopSpIndex(TInt aAfter) const
       
   803     {
       
   804     TInt count = iWgStates->Count();
       
   805     for (TInt topSp=aAfter+1; topSp<count; topSp++)
       
   806         {
       
   807         if (iWgStates->At(topSp).SpLayout())
       
   808             {
       
   809             return topSp;
       
   810             }
       
   811         }
       
   812     return KErrNotFound;
       
   813     }
       
   814 
       
   815 void CEikSgcServer::PrepareForAppExitL(TInt aWgId)
       
   816     {
       
   817     TInt topSp = TopSpIndex();
       
   818     if (topSp != KErrNotFound)
       
   819         {
       
   820         TWgState& topState = iWgStates->At(topSp);
       
   821         if (topState.WgId() == aWgId)
       
   822             {
       
   823             TInt focusWg = FocusWgIndex();
       
   824             if (focusWg != KErrNotFound && iWgStates->At(focusWg).IsPartialForeground())
       
   825                 { // we trust that wg order is valid at this point.
       
   826                 if ( focusWg < iWgStates->Count()-1 )
       
   827                     {
       
   828                     TWsEvent event;
       
   829                     event.SetType(EEventUser);
       
   830                     *(TApaSystemEvent*)(event.EventData())=EApaSystemEventBroughtToForeground;
       
   831                     event.SetTimeNow();
       
   832                     iWs.SendEventToWindowGroup(iWgStates->At(focusWg+1).WgId(), event);
       
   833                     }
       
   834                 }
       
   835                
       
   836             // remove the status pane from the exiting wg
       
   837             topState.SetSpLayout(0);
       
   838 
       
   839             // Set the status pane to the shape for the app below
       
   840             topSp = TopSpIndex(topSp);
       
   841             SetLayoutL(topSp);
       
   842             SetStatusPaneShapeAndFlagsL(topSp);
       
   843             if (iSp)
       
   844                 {
       
   845                 iSp->PrepareForAppExit();
       
   846                 }
       
   847             }
       
   848         }
       
   849     }
       
   850 
       
   851 #define FADE_COLOR_17 1
       
   852 //#define FADE_COLOR_TEXT 1
       
   853 
       
   854 inline TUint8 GetColorIntensity(TUint32 aColor)
       
   855 	{
       
   856 	// Separate R, G, B
       
   857 	register TUint32 r = (aColor >> 16) & 0xFF;
       
   858 	register TUint32 g = (aColor >> 8) & 0xFF;
       
   859 	register TUint32 b = (aColor) & 0xFF;
       
   860 	
       
   861 	// Calculate and return intensity
       
   862 	return TUint8( (r*306 + g*601 + b*117) >> 10 );
       
   863 	}
       
   864 
       
   865 void CEikSgcServer::FadeColorGenerationL()
       
   866 	{
       
   867 	MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
   868 	bool b = false;
       
   869 #if FADE_COLOR_17
       
   870 	TAknsItemID skinid = KAknsIIDQsnOtherColors; 
       
   871 	TRgb colorrgb; 
       
   872 	TInt err = AknsUtils::GetCachedColor(skin, colorrgb, skinid, 19-1); 
       
   873 	if (err != KErrNone)
       
   874 	{
       
   875 		colorrgb = TRgb(255,255,255,0);	
       
   876 
       
   877 		CFbsBitmap *bitmap=NULL, *mask=NULL;
       
   878 		TAknsItemID skinid = KAknsIIDQsnFrPopupCenter ; 
       
   879 		TRAP(err, AknsUtils::CreateIconL(skin, skinid, bitmap, mask, _L(""), -1, -1));
       
   880 		if (err == KErrNone)
       
   881 			{
       
   882 			TSize size(30,30);
       
   883 			AknIconUtils::DisableCompression(bitmap);
       
   884 			AknIconUtils::SetSize(bitmap, size, EAspectRatioNotPreserved);
       
   885 			TPoint point(15,15);
       
   886 
       
   887 			//TBuf8<4> buf;
       
   888 			//bitmap->GetScanLine(buf, point, 1, bitmap->DisplayMode());
       
   889 			//colorrgb = TRgb(buf[3], buf[2], buf[1], buf[0]);
       
   890 
       
   891 			//colorrgb.SetAlpha(buf[0]);
       
   892 			//colorrgb.SetBlue(buf[1]);
       
   893 			//colorrgb.SetGreen(buf[2]);
       
   894 			//colorrgb.SetRed(buf[3]);
       
   895 			bitmap->GetPixel(colorrgb, point);
       
   896 	
       
   897 			delete bitmap;
       
   898 			delete mask;
       
   899 			b=true;
       
   900 			}
       
   901 	}
       
   902 	TRgb blackmap, whitemap;
       
   903 	TInt err1 = AknsUtils::GetCachedColor(skin, blackmap, skinid, 17-1); 
       
   904 	TInt err2 = AknsUtils::GetCachedColor(skin, whitemap, skinid, 18-1); 
       
   905 
       
   906 	if (err1 != KErrNone) blackmap = TRgb(0,0,0,0);
       
   907 	if (err2 != KErrNone) whitemap = TRgb(255,255,255,0);
       
   908 
       
   909 	TInt blackcolor = (blackmap.Red()<<16) + (blackmap.Green()<<8) + blackmap.Blue();
       
   910 	TInt whitecolor = (whitemap.Red()<<16) + (whitemap.Green()<<8) + whitemap.Blue();
       
   911 
       
   912 	TInt blackmapint = GetColorIntensity(blackcolor);
       
   913 	TInt whitemapint = GetColorIntensity(whitecolor);
       
   914 
       
   915 #endif
       
   916 
       
   917 #if FADE_COLOR_TEXT
       
   918 	TAknsItemID skinid = KAknsIIDQsnOtherColors; 
       
   919 	TRgb colorrgb; 
       
   920 	TInt err = AknsUtils::GetCachedColor(skin, colorrgb, skinid, 17); 
       
   921 	if (err != KErrNone)
       
   922 		{
       
   923 
       
   924 		TAknsItemID skinid = KAknsIIDQsnTextColors ;
       
   925 		TInt err = AknsUtils::GetCachedColor(skin, colorrgb, skinid, EAknsCIQsnTextColorsCG19 ); 
       
   926 		}	
       
   927 	TInt blackmapint = 0;
       
   928 	TInt whitemapint = 255;
       
   929 #endif
       
   930 
       
   931 	TInt color = (colorrgb.Red()<<16) + (colorrgb.Green()<<8) + colorrgb.Blue();
       
   932 
       
   933 	if (b) 
       
   934 	{
       
   935 		TInt intensity = GetColorIntensity(color);
       
   936 		if (intensity < 127) 
       
   937 			{ // background color dark
       
   938 			blackmapint = 0;
       
   939 			whitemapint = 64;
       
   940 			color = 0xffffff;
       
   941 			}
       
   942 		else
       
   943 			{
       
   944 			blackmapint = 192;
       
   945 			whitemapint = 255;
       
   946 			color = 0xffffff;
       
   947 			}
       
   948 	}
       
   949 	RProperty::Set(KPSUidAvkonInternal, KAknFadeBlackMapHandle, blackmapint);
       
   950 	RProperty::Set(KPSUidAvkonInternal, KAknFadeWhiteMapHandle, whitemapint);
       
   951 	RProperty::Set(KPSUidAvkonInternal, KAknFadeColorHandle, color);
       
   952 	
       
   953 	}
       
   954 
       
   955 void CEikSgcServer::FadeBitmapGenerationL()
       
   956 	{
       
   957 #if FADE_BITMAP
       
   958 	//
       
   959 	// Generates bitmap and mask for fade wserv plugin and
       
   960 	// publishes them in publish&subscribe.
       
   961 	//
       
   962 	delete iFadeBitmap;
       
   963 	delete iFadeMask;
       
   964 	iFadeBitmap = NULL;
       
   965 	iFadeMask = NULL;
       
   966 
       
   967 	MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
   968 
       
   969 	TInt err= KErrNone;
       
   970 	if (!Layout_Meta_Data::IsLandscapeOrientation())
       
   971 		{
       
   972 		TAknsItemID skinid = KAknsIIDQgnGrafBgDimmingPrt; // TODO
       
   973 		TRAP(err, AknsUtils::CreateIconL(skin, skinid, iFadeBitmap, iFadeMask, _L(""), -1, -1));
       
   974 		}
       
   975 	else
       
   976 		{
       
   977 		TAknsItemID skinid = KAknsIIDQgnGrafBgDimmingLsc; // TODO
       
   978 		TRAP(err, AknsUtils::CreateIconL(skin, skinid, iFadeBitmap, iFadeMask, _L(""), -1, -1));
       
   979 		}
       
   980 	if (err != KErrNone)
       
   981 		{
       
   982 		TAknsItemID skinid = KAknsIIDQgnGrafBgDimming   ; // TODO
       
   983 		TRAP(err, AknsUtils::CreateIconL(skin, skinid, iFadeBitmap, iFadeMask, _L(""), -1, -1));
       
   984 		}
       
   985 
       
   986 	if (err == KErrNone)
       
   987 		{ // found from skins
       
   988 
       
   989 		TRect rect = TRect(0,0,0,0);
       
   990 		TAknLayoutRect r;
       
   991 		r.LayoutRect(rect, AknLayoutScalable_Avkon::Screen().LayoutLine());		
       
   992 		TSize size = r.Rect().Size();
       
   993 
       
   994 		AknIconUtils::SetSize(iFadeBitmap, size, EAspectRatioNotPreserved);
       
   995 
       
   996 
       
   997 		TInt bitmaphandle = iFadeBitmap->Handle();
       
   998 		TInt maskhandle = iFadeMask->Handle();
       
   999 		RProperty::Set(KPSUidAvkonInternal, KAknFadeBitmapHandle, bitmaphandle);
       
  1000 		RProperty::Set(KPSUidAvkonInternal, KAknFadeMaskHandle, maskhandle);
       
  1001 		}
       
  1002 #endif						   
       
  1003 	}
       
  1004 void CEikSgcServer::SetLayoutL(TInt aSpIndex)
       
  1005     {
       
  1006     if (aSpIndex == KErrNotFound)
       
  1007         {
       
  1008         return;
       
  1009         }
       
  1010 
       
  1011     TWgState& topState = iWgStates->At(aSpIndex);
       
  1012 
       
  1013     CEikonEnv* eikEnv = CEikonEnv::Static();
       
  1014     
       
  1015     CAknLayoutConfig::TScreenMode mode = CAknSgcClient::CalculateScreenMode(
       
  1016         ETrue, 
       
  1017         topState.IsOrientationSpecified(), 
       
  1018         topState.IsOrientationLandscape(), 
       
  1019         topState.AppScreenMode());
       
  1020         
       
  1021     TInt modeIndex = mode.ModeNumber();
       
  1022     TBool blank = iLastScreenModeSet != -1;
       
  1023     if (modeIndex != iLastScreenModeSet)
       
  1024         {
       
  1025 
       
  1026         // Touch compatibility mode. Disable transition effects if compa-mode
       
  1027         // application becomes foreground. Restore back in opposite case.
       
  1028         if (iTouchCompaModeIf)
       
  1029             {
       
  1030             // Disable or restore transition
       
  1031             iTouchCompaModeIf->DisableTransEffects(
       
  1032                 iTouchCompaScreenMode == modeIndex);
       
  1033             }
       
  1034 
       
  1035         TBool tfxOn = EFalse;
       
  1036 #ifdef RD_UI_TRANSITION_EFFECTS_LAYOUT_SWITCH    
       
  1037 		tfxOn = CAknTransitionUtils::TransitionsEnabled(
       
  1038 	            AknTransEffect::ELayoutswitchTransitionsOff );
       
  1039 	    if ( tfxOn )
       
  1040 	        {
       
  1041 	        iSetLayoutBlankStep = ESetLayoutBlankAfterScreenRotate;
       
  1042 	        }
       
  1043 	    else
       
  1044 	   	    {
       
  1045 	  		iSetLayoutBlankStep = ESetLayoutBlankBeforeLayoutLoad;
       
  1046 	   	    }
       
  1047 #endif
       
  1048 
       
  1049 		if (!tfxOn)
       
  1050 	    	eikEnv->WsSession().ClearAllRedrawStores();
       
  1051 		
       
  1052         // If AknNfySrv or EikSrv is displaying a global note,
       
  1053         // the screen blanker is allowed to stay on until it times
       
  1054         // out (like when AknCapSrv is displaying a note).
       
  1055         TInt blankCnt = 1;
       
  1056         if (IsGlobalNoteForeground())
       
  1057             {
       
  1058 		    // For some reason, AknNfySrv and EikSrv unblank twice on target hardware.
       
  1059 		    // therefore blank is done 3 times to allow it to remain on until timeout.
       
  1060             blankCnt += 2;
       
  1061             }
       
  1062 
       
  1063 		SetLayoutBlankScreenL(blank, ESetLayoutBlankBeforeLayoutLoad,
       
  1064 		    blankCnt);
       
  1065 
       
  1066         const TAknLayoutConfigScreenMode& modeRef = (const TAknLayoutConfigScreenMode&) mode;
       
  1067         TBool newLayoutLoaded = CAknEnv::Static()->LoadAknLayoutL(modeRef);
       
  1068 
       
  1069 		FadeBitmapGenerationL();
       
  1070 		FadeColorGenerationL();
       
  1071         SetLayoutBlankScreenL(blank, ESetLayoutBlankBetweenLayoutLoadAndScreenRotate);
       
  1072 
       
  1073  		if (tfxOn)
       
  1074 	    	eikEnv->WsSession().ClearAllRedrawStores();
       
  1075    	
       
  1076 		// if layout change is preemptive for app change, move the app here
       
  1077         DoMoveApp();
       
  1078         	
       
  1079         // Set wserv screen mode
       
  1080         iLastScreenModeSet = modeIndex;
       
  1081         eikEnv->ScreenDevice()->SetScreenMode(modeIndex);
       
  1082 
       
  1083 		SetLayoutBlankScreenL(blank, ESetLayoutBlankAfterScreenRotate,
       
  1084 		    blankCnt);
       
  1085 
       
  1086         // Set legacy mode in eiksrv app UI
       
  1087         iAvkonAppUiBase->SetLayoutAwareApp(!topState.IsLegacyLayout());
       
  1088 
       
  1089         // Start callback for handling new layout
       
  1090         if (newLayoutLoaded)
       
  1091             {
       
  1092             // Swap the screen blanker to update the foreground app's layout
       
  1093             if (blank && iSetLayoutBlankStep < ESetLayoutBlankAfterScreenRotate) 
       
  1094                 {
       
  1095                 iAknCapAppServerAppUi->SwapLayoutSwitchBlankScreenL();
       
  1096                 }
       
  1097 
       
  1098             CAknAppUi* appUi = static_cast<CAknAppUi*>(eikEnv->EikAppUi());
       
  1099             if (appUi->IsForeground())
       
  1100                 {
       
  1101                 for (; appUi; appUi = static_cast<CAknAppUi*>(appUi->ContainerAppUi()))
       
  1102                     {
       
  1103                     appUi->ReportResourceChangedToAppL(KEikDynamicLayoutVariantSwitch);
       
  1104                     }
       
  1105                 }
       
  1106                 
       
  1107             if (iLayoutChangeCallBack)
       
  1108                 {
       
  1109                 // Restart the app delay callback timer if another layout change has happened 
       
  1110                 // before it triggers.
       
  1111                 iLayoutChangeCallBack->RestartTimerL();
       
  1112                 }
       
  1113             else
       
  1114                 {
       
  1115                 iLayoutChangeCallBack = new(ELeave) CLayoutChangeCallBack(this);
       
  1116                 iLayoutChangeCallBack->ConstructL();
       
  1117                 }
       
  1118                 
       
  1119             // stop any existing timer to unblank the screen, iLayoutChangeCallBack will restart it
       
  1120             delete iRemoveBlankCallBack;
       
  1121             iRemoveBlankCallBack = NULL;
       
  1122             }
       
  1123         else
       
  1124             {
       
  1125             if (!iLayoutChangeCallBack && blank)
       
  1126                 {
       
  1127                 // The callback will not remove the screen blanker,
       
  1128                 // so remove it now.
       
  1129                 iBlankCount--;
       
  1130                 iAknCapAppServerAppUi->BlankScreenL(EFalse);
       
  1131                 }
       
  1132             }
       
  1133         }
       
  1134     }
       
  1135 
       
  1136 void CEikSgcServer::SetLayoutBlankScreenL(TBool aBlank, TInt aStep)
       
  1137 	{
       
  1138     // Use a screen blanker to hide the screen change
       
  1139     if (aBlank && aStep == iSetLayoutBlankStep)
       
  1140         {
       
  1141         // blank the screen and keep track of how many times it's been blanked
       
  1142         iBlankCount++;
       
  1143         iAknCapAppServerAppUi->BlankScreenL(ETrue, ETrue);
       
  1144         }
       
  1145 	}
       
  1146 
       
  1147 void CEikSgcServer::HandleLayoutChangeCallBackL()
       
  1148     {
       
  1149     // delete the active object
       
  1150     delete iLayoutChangeCallBack;
       
  1151     iLayoutChangeCallBack = NULL;   
       
  1152     
       
  1153     CEikonEnv* eikEnv = CEikonEnv::Static();
       
  1154     
       
  1155     // Report the layout change to the UI controls
       
  1156     for (CEikAppUi* appUi = eikEnv->EikAppUi(); appUi; appUi = appUi->ContainerAppUi())
       
  1157         {
       
  1158         appUi->ReportResourceChangedToAppL(KEikDynamicLayoutVariantSwitch);
       
  1159         }
       
  1160     
       
  1161     // if visible tasklist must be updated during layout change event
       
  1162     iAknCapAppServerAppUi->UpdateTaskListL( ETrue );
       
  1163     
       
  1164     // Remove any remaining screen blanker after a delay.
       
  1165     // Normally the foreground app will have removed all blanking
       
  1166     // before this function triggers. This is really just a backup
       
  1167     // in-case the app is behaving badly, or if some unfortuante
       
  1168     // timing has caused this function to trigger before the foreground app
       
  1169     // finished its redraw. The delay should give the foreground app
       
  1170     // sufficient time.
       
  1171     iRemoveBlankCount += iBlankCount;
       
  1172     iBlankCount = 0;
       
  1173     delete iRemoveBlankCallBack;
       
  1174     iRemoveBlankCallBack = NULL;
       
  1175     iRemoveBlankCallBack = CPeriodic::NewL(CActive::EPriorityLow);
       
  1176 
       
  1177     TInt removeBlankDelay = CAknEnv::Static()->TransparencyEnabled() ?
       
  1178         KRemoveBlankDelayTransparency : KRemoveBlankDelay;
       
  1179     
       
  1180     if(iAknCapAppServerAppUi->IsShortTimeGlobalNoteDisplaying())
       
  1181         {
       
  1182         removeBlankDelay = KRemoveBlankDelay;
       
  1183         }
       
  1184     
       
  1185     iRemoveBlankCallBack->Start(
       
  1186         removeBlankDelay,
       
  1187         removeBlankDelay,
       
  1188         TCallBack(RemoveBlankCallBack, this));
       
  1189     }
       
  1190 
       
  1191 void CEikSgcServer::RelinquishPriorityToForegroundAppL(const RMessage2& aMessage)
       
  1192     {
       
  1193     // get the client thread
       
  1194     SRelinquishedThread rel;
       
  1195     aMessage.ClientL(rel.iThread);
       
  1196     CleanupClosePushL(rel.iThread);
       
  1197     rel.iId = rel.iThread.Id();
       
  1198     rel.iPriority = rel.iThread.ProcessPriority();
       
  1199 
       
  1200     // reset the callback timer, ensure that failure does not stop existing timer
       
  1201     CPeriodic* newCallBack = CPeriodic::NewL(CActive::EPriorityStandard);
       
  1202     delete iRelinquishedThreadCallBack;
       
  1203     iRelinquishedThreadCallBack = newCallBack;
       
  1204     
       
  1205     iRelinquishedThreadCallBack->Start(
       
  1206         KRestoreThreadPriorityDelay, 
       
  1207         KRestoreThreadPriorityDelay, 
       
  1208         TCallBack(RestoreThreadPriorities, this));
       
  1209 
       
  1210     // look for an existing thread
       
  1211     TInt count = iRelinquishedThreads.Count();
       
  1212     TInt pos;
       
  1213     for ( pos = 0; pos < count; pos++ )
       
  1214         {
       
  1215         if (iRelinquishedThreads[pos].iId == rel.iId)
       
  1216             {
       
  1217             break;
       
  1218             }
       
  1219         }
       
  1220 
       
  1221     if (pos<count)
       
  1222         {
       
  1223         // thread is already recorded. Make sure it's background and stop
       
  1224         rel.iThread.SetProcessPriority(EPriorityBackground);
       
  1225         CleanupStack::PopAndDestroy(&rel.iThread);
       
  1226         }
       
  1227     else
       
  1228         {
       
  1229         // add thread to array
       
  1230         iRelinquishedThreads.AppendL(rel);
       
  1231         CleanupStack::Pop(&rel.iThread);
       
  1232          // set the thread to background priority when all recovery mechanisms are in place
       
  1233         rel.iThread.SetProcessPriority(EPriorityBackground);
       
  1234         }
       
  1235 
       
  1236     aMessage.Complete(KErrNone);
       
  1237     }
       
  1238 
       
  1239 TInt CEikSgcServer::RestoreThreadPriorities( TAny* aThis )
       
  1240     {
       
  1241     static_cast<CEikSgcServer*>( aThis )->DoRestoreThreadPriorities();
       
  1242     return EFalse;
       
  1243     }
       
  1244 
       
  1245 void CEikSgcServer::DoRestoreThreadPriorities()
       
  1246     {
       
  1247     delete iRelinquishedThreadCallBack;
       
  1248     iRelinquishedThreadCallBack = NULL;
       
  1249     TInt count = iRelinquishedThreads.Count();
       
  1250     for (TInt ii=0; ii<count; ii++)
       
  1251         {
       
  1252         SRelinquishedThread& rel = iRelinquishedThreads[ii];
       
  1253         rel.iThread.SetProcessPriority(rel.iPriority);
       
  1254         rel.iThread.Close();
       
  1255         }
       
  1256     iRelinquishedThreads.Reset();
       
  1257     }
       
  1258 
       
  1259 void CEikSgcServer::SetAknCapAppServerAppUi(CAknCapAppServerAppUi* aAknCapAppServerAppUi)
       
  1260     {
       
  1261     iAknCapAppServerAppUi = aAknCapAppServerAppUi;      
       
  1262     }
       
  1263 
       
  1264 void CEikSgcServer::RotateScreenL()
       
  1265     {
       
  1266     // Toggle preferred orientation
       
  1267     TInt orientation;
       
  1268     TInt err = RProperty::Get(KPSUidUikon, KUikPreferredOrientation, orientation);
       
  1269     User::LeaveIfError(err);
       
  1270     
       
  1271     if (orientation == EPreferredOrientationNormal)
       
  1272         {
       
  1273         orientation = EPreferredOrientationAlternate;
       
  1274         }
       
  1275     else // alternate screen orientation
       
  1276         {
       
  1277         orientation = EPreferredOrientationNormal;
       
  1278         }
       
  1279 
       
  1280     err = RProperty::Set(KPSUidUikon, KUikPreferredOrientation, orientation);
       
  1281     User::LeaveIfError(err);
       
  1282 
       
  1283     CWsScreenDevice* device = CEikonEnv::Static()->ScreenDevice();
       
  1284     TInt screenMode = device->CurrentScreenMode();
       
  1285 
       
  1286     CEikonEnv* eikEnv = CEikonEnv::Static();
       
  1287     
       
  1288     // Update the setting cache and get SGCS to process the screen mode
       
  1289     // change, this may broadcast a screen device change to the apps,
       
  1290     // to inform them of the update
       
  1291     CAknEnv::Static()->SettingCache().Update( KAknHardwareLayoutSwitch );
       
  1292     HandleWindowGroupParamChangeL(
       
  1293         eikEnv->RootWin().Identifier(),
       
  1294         0,
       
  1295         0,
       
  1296         0,
       
  1297         KAknScreenModeUnset );
       
  1298 
       
  1299     if (screenMode == device->CurrentScreenMode())
       
  1300         {
       
  1301         // Apps will not have received a screen device changed event
       
  1302         // so send a KAknHardwareLayoutSwitch to the apps to ensure
       
  1303         // they get to know about the key
       
  1304         TWsEvent event;
       
  1305         event.SetType(KAknHardwareLayoutSwitch);
       
  1306         event.SetHandle(0);
       
  1307         eikEnv->WsSession().SendEventToAllWindowGroups( 0, event );
       
  1308         }
       
  1309     }
       
  1310 
       
  1311 void CEikSgcServer::UpdateNotificationsInIdleAllowedKey()
       
  1312     {
       
  1313     // First, get screensaver window group identifier.
       
  1314     TApaTaskList taskList(CEikonEnv::Static()->WsSession());
       
  1315     const TApaTask screensaverTask = taskList.FindApp(KScreensaverAppUid);
       
  1316     const TInt screensaverWgId = screensaverTask.WgId();
       
  1317     
       
  1318     // Get also idle window group identifier.
       
  1319     TVwsViewId idleView;
       
  1320     if (AknDef::GetPhoneIdleViewId(idleView) != KErrNone)
       
  1321         {
       
  1322         return;
       
  1323         }
       
  1324         
       
  1325     const TApaTask idleTask = taskList.FindApp(idleView.iAppUid);
       
  1326     const TInt idleWgId = idleTask.WgId();
       
  1327     
       
  1328     // Then go through window groups skipping partial apps and screensaver - 
       
  1329     // check if idleWgId follows.
       
  1330     TBool result = EFalse;
       
  1331     TBool found = EFalse;
       
  1332     const TInt wgCount = iWgStates->Count();
       
  1333     TInt ii = FocusWgIndex();
       
  1334         
       
  1335     LOGTEXT0("======================================");
       
  1336     LOGTEXT1("Window groups: %d",      wgCount);
       
  1337     LOGTEXT1("Idle wg id: %d",         idleWgId);
       
  1338     LOGTEXT1("Screensaver wg id: %d",  screensaverWgId);
       
  1339     LOGTEXT1("Focus window group: %d", ii);
       
  1340     LOGTEXT0("======================================");
       
  1341                 
       
  1342     // Loops window groups from top to bottom, starting from focus window group.
       
  1343     // (Index 0 contains the foreground window group.)
       
  1344     while (ii < wgCount && !found)
       
  1345         {
       
  1346         const TWgState& state = iWgStates->At(ii);
       
  1347         const TInt currentWgId = state.WgId();
       
  1348         
       
  1349         LOGTEXT0("\n");
       
  1350         LOGTEXT1("  Window group id: %d",              currentWgId);
       
  1351         LOGTEXT1("  UnderstandsPartialForeground: %d", state.UnderstandsPartialForeground());
       
  1352         LOGTEXT1("  IsFullScreen: %d",                 state.IsFullScreen());
       
  1353         
       
  1354         // Ignores non-application window groups (e.g. incall bubble), partial screen
       
  1355         // applications and screensaver. 
       
  1356         if (state.UnderstandsPartialForeground() &&
       
  1357             state.IsFullScreen()                 && 
       
  1358             currentWgId != screensaverWgId)        
       
  1359             {
       
  1360             // Check if current app is idle.
       
  1361             result = (idleWgId == currentWgId);
       
  1362             found = ETrue;
       
  1363             
       
  1364             LOGTEXT0("\n");
       
  1365             LOGTEXT1("Window group found. Result: %d", result);
       
  1366             }
       
  1367             
       
  1368         ii++;
       
  1369         }
       
  1370         
       
  1371     // Update the P&S key only if the value has been changed.
       
  1372     if ((iNotificationsInIdleAllowed && !result) || (!iNotificationsInIdleAllowed && result))
       
  1373         {
       
  1374         iNotificationsInIdleAllowed = result;
       
  1375         RProperty::Set(KPSUidAvkonDomain, KAknNotificationsInIdleAllowed, result);
       
  1376         }
       
  1377     } 
       
  1378     
       
  1379 
       
  1380 TInt CEikSgcServer::RemoveBlankCallBack( TAny* aThis )
       
  1381     {
       
  1382     static_cast<CEikSgcServer*>( aThis )->DoRemoveBlank();
       
  1383     return EFalse;
       
  1384     }
       
  1385 
       
  1386 void CEikSgcServer::DoRemoveBlank()
       
  1387     {
       
  1388     // remove any remaining screen blanker
       
  1389     for (; iRemoveBlankCount>0; iRemoveBlankCount--)
       
  1390         {
       
  1391         TRAP_IGNORE( iAknCapAppServerAppUi->BlankScreenL( EFalse ) );
       
  1392         }
       
  1393         
       
  1394     iRemoveBlankCount = 0;
       
  1395     
       
  1396     // readjust the status pane wg since we pushed it forward with the screen blanker
       
  1397     iLastTopSpWg = -1;
       
  1398 
       
  1399     delete iRemoveBlankCallBack;
       
  1400     iRemoveBlankCallBack = NULL;
       
  1401     }
       
  1402 
       
  1403 void CEikSgcServer::SetLayoutBlankScreenL(TBool aBlank, TInt aStep,
       
  1404     TInt aCnt)
       
  1405     {
       
  1406     while(aCnt--)
       
  1407         {
       
  1408         SetLayoutBlankScreenL(aBlank, aStep);
       
  1409         }
       
  1410     }
       
  1411 
       
  1412 // Check if AknNfySrv or EikSrv is displaying a global note
       
  1413 TBool CEikSgcServer::IsGlobalNoteForeground()
       
  1414     {
       
  1415     TBool isForeground = EFalse;
       
  1416     TThreadId threadId;
       
  1417     if (iWs.GetWindowGroupClientThreadId(iWs.GetFocusWindowGroup(),
       
  1418         threadId) == KErrNone)
       
  1419         {
       
  1420         RThread thread;
       
  1421         if (thread.Open(threadId) == KErrNone)
       
  1422             {
       
  1423             TSecureId secId = thread.SecureId();
       
  1424             thread.Close();
       
  1425             const TUid KEikSrvUid = {0x10003a4a};
       
  1426             isForeground =
       
  1427                 secId.iId == KCommonNotifierAppSrvUid.iUid ||
       
  1428                 secId.iId == KEikSrvUid.iUid;
       
  1429             }
       
  1430         }
       
  1431     return isForeground;
       
  1432     }
       
  1433 
       
  1434 void CEikSgcServer::MoveAppL(TInt aAppWindowGroupId, TSgcMoveAppToWhere aWhere)
       
  1435 	{
       
  1436 	CAknTaskList* taskList = CAknTaskList::NewLC(iWs);
       
  1437 	
       
  1438 	// step 1: Find root (going to foreground) or tip (going to background) of 
       
  1439 	// aAppWindowGroupId's window group chain
       
  1440 	TInt wgId = aAppWindowGroupId;
       
  1441 	for (TInt next=wgId; next;)
       
  1442 		{
       
  1443 		wgId = next;
       
  1444 		next = (aWhere == ESgcMoveAppToForeground) ?
       
  1445 			taskList->FindParentWgId(wgId) :
       
  1446 			taskList->FindChildWgId(wgId);
       
  1447 		}
       
  1448 	
       
  1449 	// step 2: Move whole window group chain
       
  1450 	while (wgId)
       
  1451 		{
       
  1452 		// move the window group
       
  1453 	    TInt index = WgStateIndex(wgId);
       
  1454 	    if (index >= 0)
       
  1455 	    	{
       
  1456 		    TWgState state = iWgStates->At(index);
       
  1457 		    iWgStates->Delete(index);
       
  1458 			if (aWhere == ESgcMoveAppToForeground)
       
  1459 				iWgStates->InsertL(0, state);
       
  1460 			else
       
  1461 				iWgStates->AppendL(state);
       
  1462 	    	}
       
  1463 		
       
  1464 		// get the next window group in the chain
       
  1465 		wgId = (aWhere == ESgcMoveAppToForeground) ?
       
  1466 			taskList->FindChildWgId(wgId) :
       
  1467 			taskList->FindParentWgId(wgId);
       
  1468 		}
       
  1469 		
       
  1470 	CleanupStack::PopAndDestroy(taskList);
       
  1471 	
       
  1472 	// Step 3: do screen rotation and move app
       
  1473 	iMoveAppWdId = aAppWindowGroupId;
       
  1474 	iMoveAppWhere = aWhere;
       
  1475 	
       
  1476     PostChangeRecalcL();
       
  1477     
       
  1478     // if no layout switch occured, move app here
       
  1479     DoMoveApp();
       
  1480    	}
       
  1481 
       
  1482 void CEikSgcServer::DoMoveApp()
       
  1483 	{
       
  1484     if (iMoveAppWdId)
       
  1485     	{
       
  1486 		TApaTask task(iWs);
       
  1487 		task.SetWgId(iMoveAppWdId);
       
  1488 		if (iMoveAppWhere == ESgcMoveAppToForeground)
       
  1489 			task.BringToForeground();
       
  1490 		else
       
  1491 			task.SendToBackground();	
       
  1492 		iMoveAppWdId = 0;
       
  1493     	}
       
  1494 	}
       
  1495 
       
  1496 
       
  1497 //
       
  1498 // CAknSgcServerImpl
       
  1499 //
       
  1500 CAknSgcServerImpl::CAknSgcServerImpl(CEikSgcServer* aServer)
       
  1501 : iServer(aServer)
       
  1502 	{
       
  1503 	}
       
  1504 
       
  1505 void CAknSgcServerImpl::MoveApp(TInt aAppWindowGroupId, TSgcMoveAppToWhere aWhere)
       
  1506 	{
       
  1507 	TRAP_IGNORE(iServer->MoveAppL(aAppWindowGroupId, aWhere));
       
  1508 	}
       
  1509 
       
  1510 // End of file