Merge lp:~charlesk/indicator-location/style into lp:indicator-location/16.04

Proposed by Charles Kerr
Status: Merged
Approved by: Xavi Garcia
Approved revision: 170
Merged at revision: 153
Proposed branch: lp:~charlesk/indicator-location/style
Merge into: lp:indicator-location/16.04
Prerequisite: lp:~charlesk/indicator-location/use-properties-cpp
Diff against target: 3658 lines (+1650/-1442)
23 files modified
CMakeLists.txt (+34/-0)
_clang-format (+48/-0)
astyle-config (+44/-0)
debian/control (+4/-0)
src/controller.h (+9/-12)
src/dbus-shared.h (+14/-17)
src/location-service-controller.cc (+124/-161)
src/location-service-controller.h (+12/-16)
src/main.cc (+33/-35)
src/phone.cc (+226/-265)
src/phone.h (+32/-34)
src/service.cc (+124/-141)
src/service.h (+34/-39)
src/utils.h (+34/-23)
tests/CMakeLists.txt (+3/-0)
tests/controller-mock.h (+36/-21)
tests/gtest-dbus-fixture.h (+100/-109)
tests/gtest-dbus-indicator-fixture.h (+261/-245)
tests/phone-test.cc (+320/-324)
tools/CMakeLists.txt (+1/-0)
tools/format-files.sh (+49/-0)
tools/format-test.sh (+44/-0)
tools/formatcode.in (+64/-0)
To merge this branch: bzr merge lp:~charlesk/indicator-location/style
Reviewer Review Type Date Requested Status
Xavi Garcia Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+283678@code.launchpad.net

Commit message

Style guide code cleanup. No functional changes.

Description of the change

Style guide code cleanup. No functional changes.

 * Copy michi's code-formatting config files, tools and cmake rules from unity-scopes-api
 * Add new test-format.sh script so "make test" fails if new code's style doesn't match
 * Reformat the codebase to fit the style guide

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
169. By Charles Kerr

specify build-dependency's clang-format version

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
170. By Charles Kerr

typo fix in debian/control

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Xavi Garcia (xavi-garcia-mena) wrote :

Very nice branch, thanks for this Charles!.

In scopes-api and other libraries we are following the convention of coding const pointers and references as: Something const * or Something const &.

That's absolutely not a blocker for me... just wondering if we should follow the same convention in other projects or not.

I have no particular preference for any of the options... so approving the MP.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-01-22 20:08:44 +0000
3+++ CMakeLists.txt 2016-01-22 20:08:44 +0000
4@@ -40,6 +40,39 @@
5 include_directories (SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS})
6
7 ##
8+## Code Style
9+##
10+
11+# Code style fixer from unity-scopes-api.
12+#
13+# We put the code through astyle first because it makes some fixes that clang-format
14+# won't do (such as "char *p" -> "char* p"). But astyle messes up other things
15+# (particularly lambdas and assembly-style comments), which clang-format does right.
16+# So, we run clang-format after running astyle, which undoes the damage done by astyle
17+# without reverting desirable astyle fixes.
18+
19+find_program(ASTYLE_COMMAND NAMES astyle)
20+if (NOT ASTYLE_COMMAND)
21+ message(WARNING "Cannot find astyle: formatcode target will not be available")
22+else()
23+ # astyle 2.03 creates DOS line endings, so we need to fix its output
24+ find_program(DOS2UNIX_COMMAND NAMES dos2unix)
25+ if (NOT DOS2UNIX_COMMAND)
26+ message(WARNING "Cannot find dos2unix: formatcode target will not be available")
27+ else()
28+ find_program(CLANG_FORMAT_COMMAND NAMES clang-format-3.6 clang-format-3.5)
29+ if (NOT CLANG_FORMAT_COMMAND)
30+ message(WARNING "Cannot find clang-format >= clang-format-3.5: formatcode target will not be available")
31+ endif()
32+ endif()
33+endif()
34+
35+if (ASTYLE_COMMAND AND DOS2UNIX_COMMAND AND CLANG_FORMAT_COMMAND)
36+ add_custom_target(formatcode
37+ ${PROJECT_SOURCE_DIR}/tools/format-files.sh ${PROJECT_SOURCE_DIR} ${ASTYLE_COMMAND} ${CLANG_FORMAT_COMMAND})
38+endif()
39+
40+##
41 ##
42 ##
43
44@@ -60,6 +93,7 @@
45 add_subdirectory (src)
46 add_subdirectory (data)
47 add_subdirectory (po)
48+add_subdirectory (tools)
49 if (${enable_tests})
50 add_subdirectory (tests)
51 endif ()
52
53=== added file '_clang-format'
54--- _clang-format 1970-01-01 00:00:00 +0000
55+++ _clang-format 2016-01-22 20:08:44 +0000
56@@ -0,0 +1,48 @@
57+---
58+AccessModifierOffset: -4
59+AlignEscapedNewlinesLeft: true
60+AlignTrailingComments: true
61+AllowAllParametersOfDeclarationOnNextLine: true
62+AllowShortFunctionsOnASingleLine: false
63+AllowShortIfStatementsOnASingleLine: false
64+AllowShortLoopsOnASingleLine: false
65+AlwaysBreakBeforeMultilineStrings: true
66+AlwaysBreakTemplateDeclarations: true
67+BinPackParameters: false
68+BreakBeforeBinaryOperators: false
69+BreakBeforeBraces: Allman
70+BreakBeforeTernaryOperators: false
71+BreakConstructorInitializersBeforeComma: true
72+ColumnLimit: 120
73+ConstructorInitializerAllOnOneLineOrOnePerLine: false
74+ConstructorInitializerIndentWidth: 4
75+ContinuationIndentWidth: 4
76+Cpp11BracedListStyle: true
77+DerivePointerBinding: true
78+ExperimentalAutoDetectBinPacking: false
79+IndentCaseLabels: true
80+IndentFunctionDeclarationAfterType: true
81+IndentWidth: 4
82+Language: Cpp
83+MaxEmptyLinesToKeep: 1
84+NamespaceIndentation: None
85+ObjCSpaceBeforeProtocolList: false
86+PenaltyBreakBeforeFirstCallParameter: 1
87+PenaltyBreakComment: 60
88+PenaltyBreakFirstLessLess: 120
89+PenaltyBreakString: 1000
90+PenaltyExcessCharacter: 1000000
91+PenaltyReturnTypeOnItsOwnLine: 200
92+PointerBindsToType: true
93+SpaceBeforeAssignmentOperators: true
94+SpaceBeforeParens: ControlStatements
95+SpaceInEmptyParentheses: false
96+SpacesBeforeTrailingComments: 2
97+SpacesInAngles: false
98+SpacesInCStyleCastParentheses: false
99+SpacesInParentheses: false
100+Standard: Cpp11
101+TabWidth: 8
102+UseTab: Never
103+...
104+
105
106=== added file 'astyle-config'
107--- astyle-config 1970-01-01 00:00:00 +0000
108+++ astyle-config 2016-01-22 20:08:44 +0000
109@@ -0,0 +1,44 @@
110+# Options for formatting code with astyle.
111+#
112+# This helps to make code match the style guide.
113+#
114+# Use like this:
115+#
116+# astyle --options=astyle-config mfile.h myfile.cpp
117+#
118+# Occasionally, astyle does something silly (particularly with lambdas), so it's
119+# still necessary to scan the changes for things that are wrong.
120+# But, for most files, it does a good job.
121+#
122+# Please consider using this before checking code in for review. Code reviews shouldn't
123+# have to deal with layout issues, they are just a distraction. It's better to be able
124+# to focus on semantics in a code review, with style issues out of the way.
125+
126+--formatted
127+--style=allman
128+--min-conditional-indent=2
129+--indent-switches
130+--max-instatement-indent=120
131+--pad-header
132+--align-pointer=type
133+--align-reference=type
134+--add-brackets
135+--convert-tabs
136+--close-templates
137+--max-code-length=120
138+
139+# --pad-oper
140+#
141+# Commented out for now. It changes
142+#
143+# for (int i=0; i<10; ++i)
144+# to
145+# for (int i = 0; i < 10; ++i)
146+#
147+# Unfortunately, it also messes with rvalue references:
148+#
149+# ResourcePtr& operator=(ResourcePtr&& r);
150+#
151+# becomes:
152+#
153+# ResourcePtr& operator=(ResourcePtr && r);
154
155=== modified file 'debian/control'
156--- debian/control 2015-07-15 18:49:08 +0000
157+++ debian/control 2016-01-22 20:08:44 +0000
158@@ -13,6 +13,10 @@
159 liburl-dispatcher1-dev,
160 python,
161 libproperties-cpp-dev,
162+# for code formatting
163+ astyle,
164+ clang-format-3.6,
165+ dos2unix,
166 Standards-Version: 3.9.4
167 Homepage: http://launchpad.net/indicator-location/
168 # If you aren't a member of ~indicator-applet-developers but need to upload
169
170=== modified file 'src/controller.h'
171--- src/controller.h 2016-01-22 20:08:44 +0000
172+++ src/controller.h 2016-01-22 20:08:44 +0000
173@@ -1,5 +1,5 @@
174 /*
175- * Copyright 2013 Canonical Ltd.
176+ * Copyright 2013-2016 Canonical Ltd.
177 *
178 * This program is free software; you can redistribute it and/or modify
179 * it under the terms of the GNU General Public License as published by
180@@ -17,8 +17,7 @@
181 * Charles Kerr <charles.kerr@canonical.com>
182 */
183
184-#ifndef __INDICATOR_LOCATION_CONTROLLER_H__
185-#define __INDICATOR_LOCATION_CONTROLLER_H__
186+#pragma once
187
188 #include <core/property.h>
189
190@@ -29,13 +28,11 @@
191 virtual ~Controller();
192
193 /// True iff we've gotten status info from the location service
194- virtual const core::Property<bool>& is_valid() const =0;
195-
196- virtual const core::Property<bool>& gps_enabled() const =0;
197- virtual const core::Property<bool>& location_service_enabled() const =0;
198-
199- virtual void set_gps_enabled (bool enabled) =0;
200- virtual void set_location_service_enabled (bool enabled) =0;
201+ virtual const core::Property<bool>& is_valid() const = 0;
202+
203+ virtual const core::Property<bool>& gps_enabled() const = 0;
204+ virtual const core::Property<bool>& location_service_enabled() const = 0;
205+
206+ virtual void set_gps_enabled(bool enabled) = 0;
207+ virtual void set_location_service_enabled(bool enabled) = 0;
208 };
209-
210-#endif // __INDICATOR_LOCATION_CONTROLLER_H__
211
212=== modified file 'src/dbus-shared.h'
213--- src/dbus-shared.h 2014-10-03 16:48:12 +0000
214+++ src/dbus-shared.h 2016-01-22 20:08:44 +0000
215@@ -1,26 +1,23 @@
216 /*
217- * Copyright 2014 Canonical Ltd.
218- *
219- * This program is free software: you can redistribute it and/or modify it
220- * under the terms of the GNU General Public License version 3, as published
221- * by the Free Software Foundation.
222- *
223- * This program is distributed in the hope that it will be useful, but
224- * WITHOUT ANY WARRANTY; without even the implied warranties of
225- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
226- * PURPOSE. See the GNU General Public License for more details.
227- *
228- * You should have received a copy of the GNU General Public License along
229- * with this program. If not, see <http://www.gnu.org/licenses/>.
230+ * Copyright 2014-2016 Canonical Ltd.
231+ *
232+ * This program is free software; you can redistribute it and/or modify
233+ * it under the terms of the GNU General Public License as published by
234+ * the Free Software Foundation; version 3.
235+ *
236+ * This program is distributed in the hope that it will be useful,
237+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
238+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
239+ * GNU Lesser General Public License for more details.
240+ *
241+ * You should have received a copy of the GNU Lesser General Public License
242+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
243 *
244 * Authors:
245 * Charles Kerr <charles.kerr@canonical.com>
246 */
247
248-#ifndef DBUS_SHARED_H
249-#define DBUS_SHARED_H
250+#pragma once
251
252 #define INDICATOR_BUS_NAME "com.canonical.indicator.location"
253 #define INDICATOR_OBJECT_PATH "/com/canonical/indicator/location"
254-
255-#endif /* DBUS_SHARED_H */
256
257=== modified file 'src/location-service-controller.cc'
258--- src/location-service-controller.cc 2016-01-22 20:08:44 +0000
259+++ src/location-service-controller.cc 2016-01-22 20:08:44 +0000
260@@ -1,6 +1,5 @@
261-
262 /*
263- * Copyright 2013 Canonical Ltd.
264+ * Copyright 2013-2016 Canonical Ltd.
265 *
266 * This program is free software; you can redistribute it and/or modify
267 * it under the terms of the GNU General Public License as published by
268@@ -30,21 +29,18 @@
269 class LocationServiceController::Impl
270 {
271 public:
272-
273 Impl()
274 {
275- m_cancellable.reset(g_cancellable_new(), [](GCancellable* c) {
276- g_cancellable_cancel(c);
277- g_object_unref(c);
278- });
279+ m_cancellable.reset(g_cancellable_new(), [](GCancellable* c)
280+ {
281+ g_cancellable_cancel(c);
282+ g_object_unref(c);
283+ });
284
285- g_bus_get(G_BUS_TYPE_SYSTEM,
286- m_cancellable.get(),
287- on_system_bus_ready,
288- this);
289+ g_bus_get(G_BUS_TYPE_SYSTEM, m_cancellable.get(), on_system_bus_ready, this);
290 }
291
292- ~Impl() =default;
293+ ~Impl() = default;
294
295 const core::Property<bool>& is_valid() const
296 {
297@@ -72,7 +68,6 @@
298 }
299
300 private:
301-
302 /***
303 **** bus bootstrapping & name watching
304 ***/
305@@ -90,33 +85,30 @@
306
307 self->m_system_bus.reset(system_bus, GObjectDeleter());
308
309- auto name_tag = g_bus_watch_name_on_connection(
310- system_bus,
311- BUS_NAME,
312- G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
313- on_name_appeared,
314- on_name_vanished,
315- gself,
316- nullptr);
317+ auto name_tag = g_bus_watch_name_on_connection(system_bus, BUS_NAME, G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
318+ on_name_appeared, on_name_vanished, gself, nullptr);
319
320 // manage the name_tag's lifespan
321- self->m_name_tag.reset(new guint{name_tag}, [](guint* tag){
322- g_bus_unwatch_name(*tag);
323- delete tag;
324- });
325+ self->m_name_tag.reset(new guint{name_tag}, [](guint* tag)
326+ {
327+ g_bus_unwatch_name(*tag);
328+ delete tag;
329+ });
330 }
331 else if (error != nullptr)
332 {
333 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
334+ {
335 g_warning("Couldn't get system bus: %s", error->message);
336+ }
337 g_error_free(error);
338 }
339 }
340
341- static void on_name_appeared(GDBusConnection * system_bus,
342- const gchar * /*bus_name*/,
343- const gchar * name_owner,
344- gpointer gself)
345+ static void on_name_appeared(GDBusConnection* system_bus,
346+ const gchar* /*bus_name*/,
347+ const gchar* name_owner,
348+ gpointer gself)
349 {
350 auto self = static_cast<Impl*>(gself);
351
352@@ -127,49 +119,33 @@
353
354 // subscribe to PropertiesChanged signals from the service
355 auto signal_tag = g_dbus_connection_signal_subscribe(
356- system_bus,
357- name_owner,
358- PROP_IFACE_NAME,
359- "PropertiesChanged",
360- OBJECT_PATH,
361- nullptr, // arg0
362- G_DBUS_SIGNAL_FLAGS_NONE,
363- on_properties_changed,
364- gself,
365- nullptr);
366+ system_bus, name_owner, PROP_IFACE_NAME, "PropertiesChanged", OBJECT_PATH,
367+ nullptr, // arg0
368+ G_DBUS_SIGNAL_FLAGS_NONE, on_properties_changed, gself, nullptr);
369
370 // manage the signal_tag lifespan
371 g_object_ref(system_bus);
372- self->m_signal_tag.reset(new guint{signal_tag},
373- [system_bus](guint* tag){
374- g_dbus_connection_signal_unsubscribe(system_bus, *tag);
375- g_object_unref(system_bus);
376- delete tag;
377- });
378+ self->m_signal_tag.reset(new guint{signal_tag}, [system_bus](guint* tag)
379+ {
380+ g_dbus_connection_signal_unsubscribe(system_bus, *tag);
381+ g_object_unref(system_bus);
382+ delete tag;
383+ });
384
385 // GetAll is borked so call Get on each property we care about
386- struct {
387- const char * name;
388+ struct
389+ {
390+ const char* name;
391 GAsyncReadyCallback callback;
392- } props[] = {
393- { PROP_KEY_LOC_ENABLED, on_loc_enabled_reply },
394- { PROP_KEY_GPS_ENABLED, on_gps_enabled_reply }
395- };
396+ } props[] = {{PROP_KEY_LOC_ENABLED, on_loc_enabled_reply}, {PROP_KEY_GPS_ENABLED, on_gps_enabled_reply}};
397 for (const auto& prop : props)
398- {
399- g_dbus_connection_call(
400- system_bus,
401- BUS_NAME,
402- OBJECT_PATH,
403- PROP_IFACE_NAME,
404- "Get",
405- g_variant_new("(ss)", LOC_IFACE_NAME, prop.name), // args
406- G_VARIANT_TYPE("(v)"), // return type
407- G_DBUS_CALL_FLAGS_NONE,
408- -1, // use default timeout
409- self->m_cancellable.get(),
410- prop.callback,
411- gself);
412+ {
413+ g_dbus_connection_call(system_bus, BUS_NAME, OBJECT_PATH, PROP_IFACE_NAME, "Get",
414+ g_variant_new("(ss)", LOC_IFACE_NAME, prop.name), // args
415+ G_VARIANT_TYPE("(v)"), // return type
416+ G_DBUS_CALL_FLAGS_NONE,
417+ -1, // use default timeout
418+ self->m_cancellable.get(), prop.callback, gself);
419 }
420
421 g_debug("setting is_valid to true: location-service appeared");
422@@ -189,35 +165,35 @@
423 **** org.freedesktop.dbus.properties.PropertiesChanged handling
424 ***/
425
426- static void on_properties_changed(GDBusConnection * /*connection*/,
427- const gchar * /*sender_name*/,
428- const gchar * /*object_path*/,
429- const gchar * /*interface_name*/,
430- const gchar * /*signal_name*/,
431- GVariant * parameters,
432- gpointer gself)
433+ static void on_properties_changed(GDBusConnection* /*connection*/,
434+ const gchar* /*sender_name*/,
435+ const gchar* /*object_path*/,
436+ const gchar* /*interface_name*/,
437+ const gchar* /*signal_name*/,
438+ GVariant* parameters,
439+ gpointer gself)
440 {
441 auto self = static_cast<Impl*>(gself);
442- const gchar *interface_name;
443- GVariant *changed_properties;
444- const gchar **invalidated_properties;
445+ const gchar* interface_name;
446+ GVariant* changed_properties;
447+ const gchar** invalidated_properties;
448 GVariantIter property_iter;
449- const gchar *key;
450+ const gchar* key;
451 GVariant* val;
452
453- g_variant_get(parameters,
454- "(&s@a{sv}^a&s)",
455- &interface_name,
456- &changed_properties,
457- &invalidated_properties);
458+ g_variant_get(parameters, "(&s@a{sv}^a&s)", &interface_name, &changed_properties, &invalidated_properties);
459
460 g_variant_iter_init(&property_iter, changed_properties);
461 while (g_variant_iter_next(&property_iter, "{&sv}", &key, &val))
462 {
463 if (!g_strcmp0(key, PROP_KEY_LOC_ENABLED))
464+ {
465 self->m_loc_enabled.set(g_variant_get_boolean(val));
466+ }
467 else if (!g_strcmp0(key, PROP_KEY_GPS_ENABLED))
468+ {
469 self->m_gps_enabled.set(g_variant_get_boolean(val));
470+ }
471
472 g_variant_unref(val);
473 }
474@@ -230,20 +206,19 @@
475 **** org.freedesktop.dbus.properties.Get handling
476 ***/
477
478- static std::tuple<bool,bool> get_bool_reply_from_call(GObject * source,
479- GAsyncResult * res)
480+ static std::tuple<bool, bool> get_bool_reply_from_call(GObject* source, GAsyncResult* res)
481 {
482- GError * error;
483- GVariant * v;
484- bool success {false};
485- bool result {false};
486+ GError* error;
487+ GVariant* v;
488+ bool success{false};
489+ bool result{false};
490
491 error = nullptr;
492- GDBusConnection * conn = G_DBUS_CONNECTION(source);
493+ GDBusConnection* conn = G_DBUS_CONNECTION(source);
494 v = g_dbus_connection_call_finish(conn, res, &error);
495 if (v != nullptr)
496 {
497- GVariant* inner {};
498+ GVariant* inner{};
499 g_variant_get(v, "(v)", &inner);
500 success = true;
501 result = g_variant_get_boolean(inner);
502@@ -253,7 +228,9 @@
503 else if (error != nullptr)
504 {
505 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
506+ {
507 g_warning("Error calling dbus method: %s", error->message);
508+ }
509 g_error_free(error);
510 success = false;
511 }
512@@ -261,26 +238,26 @@
513 return std::make_tuple(success, result);
514 }
515
516- static void on_loc_enabled_reply(GObject * source_object,
517- GAsyncResult * res,
518- gpointer gself)
519+ static void on_loc_enabled_reply(GObject* source_object, GAsyncResult* res, gpointer gself)
520 {
521 bool success, value;
522 std::tie(success, value) = get_bool_reply_from_call(source_object, res);
523 g_debug("service loc reply: success %d value %d", int(success), int(value));
524 if (success)
525+ {
526 static_cast<Impl*>(gself)->m_loc_enabled.set(value);
527+ }
528 }
529
530- static void on_gps_enabled_reply(GObject * source_object,
531- GAsyncResult * res,
532- gpointer gself)
533+ static void on_gps_enabled_reply(GObject* source_object, GAsyncResult* res, gpointer gself)
534 {
535 bool success, value;
536 std::tie(success, value) = get_bool_reply_from_call(source_object, res);
537 g_debug("service gps reply: success %d value %d", int(success), int(value));
538 if (success)
539+ {
540 static_cast<Impl*>(gself)->m_gps_enabled.set(value);
541+ }
542 }
543
544 /***
545@@ -291,30 +268,20 @@
546 {
547 g_return_if_fail(m_system_bus);
548
549- auto args = g_variant_new("(ssv)",
550- LOC_IFACE_NAME,
551- property_name,
552- g_variant_new_boolean(b));
553- g_dbus_connection_call(m_system_bus.get(),
554- BUS_NAME,
555- OBJECT_PATH,
556- PROP_IFACE_NAME,
557- "Set", // method name,
558+ auto args = g_variant_new("(ssv)", LOC_IFACE_NAME, property_name, g_variant_new_boolean(b));
559+ g_dbus_connection_call(m_system_bus.get(), BUS_NAME, OBJECT_PATH, PROP_IFACE_NAME,
560+ "Set", // method name,
561 args,
562- nullptr, // reply type
563+ nullptr, // reply type
564 G_DBUS_CALL_FLAGS_NONE,
565- -1, // timeout msec
566- m_cancellable.get(),
567- check_method_call_reply,
568- this);
569+ -1, // timeout msec
570+ m_cancellable.get(), check_method_call_reply, this);
571 }
572
573- static void check_method_call_reply(GObject *connection,
574- GAsyncResult *res,
575- gpointer /*gself*/)
576+ static void check_method_call_reply(GObject* connection, GAsyncResult* res, gpointer /*gself*/)
577 {
578- GError * error;
579- GVariant * v;
580+ GError* error;
581+ GVariant* v;
582
583 error = nullptr;
584 v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(connection), res, &error);
585@@ -328,7 +295,9 @@
586 else if (error != nullptr)
587 {
588 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
589+ {
590 g_warning("dbus method returned an error : %s", error->message);
591+ }
592
593 g_error_free(error);
594 }
595@@ -338,29 +307,29 @@
596 ****
597 ***/
598
599- static constexpr const char* BUS_NAME {"com.ubuntu.location.Service"};
600- static constexpr const char* OBJECT_PATH {"/com/ubuntu/location/Service"};
601- static constexpr const char* LOC_IFACE_NAME {"com.ubuntu.location.Service"};
602- static constexpr const char* PROP_IFACE_NAME {"org.freedesktop.DBus.Properties"};
603- static constexpr const char* PROP_KEY_LOC_ENABLED {"IsOnline"};
604- static constexpr const char* PROP_KEY_GPS_ENABLED {"DoesSatelliteBasedPositioning"};
605-
606- core::Property<bool> m_gps_enabled {false};
607- core::Property<bool> m_loc_enabled {false};
608- core::Property<bool> m_is_valid {false};
609-
610- std::shared_ptr<GCancellable> m_cancellable {};
611- std::shared_ptr<GDBusConnection> m_system_bus {};
612- std::shared_ptr<guint> m_name_tag {};
613- std::shared_ptr<guint> m_signal_tag {};
614+ static constexpr const char* BUS_NAME{"com.ubuntu.location.Service"};
615+ static constexpr const char* OBJECT_PATH{"/com/ubuntu/location/Service"};
616+ static constexpr const char* LOC_IFACE_NAME{"com.ubuntu.location.Service"};
617+ static constexpr const char* PROP_IFACE_NAME{"org.freedesktop.DBus.Properties"};
618+ static constexpr const char* PROP_KEY_LOC_ENABLED{"IsOnline"};
619+ static constexpr const char* PROP_KEY_GPS_ENABLED{"DoesSatelliteBasedPositioning"};
620+
621+ core::Property<bool> m_gps_enabled{false};
622+ core::Property<bool> m_loc_enabled{false};
623+ core::Property<bool> m_is_valid{false};
624+
625+ std::shared_ptr<GCancellable> m_cancellable{};
626+ std::shared_ptr<GDBusConnection> m_system_bus{};
627+ std::shared_ptr<guint> m_name_tag{};
628+ std::shared_ptr<guint> m_signal_tag{};
629 };
630
631 /***
632 ****
633 ***/
634
635-LocationServiceController::LocationServiceController():
636- impl{new Impl{}}
637+LocationServiceController::LocationServiceController()
638+ : impl{new Impl{}}
639 {
640 }
641
642@@ -368,33 +337,27 @@
643 {
644 }
645
646-const core::Property<bool>&
647-LocationServiceController::is_valid() const
648-{
649- return impl->is_valid();
650-}
651-
652-const core::Property<bool>&
653-LocationServiceController::gps_enabled() const
654-{
655- return impl->gps_enabled();
656-}
657-
658-const core::Property<bool>&
659-LocationServiceController::location_service_enabled() const
660-{
661- return impl->location_service_enabled();
662-}
663-
664-void
665-LocationServiceController::set_gps_enabled(bool enabled)
666-{
667- impl->set_gps_enabled(enabled);
668-}
669-
670-void
671-LocationServiceController::set_location_service_enabled(bool enabled)
672-{
673- impl->set_location_service_enabled(enabled);
674-}
675-
676+const core::Property<bool>& LocationServiceController::is_valid() const
677+{
678+ return impl->is_valid();
679+}
680+
681+const core::Property<bool>& LocationServiceController::gps_enabled() const
682+{
683+ return impl->gps_enabled();
684+}
685+
686+const core::Property<bool>& LocationServiceController::location_service_enabled() const
687+{
688+ return impl->location_service_enabled();
689+}
690+
691+void LocationServiceController::set_gps_enabled(bool enabled)
692+{
693+ impl->set_gps_enabled(enabled);
694+}
695+
696+void LocationServiceController::set_location_service_enabled(bool enabled)
697+{
698+ impl->set_location_service_enabled(enabled);
699+}
700
701=== modified file 'src/location-service-controller.h'
702--- src/location-service-controller.h 2016-01-22 20:08:44 +0000
703+++ src/location-service-controller.h 2016-01-22 20:08:44 +0000
704@@ -1,5 +1,5 @@
705 /*
706- * Copyright 2013 Canonical Ltd.
707+ * Copyright 2013-2016 Canonical Ltd.
708 *
709 * This program is free software; you can redistribute it and/or modify
710 * it under the terms of the GNU General Public License as published by
711@@ -17,14 +17,13 @@
712 * Charles Kerr <charles.kerr@canonical.com>
713 */
714
715-#ifndef INDICATOR_LOCATION_CONTROLLER_LOCATION_SERVICE
716-#define INDICATOR_LOCATION_CONTROLLER_LOCATION_SERVICE
717-
718-#include "controller.h" // parent class
719-
720-#include <memory> // std::unique_ptr
721-
722-class LocationServiceController: public Controller
723+#pragma once
724+
725+#include "controller.h" // parent class
726+
727+#include <memory> // std::unique_ptr
728+
729+class LocationServiceController : public Controller
730 {
731 public:
732 LocationServiceController();
733@@ -33,17 +32,14 @@
734 const core::Property<bool>& is_valid() const override;
735 const core::Property<bool>& gps_enabled() const override;
736 const core::Property<bool>& location_service_enabled() const override;
737- void set_gps_enabled (bool enabled) override;
738- void set_location_service_enabled (bool enabled) override;
739+ void set_gps_enabled(bool enabled) override;
740+ void set_location_service_enabled(bool enabled) override;
741
742- LocationServiceController(const LocationServiceController&) =delete;
743- LocationServiceController& operator=(const LocationServiceController&) =delete;
744+ LocationServiceController(const LocationServiceController&) = delete;
745+ LocationServiceController& operator=(const LocationServiceController&) = delete;
746
747 private:
748 friend class Impl;
749 class Impl;
750 std::unique_ptr<Impl> impl;
751 };
752-
753-#endif // INDICATOR_LOCATION_CONTROLLER_LOCATION_SERVICE
754-
755
756=== modified file 'src/main.cc'
757--- src/main.cc 2016-01-22 20:08:44 +0000
758+++ src/main.cc 2016-01-22 20:08:44 +0000
759@@ -1,20 +1,20 @@
760 /*
761- * Copyright 2013 Canonical Ltd.
762+ * Copyright 2013-2016 Canonical Ltd.
763+ *
764+ * This program is free software; you can redistribute it and/or modify
765+ * it under the terms of the GNU General Public License as published by
766+ * the Free Software Foundation; version 3.
767+ *
768+ * This program is distributed in the hope that it will be useful,
769+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
770+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
771+ * GNU Lesser General Public License for more details.
772+ *
773+ * You should have received a copy of the GNU Lesser General Public License
774+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
775 *
776 * Authors:
777 * Charles Kerr <charles.kerr@canonical.com>
778- *
779- * This program is free software: you can redistribute it and/or modify it
780- * under the terms of the GNU General Public License version 3, as published
781- * by the Free Software Foundation.
782- *
783- * This program is distributed in the hope that it will be useful, but
784- * WITHOUT ANY WARRANTY; without even the implied warranties of
785- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
786- * PURPOSE. See the GNU General Public License for more details.
787- *
788- * You should have received a copy of the GNU General Public License along
789- * with this program. If not, see <http://www.gnu.org/licenses/>.
790 */
791
792 #include <locale.h>
793@@ -24,30 +24,28 @@
794 #include "location-service-controller.h"
795 #include "service.h"
796
797-static void
798-on_name_lost (Service * service G_GNUC_UNUSED, gpointer loop)
799+static void on_name_lost(Service* service G_GNUC_UNUSED, gpointer loop)
800 {
801- g_main_loop_quit (static_cast<GMainLoop*>(loop));
802+ g_main_loop_quit(static_cast<GMainLoop*>(loop));
803 }
804
805-int
806-main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED)
807+int main(int argc G_GNUC_UNUSED, char** argv G_GNUC_UNUSED)
808 {
809- GMainLoop * loop;
810-
811- /* boilerplate i18n */
812- setlocale (LC_ALL, "");
813- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
814- textdomain (GETTEXT_PACKAGE);
815-
816- /* set up the service */
817- loop = g_main_loop_new (nullptr, false);
818- auto controller = std::make_shared<LocationServiceController>();
819- Service service (controller);
820- service.set_name_lost_callback (on_name_lost, loop);
821- g_main_loop_run (loop);
822-
823- /* cleanup */
824- g_main_loop_unref (loop);
825- return 0;
826+ GMainLoop* loop;
827+
828+ /* boilerplate i18n */
829+ setlocale(LC_ALL, "");
830+ bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR);
831+ textdomain(GETTEXT_PACKAGE);
832+
833+ /* set up the service */
834+ loop = g_main_loop_new(nullptr, false);
835+ auto controller = std::make_shared<LocationServiceController>();
836+ Service service(controller);
837+ service.set_name_lost_callback(on_name_lost, loop);
838+ g_main_loop_run(loop);
839+
840+ /* cleanup */
841+ g_main_loop_unref(loop);
842+ return 0;
843 }
844
845=== modified file 'src/phone.cc'
846--- src/phone.cc 2016-01-22 20:08:44 +0000
847+++ src/phone.cc 2016-01-22 20:08:44 +0000
848@@ -1,5 +1,5 @@
849 /*
850- * Copyright 2013 Canonical Ltd.
851+ * Copyright 2013-2016 Canonical Ltd.
852 *
853 * This program is free software; you can redistribute it and/or modify
854 * it under the terms of the GNU General Public License as published by
855@@ -25,216 +25,187 @@
856 #include <ubuntu-app-launch.h>
857
858 #include "phone.h"
859-#include "utils.h" // GObjectDeleter
860+#include "utils.h" // GObjectDeleter
861
862 #define PROFILE_NAME "phone"
863
864 #define LOCATION_ACTION_KEY "location-detection-enabled"
865 #define GPS_ACTION_KEY "gps-detection-enabled"
866
867-Phone :: Phone (const std::shared_ptr<Controller>& controller_,
868- const std::shared_ptr<GSimpleActionGroup>& action_group_):
869- controller (controller_),
870- action_group (action_group_)
871+Phone::Phone(const std::shared_ptr<Controller>& controller_, const std::shared_ptr<GSimpleActionGroup>& action_group_)
872+ : controller(controller_)
873+ , action_group(action_group_)
874 {
875- create_menu ();
876-
877- auto on_gps = [this](bool enabled){
878- update_gps_enabled_action();
879- update_header();
880- };
881- controller_connections.push_back(
882- controller->gps_enabled().changed().connect(on_gps)
883- );
884-
885- auto on_loc = [this](bool enabled){
886- update_detection_enabled_action();
887- update_header();
888- };
889- controller_connections.push_back(
890- controller->location_service_enabled().changed().connect(on_loc)
891- );
892-
893- auto on_valid = [this](bool valid){
894+ create_menu();
895+
896+ auto on_gps = [this](bool enabled)
897+ {
898+ update_gps_enabled_action();
899+ update_header();
900+ };
901+ controller_connections.push_back(controller->gps_enabled().changed().connect(on_gps));
902+
903+ auto on_loc = [this](bool enabled)
904+ {
905+ update_detection_enabled_action();
906+ update_header();
907+ };
908+ controller_connections.push_back(controller->location_service_enabled().changed().connect(on_loc));
909+
910+ auto on_valid = [this](bool valid)
911+ {
912+ update_actions_enabled();
913+ };
914+ controller_connections.push_back(controller->is_valid().changed().connect(on_valid));
915+
916+ /* create the actions & add them to the group */
917+ std::array<GSimpleAction*, 4> actions = {
918+ create_root_action(), create_detection_enabled_action(), create_gps_enabled_action(), create_settings_action()};
919+ for (auto a : actions)
920+ {
921+ g_action_map_add_action(G_ACTION_MAP(action_group.get()), G_ACTION(a));
922+ g_object_unref(a);
923+ }
924+
925 update_actions_enabled();
926- };
927- controller_connections.push_back(
928- controller->is_valid().changed().connect(on_valid)
929- );
930-
931- /* create the actions & add them to the group */
932- std::array<GSimpleAction*, 4> actions = { create_root_action(),
933- create_detection_enabled_action(),
934- create_gps_enabled_action(),
935- create_settings_action() };
936- for (auto a : actions)
937- {
938- g_action_map_add_action (G_ACTION_MAP(action_group.get()), G_ACTION(a));
939- g_object_unref (a);
940- }
941-
942- update_actions_enabled();
943-}
944-
945-Phone :: ~Phone ()
946-{
947-}
948-
949-/***
950-****
951-***/
952-
953-bool
954-Phone :: should_be_visible () const
955-{
956- if (!controller->is_valid())
957- return false;
958-
959- // as per "Indicators - RTM Usability Fix" document:
960- // visible iff location is enabled
961- return controller->location_service_enabled().get();
962-}
963-
964-GVariant *
965-Phone :: action_state_for_root () const
966-{
967- GVariantBuilder builder;
968- g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
969-
970- const char * a11y = _("Location");
971- g_variant_builder_add (&builder, "{sv}", "accessible-desc", g_variant_new_string (a11y));
972-
973- const char * title = _("Location");
974- g_variant_builder_add (&builder, "{sv}", "title", g_variant_new_string (title));
975-
976- gboolean visible = should_be_visible ();
977- g_variant_builder_add (&builder, "{sv}", "visible", g_variant_new_boolean (visible));
978-
979- const char * icon_name = "gps";
980- GIcon * icon = g_themed_icon_new_with_default_fallbacks (icon_name);
981- GVariant * serialized_icon = g_icon_serialize (icon);
982- if (serialized_icon != NULL)
983- {
984- g_variant_builder_add (&builder, "{sv}", "icon", serialized_icon);
985- g_variant_unref (serialized_icon);
986- }
987- g_object_unref (icon);
988-
989- return g_variant_builder_end (&builder);
990-}
991-
992-#define HEADER_ACTION_KEY PROFILE_NAME"-header"
993-
994-GSimpleAction *
995-Phone :: create_root_action ()
996-{
997- return g_simple_action_new_stateful (HEADER_ACTION_KEY,
998- nullptr,
999- action_state_for_root ());
1000-}
1001-
1002-void
1003-Phone::update_header()
1004-{
1005- g_action_group_change_action_state(G_ACTION_GROUP(action_group.get()),
1006- HEADER_ACTION_KEY,
1007- action_state_for_root());
1008-}
1009-
1010-void
1011-Phone :: update_actions_enabled()
1012-{
1013- const auto map = G_ACTION_MAP(action_group.get());
1014- const bool is_valid = controller->is_valid().get();
1015- std::array<const char*,2> keys = { LOCATION_ACTION_KEY, GPS_ACTION_KEY };
1016- for(const auto& key : keys)
1017- g_simple_action_set_enabled(G_SIMPLE_ACTION(g_action_map_lookup_action(map, key)), is_valid);
1018-
1019- update_header();
1020-}
1021-
1022-/***
1023-****
1024-***/
1025-
1026-GVariant *
1027-Phone :: action_state_for_location_detection ()
1028-{
1029- return g_variant_new_boolean (controller->location_service_enabled().get());
1030-}
1031-
1032-void
1033-Phone :: on_detection_location_activated (GSimpleAction * action,
1034- GVariant * parameter G_GNUC_UNUSED,
1035- gpointer gself)
1036-{
1037- GVariant * state = g_action_get_state (G_ACTION (action));
1038- static_cast<Phone*>(gself)->controller->set_location_service_enabled (!g_variant_get_boolean (state));
1039- g_variant_unref (state);
1040-}
1041-
1042-GSimpleAction *
1043-Phone :: create_detection_enabled_action ()
1044-{
1045- GSimpleAction * action;
1046-
1047- action = g_simple_action_new_stateful (LOCATION_ACTION_KEY,
1048- nullptr,
1049- action_state_for_location_detection());
1050-
1051- g_signal_connect (action, "activate",
1052- G_CALLBACK(on_detection_location_activated), this);
1053-
1054- return action;
1055-}
1056-
1057-void
1058-Phone::update_detection_enabled_action()
1059-{
1060- GAction * action = g_action_map_lookup_action (G_ACTION_MAP(action_group.get()), LOCATION_ACTION_KEY);
1061- g_simple_action_set_state (G_SIMPLE_ACTION(action), action_state_for_location_detection());
1062-}
1063-
1064-/***
1065-****
1066-***/
1067-
1068-GVariant *
1069-Phone :: action_state_for_gps_detection ()
1070-{
1071- return g_variant_new_boolean (controller->gps_enabled().get());
1072-}
1073-
1074-void
1075-Phone :: on_detection_gps_activated (GSimpleAction * action,
1076- GVariant * parameter G_GNUC_UNUSED,
1077- gpointer gself)
1078-{
1079- GVariant * state = g_action_get_state (G_ACTION (action));
1080- static_cast<Phone*>(gself)->controller->set_gps_enabled (!g_variant_get_boolean (state));
1081- g_variant_unref (state);
1082-}
1083-
1084-GSimpleAction *
1085-Phone :: create_gps_enabled_action()
1086-{
1087- GSimpleAction * action;
1088-
1089- action = g_simple_action_new_stateful (GPS_ACTION_KEY,
1090- nullptr,
1091- action_state_for_gps_detection());
1092-
1093- g_signal_connect (action, "activate",
1094- G_CALLBACK(on_detection_gps_activated), this);
1095-
1096- return action;
1097-}
1098-
1099-void
1100-Phone::update_gps_enabled_action()
1101-{
1102- GAction * action = g_action_map_lookup_action (G_ACTION_MAP(action_group.get()), GPS_ACTION_KEY);
1103- g_simple_action_set_state (G_SIMPLE_ACTION(action), action_state_for_gps_detection());
1104+}
1105+
1106+Phone::~Phone()
1107+{
1108+}
1109+
1110+/***
1111+****
1112+***/
1113+
1114+bool Phone::should_be_visible() const
1115+{
1116+ if (!controller->is_valid())
1117+ {
1118+ return false;
1119+ }
1120+
1121+ // as per "Indicators - RTM Usability Fix" document:
1122+ // visible iff location is enabled
1123+ return controller->location_service_enabled().get();
1124+}
1125+
1126+GVariant* Phone::action_state_for_root() const
1127+{
1128+ GVariantBuilder builder;
1129+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
1130+
1131+ const char* a11y = _("Location");
1132+ g_variant_builder_add(&builder, "{sv}", "accessible-desc", g_variant_new_string(a11y));
1133+
1134+ const char* title = _("Location");
1135+ g_variant_builder_add(&builder, "{sv}", "title", g_variant_new_string(title));
1136+
1137+ gboolean visible = should_be_visible();
1138+ g_variant_builder_add(&builder, "{sv}", "visible", g_variant_new_boolean(visible));
1139+
1140+ const char* icon_name = "gps";
1141+ GIcon* icon = g_themed_icon_new_with_default_fallbacks(icon_name);
1142+ GVariant* serialized_icon = g_icon_serialize(icon);
1143+ if (serialized_icon != NULL)
1144+ {
1145+ g_variant_builder_add(&builder, "{sv}", "icon", serialized_icon);
1146+ g_variant_unref(serialized_icon);
1147+ }
1148+ g_object_unref(icon);
1149+
1150+ return g_variant_builder_end(&builder);
1151+}
1152+
1153+#define HEADER_ACTION_KEY PROFILE_NAME "-header"
1154+
1155+GSimpleAction* Phone::create_root_action()
1156+{
1157+ return g_simple_action_new_stateful(HEADER_ACTION_KEY, nullptr, action_state_for_root());
1158+}
1159+
1160+void Phone::update_header()
1161+{
1162+ g_action_group_change_action_state(G_ACTION_GROUP(action_group.get()), HEADER_ACTION_KEY, action_state_for_root());
1163+}
1164+
1165+void Phone::update_actions_enabled()
1166+{
1167+ const auto map = G_ACTION_MAP(action_group.get());
1168+ const bool is_valid = controller->is_valid().get();
1169+ std::array<const char*, 2> keys = {LOCATION_ACTION_KEY, GPS_ACTION_KEY};
1170+ for (const auto& key : keys)
1171+ {
1172+ g_simple_action_set_enabled(G_SIMPLE_ACTION(g_action_map_lookup_action(map, key)), is_valid);
1173+ }
1174+
1175+ update_header();
1176+}
1177+
1178+/***
1179+****
1180+***/
1181+
1182+GVariant* Phone::action_state_for_location_detection()
1183+{
1184+ return g_variant_new_boolean(controller->location_service_enabled().get());
1185+}
1186+
1187+void Phone::on_detection_location_activated(GSimpleAction* action, GVariant* parameter G_GNUC_UNUSED, gpointer gself)
1188+{
1189+ GVariant* state = g_action_get_state(G_ACTION(action));
1190+ static_cast<Phone*>(gself)->controller->set_location_service_enabled(!g_variant_get_boolean(state));
1191+ g_variant_unref(state);
1192+}
1193+
1194+GSimpleAction* Phone::create_detection_enabled_action()
1195+{
1196+ GSimpleAction* action;
1197+
1198+ action = g_simple_action_new_stateful(LOCATION_ACTION_KEY, nullptr, action_state_for_location_detection());
1199+
1200+ g_signal_connect(action, "activate", G_CALLBACK(on_detection_location_activated), this);
1201+
1202+ return action;
1203+}
1204+
1205+void Phone::update_detection_enabled_action()
1206+{
1207+ GAction* action = g_action_map_lookup_action(G_ACTION_MAP(action_group.get()), LOCATION_ACTION_KEY);
1208+ g_simple_action_set_state(G_SIMPLE_ACTION(action), action_state_for_location_detection());
1209+}
1210+
1211+/***
1212+****
1213+***/
1214+
1215+GVariant* Phone::action_state_for_gps_detection()
1216+{
1217+ return g_variant_new_boolean(controller->gps_enabled().get());
1218+}
1219+
1220+void Phone::on_detection_gps_activated(GSimpleAction* action, GVariant* parameter G_GNUC_UNUSED, gpointer gself)
1221+{
1222+ GVariant* state = g_action_get_state(G_ACTION(action));
1223+ static_cast<Phone*>(gself)->controller->set_gps_enabled(!g_variant_get_boolean(state));
1224+ g_variant_unref(state);
1225+}
1226+
1227+GSimpleAction* Phone::create_gps_enabled_action()
1228+{
1229+ GSimpleAction* action;
1230+
1231+ action = g_simple_action_new_stateful(GPS_ACTION_KEY, nullptr, action_state_for_gps_detection());
1232+
1233+ g_signal_connect(action, "activate", G_CALLBACK(on_detection_gps_activated), this);
1234+
1235+ return action;
1236+}
1237+
1238+void Phone::update_gps_enabled_action()
1239+{
1240+ GAction* action = g_action_map_lookup_action(G_ACTION_MAP(action_group.get()), GPS_ACTION_KEY);
1241+ g_simple_action_set_state(G_SIMPLE_ACTION(action), action_state_for_gps_detection());
1242 }
1243
1244 /***
1245@@ -245,77 +216,67 @@
1246
1247 namespace
1248 {
1249- void
1250- on_uri_dispatched (const gchar * uri,
1251- gboolean success,
1252- gpointer user_data G_GNUC_UNUSED)
1253- {
1254+void on_uri_dispatched(const gchar* uri, gboolean success, gpointer user_data G_GNUC_UNUSED)
1255+{
1256 if (!success)
1257- g_warning ("Unable to activate '%s'", uri);
1258- }
1259-
1260- void
1261- on_settings_activated (GSimpleAction * simple G_GNUC_UNUSED,
1262- GVariant * parameter,
1263- gpointer user_data G_GNUC_UNUSED)
1264- {
1265- const char * key = g_variant_get_string (parameter, nullptr);
1266- gchar * uri = g_strdup_printf ("settings:///system/%s", key);
1267- url_dispatch_send (uri, on_uri_dispatched, nullptr);
1268- g_free (uri);
1269- }
1270-}
1271-
1272-GSimpleAction *
1273-Phone :: create_settings_action ()
1274-{
1275- GSimpleAction * action;
1276-
1277- action = g_simple_action_new (SETTINGS_ACTION_KEY, G_VARIANT_TYPE_STRING);
1278-
1279- g_signal_connect (action, "activate",
1280- G_CALLBACK(on_settings_activated), nullptr);
1281-
1282- return action;
1283+ {
1284+ g_warning("Unable to activate '%s'", uri);
1285+ }
1286+}
1287+
1288+void on_settings_activated(GSimpleAction* simple G_GNUC_UNUSED, GVariant* parameter, gpointer user_data G_GNUC_UNUSED)
1289+{
1290+ const char* key = g_variant_get_string(parameter, nullptr);
1291+ gchar* uri = g_strdup_printf("settings:///system/%s", key);
1292+ url_dispatch_send(uri, on_uri_dispatched, nullptr);
1293+ g_free(uri);
1294+}
1295+}
1296+
1297+GSimpleAction* Phone::create_settings_action()
1298+{
1299+ GSimpleAction* action;
1300+
1301+ action = g_simple_action_new(SETTINGS_ACTION_KEY, G_VARIANT_TYPE_STRING);
1302+
1303+ g_signal_connect(action, "activate", G_CALLBACK(on_settings_activated), nullptr);
1304+
1305+ return action;
1306 }
1307
1308 /***
1309 ****
1310 ***/
1311
1312-void
1313-Phone :: create_menu ()
1314+void Phone::create_menu()
1315 {
1316- GMenuItem * header;
1317-
1318- /* create the submenu */
1319- submenu.reset(g_menu_new (), GObjectDeleter());
1320-
1321- /* populate the submenu */
1322- rebuild_submenu();
1323-
1324- /* add the submenu to a new header */
1325- header = g_menu_item_new (nullptr, "indicator." HEADER_ACTION_KEY);
1326- g_menu_item_set_attribute (header, "x-canonical-type", "s", "com.canonical.indicator.root");
1327- g_menu_item_set_submenu (header, G_MENU_MODEL (submenu.get()));
1328-
1329- /* add the header to a new menu */
1330- menu.reset(g_menu_new (), GObjectDeleter());
1331- g_menu_append_item (menu.get(), header);
1332- g_object_unref (header);
1333+ GMenuItem* header;
1334+
1335+ /* create the submenu */
1336+ submenu.reset(g_menu_new(), GObjectDeleter());
1337+
1338+ /* populate the submenu */
1339+ rebuild_submenu();
1340+
1341+ /* add the submenu to a new header */
1342+ header = g_menu_item_new(nullptr, "indicator." HEADER_ACTION_KEY);
1343+ g_menu_item_set_attribute(header, "x-canonical-type", "s", "com.canonical.indicator.root");
1344+ g_menu_item_set_submenu(header, G_MENU_MODEL(submenu.get()));
1345+
1346+ /* add the header to a new menu */
1347+ menu.reset(g_menu_new(), GObjectDeleter());
1348+ g_menu_append_item(menu.get(), header);
1349+ g_object_unref(header);
1350 }
1351
1352-void
1353-Phone::rebuild_submenu()
1354+void Phone::rebuild_submenu()
1355 {
1356- g_menu_remove_all(submenu.get());
1357-
1358- GMenuItem * location = g_menu_item_new(_("Location detection"),
1359- "indicator." LOCATION_ACTION_KEY);
1360- g_menu_item_set_attribute(location, "x-canonical-type", "s",
1361- "com.canonical.indicator.switch");
1362- g_menu_append_item(submenu.get(), location);
1363- g_object_unref(location);
1364-
1365- g_menu_append (submenu.get(), _("Location settings…"), "indicator." SETTINGS_ACTION_KEY "::security-privacy");
1366+ g_menu_remove_all(submenu.get());
1367+
1368+ GMenuItem* location = g_menu_item_new(_("Location detection"), "indicator." LOCATION_ACTION_KEY);
1369+ g_menu_item_set_attribute(location, "x-canonical-type", "s", "com.canonical.indicator.switch");
1370+ g_menu_append_item(submenu.get(), location);
1371+ g_object_unref(location);
1372+
1373+ g_menu_append(submenu.get(), _("Location settings…"), "indicator." SETTINGS_ACTION_KEY "::security-privacy");
1374 }
1375
1376=== modified file 'src/phone.h'
1377--- src/phone.h 2016-01-22 20:08:44 +0000
1378+++ src/phone.h 2016-01-22 20:08:44 +0000
1379@@ -1,5 +1,5 @@
1380 /*
1381- * Copyright 2013 Canonical Ltd.
1382+ * Copyright 2013-2016 Canonical Ltd.
1383 *
1384 * This program is free software; you can redistribute it and/or modify
1385 * it under the terms of the GNU General Public License as published by
1386@@ -17,8 +17,7 @@
1387 * Charles Kerr <charles.kerr@canonical.com>
1388 */
1389
1390-#ifndef __INDICATOR_LOCATION_PHONE_H__
1391-#define __INDICATOR_LOCATION_PHONE_H__
1392+#pragma once
1393
1394 #include <memory>
1395 #include <vector>
1396@@ -30,50 +29,49 @@
1397
1398 class Phone
1399 {
1400- public:
1401- Phone (const std::shared_ptr<Controller>& controller,
1402- const std::shared_ptr<GSimpleActionGroup>& action_group);
1403- virtual ~Phone ();
1404- std::shared_ptr<GMenu> get_menu () { return menu; }
1405+public:
1406+ Phone(const std::shared_ptr<Controller>& controller, const std::shared_ptr<GSimpleActionGroup>& action_group);
1407+ virtual ~Phone();
1408+ std::shared_ptr<GMenu> get_menu()
1409+ {
1410+ return menu;
1411+ }
1412
1413- protected:
1414+protected:
1415 std::shared_ptr<Controller> controller;
1416 std::vector<core::ScopedConnection> controller_connections;
1417
1418- private:
1419+private:
1420 std::shared_ptr<GMenu> menu;
1421 std::shared_ptr<GMenu> submenu;
1422 std::shared_ptr<GSimpleActionGroup> action_group;
1423
1424- private:
1425- void create_menu ();
1426+private:
1427+ void create_menu();
1428 void rebuild_submenu();
1429
1430- private:
1431- bool should_be_visible () const;
1432- GVariant * action_state_for_root () const;
1433- GSimpleAction * create_root_action ();
1434+private:
1435+ bool should_be_visible() const;
1436+ GVariant* action_state_for_root() const;
1437+ GSimpleAction* create_root_action();
1438 void update_header();
1439 void update_actions_enabled();
1440
1441- private:
1442- GVariant * action_state_for_location_detection ();
1443- GSimpleAction * create_detection_enabled_action ();
1444+private:
1445+ GVariant* action_state_for_location_detection();
1446+ GSimpleAction* create_detection_enabled_action();
1447 void update_detection_enabled_action();
1448- static void on_detection_location_activated (GSimpleAction*, GVariant*, gpointer);
1449-
1450-
1451- private:
1452- GVariant * action_state_for_gps_detection ();
1453- GSimpleAction * create_gps_enabled_action ();
1454+ static void on_detection_location_activated(GSimpleAction*, GVariant*, gpointer);
1455+
1456+private:
1457+ GVariant* action_state_for_gps_detection();
1458+ GSimpleAction* create_gps_enabled_action();
1459 void update_gps_enabled_action();
1460- static void on_detection_gps_activated (GSimpleAction*, GVariant*, gpointer);
1461-
1462- private:
1463- GSimpleAction * create_settings_action ();
1464-
1465- private:
1466- GSimpleAction * create_licence_action ();
1467+ static void on_detection_gps_activated(GSimpleAction*, GVariant*, gpointer);
1468+
1469+private:
1470+ GSimpleAction* create_settings_action();
1471+
1472+private:
1473+ GSimpleAction* create_licence_action();
1474 };
1475-
1476-#endif /* __INDICATOR_LOCATION_PHONE_H__ */
1477
1478=== modified file 'src/service.cc'
1479--- src/service.cc 2016-01-22 20:08:44 +0000
1480+++ src/service.cc 2016-01-22 20:08:44 +0000
1481@@ -1,20 +1,20 @@
1482 /*
1483- * Copyright 2013 Canonical Ltd.
1484+ * Copyright 2013-2016 Canonical Ltd.
1485+ *
1486+ * This program is free software; you can redistribute it and/or modify
1487+ * it under the terms of the GNU General Public License as published by
1488+ * the Free Software Foundation; version 3.
1489+ *
1490+ * This program is distributed in the hope that it will be useful,
1491+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1492+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1493+ * GNU Lesser General Public License for more details.
1494+ *
1495+ * You should have received a copy of the GNU Lesser General Public License
1496+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1497 *
1498 * Authors:
1499 * Charles Kerr <charles.kerr@canonical.com>
1500- *
1501- * This program is free software: you can redistribute it and/or modify it
1502- * under the terms of the GNU General Public License version 3, as published
1503- * by the Free Software Foundation.
1504- *
1505- * This program is distributed in the hope that it will be useful, but
1506- * WITHOUT ANY WARRANTY; without even the implied warranties of
1507- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1508- * PURPOSE. See the GNU General Public License for more details.
1509- *
1510- * You should have received a copy of the GNU General Public License along
1511- * with this program. If not, see <http://www.gnu.org/licenses/>.
1512 */
1513
1514 #include <glib/gi18n.h>
1515@@ -27,55 +27,53 @@
1516 ***
1517 **/
1518
1519-Service :: Service (const std::shared_ptr<Controller>& controller):
1520- action_group (g_simple_action_group_new(), GObjectDeleter()),
1521- phone_profile (controller, action_group),
1522- name_lost_callback (nullptr),
1523- name_lost_user_data (0),
1524- action_group_export_id (0),
1525- bus_own_id (0)
1526-{
1527- bus_own_id = g_bus_own_name (G_BUS_TYPE_SESSION,
1528- INDICATOR_BUS_NAME,
1529- G_BUS_NAME_OWNER_FLAGS_NONE,
1530- on_bus_acquired,
1531- nullptr,
1532- on_name_lost,
1533- this,
1534- nullptr);
1535-}
1536-
1537-Service :: ~Service ()
1538-{
1539- if (connection)
1540- unexport ();
1541-
1542- if (bus_own_id != 0)
1543- g_bus_unown_name (bus_own_id);
1544-}
1545-
1546-void
1547-Service :: set_name_lost_callback (name_lost_callback_func callback, void* user_data)
1548-{
1549- name_lost_callback = callback;
1550- name_lost_user_data = user_data;
1551-}
1552-
1553-void
1554-Service :: unexport ()
1555-{
1556- g_return_if_fail (connection);
1557-
1558- // unexport the menu(s)
1559- for (auto& id : exported_menus)
1560- g_dbus_connection_unexport_menu_model (connection.get(), id);
1561- exported_menus.clear ();
1562-
1563- // unexport the action group
1564- if (action_group_export_id != 0)
1565- {
1566- g_dbus_connection_unexport_action_group (connection.get(), action_group_export_id);
1567- action_group_export_id = 0;
1568+Service::Service(const std::shared_ptr<Controller>& controller)
1569+ : action_group(g_simple_action_group_new(), GObjectDeleter())
1570+ , phone_profile(controller, action_group)
1571+ , name_lost_callback(nullptr)
1572+ , name_lost_user_data(0)
1573+ , action_group_export_id(0)
1574+ , bus_own_id(0)
1575+{
1576+ bus_own_id = g_bus_own_name(G_BUS_TYPE_SESSION, INDICATOR_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired,
1577+ nullptr, on_name_lost, this, nullptr);
1578+}
1579+
1580+Service::~Service()
1581+{
1582+ if (connection)
1583+ {
1584+ unexport();
1585+ }
1586+
1587+ if (bus_own_id != 0)
1588+ {
1589+ g_bus_unown_name(bus_own_id);
1590+ }
1591+}
1592+
1593+void Service::set_name_lost_callback(name_lost_callback_func callback, void* user_data)
1594+{
1595+ name_lost_callback = callback;
1596+ name_lost_user_data = user_data;
1597+}
1598+
1599+void Service::unexport()
1600+{
1601+ g_return_if_fail(connection);
1602+
1603+ // unexport the menu(s)
1604+ for (auto& id : exported_menus)
1605+ {
1606+ g_dbus_connection_unexport_menu_model(connection.get(), id);
1607+ }
1608+ exported_menus.clear();
1609+
1610+ // unexport the action group
1611+ if (action_group_export_id != 0)
1612+ {
1613+ g_dbus_connection_unexport_action_group(connection.get(), action_group_export_id);
1614+ action_group_export_id = 0;
1615 }
1616 }
1617
1618@@ -83,82 +81,67 @@
1619 **** GDBus
1620 ***/
1621
1622-void
1623-Service :: on_name_lost (GDBusConnection * conn,
1624- const char * name,
1625- gpointer gself)
1626-{
1627- g_debug ("%s::%s: %s %p", G_STRLOC, G_STRFUNC, name, conn);
1628-
1629- static_cast<Service*>(gself)->on_name_lost (conn, name);
1630-}
1631-void
1632-Service :: on_name_lost (GDBusConnection * conn,
1633- const char * name)
1634-{
1635- g_debug ("%s::%s: %s %p", G_STRLOC, G_STRFUNC, name, conn);
1636-
1637- if (name_lost_callback != nullptr)
1638- (name_lost_callback)(this, name_lost_user_data);
1639-}
1640-
1641-void
1642-Service :: on_bus_acquired (GDBusConnection * conn,
1643- const char * name,
1644- gpointer gself)
1645-{
1646- static_cast<Service*>(gself)->on_bus_acquired (conn, name);
1647-}
1648-void
1649-Service :: on_bus_acquired (GDBusConnection * conn,
1650- const char * name)
1651-{
1652- g_debug ("%s::%s: %s %p", G_STRLOC, G_STRFUNC, name, conn);
1653-
1654- this->connection.reset (G_DBUS_CONNECTION (g_object_ref(conn)));
1655-
1656- GError * error = nullptr;
1657-
1658- /* export the action group */
1659-
1660- unsigned int export_id = g_dbus_connection_export_action_group (conn,
1661- INDICATOR_OBJECT_PATH,
1662- G_ACTION_GROUP (action_group.get()),
1663- &error);
1664- if (error != nullptr)
1665- {
1666- g_warning ("Unable to export action group: %s", error->message);
1667- g_clear_error (&error);
1668- }
1669- else
1670- {
1671- action_group_export_id = export_id;
1672- }
1673-
1674- /* export the menu(s) */
1675-
1676- struct {
1677- std::shared_ptr<GMenu> menu;
1678- const char * path;
1679- } menus[] = {
1680- { phone_profile.get_menu(), INDICATOR_OBJECT_PATH "/phone" }
1681- };
1682-
1683- for (unsigned int i=0, n=G_N_ELEMENTS(menus); i<n; i++)
1684- {
1685- export_id = g_dbus_connection_export_menu_model (conn,
1686- menus[i].path,
1687- G_MENU_MODEL (menus[i].menu.get()),
1688- &error);
1689- if (error != nullptr)
1690- {
1691- g_warning ("Unable to export phone menu: %s", error->message);
1692- g_clear_error (&error);
1693- }
1694- else
1695- {
1696- exported_menus.insert (export_id);
1697- }
1698- }
1699-}
1700-
1701+void Service::on_name_lost(GDBusConnection* conn, const char* name, gpointer gself)
1702+{
1703+ g_debug("%s::%s: %s %p", G_STRLOC, G_STRFUNC, name, conn);
1704+
1705+ static_cast<Service*>(gself)->on_name_lost(conn, name);
1706+}
1707+void Service::on_name_lost(GDBusConnection* conn, const char* name)
1708+{
1709+ g_debug("%s::%s: %s %p", G_STRLOC, G_STRFUNC, name, conn);
1710+
1711+ if (name_lost_callback != nullptr)
1712+ {
1713+ (name_lost_callback)(this, name_lost_user_data);
1714+ }
1715+}
1716+
1717+void Service::on_bus_acquired(GDBusConnection* conn, const char* name, gpointer gself)
1718+{
1719+ static_cast<Service*>(gself)->on_bus_acquired(conn, name);
1720+}
1721+void Service::on_bus_acquired(GDBusConnection* conn, const char* name)
1722+{
1723+ g_debug("%s::%s: %s %p", G_STRLOC, G_STRFUNC, name, conn);
1724+
1725+ this->connection.reset(G_DBUS_CONNECTION(g_object_ref(conn)));
1726+
1727+ GError* error = nullptr;
1728+
1729+ /* export the action group */
1730+
1731+ unsigned int export_id =
1732+ g_dbus_connection_export_action_group(conn, INDICATOR_OBJECT_PATH, G_ACTION_GROUP(action_group.get()), &error);
1733+ if (error != nullptr)
1734+ {
1735+ g_warning("Unable to export action group: %s", error->message);
1736+ g_clear_error(&error);
1737+ }
1738+ else
1739+ {
1740+ action_group_export_id = export_id;
1741+ }
1742+
1743+ /* export the menu(s) */
1744+
1745+ struct
1746+ {
1747+ std::shared_ptr<GMenu> menu;
1748+ const char* path;
1749+ } menus[] = {{phone_profile.get_menu(), INDICATOR_OBJECT_PATH "/phone"}};
1750+
1751+ for (unsigned int i = 0, n = G_N_ELEMENTS(menus); i < n; i++)
1752+ {
1753+ export_id = g_dbus_connection_export_menu_model(conn, menus[i].path, G_MENU_MODEL(menus[i].menu.get()), &error);
1754+ if (error != nullptr)
1755+ {
1756+ g_warning("Unable to export phone menu: %s", error->message);
1757+ g_clear_error(&error);
1758+ }
1759+ else
1760+ {
1761+ exported_menus.insert(export_id);
1762+ }
1763+ }
1764+}
1765
1766=== modified file 'src/service.h'
1767--- src/service.h 2016-01-22 20:08:44 +0000
1768+++ src/service.h 2016-01-22 20:08:44 +0000
1769@@ -1,64 +1,59 @@
1770 /*
1771- * Copyright 2013 Canonical Ltd.
1772+ * Copyright 2013-2016 Canonical Ltd.
1773+ *
1774+ * This program is free software; you can redistribute it and/or modify
1775+ * it under the terms of the GNU General Public License as published by
1776+ * the Free Software Foundation; version 3.
1777+ *
1778+ * This program is distributed in the hope that it will be useful,
1779+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1780+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1781+ * GNU Lesser General Public License for more details.
1782+ *
1783+ * You should have received a copy of the GNU Lesser General Public License
1784+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1785 *
1786 * Authors:
1787 * Charles Kerr <charles.kerr@canonical.com>
1788- *
1789- * This program is free software: you can redistribute it and/or modify it
1790- * under the terms of the GNU General Public License version 3, as published
1791- * by the Free Software Foundation.
1792- *
1793- * This program is distributed in the hope that it will be useful, but
1794- * WITHOUT ANY WARRANTY; without even the implied warranties of
1795- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1796- * PURPOSE. See the GNU General Public License for more details.
1797- *
1798- * You should have received a copy of the GNU General Public License along
1799- * with this program. If not, see <http://www.gnu.org/licenses/>.
1800 */
1801
1802-#ifndef __INDICATOR_LOCATION_SERVICE_H__
1803-#define __INDICATOR_LOCATION_SERVICE_H__
1804+#pragma once
1805
1806 #include <memory>
1807 #include <set>
1808
1809 #include "controller.h"
1810 #include "phone.h"
1811-#include "utils.h" // GObjectDeleter
1812+#include "utils.h" // GObjectDeleter
1813
1814 class Service
1815 {
1816- public:
1817- explicit Service (const std::shared_ptr<Controller>& controller);
1818- virtual ~Service ();
1819+public:
1820+ explicit Service(const std::shared_ptr<Controller>& controller);
1821+ virtual ~Service();
1822
1823- private:
1824+private:
1825 std::shared_ptr<GSimpleActionGroup> action_group;
1826- std::unique_ptr<GDBusConnection,GObjectDeleter> connection;
1827+ std::unique_ptr<GDBusConnection, GObjectDeleter> connection;
1828 Phone phone_profile;
1829
1830- public:
1831+public:
1832 typedef void (*name_lost_callback_func)(Service*, void* user_data);
1833- void set_name_lost_callback (name_lost_callback_func callback, void* user_data);
1834- private:
1835+ void set_name_lost_callback(name_lost_callback_func callback, void* user_data);
1836+
1837+private:
1838 name_lost_callback_func name_lost_callback;
1839- void * name_lost_user_data;
1840-
1841-
1842- private:
1843+ void* name_lost_user_data;
1844+
1845+private:
1846 unsigned int action_group_export_id;
1847 std::set<unsigned int> exported_menus;
1848- void unexport ();
1849-
1850-
1851- private: // DBus callbacks
1852+ void unexport();
1853+
1854+private: // DBus callbacks
1855 unsigned int bus_own_id;
1856- void on_name_lost (GDBusConnection*, const char*);
1857- void on_bus_acquired (GDBusConnection*, const char*);
1858- static void on_name_lost (GDBusConnection*, const char*, gpointer);
1859- static void on_bus_acquired (GDBusConnection*, const char*, gpointer);
1860+ void on_name_lost(GDBusConnection*, const char*);
1861+ void on_bus_acquired(GDBusConnection*, const char*);
1862+ static void on_name_lost(GDBusConnection*, const char*, gpointer);
1863+ static void on_bus_acquired(GDBusConnection*, const char*, gpointer);
1864 };
1865-
1866-#endif /* __INDICATOR_LOCATION_SERVICE_H__ */
1867-
1868
1869=== modified file 'src/utils.h'
1870--- src/utils.h 2014-09-02 17:33:44 +0000
1871+++ src/utils.h 2016-01-22 20:08:44 +0000
1872@@ -1,37 +1,48 @@
1873 /*
1874- * Copyright 2013 Canonical Ltd.
1875+ * Copyright 2013-2016 Canonical Ltd.
1876+ *
1877+ * This program is free software; you can redistribute it and/or modify
1878+ * it under the terms of the GNU General Public License as published by
1879+ * the Free Software Foundation; version 3.
1880+ *
1881+ * This program is distributed in the hope that it will be useful,
1882+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1883+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1884+ * GNU Lesser General Public License for more details.
1885+ *
1886+ * You should have received a copy of the GNU Lesser General Public License
1887+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1888 *
1889 * Authors:
1890 * Charles Kerr <charles.kerr@canonical.com>
1891- *
1892- * This program is free software: you can redistribute it and/or modify it
1893- * under the terms of the GNU General Public License version 3, as published
1894- * by the Free Software Foundation.
1895- *
1896- * This program is distributed in the hope that it will be useful, but
1897- * WITHOUT ANY WARRANTY; without even the implied warranties of
1898- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1899- * PURPOSE. See the GNU General Public License for more details.
1900- *
1901- * You should have received a copy of the GNU General Public License along
1902- * with this program. If not, see <http://www.gnu.org/licenses/>.
1903 */
1904
1905-#ifndef __INDICATOR_LOCATION_UTILS_H__
1906-#define __INDICATOR_LOCATION_UTILS_H__
1907+#pragma once
1908
1909 #include <glib.h>
1910 #include <gio/gio.h>
1911
1912 struct GObjectDeleter
1913 {
1914- void operator()(GObject * o) { g_object_unref (o); }
1915+ void operator()(GObject* o)
1916+ {
1917+ g_object_unref(o);
1918+ }
1919
1920- void operator()(GMenu * o) { operator()(G_OBJECT(o)); }
1921- void operator()(GDBusProxy * o) { operator()(G_OBJECT(o)); }
1922- void operator()(GDBusConnection * o) { operator()(G_OBJECT(o)); }
1923- void operator()(GSimpleActionGroup * o) { operator()(G_OBJECT(o)); }
1924+ void operator()(GMenu* o)
1925+ {
1926+ operator()(G_OBJECT(o));
1927+ }
1928+ void operator()(GDBusProxy* o)
1929+ {
1930+ operator()(G_OBJECT(o));
1931+ }
1932+ void operator()(GDBusConnection* o)
1933+ {
1934+ operator()(G_OBJECT(o));
1935+ }
1936+ void operator()(GSimpleActionGroup* o)
1937+ {
1938+ operator()(G_OBJECT(o));
1939+ }
1940 };
1941-
1942-#endif /* __INDICATOR_LOCATION_UTILS_H__ */
1943-
1944
1945=== modified file 'tests/CMakeLists.txt'
1946--- tests/CMakeLists.txt 2015-04-16 01:54:48 +0000
1947+++ tests/CMakeLists.txt 2016-01-22 20:08:44 +0000
1948@@ -19,6 +19,9 @@
1949 set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g ${CC_WARNING_ARGS}")
1950 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g ${CC_WARNING_ARGS} -std=c++11")
1951
1952+add_test(NAME formatcode
1953+ COMMAND "${CMAKE_SOURCE_DIR}/tools/format-test.sh" "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}/tools/formatcode")
1954+
1955 ###
1956 ### phone-test
1957 ###
1958
1959=== modified file 'tests/controller-mock.h'
1960--- tests/controller-mock.h 2016-01-22 20:08:44 +0000
1961+++ tests/controller-mock.h 2016-01-22 20:08:44 +0000
1962@@ -1,5 +1,5 @@
1963 /*
1964- * Copyright 2013 Canonical Ltd.
1965+ * Copyright 2013-2016 Canonical Ltd.
1966 *
1967 * This program is free software; you can redistribute it and/or modify
1968 * it under the terms of the GNU General Public License as published by
1969@@ -21,25 +21,40 @@
1970
1971 #include <src/controller.h>
1972
1973-class MockController: public Controller
1974+class MockController : public Controller
1975 {
1976- public:
1977-
1978- MockController() =default;
1979- virtual ~MockController() =default;
1980-
1981- core::Property<bool>& is_valid() { return m_is_valid; }
1982- const core::Property<bool>& is_valid() const override { return m_is_valid; }
1983- const core::Property<bool>& gps_enabled() const override { return m_gps_enabled; }
1984- const core::Property<bool>& location_service_enabled() const override { return m_location_service_enabled; }
1985-
1986- void set_gps_enabled (bool enabled) override { m_gps_enabled=enabled; }
1987- void set_location_service_enabled (bool enabled) override { m_location_service_enabled=enabled; }
1988-
1989- private:
1990-
1991- core::Property<bool> m_is_valid {true};
1992- core::Property<bool> m_gps_enabled {false};
1993- core::Property<bool> m_location_service_enabled {false};
1994+public:
1995+ MockController() = default;
1996+ virtual ~MockController() = default;
1997+
1998+ core::Property<bool>& is_valid()
1999+ {
2000+ return m_is_valid;
2001+ }
2002+ const core::Property<bool>& is_valid() const override
2003+ {
2004+ return m_is_valid;
2005+ }
2006+ const core::Property<bool>& gps_enabled() const override
2007+ {
2008+ return m_gps_enabled;
2009+ }
2010+ const core::Property<bool>& location_service_enabled() const override
2011+ {
2012+ return m_location_service_enabled;
2013+ }
2014+
2015+ void set_gps_enabled(bool enabled) override
2016+ {
2017+ m_gps_enabled = enabled;
2018+ }
2019+ void set_location_service_enabled(bool enabled) override
2020+ {
2021+ m_location_service_enabled = enabled;
2022+ }
2023+
2024+private:
2025+ core::Property<bool> m_is_valid{true};
2026+ core::Property<bool> m_gps_enabled{false};
2027+ core::Property<bool> m_location_service_enabled{false};
2028 };
2029-
2030
2031=== modified file 'tests/gtest-dbus-fixture.h'
2032--- tests/gtest-dbus-fixture.h 2016-01-22 20:08:44 +0000
2033+++ tests/gtest-dbus-fixture.h 2016-01-22 20:08:44 +0000
2034@@ -1,22 +1,24 @@
2035 /*
2036- * Copyright 2013 Canonical Ltd.
2037+ * Copyright 2013-2016 Canonical Ltd.
2038+ *
2039+ * This program is free software; you can redistribute it and/or modify
2040+ * it under the terms of the GNU General Public License as published by
2041+ * the Free Software Foundation; version 3.
2042+ *
2043+ * This program is distributed in the hope that it will be useful,
2044+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2045+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2046+ * GNU Lesser General Public License for more details.
2047+ *
2048+ * You should have received a copy of the GNU Lesser General Public License
2049+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2050 *
2051 * Authors:
2052 * Charles Kerr <charles.kerr@canonical.com>
2053- *
2054- * This program is free software: you can redistribute it and/or modify it
2055- * under the terms of the GNU General Public License version 3, as published
2056- * by the Free Software Foundation.
2057- *
2058- * This program is distributed in the hope that it will be useful, but
2059- * WITHOUT ANY WARRANTY; without even the implied warranties of
2060- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2061- * PURPOSE. See the GNU General Public License for more details.
2062- *
2063- * You should have received a copy of the GNU General Public License along
2064- * with this program. If not, see <http://www.gnu.org/licenses/>.
2065 */
2066
2067+#pragma once
2068+
2069 #include <glib.h>
2070 #include <gio/gio.h>
2071
2072@@ -28,114 +30,103 @@
2073
2074 class GTestDBusFixture : public ::testing::Test
2075 {
2076- private:
2077-
2078- static void
2079- on_bus_opened (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
2080- {
2081- GTestDBusFixture * self = static_cast<GTestDBusFixture*>(gself);
2082-
2083- GError * err = nullptr;
2084- self->conn = g_bus_get_finish (res, &err);
2085- g_assert_no_error (err);
2086-
2087- g_main_loop_quit (self->loop);
2088- }
2089-
2090- static void
2091- on_bus_closed (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself)
2092- {
2093- GTestDBusFixture * self = static_cast<GTestDBusFixture*>(gself);
2094-
2095- GError * err = nullptr;
2096- g_dbus_connection_close_finish (self->conn, res, &err);
2097- g_assert_no_error (err);
2098-
2099- g_main_loop_quit (self->loop);
2100- }
2101-
2102- static gboolean
2103- wait_for_signal__timeout (gpointer name)
2104- {
2105- g_error ("%s: timed out waiting for signal '%s'", G_STRLOC, name);
2106- return G_SOURCE_REMOVE;
2107- }
2108-
2109- static gboolean
2110- wait_msec__timeout(gpointer loop)
2111- {
2112- g_main_loop_quit(static_cast<GMainLoop*>(loop));
2113- return G_SOURCE_CONTINUE;
2114- }
2115-
2116- protected:
2117-
2118- virtual void SetUp ()
2119- {
2120- conn = nullptr;
2121- test_dbus = nullptr;
2122- loop = nullptr;
2123-
2124- //g_setenv ("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, TRUE);
2125- //g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
2126- //g_debug ("SCHEMA_DIR is %s", SCHEMA_DIR);
2127-
2128- // pull up a test dbus
2129- loop = g_main_loop_new (nullptr, FALSE);
2130- test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
2131- //g_test_dbus_add_service_dir (test_dbus, INDICATOR_SERVICE_DIR);
2132- //g_debug ("INDICATOR_SERVICE_DIR is %s", INDICATOR_SERVICE_DIR);
2133- g_test_dbus_up (test_dbus);
2134- const char * address;
2135- address = g_test_dbus_get_bus_address (test_dbus);
2136- g_setenv ("DBUS_SYSTEM_BUS_ADDRESS", address, TRUE);
2137- g_debug ("test_dbus's address is %s", address);
2138-
2139- // wait for the GDBusConnection before returning
2140- g_bus_get (G_BUS_TYPE_SYSTEM, nullptr, on_bus_opened, this);
2141- g_main_loop_run (loop);
2142+private:
2143+ static void on_bus_opened(GObject* o G_GNUC_UNUSED, GAsyncResult* res, gpointer gself)
2144+ {
2145+ GTestDBusFixture* self = static_cast<GTestDBusFixture*>(gself);
2146+
2147+ GError* err = nullptr;
2148+ self->conn = g_bus_get_finish(res, &err);
2149+ g_assert_no_error(err);
2150+
2151+ g_main_loop_quit(self->loop);
2152+ }
2153+
2154+ static void on_bus_closed(GObject* o G_GNUC_UNUSED, GAsyncResult* res, gpointer gself)
2155+ {
2156+ GTestDBusFixture* self = static_cast<GTestDBusFixture*>(gself);
2157+
2158+ GError* err = nullptr;
2159+ g_dbus_connection_close_finish(self->conn, res, &err);
2160+ g_assert_no_error(err);
2161+
2162+ g_main_loop_quit(self->loop);
2163+ }
2164+
2165+ static gboolean wait_for_signal__timeout(gpointer name)
2166+ {
2167+ g_error("%s: timed out waiting for signal '%s'", G_STRLOC, name);
2168+ return G_SOURCE_REMOVE;
2169+ }
2170+
2171+ static gboolean wait_msec__timeout(gpointer loop)
2172+ {
2173+ g_main_loop_quit(static_cast<GMainLoop*>(loop));
2174+ return G_SOURCE_CONTINUE;
2175+ }
2176+
2177+protected:
2178+ virtual void SetUp()
2179+ {
2180+ conn = nullptr;
2181+ test_dbus = nullptr;
2182+ loop = nullptr;
2183+
2184+ // g_setenv ("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, TRUE);
2185+ // g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
2186+ // g_debug ("SCHEMA_DIR is %s", SCHEMA_DIR);
2187+
2188+ // pull up a test dbus
2189+ loop = g_main_loop_new(nullptr, FALSE);
2190+ test_dbus = g_test_dbus_new(G_TEST_DBUS_NONE);
2191+ // g_test_dbus_add_service_dir (test_dbus, INDICATOR_SERVICE_DIR);
2192+ // g_debug ("INDICATOR_SERVICE_DIR is %s", INDICATOR_SERVICE_DIR);
2193+ g_test_dbus_up(test_dbus);
2194+ const char* address;
2195+ address = g_test_dbus_get_bus_address(test_dbus);
2196+ g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, TRUE);
2197+ g_debug("test_dbus's address is %s", address);
2198+
2199+ // wait for the GDBusConnection before returning
2200+ g_bus_get(G_BUS_TYPE_SYSTEM, nullptr, on_bus_opened, this);
2201+ g_main_loop_run(loop);
2202 }
2203
2204 virtual void TearDown()
2205 {
2206- // close the bus connection
2207- g_dbus_connection_close (conn, nullptr, on_bus_closed, this);
2208- g_main_loop_run (loop);
2209- g_clear_object (&conn);
2210-
2211- // tear down the test dbus
2212- g_test_dbus_down (test_dbus);
2213- g_clear_object (&test_dbus);
2214-
2215- g_clear_pointer (&loop, g_main_loop_unref);
2216+ // close the bus connection
2217+ g_dbus_connection_close(conn, nullptr, on_bus_closed, this);
2218+ g_main_loop_run(loop);
2219+ g_clear_object(&conn);
2220+
2221+ // tear down the test dbus
2222+ g_test_dbus_down(test_dbus);
2223+ g_clear_object(&test_dbus);
2224+
2225+ g_clear_pointer(&loop, g_main_loop_unref);
2226 }
2227
2228- protected:
2229-
2230+protected:
2231 /* convenience func to loop while waiting for a GObject's signal */
2232- void wait_for_signal(gpointer o, const gchar * signal, const guint timeout_seconds=5)
2233+ void wait_for_signal(gpointer o, const gchar* signal, const guint timeout_seconds = 5)
2234 {
2235- // wait for the signal or for timeout, whichever comes first
2236- const auto handler_id = g_signal_connect_swapped(o, signal,
2237- G_CALLBACK(g_main_loop_quit),
2238- loop);
2239- const auto timeout_id = g_timeout_add_seconds(timeout_seconds,
2240- wait_for_signal__timeout,
2241- loop);
2242- g_main_loop_run(loop);
2243- g_source_remove(timeout_id);
2244- g_signal_handler_disconnect(o, handler_id);
2245+ // wait for the signal or for timeout, whichever comes first
2246+ const auto handler_id = g_signal_connect_swapped(o, signal, G_CALLBACK(g_main_loop_quit), loop);
2247+ const auto timeout_id = g_timeout_add_seconds(timeout_seconds, wait_for_signal__timeout, loop);
2248+ g_main_loop_run(loop);
2249+ g_source_remove(timeout_id);
2250+ g_signal_handler_disconnect(o, handler_id);
2251 }
2252
2253 /* convenience func to loop for N msec */
2254- void wait_msec(guint msec=50)
2255+ void wait_msec(guint msec = 50)
2256 {
2257- const auto id = g_timeout_add(msec, wait_msec__timeout, loop);
2258- g_main_loop_run(loop);
2259- g_source_remove(id);
2260+ const auto id = g_timeout_add(msec, wait_msec__timeout, loop);
2261+ g_main_loop_run(loop);
2262+ g_source_remove(id);
2263 }
2264
2265- GMainLoop * loop;
2266- GTestDBus * test_dbus;
2267- GDBusConnection * conn;
2268+ GMainLoop* loop;
2269+ GTestDBus* test_dbus;
2270+ GDBusConnection* conn;
2271 };
2272
2273=== modified file 'tests/gtest-dbus-indicator-fixture.h'
2274--- tests/gtest-dbus-indicator-fixture.h 2016-01-22 20:08:44 +0000
2275+++ tests/gtest-dbus-indicator-fixture.h 2016-01-22 20:08:44 +0000
2276@@ -1,5 +1,5 @@
2277 /*
2278- * Copyright 2013 Canonical Ltd.
2279+ * Copyright 2013-2016 Canonical Ltd.
2280 *
2281 * This program is free software; you can redistribute it and/or modify
2282 * it under the terms of the GNU General Public License as published by
2283@@ -17,264 +17,280 @@
2284 * Charles Kerr <charles.kerr@canonical.com>
2285 */
2286
2287+#pragma once
2288+
2289 #include "src/dbus-shared.h"
2290 #include "gtest-dbus-fixture.h"
2291
2292-class GTestDBusIndicatorFixture: public GTestDBusFixture
2293+class GTestDBusIndicatorFixture : public GTestDBusFixture
2294 {
2295 typedef GTestDBusFixture super;
2296
2297- enum { TIME_LIMIT_SEC = 10 };
2298-
2299- private:
2300-
2301- static void on_name_appeared (GDBusConnection * connection G_GNUC_UNUSED,
2302- const gchar * name G_GNUC_UNUSED,
2303- const gchar * name_owner G_GNUC_UNUSED,
2304- gpointer gself)
2305- {
2306- g_main_loop_quit (static_cast<GTestDBusIndicatorFixture*>(gself)->loop);
2307+ enum
2308+ {
2309+ TIME_LIMIT_SEC = 10
2310+ };
2311+
2312+private:
2313+ static void on_name_appeared(GDBusConnection* connection G_GNUC_UNUSED,
2314+ const gchar* name G_GNUC_UNUSED,
2315+ const gchar* name_owner G_GNUC_UNUSED,
2316+ gpointer gself)
2317+ {
2318+ g_main_loop_quit(static_cast<GTestDBusIndicatorFixture*>(gself)->loop);
2319 }
2320
2321- GSList * menu_references;
2322+ GSList* menu_references;
2323
2324 gboolean any_item_changed;
2325
2326- static void on_items_changed (GMenuModel * model G_GNUC_UNUSED,
2327- gint position G_GNUC_UNUSED,
2328- gint removed G_GNUC_UNUSED,
2329- gint added G_GNUC_UNUSED,
2330- gpointer gany_item_changed)
2331- {
2332- *static_cast<gboolean*>(gany_item_changed) = true;
2333- }
2334-
2335- protected:
2336-
2337- void activate_subtree (GMenuModel * model)
2338- {
2339- // query the GDBusMenuModel for information to activate it
2340- int n = g_menu_model_get_n_items (model);
2341- if (!n)
2342- {
2343- // give the model a moment to populate its info
2344- wait_msec (100);
2345- n = g_menu_model_get_n_items (model);
2346- }
2347-
2348- // keep a ref so that it stays activated
2349- menu_references = g_slist_prepend (menu_references, g_object_ref(model));
2350-
2351- g_signal_connect (model, "items-changed", G_CALLBACK(on_items_changed), &any_item_changed);
2352-
2353- // recurse
2354- for (int i=0; i<n; ++i)
2355- {
2356- GMenuModel * link;
2357- GMenuLinkIter * iter = g_menu_model_iterate_item_links (model, i);
2358- while (g_menu_link_iter_get_next (iter, nullptr, &link))
2359- {
2360- activate_subtree (link);
2361- g_object_unref (link);
2362- }
2363- g_clear_object (&iter);
2364- }
2365- }
2366-
2367- void sync_menu (void)
2368- {
2369- g_slist_free_full (menu_references, GDestroyNotify(g_object_unref));
2370- menu_references = nullptr;
2371- activate_subtree (G_MENU_MODEL (menu_model));
2372- }
2373-
2374- GDBusMenuModel * menu_model;
2375- GDBusActionGroup * action_group;
2376- GTimer * timer;
2377-
2378- virtual void setup_service () = 0;
2379- virtual void teardown_service () = 0;
2380-
2381- virtual void SetUp ()
2382- {
2383- super :: SetUp ();
2384-
2385- menu_references = nullptr;
2386- any_item_changed = FALSE;
2387-
2388- timer = g_timer_new ();
2389-
2390- // Start an IndicatorSessionService and wait for it to appear on the bus.
2391- setup_service ();
2392- const guint watch_id = g_bus_watch_name_on_connection (conn,
2393- INDICATOR_BUS_NAME,
2394- G_BUS_NAME_WATCHER_FLAGS_NONE,
2395- on_name_appeared, // quits the loop
2396- nullptr, this, nullptr);
2397- const guint timer_id = g_timeout_add_seconds (TIME_LIMIT_SEC, GSourceFunc(g_main_loop_quit), loop);
2398- g_main_loop_run (loop);
2399- g_source_remove (timer_id);
2400- g_bus_unwatch_name (watch_id);
2401- ASSERT_FALSE (times_up());
2402-
2403- // get the actions & menus that the service exported.
2404- action_group = g_dbus_action_group_get (conn,
2405- INDICATOR_BUS_NAME,
2406- INDICATOR_OBJECT_PATH);
2407- menu_model = g_dbus_menu_model_get (conn,
2408- INDICATOR_BUS_NAME,
2409- INDICATOR_OBJECT_PATH "/" INDICATOR_PROFILE);
2410- // the actions are added asynchronously, so wait for the actions
2411- if (!g_action_group_has_action (G_ACTION_GROUP(action_group), INDICATOR_PROFILE "-header"))
2412- wait_for_signal (action_group, "action-added");
2413- // activate all the groups in the menu so it'll be ready when we need it
2414- g_signal_connect (menu_model, "items-changed", G_CALLBACK(on_items_changed), &any_item_changed);
2415- sync_menu ();
2416- }
2417-
2418- virtual void TearDown ()
2419- {
2420- g_clear_pointer (&timer, g_timer_destroy);
2421-
2422- g_slist_free_full (menu_references, GDestroyNotify(g_object_unref));
2423- menu_references = nullptr;
2424- g_clear_object (&menu_model);
2425-
2426- g_clear_object (&action_group);
2427- teardown_service ();
2428- wait_msec (100);
2429-
2430- super :: TearDown ();
2431- }
2432-
2433- private:
2434-
2435- bool times_up () const
2436- {
2437- return g_timer_elapsed (timer, nullptr) >= TIME_LIMIT_SEC;
2438- }
2439-
2440- protected:
2441-
2442- void wait_for_has_action (const char * name)
2443- {
2444- while (!g_action_group_has_action (G_ACTION_GROUP(action_group), name) && !times_up())
2445- wait_msec (50);
2446-
2447- ASSERT_FALSE (times_up());
2448- ASSERT_TRUE (g_action_group_has_action (G_ACTION_GROUP(action_group), name));
2449- }
2450-
2451- void wait_for_menu_resync (void)
2452- {
2453- any_item_changed = false;
2454- while (!times_up() && !any_item_changed)
2455- wait_msec (50);
2456- g_warn_if_fail (any_item_changed);
2457- sync_menu ();
2458- }
2459-
2460- void wait_for_action_state_change (const gchar * action_name)
2461- {
2462- gchar * signal_name = g_strdup_printf ("action-state-changed::%s", action_name);
2463- wait_for_signal (action_group, signal_name);
2464- g_free (signal_name);
2465- }
2466-
2467- void wait_for_action_enabled_change (const gchar * action_name)
2468- {
2469- gchar * signal_name = g_strdup_printf ("action-enabled-changed::%s", action_name);
2470- wait_for_signal (action_group, signal_name);
2471- g_free (signal_name);
2472- }
2473-
2474- protected:
2475-
2476- bool find_menu_item_for_action (const char * action_key, GMenuModel ** setme, int * item_index)
2477- {
2478- bool success = false;
2479-
2480- for (GSList * l=menu_references; !success && (l!=nullptr); l=l->next)
2481- {
2482- GMenuModel * mm = G_MENU_MODEL (l->data);
2483- const int n = g_menu_model_get_n_items (mm);
2484-
2485- for (int i=0; !success && i<n; ++i)
2486- {
2487- char * action = nullptr;
2488- if (!g_menu_model_get_item_attribute (mm, i, G_MENU_ATTRIBUTE_ACTION, "s", &action))
2489- continue;
2490-
2491- if ((success = !g_strcmp0 (action, action_key)))
2492- {
2493- if (setme != nullptr)
2494- *setme = G_MENU_MODEL (g_object_ref (G_OBJECT(mm)));
2495-
2496- if (item_index != nullptr)
2497- *item_index = i;
2498- }
2499-
2500- g_free (action);
2501- }
2502- }
2503-
2504- return success;
2505- }
2506-
2507- bool action_exists (const char * action_name)
2508+ static void on_items_changed(GMenuModel* model G_GNUC_UNUSED,
2509+ gint position G_GNUC_UNUSED,
2510+ gint removed G_GNUC_UNUSED,
2511+ gint added G_GNUC_UNUSED,
2512+ gpointer gany_item_changed)
2513+ {
2514+ *static_cast<gboolean*>(gany_item_changed) = true;
2515+ }
2516+
2517+protected:
2518+ void activate_subtree(GMenuModel* model)
2519+ {
2520+ // query the GDBusMenuModel for information to activate it
2521+ int n = g_menu_model_get_n_items(model);
2522+ if (!n)
2523+ {
2524+ // give the model a moment to populate its info
2525+ wait_msec(100);
2526+ n = g_menu_model_get_n_items(model);
2527+ }
2528+
2529+ // keep a ref so that it stays activated
2530+ menu_references = g_slist_prepend(menu_references, g_object_ref(model));
2531+
2532+ g_signal_connect(model, "items-changed", G_CALLBACK(on_items_changed), &any_item_changed);
2533+
2534+ // recurse
2535+ for (int i = 0; i < n; ++i)
2536+ {
2537+ GMenuModel* link;
2538+ GMenuLinkIter* iter = g_menu_model_iterate_item_links(model, i);
2539+ while (g_menu_link_iter_get_next(iter, nullptr, &link))
2540+ {
2541+ activate_subtree(link);
2542+ g_object_unref(link);
2543+ }
2544+ g_clear_object(&iter);
2545+ }
2546+ }
2547+
2548+ void sync_menu(void)
2549+ {
2550+ g_slist_free_full(menu_references, GDestroyNotify(g_object_unref));
2551+ menu_references = nullptr;
2552+ activate_subtree(G_MENU_MODEL(menu_model));
2553+ }
2554+
2555+ GDBusMenuModel* menu_model;
2556+ GDBusActionGroup* action_group;
2557+ GTimer* timer;
2558+
2559+ virtual void setup_service() = 0;
2560+ virtual void teardown_service() = 0;
2561+
2562+ virtual void SetUp()
2563+ {
2564+ super::SetUp();
2565+
2566+ menu_references = nullptr;
2567+ any_item_changed = FALSE;
2568+
2569+ timer = g_timer_new();
2570+
2571+ // Start an IndicatorSessionService and wait for it to appear on the bus.
2572+ setup_service();
2573+ const guint watch_id = g_bus_watch_name_on_connection(conn, INDICATOR_BUS_NAME, G_BUS_NAME_WATCHER_FLAGS_NONE,
2574+ on_name_appeared, // quits the loop
2575+ nullptr, this, nullptr);
2576+ const guint timer_id = g_timeout_add_seconds(TIME_LIMIT_SEC, GSourceFunc(g_main_loop_quit), loop);
2577+ g_main_loop_run(loop);
2578+ g_source_remove(timer_id);
2579+ g_bus_unwatch_name(watch_id);
2580+ ASSERT_FALSE(times_up());
2581+
2582+ // get the actions & menus that the service exported.
2583+ action_group = g_dbus_action_group_get(conn, INDICATOR_BUS_NAME, INDICATOR_OBJECT_PATH);
2584+ menu_model = g_dbus_menu_model_get(conn, INDICATOR_BUS_NAME, INDICATOR_OBJECT_PATH "/" INDICATOR_PROFILE);
2585+ // the actions are added asynchronously, so wait for the actions
2586+ if (!g_action_group_has_action(G_ACTION_GROUP(action_group), INDICATOR_PROFILE "-header"))
2587+ {
2588+ wait_for_signal(action_group, "action-added");
2589+ }
2590+ // activate all the groups in the menu so it'll be ready when we need it
2591+ g_signal_connect(menu_model, "items-changed", G_CALLBACK(on_items_changed), &any_item_changed);
2592+ sync_menu();
2593+ }
2594+
2595+ virtual void TearDown()
2596+ {
2597+ g_clear_pointer(&timer, g_timer_destroy);
2598+
2599+ g_slist_free_full(menu_references, GDestroyNotify(g_object_unref));
2600+ menu_references = nullptr;
2601+ g_clear_object(&menu_model);
2602+
2603+ g_clear_object(&action_group);
2604+ teardown_service();
2605+ wait_msec(100);
2606+
2607+ super::TearDown();
2608+ }
2609+
2610+private:
2611+ bool times_up() const
2612+ {
2613+ return g_timer_elapsed(timer, nullptr) >= TIME_LIMIT_SEC;
2614+ }
2615+
2616+protected:
2617+ void wait_for_has_action(const char* name)
2618+ {
2619+ while (!g_action_group_has_action(G_ACTION_GROUP(action_group), name) && !times_up())
2620+ {
2621+ wait_msec(50);
2622+ }
2623+
2624+ ASSERT_FALSE(times_up());
2625+ ASSERT_TRUE(g_action_group_has_action(G_ACTION_GROUP(action_group), name));
2626+ }
2627+
2628+ void wait_for_menu_resync(void)
2629+ {
2630+ any_item_changed = false;
2631+ while (!times_up() && !any_item_changed)
2632+ {
2633+ wait_msec(50);
2634+ }
2635+ g_warn_if_fail(any_item_changed);
2636+ sync_menu();
2637+ }
2638+
2639+ void wait_for_action_state_change(const gchar* action_name)
2640+ {
2641+ gchar* signal_name = g_strdup_printf("action-state-changed::%s", action_name);
2642+ wait_for_signal(action_group, signal_name);
2643+ g_free(signal_name);
2644+ }
2645+
2646+ void wait_for_action_enabled_change(const gchar* action_name)
2647+ {
2648+ gchar* signal_name = g_strdup_printf("action-enabled-changed::%s", action_name);
2649+ wait_for_signal(action_group, signal_name);
2650+ g_free(signal_name);
2651+ }
2652+
2653+protected:
2654+ bool find_menu_item_for_action(const char* action_key, GMenuModel** setme, int* item_index)
2655+ {
2656+ bool success = false;
2657+
2658+ for (GSList* l = menu_references; !success && (l != nullptr); l = l->next)
2659+ {
2660+ GMenuModel* mm = G_MENU_MODEL(l->data);
2661+ const int n = g_menu_model_get_n_items(mm);
2662+
2663+ for (int i = 0; !success && i < n; ++i)
2664+ {
2665+ char* action = nullptr;
2666+ if (!g_menu_model_get_item_attribute(mm, i, G_MENU_ATTRIBUTE_ACTION, "s", &action))
2667+ {
2668+ continue;
2669+ }
2670+
2671+ if ((success = !g_strcmp0(action, action_key)))
2672+ {
2673+ if (setme != nullptr)
2674+ {
2675+ *setme = G_MENU_MODEL(g_object_ref(G_OBJECT(mm)));
2676+ }
2677+
2678+ if (item_index != nullptr)
2679+ {
2680+ *item_index = i;
2681+ }
2682+ }
2683+
2684+ g_free(action);
2685+ }
2686+ }
2687+
2688+ return success;
2689+ }
2690+
2691+ bool action_exists(const char* action_name)
2692 {
2693 #if 0
2694- gchar ** actions = g_action_group_list_actions (G_ACTION_GROUP (action_group));
2695- for (int i=0; actions && actions[i]; i++)
2696- g_message ("[%d][%s]", i, actions[i]);
2697+ gchar** actions = g_action_group_list_actions (G_ACTION_GROUP (action_group));
2698+ for (int i=0; actions && actions[i]; i++)
2699+ {
2700+ g_message ("[%d][%s]", i, actions[i]);
2701+ }
2702 #endif
2703
2704- return g_action_group_has_action (G_ACTION_GROUP(action_group), action_name);
2705- }
2706-
2707- bool action_menuitem_exists (const char * action_name)
2708- {
2709- bool found;
2710- GMenuModel * model = nullptr;
2711- int pos = -1;
2712-
2713- if ((found = find_menu_item_for_action (action_name, &model, &pos)))
2714- g_object_unref (G_OBJECT(model));
2715-
2716- return found;
2717- }
2718-
2719- void check_header (const char * expected_label, const char * expected_icon, const char * expected_a11y)
2720- {
2721- GVariant * variant;
2722- const gchar * label = nullptr;
2723- const gchar * icon = nullptr;
2724- const gchar * a11y = nullptr;
2725- gboolean visible;
2726-
2727- variant = g_action_group_get_action_state (G_ACTION_GROUP(action_group), "_header");
2728- g_variant_get (variant, "(&s&s&sb)", &label, &icon, &a11y, &visible);
2729-
2730- if (expected_label != nullptr)
2731- ASSERT_STREQ (expected_label, label);
2732-
2733- if (expected_icon != nullptr)
2734- ASSERT_STREQ (expected_icon, icon);
2735-
2736- if (expected_a11y != nullptr)
2737- ASSERT_STREQ (expected_a11y, a11y);
2738-
2739- // the session menu is always visible...
2740- ASSERT_TRUE (visible);
2741-
2742- g_variant_unref (variant);
2743- }
2744-
2745- void check_label (const char * expected_label, GMenuModel * model, int pos)
2746- {
2747- char * label = nullptr;
2748- ASSERT_TRUE (g_menu_model_get_item_attribute (model, pos, G_MENU_ATTRIBUTE_LABEL, "s", &label));
2749- ASSERT_STREQ (expected_label, label);
2750- g_free (label);
2751+ return g_action_group_has_action(G_ACTION_GROUP(action_group), action_name);
2752+ }
2753+
2754+ bool action_menuitem_exists(const char* action_name)
2755+ {
2756+ bool found;
2757+ GMenuModel* model = nullptr;
2758+ int pos = -1;
2759+
2760+ if ((found = find_menu_item_for_action(action_name, &model, &pos)))
2761+ {
2762+ g_object_unref(G_OBJECT(model));
2763+ }
2764+
2765+ return found;
2766+ }
2767+
2768+ void check_header(const char* expected_label, const char* expected_icon, const char* expected_a11y)
2769+ {
2770+ GVariant* variant;
2771+ const gchar* label = nullptr;
2772+ const gchar* icon = nullptr;
2773+ const gchar* a11y = nullptr;
2774+ gboolean visible;
2775+
2776+ variant = g_action_group_get_action_state(G_ACTION_GROUP(action_group), "_header");
2777+ g_variant_get(variant, "(&s&s&sb)", &label, &icon, &a11y, &visible);
2778+
2779+ if (expected_label != nullptr)
2780+ {
2781+ ASSERT_STREQ(expected_label, label);
2782+ }
2783+
2784+ if (expected_icon != nullptr)
2785+ {
2786+ ASSERT_STREQ(expected_icon, icon);
2787+ }
2788+
2789+ if (expected_a11y != nullptr)
2790+ {
2791+ ASSERT_STREQ(expected_a11y, a11y);
2792+ }
2793+
2794+ // the session menu is always visible...
2795+ ASSERT_TRUE(visible);
2796+
2797+ g_variant_unref(variant);
2798+ }
2799+
2800+ void check_label(const char* expected_label, GMenuModel* model, int pos)
2801+ {
2802+ char* label = nullptr;
2803+ ASSERT_TRUE(g_menu_model_get_item_attribute(model, pos, G_MENU_ATTRIBUTE_LABEL, "s", &label));
2804+ ASSERT_STREQ(expected_label, label);
2805+ g_free(label);
2806 }
2807 };
2808
2809=== modified file 'tests/phone-test.cc'
2810--- tests/phone-test.cc 2016-01-22 20:08:44 +0000
2811+++ tests/phone-test.cc 2016-01-22 20:08:44 +0000
2812@@ -1,5 +1,5 @@
2813 /*
2814- * Copyright 2013 Canonical Ltd.
2815+ * Copyright 2013-2016 Canonical Ltd.
2816 *
2817 * This program is free software; you can redistribute it and/or modify
2818 * it under the terms of the GNU General Public License as published by
2819@@ -25,10 +25,9 @@
2820 #include "src/dbus-shared.h"
2821 #include "src/service.h"
2822
2823-class PhoneTest: public GTestDBusIndicatorFixture
2824+class PhoneTest : public GTestDBusIndicatorFixture
2825 {
2826- protected:
2827-
2828+protected:
2829 bool loc_enabled;
2830 bool loc_enabled_changed;
2831 bool gps_enabled;
2832@@ -38,330 +37,327 @@
2833 std::shared_ptr<Service> myService;
2834 std::vector<core::ScopedConnection> myConnections;
2835
2836- public:
2837-
2838- void clear_callbacks ()
2839- {
2840- gps_enabled = false;
2841- gps_enabled_changed = false;
2842- loc_enabled = false;
2843- loc_enabled_changed = false;
2844- }
2845-
2846- virtual void on_gps_enabled_changed (bool is_enabled)
2847- {
2848- gps_enabled_changed = true;
2849- gps_enabled = is_enabled;
2850- }
2851-
2852- virtual void on_location_service_enabled_changed (bool is_enabled)
2853- {
2854- loc_enabled_changed = true;
2855- loc_enabled = is_enabled;
2856- }
2857-
2858- protected:
2859-
2860- virtual void SetUp ()
2861- {
2862- GTestDBusIndicatorFixture :: SetUp ();
2863-
2864- clear_callbacks ();
2865- }
2866-
2867- virtual void setup_service ()
2868- {
2869- myController.reset (new MockController ());
2870- myService.reset (new Service (myController));
2871-
2872- myConnections.push_back(
2873- myController->gps_enabled().changed().connect([this](bool enabled){
2874- gps_enabled_changed = true;
2875- gps_enabled = enabled;
2876- })
2877- );
2878-
2879- myConnections.push_back(
2880- myController->location_service_enabled().changed().connect([this](bool enabled){
2881- loc_enabled_changed = true;
2882- loc_enabled = enabled;
2883- })
2884- );
2885- }
2886-
2887- virtual void teardown_service ()
2888- {
2889- myService.reset ();
2890- myConnections.clear ();
2891- myController.reset ();
2892+public:
2893+ void clear_callbacks()
2894+ {
2895+ gps_enabled = false;
2896+ gps_enabled_changed = false;
2897+ loc_enabled = false;
2898+ loc_enabled_changed = false;
2899+ }
2900+
2901+ virtual void on_gps_enabled_changed(bool is_enabled)
2902+ {
2903+ gps_enabled_changed = true;
2904+ gps_enabled = is_enabled;
2905+ }
2906+
2907+ virtual void on_location_service_enabled_changed(bool is_enabled)
2908+ {
2909+ loc_enabled_changed = true;
2910+ loc_enabled = is_enabled;
2911+ }
2912+
2913+protected:
2914+ virtual void SetUp()
2915+ {
2916+ GTestDBusIndicatorFixture::SetUp();
2917+
2918+ clear_callbacks();
2919+ }
2920+
2921+ virtual void setup_service()
2922+ {
2923+ myController.reset(new MockController());
2924+ myService.reset(new Service(myController));
2925+
2926+ myConnections.push_back(myController->gps_enabled().changed().connect([this](bool enabled)
2927+ {
2928+ gps_enabled_changed = true;
2929+ gps_enabled = enabled;
2930+ }));
2931+
2932+ myConnections.push_back(myController->location_service_enabled().changed().connect([this](bool enabled)
2933+ {
2934+ loc_enabled_changed =
2935+ true;
2936+ loc_enabled = enabled;
2937+ }));
2938+ }
2939+
2940+ virtual void teardown_service()
2941+ {
2942+ myService.reset();
2943+ myConnections.clear();
2944+ myController.reset();
2945 }
2946 };
2947
2948-TEST_F (PhoneTest, ActionsExit)
2949-{
2950- ASSERT_TRUE (action_exists ("gps-detection-enabled"));
2951- ASSERT_TRUE (action_exists ("location-detection-enabled"));
2952- ASSERT_TRUE (action_exists ("phone-header"));
2953- ASSERT_TRUE (action_exists ("settings"));
2954-}
2955-
2956-TEST_F (PhoneTest, MenuitemsExist)
2957-{
2958- ASSERT_TRUE (action_menuitem_exists ("indicator.location-detection-enabled"));
2959- ASSERT_FALSE (action_menuitem_exists ("indicator.gps-detection-enabled"));
2960- ASSERT_TRUE (action_menuitem_exists ("indicator.settings"));
2961-}
2962-
2963-TEST_F (PhoneTest, IsValidEnabled)
2964-{
2965- bool is_valid = myController->is_valid().get();
2966- auto ag = G_ACTION_GROUP(action_group);
2967- constexpr int n_iters = 4;
2968- const std::array<const char*,2> action_names = { "gps-detection-enabled",
2969- "location-detection-enabled" };
2970-
2971- // test that the loc/gps actions are enabled/disabled based on controller->is_valid()
2972- for (int i=0; i<n_iters; ++i)
2973- {
2974- is_valid = !is_valid;
2975- myController->is_valid().set(is_valid);
2976- wait_for_action_enabled_change(action_names[0]);
2977- for(const auto& action_name : action_names)
2978- {
2979- EXPECT_EQ(is_valid, g_action_group_get_action_enabled(ag, action_name));
2980- }
2981- }
2982-}
2983-
2984-TEST_F (PhoneTest, IsValidVisible)
2985-{
2986- // make sure something's enabled so that the indicator should be visible
2987- if (!myController->location_service_enabled().get()) {
2988- myController->set_location_service_enabled(true);
2989- wait_for_action_state_change("location-detection-enabled");
2990- }
2991-
2992- // test the header's 'invisible' entry tracks the controller's is_valid() state
2993- constexpr int n_iters = 4;
2994- const char* header_action_name = INDICATOR_PROFILE "-header";
2995- auto ag = G_ACTION_GROUP(action_group);
2996- for (int i=0; i<n_iters; ++i)
2997- {
2998- myController->is_valid().set(!myController->is_valid().get());
2999- wait_for_action_state_change(header_action_name);
3000-
3001- auto dict = g_action_group_get_action_state(ag, header_action_name);
3002+TEST_F(PhoneTest, ActionsExit)
3003+{
3004+ ASSERT_TRUE(action_exists("gps-detection-enabled"));
3005+ ASSERT_TRUE(action_exists("location-detection-enabled"));
3006+ ASSERT_TRUE(action_exists("phone-header"));
3007+ ASSERT_TRUE(action_exists("settings"));
3008+}
3009+
3010+TEST_F(PhoneTest, MenuitemsExist)
3011+{
3012+ ASSERT_TRUE(action_menuitem_exists("indicator.location-detection-enabled"));
3013+ ASSERT_FALSE(action_menuitem_exists("indicator.gps-detection-enabled"));
3014+ ASSERT_TRUE(action_menuitem_exists("indicator.settings"));
3015+}
3016+
3017+TEST_F(PhoneTest, IsValidEnabled)
3018+{
3019+ bool is_valid = myController->is_valid().get();
3020+ auto ag = G_ACTION_GROUP(action_group);
3021+ constexpr int n_iters = 4;
3022+ const std::array<const char*, 2> action_names = {"gps-detection-enabled", "location-detection-enabled"};
3023+
3024+ // test that the loc/gps actions are enabled/disabled based on controller->is_valid()
3025+ for (int i = 0; i < n_iters; ++i)
3026+ {
3027+ is_valid = !is_valid;
3028+ myController->is_valid().set(is_valid);
3029+ wait_for_action_enabled_change(action_names[0]);
3030+ for (const auto& action_name : action_names)
3031+ {
3032+ EXPECT_EQ(is_valid, g_action_group_get_action_enabled(ag, action_name));
3033+ }
3034+ }
3035+}
3036+
3037+TEST_F(PhoneTest, IsValidVisible)
3038+{
3039+ // make sure something's enabled so that the indicator should be visible
3040+ if (!myController->location_service_enabled().get())
3041+ {
3042+ myController->set_location_service_enabled(true);
3043+ wait_for_action_state_change("location-detection-enabled");
3044+ }
3045+
3046+ // test the header's 'invisible' entry tracks the controller's is_valid() state
3047+ constexpr int n_iters = 4;
3048+ const char* header_action_name = INDICATOR_PROFILE "-header";
3049+ auto ag = G_ACTION_GROUP(action_group);
3050+ for (int i = 0; i < n_iters; ++i)
3051+ {
3052+ myController->is_valid().set(!myController->is_valid().get());
3053+ wait_for_action_state_change(header_action_name);
3054+
3055+ auto dict = g_action_group_get_action_state(ag, header_action_name);
3056+ EXPECT_TRUE(dict != nullptr);
3057+ EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
3058+ auto v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN);
3059+ EXPECT_TRUE(v != nullptr);
3060+ EXPECT_EQ(myController->is_valid().get(), g_variant_get_boolean(v));
3061+ g_clear_pointer(&v, g_variant_unref);
3062+ g_clear_pointer(&dict, g_variant_unref);
3063+ }
3064+}
3065+
3066+TEST_F(PhoneTest, PlatformTogglesGPS)
3067+{
3068+ bool enabled;
3069+ const char* const key = "gps-detection-enabled";
3070+ GActionGroup* ag = G_ACTION_GROUP(action_group);
3071+ GVariant* v;
3072+
3073+ // check that the current state is the default value of 'false'
3074+ v = g_action_group_get_action_state(ag, key);
3075+ ASSERT_TRUE(v != nullptr);
3076+ enabled = g_variant_get_boolean(v);
3077+ g_variant_unref(v);
3078+ ASSERT_FALSE(enabled);
3079+
3080+ // confirm that toggling the mock controller's GPS is reflected in the action state
3081+ for (int i = 0; i < 4; i++)
3082+ {
3083+ enabled = !enabled;
3084+
3085+ myController->set_gps_enabled(enabled);
3086+ wait_for_action_state_change(key);
3087+ v = g_action_group_get_action_state(ag, key);
3088+ ASSERT_TRUE(v != nullptr);
3089+ ASSERT_EQ(enabled, g_variant_get_boolean(v));
3090+ g_variant_unref(v);
3091+ }
3092+}
3093+
3094+TEST_F(PhoneTest, UserTogglesGPS)
3095+{
3096+ bool enabled;
3097+ const char* const key = "gps-detection-enabled";
3098+ GActionGroup* ag = G_ACTION_GROUP(action_group);
3099+ GVariant* v;
3100+
3101+ // check that the current state is the default value of 'false'
3102+ v = g_action_group_get_action_state(ag, key);
3103+ ASSERT_TRUE(v != nullptr);
3104+ enabled = g_variant_get_boolean(v);
3105+ g_variant_unref(v);
3106+ ASSERT_FALSE(enabled);
3107+
3108+ // confirm that toggling menu updates the controller
3109+ for (int i = 0; i < 4; i++)
3110+ {
3111+ clear_callbacks();
3112+
3113+ g_action_group_activate_action(ag, key, nullptr);
3114+ while (!gps_enabled_changed)
3115+ {
3116+ wait_msec(50);
3117+ }
3118+
3119+ ASSERT_TRUE(gps_enabled_changed);
3120+ enabled = !enabled;
3121+ ASSERT_EQ(enabled, gps_enabled);
3122+ }
3123+}
3124+
3125+TEST_F(PhoneTest, PlatformTogglesLocation)
3126+{
3127+ bool enabled;
3128+ const char* const key = "location-detection-enabled";
3129+ GActionGroup* ag = G_ACTION_GROUP(action_group);
3130+ GVariant* v;
3131+
3132+ // check that the current state is the default value of 'false'
3133+ v = g_action_group_get_action_state(ag, key);
3134+ ASSERT_TRUE(v != nullptr);
3135+ enabled = g_variant_get_boolean(v);
3136+ g_variant_unref(v);
3137+ ASSERT_FALSE(enabled);
3138+
3139+ // confirm that toggling the mock controller's GPS is reflected in the action state
3140+ for (int i = 0; i < 4; i++)
3141+ {
3142+ enabled = !enabled;
3143+
3144+ myController->set_location_service_enabled(enabled);
3145+ wait_for_action_state_change(key);
3146+ v = g_action_group_get_action_state(ag, key);
3147+ ASSERT_TRUE(v != nullptr);
3148+ ASSERT_EQ(enabled, g_variant_get_boolean(v));
3149+ g_variant_unref(v);
3150+ }
3151+}
3152+
3153+TEST_F(PhoneTest, UserTogglesLocation)
3154+{
3155+ bool enabled;
3156+ const char* const key = "location-detection-enabled";
3157+ GActionGroup* ag = G_ACTION_GROUP(action_group);
3158+ GVariant* v;
3159+
3160+ // check that the current state is the default value of 'false'
3161+ v = g_action_group_get_action_state(ag, key);
3162+ ASSERT_TRUE(v != nullptr);
3163+ enabled = g_variant_get_boolean(v);
3164+ g_variant_unref(v);
3165+ ASSERT_FALSE(enabled);
3166+
3167+ // confirm that toggling menu updates the controller
3168+ for (int i = 0; i < 4; i++)
3169+ {
3170+ clear_callbacks();
3171+
3172+ g_action_group_activate_action(ag, key, nullptr);
3173+ while (!loc_enabled_changed)
3174+ {
3175+ wait_msec(50);
3176+ }
3177+
3178+ ASSERT_TRUE(loc_enabled_changed);
3179+ enabled = !enabled;
3180+ ASSERT_EQ(enabled, loc_enabled);
3181+ }
3182+}
3183+
3184+TEST_F(PhoneTest, Header)
3185+{
3186+ wait_msec();
3187+
3188+ auto connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
3189+
3190+ // SETUP: get the action group and wait for it to be populated
3191+ auto dbus_action_group = g_dbus_action_group_get(connection, INDICATOR_BUS_NAME, INDICATOR_OBJECT_PATH);
3192+ auto action_group = G_ACTION_GROUP(dbus_action_group);
3193+ auto names_strv = g_action_group_list_actions(action_group);
3194+ if (g_strv_length(names_strv) == 0)
3195+ {
3196+ g_strfreev(names_strv);
3197+ wait_for_signal(dbus_action_group, "action-added");
3198+ names_strv = g_action_group_list_actions(action_group);
3199+ }
3200+ g_clear_pointer(&names_strv, g_strfreev);
3201+
3202+ // SETUP: get the menu model and wait for it to be activated
3203+ auto dbus_menu_model =
3204+ g_dbus_menu_model_get(connection, INDICATOR_BUS_NAME, INDICATOR_OBJECT_PATH "/" INDICATOR_PROFILE);
3205+ auto menu_model = G_MENU_MODEL(dbus_menu_model);
3206+ int n = g_menu_model_get_n_items(menu_model);
3207+ if (!n)
3208+ {
3209+ // give the model a moment to populate its info
3210+ wait_msec(100);
3211+ n = g_menu_model_get_n_items(menu_model);
3212+ }
3213+ EXPECT_TRUE(menu_model != nullptr);
3214+ EXPECT_NE(0, n);
3215+
3216+ // test to confirm that a header menuitem exists
3217+ gchar* str = nullptr;
3218+ g_menu_model_get_item_attribute(menu_model, 0, "x-canonical-type", "s", &str);
3219+ EXPECT_STREQ("com.canonical.indicator.root", str);
3220+ g_clear_pointer(&str, g_free);
3221+ g_menu_model_get_item_attribute(menu_model, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str);
3222+ const auto action_name = INDICATOR_PROFILE "-header";
3223+ EXPECT_EQ(std::string("indicator.") + action_name, str);
3224+ g_clear_pointer(&str, g_free);
3225+
3226+ // cursory first look at the header
3227+ auto dict = g_action_group_get_action_state(action_group, action_name);
3228 EXPECT_TRUE(dict != nullptr);
3229 EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
3230- auto v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN);
3231- EXPECT_TRUE(v != nullptr);
3232- EXPECT_EQ(myController->is_valid().get(), g_variant_get_boolean(v));
3233+ auto v = g_variant_lookup_value(dict, "accessible-desc", G_VARIANT_TYPE_STRING);
3234+ EXPECT_TRUE(v != nullptr);
3235+ g_variant_unref(v);
3236+ v = g_variant_lookup_value(dict, "title", G_VARIANT_TYPE_STRING);
3237+ EXPECT_TRUE(v != nullptr);
3238+ g_variant_unref(v);
3239+ v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN);
3240+ EXPECT_TRUE(v != nullptr);
3241 g_clear_pointer(&v, g_variant_unref);
3242 g_clear_pointer(&dict, g_variant_unref);
3243- }
3244-}
3245-
3246-TEST_F (PhoneTest, PlatformTogglesGPS)
3247-{
3248- bool enabled;
3249- const char * const key = "gps-detection-enabled";
3250- GActionGroup * ag = G_ACTION_GROUP (action_group);
3251- GVariant * v;
3252-
3253- // check that the current state is the default value of 'false'
3254- v = g_action_group_get_action_state (ag, key);
3255- ASSERT_TRUE (v != nullptr);
3256- enabled = g_variant_get_boolean (v);
3257- g_variant_unref (v);
3258- ASSERT_FALSE (enabled);
3259-
3260- // confirm that toggling the mock controller's GPS is reflected in the action state
3261- for (int i=0; i<4; i++)
3262- {
3263- enabled = !enabled;
3264-
3265- myController->set_gps_enabled (enabled);
3266- wait_for_action_state_change (key);
3267- v = g_action_group_get_action_state (ag, key);
3268- ASSERT_TRUE (v != nullptr);
3269- ASSERT_EQ (enabled, g_variant_get_boolean (v));
3270- g_variant_unref (v);
3271- }
3272-}
3273-
3274-TEST_F (PhoneTest, UserTogglesGPS)
3275-{
3276- bool enabled;
3277- const char * const key = "gps-detection-enabled";
3278- GActionGroup * ag = G_ACTION_GROUP (action_group);
3279- GVariant * v;
3280-
3281- // check that the current state is the default value of 'false'
3282- v = g_action_group_get_action_state (ag, key);
3283- ASSERT_TRUE (v != nullptr);
3284- enabled = g_variant_get_boolean (v);
3285- g_variant_unref (v);
3286- ASSERT_FALSE (enabled);
3287-
3288- // confirm that toggling menu updates the controller
3289- for (int i=0; i<4; i++)
3290- {
3291- clear_callbacks ();
3292-
3293- g_action_group_activate_action (ag, key, nullptr);
3294- while (!gps_enabled_changed)
3295- wait_msec (50);
3296-
3297- ASSERT_TRUE (gps_enabled_changed);
3298- enabled = !enabled;
3299- ASSERT_EQ (enabled, gps_enabled);
3300- }
3301-}
3302-
3303-TEST_F (PhoneTest, PlatformTogglesLocation)
3304-{
3305- bool enabled;
3306- const char * const key = "location-detection-enabled";
3307- GActionGroup * ag = G_ACTION_GROUP (action_group);
3308- GVariant * v;
3309-
3310- // check that the current state is the default value of 'false'
3311- v = g_action_group_get_action_state (ag, key);
3312- ASSERT_TRUE (v != nullptr);
3313- enabled = g_variant_get_boolean (v);
3314- g_variant_unref (v);
3315- ASSERT_FALSE (enabled);
3316-
3317- // confirm that toggling the mock controller's GPS is reflected in the action state
3318- for (int i=0; i<4; i++)
3319- {
3320- enabled = !enabled;
3321-
3322- myController->set_location_service_enabled (enabled);
3323- wait_for_action_state_change (key);
3324- v = g_action_group_get_action_state (ag, key);
3325- ASSERT_TRUE (v != nullptr);
3326- ASSERT_EQ (enabled, g_variant_get_boolean (v));
3327- g_variant_unref (v);
3328- }
3329-}
3330-
3331-TEST_F (PhoneTest, UserTogglesLocation)
3332-{
3333- bool enabled;
3334- const char * const key = "location-detection-enabled";
3335- GActionGroup * ag = G_ACTION_GROUP (action_group);
3336- GVariant * v;
3337-
3338- // check that the current state is the default value of 'false'
3339- v = g_action_group_get_action_state (ag, key);
3340- ASSERT_TRUE (v != nullptr);
3341- enabled = g_variant_get_boolean (v);
3342- g_variant_unref (v);
3343- ASSERT_FALSE (enabled);
3344-
3345- // confirm that toggling menu updates the controller
3346- for (int i=0; i<4; i++)
3347- {
3348- clear_callbacks ();
3349-
3350- g_action_group_activate_action (ag, key, nullptr);
3351- while (!loc_enabled_changed)
3352- wait_msec (50);
3353-
3354- ASSERT_TRUE (loc_enabled_changed);
3355- enabled = !enabled;
3356- ASSERT_EQ (enabled, loc_enabled);
3357- }
3358-}
3359-
3360-TEST_F (PhoneTest, Header)
3361-{
3362- wait_msec();
3363-
3364- auto connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr);
3365-
3366- // SETUP: get the action group and wait for it to be populated
3367- auto dbus_action_group = g_dbus_action_group_get(connection, INDICATOR_BUS_NAME, INDICATOR_OBJECT_PATH);
3368- auto action_group = G_ACTION_GROUP(dbus_action_group);
3369- auto names_strv = g_action_group_list_actions(action_group);
3370- if (g_strv_length(names_strv) == 0)
3371- {
3372- g_strfreev(names_strv);
3373- wait_for_signal(dbus_action_group, "action-added");
3374- names_strv = g_action_group_list_actions(action_group);
3375- }
3376- g_clear_pointer(&names_strv, g_strfreev);
3377-
3378- // SETUP: get the menu model and wait for it to be activated
3379- auto dbus_menu_model = g_dbus_menu_model_get(connection, INDICATOR_BUS_NAME, INDICATOR_OBJECT_PATH "/" INDICATOR_PROFILE);
3380- auto menu_model = G_MENU_MODEL(dbus_menu_model);
3381- int n = g_menu_model_get_n_items(menu_model);
3382- if (!n)
3383- {
3384- // give the model a moment to populate its info
3385- wait_msec(100);
3386- n = g_menu_model_get_n_items(menu_model);
3387- }
3388- EXPECT_TRUE(menu_model != nullptr);
3389- EXPECT_NE(0, n);
3390-
3391- // test to confirm that a header menuitem exists
3392- gchar* str = nullptr;
3393- g_menu_model_get_item_attribute(menu_model, 0, "x-canonical-type", "s", &str);
3394- EXPECT_STREQ("com.canonical.indicator.root", str);
3395- g_clear_pointer(&str, g_free);
3396- g_menu_model_get_item_attribute(menu_model, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str);
3397- const auto action_name = INDICATOR_PROFILE "-header";
3398- EXPECT_EQ(std::string("indicator.")+action_name, str);
3399- g_clear_pointer(&str, g_free);
3400-
3401- // cursory first look at the header
3402- auto dict = g_action_group_get_action_state(action_group, action_name);
3403- EXPECT_TRUE(dict != nullptr);
3404- EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
3405- auto v = g_variant_lookup_value(dict, "accessible-desc", G_VARIANT_TYPE_STRING);
3406- EXPECT_TRUE(v != nullptr);
3407- g_variant_unref(v);
3408- v = g_variant_lookup_value(dict, "title", G_VARIANT_TYPE_STRING);
3409- EXPECT_TRUE(v != nullptr);
3410- g_variant_unref(v);
3411- v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN);
3412- EXPECT_TRUE(v != nullptr);
3413- g_clear_pointer(&v, g_variant_unref);
3414- g_clear_pointer(&dict, g_variant_unref);
3415-
3416- // test visibility states
3417- struct {
3418- bool gps_enabled;
3419- bool location_service_enabled;
3420- bool expected_visible;
3421- } visibility_tests[] = {
3422- { false, false, false },
3423- { true, false, false },
3424- { false, true, true },
3425- { true, true, true }
3426- };
3427- for (const auto& test : visibility_tests)
3428- {
3429- myController->set_gps_enabled(test.gps_enabled);
3430- myController->set_location_service_enabled(test.location_service_enabled);
3431- wait_msec();
3432-
3433- // cusory first look at the header
3434- dict = g_action_group_get_action_state(action_group, action_name);
3435- EXPECT_TRUE(dict != nullptr);
3436- EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
3437- v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN);
3438- EXPECT_TRUE(v != nullptr);
3439- EXPECT_EQ(test.expected_visible, g_variant_get_boolean(v));
3440- g_clear_pointer(&v, g_variant_unref);
3441- g_clear_pointer(&dict, g_variant_unref);
3442- }
3443-
3444- // cleanup
3445- g_clear_object(&action_group);
3446- g_clear_object(&dbus_menu_model);
3447- g_clear_object(&connection);
3448-}
3449-
3450+
3451+ // test visibility states
3452+ struct
3453+ {
3454+ bool gps_enabled;
3455+ bool location_service_enabled;
3456+ bool expected_visible;
3457+ } visibility_tests[] = {{false, false, false}, {true, false, false}, {false, true, true}, {true, true, true}};
3458+ for (const auto& test : visibility_tests)
3459+ {
3460+ myController->set_gps_enabled(test.gps_enabled);
3461+ myController->set_location_service_enabled(test.location_service_enabled);
3462+ wait_msec();
3463+
3464+ // cusory first look at the header
3465+ dict = g_action_group_get_action_state(action_group, action_name);
3466+ EXPECT_TRUE(dict != nullptr);
3467+ EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT));
3468+ v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN);
3469+ EXPECT_TRUE(v != nullptr);
3470+ EXPECT_EQ(test.expected_visible, g_variant_get_boolean(v));
3471+ g_clear_pointer(&v, g_variant_unref);
3472+ g_clear_pointer(&dict, g_variant_unref);
3473+ }
3474+
3475+ // cleanup
3476+ g_clear_object(&action_group);
3477+ g_clear_object(&dbus_menu_model);
3478+ g_clear_object(&connection);
3479+}
3480
3481=== added directory 'tools'
3482=== added file 'tools/CMakeLists.txt'
3483--- tools/CMakeLists.txt 1970-01-01 00:00:00 +0000
3484+++ tools/CMakeLists.txt 2016-01-22 20:08:44 +0000
3485@@ -0,0 +1,1 @@
3486+configure_file(formatcode.in formatcode)
3487
3488=== added file 'tools/format-files.sh'
3489--- tools/format-files.sh 1970-01-01 00:00:00 +0000
3490+++ tools/format-files.sh 2016-01-22 20:08:44 +0000
3491@@ -0,0 +1,49 @@
3492+#!/bin/sh
3493+
3494+# Copyright (C) 2013 Canonical Ltd
3495+#
3496+# This program is free software: you can redistribute it and/or modify
3497+# it under the terms of the GNU Lesser General Public License version 3 as
3498+# published by the Free Software Foundation.
3499+#
3500+# This program is distributed in the hope that it will be useful,
3501+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3502+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3503+# GNU Lesser General Public License for more details.
3504+#
3505+# You should have received a copy of the GNU Lesser General Public License
3506+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3507+#
3508+# Authored by: Michi Henning <michi.henning@canonical.com>
3509+
3510+# Simple script to run the code base through astyle, followed by clang-format (which
3511+# undoes some damage that's done by astyle, without wiping out astyle edits we want
3512+# to happen).
3513+#
3514+# If either program makes a mess of some file such that it won't compile anymore
3515+# or otherwise gets adorned with unacceptable edits, add the file to the list
3516+# of files to filter out (grep -v below).
3517+
3518+usage()
3519+{
3520+ echo usage: format-files project_dir astyle_cmd clang_format_cmd 2>&1
3521+ exit 1
3522+}
3523+
3524+[ $# -ne 3 ] && usage
3525+
3526+dir="$1"
3527+astyle="$2"
3528+format="$3"
3529+
3530+files=`find "$dir" -name '*.h' -o -name '*.cpp' -o -name '*.c' -o -name '*.cc' \
3531+ | grep -v UnityScopesApi_tp.h`
3532+
3533+"$astyle" --options="$dir"/astyle-config -n $files
3534+[ $? -ne 0 ] && exit $?
3535+
3536+# astyle 2.03 writes DOS line endings: https://sourceforge.net/p/astyle/bugs/268/
3537+dos2unix -q $files
3538+
3539+"$format" -i -style=file $files
3540+exit $?
3541
3542=== added file 'tools/format-test.sh'
3543--- tools/format-test.sh 1970-01-01 00:00:00 +0000
3544+++ tools/format-test.sh 2016-01-22 20:08:44 +0000
3545@@ -0,0 +1,44 @@
3546+#!/bin/sh
3547+
3548+# Copyright (C) 2016 Canonical Ltd
3549+#
3550+# This program is free software: you can redistribute it and/or modify
3551+# it under the terms of the GNU Lesser General Public License version 3 as
3552+# published by the Free Software Foundation.
3553+#
3554+# This program is distributed in the hope that it will be useful,
3555+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3556+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3557+# GNU Lesser General Public License for more details.
3558+#
3559+# You should have received a copy of the GNU Lesser General Public License
3560+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3561+
3562+# Tests to see if a file is in the project's format.
3563+
3564+usage()
3565+{
3566+ echo usage: format-test project_dir formatcode 2>&1
3567+ exit 1
3568+}
3569+
3570+[ $# -ne 2 ] && usage
3571+
3572+dir="$1"
3573+formatcode="$2"
3574+
3575+exitval=0
3576+for file in $(find "$dir" -name '*.h' -o -name '*.cpp' -o -name '*.c' -o -name '*.cc' -print0 | xargs -0);
3577+do
3578+ results=$(cat $file | $formatcode | diff -u $file -)
3579+ linecount=$(echo "$var" | wc -l)
3580+ if test $linecount -gt 1
3581+ then
3582+ basecmd=$(basename $0)
3583+ echo "$basecmd FAIL $file"
3584+ echo "${results}"
3585+ exitval=1
3586+ fi
3587+done
3588+
3589+exit $exitval
3590
3591=== added file 'tools/formatcode.in'
3592--- tools/formatcode.in 1970-01-01 00:00:00 +0000
3593+++ tools/formatcode.in 2016-01-22 20:08:44 +0000
3594@@ -0,0 +1,64 @@
3595+#!/bin/sh
3596+
3597+# Copyright (C) 2013 Canonical Ltd
3598+#
3599+# This program is free software: you can redistribute it and/or modify
3600+# it under the terms of the GNU Lesser General Public License version 3 as
3601+# published by the Free Software Foundation.
3602+#
3603+# This program is distributed in the hope that it will be useful,
3604+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3605+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3606+# GNU Lesser General Public License for more details.
3607+#
3608+# You should have received a copy of the GNU Lesser General Public License
3609+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3610+#
3611+# Authored by: Michi Henning <michi.henning@canonical.com>
3612+
3613+# Simple script to format files with astyle, followed by clang-format (which
3614+# undoes some damage that's done by astyle, without wiping out astyle edits we want
3615+# to happen).
3616+#
3617+# usage: formatcode [FILE]...
3618+#
3619+# If no arguments are provided, we format stdin and write to stdout.
3620+
3621+astyle="@ASTYLE_COMMAND@"
3622+format="@CLANG_FORMAT_COMMAND@"
3623+dos2unix="@DOS2UNIX_COMMAND@"
3624+style="@CMAKE_SOURCE_DIR@/_clang-format"
3625+
3626+# Check that the format commands were found.
3627+[ "$astyle" = "ASTYLE_COMMAND-NOTFOUND" -o \
3628+ "$dos2unix" = "DOS2UNIX_COMMAND-NOTFOUND" -o \
3629+ "$format" = "CLANG_FORMAT_COMMAND-NOTFOUND" ] && {
3630+ echo "formatcode: cmake did not find all formatting tools" >&2
3631+ exit 1
3632+}
3633+
3634+# If no arguments were provided, read stdin and write stdout.
3635+# Recent versions of astyle can't read stdin: http://sourceforge.net/p/astyle/bugs/63/
3636+# astyle 2.03 writes DOS line endings: https://sourceforge.net/p/astyle/bugs/268/
3637+[ $# -eq 0 ] && {
3638+ tmpdir=`mktemp -d`
3639+ tmp=`mktemp -p $tmpdir`
3640+ cp "$style" $tmpdir
3641+ cat >$tmp
3642+ cd $tmpdir
3643+ "$astyle" -q --options=@CMAKE_SOURCE_DIR@/astyle-config -n $tmp
3644+ "$dos2unix" -q $tmp
3645+ "$format" -i -style=file $tmp
3646+ cat $tmp
3647+ rm -fr $tmpdir
3648+ exit $?
3649+}
3650+
3651+# Format files in place.
3652+"$astyle" --options=@CMAKE_SOURCE_DIR@/astyle-config -n "$@"
3653+[ $? -ne 0 ] && exit $?
3654+
3655+"$dos2unix" -q "$@"
3656+
3657+"$format" -i -style=file $files "$@"
3658+exit $?

Subscribers

People subscribed via source and target branches