]> git.0d.be Git - empathy.git/blob - libempathy/empathy-debugger.c
Updated Basque language
[empathy.git] / libempathy / empathy-debugger.c
1 /*
2  * Telepathy debug interface implementation
3  * Copyright (C) 2009 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include "empathy-debugger.h"
21 #include "config.h"
22
23 #include <telepathy-glib/dbus.h>
24
25 #include "extensions/extensions.h"
26
27 static EmpathyDebugger *singleton = NULL;
28
29 static void
30 debug_iface_init (gpointer g_iface, gpointer iface_data);
31
32 G_DEFINE_TYPE_WITH_CODE (EmpathyDebugger, empathy_debugger, G_TYPE_OBJECT,
33     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
34         tp_dbus_properties_mixin_iface_init);
35     G_IMPLEMENT_INTERFACE (EMP_TYPE_SVC_DEBUG, debug_iface_init));
36
37 /* properties */
38 enum
39 {
40   PROP_ENABLED = 1,
41   NUM_PROPERTIES
42 };
43
44 static EmpDebugLevel
45 log_level_flags_to_debug_level (GLogLevelFlags level)
46 {
47   if (level & G_LOG_LEVEL_ERROR)
48     return EMP_DEBUG_LEVEL_ERROR;
49   else if (level & G_LOG_LEVEL_CRITICAL)
50     return EMP_DEBUG_LEVEL_CRITICAL;
51   else if (level & G_LOG_LEVEL_WARNING)
52     return EMP_DEBUG_LEVEL_WARNING;
53   else if (level & G_LOG_LEVEL_MESSAGE)
54     return EMP_DEBUG_LEVEL_MESSAGE;
55   else if (level & G_LOG_LEVEL_INFO)
56     return EMP_DEBUG_LEVEL_INFO;
57   else if (level & G_LOG_LEVEL_DEBUG)
58     return EMP_DEBUG_LEVEL_DEBUG;
59   else
60     /* Fall back to DEBUG if all else fails */
61     return EMP_DEBUG_LEVEL_DEBUG;
62 }
63
64 static EmpathyDebugMessage *
65 debug_message_new (GTimeVal *timestamp,
66     const gchar *domain,
67     GLogLevelFlags level,
68     const gchar *string)
69 {
70   EmpathyDebugMessage *msg;
71
72   msg = g_slice_new0 (EmpathyDebugMessage);
73   msg->timestamp = timestamp->tv_sec + timestamp->tv_usec / 1e6;
74   msg->domain = g_strdup (domain);
75   msg->level = log_level_flags_to_debug_level (level);
76   msg->string = g_strdup (string);
77   return msg;
78 }
79
80 static void
81 debug_message_free (EmpathyDebugMessage *msg)
82 {
83   g_free (msg->domain);
84   g_free (msg->string);
85   g_slice_free (EmpathyDebugMessage, msg);
86 }
87
88 static void
89 empathy_debugger_get_property (GObject *object,
90     guint property_id,
91     GValue *value,
92     GParamSpec *pspec)
93 {
94   EmpathyDebugger *self = EMPATHY_DEBUGGER (object);
95
96   switch (property_id)
97     {
98       case PROP_ENABLED:
99         g_value_set_boolean (value, self->enabled);
100         break;
101
102       default:
103         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104     }
105 }
106
107 static void
108 empathy_debugger_set_property (GObject *object,
109     guint property_id,
110     const GValue *value,
111     GParamSpec *pspec)
112 {
113   EmpathyDebugger *self = EMPATHY_DEBUGGER (object);
114
115   switch (property_id)
116     {
117       case PROP_ENABLED:
118         self->enabled = g_value_get_boolean (value);
119         break;
120
121      default:
122        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
123   }
124 }
125
126 static void
127 empathy_debugger_finalize (GObject *object)
128 {
129   EmpathyDebugger *self = EMPATHY_DEBUGGER (object);
130
131   g_queue_foreach (self->messages, (GFunc) debug_message_free, NULL);
132   g_queue_free (self->messages);
133   self->messages = NULL;
134
135   G_OBJECT_CLASS (empathy_debugger_parent_class)->finalize (object);
136 }
137
138 static void
139 empathy_debugger_class_init (EmpathyDebuggerClass *klass)
140 {
141   GObjectClass *object_class = G_OBJECT_CLASS (klass);
142   static TpDBusPropertiesMixinPropImpl debug_props[] = {
143       { "Enabled", "enabled", "enabled" },
144       { NULL }
145   };
146   static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
147       { EMP_IFACE_DEBUG,
148         tp_dbus_properties_mixin_getter_gobject_properties,
149         tp_dbus_properties_mixin_setter_gobject_properties,
150         debug_props,
151       },
152       { NULL }
153   };
154
155   object_class->get_property = empathy_debugger_get_property;
156   object_class->set_property = empathy_debugger_set_property;
157   object_class->finalize = empathy_debugger_finalize;
158
159   g_object_class_install_property (object_class, PROP_ENABLED,
160       g_param_spec_boolean ("enabled", "Enabled?",
161           "True if the new-debug-message signal is enabled.",
162           FALSE,
163           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164
165   klass->dbus_props_class.interfaces = prop_interfaces;
166   tp_dbus_properties_mixin_class_init (object_class,
167       G_STRUCT_OFFSET (EmpathyDebuggerClass, dbus_props_class));
168 }
169
170 static void
171 get_messages (EmpSvcDebug *self,
172     DBusGMethodInvocation *context)
173 {
174   EmpathyDebugger *dbg = EMPATHY_DEBUGGER (self);
175   GPtrArray *messages;
176   static GType struct_type = 0;
177   GList *i;
178   guint j;
179
180   if (G_UNLIKELY (struct_type == 0))
181     {
182       struct_type = dbus_g_type_get_struct (
183           "GValueArray", G_TYPE_DOUBLE, G_TYPE_STRING, G_TYPE_UINT,
184           G_TYPE_STRING, G_TYPE_INVALID);
185     }
186
187   messages = g_ptr_array_sized_new (g_queue_get_length (dbg->messages));
188
189   for (i = dbg->messages->head; i; i = i->next)
190     {
191       GValue gvalue = { 0 };
192       EmpathyDebugMessage *message = (EmpathyDebugMessage *) i->data;
193
194       g_value_init (&gvalue, struct_type);
195       g_value_take_boxed (&gvalue,
196           dbus_g_type_specialized_construct (struct_type));
197       dbus_g_type_struct_set (&gvalue,
198           0, message->timestamp,
199           1, message->domain,
200           2, message->level,
201           3, message->string,
202           G_MAXUINT);
203       g_ptr_array_add (messages, g_value_get_boxed (&gvalue));
204     }
205
206   emp_svc_debug_return_from_get_messages (context, messages);
207
208   for (j = 0; j < messages->len; j++)
209     g_boxed_free (struct_type, messages->pdata[j]);
210
211   g_ptr_array_free (messages, TRUE);
212 }
213
214 static void
215 debug_iface_init (gpointer g_iface,
216     gpointer iface_data)
217 {
218   EmpSvcDebugClass *klass = (EmpSvcDebugClass *) g_iface;
219
220   emp_svc_debug_implement_get_messages (klass, get_messages);
221 }
222
223 static void
224 empathy_debugger_init (EmpathyDebugger *self)
225 {
226   self->messages = g_queue_new ();
227 }
228
229 EmpathyDebugger *
230 empathy_debugger_get_singleton (void)
231 {
232   if (G_UNLIKELY (singleton == NULL))
233     {
234       DBusGConnection *bus;
235
236       singleton = g_object_new (EMPATHY_TYPE_DEBUGGER, NULL);
237       bus = tp_get_bus ();
238       dbus_g_connection_register_g_object (bus,
239           "/org/freedesktop/Telepathy/debug", (GObject *) singleton);
240     }
241
242   return singleton;
243 }
244
245 void
246 empathy_debugger_add_message (EmpathyDebugger *self,
247     GTimeVal *timestamp,
248     const gchar *domain,
249     GLogLevelFlags level,
250     const gchar *string)
251 {
252   EmpathyDebugMessage *new_msg;
253
254   if (g_queue_get_length (self->messages) >= DEBUG_MESSAGE_LIMIT)
255     {
256       EmpathyDebugMessage *old_head =
257         (EmpathyDebugMessage *) g_queue_pop_head (self->messages);
258
259       debug_message_free (old_head);
260     }
261
262   new_msg = debug_message_new (timestamp, domain, level, string);
263   g_queue_push_tail (self->messages, new_msg);
264
265   if (self->enabled)
266     {
267       emp_svc_debug_emit_new_debug_message (self, new_msg->timestamp,
268           domain, new_msg->level, string);
269     }
270 }