src/hbservers/hbthemeserver/hbthemeserverutils.cpp
changeset 21 4633027730f5
parent 5 627c4a0fd0e7
child 28 b7da29130b0e
equal deleted inserted replaced
7:923ff622b8b9 21:4633027730f5
    35 #include "hbcssparser_p.h"
    35 #include "hbcssparser_p.h"
    36 #include "hbeffectfxmldata_p.h"
    36 #include "hbeffectfxmldata_p.h"
    37 #include "hbeffectxmlparser_p.h"
    37 #include "hbeffectxmlparser_p.h"
    38 #include "hbdeviceprofiledatabase_p.h"
    38 #include "hbdeviceprofiledatabase_p.h"
    39 #include "hbthemeperf_p.h"
    39 #include "hbthemeperf_p.h"
    40 #include "hbcache_p.h"
       
    41 #include "hbiconsource_p.h"
    40 #include "hbiconsource_p.h"
    42 #include "hbwidgetloader_p.h"
    41 #include "hbwidgetloader_p.h"
    43 #include "hbwidgetloaderactions_p.h"
    42 #include "hbwidgetloaderactions_p.h"
    44 #include "hbthemeindex_p.h"
    43 #include "hbthemeindex_p.h"
    45 
    44 
    51 // cache at the server side to maintain the offsets for
    50 // cache at the server side to maintain the offsets for
    52 // the filename,layout and section combination.
    51 // the filename,layout and section combination.
    53 typedef QHash<QString, int> ServerHashForLayoutDefs;
    52 typedef QHash<QString, int> ServerHashForLayoutDefs;
    54 Q_GLOBAL_STATIC(ServerHashForLayoutDefs, layoutDefsCache)
    53 Q_GLOBAL_STATIC(ServerHashForLayoutDefs, layoutDefsCache)
    55 
    54 
       
    55 // Offset for the cache of the missed CSS files for classes starting 'hb'
       
    56 static int missedHbCssFilesOffset = -1;
       
    57 static const QString HB_CLASSNAME_PREFIX("hb");
       
    58 
    56 static const int ICON_SOURCES_MAX_SIZE = 8;
    59 static const int ICON_SOURCES_MAX_SIZE = 8;
    57 static QList<HbIconSource *> iconSources; // cache of recently used icon sources
    60 static QList<HbIconSource *> iconSources; // cache of recently used icon sources
    58 
    61 
    59 HbIconSource *HbThemeServerUtils::getIconSource(const QString &filename)
    62 HbIconSource *HbThemeServerUtils::getIconSource(const QString &filename)
    60 {
    63 {
   105  * \return offset of the shared style sheet in the shared memory, -1 if error
   108  * \return offset of the shared style sheet in the shared memory, -1 if error
   106  *
   109  *
   107  */
   110  */
   108 int HbThemeServerUtils::getSharedStylesheet(const QString &fileName,
   111 int HbThemeServerUtils::getSharedStylesheet(const QString &fileName,
   109                                             HbLayeredStyleLoader::LayerPriority priority,
   112                                             HbLayeredStyleLoader::LayerPriority priority,
       
   113                                             bool &fileExists,
   110                                             bool *inSharedCache)
   114                                             bool *inSharedCache)
   111 {
   115 {
   112     int cssOffset = -1;
   116     qptrdiff cssOffset = -1;
   113     HbSharedCache *sharedCache = 0;
   117     HbSharedCache *sharedCache = 0;
   114     if (priority == HbLayeredStyleLoader::Priority_Core) {
   118     if (priority == HbLayeredStyleLoader::Priority_Core) {
   115         sharedCache = HbSharedCache::instance();
   119         sharedCache = HbSharedCache::instance();
   116         cssOffset = sharedCache->offset(HbSharedCache::Stylesheet, fileName);
   120         cssOffset = sharedCache->offset(HbSharedCache::Stylesheet, fileName);
   117         if (inSharedCache) {
   121         if (inSharedCache) {
   123 
   127 
   124 #ifdef THEME_SERVER_TRACES
   128 #ifdef THEME_SERVER_TRACES
   125     qDebug() << "In " << Q_FUNC_INFO;
   129     qDebug() << "In " << Q_FUNC_INFO;
   126 #endif // THEME_SERVER_TRACES
   130 #endif // THEME_SERVER_TRACES
   127     if (cssOffset < 0) {
   131     if (cssOffset < 0) {
   128         if (QFile::exists(fileName)) {
   132         HbCss::Parser parser;
   129             HbCss::Parser parser;
   133         if (!parseCssFile(parser, fileName, cssOffset, fileExists)) {
   130             if (!parseCssFile(parser, fileName, cssOffset)) {
   134             if (parser.errorCode == HbCss::Parser::OutOfMemoryError) {
   131                 if (parser.errorCode == HbCss::Parser::OutOfMemoryError) {
   135                 return OUT_OF_MEMORY_ERROR;
   132                     return OUT_OF_MEMORY_ERROR;
       
   133                 }
       
   134             }
   136             }
   135         }
   137         }
   136         if (sharedCache) { //sharedCache valid only when priority is Priority_Core
   138         if (sharedCache) { //sharedCache valid only when priority is Priority_Core
   137             sharedCache->add(HbSharedCache::Stylesheet, fileName, cssOffset);
   139             sharedCache->add(HbSharedCache::Stylesheet, fileName, cssOffset);
   138         }
   140         }
   139     }
   141     }
   140     return cssOffset;
   142     return cssOffset;
   141 }
   143 }
   142 
   144 
       
   145 /*
       
   146  * Returns the offset of the missed CSS files for widgets starting with 'hb'
       
   147  */
       
   148 int HbThemeServerUtils::getMissedHbCssFilesOffset()
       
   149 {
       
   150     if (missedHbCssFilesOffset < 0) {
       
   151         initMissedHbCssFilesList();
       
   152     }
       
   153     return missedHbCssFilesOffset;
       
   154 }
       
   155 
       
   156 void HbThemeServerUtils::initMissedHbCssFilesList()
       
   157 {
       
   158     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
       
   159     int offset = -1;
       
   160     try {
       
   161         offset = manager->alloc(sizeof(HbVector<uint>));
       
   162         HbVector<uint> *list = new((char*)manager->base() + offset)
       
   163                 HbVector<uint>(HbMemoryManager::SharedMemory);
       
   164     } catch (std::bad_alloc &) {
       
   165         if (offset >= 0) {
       
   166             manager->free(offset);
       
   167             offset = -1;
       
   168         }
       
   169     }
       
   170     missedHbCssFilesOffset = offset;
       
   171 }
       
   172 
   143 /**
   173 /**
   144  * HbThemeServerUtils::parseCssFile()
   174  * HbThemeServerUtils::parseCssFile()
   145  *
   175  *
   146  * Returns false in case Css file has some error or there is not enough memory
   176  * Returns false in case Css file has some error or there is not enough memory
   147  */
   177  */
   148 bool HbThemeServerUtils::parseCssFile(HbCss::Parser &parser, const QString &fileName,
   178 bool HbThemeServerUtils::parseCssFile(HbCss::Parser &parser, const QString &fileName,
   149                                       int &cssOffset)
   179                                       qptrdiff &cssOffset, bool &fileExists)
   150 {
   180 {
   151     bool retVal = false;
   181     bool retVal = false;
   152     // 1. Create a styleSheet in shared memory
   182     // 1. Create a styleSheet in shared memory
   153     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory) ;
   183     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory) ;
   154     HB_START_SHAREDMEMORY_PRINT("");
   184     HB_START_SHAREDMEMORY_PRINT("");
   166             cssOffset = -1;
   196             cssOffset = -1;
   167         }
   197         }
   168         return retVal;
   198         return retVal;
   169     }
   199     }
   170     // 2. Parse the required file into styleSheet.
   200     // 2. Parse the required file into styleSheet.
   171     parser.init(fileName, true);
   201     fileExists = parser.init(fileName, true);
       
   202     if (!fileExists) {
       
   203         if (QFileInfo(fileName).fileName().startsWith(HB_CLASSNAME_PREFIX)) {
       
   204             HbVector<uint> *list = HbMemoryUtils::getAddress<HbVector<uint> >(
       
   205                 HbMemoryManager::SharedMemory, getMissedHbCssFilesOffset());
       
   206             if (list) {
       
   207                 list->append(qHash(fileName));
       
   208             }
       
   209         }
       
   210         if (cssOffset != -1) {
       
   211             manager->free(cssOffset);
       
   212             cssOffset = -1;
       
   213         }
       
   214         return retVal;
       
   215     }
   172     
   216     
   173     retVal = parser.parse(styleSheet);
   217     retVal = parser.parse(styleSheet);
   174     if (!retVal) {
   218     if (!retVal) {
   175         //parser::parse returns false in a number of scenarios
   219         //parser::parse returns false in a number of scenarios
   176         // 1. css file has some error
   220         // 1. css file has some error
   187 /*
   231 /*
   188   Returns of the offset for the given filename,layout and section name.
   232   Returns of the offset for the given filename,layout and section name.
   189  */
   233  */
   190 
   234 
   191 int HbThemeServerUtils::getSharedLayoutDefinition(const QString &fileName, const QString &layout,
   235 int HbThemeServerUtils::getSharedLayoutDefinition(const QString &fileName, const QString &layout,
   192                                                   const QString &section)
   236                                                   const QString &section, bool &fileExists)
   193 {
   237 {
   194     int layoutDefOffset = -1;
   238     qptrdiff layoutDefOffset = -1;
   195     QStringRef nameKey(&fileName);
   239     QStringRef nameKey(&fileName);
   196     if (nameKey.at(0) == ':') {
   240     if (nameKey.at(0) == ':') {
   197         //use only filename as a key.
   241         //use only filename as a key.
   198         int index = fileName.lastIndexOf('/');
   242         int index = fileName.lastIndexOf('/');
   199         if (index >= 0) {
   243         if (index >= 0) {
   216         return layoutDefOffset;
   260         return layoutDefOffset;
   217     }
   261     }
   218     HbWidgetLoader loader;
   262     HbWidgetLoader loader;
   219 
   263 
   220     QFile file(fileName);
   264     QFile file(fileName);
   221     if (!file.open(QFile::ReadOnly | QFile::Text)) {
   265     fileExists = file.open(QFile::ReadOnly | QFile::Text);
       
   266     if (!fileExists) {
       
   267 #ifdef THEME_SERVER_TRACES
   222         qWarning("Unable to open file");
   268         qWarning("Unable to open file");
       
   269 #endif
   223         return -1;
   270         return -1;
   224     }
   271     }
   225 #ifdef THEME_SERVER_TRACES
   272 #ifdef THEME_SERVER_TRACES
   226     qDebug() << "Trying to load: " << fileName << "::" << layout << "::" << section;
   273     qDebug() << "Trying to load: " << fileName << "::" << layout << "::" << section;
   227 #endif // THEME_SERVER_TRACES
   274 #endif // THEME_SERVER_TRACES
   309 {
   356 {
   310 #ifdef THEME_SERVER_TRACES
   357 #ifdef THEME_SERVER_TRACES
   311     qDebug() << "In " << Q_FUNC_INFO << fileName;
   358     qDebug() << "In " << Q_FUNC_INFO << fileName;
   312 #endif // THEME_SERVER_TRACES
   359 #endif // THEME_SERVER_TRACES
   313 
   360 
   314     int effOffset = -1;
   361     qptrdiff effOffset = -1;
   315     if (effCache()->contains(fileName)) {
   362     if (effCache()->contains(fileName)) {
   316         effOffset = effCache()->value(fileName);
   363         effOffset = effCache()->value(fileName);
   317 
   364 
   318 #ifdef THEME_SERVER_TRACES
   365 #ifdef THEME_SERVER_TRACES
   319         qDebug() << "Got effect in cache: " << fileName << "offset=" << effOffset;
   366         qDebug() << "Got effect in cache: " << fileName << "offset=" << effOffset;
   381 #endif // THEME_SERVER_TRACES
   428 #endif // THEME_SERVER_TRACES
   382 
   429 
   383     return effOffset;
   430     return effOffset;
   384 }
   431 }
   385 
   432 
   386 /**
       
   387  * cleanupUnusedCss  function removes css-resources (stylesheets), whose reference count
       
   388  * is zero, it also releases the shared memory occupied by those resources.
       
   389  * \param cache server css-cache
       
   390  *
       
   391  */
       
   392 void HbThemeServerUtils::cleanupUnusedCss(HbCache *cache)
       
   393 {
       
   394     QList<HbCacheItem*> list = cache->lruList();
       
   395     while (!list.isEmpty()) {
       
   396         HbCacheItem* itemToRemove = list.takeFirst();
       
   397         if (itemToRemove->offset != -1) {
       
   398             HbCss::StyleSheet *styleSheet =
       
   399                 HbMemoryUtils::getAddress<HbCss::StyleSheet>(HbMemoryManager::SharedMemory,
       
   400                         itemToRemove->offset);
       
   401             HbMemoryUtils::release<HbCss::StyleSheet>(styleSheet);
       
   402             itemToRemove->offset = -1;
       
   403         }
       
   404         //Since we are cleaning up css-resources whose ref-count is zero, these entries will be
       
   405         // removed from actual cache.
       
   406         delete cache->cacheHandle().take(itemToRemove->fileName);
       
   407     }
       
   408 }
       
   409 
       
   410 void HbThemeServerUtils::createThemeIndex(const QString &themePath, const HbThemeType &themetype)
   433 void HbThemeServerUtils::createThemeIndex(const QString &themePath, const HbThemeType &themetype)
   411 {
   434 {
   412     #ifdef THEME_INDEX_TRACES
   435     #ifdef THEME_INDEX_TRACES
   413     qDebug() <<  "ThemeIndex: createThemeIndex" << themePath.toUtf8();
   436     qDebug() <<  "ThemeIndex: createThemeIndex" << themePath.toUtf8();
   414     #endif
   437     #endif
   465 
   488 
   466             // Verify theme index contents if it is not located in ROM,
   489             // Verify theme index contents if it is not located in ROM,
   467             // so that it does not have over-indexing offsets which might
   490             // so that it does not have over-indexing offsets which might
   468             // crash all the clients trying to read from it.
   491             // crash all the clients trying to read from it.
   469 
   492 
   470 #ifdef Q_OS_SYMBIAN // ROM check only for Symbian - verify always in other platforms.
       
   471             if (themePath[0] != 'z' && themePath[0] != 'Z') {
   493             if (themePath[0] != 'z' && themePath[0] != 'Z') {
   472 #endif
       
   473                 #ifdef THEME_INDEX_TRACES
   494                 #ifdef THEME_INDEX_TRACES
   474                 qDebug() <<  "ThemeIndex: Validating themeindex for theme" << themeName.toUtf8();
   495                 qDebug() <<  "ThemeIndex: Validating themeindex for theme" << themeName.toUtf8();
   475                 #endif
   496                 #endif
   476 
   497 
   477                 HbThemeIndex index(address);
   498                 HbThemeIndex index(address);
   478                 indexOK = index.validateItems(byteSize);
   499                 indexOK = index.validateItems(byteSize);
   479 
   500 
   480                 #ifdef THEME_INDEX_TRACES
   501                 #ifdef THEME_INDEX_TRACES
   481                 qDebug() <<  "ThemeIndex: Validating themeindex for theme" << themeName.toUtf8() << " done! Result: " << indexOK;
   502                 qDebug() <<  "ThemeIndex: Validating themeindex for theme" << themeName.toUtf8() << " done! Result: " << indexOK;
   482                 #endif
   503                 #endif
   483 #ifdef Q_OS_SYMBIAN
       
   484             }
   504             }
   485 #endif
   505 
   486             if (indexOK) {
   506             if (indexOK) {
   487                 // Allocate theme path string from shared memory
   507                 // Allocate theme path string from shared memory
   488                 QByteArray themePathArray = themeBasePath.absolutePath().toLatin1();
   508                 QByteArray themePathArray = themeBasePath.absolutePath().toLatin1();
   489                 quint32 themePathOffset = manager->alloc(themePathArray.size()+1);
   509                 quint32 themePathOffset = manager->alloc(themePathArray.size()+1);
   490                 memcpy(HbMemoryUtils::getAddress<char>(
   510                 memcpy(HbMemoryUtils::getAddress<char>(