src/hbcore/inputfw/hbinputmodecache.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
--- a/src/hbcore/inputfw/hbinputmodecache.cpp	Mon Oct 04 17:49:30 2010 +0300
+++ b/src/hbcore/inputfw/hbinputmodecache.cpp	Mon Oct 18 18:23:13 2010 +0300
@@ -23,6 +23,7 @@
 **
 ****************************************************************************/
 #include "hbinputmodecache_p.h"
+#include "hbinputmodecache_p_p.h"
 
 #include <QInputContextPlugin>
 #include <QLocale>
@@ -30,6 +31,9 @@
 #include <QLibrary>
 #include <QPluginLoader>
 #include <QDir>
+#include <QSharedMemory>
+#include <QDataStream>
+#include <QBuffer>
 
 #include "hbinpututils.h"
 #include "hbinputmethod.h"
@@ -42,50 +46,217 @@
 
 /*!
 @alpha
-@hbcore
 \class HbInputModeCache
 \brief Input framework's internal input mode resolver class.
 */
 
 /// @cond
 
-class HbInputMethodListItem
+void HbInputMethodListItem::setValues(QInputContextPlugin *plugin, const QString &key)
+{
+    if (plugin) {
+        descriptor.setKey(key);
+        descriptor.setDisplayName(plugin->displayName(key));
+
+        HbInputContextPlugin *extension = qobject_cast<HbInputContextPlugin *>(plugin);
+        if (extension) {
+            descriptor.setDisplayNames(extension->displayNames(key));
+            descriptor.setIcon(extension->icon(key));
+            descriptor.setIcons(extension->icons(key));
+        }
+    }
+}
+
+QDataStream &operator<<(QDataStream &out, const HbInputMethodListItem &item)
+{
+    out << item.descriptor;
+    out << item.languages;
+    return out;
+}
+
+QDataStream &operator>>(QDataStream &in, HbInputMethodListItem &item)
+{
+    in >> item.descriptor;
+    in >> item.languages;
+    item.cached = 0;
+    item.toBeRemoved = false;
+    return in;
+}
+
+HbInputModeCachePrivate::HbInputModeCachePrivate()
+  : mSharedMethodList(0),
+    mMethodListModTime(0),
+    mMethodListLastUpdate(0),
+    mMethodsFetchedFromDisk(false),
+    mShuttingDown(false)
 {
-public:
-    HbInputMethodListItem() : cached(0), toBeRemoved(false) {}
-    bool operator==(const HbInputMethodListItem &item) const {
-        return (descriptor.pluginNameAndPath() == item.descriptor.pluginNameAndPath() &&
-                descriptor.key() == item.descriptor.key());
+    mSharedMethodList = new QSharedMemory(HbInputMethodListKey);
+    // sharedMethodList is only attached when the list is updated
+    mMethodListModTime = new QSharedMemory(HbInputMethodListModTimeKey);
+    mMethodListModTime->attach();
+}
+
+HbInputModeCachePrivate::~HbInputModeCachePrivate()
+{
+    delete mSharedMethodList;
+    delete mMethodListModTime;
+}
+
+void HbInputModeCachePrivate::refresh()
+{
+    // Shared memory data is used if available (checked every time we refresh)
+    // Otherwise the methods are read from disk, but just once during modecache lifetime
+    if (!readInputMethodDataFromSharedMemory() && !mMethodsFetchedFromDisk) {
+        readInputMethodDataFromDisk(&mMethods);
+        pruneRemovedMethods();
+        mMethodsFetchedFromDisk = true;
+    }
+}
+
+void HbInputModeCachePrivate::readInputMethodDataFromDisk(QList<HbInputMethodListItem>* methodList, const QDir &readPath)
+{
+    bool readFromSinglePath = (readPath != QDir());
+    // First go through all the previously found entries and
+    // tag them not refreshed. In case a directory is defined, only marks entries
+    // in that directory
+    for (int i = 0; i < methodList->size(); ++i) {
+        if (readFromSinglePath) {
+            if (methodList->at(i).descriptor.pluginNameAndPath().left(methodList->at(i).descriptor.pluginNameAndPath().lastIndexOf(QDir::separator()))
+                == readPath.absolutePath()) {
+                (*methodList)[i].toBeRemoved = true;
+            }
+        } else {
+            (*methodList)[i].toBeRemoved = true;
+        }
     }
 
-public:
-    HbInputMethodDescriptor descriptor;
-    QStringList languages;
-    HbInputMethod *cached;
-    bool toBeRemoved;
-};
+    // Query plugin paths and scan the folders.
+    QStringList folders = HbInputSettingProxy::instance()->inputMethodPluginPaths();
+    foreach(const QString &folder, folders) {
+        QDir dir(folder);
+        if (!readFromSinglePath || readPath == dir) {
+            for (unsigned int i = 0; i < dir.count(); i++) {
+                QString path = QString(dir.absolutePath());
+                if (path.right(1) != "\\" && path.right(1) != "/") {
+                    path += QDir::separator();
+                }
+                path += dir[i];
+                QInputContextPlugin *inputContextPlugin = pluginInstance(path);
+                if (inputContextPlugin) {
+                    HbInputMethodListItem listItem;
+                    listItem.descriptor.setPluginNameAndPath(dir.absolutePath() + QDir::separator() + dir[i]);
 
-class HbInputModeCachePrivate
+                    // For each found plugin, check if there is already a list item for it.
+                    // If not, then add one.
+                    QStringList contextKeys = inputContextPlugin->keys();
+                    foreach(const QString &key, contextKeys) {
+                        listItem.setValues(inputContextPlugin, key);
+
+                        int index = methodList->indexOf(listItem);
+                        if (index >= 0) {
+                            // The method is already in the list, the situation hasn't changed.
+                            // just tag it not to be removed.
+                            (*methodList)[index].toBeRemoved = false;
+                        } else {
+                            listItem.languages = inputContextPlugin->languages(key);
+                            methodList->append(listItem);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+bool HbInputModeCachePrivate::readInputMethodDataFromSharedMemory()
 {
-public:
-    HbInputModeCachePrivate() : mWatcher(new QFileSystemWatcher()), mShuttingDown(false) {}
-    ~HbInputModeCachePrivate() {}
-    void refresh(const QString &directory = QString());
-    QInputContextPlugin *pluginInstance(const QString &pluginFileName) const;
-    HbInputMethod *methodInstance(const QString &pluginFileName, const QString &key) const;
-    HbInputModeProperties propertiesFromString(const QString &entry) const;
-    HbInputModeProperties propertiesFromState(const HbInputState &state) const;
-    HbInputMethod *cachedMethod(HbInputMethodListItem &item);
-    void updateMonitoredPaths();
-    bool isMappedLanguage(const HbInputLanguage &language) const;
+    // Check if the shared list has been modified
+    if (!mMethodListModTime->isAttached()) {
+        // Shared memory is not attached
+        // Revert to in-process handling
+        return false;
+    }
+    // No locking, since in case the value is corrupt we just need to read the list again
+    // on the next run
+    uint *newModTime = static_cast<uint *>(mMethodListModTime->data());
+    if (*newModTime == mMethodListLastUpdate) {
+        // The internal list is still in sync with the one in shared memory
+        return true;
+    }
+    // Modifications done since last update, try to attach the method list
+    // Revert to in-process handling if not successful
+    if (!mSharedMethodList->attach()) {
+        return false;
+    }
+    // Attached successfully, update the modification time
+    mMethodListLastUpdate = *newModTime;
+
+    // To start updating the list, first mark all methods for removal
+    for (int k = 0; k < mMethods.count(); k++) {
+        mMethods[k].toBeRemoved = true;
+    }
+
+    // Get a copy of the list from shared memory
+    mSharedMethodList->lock();
+    QByteArray array(static_cast<const char *>(mSharedMethodList->data())+sizeof(int), *static_cast<int *>(mSharedMethodList->data()));
+    // array now has a copy of the data, so we can unlock and detach
+    mSharedMethodList->unlock();
+    mSharedMethodList->detach();
+
+    // Next read the entries from the array to a temporary list
+    QDataStream in(&array, QIODevice::ReadOnly);
+    QList<HbInputMethodListItem> newMethodList;
+    in >> newMethodList;
 
-public:
-    QFileSystemWatcher *mWatcher;
-    QList<HbInputMethodListItem> mMethods;
-    bool mShuttingDown;
-};
+    // Go through the temporary list and append new methods to internal list
+    // Duplicates are marked as not to be removed, the rest will be removed by pruneRemovedMethods
+    foreach (const HbInputMethodListItem& item, newMethodList) {
+        int index = mMethods.indexOf(item);
+        if (index >= 0) {
+            mMethods[index].toBeRemoved = false;
+        } else {
+            mMethods.append(item);
+        }
+    }
+    pruneRemovedMethods();
+    return true;
+}
 
-QInputContextPlugin *HbInputModeCachePrivate::pluginInstance(const QString &pluginFileName) const
+void HbInputModeCachePrivate::pruneRemovedMethods()
+{
+    // Go through the cache list and find out if some of the previous items need to be
+    // removed after the refresh.
+    for (int i = 0; i < mMethods.count(); i++) {
+        if (mMethods.at(i).toBeRemoved) {
+            if (mMethods.at(i).cached && mMethods.at(i).cached->isActiveMethod()) {
+                // If the item to be removed happens to be the active one,
+                // try to deal with the situation.
+                mMethods.at(i).cached->forceUnfocus();
+                // The active custom method is being removed.
+                // Clear out related setting proxy values.
+                if (mMethods.at(i).descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Horizontal).pluginNameAndPath()) {
+                    HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Horizontal, HbInputMethodDescriptor());
+                }
+                if (mMethods.at(i).descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Vertical).pluginNameAndPath()) {
+                    HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Vertical, HbInputMethodDescriptor());
+                }
+
+                // Replace it with null input context.
+                HbInputMethod *master = HbInputMethodNull::Instance();
+                master->d_ptr->mIsActive = true;
+                QInputContext *proxy = master->d_ptr->proxy();
+                if (proxy != qApp->inputContext()) {
+                    qApp->setInputContext(proxy);
+                }
+            }
+            delete mMethods[i].cached;
+            mMethods.removeAt(i);
+            i--;
+        }
+    }
+}
+
+QInputContextPlugin *HbInputModeCachePrivate::pluginInstance(const QString &pluginFileName)
 {
     if (QLibrary::isLibrary(pluginFileName)) {
         QPluginLoader loader(pluginFileName);
@@ -108,7 +279,7 @@
             QStringList languages = plugin->languages(key);
             QList<HbInputModeProperties> modeList;
             foreach(const QString &language, languages) {
-                modeList.append(propertiesFromString(language));
+                modeList.append(HbInputModeProperties::fromString(language));
             }
             result->d_ptr->mInputModes = modeList;
         }
@@ -118,122 +289,6 @@
     return 0;
 }
 
-void HbInputModeCachePrivate::refresh(const QString &directory)
-{
-    Q_UNUSED(directory);
-    // optimize later so that if the directory is given, only changes concerning
-    // it are taken into account.
-
-    // First go through all the previously found entries and
-    // tag them not refreshed.
-    for (int k = 0; k < mMethods.count(); k++) {
-        mMethods[k].toBeRemoved = true;
-    }
-
-    // Query plugin paths and scan the folders.
-    QStringList folders = HbInputSettingProxy::instance()->inputMethodPluginPaths();
-    foreach(const QString &folder, folders) {
-        QDir dir(folder);
-        for (unsigned int i = 0; i < dir.count(); i++) {
-            QString path = QString(dir.absolutePath());
-            if (path.right(1) != "\\" && path.right(1) != "/") {
-                path += QDir::separator();
-            }
-            path += dir[i];
-            QInputContextPlugin *inputContextPlugin = pluginInstance(path);
-            if (inputContextPlugin) {
-                HbInputMethodListItem listItem;
-                listItem.descriptor.setPluginNameAndPath(dir.absolutePath() + QDir::separator() + dir[i]);
-
-                // For each found plugin, check if there is already a list item for it.
-                // If not, then add one.
-                QStringList contextKeys = inputContextPlugin->keys();
-                foreach(const QString &key, contextKeys) {
-                    listItem.descriptor.setKey(key);
-                    listItem.descriptor.setDisplayName(inputContextPlugin->displayName(key));
-
-                    HbInputContextPlugin *extension = qobject_cast<HbInputContextPlugin *>(inputContextPlugin);
-                    if (extension) {
-                        listItem.descriptor.setDisplayNames(extension->displayNames(key));
-                        listItem.descriptor.setIcon(extension->icon(key));
-                        listItem.descriptor.setIcons(extension->icons(key));
-                    }
-
-                    int index = mMethods.indexOf(listItem);
-                    if (index >= 0) {
-                        // The method is already in the list, the situation hasn't changed.
-                        // just tag it not to be removed.
-                        mMethods[index].toBeRemoved = false;
-                    } else {
-                        listItem.languages = inputContextPlugin->languages(key);
-                        mMethods.append(listItem);
-                    }
-                }
-            }
-        }
-    }
-
-    // Go through the cache list and find out if some of the previous items need to be
-    // removed after the refresh.
-    for (int i = 0; i < mMethods.count(); i++) {
-        if (mMethods[i].toBeRemoved) {
-            if (mMethods[i].cached && mMethods[i].cached->isActiveMethod()) {
-                // If the item to be removed happens to be the active one,
-                // try to deal with the situation.
-                mMethods[i].cached->forceUnfocus();
-                // The active custom method is being removed.
-                // Clear out related setting proxy values.
-                if (mMethods[i].descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Horizontal).pluginNameAndPath()) {
-                    HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Horizontal, HbInputMethodDescriptor());
-                }
-                if (mMethods[i].descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Vertical).pluginNameAndPath()) {
-                    HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Vertical, HbInputMethodDescriptor());
-                }
-
-                // Replace it with null input context.
-                HbInputMethod *master = HbInputMethodNull::Instance();
-                master->d_ptr->mIsActive = true;
-                QInputContext *proxy = master->d_ptr->proxy();
-                if (proxy != qApp->inputContext()) {
-                    qApp->setInputContext(proxy);
-                }
-            }
-            delete mMethods[i].cached;
-            mMethods.removeAt(i);
-            i--;
-        }
-    }
-}
-
-HbInputModeProperties HbInputModeCachePrivate::propertiesFromString(const QString &entry) const
-{
-    HbInputModeProperties result;
-
-    QStringList parts = entry.split(' ');
-    if (parts.count() == 4) {
-        // See HbInputModeProperties::toString() for details,
-        QString languageStr = parts[0] + QString(" ") + parts[1];
-        HbInputLanguage language;
-        language.fromString(languageStr);
-        result.setLanguage(language);
-        result.setInputMode((HbInputModeType)parts[2].toLong());
-        result.setKeyboard((HbKeyboardType)parts[3].toLong());
-    }
-
-    return result;
-}
-
-HbInputModeProperties HbInputModeCachePrivate::propertiesFromState(const HbInputState &state) const
-{
-    HbInputModeProperties result;
-
-    result.setLanguage(state.language());
-    result.setKeyboard(state.keyboard());
-    result.setInputMode(state.inputMode());
-
-    return HbInputModeProperties(result);
-}
-
 HbInputMethod *HbInputModeCachePrivate::cachedMethod(HbInputMethodListItem &item)
 {
     if (!item.cached) {
@@ -243,36 +298,9 @@
     return item.cached;
 }
 
-void HbInputModeCachePrivate::updateMonitoredPaths()
-{
-    QStringList watchedDirs = mWatcher->directories();
-    if (!watchedDirs.isEmpty()) {
-        mWatcher->removePaths(watchedDirs);
-    }
-
-    QStringList paths = HbInputSettingProxy::instance()->inputMethodPluginPaths();
-    foreach(const QString &path, paths) {
-        QDir dir(path);
-        if (!dir.exists() && path.left(1) == "f") {
-            mWatcher->addPath(QString("f:") + QDir::separator());
-        } else {
-            mWatcher->addPath(path);
-        }
-    }
-}
-
 bool HbInputModeCachePrivate::isMappedLanguage(const HbInputLanguage &language) const
 {
-    if (language.defined()) {
-        QList<HbInputLanguage> languages = HbKeymapFactory::instance()->availableLanguages();
-        foreach(const HbInputLanguage &mappedLanguage, languages) {
-            if (mappedLanguage == language) {
-                return true;
-            }
-        }
-    }
-
-    return false;
+    return (HbKeymapFactory::instance()->keymap(language) != 0);
 }
 
 /// @endcond
@@ -295,10 +323,6 @@
 {
     Q_D(HbInputModeCache);
 
-    // Start to monitor file system for changes.
-    d->updateMonitoredPaths();
-    connect(d->mWatcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
-
     d->refresh();
 }
 
@@ -313,22 +337,6 @@
 
 /*!
 \internal
-This slot is called whenever a change in input method plugin file system is detected and
-the list needs to be refreshed.
-*/
-void HbInputModeCache::directoryChanged(const QString &directory)
-{
-    Q_D(HbInputModeCache);
-
-    d->updateMonitoredPaths();
-
-    if (!d->mShuttingDown) {
-        d->refresh(directory);
-    }
-}
-
-/*!
-\internal
 Shuts down the object safely. This is needed mainly for singleton object. There has been a lot
 of problems related to randown singleton desctruction order and additional shutdown step is
 needed to guarantee that it will be done safely. The slot is connected to
@@ -344,8 +352,6 @@
         method.cached = 0;
     }
     d->mMethods.clear();
-    delete d->mWatcher;
-    d->mWatcher = 0;
 }
 
 /*!
@@ -355,11 +361,12 @@
 HbInputMethod *HbInputModeCache::loadInputMethod(const HbInputMethodDescriptor &inputMethod)
 {
     Q_D(HbInputModeCache);
+    d->refresh();
 
     for (int i = 0; i < d->mMethods.count(); i++) {
-        if (d->mMethods[i].descriptor.pluginNameAndPath() == inputMethod.pluginNameAndPath() &&
-            d->mMethods[i].descriptor.key() == inputMethod.key()) {
-            if (!d->mMethods[i].cached) {
+        if (d->mMethods.at(i).descriptor.pluginNameAndPath() == inputMethod.pluginNameAndPath() &&
+            d->mMethods.at(i).descriptor.key() == inputMethod.key()) {
+            if (!d->mMethods.at(i).cached) {
                 d->mMethods[i].cached = d->methodInstance(inputMethod.pluginNameAndPath(), inputMethod.key());
             }
 
@@ -377,12 +384,13 @@
 QList<HbInputMethodDescriptor> HbInputModeCache::listCustomInputMethods()
 {
     Q_D(HbInputModeCache);
+    d->refresh();
 
     QList<HbInputMethodDescriptor> result;
 
     foreach(const HbInputMethodListItem &item, d->mMethods) {
         foreach(const QString &language, item.languages) {
-            HbInputModeProperties properties = d->propertiesFromString(language);
+            HbInputModeProperties properties = HbInputModeProperties::fromString(language);
             if (properties.inputMode() == HbInputModeCustom) {
                 result.append(item.descriptor);
                 break;
@@ -400,12 +408,13 @@
 QList<HbInputMethodDescriptor> HbInputModeCache::listCustomInputMethods(Qt::Orientation orientation, const HbInputLanguage &language)
 {
     Q_D(HbInputModeCache);
+    d->refresh();
 
     QList<HbInputMethodDescriptor> result;
 
-    foreach (const HbInputMethodListItem &item, d->mMethods) {
-        foreach (const QString &lang, item.languages) {
-            HbInputModeProperties properties = d->propertiesFromString(lang);
+    for (int i = 0; i < d->mMethods.count(); i++) {
+        foreach (const QString &lang, d->mMethods.at(i).languages) {
+            HbInputModeProperties properties = HbInputModeProperties::fromString(lang);
             
             // Find custom methods that supports given language or any language and
             // supports given orientation
@@ -413,7 +422,8 @@
                 (properties.language() == language || properties.language() == HbInputLanguage()) &&
                 ((orientation == Qt::Vertical && properties.keyboard() == HbKeyboardTouchPortrait) ||
                 (orientation == Qt::Horizontal && properties.keyboard() == HbKeyboardTouchLandscape))) {
-                result.append(item.descriptor);
+
+                result.append(d->mMethods[i].descriptor);
                 break;
             }
         }
@@ -429,23 +439,40 @@
 HbInputMethodDescriptor HbInputModeCache::defaultInputMethod(Qt::Orientation orientation)
 {
     Q_D(HbInputModeCache);
+    d->refresh();
 
-    HbInputMethodDescriptor result;
-    foreach (const HbInputMethodListItem &item, d->mMethods) {
-        foreach (const QString &language, item.languages) {
-            HbInputModeProperties properties = d->propertiesFromString(language);
+    HbInputLanguage currentLanguage = HbInputSettingProxy::instance()->globalInputLanguage();
+    bool mapped = d->isMappedLanguage(currentLanguage);
+
+    for (int i = 0; i < d->mMethods.count(); i++) {
+        foreach (const QString &language, d->mMethods[i].languages) {
+            HbInputModeProperties properties = HbInputModeProperties::fromString(language);
+
+            if (properties.language().undefined()) {
+                // The input method reports language range but current language is not mapped
+                // language. Skip this one. 
+                if (!mapped) {
+                    continue; 
+                }
+            } else {
+                // The input method reports support for specific language but it is not an exact
+                // match to current language. Skip this one 
+                if (properties.language() != currentLanguage) {
+                    // It is not direct match either.
+                    continue;
+                }
+            }
 
             // Find default method that supports given orientation
             if (properties.inputMode() == HbInputModeDefault &&
                 ((orientation == Qt::Vertical && properties.keyboard() == HbKeyboardTouchPortrait) ||
                 (orientation == Qt::Horizontal && properties.keyboard() == HbKeyboardTouchLandscape))) {
-                result = item.descriptor;
-                break;
+                return d->mMethods[i].descriptor;
             }
         }
     }
 
-    return result;
+    return HbInputMethodDescriptor();
 }
 
 /*!
@@ -455,15 +482,16 @@
 HbInputMethod *HbInputModeCache::findStateHandler(const HbInputState &state)
 {
     Q_D(HbInputModeCache);
+    d->refresh();
 
-    HbInputModeProperties stateProperties = d->propertiesFromState(state);
+    HbInputModeProperties stateProperties(state);
     int languageRangeIndex = -1;
 
     // First check if there is a method that matches excatly (ie. also specifies
     // the language).
     for (int i = 0; i < d->mMethods.count(); i++) {
         foreach(const QString &language, d->mMethods[i].languages) {
-            HbInputModeProperties properties = d->propertiesFromString(language);
+            HbInputModeProperties properties = HbInputModeProperties::fromString(language);
             if (properties.language().undefined() &&
                 properties.keyboard() == stateProperties.keyboard() &&
                 properties.inputMode() == stateProperties.inputMode()) {
@@ -507,9 +535,10 @@
 
 \sa HbInputMethod
 */
-HbInputMethod *HbInputModeCache::activeMethod() const
+HbInputMethod *HbInputModeCache::activeMethod()
 {
-    Q_D(const HbInputModeCache);
+    Q_D(HbInputModeCache);
+    d->refresh();
 
     foreach(const HbInputMethodListItem &item, d->mMethods) {
         if (item.cached && item.cached->isActiveMethod()) {
@@ -524,15 +553,16 @@
 \internal
 Lists available input languages.
 */
-QList<HbInputLanguage> HbInputModeCache::listInputLanguages() const
+QList<HbInputLanguage> HbInputModeCache::listInputLanguages()
 {
-    Q_D(const HbInputModeCache);
+    Q_D(HbInputModeCache);
+    d->refresh();
 
     QList<HbInputLanguage> result;
 
     foreach(const HbInputMethodListItem &item, d->mMethods) {
         foreach(const QString &language, item.languages) {
-            HbInputModeProperties mode = d->propertiesFromString(language);
+            HbInputModeProperties mode = HbInputModeProperties::fromString(language);
             if (mode.inputMode() != HbInputModeCustom) {
                 if (mode.language().undefined()) {
                     // This is language range. Let's add everything
@@ -559,14 +589,15 @@
 \internal
 Returns true if given input method is able to handle given input state.
 */
-bool HbInputModeCache::acceptsState(const HbInputMethod *inputMethod, const HbInputState &state) const
+bool HbInputModeCache::acceptsState(const HbInputMethod *inputMethod, const HbInputState &state)
 {
-    Q_D(const HbInputModeCache);
+    Q_D(HbInputModeCache);
+    d->refresh();
 
     foreach(const HbInputMethodListItem &item, d->mMethods) {
         if (item.cached == inputMethod) {
             foreach(const QString &language, item.languages) {
-                HbInputModeProperties mode = d->propertiesFromString(language);
+                HbInputModeProperties mode = HbInputModeProperties::fromString(language);
                 // Check if keyboard type matches.
                 if (mode.keyboard() == state.keyboard()) {
                     // Check if input mode matches or it is a custom input method but
@@ -594,9 +625,10 @@
 Returns input method descriptor for given input method. Returns empty descriptor if the framework
 doesn't recognize given input method.
 */
-HbInputMethodDescriptor HbInputModeCache::descriptor(const HbInputMethod *inputMethod) const
+HbInputMethodDescriptor HbInputModeCache::descriptor(const HbInputMethod *inputMethod)
 {
-    Q_D(const HbInputModeCache);
+    Q_D(HbInputModeCache);
+    d->refresh();
 
     foreach(const HbInputMethodListItem &item, d->mMethods) {
         if (item.cached == inputMethod) {