r6881 - in dumbhippo/trunk/client: common/ddm common/hippo linux/src
- From: commits mugshot org
- To: online-desktop-list gnome org
- Subject: r6881 - in dumbhippo/trunk/client: common/ddm common/hippo linux/src
- Date: Thu, 8 Nov 2007 14:39:57 -0600 (CST)
Author: otaylor
Date: 2007-11-08 14:39:56 -0600 (Thu, 08 Nov 2007)
New Revision: 6881
Modified:
dumbhippo/trunk/client/common/ddm/ddm-data-fetch.c
dumbhippo/trunk/client/common/ddm/ddm-data-model-dbus.c
dumbhippo/trunk/client/common/ddm/ddm-data-model.c
dumbhippo/trunk/client/common/ddm/ddm-data-model.h
dumbhippo/trunk/client/common/ddm/ddm-data-query-internal.h
dumbhippo/trunk/client/common/ddm/ddm-data-query.c
dumbhippo/trunk/client/common/ddm/ddm-data-query.h
dumbhippo/trunk/client/common/ddm/ddm-work-item.c
dumbhippo/trunk/client/common/ddm/hippo-dbus-helper.c
dumbhippo/trunk/client/common/ddm/static-file-backend.c
dumbhippo/trunk/client/common/ddm/test-ddm.c
dumbhippo/trunk/client/common/ddm/test-multipart-fetch.c
dumbhippo/trunk/client/common/ddm/test-notification.c
dumbhippo/trunk/client/common/ddm/test-static-file-backend.c
dumbhippo/trunk/client/common/hippo/hippo-connection.c
dumbhippo/trunk/client/common/hippo/hippo-connection.h
dumbhippo/trunk/client/common/hippo/hippo-data-model-backend.c
dumbhippo/trunk/client/linux/src/hippo-dbus-model-client.c
dumbhippo/trunk/client/linux/src/hippo-dbus-model.c
dumbhippo/trunk/client/linux/src/hippo-platform-impl.c
Log:
ddm-data-mode.c hippo-data-model-backend.c ddm-dbus-model.c: Replace
the idea of connected with "ready" ... a model is initially not
ready, deterministically becomes ready and emits ::ready at that
point. ::ready can be emitted later to mean start over.
ddm-data-model.[ch] hippo-data-model-backend.c ddm-dbus-model.c: Add
ddm_data_model_get_{global,self}_resource special-casing to avoid
tedious duplicated logic in every handler for ::ready
ddm-data-model.[ch] test-multipart-fetch.c test-notification.c
test-static-file-backend.c: Rename
ddm_data_model_query_resource() to query_resource_by_id(), make
query_resource() take a DDMDataResource instead.
hippo-dbus-model.c ddm-data-model-dbus.c: Change to the D-BUS protocol
ConnectedChanged signal removed, replaced with Ready. Connected
property replaced with Ready. SelfId and WebBaseUrl properties removed.
ddm-data-query.[ch] ddm-data-query-internal.h: Add
ddm_data_query_error_async() to have a generic way to error a query
without causing unexpected reentrancy.
ddm-data-model-dbus.c: Remove queuing of outgoing queries; queries before
connection are report errors.
hippo-connection.[ch] hippo-platform-impl.c: Add a REDIRECTING state,
so that the redircection from the load balancer doesn't look like a
disconnection.
hippo-dbus-model-client.c: Reference the resource we store in a
DataClientConnection.
ddm-data-query.c ddm-work-item.c: Move detection of completely failed
queries (resources end up with class_id == NULL) into ddm-work-item.c.
ddm-work-item.c static-file-backend.c: Fix a cut-and-pasted bug bug with
descending while iterating a fetch.
ddm-data-fetch.c: Fix a bug in ddm_data_fetch_merge()
hippo-dbus-helper.c: Call the 'unavailable' call back if the service is
unavailable on startup (needs some more work to handle activation
properly)
test-ddm.c: Adapt to the new C API.
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-fetch.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-fetch.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-fetch.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -503,7 +503,7 @@
fetch_property_copy(&result->properties[total_properties], &other->properties[j]);
j++;
} else {
- fetch_property_merge(&result->properties[total_properties], &fetch->properties[i], &fetch->properties[i]);
+ fetch_property_merge(&result->properties[total_properties], &fetch->properties[i], &other->properties[j]);
i++;
j++;
}
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-model-dbus.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-model-dbus.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-model-dbus.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -13,33 +13,16 @@
#include <dbus/dbus.h>
-typedef enum {
- PENDING_REQUEST_QUERY,
- PENDING_REQUEST_UPDATE
-} PendingRequestType;
-
typedef struct {
- PendingRequestType type;
- DDMDataQuery *query;
-} PendingRequest;
-
-typedef struct {
int refcount;
char *path;
DDMDataModel *ddm_model;
DBusConnection *connection;
HippoDBusProxy *engine_proxy;
+ gboolean engine_ready;
HippoDBusProxy *engine_props_proxy;
- GSList *pending_requests;
} DBusModel;
-static void ddm_dbus_send_query (DDMDataModel *ddm_model,
- DDMDataQuery *query,
- void *backend_data);
-static void ddm_dbus_send_update (DDMDataModel *ddm_model,
- DDMDataQuery *query,
- void *backend_data);
-
static void
model_ref(DBusModel *dbus_model)
{
@@ -70,59 +53,6 @@
return dbus_model;
}
-static void
-model_add_pending_query(DBusModel *dbus_model,
- DDMDataQuery *query)
-{
- PendingRequest *pr;
-
- g_debug("delaying Query to org.freedesktop.od.Engine until we connect");
-
- pr = g_new0(PendingRequest, 1);
- pr->type = PENDING_REQUEST_QUERY;
- pr->query = query;
-
- dbus_model->pending_requests = g_slist_append(dbus_model->pending_requests, pr);
-}
-
-static void
-model_add_pending_update(DBusModel *dbus_model,
- DDMDataQuery *query)
-{
- PendingRequest *pr;
-
- g_debug("delaying Update to org.freedesktop.od.Engine until we connect");
-
- pr = g_new0(PendingRequest, 1);
- pr->type = PENDING_REQUEST_UPDATE;
- pr->query = query;
-
- dbus_model->pending_requests = g_slist_append(dbus_model->pending_requests, pr);
-}
-
-static void
-model_send_pending(DBusModel *dbus_model)
-{
- g_debug("Sending %d pending requests to org.freedesktop.od.Engine",
- g_slist_length(dbus_model->pending_requests));
-
- while (dbus_model->pending_requests != NULL) {
- PendingRequest *pr = dbus_model->pending_requests->data;
- dbus_model->pending_requests = g_slist_remove(dbus_model->pending_requests,
- dbus_model->pending_requests->data);
-
- if (pr->type == PENDING_REQUEST_QUERY) {
- ddm_dbus_send_query(dbus_model->ddm_model, pr->query, NULL);
- g_free(pr);
- } else if (pr->type == PENDING_REQUEST_UPDATE) {
- ddm_dbus_send_update(dbus_model->ddm_model, pr->query, NULL);
- g_free(pr);
- } else {
- g_warning("unknown pending request type");
- }
- }
-}
-
static gboolean
read_data_attributes(DBusMessageIter *prop_struct_iter,
DDMDataUpdate *update_type_p,
@@ -497,19 +427,97 @@
{ NULL }
};
+/* Common handling if an error occurs in the initialization path or we lose the
+ * connection to the server; we change the state to be offline and if we were
+ * still in the "not yet ready" state, signal the end of initialization
+ */
static void
-handle_get_connected_reply(DBusMessage *reply,
- void *data)
+dbus_model_set_offline(DBusModel *dbus_model)
{
+ DDMDataResource *global_resource;
+ DDMDataValue value;
+
+ global_resource = ddm_data_model_ensure_resource(dbus_model->ddm_model,
+ DDM_GLOBAL_RESOURCE, DDM_GLOBAL_RESOURCE_CLASS);
+ ddm_data_model_set_global_resource(dbus_model->ddm_model, global_resource);
+
+ value.type = DDM_DATA_BOOLEAN;
+ value.u.string = FALSE;
+
+ ddm_data_resource_update_property(global_resource,
+ ddm_qname_get(DDM_GLOBAL_RESOURCE_CLASS, "online"),
+ DDM_DATA_UPDATE_REPLACE,
+ DDM_DATA_CARDINALITY_1,
+ FALSE, NULL,
+ &value);
+
+ if (!ddm_data_model_is_ready(dbus_model->ddm_model))
+ ddm_data_model_signal_ready(dbus_model->ddm_model);
+}
+
+static void
+on_initial_query_success(DDMDataResource *resource,
+ gpointer user_data)
+{
+ DBusModel *dbus_model = user_data;
+ DDMDataResource *self_resource = NULL;
+
+ ddm_data_resource_get(resource,
+ "self", DDM_DATA_RESOURCE, &self_resource,
+ NULL);
+
+ ddm_data_model_set_self_resource(dbus_model->ddm_model, self_resource);
+
+ ddm_data_model_signal_ready(dbus_model->ddm_model);
+}
+
+
+static void
+on_initial_query_error(DDMDataError error,
+ const char *message,
+ gpointer user_data)
+{
+ DBusModel *dbus_model = user_data;
+
+ dbus_model_set_offline(dbus_model);
+}
+
+static void
+dbus_model_do_initial_query(DBusModel *dbus_model)
+{
+ DDMDataQuery *query;
+ DDMDataResource *global_resource;
+
+ dbus_model->engine_ready = TRUE;
+
+ ddm_data_model_reset(dbus_model->ddm_model);
+
+ global_resource = ddm_data_model_ensure_resource(dbus_model->ddm_model,
+ DDM_GLOBAL_RESOURCE, DDM_GLOBAL_RESOURCE_CLASS);
+ ddm_data_model_set_global_resource(dbus_model->ddm_model, global_resource);
+
+ query = ddm_data_model_query_resource(dbus_model->ddm_model, global_resource,
+ "self +;webBaseUrl;online");
+ ddm_data_query_set_single_handler(query, on_initial_query_success, dbus_model);
+ ddm_data_query_set_error_handler(query, on_initial_query_error, dbus_model);
+}
+
+static void
+handle_get_ready_reply(DBusMessage *reply,
+ void *data)
+{
DBusModel *dbus_model = data;
DBusMessageIter variant_iter;
DBusMessageIter toplevel_iter;
- dbus_bool_t connected;
+ dbus_bool_t ready;
if (dbus_model->ddm_model == NULL) /* happens if the reply comes in after we nuke the model */
return;
if (dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN) {
+ g_debug("Get of ready state failed");
+
+ dbus_model_set_offline(dbus_model);
return;
}
@@ -522,21 +530,17 @@
dbus_message_iter_recurse(&toplevel_iter, &variant_iter);
if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_BOOLEAN) {
- g_warning("Expecting Connected prop to have type boolean");
+ g_warning("Expecting Ready prop to have type boolean");
return;
}
- connected = FALSE;
- dbus_message_iter_get_basic(&variant_iter, &connected);
+ ready = FALSE;
+ dbus_message_iter_get_basic(&variant_iter, &ready);
- /* protect against a race / duplicate effort */
- if (dbus_model->connection == NULL ||
- !dbus_connection_get_is_connected(dbus_model->connection))
- connected = FALSE;
-
- ddm_data_model_set_connected(dbus_model->ddm_model, connected);
- if (connected)
- model_send_pending(dbus_model);
+ g_debug("Got Ready state, ready=%d", ready);
+
+ if (ready)
+ dbus_model_do_initial_query(dbus_model);
}
static void
@@ -555,6 +559,7 @@
unique_name,
"/org/freedesktop/od/data_model",
"org.freedesktop.od.Model");
+ dbus_model->engine_ready = FALSE;
dbus_model->engine_props_proxy = hippo_dbus_proxy_new(dbus_model->connection,
unique_name,
@@ -562,11 +567,11 @@
DBUS_INTERFACE_PROPERTIES);
iface = "org.freedesktop.od.Model";
- method = "Connected";
+ method = "Ready";
model_ref(dbus_model);
hippo_dbus_proxy_call_method_async(dbus_model->engine_props_proxy,
"Get",
- handle_get_connected_reply,
+ handle_get_ready_reply,
dbus_model,
(GFreeFunc) model_unref,
DBUS_TYPE_STRING,
@@ -584,17 +589,23 @@
{
DBusModel *dbus_model = data;
- g_debug("org.freedesktop.od.Engine went away");
-
- g_assert(dbus_model->engine_props_proxy != NULL);
-
- hippo_dbus_proxy_unref(dbus_model->engine_props_proxy);
- dbus_model->engine_props_proxy = NULL;
+ if (unique_name)
+ g_debug("org.freedesktop.od.Engine went away");
+ else
+ g_debug("org.freedesktop.od.Engine unavailable on startup");
- hippo_dbus_proxy_unref(dbus_model->engine_proxy);
- dbus_model->engine_proxy = NULL;
+ if (dbus_model->engine_props_proxy != NULL) {
+ hippo_dbus_proxy_unref(dbus_model->engine_props_proxy);
+ dbus_model->engine_props_proxy = NULL;
+ }
+
+ if (dbus_model->engine_proxy != NULL) {
+ hippo_dbus_proxy_unref(dbus_model->engine_proxy);
+ dbus_model->engine_proxy = NULL;
+ dbus_model->engine_ready = FALSE;
+ }
- ddm_data_model_set_connected(dbus_model->ddm_model, FALSE);
+ dbus_model_set_offline(dbus_model);
}
static HippoDBusServiceTracker engine_tracker = {
@@ -604,35 +615,24 @@
};
static void
-handle_connected_changed(DBusConnection *connection,
- DBusMessage *message,
- void *data)
+handle_ready(DBusConnection *connection,
+ DBusMessage *message,
+ void *data)
{
DBusModel *dbus_model = data;
- dbus_bool_t is_connected;
- const char *self_id;
- is_connected = FALSE;
- self_id = NULL;
-
if (!dbus_message_get_args(message, NULL,
- DBUS_TYPE_BOOLEAN, &is_connected,
- DBUS_TYPE_STRING, &self_id,
DBUS_TYPE_INVALID)) {
- g_warning("bad args to ConnectedChanged signal");
+ g_warning("bad args to Ready signal");
return;
}
- if (is_connected)
- ddm_data_model_reset(dbus_model->ddm_model);
- ddm_data_model_set_connected(dbus_model->ddm_model, is_connected);
- if (is_connected)
- model_send_pending(dbus_model);
+ g_debug("Got Ready signal from data model engine");
+ dbus_model_do_initial_query(dbus_model);
}
static HippoDBusSignalTracker engine_signal_handlers[] = {
- { "org.freedesktop.od.Model", "ConnectedChanged",
- handle_connected_changed },
+ { "org.freedesktop.od.Model", "Ready", handle_ready },
{ NULL, NULL, NULL }
};
@@ -884,17 +884,24 @@
dbus_model = get_dbus_model(ddm_model);
if (dbus_model->engine_proxy == NULL) {
- model_add_pending_query(dbus_model, query);
+ ddm_data_query_error_async (query,
+ DDM_DATA_ERROR_NO_CONNECTION,
+ "No connection to data model engine");
return;
}
+ if (!dbus_model->engine_ready) {
+ ddm_data_query_error_async (query,
+ DDM_DATA_ERROR_NO_CONNECTION,
+ "Data model engine is not ready");
+ return;
+ }
+
g_debug("sending Query to org.freedesktop.od.Engine %s#%s fetch %s",
ddm_data_query_get_qname(query)->uri,
ddm_data_query_get_qname(query)->name,
ddm_data_query_get_fetch_string(query));
- g_assert(dbus_model->engine_proxy != NULL); /* since connection != NULL */
-
qd = g_new(QueryData, 1);
model_ref(dbus_model);
@@ -979,14 +986,21 @@
dbus_model = get_dbus_model(ddm_model);
if (dbus_model->engine_proxy == NULL) {
- model_add_pending_update(dbus_model, query);
+ ddm_data_query_error_async (query,
+ DDM_DATA_ERROR_NO_CONNECTION,
+ "No connection to data model engine");
return;
}
+ if (!dbus_model->engine_ready) {
+ ddm_data_query_error_async (query,
+ DDM_DATA_ERROR_NO_CONNECTION,
+ "Data model engine is not ready");
+ return;
+ }
+
g_debug("sending Update to org.freedesktop.od.Engine");
- g_assert(dbus_model->engine_proxy != NULL); /* since connection != NULL */
-
qd = g_new(QueryData, 1);
model_ref(dbus_model);
@@ -1007,7 +1021,7 @@
ddm_dbus_remove_model,
ddm_dbus_send_query,
ddm_dbus_send_update,
- NULL,
+ NULL
};
const DDMDataModelBackend*
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-model.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-model.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-model.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -29,6 +29,9 @@
GHashTable *resources;
GHashTable *changed_resources;
+ DDMDataResource *global_resource;
+ DDMDataResource *self_resource;
+
GQueue *work_items;
gint64 next_query_serial;
@@ -36,6 +39,7 @@
guint flush_idle;
+ guint ready : 1;
guint connected : 1;
};
@@ -45,6 +49,7 @@
enum {
CONNECTED_CHANGED,
+ READY,
LAST_SIGNAL
};
@@ -82,6 +87,15 @@
NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals[READY] =
+ g_signal_new ("ready",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
@@ -112,10 +126,14 @@
/* FIXME: cancel and remove everything still in here */
g_queue_free(model->work_items);
- /* FIXME: actually clean up the resources */
g_hash_table_destroy(model->resources);
g_hash_table_destroy(model->changed_resources);
+ if (model->global_resource)
+ ddm_data_resource_unref(model->global_resource);
+ if (model->self_resource)
+ ddm_data_resource_unref(model->self_resource);
+
g_object_unref(model->local_client);
G_OBJECT_CLASS(ddm_data_model_parent_class)->finalize(object);
@@ -163,6 +181,14 @@
return model->connected;
}
+gboolean
+ddm_data_model_is_ready(DDMDataModel *model)
+{
+ g_return_val_if_fail(DDM_IS_DATA_MODEL(model), FALSE);
+
+ return model->ready;
+}
+
static GHashTable *
params_from_valist(va_list vap)
{
@@ -234,8 +260,10 @@
GSList *results;
if (resource_id == NULL) {
- /* FIXME: ERROR ASYNC HERE */
- return NULL;
+ ddm_data_query_error_async (query,
+ DDM_DATA_ERROR_BAD_REQUEST,
+ "resourceId parameter is required for http://mugshot.org/p/system#getResource");
+ return query;
}
/* The reason why we ensure (without specifying a class_id) here is so that
@@ -322,13 +350,29 @@
}
DDMDataQuery *
-ddm_data_model_query_resource(DDMDataModel *model,
- const char *resource_id,
- const char *fetch)
+ddm_data_model_query_resource (DDMDataModel *model,
+ DDMDataResource *resource,
+ const char *fetch)
{
g_return_val_if_fail (DDM_IS_DATA_MODEL(model), NULL);
+ g_return_val_if_fail (resource != NULL, NULL);
+ g_return_val_if_fail (fetch != NULL, NULL);
return data_model_query_internal(model, "http://mugshot.org/p/system#getResource", fetch, FALSE,
+ "resourceId", ddm_data_resource_get_resource_id(resource),
+ NULL);
+}
+
+DDMDataQuery *
+ddm_data_model_query_resource_by_id(DDMDataModel *model,
+ const char *resource_id,
+ const char *fetch)
+{
+ g_return_val_if_fail (DDM_IS_DATA_MODEL(model), NULL);
+ g_return_val_if_fail (resource_id != NULL, NULL);
+ g_return_val_if_fail (fetch != NULL, NULL);
+
+ return data_model_query_internal(model, "http://mugshot.org/p/system#getResource", fetch, FALSE,
"resourceId", resource_id,
NULL);
}
@@ -467,6 +511,16 @@
ddm_data_model_reset (DDMDataModel *model)
{
g_hash_table_foreach_remove(model->resources, model_reset_foreach, NULL);
+
+ if (model->global_resource != NULL && !ddm_data_resource_is_local(model->global_resource)) {
+ ddm_data_resource_unref(model->global_resource);
+ model->global_resource = NULL;
+ }
+
+ if (model->self_resource != NULL && !ddm_data_resource_is_local(model->self_resource)) {
+ ddm_data_resource_unref(model->self_resource);
+ model->self_resource = NULL;
+ }
}
void
@@ -482,6 +536,13 @@
}
void
+ddm_data_model_signal_ready (DDMDataModel *model)
+{
+ model->ready = TRUE;
+ g_signal_emit(G_OBJECT(model), signals[READY], 0);
+}
+
+void
_ddm_data_model_mark_changed(DDMDataModel *model,
DDMDataResource *resource)
{
@@ -686,3 +747,46 @@
return model->local_client;
}
+void
+ddm_data_model_set_global_resource (DDMDataModel *model,
+ DDMDataResource *global_resource)
+{
+ if (global_resource == model->global_resource)
+ return;
+
+ if (model->global_resource)
+ ddm_data_resource_unref(model->global_resource);
+
+ model->global_resource = global_resource;
+
+ if (model->global_resource)
+ ddm_data_resource_ref(model->global_resource);
+}
+
+void
+ddm_data_model_set_self_resource (DDMDataModel *model,
+ DDMDataResource *self_resource)
+{
+ if (self_resource == model->self_resource)
+ return;
+
+ if (model->self_resource)
+ ddm_data_resource_unref(model->self_resource);
+
+ model->self_resource = self_resource;
+
+ if (model->self_resource)
+ ddm_data_resource_ref(model->self_resource);
+}
+
+DDMDataResource *
+ddm_data_model_get_global_resource(DDMDataModel *model)
+{
+ return model->global_resource;
+}
+
+DDMDataResource *
+ddm_data_model_get_self_resource(DDMDataModel *model)
+{
+ return model->self_resource;
+}
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-model.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-model.h 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-model.h 2007-11-08 20:39:56 UTC (rev 6881)
@@ -39,6 +39,11 @@
/* Used testing purposes; you can't call query or update on such a backend */
DDMDataModel *ddm_data_model_new_no_backend (void);
gboolean ddm_data_model_get_connected (DDMDataModel *model);
+gboolean ddm_data_model_is_ready (DDMDataModel *model);
+
+DDMDataResource *ddm_data_model_get_global_resource (DDMDataModel *model);
+DDMDataResource *ddm_data_model_get_self_resource (DDMDataModel *model);
+
DDMDataQuery *ddm_data_model_query (DDMDataModel *model,
const char *method,
const char *fetch,
@@ -47,9 +52,14 @@
const char *method,
const char *fetch,
GHashTable *params);
-DDMDataQuery *ddm_data_model_query_resource (DDMDataModel *model,
- const char *resource_id,
- const char *fetch);
+
+DDMDataQuery *ddm_data_model_query_resource (DDMDataModel *model,
+ DDMDataResource *resource,
+ const char *fetch);
+DDMDataQuery *ddm_data_model_query_resource_by_id (DDMDataModel *model,
+ const char *resource_id,
+ const char *fetch);
+
DDMDataQuery *ddm_data_model_update (DDMDataModel *model,
const char *method,
...) G_GNUC_NULL_TERMINATED;
@@ -89,7 +99,13 @@
void ddm_data_model_set_connected (DDMDataModel *model,
gboolean connected);
+void ddm_data_model_signal_ready (DDMDataModel *model);
+void ddm_data_model_set_global_resource (DDMDataModel *model,
+ DDMDataResource *global_resource);
+void ddm_data_model_set_self_resource (DDMDataModel *model,
+ DDMDataResource *self_resource);
+
G_END_DECLS
#endif /* __DDM_DATA_MODEL_H__ */
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-query-internal.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-query-internal.h 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-query-internal.h 2007-11-08 20:39:56 UTC (rev 6881)
@@ -18,6 +18,13 @@
GHashTable *params,
gint64 serial);
+/* Like ddm_data_query_error_async(), but for use when a
+ * QueryResponse work item is already in the work queue.
+ */
+void _ddm_data_query_mark_error (DDMDataQuery *query,
+ DDMDataError error,
+ const char *message);
+
/* Called when we short-circuit a getResource response and throw
* it immediately on the work-item pile
*/
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-query.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-query.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-query.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -19,7 +19,10 @@
char *fetch_string;
DDMDataFetch *fetch;
GHashTable *params;
+
GSList *results;
+ DDMDataError error;
+ char *error_message;
HandlerType handler_type;
union {
@@ -87,6 +90,12 @@
return query->results;
}
+gboolean
+ddm_data_query_has_error (DDMDataQuery *query)
+{
+ return query->error_message != NULL;
+}
+
void
ddm_data_query_set_single_handler (DDMDataQuery *query,
DDMSingleHandler handler,
@@ -218,8 +227,10 @@
g_free(query->fetch_string);
g_hash_table_destroy(query->params);
+ g_free(query->id_string);
+
g_slist_free(query->results);
- g_free(query->id_string);
+ g_free(query->error_message);
g_free(query);
}
@@ -255,16 +266,16 @@
if (children != NULL) {
ddm_data_property_get_value(property, &value);
- g_assert (DDM_DATA_BASE(value.type) == DDM_DATA_RESOURCE);
-
- if (DDM_DATA_IS_LIST(value.type)) {
- GSList *l;
-
- for (l = value.u.list; l; l = l->next) {
- mark_received_fetches(l->data, children, local);
+ if (DDM_DATA_BASE(value.type) == DDM_DATA_RESOURCE) { /* Could also be NONE */
+ if (DDM_DATA_IS_LIST(value.type)) {
+ GSList *l;
+
+ for (l = value.u.list; l; l = l->next) {
+ mark_received_fetches(l->data, children, local);
+ }
+ } else {
+ mark_received_fetches(value.u.resource, children, local);
}
- } else {
- mark_received_fetches(value.u.resource, children, local);
}
}
}
@@ -280,23 +291,6 @@
DDMWorkItem *item;
GSList *l;
- /* It's possible that we succeeded in getting a list of results, but
- * couldn't even find out the class_id for the results (particularly
- * for getResource, where a simple failed query shows this way)
- * In this case, treat the whole thing as a failure.
- */
- for (l = results; l; l = l->next) {
- if (ddm_data_resource_get_class_id(l->data) == NULL) {
- g_debug("%s: resource %s has no class ID, failing query",
- query->id_string, ddm_data_resource_get_resource_id(l->data));
-
- ddm_data_query_error(query,
- DDM_DATA_ERROR_ITEM_NOT_FOUND,
- "Couldn't get details of result items");
- return;
- }
- }
-
if (!local) {
g_debug("%s: Received response", query->id_string);
@@ -323,6 +317,7 @@
GSList *results)
{
g_return_if_fail(query != NULL);
+ g_return_if_fail(query->error_message == NULL);
data_query_response_internal(query, results, FALSE);
}
@@ -332,6 +327,7 @@
GSList *results)
{
g_return_if_fail(query != NULL);
+ g_return_if_fail(query->error_message == NULL);
data_query_response_internal(query, results, TRUE);
}
@@ -341,6 +337,15 @@
{
g_return_if_fail(query != NULL);
+ if (query->error_message) {
+ if (query->error_handler)
+ query->error_handler(query->error, query->error_message, query->error_handler_data);
+
+ ddm_data_query_free(query);
+
+ return;
+ }
+
g_debug("%s: Have complete fetch, running response", query->id_string);
switch (query->handler_type) {
@@ -379,14 +384,19 @@
}
void
-ddm_data_query_error (DDMDataQuery *query,
- DDMDataError error,
- const char *message)
+_ddm_data_query_mark_error(DDMDataQuery *query,
+ DDMDataError error,
+ const char *message)
{
g_return_if_fail(query != NULL);
+ g_return_if_fail(message != NULL);
+ g_return_if_fail(query->results == NULL);
g_debug("%s: Got error response: %s (%d)", query->id_string, message != NULL ? message : "<null>", error);
+ query->error = error;
+ query->error_message = g_strdup(message);
+
/* For a getResource query for a particular resource, we want to mark the
* fetch as 'received', so that we don't try to fetch it again. This is
* especially important for keeping our multi-part fetch code from going
@@ -413,11 +423,37 @@
}
_ddm_data_model_query_answered(query->model, query);
+}
+
+void
+ddm_data_query_error (DDMDataQuery *query,
+ DDMDataError error,
+ const char *message)
+{
+ g_return_if_fail(query != NULL);
+ g_return_if_fail(message != NULL);
+ g_return_if_fail(query->results == NULL);
+
+ _ddm_data_query_mark_error(query, error, message);
+ _ddm_data_query_run_response(query);
+}
+
+void
+ddm_data_query_error_async (DDMDataQuery *query,
+ DDMDataError error,
+ const char *message)
+{
+ DDMWorkItem *item;
+
+ g_return_if_fail(query != NULL);
+ g_return_if_fail(message != NULL);
+ g_return_if_fail(query->results == NULL);
+
+ _ddm_data_query_mark_error(query, error, message);
- if (query->error_handler)
- query->error_handler(error, message, query->error_handler_data);
-
- ddm_data_query_free(query);
+ item = _ddm_work_item_query_response_new(query->model, query);
+ _ddm_data_model_add_work_item(query->model, item);
+ _ddm_work_item_unref(item);
}
gint64
Modified: dumbhippo/trunk/client/common/ddm/ddm-data-query.h
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-data-query.h 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-data-query.h 2007-11-08 20:39:56 UTC (rev 6881)
@@ -49,15 +49,25 @@
gboolean ddm_data_query_is_update (DDMDataQuery *query);
GHashTable * ddm_data_query_get_params (DDMDataQuery *query);
GSList * ddm_data_query_get_results (DDMDataQuery *query);
+gboolean ddm_data_query_has_error (DDMDataQuery *query);
/* Called by the backend when a response is received from upstream */
void ddm_data_query_response (DDMDataQuery *query,
GSList *results);
+
void ddm_data_query_error (DDMDataQuery *query,
DDMDataError error,
const char *message);
+/* Like ddm_data_query_error(), but calls the callback asynchronously;
+ * this should generally be used when an error occurs while sending
+ * a DDMDataQuery.
+ */
+void ddm_data_query_error_async (DDMDataQuery *query,
+ DDMDataError error,
+ const char *message);
+
/* Debugging convenience */
const char *ddm_data_query_get_id_string (DDMDataQuery *query);
Modified: dumbhippo/trunk/client/common/ddm/ddm-work-item.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/ddm-work-item.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/ddm-work-item.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -239,18 +239,18 @@
if (children != NULL) {
ddm_data_property_get_value(property, &value);
- g_assert (DDM_DATA_BASE(value.type) == DDM_DATA_RESOURCE);
-
- if (DDM_DATA_IS_LIST(value.type)) {
- GSList *l;
-
- for (l = value.u.list; l; l = l->next) {
- if (!item_fetch_additional(item, l->data, children))
+ if (DDM_DATA_BASE(value.type) == DDM_DATA_RESOURCE) { /* Could also be NONE */
+ if (DDM_DATA_IS_LIST(value.type)) {
+ GSList *l;
+
+ for (l = value.u.list; l; l = l->next) {
+ if (!item_fetch_additional(item, l->data, children))
+ all_satisfied = FALSE;
+ }
+ } else {
+ if (!item_fetch_additional(item, value.u.resource, children))
all_satisfied = FALSE;
}
- } else {
- if (!item_fetch_additional(item, value.u.resource, children))
- all_satisfied = FALSE;
}
}
}
@@ -317,13 +317,30 @@
break;
case ITEM_QUERY_RESPONSE:
{
- GSList *resources = ddm_data_query_get_results(item->u.query_response.query);
- for (l = resources; l; l = l->next) {
- DDMDataResource *resource = l->data;
-
- if (!item_fetch_additional(item, resource,
- ddm_data_query_get_fetch(item->u.query_response.query)))
- all_satisfied = FALSE;
+ DDMDataQuery *query = item->u.query_response.query;
+
+ if (!ddm_data_query_has_error(query)) {
+ GSList *resources = ddm_data_query_get_results(query);
+ for (l = resources; l; l = l->next) {
+ DDMDataResource *resource = l->data;
+
+ if (item_fetch_additional(item, resource,
+ ddm_data_query_get_fetch(query))) {
+ if (ddm_data_resource_get_class_id(resource) == NULL) {
+ /* This means that we've done everything we can and we still know
+ * nothing about the resource.
+ */
+ _ddm_data_query_mark_error(query,
+ DDM_DATA_ERROR_ITEM_NOT_FOUND,
+ "Couldn't get details of result item");
+ all_satisfied = TRUE;
+ break;
+
+ }
+ } else {
+ all_satisfied = FALSE;
+ }
+ }
}
}
break;
Modified: dumbhippo/trunk/client/common/ddm/hippo-dbus-helper.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/hippo-dbus-helper.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/hippo-dbus-helper.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -1145,20 +1145,26 @@
if (service == NULL)
return; /* we don't care about this */
- if (service->owner &&
- (new_owner == NULL ||
- strcmp(service->owner, new_owner) != 0)) {
- /* Our previously-believed owner is going away */
+ if ((new_owner == NULL ||
+ (service->owner != NULL && strcmp(service->owner, new_owner) != 0))) {
+ /* Our previously-believed owner is going away, or we didn't find
+ * the service on startup. */
char *owner;
-
- g_hash_table_remove(helper->services_by_owner,
- service->owner);
- owner = service->owner;
- service->owner = NULL;
- g_debug("Service '%s' is now unavailable, old owner was '%s'",
- service->well_known_name,
- owner);
+ if (service->owner) {
+ g_hash_table_remove(helper->services_by_owner,
+ service->owner);
+ owner = service->owner;
+ service->owner = NULL;
+
+ g_debug("Service '%s' is now unavailable, old owner was '%s'",
+ service->well_known_name,
+ owner);
+ } else {
+ g_debug("Service '%s' not available on startup",
+ service->well_known_name);
+ }
+
(* service->tracker->unavailable_handler) (connection,
service->well_known_name,
owner,
@@ -1241,7 +1247,6 @@
if (*v_STRING == '\0')
v_STRING = NULL;
- /* this will do nothing if going NULL->NULL on startup */
handle_name_owner_changed(god->connection,
god->well_known_name,
NULL,
@@ -1269,6 +1274,19 @@
dbus_message_unref(msg);
}
}
+ } else {
+ /*
+ * Probably org.freedesktop.DBus.Error.NameHasNoOwner, but we might as well treat
+ * all error messages the same.
+ */
+ const char *message = NULL;
+ dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &message, DBUS_TYPE_INVALID);
+ g_debug("GetNameOwner failed: %s", message);
+
+ handle_name_owner_changed(god->connection,
+ god->well_known_name,
+ NULL,
+ NULL);
}
dbus_message_unref(reply);
Modified: dumbhippo/trunk/client/common/ddm/static-file-backend.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/static-file-backend.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/static-file-backend.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -77,14 +77,13 @@
DDMDataProperty *frontend_property;
DDMQName *property_id;
DDMDataValue value;
- DDMDataFetch *children;
DDMDataCardinality cardinality;
gboolean default_include;
DDMDataFetch *default_children;
char *default_children_string;
GSList *l;
- ddm_data_fetch_iter_next(&iter, &backend_property, &children);
+ ddm_data_fetch_iter_next(&iter, &backend_property, NULL);
property_id = ddm_data_property_get_qname(backend_property);
@@ -158,16 +157,17 @@
if (children != NULL) {
ddm_data_property_get_value(backend_property, &value);
- g_assert(DDM_DATA_BASE(value.type) == DDM_DATA_RESOURCE);
- if (DDM_DATA_IS_LIST(value.type)) {
- for (l = value.u.list; l; l = l->next) {
+ if (DDM_DATA_BASE(value.type) == DDM_DATA_RESOURCE) { /* Could also be NONE */
+ if (DDM_DATA_IS_LIST(value.type)) {
+ for (l = value.u.list; l; l = l->next) {
+ model_process_query_recurse(static_file_model, query,
+ l->data, children);
+ }
+ } else {
model_process_query_recurse(static_file_model, query,
- l->data, children);
+ value.u.resource, children);
}
- } else {
- model_process_query_recurse(static_file_model, query,
- value.u.resource, children);
}
}
}
Modified: dumbhippo/trunk/client/common/ddm/test-ddm.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/test-ddm.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/test-ddm.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -58,29 +58,19 @@
}
static void
-on_query_response(GSList *resources,
- gpointer user_data)
+on_query_response(DDMDataResource *resource,
+ gpointer user_data)
{
- GSList *l;
-
- for (l = resources; l != NULL; l = l->next) {
- DDMDataResource *resource = l->data;
- GSList *properties;
+ GSList *properties;
- g_print("Resource '%s' received in reply to query\n",
- ddm_data_resource_get_resource_id(resource));
-
- properties = ddm_data_resource_get_properties(resource);
-
- print_resource_properties(resource, properties);
-
- g_slist_free(properties);
-
- ddm_data_resource_connect(resource,
- NULL, /* NULL = all properties */
- on_resource_changed,
- NULL);
- }
+ g_print("Resource '%s' received in reply to query\n",
+ ddm_data_resource_get_resource_id(resource));
+
+ properties = ddm_data_resource_get_properties(resource);
+
+ print_resource_properties(resource, properties);
+
+ g_slist_free(properties);
}
static void
@@ -91,36 +81,42 @@
g_printerr("Failed to get query reply: '%s'\n", message);
}
+static void
+on_ready(DDMDataModel *model)
+{
+ DDMDataQuery *query;
+ DDMDataResource *self_resource;
+
+ self_resource = ddm_data_model_get_self_resource(model);
+ if (self_resource != NULL) {
+ ddm_data_model_query_resource(model, self_resource,
+ "name;photoUrl;lovedAccounts +");
+ ddm_data_resource_connect(self_resource, NULL, on_resource_changed, NULL);
+ }
+
+ query = ddm_data_model_query_resource(model,
+ ddm_data_model_get_global_resource(model),
+ "self [ photoUrl ]");
+ if (query == NULL) {
+ g_printerr("Failed to query global resource\n");
+ return;
+ }
+
+ ddm_data_query_set_single_handler(query, on_query_response, NULL);
+ ddm_data_query_set_error_handler(query, on_query_error, NULL);
+}
+
int
main(int argc, char **argv)
{
- DDMDataQuery *global_resource_query;
GMainLoop *loop;
g_type_init();
ddm_model = ddm_data_model_get_default();
-#if 0
- global_resource_query = ddm_data_model_query_resource(ddm_model,
- "http://dogfood.mugshot.org:9080/o/user/c4a3fc1f528070",
- "topApplications+;contacts+;settings+");
-#else
- global_resource_query = ddm_data_model_query_resource(ddm_model,
- "online-desktop:/o/global", "self [ photoUrl ]");
-#endif
-
- if (global_resource_query == NULL) {
- g_printerr("Failed to query global resource\n");
- return 1;
- }
-
- ddm_data_query_set_multi_handler(global_resource_query,
- on_query_response, NULL);
-
- ddm_data_query_set_error_handler(global_resource_query,
- on_query_error, NULL);
-
+ g_signal_connect(ddm_model, "ready", G_CALLBACK(on_ready), NULL);
+
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
g_main_loop_unref(loop);
Modified: dumbhippo/trunk/client/common/ddm/test-multipart-fetch.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/test-multipart-fetch.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/test-multipart-fetch.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -33,7 +33,7 @@
DDMDataResource *result = NULL;
const char *error = NULL;
- query = ddm_data_model_query_resource(model, resource_id, fetch);
+ query = ddm_data_model_query_resource_by_id(model, resource_id, fetch);
ddm_data_query_set_single_handler(query, on_query_result, &result);
ddm_data_query_set_error_handler(query, on_query_error, &error);
Modified: dumbhippo/trunk/client/common/ddm/test-notification.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/test-notification.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/test-notification.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -42,7 +42,7 @@
DDMDataResource *result = NULL;
const char *error = NULL;
- query = ddm_data_model_query_resource(model, resource_id, fetch);
+ query = ddm_data_model_query_resource_by_id(model, resource_id, fetch);
ddm_data_query_set_single_handler(query, on_query_result, &result);
ddm_data_query_set_error_handler(query, on_query_error, &error);
Modified: dumbhippo/trunk/client/common/ddm/test-static-file-backend.c
===================================================================
--- dumbhippo/trunk/client/common/ddm/test-static-file-backend.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/ddm/test-static-file-backend.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -33,7 +33,7 @@
DDMDataResource *result = NULL;
const char *error = NULL;
- query = ddm_data_model_query_resource(model, resource_id, fetch);
+ query = ddm_data_model_query_resource_by_id(model, resource_id, fetch);
ddm_data_query_set_single_handler(query, on_query_result, &result);
ddm_data_query_set_error_handler(query, on_query_error, &error);
Modified: dumbhippo/trunk/client/common/hippo/hippo-connection.c
===================================================================
--- dumbhippo/trunk/client/common/hippo/hippo-connection.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/hippo/hippo-connection.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -936,10 +936,14 @@
hippo_connection_connect_failure(HippoConnection *connection,
const char *message)
{
+ /* message can be NULL */
g_debug("Connection failure message: '%s'", message ? message : "NULL");
- /* message can be NULL */
hippo_connection_clear(connection);
+
+ if (connection->state == HIPPO_STATE_REDIRECTING)
+ return;
+
hippo_connection_start_retry_timeout(connection);
hippo_connection_state_change(connection, HIPPO_STATE_RETRYING);
}
@@ -3950,8 +3954,9 @@
if (child) {
char *redirect_host = g_strdup(child->value);
g_debug("Got see-other-host message, redirected to '%s'", redirect_host);
-
- hippo_connection_signout(connection);
+
+ hippo_connection_state_change(connection, HIPPO_STATE_REDIRECTING);
+ hippo_connection_disconnect(connection);
hippo_connection_connect(connection, redirect_host);
g_free (redirect_host);
return LM_HANDLER_RESULT_REMOVE_MESSAGE;
@@ -4201,6 +4206,7 @@
tip = _("%s (please log in to mugshot.org)");
break;
case HIPPO_STATE_CONNECTING:
+ case HIPPO_STATE_REDIRECTING:
case HIPPO_STATE_AUTHENTICATING:
tip = _("%s (connecting - please wait)");
break;
@@ -4252,6 +4258,8 @@
return "SIGN_IN_WAIT";
case HIPPO_STATE_CONNECTING:
return "CONNECTING";
+ case HIPPO_STATE_REDIRECTING:
+ return "REDIRECTING";
case HIPPO_STATE_RETRYING:
return "RETRYING";
case HIPPO_STATE_AUTHENTICATING:
Modified: dumbhippo/trunk/client/common/hippo/hippo-connection.h
===================================================================
--- dumbhippo/trunk/client/common/hippo/hippo-connection.h 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/hippo/hippo-connection.h 2007-11-08 20:39:56 UTC (rev 6881)
@@ -12,6 +12,7 @@
HIPPO_STATE_SIGNED_OUT, // User hasn't asked to connect
HIPPO_STATE_SIGN_IN_WAIT, // Waiting for the user to sign in
HIPPO_STATE_CONNECTING, // Waiting for connecting to server
+ HIPPO_STATE_REDIRECTING, // Redirection from load balancer to real server
HIPPO_STATE_RETRYING, // Connection to server failed, retrying
HIPPO_STATE_AUTHENTICATING, // Waiting for authentication
HIPPO_STATE_AUTH_WAIT, // Authentication failed, waiting for new creds
Modified: dumbhippo/trunk/client/common/hippo/hippo-data-model-backend.c
===================================================================
--- dumbhippo/trunk/client/common/hippo/hippo-data-model-backend.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/common/hippo/hippo-data-model-backend.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -71,50 +71,150 @@
}
static void
-on_connection_connected_changed(HippoConnection *connection,
- gboolean connected,
- HippoModel *hippo_model)
-{
+model_set_initial_properties(HippoModel *hippo_model)
+{
+ HippoConnection *connection = hippo_data_cache_get_connection(hippo_model->data_cache);
+ HippoPlatform *platform = hippo_connection_get_platform(connection);
DDMDataResource *global_resource;
+ DDMDataResource *self_resource;
const char *self_id;
- DDMQName *self_id_prop;
DDMDataValue value;
+ char *web_server;
+ char *web_base_url;
+ global_resource = ddm_data_model_ensure_local_resource(hippo_model->ddm_model,
+ DDM_GLOBAL_RESOURCE, DDM_GLOBAL_RESOURCE_CLASS);
+ ddm_data_model_set_global_resource(hippo_model->ddm_model, global_resource);
+
+ self_id = hippo_connection_get_self_resource_id(connection);
+ if (self_id) {
+ self_resource = ddm_data_model_ensure_resource(hippo_model->ddm_model,
+ self_id, "http://mugshot.org/p/o/user");
+ value.type = DDM_DATA_RESOURCE;
+ value.u.resource = self_resource;
+ } else {
+ self_resource = NULL;
+ value.type = DDM_DATA_NONE;
+ }
+
+ ddm_data_model_set_self_resource(hippo_model->ddm_model, self_resource);
+
+ ddm_data_resource_update_property(global_resource,
+ ddm_qname_get(DDM_GLOBAL_RESOURCE_CLASS, "self"),
+ self_id ? DDM_DATA_UPDATE_REPLACE : DDM_DATA_UPDATE_DELETE,
+ DDM_DATA_CARDINALITY_01,
+ FALSE, NULL,
+ &value);
+
+ /* DESKTOP hardcoded here since this is the data model API, nothing to do with stacker */
+ web_server = hippo_platform_get_web_server(platform, HIPPO_SERVER_DESKTOP);
+ /* Note, no trailing '/', don't add one here because relative urls are given
+ * starting with '/' and so you want to be able to do baseurl + relativeurl
+ */
+ web_base_url = g_strdup_printf("http://%s", web_server);
+
+ value.type = DDM_DATA_STRING;
+ value.u.string = web_base_url;
+
+ ddm_data_resource_update_property(global_resource,
+ ddm_qname_get(DDM_GLOBAL_RESOURCE_CLASS, "webBaseUrl"),
+ DDM_DATA_UPDATE_REPLACE,
+ DDM_DATA_CARDINALITY_1,
+ FALSE, NULL,
+ &value);
+
+ g_free(web_server);
+ g_free(web_base_url);
+
+ value.type = DDM_DATA_BOOLEAN;
+ value.u.boolean = hippo_connection_get_connected(connection);
+
+ ddm_data_resource_update_property(global_resource,
+ ddm_qname_get(DDM_GLOBAL_RESOURCE_CLASS, "online"),
+ DDM_DATA_UPDATE_REPLACE,
+ DDM_DATA_CARDINALITY_1,
+ FALSE, NULL,
+ &value);
+}
+
+static void
+model_on_connected(HippoModel *hippo_model)
+{
/* We first "reset" - deleting all non-local resources from the model, and all property
* values that reference non-local properties; then we add back the "self" property, which
* references the local resource, *then* we signal that we are reconnected, so that the
* self property is already there.
*/
ddm_data_model_reset(hippo_model->ddm_model);
+
+ model_set_initial_properties(hippo_model);
+ ddm_data_model_signal_ready(hippo_model->ddm_model);
+}
+
+static void
+model_on_disconnected(HippoModel *hippo_model)
+{
+ DDMDataResource *global_resource;
+ DDMDataValue value;
+
global_resource = ddm_data_model_ensure_local_resource(hippo_model->ddm_model,
DDM_GLOBAL_RESOURCE, DDM_GLOBAL_RESOURCE_CLASS);
- if (connected) {
- self_id = hippo_connection_get_self_resource_id(connection);
- } else {
- self_id = NULL;
- }
- self_id_prop = ddm_qname_get(DDM_GLOBAL_RESOURCE_CLASS, "self");
- if (self_id) {
- value.type = DDM_DATA_RESOURCE;
- value.u.resource = ddm_data_model_ensure_resource(hippo_model->ddm_model,
- self_id, "http://mugshot.org/p/o/user");
- } else {
- value.type = DDM_DATA_NONE;
- }
+ value.type = DDM_DATA_BOOLEAN;
+ value.u.string = FALSE;
ddm_data_resource_update_property(global_resource,
- self_id_prop,
- self_id ? DDM_DATA_UPDATE_REPLACE : DDM_DATA_UPDATE_DELETE,
- DDM_DATA_CARDINALITY_01,
+ ddm_qname_get(DDM_GLOBAL_RESOURCE_CLASS, "online"),
+ DDM_DATA_UPDATE_REPLACE,
+ DDM_DATA_CARDINALITY_1,
FALSE, NULL,
&value);
+}
- ddm_data_model_set_connected(hippo_model->ddm_model, connected);
+static void
+on_connection_connected_changed(HippoConnection *connection,
+ gboolean connected,
+ HippoModel *hippo_model)
+{
+ if (connected)
+ model_on_connected(hippo_model);
+ else
+ model_on_disconnected(hippo_model);
}
static void
+on_connection_state_changed(HippoConnection *connection,
+ HippoModel *hippo_model)
+{
+ /* When we start up, we want to wait to signal ready until either:
+ *
+ * - We manage to connect
+ * - We fail to connect and are either retrying or waiting for user input
+ *
+ */
+
+ switch (hippo_connection_get_state(connection)) {
+ case HIPPO_STATE_SIGNED_OUT:
+ case HIPPO_STATE_SIGN_IN_WAIT:
+ case HIPPO_STATE_RETRYING:
+ case HIPPO_STATE_AUTH_WAIT:
+ if (!ddm_data_model_is_ready(hippo_model->ddm_model)) {
+ model_set_initial_properties(hippo_model);
+ ddm_data_model_signal_ready(hippo_model->ddm_model);
+ }
+ break;
+
+ case HIPPO_STATE_CONNECTING:
+ case HIPPO_STATE_REDIRECTING:
+ case HIPPO_STATE_AUTHENTICATING:
+ case HIPPO_STATE_AWAITING_CLIENT_INFO:
+ case HIPPO_STATE_AUTHENTICATED:
+ break;
+ }
+}
+
+static void
hippo_add_model (DDMDataModel *ddm_model,
void *backend_data)
{
@@ -141,6 +241,9 @@
g_signal_connect(connection, "has-auth-changed",
G_CALLBACK(on_connection_has_auth_changed), hippo_model);
+ g_signal_connect(connection, "state-changed",
+ G_CALLBACK(on_connection_state_changed), hippo_model);
+
open_disk_cache(hippo_model);
}
Modified: dumbhippo/trunk/client/linux/src/hippo-dbus-model-client.c
===================================================================
--- dumbhippo/trunk/client/linux/src/hippo-dbus-model-client.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/linux/src/hippo-dbus-model-client.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -56,7 +56,7 @@
DataClientConnection *connection = g_new0(DataClientConnection, 1);
connection->client = client;
- connection->resource = resource;
+ connection->resource = ddm_data_resource_ref(resource);
connection->fetch = NULL;
return connection;
@@ -81,6 +81,8 @@
data_client_connection_destroy(DataClientConnection *connection)
{
ddm_data_resource_set_client_fetch(connection->resource, DDM_CLIENT(connection->client), NULL);
+ ddm_data_resource_unref(connection->resource);
+
g_free(connection);
}
Modified: dumbhippo/trunk/client/linux/src/hippo-dbus-model.c
===================================================================
--- dumbhippo/trunk/client/linux/src/hippo-dbus-model.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/linux/src/hippo-dbus-model.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -30,9 +30,8 @@
GHashTable *clients;
};
-static void on_connected_changed (DDMDataModel *ddm_model,
- gboolean connected,
- void *data);
+static void on_ready (DDMDataModel *ddm_model,
+ void *data);
static guint
data_client_id_hash(const DataClientId *id)
@@ -318,53 +317,24 @@
}
static dbus_bool_t
-handle_get_connected(void *object,
- const char *prop_name,
- DBusMessageIter *append_iter,
- DBusError *error)
+handle_get_ready(void *object,
+ const char *prop_name,
+ DBusMessageIter *append_iter,
+ DBusError *error)
{
DDMDataModel *ddm_model;
- dbus_bool_t connected;
+ dbus_bool_t ready;
ddm_model = hippo_app_get_data_model(hippo_get_app());
- connected = ddm_data_model_get_connected(ddm_model);
+ ready = ddm_data_model_is_ready(ddm_model);
- dbus_message_iter_append_basic(append_iter, DBUS_TYPE_BOOLEAN, &connected);
+ dbus_message_iter_append_basic(append_iter, DBUS_TYPE_BOOLEAN, &ready);
return TRUE;
}
-static char *
-get_self_id()
-{
- HippoDataCache *cache = hippo_app_get_data_cache(hippo_get_app());
- HippoConnection *hippo_connection = hippo_data_cache_get_connection(cache);
- const char *self_resource_id = hippo_connection_get_self_resource_id(hippo_connection);
-
- if (self_resource_id == NULL) {
- return g_strdup("");
- } else {
- return g_strdup(self_resource_id);
- }
-}
-
static dbus_bool_t
-handle_get_self_id(void *object,
- const char *prop_name,
- DBusMessageIter *append_iter,
- DBusError *error)
-{
- char *resource_id = get_self_id();
-
- dbus_message_iter_append_basic(append_iter, DBUS_TYPE_STRING, &resource_id);
-
- g_free(resource_id);
-
- return TRUE;
-}
-
-static dbus_bool_t
handle_get_server(void *object,
const char *prop_name,
DBusMessageIter *append_iter,
@@ -386,34 +356,6 @@
return TRUE;
}
-static dbus_bool_t
-handle_get_web_base_url(void *object,
- const char *prop_name,
- DBusMessageIter *append_iter,
- DBusError *error)
-{
- char *server;
- char *url;
- HippoDataCache *cache = hippo_app_get_data_cache(hippo_get_app());
- HippoConnection *hippo_connection = hippo_data_cache_get_connection(cache);
- HippoPlatform *platform = hippo_connection_get_platform(hippo_connection);
-
- /* DESKTOP hardcoded here since this is the data model API, nothing to do with stacker */
- server = hippo_platform_get_web_server(platform, HIPPO_SERVER_DESKTOP);
-
- /* Note, no trailing '/', don't add one here because relative urls are given
- * starting with '/' and so you want to be able to do baseurl + relativeurl
- */
- url = g_strdup_printf("http://%s", server);
-
- dbus_message_iter_append_basic(append_iter, DBUS_TYPE_STRING, &url);
-
- g_free(server);
- g_free(url);
-
- return TRUE;
-}
-
static const HippoDBusMember model_members[] = {
/* Query: Send a query to the server
*
@@ -459,42 +401,22 @@
*/
{ HIPPO_DBUS_MEMBER_METHOD, "Forget", "os", "", handle_forget },
- /* ConnectedChanged: connected status changed (this signal will be replaced
- * eventually by moving self id and the online flag into global resource)
+ /* Ready: Start fetching application data from the data model
*
* Parameters:
- * boolean connected = true/false
- * string selfId
*
*/
- { HIPPO_DBUS_MEMBER_SIGNAL, "ConnectedChanged", "", "bs", NULL },
+ { HIPPO_DBUS_MEMBER_SIGNAL, "Ready", "", "", NULL },
{ 0, NULL }
};
static const HippoDBusProperty model_properties[] = {
- { "Connected", "b", handle_get_connected, NULL },
+ { "Ready", "b", handle_get_ready, NULL },
-
- /* FIXME This is probably broken to have here, since it's just a special
- * case of something that should be in the data model anyway, right?
- */
- { "SelfId", "s", handle_get_self_id, NULL },
-
/* this should return the server we are encoding in the dbus bus name, like foo.bar.org:8080 */
{ "Server", "s", handle_get_server, NULL },
- /* right now this will be the server with http:// in front, but
- * in theory could have https or a path on the host or
- * something. The url should NOT have a trailing '/', though
- * the one returned by the old "org.mugshot.Mugshot" API does.
- */
-
- /* All URLs in the data model have already been made absolute
- * on receipt from the server, so this is just useful if you want to construct
- * an URL like /account. FIXME: Such URL's perhaps should also be in the data model
- */
- { "WebBaseUrl", "s", handle_get_web_base_url, NULL },
{ NULL }
};
@@ -512,8 +434,8 @@
ddm_model = hippo_app_get_data_model(hippo_get_app());
- g_signal_connect(G_OBJECT(ddm_model), "connected-changed", G_CALLBACK(on_connected_changed),
- connection);
+ g_signal_connect(G_OBJECT(ddm_model), "ready",
+ G_CALLBACK(on_ready), connection);
}
static gboolean
@@ -542,65 +464,22 @@
}
static void
-on_connected_changed(DDMDataModel *ddm_model,
- gboolean connected,
- void *data)
+on_ready(DDMDataModel *ddm_model,
+ void *data)
{
DBusConnection *connection = data;
- if (connected) {
- DataClientMap *map = data_client_map_get(ddm_model);
- char *resource_id = get_self_id();
+ DataClientMap *map = data_client_map_get(ddm_model);
- /* Once a client receives ConnectedChanged, it must forget its current
- * state and start over. It would be a little more efficent to just remove
- * all connections and leave the D-BUS disconnection-watches in place,
- * that might be important if we had dozens of clients.
- */
- g_hash_table_remove_all(map->clients);
+ /* Once a client receives Ready, it must forget its current
+ * state and start over. It would be a little more efficent to just remove
+ * all connections and leave the D-BUS disconnection-watches in place,
+ * that might be important if we had dozens of clients.
+ */
+ g_hash_table_remove_all(map->clients);
- hippo_dbus_helper_emit_signal(connection,
- HIPPO_DBUS_MODEL_PATH, HIPPO_DBUS_MODEL_INTERFACE,
- "ConnectedChanged",
- DBUS_TYPE_BOOLEAN, &connected,
- DBUS_TYPE_STRING, &resource_id,
- DBUS_TYPE_INVALID);
-
- g_free(resource_id);
- } else {
- const char *empty_string;
-
- empty_string = "";
-
- /* Including an empty string for the self-id might make you think that being disconnected
- * means that there is no longer a self-id. That's, however, wrong. The self_id is
- * *independent* of the connected state and can be used to fetch things out of the
- * offline cache.
- *
- * In fact, I think the whole existence of a ConnectedChanged signal is possibly a confusing
- * thing. There are two different events:
- *
- * Connected:
- * - The connected boolean is true
- * - All prior notification's you've registered have been removed
- * - All data you might be caching is invalid, dump it
- * - The selfId might have changed
- * - Start fetching your data from scratch with the assumption that everything has changed
- *
- * Disconnected:
- * - The connected boolean is false
- *
- * So while the two events *do* signal changes in the Connected boolean, they otherwise require
- * entirely different handling on the part of the recipient.
- *
- * This also means that even if the connected boolean moved in the global resource, you'd
- * still want the "Connected" signal.
- */
- hippo_dbus_helper_emit_signal(connection,
- HIPPO_DBUS_MODEL_PATH, HIPPO_DBUS_MODEL_INTERFACE,
- "ConnectedChanged",
- DBUS_TYPE_BOOLEAN, &connected,
- DBUS_TYPE_STRING, &empty_string,
- DBUS_TYPE_INVALID);
- }
+ hippo_dbus_helper_emit_signal(connection,
+ HIPPO_DBUS_MODEL_PATH, HIPPO_DBUS_MODEL_INTERFACE,
+ "Ready",
+ DBUS_TYPE_INVALID);
}
Modified: dumbhippo/trunk/client/linux/src/hippo-platform-impl.c
===================================================================
--- dumbhippo/trunk/client/linux/src/hippo-platform-impl.c 2007-11-08 20:33:40 UTC (rev 6880)
+++ dumbhippo/trunk/client/linux/src/hippo-platform-impl.c 2007-11-08 20:39:56 UTC (rev 6881)
@@ -791,6 +791,7 @@
msg = _("Mugshot is not connected - please log in to mugshot.org");
break;
case HIPPO_STATE_CONNECTING:
+ case HIPPO_STATE_REDIRECTING:
case HIPPO_STATE_AUTHENTICATING:
msg = _("Mugshot is trying to connect to mugshot.org");
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]