diff options
-rw-r--r-- | lib/colord/cd-enum.c | 6 | ||||
-rw-r--r-- | lib/colord/cd-enum.h | 4 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/cd-main.c | 20 | ||||
-rw-r--r-- | src/cd-profile-db.c | 333 | ||||
-rw-r--r-- | src/cd-profile-db.h | 82 | ||||
-rw-r--r-- | src/cd-profile.c | 106 | ||||
-rw-r--r-- | src/cd-profile.h | 1 | ||||
-rw-r--r-- | src/cd-self-test.c | 71 |
9 files changed, 608 insertions, 19 deletions
diff --git a/lib/colord/cd-enum.c b/lib/colord/cd-enum.c index 934b87e..d098470 100644 --- a/lib/colord/cd-enum.c +++ b/lib/colord/cd-enum.c @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * - * Copyright (C) 2010-2013 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2010-2014 Richard Hughes <richard@hughsie.com> * * Licensed under the GNU Lesser General Public License Version 2.1 * @@ -724,6 +724,8 @@ cd_profile_error_to_string (CdProfileError error_enum) return CD_DBUS_INTERFACE_PROFILE ".FailedToAuthenticate"; if (error_enum == CD_PROFILE_ERROR_PROPERTY_INVALID) return CD_DBUS_INTERFACE_PROFILE ".PropertyInvalid"; + if (error_enum == CD_PROFILE_ERROR_FAILED_TO_GET_UID) + return CD_DBUS_INTERFACE_PROFILE ".FailedToGetUid"; return NULL; } @@ -753,6 +755,8 @@ cd_profile_error_from_string (const gchar *error_desc) return CD_PROFILE_ERROR_FAILED_TO_AUTHENTICATE; if (g_strcmp0 (error_desc, CD_DBUS_INTERFACE_PROFILE ".PropertyInvalid") == 0) return CD_PROFILE_ERROR_PROPERTY_INVALID; + if (g_strcmp0 (error_desc, CD_DBUS_INTERFACE_PROFILE ".FailedToGetUid") == 0) + return CD_PROFILE_ERROR_FAILED_TO_GET_UID; return CD_PROFILE_ERROR_LAST; } diff --git a/lib/colord/cd-enum.h b/lib/colord/cd-enum.h index c4d3b26..2a942b2 100644 --- a/lib/colord/cd-enum.h +++ b/lib/colord/cd-enum.h @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * - * Copyright (C) 2010-2013 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2010-2014 Richard Hughes <richard@hughsie.com> * * Licensed under the GNU Lesser General Public License Version 2.1 * @@ -340,6 +340,7 @@ typedef enum { * @CD_PROFILE_ERROR_FAILED_TO_READ: The profile could not be read * @CD_PROFILE_ERROR_FAILED_TO_AUTHENTICATE: Authentication failed * @CD_PROFILE_ERROR_PROPERTY_INVALID: One or more of the properties was invalid + * @CD_PROFILE_ERROR_FAILED_TO_GET_UID: Failed to get UID for sender * * Errors that can be thrown */ @@ -352,6 +353,7 @@ typedef enum CD_PROFILE_ERROR_FAILED_TO_READ, /* Since: 0.1.26 */ CD_PROFILE_ERROR_FAILED_TO_AUTHENTICATE, /* Since: 0.1.26 */ CD_PROFILE_ERROR_PROPERTY_INVALID, /* Since: 0.1.31 */ + CD_PROFILE_ERROR_FAILED_TO_GET_UID, /* Since: 1.2.1 */ /*< private >*/ CD_PROFILE_ERROR_LAST } CdProfileError; diff --git a/src/Makefile.am b/src/Makefile.am index 9994370..5e3a22f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -82,6 +82,8 @@ colord_SOURCES = \ cd-plugin.h \ cd-profile-array.c \ cd-profile-array.h \ + cd-profile-db.c \ + cd-profile-db.h \ cd-profile.c \ cd-profile.h \ cd-sensor.c \ @@ -136,6 +138,8 @@ cd_self_test_SOURCES = \ cd-mapping-db.h \ cd-profile-array.c \ cd-profile-array.h \ + cd-profile-db.c \ + cd-profile-db.h \ cd-profile.c \ cd-profile.h \ cd-resources.c \ diff --git a/src/cd-main.c b/src/cd-main.c index 963ee97..de618ff 100644 --- a/src/cd-main.c +++ b/src/cd-main.c @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * - * Copyright (C) 2010-2013 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2010-2014 Richard Hughes <richard@hughsie.com> * * Licensed under the GNU General Public License Version 2 * @@ -40,6 +40,7 @@ #include "cd-mapping-db.h" #include "cd-plugin.h" #include "cd-profile-array.h" +#include "cd-profile-db.h" #include "cd-profile.h" #include "cd-icc-store.h" #include "cd-resources.h" @@ -56,6 +57,7 @@ typedef struct { CdIccStore *icc_store; CdMappingDb *mapping_db; CdDeviceDb *device_db; + CdProfileDb *profile_db; #ifdef HAVE_UDEV CdSensorClient *sensor_client; #endif @@ -1618,6 +1620,7 @@ cd_main_daemon_method_call (GDBusConnection *connection, const gchar *sender, ret = cd_profile_set_property_internal (profile, prop_key, prop_value, + uid, &error); if (!ret) { g_dbus_method_invocation_return_gerror (invocation, @@ -1806,6 +1809,7 @@ cd_main_icc_store_added_cb (CdIccStore *icc_store, cd_profile_set_property_internal (profile, CD_PROFILE_METADATA_FILE_CHECKSUM, checksum, + 0, /* uid unknown */ NULL); /* just add it to the bus with the title as the ID */ @@ -2742,6 +2746,18 @@ main (int argc, char *argv[]) goto out; } + /* connect to the profile db */ + priv->profile_db = cd_profile_db_new (); + ret = cd_profile_db_load (priv->profile_db, + LOCALSTATEDIR "/lib/colord/storage.db", + &error); + if (!ret) { + g_warning ("CdMain: failed to load profile database: %s", + error->message); + g_error_free (error); + goto out; + } + /* load introspection from file */ priv->introspection_daemon = cd_main_load_introspection (COLORD_DBUS_INTERFACE ".xml", &error); @@ -2845,6 +2861,8 @@ out: g_object_unref (priv->mapping_db); if (priv->device_db != NULL) g_object_unref (priv->device_db); + if (priv->profile_db != NULL) + g_object_unref (priv->profile_db); if (priv->devices_array != NULL) g_object_unref (priv->devices_array); if (priv->profiles_array != NULL) diff --git a/src/cd-profile-db.c b/src/cd-profile-db.c new file mode 100644 index 0000000..4c771fe --- /dev/null +++ b/src/cd-profile-db.c @@ -0,0 +1,333 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2014 Richard Hughes <richard@hughsie.com> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <gio/gio.h> +#include <glib-object.h> +#include <sqlite3.h> +#include <syslog.h> + +#include "cd-common.h" +#include "cd-profile-db.h" + +static void cd_profile_db_finalize (GObject *object); + +#define CD_PROFILE_DB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CD_TYPE_PROFILE_DB, CdProfileDbPrivate)) + +struct CdProfileDbPrivate +{ + sqlite3 *db; +}; + +static gpointer cd_profile_db_object = NULL; + +G_DEFINE_TYPE (CdProfileDb, cd_profile_db, G_TYPE_OBJECT) + +/** + * cd_profile_db_load: + **/ +gboolean +cd_profile_db_load (CdProfileDb *pdb, + const gchar *filename, + GError **error) +{ + const gchar *statement; + gboolean ret = TRUE; + gchar *error_msg = NULL; + gchar *path = NULL; + gint rc; + + g_return_val_if_fail (CD_IS_PROFILE_DB (pdb), FALSE); + g_return_val_if_fail (pdb->priv->db == NULL, FALSE); + + /* ensure the path exists */ + path = g_path_get_dirname (filename); + ret = cd_main_mkdir_with_parents (path, error); + if (!ret) + goto out; + + g_debug ("CdProfileDb: trying to open database '%s'", filename); + syslog (LOG_INFO, "Using profile database file %s", filename); + rc = sqlite3_open (filename, &pdb->priv->db); + if (rc != SQLITE_OK) { + ret = FALSE; + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "Can't open database: %s\n", + sqlite3_errmsg (pdb->priv->db)); + sqlite3_close (pdb->priv->db); + goto out; + } + + /* we don't need to keep doing fsync */ + sqlite3_exec (pdb->priv->db, "PRAGMA synchronous=OFF", + NULL, NULL, NULL); + + /* check schema */ + rc = sqlite3_exec (pdb->priv->db, "SELECT * FROM properties_pu LIMIT 1", + NULL, NULL, &error_msg); + if (rc != SQLITE_OK) { + statement = "CREATE TABLE properties_pu (" + "profile_id TEXT," + "property TEXT," + "uid INTEGER," + "value TEXT," + "PRIMARY KEY (profile_id, property, uid));"; + sqlite3_exec (pdb->priv->db, statement, NULL, NULL, NULL); + } +out: + g_free (path); + return ret; +} + +/** + * cd_profile_db_empty: + **/ +gboolean +cd_profile_db_empty (CdProfileDb *pdb, GError **error) +{ + const gchar *statement; + gboolean ret = TRUE; + gchar *error_msg = NULL; + gint rc; + + g_return_val_if_fail (CD_IS_PROFILE_DB (pdb), FALSE); + g_return_val_if_fail (pdb->priv->db != NULL, FALSE); + + statement = "DELETE FROM properties_pu;"; + rc = sqlite3_exec (pdb->priv->db, statement, + NULL, NULL, &error_msg); + if (rc != SQLITE_OK) { + ret = FALSE; + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "SQL error: %s", + error_msg); + sqlite3_free (error_msg); + goto out; + } +out: + return ret; +} + +/** + * cd_profile_db_set_property: + **/ +gboolean +cd_profile_db_set_property (CdProfileDb *pdb, + const gchar *profile_id, + const gchar *property, + guint uid, + const gchar *value, + GError **error) +{ + gboolean ret = TRUE; + gchar *error_msg = NULL; + gchar *statement; + gint rc; + + g_return_val_if_fail (CD_IS_PROFILE_DB (pdb), FALSE); + g_return_val_if_fail (pdb->priv->db != NULL, FALSE); + + g_debug ("CdProfileDb: add profile property %s [%s=%s]", + profile_id, property, value); + statement = sqlite3_mprintf ("INSERT OR REPLACE INTO properties_pu (profile_id, " + "property, uid, value) " + "VALUES ('%q', '%q', '%u', '%q');", + profile_id, property, uid, value); + + /* insert the entry */ + rc = sqlite3_exec (pdb->priv->db, statement, NULL, NULL, &error_msg); + if (rc != SQLITE_OK) { + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "SQL error: %s", + error_msg); + sqlite3_free (error_msg); + ret = FALSE; + goto out; + } +out: + sqlite3_free (statement); + return ret; +} + +/** + * cd_profile_db_remove: + **/ +gboolean +cd_profile_db_remove (CdProfileDb *pdb, + const gchar *profile_id, + const gchar *property, + guint uid, + GError **error) +{ + gboolean ret = TRUE; + gchar *error_msg = NULL; + gchar *statement = NULL; + gint rc; + + g_return_val_if_fail (CD_IS_PROFILE_DB (pdb), FALSE); + g_return_val_if_fail (pdb->priv->db != NULL, FALSE); + + /* remove the entry */ + g_debug ("CdProfileDb: remove profile %s", profile_id); + statement = sqlite3_mprintf ("DELETE FROM properties_pu WHERE " + "profile_id = '%q' AND " + "uid = '%i' AND " + "property = '%q' LIMIT 1;", + profile_id, uid, property); + rc = sqlite3_exec (pdb->priv->db, statement, NULL, NULL, &error_msg); + if (rc != SQLITE_OK) { + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "SQL error: %s", + error_msg); + sqlite3_free (error_msg); + ret = FALSE; + goto out; + } +out: + sqlite3_free (statement); + return ret; +} + +/** + * cd_profile_db_sqlite_cb: + **/ +static gint +cd_profile_db_sqlite_cb (void *data, + gint argc, + gchar **argv, + gchar **col_name) +{ + gchar **value = (gchar **) data; + + /* should only be one entry */ + g_debug ("CdProfileDb: got sql result %s", argv[0]); + *value = g_strdup (argv[0]); + return 0; +} + +/** + * cd_profile_db_get_property: + **/ +gboolean +cd_profile_db_get_property (CdProfileDb *pdb, + const gchar *profile_id, + const gchar *property, + guint uid, + gchar **value, + GError **error) +{ + gboolean ret = TRUE; + gchar *error_msg = NULL; + gchar *statement; + gint rc; + + g_return_val_if_fail (CD_IS_PROFILE_DB (pdb), FALSE); + g_return_val_if_fail (pdb->priv->db != NULL, FALSE); + + g_debug ("CdProfileDb: get property %s for %s", property, profile_id); + statement = sqlite3_mprintf ("SELECT value FROM properties_pu WHERE " + "profile_id = '%q' AND " + "uid = '%i' AND " + "property = '%q' LIMIT 1;", + profile_id, uid, property); + + /* retrieve the entry */ + rc = sqlite3_exec (pdb->priv->db, + statement, + cd_profile_db_sqlite_cb, + value, + &error_msg); + if (rc != SQLITE_OK) { + ret = FALSE; + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "SQL error: %s", + error_msg); + sqlite3_free (error_msg); + goto out; + } +out: + sqlite3_free (statement); + return ret; +} + +/** + * cd_profile_db_class_init: + **/ +static void +cd_profile_db_class_init (CdProfileDbClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = cd_profile_db_finalize; + g_type_class_add_private (klass, sizeof (CdProfileDbPrivate)); +} + +/** + * cd_profile_db_init: + **/ +static void +cd_profile_db_init (CdProfileDb *pdb) +{ + pdb->priv = CD_PROFILE_DB_GET_PRIVATE (pdb); +} + +/** + * cd_profile_db_finalize: + **/ +static void +cd_profile_db_finalize (GObject *object) +{ + CdProfileDb *pdb; + g_return_if_fail (CD_IS_PROFILE_DB (object)); + pdb = CD_PROFILE_DB (object); + g_return_if_fail (pdb->priv != NULL); + + /* close the database */ + sqlite3_close (pdb->priv->db); + + G_OBJECT_CLASS (cd_profile_db_parent_class)->finalize (object); +} + +/** + * cd_profile_db_new: + **/ +CdProfileDb * +cd_profile_db_new (void) +{ + if (cd_profile_db_object != NULL) { + g_object_ref (cd_profile_db_object); + } else { + cd_profile_db_object = g_object_new (CD_TYPE_PROFILE_DB, NULL); + g_object_add_weak_pointer (cd_profile_db_object, &cd_profile_db_object); + } + return CD_PROFILE_DB (cd_profile_db_object); +} + diff --git a/src/cd-profile-db.h b/src/cd-profile-db.h new file mode 100644 index 0000000..09092e8 --- /dev/null +++ b/src/cd-profile-db.h @@ -0,0 +1,82 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2014 Richard Hughes <richard@hughsie.com> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CD_PROFILE_DB_H +#define __CD_PROFILE_DB_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define CD_TYPE_PROFILE_DB (cd_profile_db_get_type ()) +#define CD_PROFILE_DB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CD_TYPE_PROFILE_DB, CdProfileDb)) +#define CD_PROFILE_DB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CD_TYPE_PROFILE_DB, CdProfileDbClass)) +#define CD_IS_PROFILE_DB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CD_TYPE_PROFILE_DB)) +#define CD_IS_PROFILE_DB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CD_TYPE_PROFILE_DB)) +#define CD_PROFILE_DB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CD_TYPE_PROFILE_DB, CdProfileDbClass)) + +typedef struct CdProfileDbPrivate CdProfileDbPrivate; + +typedef struct +{ + GObject parent; + CdProfileDbPrivate *priv; +} CdProfileDb; + +typedef struct +{ + GObjectClass parent_class; +} CdProfileDbClass; + +GType cd_profile_db_get_type (void); +CdProfileDb *cd_profile_db_new (void); + +gboolean cd_profile_db_load (CdProfileDb *pdb, + const gchar *filename, + GError **error) + G_GNUC_WARN_UNUSED_RESULT; +gboolean cd_profile_db_empty (CdProfileDb *pdb, + GError **error) + G_GNUC_WARN_UNUSED_RESULT; +gboolean cd_profile_db_set_property (CdProfileDb *pdb, + const gchar *profile_id, + const gchar *property, + guint uid, + const gchar *value, + GError **error) + G_GNUC_WARN_UNUSED_RESULT; +gboolean cd_profile_db_get_property (CdProfileDb *pdb, + const gchar *profile_id, + const gchar *property, + guint uid, + gchar **value, + GError **error) + G_GNUC_WARN_UNUSED_RESULT; +gboolean cd_profile_db_remove (CdProfileDb *pdb, + const gchar *profile_id, + const gchar *property, + guint uid, + GError **error) + G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS + +#endif /* __CD_PROFILE_DB_H */ diff --git a/src/cd-profile.c b/src/cd-profile.c index a97b060..7781c3e 100644 --- a/src/cd-profile.c +++ b/src/cd-profile.c @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * - * Copyright (C) 2010-2013 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2010-2014 Richard Hughes <richard@hughsie.com> * * Licensed under the GNU General Public License Version 2 * @@ -31,6 +31,7 @@ #include "cd-common.h" #include "cd-profile.h" +#include "cd-profile-db.h" #include "cd-resources.h" static void cd_profile_finalize (GObject *object); @@ -67,6 +68,7 @@ struct _CdProfilePrivate gchar **warnings; GMappedFile *mapped_file; guint score; + CdProfileDb *db; }; enum { @@ -530,12 +532,46 @@ cd_profile_get_nullable_for_string (const gchar *value) } /** + * cd_profile_set_title: + **/ +static gboolean +cd_profile_set_title (CdProfile *profile, + const gchar *value, + guint sender_uid, + GError **error) +{ + gboolean ret = TRUE; + CdProfilePrivate *priv = profile->priv; + + /* check title is suitable */ + if (value == NULL || strlen (value) < 3 || + !g_utf8_validate (value, -1, NULL)) { + ret = FALSE; + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INPUT_INVALID, + "'Title' value input invalid: %s", value); + goto out; + } + + /* save in database */ + ret = cd_profile_db_set_property (priv->db, priv->id, + CD_PROFILE_PROPERTY_TITLE, sender_uid, + value, error); + if (!ret) + goto out; +out: + return ret; +} + +/** * cd_profile_set_property_internal: **/ gboolean cd_profile_set_property_internal (CdProfile *profile, const gchar *property, const gchar *value, + guint sender_uid, GError **error) { gboolean ret = TRUE; @@ -580,6 +616,12 @@ cd_profile_set_property_internal (CdProfile *profile, cd_profile_dbus_emit_property_changed (profile, property, g_variant_new_string (value)); + } else if (g_strcmp0 (property, CD_PROFILE_PROPERTY_TITLE) == 0) { + ret = cd_profile_set_title (profile, value, sender_uid, error); + if (!ret) + goto out; + cd_profile_dbus_emit_property_changed (profile, property, + g_variant_new_string (value)); } else { /* add to metadata */ cd_profile_set_metadata (profile, property, value); @@ -605,6 +647,7 @@ cd_profile_dbus_method_call (GDBusConnection *connection, const gchar *sender, GDBusMethodInvocation *invocation, gpointer user_data) { gboolean ret; + guint uid; const gchar *property_name = NULL; const gchar *property_value = NULL; GError *error = NULL; @@ -627,6 +670,17 @@ cd_profile_dbus_method_call (GDBusConnection *connection, const gchar *sender, goto out; } + /* get UID */ + uid = cd_main_get_sender_uid (connection, sender, &error); + if (uid == G_MAXUINT) { + g_dbus_method_invocation_return_error (invocation, + CD_PROFILE_ERROR, + CD_PROFILE_ERROR_FAILED_TO_GET_UID, + "%s", error->message); + g_error_free (error); + goto out; + } + /* set, and parse */ g_variant_get (parameters, "(&s&s)", &property_name, @@ -645,6 +699,7 @@ cd_profile_dbus_method_call (GDBusConnection *connection, const gchar *sender, ret = cd_profile_set_property_internal (profile, property_name, property_value, + uid, &error); if (!ret) { g_dbus_method_invocation_return_gerror (invocation, @@ -699,48 +754,64 @@ out: * cd_profile_dbus_get_property: **/ static GVariant * -cd_profile_dbus_get_property (GDBusConnection *connection_, const gchar *sender, +cd_profile_dbus_get_property (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *property_name, GError **error, gpointer user_data) { GVariant *retval = NULL; CdProfile *profile = CD_PROFILE (user_data); + CdProfilePrivate *priv = profile->priv; + gboolean ret; + gchar *title_db = NULL; + guint uid; if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_TITLE) == 0) { - retval = cd_profile_get_nullable_for_string (profile->priv->title); + uid = cd_main_get_sender_uid (connection, sender, error); + if (uid == G_MAXUINT) + goto out; + ret = cd_profile_db_get_property (priv->db, priv->id, + property_name, uid, + &title_db, error); + if (!ret) + goto out; + if (title_db != NULL) { + retval = cd_profile_get_nullable_for_string (title_db); + goto out; + } + retval = cd_profile_get_nullable_for_string (priv->title); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_ID) == 0) { - retval = cd_profile_get_nullable_for_string (profile->priv->id); + retval = cd_profile_get_nullable_for_string (priv->id); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_QUALIFIER) == 0) { - retval = cd_profile_get_nullable_for_string (profile->priv->qualifier); + retval = cd_profile_get_nullable_for_string (priv->qualifier); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_FORMAT) == 0) { - retval = cd_profile_get_nullable_for_string (profile->priv->format); + retval = cd_profile_get_nullable_for_string (priv->format); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_FILENAME) == 0) { - retval = cd_profile_get_nullable_for_string (profile->priv->filename); + retval = cd_profile_get_nullable_for_string (priv->filename); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_KIND) == 0) { - retval = g_variant_new_string (cd_profile_kind_to_string (profile->priv->kind)); + retval = g_variant_new_string (cd_profile_kind_to_string (priv->kind)); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_COLORSPACE) == 0) { - retval = g_variant_new_string (cd_colorspace_to_string (profile->priv->colorspace)); + retval = g_variant_new_string (cd_colorspace_to_string (priv->colorspace)); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_HAS_VCGT) == 0) { - retval = g_variant_new_boolean (profile->priv->has_vcgt); + retval = g_variant_new_boolean (priv->has_vcgt); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_IS_SYSTEM_WIDE) == 0) { - retval = g_variant_new_boolean (profile->priv->is_system_wide); + retval = g_variant_new_boolean (priv->is_system_wide); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_METADATA) == 0) { @@ -748,20 +819,20 @@ cd_profile_dbus_get_property (GDBusConnection *connection_, const gchar *sender, goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_CREATED) == 0) { - retval = g_variant_new_int64 (profile->priv->created); + retval = g_variant_new_int64 (priv->created); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_SCOPE) == 0) { - retval = g_variant_new_string (cd_object_scope_to_string (profile->priv->object_scope)); + retval = g_variant_new_string (cd_object_scope_to_string (priv->object_scope)); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_OWNER) == 0) { - retval = g_variant_new_uint32 (profile->priv->owner); + retval = g_variant_new_uint32 (priv->owner); goto out; } if (g_strcmp0 (property_name, CD_PROFILE_PROPERTY_WARNINGS) == 0) { - if (profile->priv->warnings != NULL) { - retval = g_variant_new_strv ((const gchar * const *) profile->priv->warnings, -1); + if (priv->warnings != NULL) { + retval = g_variant_new_strv ((const gchar * const *) priv->warnings, -1); } else { const gchar *tmp[] = { NULL }; retval = g_variant_new_strv (tmp, -1); @@ -776,6 +847,7 @@ cd_profile_dbus_get_property (GDBusConnection *connection_, const gchar *sender, "failed to get profile property %s", property_name); out: + g_free (title_db); return retval; } @@ -1417,6 +1489,7 @@ static void cd_profile_init (CdProfile *profile) { profile->priv = CD_PROFILE_GET_PRIVATE (profile); + profile->priv->db = cd_profile_db_new (); profile->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, @@ -1447,6 +1520,7 @@ cd_profile_finalize (GObject *object) g_free (priv->id); g_free (priv->checksum); g_free (priv->object_path); + g_object_unref (priv->db); g_strfreev (priv->warnings); g_hash_table_unref (priv->metadata); diff --git a/src/cd-profile.h b/src/cd-profile.h index d893a8a..3d33319 100644 --- a/src/cd-profile.h +++ b/src/cd-profile.h @@ -107,6 +107,7 @@ void cd_profile_watch_sender (CdProfile *profile, gboolean cd_profile_set_property_internal (CdProfile *profile, const gchar *property, const gchar *value, + guint sender_uid, GError **error); const gchar **cd_profile_get_warnings (CdProfile *profile); diff --git a/src/cd-self-test.c b/src/cd-self-test.c index 10c09b1..4a76d07 100644 --- a/src/cd-self-test.c +++ b/src/cd-self-test.c @@ -35,6 +35,7 @@ #include "cd-device.h" #include "cd-mapping-db.h" #include "cd-profile-array.h" +#include "cd-profile-db.h" #include "cd-profile.h" static void @@ -472,6 +473,75 @@ cd_device_db_func (void) g_object_unref (ddb); } +static void +cd_profile_db_func (void) +{ + CdProfileDb *pdb; + GError *error = NULL; + gboolean ret; + gchar *value = NULL; + + /* create */ + pdb = cd_profile_db_new (); + g_assert (pdb != NULL); + + /* connect, which should create it for us */ + ret = cd_profile_db_load (pdb, "/tmp/profile.db", &error); + g_assert_no_error (error); + g_assert (ret); + + /* ensure empty */ + ret = cd_profile_db_empty (pdb, &error); + g_assert_no_error (error); + g_assert (ret); + + /* set a property */ + ret = cd_profile_db_set_property (pdb, + "profile-test", + "Title", + 500, + "My Display Profile", + &error); + g_assert_no_error (error); + g_assert (ret); + + /* get a property that does not exist */ + ret = cd_profile_db_get_property (pdb, + "profile-test", + "Modified", + 500, + &value, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (value, ==, NULL); + + /* get a property for a different user */ + ret = cd_profile_db_get_property (pdb, + "profile-test", + "Title", + 501, + &value, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (value, ==, NULL); + + /* get a property that does exist */ + ret = cd_profile_db_get_property (pdb, + "profile-test", + "Title", + 500, + &value, + &error); + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (value, ==, "My Display Profile"); + g_free (value); + + g_object_unref (pdb); +} + int main (int argc, char **argv) { @@ -487,6 +557,7 @@ main (int argc, char **argv) g_test_add_func ("/colord/mapping-db", cd_mapping_db_func); g_test_add_func ("/colord/device-db", cd_device_db_func); g_test_add_func ("/colord/profile", colord_profile_func); + g_test_add_func ("/colord/profile-db", cd_profile_db_func); g_test_add_func ("/colord/device", colord_device_func); g_test_add_func ("/colord/device-array", colord_device_array_func); return g_test_run (); |