25
26
#include <boost/bind.hpp>
26
27
#include <core/core.h>
27
28
#include <NuxCore/Logger.h>
29
#include <NuxCore/LoggingWriter.h>
29
31
#include "DebugDBusInterface.h"
30
32
#include "Introspectable.h"
41
nux::logging::Logger logger("unity.debug.DebugDBusInterface");
43
nux::logging::Logger logger("unity.debug.DebugDBusInterface");
47
std::ofstream output_file;
44
51
GVariant* GetState(std::string const& query);
52
void StartLogToFile(std::string const& file_path);
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);
46
59
const char* DebugDBusInterface::DBUS_DEBUG_OBJECT_PATH = "/com/canonical/Unity/Debug";
54
67
" <arg type='aa{sv}' name='state' direction='out' />"
70
" <method name='StartLogToFile'>"
71
" <arg type='s' name='file_path' direction='in' />"
74
" <method name='ResetLogging'>"
77
" <method name='SetLogSeverity'>"
78
" <arg type='s' name='log_component' direction='in' />"
79
" <arg type='s' name='severity' direction='in' />"
82
" <method name='LogMessage'>"
83
" <arg type='s' name='severity' direction='in' />"
84
" <arg type='s' name='message' direction='in' />"
67
static CompScreen* _screen;
68
97
static Introspectable* _parent_introspectable;
70
DebugDBusInterface::DebugDBusInterface(Introspectable* parent,
99
DebugDBusInterface::DebugDBusInterface(Introspectable* parent)
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(),
147
174
g_variant_get(parameters, "(&s)", &input);
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);
181
else if (g_strcmp0(method_name, "StartLogToFile") == 0)
183
const gchar* log_path;
184
g_variant_get(parameters, "(&s)", &log_path);
186
StartLogToFile(log_path);
187
g_dbus_method_invocation_return_value(invocation, NULL);
189
else if (g_strcmp0(method_name, "ResetLogging") == 0)
192
g_dbus_method_invocation_return_value(invocation, NULL);
194
else if (g_strcmp0(method_name, "SetLogSeverity") == 0)
196
const gchar* component;
197
const gchar* severity;
198
g_variant_get(parameters, "(&s&s)", &component, &severity);
200
SetLogSeverity(component, severity);
201
g_dbus_method_invocation_return_value(invocation, NULL);
203
else if (g_strcmp0(method_name, "LogMessage") == 0)
205
const gchar* severity;
206
const gchar* message;
207
g_variant_get(parameters, "(&s&s)", &severity, &message);
209
LogMessage(severity, message);
210
g_dbus_method_invocation_return_value(invocation, NULL);
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");
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}"));
169
228
for (Introspectable *node : parts)
171
230
g_variant_builder_add_value(&builder, node->Introspect());
174
233
return g_variant_new("(aa{sv})", &builder);
236
void StartLogToFile(std::string const& file_path)
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);
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();
252
void SetLogSeverity(std::string const& log_component,
253
std::string const& severity)
255
nux::logging::Logger(log_component).SetLogLevel(nux::logging::get_logging_level(severity));
258
void LogMessage(std::string const& severity,
259
std::string const& message)
261
nux::logging::Level level = nux::logging::get_logging_level(severity);
262
if (logger.GetEffectiveLogLevel() <= level)
264
nux::logging::LogStream(level, logger.module(), __FILE__, __LINE__).stream()
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
181
273
std::list<Introspectable*> GetIntrospectableNodesFromQuery(std::string const& query, Introspectable* tree_root)
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(),
205
boost::bind( &std::string::empty, _1 ) ),
295
query_strings.erase( std::remove_if( query_strings.begin(),
297
boost::bind( &std::string::empty, _1 ) ),
206
298
query_strings.end());
207
299
foreach(std::string part, query_strings)
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;
258
350
std::queue<node_match_pair> traverse_queue;
259
351
foreach(Introspectable *node, start_points)
261
353
traverse_queue.push(node_match_pair(node, query_parts.begin()));
263
355
start_points.clear();
265
357
while (!traverse_queue.empty())
267
359
node_match_pair p = traverse_queue.front();