Commit 88375986 authored by Andrew den Exter's avatar Andrew den Exter

Merge branch 'jb37377' into 'master'

Add read-only settings for  requiring device lock, and available settings values.

See merge request !17
parents 288f7d7e 7b091ce4
......@@ -70,6 +70,10 @@ DeviceLockSettings::DeviceLockSettings(QObject *parent)
this, &DeviceLockSettings::inputIsKeyboardChanged);
connect(m_settings.data(), &SettingsWatcher::currentCodeIsDigitOnlyChanged,
this, &DeviceLockSettings::currentCodeIsDigitOnlyChanged);
connect(m_settings.data(), &SettingsWatcher::maximumAutomaticLockingChanged,
this, &DeviceLockSettings::maximumAutomaticLockingChanged);
connect(m_settings.data(), &SettingsWatcher::absoluteMaximumAttemptsChanged,
this, &DeviceLockSettings::absoluteMaximumAttemptsChanged);
m_connection->onConnected(this, [this] {
connected();
......@@ -259,11 +263,39 @@ bool DeviceLockSettings::isHomeEncrypted() const
return m_settings->isHomeEncrypted;
}
/*!
\property NemoDeviceLock::DeviceLockSettings::maximumAutomaticLocking
This property holds the maximum possible value of \l automaticLocking. If theres is no limit
this will be equal to -1.
*/
int DeviceLockSettings::maximumAutomaticLocking() const
{
return m_settings->maximumAutomaticLocking;
}
/*!
\property NemoDeviceLockSettings::absoluteMaximumAttempts
This property holds the maximum possible value of \l maximumAttempts. If theres is no limit
this will be equal to -1.
*/
int DeviceLockSettings::absoluteMaximumAttempts() const
{
return m_settings->absoluteMaximumAttempts;
}
void DeviceLockSettings::changeSetting(
const QVariant &authenticationToken, const QString &key, const QVariant &value)
{
if (m_authorization.status() == Authorization::ChallengeIssued) {
call(QStringLiteral("ChangeSetting"), m_localPath, authenticationToken, key, value);
call(QStringLiteral("ChangeSetting"),
m_localPath,
authenticationToken,
QStringLiteral("/desktop/nemo/devicelock/") + key,
value);
}
}
......
......@@ -52,6 +52,8 @@ class NEMODEVICELOCK_EXPORT DeviceLockSettings : public QObject, private Connect
Q_PROPERTY(bool inputIsKeyboard READ inputIsKeyboard NOTIFY inputIsKeyboardChanged)
Q_PROPERTY(bool currentCodeIsDigitOnly READ currentCodeIsDigitOnly NOTIFY currentCodeIsDigitOnlyChanged)
Q_PROPERTY(bool homeEncrypted READ isHomeEncrypted CONSTANT)
Q_PROPERTY(int maximumAutomaticLocking READ maximumAutomaticLocking NOTIFY maximumAutomaticLockingChanged)
Q_PROPERTY(int absoluteMaximumAttempts READ absoluteMaximumAttempts NOTIFY absoluteMaximumAttemptsChanged)
public:
explicit DeviceLockSettings(QObject *parent = nullptr);
~DeviceLockSettings();
......@@ -80,6 +82,9 @@ public:
bool isHomeEncrypted() const;
int maximumAutomaticLocking() const;
int absoluteMaximumAttempts() const;
signals:
void automaticLockingChanged();
void maximumAttemptsChanged();
......@@ -88,6 +93,8 @@ signals:
void showNotificationsChanged();
void inputIsKeyboardChanged();
void currentCodeIsDigitOnlyChanged();
void maximumAutomaticLockingChanged();
void absoluteMaximumAttemptsChanged();
private:
inline void changeSetting(
......
......@@ -31,6 +31,7 @@
*/
#include "devicereset.h"
#include "private/settingswatcher.h"
namespace NemoDeviceLock
{
......@@ -60,7 +61,11 @@ DeviceReset::DeviceReset(QObject *parent)
QStringLiteral("org.nemomobile.devicelock.DeviceReset"))
, m_authorization(m_localPath, path())
, m_authorizationAdaptor(&m_authorization, this)
, m_settings(SettingsWatcher::instance())
{
connect(m_settings.data(), &SettingsWatcher::supportedDeviceResetOptionsChanged,
this, &DeviceReset::supportedOptionsChanged);
m_connection->onConnected(this, [this] {
connected();
});
......@@ -90,6 +95,18 @@ Authorization *DeviceReset::authorization()
return &m_authorization;
}
/*!
\property NemoDeviceLock::DeviceReset::supportedOptions
This property holds the supported value for the options argument of clear device.
Values not in this set will be ignored and should not be selectable in the UI.
*/
DeviceReset::Options DeviceReset::supportedOptions() const
{
return m_settings->supportedDeviceResetOptions;
}
/*!
Requests a reset of the device to factory settings.
......
......@@ -38,16 +38,20 @@
namespace NemoDeviceLock
{
class SettingsWatcher;
class NEMODEVICELOCK_EXPORT DeviceReset : public QObject, private ConnectionClient
{
Q_OBJECT
Q_PROPERTY(NemoDeviceLock::Authorization *authorization READ authorization CONSTANT)
Q_PROPERTY(Options supportedOptions READ supportedOptions NOTIFY supportedOptionsChanged)
public:
enum Option {
Shutdown = 0x00,
Reboot = 0x01,
WipePartitions = 0x02
};
Q_ENUM(Option)
Q_DECLARE_FLAGS(Options, Option)
Q_FLAG(Options)
......@@ -56,9 +60,12 @@ public:
Authorization *authorization();
Options supportedOptions() const;
Q_INVOKABLE void clearDevice(const QVariant &authenticationToken, Options options = Shutdown);
signals:
void supportedOptionsChanged();
void clearingDevice();
void clearDeviceError();
......@@ -67,6 +74,7 @@ private:
ClientAuthorization m_authorization;
ClientAuthorizationAdaptor m_authorizationAdaptor;
QExplicitlySharedDataPointer<SettingsWatcher> m_settings;
};
}
......
......@@ -47,17 +47,35 @@
namespace NemoDeviceLock
{
const char * const SettingsWatcher::automaticLockingKey = "/desktop/nemo/devicelock/automatic_locking";
const char * const SettingsWatcher::minimumLengthKey = "/desktop/nemo/devicelock/code_min_length";
const char * const SettingsWatcher::maximumLengthKey = "/desktop/nemo/devicelock/code_max_length";
const char * const SettingsWatcher::maximumAttemptsKey = "/desktop/nemo/devicelock/maximum_attempts";
const char * const SettingsWatcher::currentAttemptsKey = "/desktop/nemo/devicelock/current_attempts";
const char * const SettingsWatcher::peekingAllowedKey = "/desktop/nemo/devicelock/peeking_allowed";
const char * const SettingsWatcher::sideloadingAllowedKey = "/desktop/nemo/devicelock/sideloading_allowed";
const char * const SettingsWatcher::showNotificationsKey = "/desktop/nemo/devicelock/show_notification";
const char * const SettingsWatcher::inputIsKeyboardKey = "/desktop/nemo/devicelock/code_input_is_keyboard";
const char * const SettingsWatcher::currentIsDigitOnlyKey = "/desktop/nemo/devicelock/code_current_is_digit_only";
const char * const SettingsWatcher::isHomeEncryptedKey = "/desktop/nemo/devicelock/encrypt_home";
QMetaEnum resolveMetaEnum(const QMetaObject *metaObject, const char *name)
{
const int index = metaObject->indexOfEnumerator(name);
return index != -1 ? metaObject->enumerator(index) : QMetaEnum();
}
int flagsFromString(const QMetaEnum &enumeration, const char *string)
{
int flags = 0;
for (const QByteArray &key : QByteArray(string).split(',')) {
const int value = enumeration.keyToValue(key);
if (value != -1) {
flags |= value;
}
}
return flags;
}
const char * const SettingsWatcher::automaticLockingKey = "automatic_locking";
const char * const SettingsWatcher::minimumLengthKey = "code_min_length";
const char * const SettingsWatcher::maximumLengthKey = "code_max_length";
const char * const SettingsWatcher::maximumAttemptsKey = "maximum_attempts";
const char * const SettingsWatcher::currentAttemptsKey = "current_attempts";
const char * const SettingsWatcher::peekingAllowedKey = "peeking_allowed";
const char * const SettingsWatcher::sideloadingAllowedKey = "sideloading_allowed";
const char * const SettingsWatcher::showNotificationsKey = "show_notification";
const char * const SettingsWatcher::inputIsKeyboardKey = "code_input_is_keyboard";
const char * const SettingsWatcher::currentIsDigitOnlyKey = "code_current_is_digit_only";
const char * const SettingsWatcher::isHomeEncryptedKey = "encrypt_home";
SettingsWatcher *SettingsWatcher::sharedInstance = nullptr;
......@@ -71,9 +89,13 @@ SettingsWatcher::SettingsWatcher(QObject *parent)
, peekingAllowed(1)
, sideloadingAllowed(-1)
, showNotifications(1)
, maximumAutomaticLocking(-1)
, absoluteMaximumAttempts(-1)
, supportedDeviceResetOptions(DeviceReset::Reboot)
, inputIsKeyboard(false)
, currentCodeIsDigitOnly(true)
, isHomeEncrypted(false)
, codeIsMandatory(false)
, m_settingsPath(QStringLiteral("/usr/share/lipstick/devicelock/devicelock_settings.conf"))
, m_watch(-1)
{
......@@ -131,8 +153,26 @@ bool SettingsWatcher::event(QEvent *event)
}
}
template <typename T> T readConfigValue(GKeyFile *config, const char *group, const char *key, T defaultValue)
{
GError *error = nullptr;
gchar *string = g_key_file_get_string(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 {
const T value = settingsValueFromString<T>(string);
g_free(string);
template <typename T> T readConfigValue(GKeyFile *config, const char *group, const char *key, T defaultValue);
return value;
}
}
template <> int readConfigValue<int>(GKeyFile *config, const char *group, const char *key, int defaultValue)
{
......@@ -169,46 +209,65 @@ template <> bool readConfigValue<bool>(
}
}
template <typename T>
static void read(
GKeyFile *settings,
SettingsWatcher *watcher,
const char *group,
const char *key,
T defaultValue,
T (SettingsWatcher::*member),
T *member,
void (SettingsWatcher::*changed)() = nullptr)
{
const T value = readConfigValue<T>(
settings,
"desktop",
QByteArray(key + 9 /* /desktop/ */).replace('/', '\\').constData(),
defaultValue);
const T value = readConfigValue<T>(settings, group, key, defaultValue);
if (watcher->*member != value) {
watcher->*member = value;
if (*member != value) {
*member = value;
if (changed) {
emit (watcher->*changed)();
}
}
}
template <typename T>
static void read(
GKeyFile *settings,
SettingsWatcher *watcher,
const char *key,
T defaultValue,
T *member,
void (SettingsWatcher::*changed)() = nullptr)
{
read(settings,
watcher,
"desktop",
(QByteArrayLiteral("nemo\\devicelock\\") + key).constData(),
defaultValue,
member,
changed);
}
void SettingsWatcher::reloadSettings()
{
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, 5, &SettingsWatcher::automaticLocking, &SettingsWatcher::automaticLockingChanged);
read(settings, this, minimumLengthKey, 5, &SettingsWatcher::minimumLength, &SettingsWatcher::minimumLengthChanged);
read(settings, this, maximumLengthKey, 42, &SettingsWatcher::maximumLength, &SettingsWatcher::maximumLengthChanged);
read(settings, this, maximumAttemptsKey, -1, &SettingsWatcher::maximumAttempts, &SettingsWatcher::maximumAttemptsChanged);
read(settings, this, currentAttemptsKey, 0, &SettingsWatcher::currentAttempts, &SettingsWatcher::currentAttemptsChanged);
read(settings, this, peekingAllowedKey, 1, &SettingsWatcher::peekingAllowed, &SettingsWatcher::peekingAllowedChanged);
read(settings, this, sideloadingAllowedKey, -1, &SettingsWatcher::sideloadingAllowed, &SettingsWatcher::sideloadingAllowedChanged);
read(settings, this, showNotificationsKey, 1, &SettingsWatcher::showNotifications, &SettingsWatcher::showNotificationsChanged);
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);
read(settings, this, automaticLockingKey, 5, &automaticLocking, &SettingsWatcher::automaticLockingChanged);
read(settings, this, minimumLengthKey, 5, &minimumLength, &SettingsWatcher::minimumLengthChanged);
read(settings, this, maximumLengthKey, 42, &maximumLength, &SettingsWatcher::maximumLengthChanged);
read(settings, this, maximumAttemptsKey, -1, &maximumAttempts, &SettingsWatcher::maximumAttemptsChanged);
read(settings, this, currentAttemptsKey, 0, &currentAttempts, &SettingsWatcher::currentAttemptsChanged);
read(settings, this, peekingAllowedKey, 1, &peekingAllowed, &SettingsWatcher::peekingAllowedChanged);
read(settings, this, sideloadingAllowedKey, -1, &sideloadingAllowed, &SettingsWatcher::sideloadingAllowedChanged);
read(settings, this, showNotificationsKey, 1, &showNotifications, &SettingsWatcher::showNotificationsChanged);
read(settings, this, inputIsKeyboardKey, false, &inputIsKeyboard, &SettingsWatcher::inputIsKeyboardChanged);
read(settings, this, currentIsDigitOnlyKey, true, &currentCodeIsDigitOnly, &SettingsWatcher::currentCodeIsDigitOnlyChanged);
read(settings, this, isHomeEncryptedKey, false, &isHomeEncrypted);
read(settings, this, "maximum_automatic_locking", -1, &maximumAutomaticLocking, &SettingsWatcher::maximumAutomaticLockingChanged);
read(settings, this, "absolute_maximum_attempts", -1, &absoluteMaximumAttempts, &SettingsWatcher::absoluteMaximumAttemptsChanged);
read(settings, this, "supported_device_reset_options", DeviceReset::Options(DeviceReset::Reboot), &supportedDeviceResetOptions, &SettingsWatcher::supportedDeviceResetOptionsChanged);
read(settings, this, "code_is_mandatory", false, &codeIsMandatory, &SettingsWatcher::codeIsMandatoryChanged);
g_key_file_free(settings);
}
......
......@@ -34,13 +34,29 @@
#define NEMODEVICELOCK_SETTINGSWATCHER_H
#include <nemo-devicelock/global.h>
#include <nemo-devicelock/devicereset.h>
#include <QMetaEnum>
#include <QSharedData>
#include <QSocketNotifier>
namespace NemoDeviceLock
{
QMetaEnum NEMODEVICELOCK_EXPORT resolveMetaEnum(const QMetaObject *metaObject, const char *name);
template <typename Enum> inline QMetaEnum resolveMetaEnum();
int NEMODEVICELOCK_EXPORT flagsFromString(const QMetaEnum &enumeration, const char *string);
template <typename Enum> inline QFlags<Enum> flagsFromString(const char *string) {
return QFlags<Enum>(flagsFromString(resolveMetaEnum<Enum>(), string)); }
template <typename T> inline T settingsValueFromString(const char *string);
template <> inline QMetaEnum resolveMetaEnum<DeviceReset::Option>() {
return resolveMetaEnum(&DeviceReset::staticMetaObject, "Option"); }
template <> inline DeviceReset::Options settingsValueFromString<DeviceReset::Options>(const char *string) {
return flagsFromString<DeviceReset::Option>(string); }
class NEMODEVICELOCK_EXPORT SettingsWatcher : public QSocketNotifier, public QSharedData
{
Q_OBJECT
......@@ -49,6 +65,7 @@ public:
static SettingsWatcher *instance();
int automaticLocking;
int minimumLength;
int maximumLength;
......@@ -57,9 +74,13 @@ public:
int peekingAllowed;
int sideloadingAllowed;
int showNotifications;
int maximumAutomaticLocking;
int absoluteMaximumAttempts;
DeviceReset::Options supportedDeviceResetOptions;
bool inputIsKeyboard;
bool currentCodeIsDigitOnly;
bool isHomeEncrypted;
bool codeIsMandatory;
static const char * const automaticLockingKey;
static const char * const minimumLengthKey;
......@@ -84,8 +105,12 @@ signals:
void peekingAllowedChanged();
void sideloadingAllowedChanged();
void showNotificationsChanged();
void absoluteMaximumAttemptsChanged();
void maximumAutomaticLockingChanged();
void supportedDeviceResetOptionsChanged();
void inputIsKeyboardChanged();
void currentCodeIsDigitOnlyChanged();
void codeIsMandatoryChanged();
private:
explicit SettingsWatcher(QObject *parent = nullptr);
......
......@@ -78,10 +78,14 @@ SecurityCodeSettings::SecurityCodeSettings(QObject *parent)
QStringLiteral("/authenticator"),
QStringLiteral("org.nemomobile.devicelock.SecurityCodeSettings"))
, m_adaptor(this)
, m_settings(SettingsWatcher::instance())
, m_set(false)
, m_changing(false)
, m_clearing(false)
{
connect(m_settings.data(), &SettingsWatcher::codeIsMandatoryChanged,
this, &SecurityCodeSettings::mandatoryChanged);
m_connection->onConnected(this, [this] {
connected();
});
......@@ -115,6 +119,11 @@ bool SecurityCodeSettings::isSet() const
return m_set;
}
bool SecurityCodeSettings::isMandatory() const
{
return m_settings->codeIsMandatory;
}
/*!
Requests a change of the user's security code.
......
......@@ -41,6 +41,8 @@
namespace NemoDeviceLock
{
class SettingsWatcher;
class SecurityCodeSettings;
class SecurityCodeSettingsAdaptor : public QDBusAbstractAdaptor
{
......@@ -64,11 +66,13 @@ class NEMODEVICELOCK_EXPORT SecurityCodeSettings : public QObject, private Conne
{
Q_OBJECT
Q_PROPERTY(bool set READ isSet NOTIFY setChanged)
Q_PROPERTY(bool mandatory READ isMandatory NOTIFY mandatoryChanged)
public:
explicit SecurityCodeSettings(QObject *parent = nullptr);
~SecurityCodeSettings();
bool isSet() const;
bool isMandatory() const;
Q_INVOKABLE void change(const QVariant &challengeCode);
Q_INVOKABLE void clear();
......@@ -76,6 +80,7 @@ public:
signals:
void setChanged();
void mandatoryChanged();
void changingChanged();
void clearingChanged();
......@@ -95,6 +100,7 @@ private:
inline void handleClearAborted();
SecurityCodeSettingsAdaptor m_adaptor;
QExplicitlySharedDataPointer<SettingsWatcher> m_settings;
bool m_set;
bool m_changing;
bool m_clearing;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment