~jaytaoko/unity/unity.coverflow.fix

« back to all changes in this revision

Viewing changes to plugins/unityshell/src/DebugDBusInterface.cpp

  • Committer: Jay Taoko
  • Date: 2012-06-14 18:07:29 UTC
  • mfrom: (1897.2.513 unity)
  • Revision ID: jay.taoko@canonical.com-20120614180729-mk56rx7i432uteok
Fixing Coverflow

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 */
19
19
 
20
20
#include <queue>
 
21
#include <fstream>
21
22
#include <sstream>
22
23
#include <boost/algorithm/string.hpp>
23
24
#include <boost/algorithm/string/split.hpp>
25
26
#include <boost/bind.hpp>
26
27
#include <core/core.h>
27
28
#include <NuxCore/Logger.h>
 
29
#include <NuxCore/LoggingWriter.h>
28
30
 
29
31
#include "DebugDBusInterface.h"
30
32
#include "Introspectable.h"
38
40
{
39
41
namespace
40
42
{
41
 
  nux::logging::Logger logger("unity.debug.DebugDBusInterface");
 
43
nux::logging::Logger logger("unity.debug.DebugDBusInterface");
 
44
 
 
45
namespace local
 
46
{
 
47
  std::ofstream output_file;
 
48
}
42
49
}
43
50
 
44
51
GVariant* GetState(std::string const& query);
 
52
void StartLogToFile(std::string const& file_path);
 
53
void ResetLogging();
 
54
void SetLogSeverity(std::string const& log_component,
 
55
  std::string const& severity);
 
56
void LogMessage(std::string const& severity,
 
57
  std::string const& message);
45
58
 
46
59
const char* DebugDBusInterface::DBUS_DEBUG_OBJECT_PATH = "/com/canonical/Unity/Debug";
47
60
 
54
67
  "       <arg type='aa{sv}' name='state' direction='out' />"
55
68
  "     </method>"
56
69
  ""
 
70
  "     <method name='StartLogToFile'>"
 
71
  "       <arg type='s' name='file_path' direction='in' />"
 
72
  "     </method>"
 
73
  ""
 
74
  "     <method name='ResetLogging'>"
 
75
  "     </method>"
 
76
  ""
 
77
  "     <method name='SetLogSeverity'>"
 
78
  "       <arg type='s' name='log_component' direction='in' />"
 
79
  "       <arg type='s' name='severity' direction='in' />"
 
80
  "     </method>"
 
81
  ""
 
82
  "     <method name='LogMessage'>"
 
83
  "       <arg type='s' name='severity' direction='in' />"
 
84
  "       <arg type='s' name='message' direction='in' />"
 
85
  "     </method>"
 
86
  ""
57
87
  "   </interface>"
58
88
  " </node>";
59
89
 
64
94
  NULL
65
95
};
66
96
 
67
 
static CompScreen* _screen;
68
97
static Introspectable* _parent_introspectable;
69
98
 
70
 
DebugDBusInterface::DebugDBusInterface(Introspectable* parent, 
71
 
                                       CompScreen* screen)
 
99
DebugDBusInterface::DebugDBusInterface(Introspectable* parent)
72
100
{
73
 
  _screen = screen;
74
101
  _parent_introspectable = parent;
75
102
  _owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
76
103
                             unity::DBUS_BUS_NAME.c_str(),
100
127
    return;
101
128
  }
102
129
 
103
 
  while (introspection_data->interfaces[i] != NULL) 
 
130
  while (introspection_data->interfaces[i] != NULL)
104
131
  {
105
132
    error = NULL;
106
133
    g_dbus_connection_register_object(connection,
147
174
    g_variant_get(parameters, "(&s)", &input);
148
175
 
149
176
    ret = GetState(input);
 
177
    // GetState returns a floating variant and
 
178
    // g_dbus_method_invocation_return_value ref sinks it
150
179
    g_dbus_method_invocation_return_value(invocation, ret);
151
 
    g_variant_unref(ret);
 
180
  }
 
181
  else if (g_strcmp0(method_name, "StartLogToFile") == 0)
 
182
  {
 
183
    const gchar* log_path;
 
184
    g_variant_get(parameters, "(&s)", &log_path);
 
185
 
 
186
    StartLogToFile(log_path);
 
187
    g_dbus_method_invocation_return_value(invocation, NULL);
 
188
  }
 
189
  else if (g_strcmp0(method_name, "ResetLogging") == 0)
 
190
  {
 
191
    ResetLogging();
 
192
    g_dbus_method_invocation_return_value(invocation, NULL);
 
193
  }
 
194
  else if (g_strcmp0(method_name, "SetLogSeverity") == 0)
 
195
  {
 
196
    const gchar* component;
 
197
    const gchar* severity;
 
198
    g_variant_get(parameters, "(&s&s)", &component, &severity);
 
199
 
 
200
    SetLogSeverity(component, severity);
 
201
    g_dbus_method_invocation_return_value(invocation, NULL);
 
202
  }
 
203
  else if (g_strcmp0(method_name, "LogMessage") == 0)
 
204
  {
 
205
    const gchar* severity;
 
206
    const gchar* message;
 
207
    g_variant_get(parameters, "(&s&s)", &severity, &message);
 
208
 
 
209
    LogMessage(severity, message);
 
210
    g_dbus_method_invocation_return_value(invocation, NULL);
152
211
  }
153
212
  else
154
213
  {
155
 
    g_dbus_method_invocation_return_dbus_error(invocation, 
 
214
    g_dbus_method_invocation_return_dbus_error(invocation,
156
215
                                               unity::DBUS_BUS_NAME.c_str(),
157
216
                                               "Failed to find method");
158
217
  }
165
224
  std::list<Introspectable*> parts = GetIntrospectableNodesFromQuery(query, _parent_introspectable);
166
225
  GVariantBuilder  builder;
167
226
  g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
168
 
  
 
227
 
169
228
  for (Introspectable *node : parts)
170
229
  {
171
230
    g_variant_builder_add_value(&builder, node->Introspect());
172
231
  }
173
 
  
 
232
 
174
233
  return g_variant_new("(aa{sv})", &builder);
175
234
}
176
235
 
 
236
void StartLogToFile(std::string const& file_path)
 
237
{
 
238
  if (local::output_file.is_open())
 
239
    local::output_file.close();
 
240
  local::output_file.open(file_path);
 
241
  nux::logging::Writer::Instance().SetOutputStream(local::output_file);
 
242
}
 
243
 
 
244
void ResetLogging()
 
245
{
 
246
  if (local::output_file.is_open())
 
247
    local::output_file.close();
 
248
  nux::logging::Writer::Instance().SetOutputStream(std::cout);
 
249
  nux::logging::reset_logging();
 
250
}
 
251
 
 
252
void SetLogSeverity(std::string const& log_component,
 
253
                    std::string const& severity)
 
254
{
 
255
  nux::logging::Logger(log_component).SetLogLevel(nux::logging::get_logging_level(severity));
 
256
}
 
257
 
 
258
void LogMessage(std::string const& severity,
 
259
                std::string const& message)
 
260
{
 
261
  nux::logging::Level level = nux::logging::get_logging_level(severity);
 
262
  if (logger.GetEffectiveLogLevel() <= level)
 
263
  {
 
264
   nux::logging::LogStream(level, logger.module(), __FILE__, __LINE__).stream()
 
265
      << message;
 
266
  }
 
267
}
 
268
 
177
269
/*
178
 
 * Do a breadth-first search of the introspection tree and find all nodes that match the 
 
270
 * Do a breadth-first search of the introspection tree and find all nodes that match the
179
271
 * query.
180
272
 */
181
273
std::list<Introspectable*> GetIntrospectableNodesFromQuery(std::string const& query, Introspectable* tree_root)
197
289
  {
198
290
    std::list<std::string> query_strings;
199
291
    boost::algorithm::split(query_strings, sanitised_query, boost::algorithm::is_any_of("/"));
200
 
    // Boost's split() implementation does not match it's documentation! According to the 
201
 
    // docs, it's not supposed to add empty strings, but it does, which is a PITA. This 
 
292
    // Boost's split() implementation does not match it's documentation! According to the
 
293
    // docs, it's not supposed to add empty strings, but it does, which is a PITA. This
202
294
    // next line removes them:
203
 
    query_strings.erase( std::remove_if( query_strings.begin(), 
204
 
                                        query_strings.end(), 
205
 
                                        boost::bind( &std::string::empty, _1 ) ), 
 
295
    query_strings.erase( std::remove_if( query_strings.begin(),
 
296
                                        query_strings.end(),
 
297
                                        boost::bind( &std::string::empty, _1 ) ),
206
298
                      query_strings.end());
207
299
    foreach(std::string part, query_strings)
208
300
    {
229
321
    {
230
322
      LOG_WARNING(logger) << "Malformed relative introspection query: '" << query << "'.";
231
323
    }
232
 
    
 
324
 
233
325
    // non-recursive BFS traversal to find starting points:
234
326
    std::queue<Introspectable*> queue;
235
327
    queue.push(tree_root);
254
346
  // now we have the tree start points, process them:
255
347
  query_parts.pop_front();
256
348
  typedef std::pair<Introspectable*, std::list<XPathQueryPart>::iterator> node_match_pair;
257
 
  
 
349
 
258
350
  std::queue<node_match_pair> traverse_queue;
259
351
  foreach(Introspectable *node, start_points)
260
352
  {
261
353
    traverse_queue.push(node_match_pair(node, query_parts.begin()));
262
354
  }
263
355
  start_points.clear();
264
 
  
 
356
 
265
357
  while (!traverse_queue.empty())
266
358
  {
267
359
    node_match_pair p = traverse_queue.front();