Skip to content

Commit

Permalink
[devicelock] Ensure settings are refreshed when changed. Fixes JB#37567
Browse files Browse the repository at this point in the history
QSettings maintains an internal static cache of files it has read and
this can sometimes get out of sync with the source file.  Use an
alternative API to read the settings and avoid this.

And don't emit device lock state changes before the state has been
fully resolved.
  • Loading branch information
adenexter committed Feb 1, 2017
1 parent 925fc5e commit 183d854
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
1 change: 1 addition & 0 deletions rpm/nemo-qml-plugin-devicelock.spec
Expand Up @@ -10,6 +10,7 @@ BuildRequires: pkgconfig(Qt5DBus)
BuildRequires: pkgconfig(Qt5Core)
BuildRequires: pkgconfig(Qt5Network)
BuildRequires: pkgconfig(Qt5Qml)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(keepalive)
BuildRequires: pkgconfig(libsystemd-daemon)
BuildRequires: pkgconfig(mce)
Expand Down
7 changes: 3 additions & 4 deletions src/nemo-devicelock/host/mcedevicelock.cpp
Expand Up @@ -293,7 +293,6 @@ void MceDeviceLock::lock()

m_hbTimer.stop();
}

}

bool MceDeviceLock::isLocked() const
Expand All @@ -318,10 +317,10 @@ void MceDeviceLock::setLocked(bool locked)

void MceDeviceLock::stateChanged()
{
emit m_adaptor.stateChanged(state());
emit HostDeviceLock::stateChanged();

setStateAndSetupLockTimer();

emit HostDeviceLock::stateChanged();
emit m_adaptor.stateChanged(state());
}

void MceDeviceLock::automaticLockingChanged()
Expand Down
4 changes: 3 additions & 1 deletion src/nemo-devicelock/lib.pro
Expand Up @@ -12,7 +12,9 @@ CONFIG += \
QT -= gui
QT += dbus

PKGCONFIG += nemodbus
PKGCONFIG += \
glib-2.0 \
nemodbus

INCLUDEPATH += ..

Expand Down
57 changes: 50 additions & 7 deletions src/nemo-devicelock/private/settingswatcher.cpp
Expand Up @@ -37,6 +37,7 @@
#include <QFile>
#include <QSettings>

#include <glib.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <unistd.h>
Expand Down Expand Up @@ -130,16 +131,59 @@ bool SettingsWatcher::event(QEvent *event)
}
}


template <typename T> T readConfigValue(GKeyFile *config, const char *group, const char *key, T defaultValue);

template <> int readConfigValue<int>(GKeyFile *config, const char *group, const char *key, int defaultValue)
{
GError *error = nullptr;
const int value = g_key_file_get_integer(config, group, key, &error);
if (error ) {
if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND
&& error->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND) {
qCWarning(devicelock) << "Error reading" << group << key << error->message;
}
g_error_free(error);

return defaultValue;
} else {
return value;
}
}

template <> bool readConfigValue<bool>(
GKeyFile *config, const char *group, const char *key, bool defaultValue)
{
GError *error = nullptr;
const gboolean value = g_key_file_get_boolean(config, group, key, &error);
if (error) {
if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND
&& error->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND) {
qCWarning(devicelock) << "Error reading" << group << key << error->message;
}
g_error_free(error);

return defaultValue;
} else {
return value;
}
}


template <typename T>
static void read(
const QSettings &settings,
GKeyFile *settings,
SettingsWatcher *watcher,
const char *key,
T defaultValue,
T (SettingsWatcher::*member),
void (SettingsWatcher::*changed)() = nullptr)
{
T value = settings.value(QString::fromUtf8(key), QVariant(defaultValue)).value<T>();
const T value = readConfigValue<T>(
settings,
"desktop",
QByteArray(key + 9 /* /desktop/ */).replace('/', '\\').constData(),
defaultValue);

if (watcher->*member != value) {
watcher->*member = value;
Expand All @@ -151,11 +195,8 @@ static void read(

void SettingsWatcher::reloadSettings()
{
QSettings settings(m_settingsPath, QSettings::IniFormat);
// QSettings appears to be caching queried data between instances and that cache isn't
// being invalidated when the file is replaced but not deleted. Forcing a sync makes it
// read the new file.
settings.sync();
GKeyFile * const settings = g_key_file_new();
g_key_file_load_from_file(settings, m_settingsPath.toUtf8().constData(), G_KEY_FILE_NONE, 0);

read(settings, this, automaticLockingKey, 10, &SettingsWatcher::automaticLocking, &SettingsWatcher::automaticLockingChanged);
read(settings, this, minimumLengthKey, 5, &SettingsWatcher::minimumLength, &SettingsWatcher::minimumLengthChanged);
Expand All @@ -168,6 +209,8 @@ void SettingsWatcher::reloadSettings()
read(settings, this, inputIsKeyboardKey, false, &SettingsWatcher::inputIsKeyboard, &SettingsWatcher::inputIsKeyboardChanged);
read(settings, this, currentIsDigitOnlyKey, true, &SettingsWatcher::currentCodeIsDigitOnly, &SettingsWatcher::currentCodeIsDigitOnlyChanged);
read(settings, this, isHomeEncryptedKey, false, &SettingsWatcher::isHomeEncrypted);

g_key_file_free(settings);
}

}

0 comments on commit 183d854

Please sign in to comment.