uifw/AvKon/akncompamode/src/akncompautils.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/akncompamode/src/akncompautils.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,402 @@
+/*
+* Copyright (c) 2007-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:  Compatibility mode utility functions
+*
+*/
+
+
+#include <e32base.h>
+#include <data_caging_path_literals.hrh>
+#include <barsread.h>
+#include <bautils.h>
+#include <aknappui.h>
+#include <coemop.h>
+#include <AknScreenMode.h>
+#include <AknSgcc.h>
+#include <AknCapServerDefs.h>
+#include <AknNotifierWrapperDefs.h>
+#include <centralrepository.h>
+#include <AvkonInternalCRKeys.h>
+#include <pslninternalcrkeys.h>
+
+#include <akncompamode.rsg>
+
+#include "akncompautils.h"
+#include "akncompakb.h"
+#include "akncompabutton.h"
+#include "akncompaclearer.h"
+#include "akncompaflags.h"
+
+// Class to detect a console application via MopGetObject
+class MConsoleApp
+    {
+public:
+    DECLARE_TYPE_ID(0x2001b26a)
+    };
+
+// --------------------------------------------------------------------------
+// Determine if app requires compa-mode and set to compa screen
+// mode if so
+// --------------------------------------------------------------------------
+TInt AknCompaUtils::SetCompaAppScreenModeL(TBool& aScrModeChanged,
+    TBool& aIsConsoleApp, CAknCompaClearer*& aClearer, TInt aAppUiFlags,
+    CAknAppUiBase& aAppUi, const CCoeEnv& aCoeEnv, CRepository& aRepository)
+    {
+    // Change application screen mode before a call to BaseConstructL().
+    // This prevents HandleResourceChangeL() to be called before application
+    // views have been constructed.
+
+    aScrModeChanged = EFalse;
+    aIsConsoleApp = IsConsoleApp(aAppUi);
+    aClearer = NULL;
+    TInt screenMode = KErrNotFound;
+
+    TInt configFlags = 0;
+    aRepository.Get(KAknCompaModeSettings, configFlags);
+
+    // Before CAknAppUi::BaseConstructL(), current screen mode is the
+    // same as the application that starts the current application.
+    TCompaAppCheckResult result =
+        IsCompaModeAppL(aIsConsoleApp, configFlags, aAppUiFlags,
+        aCoeEnv);
+    if (result == ECompaCheckResultYes)
+        {
+        screenMode = FindCompaScreenMode();
+        if (screenMode != KErrNotFound)
+            {
+            // Clear whole screen with a skin backround before
+            // screen mode changes
+            CAknCompaClearer* clearer = CAknCompaClearer::NewLC();
+
+            SetAppScreenModeL(aAppUi, screenMode);
+            aScrModeChanged = ETrue;
+            CleanupStack::Pop(); // clearer
+            aClearer = clearer; // transfer ownership
+            }
+        }
+    else if (InGlobalUiSrv(aAppUiFlags))
+        {
+        // Current process is a server that may display global
+        // notes/notifications. Return compa screen mode but don't
+        // set it as current mode.
+        screenMode = FindCompaScreenMode();
+        }
+    return screenMode;
+    }
+
+// --------------------------------------------------------------------------
+// Find compatibility screen mode
+// --------------------------------------------------------------------------
+TInt AknCompaUtils::FindCompaScreenMode()
+    {
+    // Look for screen mode style name QVGACOMPA
+    const TInt KNameHash = 0xA786E9F3;
+    CAknLayoutConfig::TScreenModeArray scrModeArray =
+        CAknSgcClient::LayoutConfig().ScreenModes();
+    TInt nModes = scrModeArray.Count();
+    TInt mode = KErrNotFound;
+    for(TInt i = 0; i < nModes && mode == KErrNotFound; i++)
+        {
+        if (scrModeArray.At(i).ScreenStyleHash() == KNameHash)
+            {
+            mode = i;
+            }
+        }
+    return mode;
+    }
+
+// --------------------------------------------------------------------------
+// Check if process is a server that displays global
+// notes/notifications (Eikon server, Avkon notify and cap servers)
+// --------------------------------------------------------------------------
+TBool AknCompaUtils::IsGlobalUiSrv(TSecureId aSecureId)
+    {
+    return IsAknCapSrv(aSecureId) ||
+        aSecureId.iId == KCommonNotifierAppSrvUid.iUid ||
+        IsEikSrv(aSecureId);
+    }
+
+// --------------------------------------------------------------------------
+// Check if process is eikon server
+// --------------------------------------------------------------------------
+TBool AknCompaUtils::IsEikSrv(TSecureId aSecureId)
+    {
+    const TUid KEikSrvUid = {0x10003a4a};
+    return aSecureId.iId == KEikSrvUid.iUid;
+    }
+
+// --------------------------------------------------------------------------
+// Check if process is AknCap server
+// --------------------------------------------------------------------------
+TBool AknCompaUtils::IsAknCapSrv(TSecureId aSecureId)
+    {
+    return aSecureId.iId == KAknCapServerUid.iUid;
+    }
+
+// --------------------------------------------------------------------------
+// Read and create buttons from a resource file
+// --------------------------------------------------------------------------
+void AknCompaUtils::ReadButtonsL(RPointerArray<CAknCompaButton>& aButtons,
+    TInt& aPenButton, CCoeEnv& aCoeEnv)
+    {
+    RResourceFile resFile;
+    AknCompaUtils::OpenResourceFileLC(resFile, aCoeEnv.FsSession());
+
+    // Add localized text resource to CoeEnv
+    TInt textResFileOffs = AddTextResourceFileL(aCoeEnv);
+
+    // Read button resources
+    HBufC8* buff = resFile.AllocReadLC(R_COMPAMODE_BUTTONS);
+    TResourceReader reader;
+    reader.SetBuffer(buff);   
+
+    TInt buttonFlags(reader.ReadInt16());
+    TInt numButtons(reader.ReadInt16());
+
+    aPenButton = KErrNotFound;
+    for(TInt i = 0; i < numButtons; i++)
+        {
+        // Create button
+        CAknCompaButton* button = CAknCompaButton::NewLC(reader);
+
+        if (button->ScanCode() != EStdKeyRightShift)
+            {
+            // Set flags for button
+            button->SetButtonFlags(buttonFlags);
+            }
+        else
+            {
+            // Enable long press event for "pen" button
+            button->SetButtonFlags(buttonFlags + KAknButtonReportOnLongPress);
+            aPenButton = i;
+            }
+
+        aButtons.AppendL(button);
+
+        CleanupStack::Pop(); // button
+        }  
+
+    aCoeEnv.DeleteResourceFile(textResFileOffs);
+
+    CleanupStack::PopAndDestroy(2); // buff, resFile
+    }
+
+// --------------------------------------------------------------------------
+// Open compamode resource file
+// --------------------------------------------------------------------------
+void AknCompaUtils::OpenResourceFileLC(RResourceFile& aResourceFile,
+    RFs& aFsSession)
+    {
+    _LIT(KResourceFileName, "z:akncompamode.rsc");
+
+    TParse parse;
+    parse.Set(KResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL);
+    TFileName fileName(parse.FullName());
+    aResourceFile.OpenL(aFsSession, fileName);
+
+    CleanupClosePushL(aResourceFile);
+    aResourceFile.ConfirmSignatureL();
+    }
+
+// --------------------------------------------------------------------------
+// Add compamode localized text resource file into CoeEnv
+// --------------------------------------------------------------------------
+TInt AknCompaUtils::AddTextResourceFileL(CCoeEnv& aCoeEnv)
+    {
+    _LIT(KResourceFileName, "z:akncomparesources.rsc");
+
+    TParse parse;
+    parse.Set(KResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL);
+    TFileName fileName(parse.FullName());
+
+    BaflUtils::NearestLanguageFile(aCoeEnv.FsSession(), fileName);
+    return aCoeEnv.AddResourceFileL(fileName);
+    }
+
+// --------------------------------------------------------------------------
+// Wait for effects to go into disabled state
+// --------------------------------------------------------------------------
+void AknCompaUtils::WaitTransEffectsOff(CRepository& aThemesCenRep)
+    {
+    const TInt KTick = 10000; // 10 ms
+    const TInt KMaxWait = 100;
+
+    // There could be a timing issue between CenRep variable change and
+    // when tfx server actually disables the effects. Tested following loop
+    // with a busy wait and there were no problems. So timing doesn't seem
+    // to matter. It would be better of course if tfx server
+    // would provide a feedback when effects actually are disabled.
+    TInt effects;
+    for(TInt i = 0; i < KMaxWait; i++)
+        {
+        aThemesCenRep.Get(KThemesTransitionEffects, effects);
+        if (effects == KAknCompaModeEffectsDisabled)
+            {
+            return;
+            }
+        User::After(KTick);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Panic application
+// --------------------------------------------------------------------------
+void AknCompaUtils::Panic(TInt aCode)
+    {
+    _LIT(KCategory, "Compamode");
+    User::Panic(KCategory, aCode);
+    }
+
+// --------------------------------------------------------------------------
+// Scale rectangle to correct size and move it if necessary.
+// --------------------------------------------------------------------------
+void AknCompaUtils::ScaleRect(TRect& aRect, TInt aMoveX, TInt aMoveY)
+    {    
+    aRect.iTl.iY = (aRect.iTl.iY * 2);
+    aRect.iBr.iY = (aRect.iBr.iY * 2);
+
+    TInt bX = aRect.iBr.iX;
+    TInt tmp = bX / 2;
+    aRect.iBr.iX = ((bX * 2) - tmp);
+
+    TInt tX = aRect.iTl.iX;
+    tmp = tX / 2;
+    aRect.iTl.iX = ((tX * 2) - tmp);
+    
+    if(aMoveX != 0 || aMoveY != 0)
+        {
+        aRect.Move(aMoveX, aMoveY);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Set application screen mode
+// --------------------------------------------------------------------------
+void AknCompaUtils::SetAppScreenModeL(CAknAppUiBase& aAppUi, TInt aMode)
+    {
+    TAknScreenModes scrModes = TAknScreenModes::GetModes();
+    TAknScreenModes::SetAppUiScreenModeL(&aAppUi, scrModes[aMode]);
+    }
+
+// --------------------------------------------------------------------------
+// Read a vector of integers from a resource file
+// --------------------------------------------------------------------------
+void AknCompaUtils::ReadIntegerResourceL(RArray<TInt>& aArray,
+        const RResourceFile& aResourceFile, TInt aResId)
+    {
+    HBufC8* buff = aResourceFile.AllocReadLC(aResId);
+
+    TResourceReader resReader;
+    resReader.SetBuffer(buff);
+
+    aArray.Reset();
+    TInt cnt = resReader.ReadInt16();
+    while(cnt--)
+        {
+        aArray.AppendL(resReader.ReadInt32());
+        }
+    CleanupStack::PopAndDestroy(); // buff
+    }
+
+// --------------------------------------------------------------------------
+// Check if application requires a compatibility mode
+// --------------------------------------------------------------------------
+AknCompaUtils::TCompaAppCheckResult AknCompaUtils::IsCompaModeAppL(
+    TBool aIsConsoleApp, TInt aConfigFlags, TInt aAppUiFlags,
+    const CCoeEnv& aCoeEnv)
+    {
+    if ((aAppUiFlags & CAknAppUiBase::EAknTouchCompatible) ||
+        (aAppUiFlags & CEikAppUi::ENoScreenFurniture && !aIsConsoleApp) ||
+        (aConfigFlags & KAknCompaSettingEnaApps) == 0)
+        {
+        return ECompaCheckResultNo;
+        }
+
+    RResourceFile resFile;
+    OpenResourceFileLC(resFile, aCoeEnv.FsSession());
+
+    RProcess process;
+    TSecureId secureId = process.SecureId();
+
+    TCompaAppCheckResult appCheckResult = ECompaCheckResultUndefinite;
+
+    RArray<TInt> array;
+    CleanupClosePushL(array);
+    // Application is not put into compa-mode if it is in non compa-mode list
+    ReadIntegerResourceL(array, resFile, R_COMPAMODE_NON_COMPA_APPS);
+    if (array.Find(secureId.iId) != KErrNotFound)
+        {
+        appCheckResult = ECompaCheckResultNo;
+        }
+    if (appCheckResult == ECompaCheckResultUndefinite)
+        {
+        // Application is put into compa-mode if it is in compa-mode list
+        ReadIntegerResourceL(array, resFile, R_COMPAMODE_COMPA_APPS);
+        if (array.Find(secureId.iId) != KErrNotFound)
+            {
+            appCheckResult = ECompaCheckResultYes;
+            }
+        }
+
+    if (appCheckResult == ECompaCheckResultUndefinite)
+        {
+        // By default, all applications included in a rom image are
+        // not put into compa-mode. Unless overriden by a flag or if
+        // the app. is a console application.
+        TFileName fileName = process.FileName();
+        _LIT(KRomDrive,"z:");
+        if (fileName.FindF(KRomDrive) == 0)
+            {
+            appCheckResult =
+                aConfigFlags & KAknCompaSettingEnaRomApps || aIsConsoleApp ?
+                ECompaCheckResultYes:ECompaCheckResultNo;
+            }
+        }
+
+    if (appCheckResult == ECompaCheckResultUndefinite)
+        {
+        // Application is not executing from rom drive. Go to compa-mode.
+        appCheckResult = ECompaCheckResultYes;
+        }
+
+    CleanupStack::PopAndDestroy(2); // resFile, array
+    return appCheckResult;
+    }
+
+// --------------------------------------------------------------------------
+// Check if current process is a server that displays global
+// notes/notifications (Eikon server, Avkon notify and cap servers)
+// --------------------------------------------------------------------------
+TBool AknCompaUtils::InGlobalUiSrv(TInt aAppUiFlags)
+    {
+    // Optimization: don't check secure id if ENoScreenFurniture
+    // flag not set.
+    TBool inGlobalUiSrv = EFalse;
+    if (aAppUiFlags & CEikAppUi::ENoScreenFurniture)
+        {
+        RProcess process;
+        inGlobalUiSrv = IsGlobalUiSrv(process.SecureId());
+        }
+    return inGlobalUiSrv;
+    }
+
+// --------------------------------------------------------------------------
+// Check if application is console application
+// --------------------------------------------------------------------------
+TBool AknCompaUtils::IsConsoleApp(CAknAppUiBase& aAppUi)
+    {
+    MConsoleApp* consoleApp;
+    aAppUi.MopGetObjectNoChaining(consoleApp);
+    return consoleApp != NULL;
+    }