src/hbservers/hbthemeserver/hbthemeserversymbian.cpp
changeset 1 f7ac710697a9
parent 0 16d8024aca5e
child 2 06ff229162e9
equal deleted inserted replaced
0:16d8024aca5e 1:f7ac710697a9
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbServers module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbthemeserversymbian_p.h"
       
    27 #include "hbthemeserverutils_p.h"
       
    28 #include "hbmemorymanager_p.h"
       
    29 #include "hbiconsource_p.h"
       
    30 #include "hbthemeindex_p.h"
       
    31 #include "hbthemeutils_p.h"
       
    32 
       
    33 #include <QHash>
       
    34 #include <QImage>
       
    35 #include <QSettings>
       
    36 #include <QSharedMemory>
       
    37 #include <QDebug>
       
    38 #include <QProcess>
       
    39 #include <QFile>
       
    40 #include <QPainter>
       
    41 #include <QSizeF>
       
    42 #include <e32property.h>
       
    43 #include <e32base.h>
       
    44 #include <e32svr.h>
       
    45 #include "hbpixmapiconprocessor_p.h"
       
    46 #include "hbpixmapiconimpl_p.h"
       
    47 #include "hblayeredstyleloader_p.h"
       
    48 #include "hbmemoryutils_p.h"
       
    49 #include "hbdeviceprofiledatabase_p.h"
       
    50 // 5 MB GPU cache size
       
    51 #define GPU_CACHE_SIZE 0x500000
       
    52 
       
    53 // 5 MB  CPU cache size
       
    54 #define CPU_CACHE_SIZE 0x500000
       
    55 
       
    56 const TInt KThemeName = 0;
       
    57 
       
    58 
       
    59 
       
    60 static HbThemeServerSymbian *TheServer = 0;
       
    61 
       
    62 // This is used as parent theme always regardless of the active theme
       
    63 static const char *baseThemeName = "hbdefault";
       
    64 const int themeIndexFailed = -2; // error code to indicate failure in processing theme index
       
    65 
       
    66 //**********************************
       
    67 //HbThemeServerSymbian
       
    68 //**********************************
       
    69 /**
       
    70 Our server class - an active object - and therefore derived ultimately from CActive.
       
    71 It accepts requests from client threads and forwards
       
    72 them to the client session to be dealt with. It also handles the creation
       
    73 of the server-side client session.
       
    74 */
       
    75 
       
    76 /**
       
    77 NewL
       
    78  */
       
    79 HbThemeServerSymbian * HbThemeServerSymbian::NewL(CActive::TPriority aActiveObjectPriority)
       
    80 {
       
    81     HbThemeServerSymbian* self = new(ELeave) HbThemeServerSymbian(aActiveObjectPriority);
       
    82     CleanupStack::PushL(self);
       
    83     self->ConstructL();
       
    84     CleanupStack::Pop(); // self
       
    85     return self;
       
    86 }
       
    87 
       
    88 /**
       
    89 ConstructL
       
    90  */
       
    91 void HbThemeServerSymbian::ConstructL()
       
    92 {
       
    93     TInt err = RProperty::Define(KServerUid3, KThemeName, RProperty::ELargeText);
       
    94     if ( err != KErrAlreadyExists ) {
       
    95         User::LeaveIfError( err );
       
    96     }
       
    97     TInt error = iThemeProperty.Attach(KServerUid3, KThemeName );
       
    98     User::LeaveIfError(error);
       
    99     
       
   100     QSettings settings(QLatin1String(ORGANIZATION), QLatin1String(THEME_COMPONENT));
       
   101     // Store the active theme name in a member string
       
   102     iCurrentThemeName = settings.value("currenttheme").toString();
       
   103     
       
   104     // HACK
       
   105     if (iCurrentThemeName.isEmpty()) {
       
   106         iCurrentThemeName = "sfblacktheme";
       
   107     }
       
   108     
       
   109     // TODO: Get default theme name if current theme setting does not return theme name
       
   110 
       
   111 /*
       
   112     if (iCurrentThemeName.isEmpty()) {
       
   113         iCurrentThemeName = HbThemeUtils::defaultTheme();
       
   114         settings.setValue("currenttheme", iCurrentThemeName); 
       
   115         settings.sync();
       
   116         TPtrC name(reinterpret_cast<const TUint16 *>(iCurrentThemeName.constData()));
       
   117         iThemeProperty.Set(name);
       
   118     }
       
   119 */
       
   120 
       
   121     // Resolve the drive letter of the current theme
       
   122     resolveCurrentThemeDrive();
       
   123     // Open index file to prevent uninstallation of the active theme
       
   124     openCurrentIndexFile();
       
   125 
       
   126     //Create the Icon cache
       
   127     cache = new HbIconDataCache();
       
   128     setMaxGpuCacheSize(GPU_CACHE_SIZE);
       
   129     setMaxCpuCacheSize(CPU_CACHE_SIZE);
       
   130     
       
   131     //Create the CSS cache
       
   132     cssCache = new HbCache();
       
   133     
       
   134     // Temporary hack for pre-loading app. background graphics in server startup to give more realistic
       
   135     // results in performance tests. (Normally these graphics get loaded anyway when the first hb app is started.)
       
   136 #ifndef HB_NVG_CS_ICON
       
   137     QProcess::startDetached("hbiconpreloader.exe");
       
   138 #endif
       
   139     
       
   140     // Process base theme index, it is used as parent index also when the current theme is something else
       
   141     processThemeIndex(baseThemeName, QChar('Z'));
       
   142     baseThemeIndexKey = themeIndexKey(baseThemeName, QChar('Z'));
       
   143 }
       
   144 
       
   145 /**
       
   146 Constructor takes the server priority value. 
       
   147 
       
   148 The server is an active object, and the priority value is the priority
       
   149 of this active object.
       
   150 
       
   151 It passes the priority value to the base class in the Ctor list.
       
   152 By default, the session is not sharable, which is what we want here
       
   153 so no second parameter is passed to the CServer2 constructor.
       
   154 */
       
   155 HbThemeServerSymbian::HbThemeServerSymbian( CActive::TPriority aActiveObjectPriority )
       
   156     : CServer2( aActiveObjectPriority ),
       
   157       currentThemeDrive('Z') // Assume default theme is in ROM
       
   158 {
       
   159     // Set server pointer in static variable
       
   160     TheServer = this;
       
   161 }
       
   162 
       
   163 /**
       
   164 Destructor
       
   165  */
       
   166 HbThemeServerSymbian::~HbThemeServerSymbian()
       
   167 {
       
   168     delete cache;
       
   169     delete cssCache;
       
   170     cache = NULL;      // so that HbSymbianThemeServSession::~HbSymbianThemeServSession can avoid using these pointers;
       
   171 	cssCache = NULL;   // it may be called inside HbThemeServerSymbian::~HbThemeServerSymbian
       
   172 }
       
   173 
       
   174 HbThemeServerSymbian *HbThemeServerSymbian::Instance()
       
   175 {
       
   176     return TheServer;
       
   177 }
       
   178 
       
   179 void HbThemeServerSymbian::openCurrentIndexFile()
       
   180 {
       
   181     // Open index file to prevent uninstallation of the active theme
       
   182     if (!iCurrentThemeName.isEmpty() && currentThemeDrive != 'Z') {
       
   183         QString indexFileName;
       
   184         indexFileName.append(currentThemeDrive);
       
   185         indexFileName.append("\\resource\\hb\\themes\\icons\\");
       
   186         indexFileName.append(iCurrentThemeName);
       
   187         indexFileName.append("\\index.theme");
       
   188 
       
   189         currentIndexfile.setFileName(indexFileName);
       
   190         if(!currentIndexfile.open(QIODevice::ReadOnly)) {
       
   191             qWarning()<< "HbSymbianThemeServer: No Index file found in the new theme, How did this happen ??";
       
   192         }
       
   193     }
       
   194 }
       
   195 
       
   196 void HbThemeServerSymbian::resolveCurrentThemeDrive()
       
   197 {
       
   198     if (!iCurrentThemeName.isEmpty()) {
       
   199         // Check for the theme's icon directory in different drives.
       
   200         // ROM is checked first and then phone memory and memory card drives.
       
   201 
       
   202         QString filename = "Z:\\resource\\hb\\themes\\icons\\";
       
   203         filename.append(iCurrentThemeName);
       
   204 
       
   205         if (QFile::exists(filename)) {
       
   206             currentThemeDrive = 'Z';
       
   207             return;
       
   208         }
       
   209     
       
   210         filename[0] = 'C';
       
   211         if (QFile::exists(filename)) {
       
   212             currentThemeDrive = 'C';
       
   213             return;
       
   214         }
       
   215 
       
   216         filename[0] = 'E';
       
   217         if (QFile::exists(filename)) {
       
   218             currentThemeDrive = 'E';
       
   219             return;
       
   220         }
       
   221         
       
   222         // Default to 'Z' if not found in any drive
       
   223         currentThemeDrive = 'Z';
       
   224     }
       
   225 }
       
   226 
       
   227 /**
       
   228 Creates a new session with the server.
       
   229 */
       
   230 CSession2* HbThemeServerSymbian::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
       
   231 {
       
   232 #ifdef THEME_SERVER_TRACES 
       
   233     qDebug() << "HbThemeServerSymbian::NewSessionL: entered";
       
   234 #endif    
       
   235     // Check that the version is OK
       
   236     TVersion v( KThemeServerMajorVersionNumber, KThemeServerMinorVersionNumber, KThemeServerBuildVersionNumber );
       
   237     if (!User::QueryVersionSupported( v, aVersion ))
       
   238         User::Leave( KErrNotSupported );  
       
   239     // Create the session.
       
   240     return new (ELeave) HbSymbianThemeServSession( const_cast<HbThemeServerSymbian*>(this) );
       
   241 }
       
   242 
       
   243 /**
       
   244 A utility function to panic the server.
       
   245 */
       
   246 void HbThemeServerSymbian::PanicServer(TPixmapServPanic aPanic)
       
   247 {
       
   248     _LIT(KTxtServerPanic, "Pixmap server panic");
       
   249     User::Panic(KTxtServerPanic, aPanic);
       
   250 }
       
   251 
       
   252 /**
       
   253  * HbThemeServerSymbian::insertIconCacheItem
       
   254  * 
       
   255  * Inserts an icon-cache item along with its key into the icon-cache.
       
   256  */
       
   257 bool HbThemeServerSymbian::insertIconCacheItem ( const HbIconKey &key,  HbIconCacheItem* item )
       
   258 {
       
   259     return (cache->insert(key, item));
       
   260 
       
   261 }
       
   262 
       
   263 /**
       
   264  * HbThemeServerSymbian::insertCssCacheItem
       
   265  * 
       
   266  * Inserts a css-cache item along with its key into the css-cache.
       
   267  */
       
   268 bool HbThemeServerSymbian::insertCssCacheItem ( const QString& key,  HbCacheItem* item )
       
   269 {
       
   270     return (cssCache->insert(key, item));
       
   271 }
       
   272 
       
   273 /**
       
   274  * HbThemeServerSymbian::iconCacheItem
       
   275  * 
       
   276  * Retrieves a icon cache-item from the icon cache based on it's key.
       
   277  */
       
   278 HbIconCacheItem * HbThemeServerSymbian::iconCacheItem ( const HbIconKey &key , bool isMultiIconPiece )
       
   279 {
       
   280     return(cache->getCacheItem(key, isMultiIconPiece));
       
   281 }
       
   282 
       
   283 /**
       
   284  * HbThemeServerSymbian::cssCacheItem
       
   285  * 
       
   286  * Retrieves a css-cache item from the css cache based on it's key.
       
   287  */
       
   288 HbCacheItem * HbThemeServerSymbian::cssCacheItem ( const QString &key)
       
   289 {
       
   290     return(cssCache->cacheItem(key));
       
   291 }
       
   292 
       
   293 void HbThemeServerSymbian::insertIconDefaultSizeCacheItem(const QString &key, const QSizeF &item)
       
   294 {
       
   295     iconDefaultSizes.insert(key, item);
       
   296 }
       
   297 
       
   298 QSizeF HbThemeServerSymbian::iconDefaultSizeCacheItem(const QString &key)
       
   299 {
       
   300     return iconDefaultSizes.value(key);
       
   301 }
       
   302 
       
   303 /**
       
   304  * HbThemeServerSymbian::clearIconCache
       
   305  * 
       
   306  * Clears icon cache.
       
   307  */
       
   308 void HbThemeServerSymbian::clearIconCache()
       
   309 {
       
   310     cache->clear();
       
   311 }
       
   312 
       
   313 /**
       
   314  * HbThemeServerSymbian::clearCssCache
       
   315  * 
       
   316  * Clears css cache.
       
   317  */
       
   318 void HbThemeServerSymbian::clearCssCache()
       
   319 {
       
   320     cssCache->clear();
       
   321 }
       
   322 
       
   323 /**
       
   324  * HbThemeServerSymbian::CleanupSessionIconItem
       
   325  * 
       
   326  * Removes an icon cache-item from icon-cache based on it's key.
       
   327  */
       
   328 void HbThemeServerSymbian::CleanupSessionIconItem(HbIconKey key)
       
   329 {
       
   330     /*
       
   331 	    Don't call any HbIconDataCache functions if HbThemeServerSymbian has already deleted it,
       
   332 	     which happens when ThemeServer is closed before the client(s).
       
   333 	*/
       
   334     if(cache)
       
   335         cache->remove(key); 
       
   336 }
       
   337 
       
   338 /**
       
   339  * HbThemeServerSymbian::CleanupSessionCssItem
       
   340  * 
       
   341  * Removes a css cache-item from css-cache based on it's key.
       
   342  */
       
   343 void HbThemeServerSymbian::CleanupSessionCssItem(QString key)
       
   344 {
       
   345     /*
       
   346 	    Don't call any HbCache ( CssCache )  functions if HbThemeServerSymbian has already deleted it,
       
   347 	     which happens when ThemeServer is closed before the client(s).
       
   348 	*/
       
   349     if(cssCache)
       
   350         cssCache->remove(key); 
       
   351 }
       
   352 
       
   353 /**
       
   354 HbThemeServerSymbian::setMaxGpuCacheSize
       
   355  */
       
   356 void HbThemeServerSymbian::setMaxGpuCacheSize(int size)
       
   357 {
       
   358     cache->setMaxGpuCacheSize(size);
       
   359 }
       
   360 
       
   361 /**
       
   362 HbThemeServerSymbian::setMaxGpuCacheSize
       
   363  */
       
   364 void HbThemeServerSymbian::setMaxCpuCacheSize(int size)
       
   365 {
       
   366     cache->setMaxCpuCacheSize(size);
       
   367 }
       
   368 
       
   369 //Debug Code for Test Purpose
       
   370 #ifdef HB_ICON_CACHE_DEBUG
       
   371 int HbThemeServerSymbian ::cacheIconCount() const
       
   372 {
       
   373     return cache->count();
       
   374 }
       
   375 
       
   376 int HbThemeServerSymbian::freeVectorMemory()
       
   377 {
       
   378     return cache->freeVectorMemory();
       
   379 }
       
   380 
       
   381 int HbThemeServerSymbian::freeRasterMemory()
       
   382 {
       
   383     return cache->freeRasterMemory();
       
   384 }
       
   385 
       
   386 int HbThemeServerSymbian::lastAddedRefCount()
       
   387 {
       
   388     return cache->lastAddedRefCount();
       
   389 }
       
   390 
       
   391 int HbThemeServerSymbian::lastAddedItemMem()
       
   392 {
       
   393     return cache->lastAddedItemMem();
       
   394 }
       
   395 
       
   396 int HbThemeServerSymbian::lastRemovedItemMem()
       
   397 {
       
   398     return cache->lastRemovedItemMem();
       
   399 }
       
   400 
       
   401 int HbThemeServerSymbian::lastRemovedItemRfCount()
       
   402 {
       
   403     return cache->lastRemovedItemRfCount();
       
   404 }
       
   405 
       
   406 bool HbThemeServerSymbian::enableCache(bool cacheIt)
       
   407 {
       
   408     return cache->enableCache(cacheIt);
       
   409 }
       
   410 
       
   411 int HbThemeServerSymbian::cacheHitCount()
       
   412 {
       
   413     return cache->cacheHitCount();
       
   414 }
       
   415 
       
   416 int HbThemeServerSymbian::cacheMissCount()
       
   417 {
       
   418     return cache->cacheMissCount();
       
   419 }
       
   420 
       
   421 int HbThemeServerSymbian::serverHeapSize()
       
   422 {
       
   423     TInt heapSize = 0; 
       
   424     User::AllocSize(heapSize);
       
   425     return heapSize;
       
   426 }
       
   427 
       
   428 void HbThemeServerSymbian::cleanVectorLRUList()
       
   429 {
       
   430     cache->cleanVectorLRUList();
       
   431 }
       
   432 
       
   433 void HbThemeServerSymbian::cleanRasterLRUList()
       
   434 {
       
   435     cache->cleanRasterLRUList();
       
   436 }
       
   437 
       
   438 int HbThemeServerSymbian::rasterLruCount()
       
   439 {
       
   440     return cache->rasterLruCount();
       
   441 }
       
   442 
       
   443 int HbThemeServerSymbian::vectorLruCount()
       
   444 {
       
   445     return cache->vectorLruCount();
       
   446 }
       
   447 #endif
       
   448 
       
   449 /**
       
   450  * HbThemeServerSymbian::doCleanup()
       
   451  * 
       
   452  * This function releases shared memory occupied by css-resources whose reference count is zero,
       
   453  * so that subsequent css-requests could be fulfilled by the server. Those css-files whose reference
       
   454  * count are zero, are already appended to the LRU list maintained by the css-cache. Since these resources
       
   455  * are not being referred to by any application, they can be removed from the cache and corresponding
       
   456  * shared memory can be freed up.
       
   457  */
       
   458 void HbThemeServerSymbian::doCleanup() 
       
   459 {
       
   460     HbThemeServerUtils::cleanupUnusedCss(cssCache);
       
   461 }
       
   462 
       
   463 QString HbThemeServerSymbian::themeIndexKey(const QString &theme, const QChar drive)
       
   464 {
       
   465     QString key(drive);
       
   466     key.append(':');
       
   467     key.append(theme);
       
   468     return key;
       
   469 }
       
   470 
       
   471 void HbThemeServerSymbian::processThemeIndex(const QString &theme, const QChar drive)
       
   472 {
       
   473     QString filename(drive);
       
   474     filename.append(":\\resource\\hb\\themes\\");
       
   475     filename.append(theme);
       
   476     filename.append(".themeindex");
       
   477     
       
   478     QFile indexFile(filename);
       
   479 
       
   480     bool indexOK = false;
       
   481 
       
   482     if (indexFile.open(QIODevice::ReadOnly)) {
       
   483 
       
   484         indexOK = true;
       
   485 
       
   486         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
       
   487 
       
   488         qint64 byteSize = indexFile.size();
       
   489         
       
   490         int offset = manager->alloc(byteSize);
       
   491         if (offset >= 0) {        
       
   492             // Read the theme index in the shared chunk
       
   493             char *address = HbMemoryUtils::getAddress<char>(HbMemoryManager::SharedMemory, offset);
       
   494 
       
   495             #ifdef THEME_INDEX_TRACES
       
   496             qDebug() <<  "ThemeIndex: Reading themeindex for theme" << theme.toUtf8();
       
   497             #endif
       
   498 
       
   499             indexFile.read(address, byteSize);
       
   500             indexFile.close();
       
   501 
       
   502             #ifdef THEME_INDEX_TRACES
       
   503             qDebug() <<  "ThemeIndex: Reading themeindex for theme" << theme.toUtf8() << "... Done!";
       
   504             #endif
       
   505 
       
   506             // Verify theme index contents if it is not located in ROM,
       
   507             // so that it does not have over-indexing offsets which might
       
   508             // crash all the clients trying to read from it.
       
   509             
       
   510             if (drive != 'Z') {
       
   511                 #ifdef THEME_INDEX_TRACES
       
   512                 qDebug() <<  "ThemeIndex: Validating themeindex for theme" << theme.toUtf8();
       
   513                 #endif
       
   514 
       
   515                 HbThemeIndex index(address);
       
   516                 int count = index.itemCount();
       
   517                 if (count * sizeof(HbThemeIndexItem) >= byteSize) {
       
   518                     indexOK = false;
       
   519                 } else {
       
   520                     const HbThemeIndexItem *itemArray = index.itemArray();
       
   521                     int stringAreaStart = reinterpret_cast<int>(index.stringAreaStart()) - reinterpret_cast<int>(address);
       
   522 
       
   523                     for (int i = 0; i<count; i++) {
       
   524                         const HbThemeIndexItem *item = itemArray++;
       
   525                         if (item->iconnameOffset < stringAreaStart || item->iconnameOffset >= byteSize ||
       
   526                             item->folderOffset < stringAreaStart || item->folderOffset >= byteSize ||
       
   527                             item->extOffset < stringAreaStart || item->extOffset >= byteSize ||
       
   528                             item->mirroredExtOffset != -1 &&
       
   529                             (item->mirroredExtOffset < stringAreaStart || item->mirroredExtOffset >= byteSize)) {
       
   530                             
       
   531                             indexOK = false;
       
   532                             break;
       
   533                         }
       
   534                     }
       
   535                     
       
   536                 }
       
   537 
       
   538                 #ifdef THEME_INDEX_TRACES
       
   539                 qDebug() <<  "ThemeIndex: Validating themeindex for theme" << theme.toUtf8() << "... Done!";
       
   540                 #endif
       
   541             }
       
   542 
       
   543             if (indexOK) {
       
   544                 // Clear some old indexes so the chunk does not get filled completely if
       
   545                 // the user switches themes a lot.
       
   546                 removeOldThemeIndexes();            
       
   547                 // Store offset to the index in chunk
       
   548                 lastThemeIndexKey = themeIndexKey(theme, drive);
       
   549                 themeIndexes.insert(lastThemeIndexKey, offset);                
       
   550             } else {
       
   551                 // If the index contents were not OK, remove the index from the chunk
       
   552                 manager->free(offset);
       
   553             }
       
   554         }
       
   555     }
       
   556 
       
   557 
       
   558     if (!indexOK) {
       
   559         // If there was a problem with the index, store error code so the index loading is not retried.
       
   560         themeIndexes.insert(themeIndexKey(theme, drive), themeIndexFailed);
       
   561     }
       
   562 }
       
   563 
       
   564 void HbThemeServerSymbian::removeOldThemeIndexes()
       
   565 {
       
   566     // This function removes the previously used theme indexes from the shared chunk.
       
   567     // The last index is not removed, because some clients might be still using it.
       
   568     // Also the base theme index is never removed.
       
   569     
       
   570     QMap<QString, int>::const_iterator i = themeIndexes.constBegin();
       
   571 
       
   572     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
       
   573 
       
   574     while (i != themeIndexes.constEnd()) {
       
   575         if (i.value() != themeIndexFailed && i.key() != baseThemeIndexKey && i.key() != lastThemeIndexKey) {
       
   576             QString key = i.key();
       
   577             // Advance iterator before removing the current item from the map.
       
   578             i++;
       
   579 
       
   580             // Remove the theme index table from the shared chunk and offset map
       
   581             manager->free(i.value());        
       
   582             themeIndexes.remove(key);
       
   583         } else {
       
   584             i++;
       
   585         }
       
   586     }
       
   587 }
       
   588 
       
   589 void HbThemeServerSymbian::getThemeIndexTables(ThemeIndexTables &tables)
       
   590 {
       
   591     QString key = themeIndexKey(iCurrentThemeName, currentThemeDrive);
       
   592     int offset = themeIndexes.value(key, -1);
       
   593 
       
   594     // If the index has failed earlier, do not retry
       
   595     if (offset == themeIndexFailed) {
       
   596         return;
       
   597     }
       
   598 
       
   599     if (offset == -1) {
       
   600         processThemeIndex(iCurrentThemeName, currentThemeDrive);
       
   601     }
       
   602     
       
   603     tables.tables[0] = themeIndexes.value(key, -1);
       
   604     tables.drives[0] = currentThemeDrive;
       
   605 
       
   606     // Set base theme table as parent table if the current theme is not the base theme
       
   607     if (tables.tables[0] >= 0 && iCurrentThemeName != baseThemeName) {
       
   608         QString base(baseThemeName);
       
   609         tables.tables[1] = themeIndexes.value(themeIndexKey(base, 'Z'), -1);
       
   610         tables.drives[1] = 'Z';
       
   611     }    
       
   612 }
       
   613 
       
   614 
       
   615 //**********************************
       
   616 //HbSymbianThemeServSession
       
   617 //**********************************
       
   618 /**
       
   619 This class represents a session with the  server.
       
   620 Functions are provided to respond appropriately to client messages.
       
   621 */
       
   622 
       
   623 /**
       
   624 Constructor
       
   625 */
       
   626 HbSymbianThemeServSession::HbSymbianThemeServSession(HbThemeServerSymbian *aServer):
       
   627         iServer(aServer)        
       
   628 {
       
   629 
       
   630 }
       
   631 
       
   632 /**
       
   633 Destructor
       
   634 */
       
   635 HbSymbianThemeServSession::~HbSymbianThemeServSession()
       
   636 {
       
   637     //Clean up the icon related session-specific info
       
   638   QList<HbIconKey>::const_iterator itEnd( sessionData.constEnd() );
       
   639     for ( QList<HbIconKey>::const_iterator iter = sessionData.constBegin();
       
   640             iter != itEnd;
       
   641             ++iter ) {
       
   642                 iServer->CleanupSessionIconItem(*iter);
       
   643     }   
       
   644     //clean up css related session-specific info
       
   645     QList<QString>::const_iterator iterEnd( sessionCssData.constEnd() );
       
   646     for ( QList<QString>::const_iterator iter = sessionCssData.constBegin();
       
   647             iter != iterEnd;
       
   648             ++iter ) {
       
   649                 iServer->CleanupSessionCssItem(*iter);
       
   650         }
       
   651     
       
   652     sessionData.clear();
       
   653     sessionCssData.clear();
       
   654 }
       
   655 
       
   656 TIconParams HbSymbianThemeServSession::ReadMessageAndRetrieveParams(const RMessage2& aMessage)
       
   657 {
       
   658     TInt deslen = aMessage.GetDesLength(0);
       
   659     TIconParams params;
       
   660     TPckg<TIconParams> paramPckg(params);
       
   661     // Copy the client's descriptor data into our buffer.
       
   662     aMessage.ReadL(0, paramPckg, 0);
       
   663     return params;
       
   664 }
       
   665 
       
   666 /**
       
   667 Services a client request.
       
   668 */
       
   669 void HbSymbianThemeServSession::ServiceL(const RMessage2& aMessage)
       
   670 {    
       
   671 #ifdef THEME_SERVER_TRACES 
       
   672     qDebug() << "Just entered HbSymbianThemeServSession::ServiceL";
       
   673 #endif    
       
   674     
       
   675     TRAPD(err, DispatchMessageL(aMessage));
       
   676     aMessage.Complete(err);
       
   677     QString er;
       
   678     er.setNum(err);
       
   679     
       
   680 #ifdef THEME_SERVER_TRACES 
       
   681     qDebug() << "completed DispatchMessageL error code is " + er;
       
   682 #endif    
       
   683     
       
   684 }
       
   685 
       
   686 /**
       
   687 Called by ServiceL()
       
   688 
       
   689 It tests the function code and then delegates to
       
   690 the appropriate function.
       
   691 */
       
   692 void HbSymbianThemeServSession::DispatchMessageL(const RMessage2& aMessage)
       
   693 {    
       
   694 #ifdef THEME_SERVER_TRACES 
       
   695     qDebug() << "Just entered HbSymbianThemeServSession::DispatchMessageL";
       
   696 #endif       
       
   697     
       
   698     switch (aMessage.Function()) {
       
   699     case EStyleSheetLookup:
       
   700         HandleStyleSheetLookupL(aMessage);
       
   701         break;   
       
   702     case EWidgetMLLookup:
       
   703         HandleWidgetMLLookupL(aMessage);
       
   704         break;
       
   705     case EDeviceProfileOffset:
       
   706         HandleDeviceProfilesReqL(aMessage);
       
   707         break;
       
   708     case ESecondaryCacheOffset:
       
   709         HandleSecondaryCacheOffsetReqL(aMessage);
       
   710         break;
       
   711     case EEffectAdd: // FALLTHROUGH
       
   712     case EEffectLookupFilePath:
       
   713         HandleEffectAddAndFileLookupL(aMessage);
       
   714         break;
       
   715 
       
   716     case EIconLookup:
       
   717         GetSharedIconInfoL(aMessage);
       
   718         break;
       
   719         
       
   720     case EIconDefaultSize:
       
   721         GetSharedIconDefaultSizeInfoL(aMessage);
       
   722         break;
       
   723 
       
   724     case EThemeSelection:
       
   725         HandleThemeSelectionL(aMessage);
       
   726         break;
       
   727         
       
   728     case EMultiPieceIcon: 
       
   729         GetSharedMultiIconInfoL(aMessage);
       
   730         break;
       
   731 
       
   732         //Debug Code for Test Purpose
       
   733 #ifdef HB_ICON_CACHE_DEBUG
       
   734         case ECacheIconCount: {
       
   735             TInt count = iServer->cacheIconCount();             
       
   736             TPckg<TInt> out(count);
       
   737             aMessage.WriteL(1, out);
       
   738             break;
       
   739         }
       
   740         case ERasterMemLimit: {
       
   741             TInt params = 0;
       
   742             TPckg<TInt> paramPckg(params);      
       
   743             aMessage.ReadL(0, paramPckg, 0);
       
   744             
       
   745             iServer->setMaxGpuCacheSize(params);
       
   746             break;  
       
   747         }
       
   748         case EVectorMemLimit: {
       
   749             TInt params = 0;
       
   750             TPckg<TInt> paramPckg(params);      
       
   751             aMessage.ReadL(0, paramPckg, 0);            
       
   752             iServer->setMaxCpuCacheSize(params); 
       
   753             break;
       
   754         }
       
   755         case EFreeRasterMem: {
       
   756             TInt freeRastMem = iServer->freeRasterMemory();
       
   757             TPckg<TInt> out(freeRastMem);
       
   758             aMessage.WriteL(1, out);
       
   759             break;
       
   760         }
       
   761         case EFreeVectorMem: {
       
   762             TInt freeVectMem = iServer->freeVectorMemory();
       
   763             TPckg<TInt> out(freeVectMem);
       
   764             aMessage.WriteL(1, out);
       
   765             break;
       
   766         }
       
   767         case ELastAddedItemMem: {
       
   768             TInt lAddItemMem = iServer->lastAddedItemMem();
       
   769             TPckg<TInt> out(lAddItemMem);
       
   770             aMessage.WriteL(1, out);
       
   771             break;
       
   772         }
       
   773         case ELastRemovedItemMem: {
       
   774             TInt lRemItemMem = iServer->lastRemovedItemMem();
       
   775             TPckg<TInt> out(lRemItemMem);
       
   776             aMessage.WriteL(1, out);
       
   777             break;
       
   778         }
       
   779         case ELastAddedItemRefCount: {
       
   780             TInt lAddItemRfCnt = iServer->lastAddedRefCount();
       
   781             TPckg<TInt> out(lAddItemRfCnt);
       
   782             aMessage.WriteL(1, out);
       
   783             break;
       
   784         }
       
   785         case EEnableCache: {
       
   786             TBool params = 0;
       
   787             TPckg<TBool> paramPckg(params);     
       
   788             aMessage.ReadL(0, paramPckg, 0);
       
   789             TBool success = iServer->enableCache(params);
       
   790             TPckg<TBool> out(success);
       
   791             aMessage.WriteL(1, out);
       
   792             break;
       
   793         }
       
   794         case ECacheHit: {
       
   795             int cacheHitCnt = iServer->cacheHitCount();
       
   796             TPckg<TInt> out(cacheHitCnt);
       
   797             aMessage.WriteL(1, out);
       
   798             break;
       
   799         }
       
   800         case ECacheMiss: {
       
   801             int cacheMissCnt = iServer->cacheMissCount();
       
   802             TPckg<TInt> out(cacheMissCnt);
       
   803             aMessage.WriteL(1, out);
       
   804             break;
       
   805         }
       
   806         case ECleanRasterLRUList: {
       
   807             iServer->cleanRasterLRUList();
       
   808             break;
       
   809         }
       
   810         case ECleanVectorLRUList: {
       
   811             iServer->cleanVectorLRUList();
       
   812             break;
       
   813         }
       
   814         case EGpuLruCount: {
       
   815             TInt rasterMissCount = iServer->rasterLruCount();
       
   816             TPckg<TInt> out(rasterMissCount);
       
   817             aMessage.WriteL(1, out);
       
   818             break;
       
   819         }
       
   820         case ECpuLruCount: {
       
   821             TInt vectorMissCount = iServer->vectorLruCount();
       
   822             TPckg<TInt> out(vectorMissCount);
       
   823             aMessage.WriteL(1, out);
       
   824             break;
       
   825         }
       
   826         case EServerHeap: {
       
   827             TInt heapSize = iServer->serverHeapSize();
       
   828             TPckg<TInt> out(heapSize);
       
   829             aMessage.WriteL(1, out);
       
   830             break;
       
   831         }
       
   832         
       
   833         case ELastRemovedItemRefCount: {
       
   834             TInt lastItemRemovedRefCount = iServer->lastRemovedItemRfCount();
       
   835             TPckg<TInt> out(lastItemRemovedRefCount);
       
   836             aMessage.WriteL(1, out);
       
   837             break;
       
   838         }
       
   839         
       
   840         case EServerHeapMarkStart: {
       
   841             __UHEAP_MARK;
       
   842             break;
       
   843         }
       
   844 
       
   845         case EServerHeapMarkEnd: {
       
   846             __UHEAP_MARKEND;
       
   847             break;
       
   848         }
       
   849 
       
   850         case EServerAllocFail: {
       
   851             //TODO
       
   852             break;
       
   853         }
       
   854         
       
   855         case EServerAllocReset: {
       
   856             //TODO
       
   857             break;
       
   858         }
       
   859 #endif
       
   860         case EUnloadIcon: {
       
   861             TIconParams params = ReadMessageAndRetrieveParams(aMessage);
       
   862             QString filename((QChar*)params.fileName.Ptr(),params.fileName.Length());
       
   863             QColor color = GetColorFromRgba(params.rgba,params.colorflag);
       
   864             HbIconKey key(filename, QSizeF(params.width, params.height), 
       
   865                         (Qt::AspectRatioMode)params.aspectRatioMode,
       
   866                         (QIcon::Mode)params.mode, params.mirrored, color);
       
   867             iServer->CleanupSessionIconItem(key);
       
   868             sessionData.removeOne(key);
       
   869             break;
       
   870 
       
   871         }
       
   872 
       
   873         case EThemeIndex: {
       
   874             // Using leave here because this function does not return a value
       
   875             ThemeIndexTables tables;
       
   876             iServer->getThemeIndexTables(tables);
       
   877             TPckg<ThemeIndexTables> out(tables);
       
   878             aMessage.WriteL(0, out);
       
   879             break;
       
   880         }
       
   881 
       
   882         // This is an example of a request that we know about, but don't support.
       
   883         // We cause KErrNotSupported to be returned to the client.
       
   884         default:
       
   885             PanicClient(aMessage, EBadRequest);
       
   886             break;
       
   887     }
       
   888 #ifdef THEME_SERVER_TRACES 
       
   889     qDebug() << "Leave HbSymbianThemeServSession::DispatchMessageL";
       
   890 #endif  
       
   891     
       
   892 }
       
   893 
       
   894 /**
       
   895  * HandleStyleSheetLookupL
       
   896  */
       
   897 void HbSymbianThemeServSession::HandleStyleSheetLookupL(const RMessage2& aMessage)
       
   898 {
       
   899     if (aMessage.GetDesLength(0) == 0) {    
       
   900 #ifdef THEME_SERVER_TRACES 
       
   901         qDebug() << "Empty Filename";
       
   902 #endif         
       
   903         return;
       
   904     }
       
   905 
       
   906     TBuf<256> fileName;
       
   907     aMessage.ReadL(0, fileName, 0);
       
   908     TBuf<256> layerPriorityBuf;
       
   909     aMessage.ReadL(1,layerPriorityBuf,0);
       
   910     TLex lex(layerPriorityBuf);
       
   911     TInt priorityValue;
       
   912     lex.Val(priorityValue);
       
   913 
       
   914     HbLayeredStyleLoader::LayerPriority layerPriority = ( HbLayeredStyleLoader::LayerPriority) priorityValue;
       
   915 
       
   916     QString cssFileName((QChar*)fileName.Ptr(), fileName.Length()); 
       
   917     HbSharedStyleSheetInfo offsetInfo;
       
   918     HbCacheItem* cssCacheItem = iServer->cssCacheItem(cssFileName);
       
   919     bool insertKeyIntoSessionList = false;
       
   920     if ( cssCacheItem ) {
       
   921         //The item was found in the cache and reference count was incremented
       
   922         insertKeyIntoSessionList = true;
       
   923         offsetInfo.offset = cssCacheItem->offset;
       
   924     }
       
   925     else{
       
   926             bool tryAgain = false;
       
   927             do{
       
   928                 offsetInfo.offset = HbThemeServerUtils::getSharedStylesheet(cssFileName,layerPriority);
       
   929                 if(offsetInfo.offset >= 0){
       
   930                     HbCacheItem *cssItem =  new HbCacheItem(offsetInfo.offset,0,cssFileName);
       
   931                     insertKeyIntoSessionList = iServer->insertCssCacheItem(cssFileName,cssItem);
       
   932                     if(layerPriority == HbLayeredStyleLoader::Priority_Core && cssItem->refCount == 1) {
       
   933                         // This will make sure the requested stylesheet will always remain
       
   934                         // in the primary and secondary cache.
       
   935                         cssItem->incrementRefCount();
       
   936                     }
       
   937                     break;
       
   938                 }else if(offsetInfo.offset == OUT_OF_MEMORY_ERROR && tryAgain == false){
       
   939                     iServer->doCleanup();
       
   940                     tryAgain = true;
       
   941                 }else if(offsetInfo.offset == OUT_OF_MEMORY_ERROR && tryAgain == true){
       
   942                     //try only once to free up memory, else offset remains -2
       
   943                     tryAgain = false;
       
   944             }
       
   945       }while(tryAgain);
       
   946     }
       
   947     if(insertKeyIntoSessionList) {
       
   948         //The session will only keep track of cssFiles that were either successfully found or were
       
   949         //successfully inserted in the cache. 
       
   950         sessionCssData.append(cssFileName);
       
   951         }
       
   952     TPckg<HbSharedStyleSheetInfo> data(offsetInfo);
       
   953     aMessage.WriteL(2, data);
       
   954 }
       
   955 
       
   956 /**
       
   957  * HandleWidgetMLLookUp
       
   958  */
       
   959 void HbSymbianThemeServSession::HandleWidgetMLLookupL(const RMessage2& aMessage)
       
   960 {
       
   961     if (aMessage.GetDesLength(0) == 0) {
       
   962         return;
       
   963     }
       
   964 
       
   965     TBuf<256> fileName;
       
   966     aMessage.ReadL(0, fileName, 0);
       
   967     TBuf<256> layoutName;
       
   968     aMessage.ReadL(1, layoutName, 0);
       
   969     TBuf<256> sectionName;
       
   970     aMessage.ReadL(2, sectionName, 0);
       
   971 
       
   972     QString wmlFileName((QChar*)fileName.Ptr(), fileName.Length());
       
   973     QString layout((QChar*)layoutName.Ptr(), layoutName.Length());
       
   974     QString section((QChar*)sectionName.Ptr(), sectionName.Length());
       
   975 
       
   976     HbSharedWMLInfo offsetInfo;
       
   977     offsetInfo.offset = HbThemeServerUtils::getSharedLayoutDefinition(wmlFileName,layout,section);
       
   978     TPckg<HbSharedWMLInfo> data(offsetInfo);
       
   979     aMessage.WriteL(3, data);
       
   980 }
       
   981 
       
   982 
       
   983 /**
       
   984  * Handle DeviceProfiles Request.
       
   985  */
       
   986 void HbSymbianThemeServSession::HandleDeviceProfilesReqL(const RMessage2& aMessage)
       
   987 {
       
   988     HbDeviceProfileInfo offsetInfo;
       
   989     HbDeviceProfileDatabase *deviceProfileDatabase = HbDeviceProfileDatabase::instance(HbMemoryManager::SharedMemory);
       
   990     if(deviceProfileDatabase) {
       
   991     	offsetInfo.offset = deviceProfileDatabase->deviceProfilesOffset();
       
   992     } else {
       
   993     	offsetInfo.offset = -1;
       
   994     }
       
   995     TPckg<HbDeviceProfileInfo> data(offsetInfo);
       
   996     aMessage.WriteL(0, data);
       
   997 }
       
   998 
       
   999 /**
       
  1000  * Handle SecondaryCacheOffset Request.
       
  1001  */
       
  1002 void HbSymbianThemeServSession::HandleSecondaryCacheOffsetReqL(const RMessage2& aMessage)
       
  1003 {
       
  1004     SecondaryCacheInfo offsetInfo;
       
  1005     offsetInfo.offset = HbThemeServerUtils::sharedCacheOffset();
       
  1006     TPckg<SecondaryCacheInfo> data(offsetInfo);
       
  1007     aMessage.WriteL(0, data);
       
  1008 }
       
  1009 
       
  1010 /**
       
  1011  * HandleEffectAddAndFileLookupL
       
  1012  */
       
  1013 void HbSymbianThemeServSession::HandleEffectAddAndFileLookupL(const RMessage2& aMessage)
       
  1014 {
       
  1015     TInt fileNameLength = aMessage.GetDesLength(0);
       
  1016     if (fileNameLength == 0) {
       
  1017         return;
       
  1018     }
       
  1019 
       
  1020     TFileName fileName;
       
  1021     aMessage.ReadL(0, fileName, 0);
       
  1022     QString effFileName((QChar*)fileName.Ptr(), fileName.Length()); 
       
  1023     HbSharedEffectInfo offsetInfo;
       
  1024     offsetInfo.offset = HbThemeServerUtils::getSharedEffect(effFileName);
       
  1025     TPckg<HbSharedEffectInfo> data(offsetInfo);
       
  1026     aMessage.WriteL(1, data);
       
  1027 }
       
  1028 
       
  1029 void HbSymbianThemeServSession::GetSharedIconDefaultSizeInfoL(const RMessage2 &aMessage)
       
  1030 {
       
  1031     TIconParams params = ReadMessageAndRetrieveParams(aMessage);
       
  1032 
       
  1033     // Need to be allocated from heap or the leave in the end causes a crash
       
  1034     QScopedPointer<QString> filenamePtr(new QString((QChar*)params.fileName.Ptr(), params.fileName.Length()));
       
  1035     
       
  1036     // See if the icon's default size has been queried already earlier and
       
  1037     // can be found stored in the hash.
       
  1038 
       
  1039     QSizeF defSize = iServer->iconDefaultSizeCacheItem(*filenamePtr.data());
       
  1040                     
       
  1041     if (!defSize.isValid()) {
       
  1042         defSize = RetrieveIconDefaultSize(*filenamePtr.data());
       
  1043 
       
  1044         // If the default size was retrieved, insert it in the hash for further lookups
       
  1045         if (defSize.isValid()) {
       
  1046             iServer->insertIconDefaultSizeCacheItem(*filenamePtr.data(), defSize);
       
  1047         }
       
  1048     }
       
  1049     
       
  1050     // Return the default size back to the client if it was resolved
       
  1051     if (defSize.isValid()) {    
       
  1052         TPckg<QSizeF> returnData(defSize);
       
  1053         aMessage.WriteL(1, returnData);
       
  1054 #ifdef THEME_SERVER_TRACES 
       
  1055         qDebug() << "Completed aMessage.WriteL";
       
  1056 #endif
       
  1057     }
       
  1058     // Otherwise leave with error code
       
  1059     else {
       
  1060         User::Leave(KErrNotFound);
       
  1061     }
       
  1062 }
       
  1063 
       
  1064 QSizeF HbSymbianThemeServSession::RetrieveIconDefaultSize(const QString &filename)
       
  1065 {
       
  1066     QSizeF ret;
       
  1067 
       
  1068     // Get icon source, previous icons sources are cached so if accessed again,
       
  1069     // they don't need to be loaded and parsed from a file always.
       
  1070     HbIconSource *source = HbThemeServerUtils::getIconSource(filename);
       
  1071     if (source) {
       
  1072         ret = source->defaultSize();
       
  1073     }
       
  1074 
       
  1075     return ret;
       
  1076 }
       
  1077 
       
  1078 /**
       
  1079  * GetSharedIconInfoL
       
  1080  */
       
  1081 void HbSymbianThemeServSession::GetSharedIconInfoL(const RMessage2& aMessage)
       
  1082 {
       
  1083     HbSharedIconInfo data;
       
  1084     TIconParams params = ReadMessageAndRetrieveParams(aMessage);
       
  1085 
       
  1086     QString filename((QChar*)params.fileName.Ptr(), params.fileName.Length());
       
  1087     QColor color = GetColorFromRgba(params.rgba,params.colorflag);
       
  1088     HbIconKey key(filename, QSizeF(params.width, params.height), 
       
  1089                     (Qt::AspectRatioMode)params.aspectRatioMode,
       
  1090                     (QIcon::Mode)params.mode, params.mirrored, color);
       
  1091                     
       
  1092     HbIconCacheItem* cacheItem = iServer->iconCacheItem(key);
       
  1093     bool insertKeyIntoSessionList = false;  
       
  1094     if ( cacheItem ) {
       
  1095         insertKeyIntoSessionList = true; //The item was found in the cache and ref count was incremented
       
  1096         if(cacheItem->rasterIconData.type != INVALID_FORMAT ) {
       
  1097             data = cacheItem->rasterIconData;
       
  1098         } else if( cacheItem->vectorIconData.type != INVALID_FORMAT ) {
       
  1099             data = cacheItem->vectorIconData;
       
  1100         } else if (cacheItem->blobIconData.type != INVALID_FORMAT) {
       
  1101             data = cacheItem->blobIconData;
       
  1102         } else {
       
  1103             data.type = INVALID_FORMAT;
       
  1104         } 
       
  1105     } else {
       
  1106         QString format = HbThemeServerUtils::formatFromPath( key.filename );
       
  1107         cacheItem = HbIconCacheItemCreator::createCacheItem( key, 
       
  1108                           (HbIconLoader::IconLoaderOptions)params.options, format);
       
  1109         if( cacheItem) {
       
  1110             if( cacheItem->rasterIconData.type != INVALID_FORMAT) {
       
  1111                 data = cacheItem->rasterIconData;
       
  1112             } else if( cacheItem->vectorIconData.type != INVALID_FORMAT ) {
       
  1113                 data = cacheItem->vectorIconData;
       
  1114             } else if (cacheItem->blobIconData.type != INVALID_FORMAT) {
       
  1115                 data = cacheItem->blobIconData;
       
  1116             } else {
       
  1117                 data.type = INVALID_FORMAT;
       
  1118             }
       
  1119             if( data.type != INVALID_FORMAT ) {
       
  1120                 insertKeyIntoSessionList = iServer->insertIconCacheItem(key, cacheItem);
       
  1121                 if (!insertKeyIntoSessionList ) {
       
  1122                     FreeDataFromCacheItem(cacheItem);
       
  1123                     delete cacheItem; // do delete the item after gpu/cpu memory is freed
       
  1124                     data.type = INVALID_FORMAT;
       
  1125                 }
       
  1126             }
       
  1127         }
       
  1128     }
       
  1129     if(insertKeyIntoSessionList) {
       
  1130         //The session will only keep track of icons that were either successfully found or were
       
  1131         //successfully inserted in the cache.       
       
  1132         sessionData.append(key);
       
  1133     }
       
  1134     // create dshared pixmap info from HbIconCacheItem  
       
  1135     TPckg<HbSharedIconInfo> pixdata(data);
       
  1136     aMessage.WriteL(1, pixdata);
       
  1137     
       
  1138 #ifdef THEME_SERVER_TRACES 
       
  1139     qDebug() << "Completed  aMessage.WriteL";
       
  1140 #endif
       
  1141 }
       
  1142 
       
  1143 /**
       
  1144  * handleThemeSelectionL
       
  1145  */
       
  1146 void HbSymbianThemeServSession::HandleThemeSelectionL(const RMessage2& aMessage)
       
  1147 {
       
  1148     TInt deslen = aMessage.GetDesLength(0);
       
  1149     RBuf buffer;
       
  1150     buffer.CreateL(deslen);
       
  1151     buffer.CleanupClosePushL();
       
  1152     aMessage.ReadL(0, buffer, 0);
       
  1153     if (buffer.Length() == 0) {
       
  1154         User::Leave(ENonNumericString);
       
  1155     }
       
  1156     QString newTheme((QChar*)buffer.Ptr(), buffer.Length());
       
  1157     CleanupStack::PopAndDestroy(); // close the buffer
       
  1158 
       
  1159     QString cleanThemeName = newTheme.trimmed();    
       
  1160     
       
  1161     if (cleanThemeName == iServer->iCurrentThemeName) {
       
  1162         // Theme did not change, return.
       
  1163         return;
       
  1164     }
       
  1165     // ToDo: Validate the theme name somehow
       
  1166 
       
  1167     iServer->iCurrentThemeName = cleanThemeName;
       
  1168     
       
  1169     // Resolve the drive letter of the current theme
       
  1170     iServer->resolveCurrentThemeDrive();
       
  1171 
       
  1172     iServer->currentIndexfile.close();
       
  1173     // Open index file to prevent uninstallation of the active theme
       
  1174     iServer->openCurrentIndexFile();
       
  1175 
       
  1176     QSettings settings(QLatin1String(ORGANIZATION), QLatin1String(THEME_COMPONENT));    
       
  1177     settings.setValue("currenttheme", cleanThemeName); 
       
  1178     settings.sync();
       
  1179     TPtrC name(reinterpret_cast<const TUint16 *>(cleanThemeName.constData()));
       
  1180     TInt err = iServer->iThemeProperty.Set(name);
       
  1181     User::LeaveIfError(err);
       
  1182 }
       
  1183 
       
  1184 /**
       
  1185  * Panics the client
       
  1186  */
       
  1187 void HbSymbianThemeServSession::PanicClient(const RMessage2& aMessage, TInt aPanic) const
       
  1188 {
       
  1189     _LIT(KTxtServer, "Theme server");
       
  1190     aMessage.Panic(KTxtServer, aPanic);
       
  1191 }
       
  1192 
       
  1193 QColor HbSymbianThemeServSession::GetColorFromRgba(TUint32 aRgba,bool aColorFlag) 
       
  1194 {
       
  1195     QColor color;
       
  1196     if(aColorFlag){
       
  1197         color.setRgba((QRgb)aRgba);
       
  1198     }
       
  1199     return color;
       
  1200 }
       
  1201 
       
  1202 /**
       
  1203  * HbThemeServerSymbian::GetSharedMultiIconInfoL
       
  1204   Creates a consolidated icon of the frame item pieces , 
       
  1205   if failed to do so creates a icons of the pieces provided 
       
  1206   there is enough space in the cache and shared memory.
       
  1207  */
       
  1208 void HbSymbianThemeServSession::GetSharedMultiIconInfoL(const RMessage2& aMessage)
       
  1209 {
       
  1210     HbSharedIconInfo stitchedData;
       
  1211     stitchedData.type = INVALID_FORMAT;
       
  1212     QVector<HbIconKey> insertedKeys;
       
  1213     TMultiIconSymbParams params = ReadMessageAndRetrieveMultiIconParams(aMessage);
       
  1214 
       
  1215     QColor color = GetColorFromRgba(params.rgba, params.colorflag);
       
  1216     QString iconId((QChar*)params.multiPartIconId.Ptr(), params.multiPartIconId.Length());
       
  1217     QString fullPath((QChar*)params.multiPartIconList[0].Ptr(), params.multiPartIconList[0].Length());
       
  1218     int index = fullPath.lastIndexOf("/");
       
  1219     fullPath = fullPath.left(index + 1);
       
  1220     iconId.prepend(fullPath);
       
  1221     HbIconKey finalIconKey(iconId,
       
  1222                    (QSizeF)params.size,
       
  1223                    (Qt::AspectRatioMode)params.aspectRatioMode,
       
  1224                    (QIcon::Mode)params.mode,
       
  1225                    (bool)params.mirrored,
       
  1226                    color);
       
  1227 
       
  1228     if (!IconInfoFromSingleIcon( finalIconKey, stitchedData)) {
       
  1229         HbMultiIconParams frameItemParams;
       
  1230         int noOfPieces = 1;
       
  1231         if (iconId.contains("_3PV",Qt::CaseInsensitive) || iconId.contains("_3PH",Qt::CaseInsensitive)) {
       
  1232             noOfPieces = 3;
       
  1233         } else if (iconId.contains("_9P",Qt::CaseInsensitive)) {
       
  1234             noOfPieces = 9;
       
  1235         }
       
  1236 
       
  1237         frameItemParams.multiPartIconId = iconId;
       
  1238         frameItemParams.aspectRatioMode = (Qt::AspectRatioMode)params.aspectRatioMode;
       
  1239         frameItemParams.colorflag = params.colorflag;
       
  1240         frameItemParams.mirrored = (bool)params.mirrored;
       
  1241         frameItemParams.options = params.options;
       
  1242         frameItemParams.rgba = params.rgba;
       
  1243         frameItemParams.mode = (QIcon::Mode)params.mode;
       
  1244         frameItemParams.size = (QSizeF)params.size;
       
  1245         frameItemParams.color = color;
       
  1246         for (int i = 0; i < noOfPieces; i++) {
       
  1247             frameItemParams.multiPartIconData.pixmapSizes[i] = (QSize &)params.pixmapSizes[i];
       
  1248         }
       
  1249 
       
  1250         for (int i = 0; i < noOfPieces; i++) {
       
  1251             frameItemParams.multiPartIconData.targets[i] = (QRect &)params.targets[i];
       
  1252         }
       
  1253 
       
  1254         for (int i = 0; i < noOfPieces; i++) {
       
  1255             frameItemParams.multiPartIconData.sources[i] = (QRect &)params.sources[i];
       
  1256         }
       
  1257 
       
  1258         for (int i = 0; i < noOfPieces; i++) {
       
  1259             QString pieceName((QChar*)params.multiPartIconList[i].Ptr(), params.multiPartIconList[i].Length());
       
  1260             frameItemParams.multiPartIconList.append(pieceName);                
       
  1261         }
       
  1262 
       
  1263         IconInfoFromMultiParts(frameItemParams, noOfPieces, finalIconKey, stitchedData);
       
  1264     }
       
  1265 
       
  1266      // create dshared pixmap info from HbIconCacheItem  
       
  1267      TPckg<HbSharedIconInfo> pixdata(stitchedData);
       
  1268      aMessage.WriteL(1,pixdata);
       
  1269 }
       
  1270 
       
  1271 /**
       
  1272  * HbThemeServerSymbian::IconInfoFromSingleIcon
       
  1273   Checks for the cacheItem for a given key, if found gets the data relevant of the cacheItem.
       
  1274  */
       
  1275 
       
  1276 bool HbSymbianThemeServSession::IconInfoFromSingleIcon(HbIconKey key,
       
  1277                 HbSharedIconInfo &stitchedData)
       
  1278 {
       
  1279     stitchedData.type = INVALID_FORMAT;
       
  1280     HbIconCacheItem * cacheItem = iServer->iconCacheItem(key, true);
       
  1281     if (cacheItem) {
       
  1282         GetDataFromCacheItem(cacheItem, stitchedData );
       
  1283         return true; //The item was found in the cache and ref count was incremented
       
  1284     } 
       
  1285     return false;
       
  1286 }
       
  1287     
       
  1288 /**
       
  1289  * HbThemeServerSymbian::createCacheItemData
       
  1290   Creates a cacheItem of the given key and insert the item in to the list 
       
  1291   else free the data allocated for the cache.
       
  1292  */
       
  1293     
       
  1294 bool HbSymbianThemeServSession::CreateCacheItemData(HbIconKey key, int options ,HbSharedIconInfo &data, bool isMultiIcon)
       
  1295 {
       
  1296     bool insertKeyIntoSessionList = false;
       
  1297     data.type = INVALID_FORMAT;
       
  1298     QString format = HbThemeServerUtils::formatFromPath( key.filename );
       
  1299     HbIconCacheItem * cacheItemOfPiece = iServer->iconCacheItem(key, isMultiIcon);
       
  1300     if (cacheItemOfPiece) {
       
  1301         GetDataFromCacheItem(cacheItemOfPiece, data);
       
  1302         insertKeyIntoSessionList = true;
       
  1303     }
       
  1304     else {
       
  1305     cacheItemOfPiece = HbIconCacheItemCreator::createCacheItem(key, 
       
  1306                                             (HbIconLoader::IconLoaderOptions)options, format, isMultiIcon);
       
  1307     if (cacheItemOfPiece) {
       
  1308         GetDataFromCacheItem(cacheItemOfPiece, data);
       
  1309         if (data.type != INVALID_FORMAT) {
       
  1310             insertKeyIntoSessionList = iServer->insertIconCacheItem(key, cacheItemOfPiece);
       
  1311             if (!insertKeyIntoSessionList) {
       
  1312                 //if insertion failed free the memory
       
  1313                 FreeDataFromCacheItem(cacheItemOfPiece);
       
  1314                 delete cacheItemOfPiece; // do delete the item after gpu/cpu memory is freed
       
  1315                 data.type = INVALID_FORMAT;
       
  1316                 }
       
  1317             }
       
  1318         }
       
  1319     }
       
  1320     return insertKeyIntoSessionList;
       
  1321 }
       
  1322 
       
  1323 /**
       
  1324  * HbThemeServerSymbian::CreateStichedIconInfoOfParts
       
  1325   Creates a consolidated icon of the availble piece iconInfo.
       
  1326  */
       
  1327 
       
  1328 bool HbSymbianThemeServSession::CreateStichedIconInfoOfParts(QVector<HbSharedIconInfo> dataForParts,HbMultiIconParams params,
       
  1329                                                             HbIconKey &finalIconKey, HbSharedIconInfo &stitchedData)
       
  1330 {
       
  1331     bool insertKeyIntoSessionList = false;
       
  1332     stitchedData.type = INVALID_FORMAT;
       
  1333     QString format = HbThemeServerUtils::formatFromPath( params.multiPartIconList[0] );
       
  1334     
       
  1335     HbIconCacheItem * cacheItem = HbIconCacheItemCreator::createMultiPieceCacheItem(finalIconKey, (HbIconLoader::IconLoaderOptions)params.options, format,dataForParts, params);
       
  1336     if( cacheItem) {
       
  1337         if( cacheItem->rasterIconData.type == INVALID_FORMAT) {
       
  1338             return false;
       
  1339         }
       
  1340     }    
       
  1341 
       
  1342     stitchedData = cacheItem->rasterIconData;
       
  1343     if (stitchedData.type != INVALID_FORMAT) {
       
  1344         insertKeyIntoSessionList = iServer->insertIconCacheItem(finalIconKey, cacheItem);
       
  1345         if (!insertKeyIntoSessionList) {
       
  1346                 //if insertion failed free the memory
       
  1347             FreeDataFromCacheItem(cacheItem);
       
  1348             delete cacheItem; // do delete the item after gpu/cpu memory is freed
       
  1349             stitchedData.type = INVALID_FORMAT;
       
  1350         }
       
  1351     }
       
  1352 
       
  1353     return insertKeyIntoSessionList;
       
  1354 }
       
  1355 
       
  1356 /**
       
  1357  * HbThemeServerSymbian::iconInfoFromMultiParts
       
  1358   Creates a shared IconInfo of the piece files of a frame item and 
       
  1359   tries to create a stiched icon of the same.
       
  1360  */
       
  1361 
       
  1362 void HbSymbianThemeServSession::IconInfoFromMultiParts(const HbMultiIconParams &frameItemParams,
       
  1363                 const int noOfPieces,
       
  1364                 HbIconKey &stichedKey,
       
  1365                 HbSharedIconInfo &stitchedData)
       
  1366 {
       
  1367     QVector<HbIconKey> keysInserted;
       
  1368     QVector<HbSharedIconInfo> dataForParts;
       
  1369     bool insertKeyIntoSessionList = false;
       
  1370     bool failedToCreateParts = false;
       
  1371     QString format;
       
  1372 
       
  1373 
       
  1374     for(int i = 0; i < noOfPieces;i++) {
       
  1375         HbSharedIconInfo data;
       
  1376         bool iconPieceMirrored = false;
       
  1377         HbIconKey key(frameItemParams.multiPartIconList.at(i), frameItemParams.multiPartIconData.pixmapSizes[i], (Qt::AspectRatioMode)stichedKey.aspectRatioMode, (QIcon::Mode)stichedKey.mode, iconPieceMirrored, stichedKey.color);
       
  1378         insertKeyIntoSessionList = IconInfoFromSingleIcon(key, data);
       
  1379         if (!insertKeyIntoSessionList) {
       
  1380             insertKeyIntoSessionList = CreateCacheItemData(key, frameItemParams.options, data, true);
       
  1381         }
       
  1382         if ((data.type == INVALID_FORMAT) || (!insertKeyIntoSessionList)) {
       
  1383             failedToCreateParts = true;
       
  1384             break;
       
  1385         } else {
       
  1386             //The session will only keep track of icons that were either successfully found or were
       
  1387             //successfully inserted in the cache.
       
  1388             keysInserted.append(key);
       
  1389             dataForParts.append(data);
       
  1390         }
       
  1391     }//end of for
       
  1392     
       
  1393     int dataPartCount = dataForParts.count();
       
  1394     if ((failedToCreateParts) || (dataPartCount != noOfPieces)|| (!insertKeyIntoSessionList)) {
       
  1395         //atLeast one of the icon did'nt get constructed , so move the cached piece icons to unused state and return
       
  1396     QVector<HbIconKey>::const_iterator itEnd( keysInserted.constEnd() );
       
  1397             for ( QVector<HbIconKey>::const_iterator iter = keysInserted.constBegin();
       
  1398                     iter != itEnd;
       
  1399                     ++iter ) {
       
  1400                         iServer->CleanupSessionIconItem(*iter);
       
  1401             }          
       
  1402         stitchedData.type = INVALID_FORMAT;
       
  1403         return;
       
  1404     } 
       
  1405 // Create a stitched icon of the available piece shared iconinfos
       
  1406     if ((dataPartCount == noOfPieces)&& (!failedToCreateParts) &&         
       
  1407         (CreateStichedIconInfoOfParts(dataForParts, frameItemParams, stichedKey, stitchedData))) {
       
  1408             sessionData.append(stichedKey);
       
  1409         }
       
  1410     
       
  1411     QVector<HbIconKey>::const_iterator itEnd( keysInserted.constEnd() );
       
  1412        for ( QVector<HbIconKey>::const_iterator iter = keysInserted.constBegin();
       
  1413                iter != itEnd;
       
  1414                ++iter ) {
       
  1415                    iServer->CleanupSessionIconItem(*iter);
       
  1416        }   
       
  1417 }
       
  1418 
       
  1419 /**
       
  1420  * HbThemeServerSymbian::FreeDataFromCacheItem
       
  1421  *Frees data from the cached item when insertion to the list fails.
       
  1422  */
       
  1423 void HbSymbianThemeServSession::FreeDataFromCacheItem(HbIconCacheItem* cacheItem)
       
  1424 {
       
  1425     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory)
       
  1426     if ( cacheItem->rasterIconData.type != INVALID_FORMAT ) {
       
  1427         switch(cacheItem->rasterIconData.type) {
       
  1428         case PIC :
       
  1429             manager->free(cacheItem->rasterIconData.picData.offset);
       
  1430         break;
       
  1431         case NVG :
       
  1432             manager->free(cacheItem->rasterIconData.nvgData.offset);
       
  1433         break;
       
  1434         case OTHER_SUPPORTED_FORMATS :
       
  1435             manager->free(cacheItem->rasterIconData.pixmapData.offset);
       
  1436         break;
       
  1437         default:
       
  1438         break;
       
  1439         }
       
  1440     }
       
  1441     if ( cacheItem->vectorIconData.type != INVALID_FORMAT ) {
       
  1442         switch(cacheItem->vectorIconData.type) {
       
  1443         case PIC :
       
  1444             manager->free(cacheItem->vectorIconData.picData.offset);
       
  1445         break;
       
  1446         case NVG :
       
  1447             manager->free(cacheItem->vectorIconData.nvgData.offset);
       
  1448         break;
       
  1449         case OTHER_SUPPORTED_FORMATS :
       
  1450             manager->free(cacheItem->vectorIconData.pixmapData.offset);
       
  1451         break;
       
  1452         default:
       
  1453         break;
       
  1454         }
       
  1455     }
       
  1456     if (cacheItem->blobIconData.type == BLOB) {
       
  1457         manager->free(cacheItem->blobIconData.blobData.offset);
       
  1458     }
       
  1459 }
       
  1460 
       
  1461 /**
       
  1462  * HbThemeServerSymbian::GetDataFromCacheItem
       
  1463  * Gets data from the cache Item.
       
  1464  */
       
  1465 
       
  1466 // Code to get data from the cached item
       
  1467 void HbSymbianThemeServSession::GetDataFromCacheItem(HbIconCacheItem* cacheItem, HbSharedIconInfo &data ) const
       
  1468 {
       
  1469     if ( cacheItem) {
       
  1470         if ( cacheItem->rasterIconData.type != INVALID_FORMAT) {
       
  1471             data = cacheItem->rasterIconData;
       
  1472         } else if ( cacheItem->vectorIconData.type != INVALID_FORMAT ) {
       
  1473             data = cacheItem->vectorIconData;
       
  1474         } else if (cacheItem->blobIconData.type != INVALID_FORMAT) {
       
  1475             data = cacheItem->blobIconData;
       
  1476         } else {
       
  1477             data.type = INVALID_FORMAT;
       
  1478         }
       
  1479     }
       
  1480 }
       
  1481 
       
  1482 /**
       
  1483  * HbThemeServerSymbian::ReadMessageAndRetrieveMultiIconParams
       
  1484  * 
       
  1485  * Reads all the information from client.
       
  1486  */
       
  1487     
       
  1488 TMultiIconSymbParams HbSymbianThemeServSession::ReadMessageAndRetrieveMultiIconParams(const RMessage2& aMessage)
       
  1489 {
       
  1490     TInt deslen = aMessage.GetDesLength(0);
       
  1491     TMultiIconSymbParams params;
       
  1492     TPckg<TMultiIconSymbParams> paramPckg(params);
       
  1493     // Copy the client's descriptor data into our buffer.
       
  1494     aMessage.ReadL(0,paramPckg,0);
       
  1495     return params;
       
  1496 }