Merge lp:~unity-api-team/indicator-network/indicator-network-cpp into lp:indicator-network/14.10

Proposed by Antti Kaijanmäki
Status: Merged
Approved by: Antti Kaijanmäki
Approved revision: 363
Merged at revision: 328
Proposed branch: lp:~unity-api-team/indicator-network/indicator-network-cpp
Merge into: lp:indicator-network/14.10
Diff against target: 21218 lines (+16387/-4059)
114 files modified
.bzrignore (+3/-12)
CMakeLists.txt (+21/-5)
cmake/FindVala.cmake (+0/-57)
cmake/UseVala.cmake (+0/-241)
config.h.in (+0/-1)
data/com.canonical.indicator.network (+22/-2)
data/indicator-network.conf.in (+4/-1)
debian/control (+17/-1)
debian/indicator-network-autopilot.install (+2/-0)
debian/indicator-network.install (+8/-0)
debian/rules (+16/-3)
network/CMakeLists.txt (+57/-180)
network/action-muxer.c (+0/-501)
network/action-muxer.h (+0/-47)
network/action-muxer.vapi (+0/-10)
network/config.vapi (+0/-8)
network/dbus-cpp/services/ofono.h (+1322/-0)
network/device-base.vala (+0/-245)
network/device-ethernet.vala (+0/-64)
network/device-mobile.vala (+0/-166)
network/device-wifi.vala (+0/-578)
network/glib.supp (+141/-0)
network/indicator-menu.h (+99/-0)
network/indicator-network-service.cpp (+99/-0)
network/menuitems/access-point-item.h (+128/-0)
network/menuitems/item.h (+60/-0)
network/menuitems/section.h (+39/-0)
network/menuitems/switch-item.h (+80/-0)
network/menuitems/text-item.h (+72/-0)
network/menumodel-cpp/CMakeLists.txt (+32/-0)
network/menumodel-cpp/action-group-exporter.h (+93/-0)
network/menumodel-cpp/action-group-merger.h (+147/-0)
network/menumodel-cpp/action-group.h (+92/-0)
network/menumodel-cpp/action.cpp (+129/-0)
network/menumodel-cpp/action.h (+76/-0)
network/menumodel-cpp/gio-helpers/util.cpp (+55/-0)
network/menumodel-cpp/gio-helpers/util.h (+250/-0)
network/menumodel-cpp/gio-helpers/variant.h (+235/-0)
network/menumodel-cpp/menu-exporter.h (+63/-0)
network/menumodel-cpp/menu-item.h (+162/-0)
network/menumodel-cpp/menu-merger.h (+135/-0)
network/menumodel-cpp/menu-model.h (+31/-0)
network/menumodel-cpp/menu.h (+213/-0)
network/mobile-sim-manager.vala (+0/-545)
network/modem-manager.cpp (+194/-0)
network/modem-manager.h (+45/-0)
network/modem.cpp (+289/-0)
network/modem.h (+86/-0)
network/network-action-manager.vala (+0/-654)
network/network-menu-service.vala (+0/-43)
network/network-menu.vala (+0/-283)
network/notify-cpp/notification.cpp (+135/-0)
network/notify-cpp/notification.h (+65/-0)
network/notify-cpp/snapdecision/sim-unlock.cpp (+233/-0)
network/notify-cpp/snapdecision/sim-unlock.h (+78/-0)
network/ofono.vala (+0/-59)
network/quick-access-section.cpp (+96/-0)
network/quick-access-section.h (+41/-0)
network/root-state.cpp (+370/-0)
network/root-state.h (+43/-0)
network/run_valgrind.sh (+5/-0)
network/service.h (+151/-0)
network/settings-airplane.vala (+0/-45)
network/settings-base.vala (+0/-98)
network/settings-wifi.vala (+0/-52)
network/sim-unlock-dialog.cpp (+465/-0)
network/sim-unlock-dialog.h (+60/-0)
network/url-dispatcher-cpp/url-dispatcher.cpp (+44/-0)
network/url-dispatcher-cpp/url-dispatcher.h (+32/-0)
network/url-dispatcher.vapi (+0/-5)
network/util-wrapper.c (+0/-30)
network/util-wrapper.h (+0/-20)
network/util-wrapper.vapi (+0/-5)
network/utils.vala (+0/-23)
network/wifi-link-item.h (+251/-0)
network/wifi-section.cpp (+101/-0)
network/wifi-section.h (+45/-0)
network/wifi-settings.h (+37/-0)
network/wired-link.h (+34/-0)
network/wwan-link-item.cpp (+1019/-0)
network/wwan-link-item.h (+43/-0)
network/wwan-section.cpp (+149/-0)
network/wwan-section.h (+41/-0)
po/POTFILES.in (+0/-11)
po/POTFILES.skip (+0/-11)
secret-agent/PasswordMenu.cpp (+1/-0)
secret-agent/SecretAgent.cpp (+6/-0)
secret-agent/SecretRequest.cpp (+2/-0)
tests/CMakeLists.txt (+5/-51)
tests/autopilot/CMakeLists.txt (+8/-0)
tests/autopilot/README (+8/-0)
tests/autopilot/indicator_network/__init__.py (+17/-0)
tests/autopilot/indicator_network/data/pin-unlock.xml (+3677/-0)
tests/autopilot/indicator_network/helpers/phonesim_manager.py (+94/-0)
tests/autopilot/indicator_network/tests/__init__.py (+17/-0)
tests/autopilot/indicator_network/tests/test_unlock_sim.py (+143/-0)
tests/autopilot/setup.py (+32/-0)
tests/data/CMakeLists.txt (+4/-0)
tests/data/phonesim/pin-unlock.xml (+3677/-0)
tests/integration/CMakeLists.txt (+34/-0)
tests/unit/CMakeLists.txt (+2/-0)
tests/unit/network/CMakeLists.txt (+5/-0)
tests/unit/network/menuitems/CMakeLists.txt (+35/-0)
tests/unit/network/menuitems/test-access-point-item.cpp (+91/-0)
tests/unit/network/menuitems/test-switch-item.cpp (+65/-0)
tests/unit/network/menumodel-cpp/CMakeLists.txt (+34/-0)
tests/unit/network/menumodel-cpp/test-menu-exporter.cpp (+188/-0)
tests/unit/secret-agent/CMakeLists.txt (+50/-0)
tests/unit/secret-agent/TestSecretAgent.cpp (+4/-0)
tests/unit/test_variant.h (+14/-0)
tests/utils/CMakeLists.txt (+14/-0)
tests/utils/action-utils.cpp (+65/-0)
tests/utils/action-utils.h (+40/-0)
tests/utils/main.cpp (+0/-2)
To merge this branch: bzr merge lp:~unity-api-team/indicator-network/indicator-network-cpp
Reviewer Review Type Date Requested Status
Jussi Pakkanen (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+210973@code.launchpad.net

Commit message

C++ service using the connectivity-api.

To post a comment you must log in.
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

not ready yet. I will update the testplan and checklist.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:322
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~unity-api-team/indicator-network/indicator-network-cpp/+merge/210973/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/indicator-network-ci/105/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/indicator-network-trusty-amd64-ci/13/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/indicator-network-trusty-armhf-ci/11/console

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/indicator-network-ci/105/rebuild

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
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (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: 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
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
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
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
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
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
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

interesting..
I thought I was merging my stuff against the branch head, but seemed I merged everyone elses :D
Oh, well. You still have your attributions in the bzr log --include-merges

Revision history for this message
Pete Woods (pete-woods) wrote :

Working at 1:00 am is just as bad as reading your e-mail at 1:00 am :p

Revision history for this message
Charles Kerr (charlesk) wrote :
Download full text (4.9 KiB)

Antti, I this is a big undertaking, now I understand how pete-woods must've felt when I asked him to review indicator datetime-cpp.

Here are some notes I took while reading this morning & this afternoon, I got through some of the build stuff and through the gio utils and gmenu abstraction. This is a long list but most of the bullet points are minor.

The big takeaway I got from what I read today is that I really like these pieces; you should consider extracting them out so that they could be used by other indicators too. I've gone through some of the same questions of "how much of the toolkit pieces should I abstract out?" but menumodel-cpp goes much much further than I did...

* in network/dbus-cpp/services/ofono.h, license is LGPLv3 unlike all the rest of the code

* in COPYING.LGPL, this file should be removed

* in README: still says the system is built with autogen

* in README.widgets is nice. I'm going to steal this a a template. :)

* in debian/control, building still requires valac

* in README.widgets, why do the widgets have an x-canonical-widget-type of 'unity.widgets.systemsettings.${profile}.widgettype' instead of 'com.canonical.indicator.widgettype'?

* In debian/control, indicator-network still conflicts with chewie. Is this line still relevant?

* in CMakeLists.txt, a lot of the pkg_check_modules() + include_directories() pairs are only needed for tests. If they were moved into tests/CMakeLists.txt it would avoid polluting the include path when building the rest of the code

* in CMakeLists.txt, why the duplicate test for gio-2.0>=${GLIB_REQUIRED_VERSION} ?

* in gio-helpers/*, inconsistent use of assert: assert() in variant.h, g_assert() in util.h

* in gio-helpers/* and menumodel-cpp/*, lots header bloat: most of this could be moved into .cpp files

* in gio-helpers/util.h, why #define _(String) instead of including gi18n.h?

* in gio-helpers/util.h, why use std::cerr instead of g_warning()?

* in gio-helpers/util.h, SessionBus::address() should be a const method

* in gio-helpers/util.h, SessionBus::address() the second 'error = NULL' isn't needed

* in gio-helpers/util.h, GMainLoopSync appears to be unused code & can be removed

* in gio-helpers/util.h GMainLoopDispatch::dispatch_cb(), funcPtr should be auto

* in gio-helpers/util.h, SessionBus::SessionBus() should use g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)

* in gio-helpers/variant.h, Variant::as() should be a const method

* in gio-helpers/variant.h, what's the decision process for deciding which methods got the 'inline' keyword?

* in gio-helpers/variant.h, debug messages have leaked into cout. I =hate= this; suggest g_debug() instead

* in gio-helpers/variant.h Codec::vector<Variant>::encode_argument(), "auto value" would be slightly better as "auto& value"

* in gio-helpers/variant.h, #include warts: (1) uses string w/o including it (2) uses std::move() w/o including <utility)

* in menumodel-cpp, lots of use of std::lock_guards, not disagreeing with this but I'm curious about the context -- does i-network have thread contention issues with menus?

* in menumodel-cpp/menu.h, #include warts: (1) includes map w/o using it, (2) includes vector w/o usi...

Read more...

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: 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
Jussi Pakkanen (jpakkane) wrote :

The build failure is caused by building against too old of a connectivity-api (should be connectivity-api/devel).

Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> The build failure is caused by building against too old of a connectivity-api
> (should be connectivity-api/devel).

yes, indeed. the required version of connectivity-api is in the same silo as this MP, and unfortunately that also means that we can't get Jenkins to build the package as it only can fetch packages from the archive.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

I am a rubber stamp.

review: Approve
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> I am a rubber stamp.

So yes, this is basically a new component which has been developed and reviewed as we go. Trying to do a complete code review here is unproductive. Now that this MP has been top-approved we get a silo and can run throughout testing with the packages from the silo.

364. By Antti Kaijanmäki

Fix AP test on the phone and small problem when a wifi password dialog is cancelled.

365. By Antti Kaijanmäki

disconnect gio signals straight away.

366. By Jussi Pakkanen

Use standard gcc.

367. By Jussi Pakkanen

Flag update for Gcc >4.7.

368. By Antti Kaijanmäki

depend on a specific version of libdbus-cpp

369. By Antti Kaijanmäki

depend on a never version of connectivity-api as it too got rebuild with stock gcc.

370. By Antti Kaijanmäki

disable tests on powerpc for now.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2013-08-27 13:48:41 +0000
3+++ .bzrignore 2014-05-14 11:21:27 +0000
4@@ -1,12 +1,3 @@
5-.anjuta*
6-*.anjuta
7-config.h
8-network/network-menu-application.c
9-*/*.la
10-*/*.lo
11-*.tar.gz
12-network/*.c
13-network/*.h
14-network/*.vapi
15-data/com.canonical.settings.network.service
16-data/indicator-network.conf
17+*.autosave
18+CMakeLists.txt.user
19+CMakeLists.txt.user.3.0-pre1
20
21=== modified file 'CMakeLists.txt'
22--- CMakeLists.txt 2013-11-07 11:52:44 +0000
23+++ CMakeLists.txt 2014-05-14 11:21:27 +0000
24@@ -3,16 +3,18 @@
25
26 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
27
28+
29+# combine these two?
30 set(PACKAGE ${CMAKE_PROJECT_NAME})
31 set(GETTEXT_PACKAGE indicator-network)
32 set(LOCALE_DIR "${CMAKE_INSTALL_FULL_DATADIR}/locale")
33
34-add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" )
35+# in config.h
36+#add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" )
37
38 find_package(PkgConfig REQUIRED)
39 include(GNUInstallDirs)
40 include(Coverage)
41-include(UseVala)
42 include(UseGSettings)
43
44 # Workaround for libexecdir on debian
45@@ -41,6 +43,14 @@
46 )
47 include_directories(${NM_INCLUDE_DIRS})
48
49+set(OFONO_REQUIRED_VERSION 1.12)
50+pkg_check_modules(
51+ OFONO REQUIRED
52+ ofono>=${OFONO_REQUIRED_VERSION}
53+)
54+include_directories(${OFONO_INCLUDE_DIRS})
55+
56+
57 set(NOTIFY_REQUIRED_VERSION 0.7.5)
58 pkg_check_modules(
59 NOTIFY REQUIRED
60@@ -48,6 +58,12 @@
61 )
62 include_directories(${NOTIFY_INCLUDE_DIRS})
63
64+pkg_check_modules(
65+ CONNECTIVITY_CPP REQUIRED
66+ connectivity-cpp
67+)
68+include_directories(${CONNECTIVITY_CPP_INCLUDE_DIRS})
69+
70 find_package(Qt5Core REQUIRED)
71 include_directories(${Qt5Core_INCLUDE_DIRS})
72
73@@ -75,8 +91,6 @@
74 set(CMAKE_AUTOMOC ON)
75 set(CMAKE_INCLUDE_CURRENT_DIR ON)
76
77-find_package(Vala 0.22)
78-
79 find_package(GObjectIntrospection 0.9.12)
80
81 include_directories(${CMAKE_BINARY_DIR})
82@@ -85,7 +99,9 @@
83 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
84
85 add_definitions(
86- -Wall
87+ -Wall
88+ -Wextra
89+ -Wpedantic
90 )
91
92 configure_file(
93
94=== removed file 'cmake/FindVala.cmake'
95--- cmake/FindVala.cmake 2013-08-27 13:48:41 +0000
96+++ cmake/FindVala.cmake 1970-01-01 00:00:00 +0000
97@@ -1,57 +0,0 @@
98-# - Find Vala
99-# This module looks for valac.
100-# This module defines the following values:
101-# VALA_FOUND
102-# VALA_COMPILER
103-# VALA_VERSION
104-# VAPI_GEN
105-# VAPI_GEN_VERSION
106-
107-#=============================================================================
108-# Copyright Přemysl Janouch 2011
109-# All rights reserved.
110-#
111-# Redistribution and use in source and binary forms, with or without
112-# modification, are permitted provided that the following conditions are met:
113-# * Redistributions of source code must retain the above copyright
114-# notice, this list of conditions and the following disclaimer.
115-# * Redistributions in binary form must reproduce the above copyright
116-# notice, this list of conditions and the following disclaimer in the
117-# documentation and/or other materials provided with the distribution.
118-#
119-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
120-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
121-# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
122-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
123-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
124-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
125-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
126-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
127-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
128-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
129-# OF SUCH DAMAGE.
130-#=============================================================================
131-
132-find_program (VALA_COMPILER "valac")
133-
134-if (VALA_COMPILER)
135- execute_process (COMMAND ${VALA_COMPILER} --version
136- OUTPUT_VARIABLE VALA_VERSION)
137- string (REGEX MATCH "[.0-9]+" VALA_VERSION "${VALA_VERSION}")
138-endif (VALA_COMPILER)
139-
140-find_program (VAPI_GEN "vapigen")
141-
142-if (VAPI_GEN)
143- execute_process (COMMAND ${VAPI_GEN} --version
144- OUTPUT_VARIABLE VAPI_GEN_VERSION)
145- string (REGEX MATCH "[.0-9]+" VAPI_GEN_VERSION "${VAPI_GEN_VERSION}")
146-endif (VAPI_GEN)
147-
148-include (FindPackageHandleStandardArgs)
149-FIND_PACKAGE_HANDLE_STANDARD_ARGS (Vala
150- REQUIRED_VARS VALA_COMPILER
151- VERSION_VAR VALA_VERSION)
152-
153-mark_as_advanced (VALA_COMPILER VALA_VERSION VAPI_GEN)
154-
155
156=== removed file 'cmake/UseVala.cmake'
157--- cmake/UseVala.cmake 2013-08-27 13:48:41 +0000
158+++ cmake/UseVala.cmake 1970-01-01 00:00:00 +0000
159@@ -1,241 +0,0 @@
160-# - Precompilation of Vala/Genie source files into C sources
161-# Makes use of the parallel build ability introduced in Vala 0.11. Derived
162-# from a similar module by Jakob Westhoff and the original GNU Make rules.
163-# Might be a bit oversimplified.
164-#
165-# This module defines three functions. The first one:
166-#
167-# vala_init (id
168-# [DIRECTORY dir] - Output directory (binary dir by default)
169-# [PACKAGES package...] - Package dependencies
170-# [OPTIONS option...] - Extra valac options
171-# [CUSTOM_VAPIS file...]) - Custom vapi files to include in the build
172-# [DEPENDS targets...]) - Extra dependencies for code generation
173-#
174-# initializes a single precompilation unit using the given arguments.
175-# You can put files into it via the following function:
176-#
177-# vala_add (id source.vala
178-# [DEPENDS source...]) - Vala/Genie source or .vapi dependencies
179-#
180-# Finally retrieve paths for generated C files by calling:
181-#
182-# vala_finish (id
183-# [SOURCES sources_var] - Input Vala/Genie sources
184-# [OUTPUTS outputs_var] - Output C sources
185-# [GENERATE_HEADER id.h - Generate id.h and id_internal.h
186-# [GENERATE_VAPI id.vapi] - Generate a vapi file
187-# [GENERATE_SYMBOLS id.def]]) - Generate a list of public symbols
188-#
189-
190-#=============================================================================
191-# Copyright Přemysl Janouch 2011
192-# All rights reserved.
193-#
194-# Redistribution and use in source and binary forms, with or without
195-# modification, are permitted provided that the following conditions are met:
196-# * Redistributions of source code must retain the above copyright
197-# notice, this list of conditions and the following disclaimer.
198-# * Redistributions in binary form must reproduce the above copyright
199-# notice, this list of conditions and the following disclaimer in the
200-# documentation and/or other materials provided with the distribution.
201-#
202-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
203-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
204-# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
205-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
206-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
207-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
208-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
209-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
210-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
211-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
212-# OF SUCH DAMAGE.
213-#=============================================================================
214-
215-find_package (Vala 0.18 REQUIRED)
216-include (CMakeParseArguments)
217-
218-function (vala_init id)
219- set (_multi_value PACKAGES OPTIONS CUSTOM_VAPIS DEPENDS)
220- cmake_parse_arguments (arg "" "DIRECTORY" "${_multi_value}" ${ARGN})
221-
222- if (arg_DIRECTORY)
223- set (directory ${arg_DIRECTORY})
224- if (NOT IS_DIRECTORY ${directory})
225- file (MAKE_DIRECTORY ${directory})
226- endif (NOT IS_DIRECTORY ${directory})
227- else (arg_DIRECTORY)
228- set (directory ${CMAKE_CURRENT_BINARY_DIR})
229- endif (arg_DIRECTORY)
230-
231- set (pkg_opts)
232- foreach (pkg ${arg_PACKAGES})
233- list (APPEND pkg_opts "--pkg=${pkg}")
234- endforeach (pkg)
235-
236- set (VALA_${id}_DIR "${directory}" PARENT_SCOPE)
237- set (VALA_${id}_ARGS ${pkg_opts} ${arg_OPTIONS}
238- ${arg_CUSTOM_VAPIS} PARENT_SCOPE)
239- set (VALA_${id}_DEPENDS ${arg_DEPENDS}
240- PARENT_SCOPE)
241-
242- set (VALA_${id}_SOURCES "" PARENT_SCOPE)
243- set (VALA_${id}_OUTPUTS "" PARENT_SCOPE)
244- set (VALA_${id}_FAST_VAPI_FILES "" PARENT_SCOPE)
245- set (VALA_${id}_FAST_VAPI_ARGS "" PARENT_SCOPE)
246-endfunction (vala_init)
247-
248-function (vala_add id file)
249- cmake_parse_arguments (arg "" "" "DEPENDS" ${ARGN})
250-
251- if (NOT IS_ABSOLUTE "${file}")
252- set (file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
253- endif (NOT IS_ABSOLUTE "${file}")
254-
255- get_filename_component (output_name "${file}" NAME)
256- get_filename_component (output_base "${file}" NAME_WE)
257- set (output_base "${VALA_${id}_DIR}/${output_base}")
258-
259- # XXX: It would be best to have it working without touching the vapi
260- # but it appears this cannot be done in CMake.
261- add_custom_command (OUTPUT "${output_base}.vapi"
262- COMMAND ${VALA_COMPILER} "${file}" "--fast-vapi=${output_base}.vapi"
263- COMMAND ${CMAKE_COMMAND} -E touch "${output_base}.vapi"
264- DEPENDS "${file}"
265- COMMENT "Generating a fast vapi for ${output_name}" VERBATIM)
266-
267- set (vapi_opts)
268- set (vapi_depends)
269- foreach (vapi ${arg_DEPENDS})
270- if (NOT IS_ABSOLUTE "${vapi}")
271- set (vapi "${VALA_${id}_DIR}/${vapi}.vapi")
272- endif (NOT IS_ABSOLUTE "${vapi}")
273-
274- list (APPEND vapi_opts "--use-fast-vapi=${vapi}")
275- list (APPEND vapi_depends "${vapi}")
276- endforeach (vapi)
277-
278- add_custom_command (OUTPUT "${output_base}.c"
279- COMMAND ${VALA_COMPILER} "${file}" -C ${vapi_opts} ${VALA_${id}_ARGS}
280- COMMAND ${CMAKE_COMMAND} -E touch "${output_base}.c"
281- DEPENDS "${file}" ${vapi_depends} ${VALA_${id}_DEPENDS}
282- WORKING_DIRECTORY "${VALA_${id}_DIR}"
283- COMMENT "Precompiling ${output_name}" VERBATIM)
284-
285- set (VALA_${id}_SOURCES ${VALA_${id}_SOURCES}
286- "${file}" PARENT_SCOPE)
287- set (VALA_${id}_OUTPUTS ${VALA_${id}_OUTPUTS}
288- "${output_base}.c" PARENT_SCOPE)
289- set (VALA_${id}_FAST_VAPI_FILES ${VALA_${id}_FAST_VAPI_FILES}
290- "${output_base}.vapi" PARENT_SCOPE)
291- set (VALA_${id}_FAST_VAPI_ARGS ${VALA_${id}_FAST_VAPI_ARGS}
292- "--use-fast-vapi=${output_base}.vapi" PARENT_SCOPE)
293-endfunction (vala_add)
294-
295-function (vala_finish id)
296- set (_one_value SOURCES OUTPUTS
297- GENERATE_VAPI GENERATE_HEADER GENERATE_SYMBOLS)
298- cmake_parse_arguments (arg "" "${_one_value}" "" ${ARGN})
299-
300- if (arg_SOURCES)
301- set (${arg_SOURCES} ${VALA_${id}_SOURCES} PARENT_SCOPE)
302- endif (arg_SOURCES)
303-
304- if (arg_OUTPUTS)
305- set (${arg_OUTPUTS} ${VALA_${id}_OUTPUTS} PARENT_SCOPE)
306- endif (arg_OUTPUTS)
307-
308- set (outputs)
309- set (export_args)
310-
311- if (arg_GENERATE_VAPI)
312- if (NOT IS_ABSOLUTE "${arg_GENERATE_VAPI}")
313- set (arg_GENERATE_VAPI
314- "${VALA_${id}_DIR}/${arg_GENERATE_VAPI}")
315- endif (NOT IS_ABSOLUTE "${arg_GENERATE_VAPI}")
316-
317- list (APPEND outputs "${arg_GENERATE_VAPI}")
318- list (APPEND export_args "--internal-vapi=${arg_GENERATE_VAPI}")
319-
320- if (NOT arg_GENERATE_HEADER)
321- message (FATAL_ERROR "Header generation required for vapi")
322- endif (NOT arg_GENERATE_HEADER)
323- endif (arg_GENERATE_VAPI)
324-
325- if (arg_GENERATE_SYMBOLS)
326- if (NOT IS_ABSOLUTE "${arg_GENERATE_SYMBOLS}")
327- set (arg_GENERATE_SYMBOLS
328- "${VALA_${id}_DIR}/${arg_GENERATE_SYMBOLS}")
329- endif (NOT IS_ABSOLUTE "${arg_GENERATE_SYMBOLS}")
330-
331- list (APPEND outputs "${arg_GENERATE_SYMBOLS}")
332- list (APPEND export_args "--symbols=${arg_GENERATE_SYMBOLS}")
333-
334- if (NOT arg_GENERATE_HEADER)
335- message (FATAL_ERROR "Header generation required for symbols")
336- endif (NOT arg_GENERATE_HEADER)
337- endif (arg_GENERATE_SYMBOLS)
338-
339- if (arg_GENERATE_HEADER)
340- if (NOT IS_ABSOLUTE "${arg_GENERATE_HEADER}")
341- set (arg_GENERATE_HEADER
342- "${VALA_${id}_DIR}/${arg_GENERATE_HEADER}")
343- endif (NOT IS_ABSOLUTE "${arg_GENERATE_HEADER}")
344-
345- get_filename_component (header_path "${arg_GENERATE_HEADER}" PATH)
346- get_filename_component (header_name "${arg_GENERATE_HEADER}" NAME_WE)
347- set (header_base "${header_path}/${header_name}")
348- get_filename_component (header_ext "${arg_GENERATE_HEADER}" EXT)
349-
350- list (APPEND outputs
351- "${header_base}${header_ext}"
352- "${header_base}_internal${header_ext}")
353- list (APPEND export_args
354- "--header=${header_base}${header_ext}"
355- "--internal-header=${header_base}_internal${header_ext}")
356- endif (arg_GENERATE_HEADER)
357-
358- if (outputs)
359- add_custom_command (OUTPUT ${outputs}
360- COMMAND ${VALA_COMPILER} -C ${VALA_${id}_ARGS}
361- ${export_args} ${VALA_${id}_FAST_VAPI_ARGS}
362- DEPENDS ${VALA_${id}_FAST_VAPI_FILES}
363- COMMENT "Generating vapi/headers/symbols" VERBATIM)
364- endif (outputs)
365-endfunction (vala_finish id)
366-
367-
368-function (vapi_gen id)
369- set (_one_value LIBRARY INPUT)
370- set (_multi_value PACKAGES)
371- cmake_parse_arguments (arg "" "${_one_value}" "${_multi_value}" ${ARGN})
372-
373- set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${id}.vapi")
374- if (arg_LIBRARY)
375- set (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${arg_LIBRARY}.vapi")
376- endif (arg_LIBRARY)
377-
378- set("${id}_OUTPUT" ${OUTPUT} PARENT_SCOPE)
379-
380- set(PACKAGE_LIST)
381- foreach(PACKAGE ${arg_PACKAGES})
382- list(APPEND PACKAGE_LIST "--pkg" ${PACKAGE})
383- endforeach()
384-
385- add_custom_command(
386- OUTPUT
387- ${OUTPUT}
388- COMMAND
389- ${VAPI_GEN}
390- ${PACKAGE_LIST}
391- --library=${arg_LIBRARY}
392- ${arg_INPUT}
393- DEPENDS
394- ${arg_INPUT}
395- VERBATIM
396- )
397-
398- add_custom_target(${id} ALL DEPENDS ${OUTPUT})
399-endfunction (vapi_gen id)
400-
401
402=== modified file 'config.h.in'
403--- config.h.in 2013-08-27 14:54:25 +0000
404+++ config.h.in 2014-05-14 11:21:27 +0000
405@@ -20,7 +20,6 @@
406 #define INDICATOR_NETWORK_CONFIG_H_
407
408 #define GETTEXT_PACKAGE "@GETTEXT_PACKAGE@"
409-#define GNOMELOCALEDIR "@LOCALE_DIR@"
410 #define LOCALE_DIR "@LOCALE_DIR@"
411
412 #endif // INDICATOR_NETWORK_CONFIG_H_
413
414=== modified file 'data/com.canonical.indicator.network'
415--- data/com.canonical.indicator.network 2013-12-20 10:25:06 +0000
416+++ data/com.canonical.indicator.network 2014-05-14 11:21:27 +0000
417@@ -6,12 +6,32 @@
418 [desktop]
419 ObjectPath=/com/canonical/indicator/network/desktop
420
421+[desktop_greeter]
422+ObjectPath=/com/canonical/indicator/network/desktop_greeter
423+
424+[desktop_wifi_settings]
425+ObjectPath=/com/canonical/indicator/network/desktop_wifi_settings
426+
427+
428+[tablet]
429+ObjectPath=/com/canonical/indicator/network/tablet
430+
431+[tablet_greeter]
432+ObjectPath=/com/canonical/indicator/network/tablet_greeter
433+
434+[tablet_wifi_settings]
435+ObjectPath=/com/canonical/indicator/network/tablet_wifi_settings
436+
437+
438 [phone]
439 ObjectPath=/com/canonical/indicator/network/phone
440
441+[phone_greeter]
442+ObjectPath=/com/canonical/indicator/network/phone_greeter
443+
444 [phone_wifi_settings]
445 ObjectPath=/com/canonical/indicator/network/phone_wifi_settings
446
447-[phone_greeter]
448-ObjectPath=/com/canonical/indicator/network/phone
449
450+[ubiquity]
451+ObjectPath=/com/canonical/indicator/network/ubiquity
452
453=== modified file 'data/indicator-network.conf.in'
454--- data/indicator-network.conf.in 2014-04-08 15:28:17 +0000
455+++ data/indicator-network.conf.in 2014-05-14 11:21:27 +0000
456@@ -11,8 +11,11 @@
457
458 pre-start script
459 # NOTE: Only used on Unity8 today, not 7
460+ # Still allows manual starting
461 if [ "x$DESKTOP_SESSION" != "xubuntu-touch" ] ; then
462- stop; exit 0
463+ if [ "x$UPSTART_EVENTS" != "x" ] ; then
464+ stop; exit 0
465+ fi
466 fi
467 end script
468
469
470=== modified file 'debian/control'
471--- debian/control 2014-03-11 12:57:13 +0000
472+++ debian/control 2014-05-14 11:21:27 +0000
473@@ -7,6 +7,8 @@
474 dbus,
475 debhelper (>= 9.0.0),
476 google-mock (>= 1.6.0+svn437),
477+ libconnectivity-cpp-dev (>=0.0.1+14.10.20140514),
478+ libdbus-cpp-dev (>= 3.0.0),
479 libglib2.0-dev,
480 libnm-glib-dev (>= 0.9),
481 libnm-util-dev (>= 0.9),
482@@ -16,10 +18,11 @@
483 libqtdbustest1-dev,
484 liburl-dispatcher1-dev,
485 network-manager-dev,
486+ ofono-dev,
487 pkg-config,
488 python3-dbusmock,
489+ python3-setuptools,
490 qtbase5-dev,
491- valac (>= 0.22),
492 valgrind [amd64 armhf i386 powerpc],
493 Standards-Version: 3.9.3
494 # If you aren't a member of ~indicator-applet-developers but need to upload
495@@ -42,3 +45,16 @@
496 Description: Systems settings menu service - Network indicator
497 The Indicator-network service is responsible for exporting the system settings
498 menu through dbus.
499+
500+Package: indicator-network-autopilot
501+Architecture: all
502+Depends: ${misc:Depends},
503+ indicator-network (>= ${source:Version}),
504+ libautopilot-qt (>= 1.4),
505+ ofono-phonesim-autostart,
506+ unity8-autopilot,
507+ python-dbus,
508+ python-pkg-resources,
509+Description: Autopilot tests for the network indicator for Ubuntu
510+ The Indicator-network service is responsible for exporting the system settings
511+ menu through dbus. This package contains its autopilot tests.
512
513=== added file 'debian/indicator-network-autopilot.install'
514--- debian/indicator-network-autopilot.install 1970-01-01 00:00:00 +0000
515+++ debian/indicator-network-autopilot.install 2014-05-14 11:21:27 +0000
516@@ -0,0 +1,2 @@
517+usr/lib/python*/dist-packages/indicator_network*
518+usr/share/indicator-network/phonesim/*
519
520=== added file 'debian/indicator-network.install'
521--- debian/indicator-network.install 1970-01-01 00:00:00 +0000
522+++ debian/indicator-network.install 2014-05-14 11:21:27 +0000
523@@ -0,0 +1,8 @@
524+usr/share/upstart/xdg/autostart/indicator-network.desktop
525+usr/share/upstart/sessions/indicator-network.conf
526+usr/share/upstart/sessions/indicator-secret-agent.conf
527+usr/share/glib-2.0/schemas/com.canonical.indicator.network.gschema.xml
528+usr/share/unity/indicators/com.canonical.indicator.network
529+usr/lib/*/indicator-secret-agent
530+usr/lib/*/indicator-network/indicator-network-service
531+etc/xdg/autostart/indicator-network.desktop
532
533=== modified file 'debian/rules'
534--- debian/rules 2013-08-27 13:48:41 +0000
535+++ debian/rules 2014-05-14 11:21:27 +0000
536@@ -3,15 +3,28 @@
537 # Uncomment this to turn on verbose mode.
538 #export DH_VERBOSE=1
539
540+include /usr/share/dpkg/default.mk
541+
542 export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
543
544 %:
545- dh $@ --parallel --fail-missing
546+ dh $@ --parallel --fail-missing --with python3
547+
548+ifeq ($(DEB_HOST_ARCH),powerpc)
549+# TestAccessPointItem.ExportBasicActionsAndMenu fails on powerpc, but we
550+# don't care all that much right now.
551+override_dh_auto_test:
552+ dh_auto_test || true
553+endif
554
555 override_dh_install:
556+ cd tests/autopilot; \
557+ set -ex; for python in $(shell py3versions -r); do \
558+ $$python setup.py install --root=$(CURDIR)/debian/tmp --install-layout=deb; \
559+ done; \
560+ cd $(CURDIR)
561 mkdir -p debian/indicator-network/etc/apport/crashdb.conf.d
562 cp debian/indicator-network-crashdb.conf debian/indicator-network/etc/apport/crashdb.conf.d
563 mkdir -p debian/indicator-network/usr/share/apport/package-hooks
564 cp debian/source_indicator-network.py debian/indicator-network/usr/share/apport/package-hooks
565- dh_install --list-missing
566-
567+ dh_install -X'*.pyc' -X'__pycache__' --fail-missing
568
569=== modified file 'network/CMakeLists.txt'
570--- network/CMakeLists.txt 2013-10-10 15:57:05 +0000
571+++ network/CMakeLists.txt 2014-05-14 11:21:27 +0000
572@@ -1,192 +1,69 @@
573
574-add_definitions(
575- -w
576-)
577-
578-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
579-include_directories(${CMAKE_CURRENT_BINARY_DIR})
580-
581-###########################
582-# libnetwork
583-###########################
584-
585-vala_init(libnetwork
586- PACKAGES
587- libnm-glib
588- libnotify
589- CUSTOM_VAPIS
590- "${CMAKE_CURRENT_SOURCE_DIR}/action-muxer.vapi"
591- "${CMAKE_CURRENT_SOURCE_DIR}/url-dispatcher.vapi"
592- "${CMAKE_CURRENT_SOURCE_DIR}/util-wrapper.vapi"
593-)
594-
595-vala_add(libnetwork
596- ofono.vala
597-)
598-
599-vala_add(libnetwork
600- utils.vala
601-)
602-
603-vala_add(libnetwork
604- network-action-manager.vala
605- DEPENDS
606- ofono
607- utils
608-)
609-
610-vala_add(libnetwork
611- network-menu.vala
612- DEPENDS
613- device-base
614- device-ethernet
615- device-mobile
616- device-wifi
617- settings-base
618- settings-wifi
619- settings-airplane
620- network-action-manager
621- mobile-sim-manager
622-)
623-
624-vala_add(libnetwork
625- mobile-sim-manager.vala
626- DEPENDS
627- ofono
628- utils
629-)
630-
631-vala_add(libnetwork
632- device-base.vala
633-)
634-
635-vala_add(libnetwork
636- device-ethernet.vala
637- DEPENDS
638- device-base
639-)
640-
641-vala_add(libnetwork
642- device-mobile.vala
643- DEPENDS
644- device-base
645- mobile-sim-manager
646-)
647-
648-vala_add(libnetwork
649- device-wifi.vala
650- DEPENDS
651- device-base
652-)
653-
654-vala_add(libnetwork
655- settings-base.vala
656-)
657-
658-vala_add(libnetwork
659- settings-airplane.vala
660- DEPENDS
661- settings-base
662-)
663-
664-vala_add(libnetwork
665- settings-wifi.vala
666- DEPENDS
667- settings-base
668-)
669-
670-vala_finish(libnetwork
671- SOURCES
672- LIBNETWORK_VALA_SOURCES
673- OUTPUTS
674- LIBNETWORK_VALA_C
675- GENERATE_HEADER
676- libnetwork.h
677- GENERATE_VAPI
678- libnetwork.vapi
679- GENERATE_SYMBOLS
680- libnetwork.def
681-)
682-
683-set_source_files_properties(
684- ${LIBNETWORK_VALA_SOURCES}
685- PROPERTIES
686- HEADER_FILE_ONLY TRUE
687-)
688-
689-set(
690- LIBNETWORK_SOURCES
691- ${LIBNETWORK_VALA_SOURCES}
692- ${LIBNETWORK_VALA_C}
693- action-muxer.c
694- util-wrapper.c
695-)
696-
697-add_library(
698- network
699- STATIC
700- ${LIBNETWORK_SOURCES}
701-)
702-
703-target_link_libraries(
704- network
705- ${GLIB_LIBRARIES}
706- ${NM_LIBRARIES}
707- ${NOTIFY_LIBRARIES}
708-)
709-
710-###########################
711-# network service
712-###########################
713-
714-vala_init(network-service
715- PACKAGES
716- libnm-glib
717- libnotify
718- libnetwork
719- DEPENDS
720- "${CMAKE_CURRENT_BINARY_DIR}/libnetwork.vapi"
721- CUSTOM_VAPIS
722- "${CMAKE_CURRENT_SOURCE_DIR}/config.vapi"
723- "${CMAKE_CURRENT_SOURCE_DIR}/action-muxer.vapi"
724- "${CMAKE_CURRENT_SOURCE_DIR}/util-wrapper.vapi"
725- OPTIONS
726- --vapidir=.
727-)
728-
729-vala_add(network-service
730- network-menu-service.vala
731-)
732-
733-vala_finish(network-service
734- SOURCES
735- NETWORK_SERVICE_VALA_SOURCES
736- OUTPUTS
737- NETWORK_SERVICE_VALA_C
738-)
739-
740-set_source_files_properties(
741- ${NETWORK_SERVICE_VALA_SOURCES}
742- PROPERTIES
743- HEADER_FILE_ONLY TRUE
744-)
745-
746-set(
747- NETWORK_SERVICE_SOURCES
748- ${NETWORK_SERVICE_VALA_SOURCES}
749- ${NETWORK_SERVICE_VALA_C}
750-)
751+add_subdirectory(menumodel-cpp)
752+
753+include_directories(notify-cpp)
754+
755+set(NOTIFY_CPP_SOURCES
756+ notify-cpp/notification.cpp
757+ notify-cpp/snapdecision/sim-unlock.cpp
758+)
759+
760+set(NETWORK_SERVICE_SOURCES
761+ indicator-network-service.cpp
762+
763+ service.h
764+ indicator-menu.h
765+ modem.cpp
766+ modem.h
767+ modem-manager.cpp
768+ quick-access-section.cpp
769+ sim-unlock-dialog.cpp
770+ root-state.cpp
771+ wifi-link-item.h
772+ wifi-section.cpp
773+ wifi-settings.h
774+ wired-link.h
775+ wwan-link-item.cpp
776+ wwan-section.cpp
777+
778+ dbus-cpp/services/ofono.h
779+
780+ menuitems/access-point-item.h
781+ menuitems/item.h
782+ menuitems/section.h
783+ menuitems/switch-item.h
784+ menuitems/text-item.h
785+
786+ ${NOTIFY_CPP_SOURCES}
787+
788+ url-dispatcher-cpp/url-dispatcher.cpp
789+)
790+
791+#include_directories(include)
792+
793+# get std::thread working...
794+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52681
795+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
796
797 add_executable(
798 indicator-network-service
799 ${NETWORK_SERVICE_SOURCES}
800 )
801-
802 target_link_libraries(
803- indicator-network-service
804- network
805+ indicator-network-service
806+ menumodel_cpp
807+ ${CONNECTIVITY_CPP_LDFLAGS}
808+ ${GLIB_LIBRARIES}
809+ ${GIO_LIBRARIES}
810+ ${NOTIFY_LIBRARIES}
811+ ${OFONO_LIBRARIES}
812 )
813
814+#target_link_libraries(
815+# indicator-network-service
816+# network
817+#)
818+
819 ###########################
820 # Installation
821 ###########################
822
823=== removed file 'network/action-muxer.c'
824--- network/action-muxer.c 2013-07-25 16:38:48 +0000
825+++ network/action-muxer.c 1970-01-01 00:00:00 +0000
826@@ -1,501 +0,0 @@
827-/*
828- * Copyright 2012 Canonical Ltd.
829- *
830- * This program is free software: you can redistribute it and/or modify it
831- * under the terms of the GNU General Public License version 3, as published
832- * by the Free Software Foundation.
833- *
834- * This program is distributed in the hope that it will be useful, but
835- * WITHOUT ANY WARRANTY; without even the implied warranties of
836- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
837- * PURPOSE. See the GNU General Public License for more details.
838- *
839- * You should have received a copy of the GNU General Public License along
840- * with this program. If not, see <http://www.gnu.org/licenses/>.
841- *
842- * Authors:
843- * Lars Uebernickel <lars.uebernickel@canonical.com>
844- * Ryan Lortie <desrt@desrt.ca>
845- */
846-
847-#include "action-muxer.h"
848-
849-#include <string.h>
850-
851-/*
852- * SECTION:gactionmuxer
853- * @short_description: Aggregate several action groups
854- *
855- * #GActionMuxer is a #GActionGroup that is capable of containing other
856- * #GActionGroup instances.
857- *
858- * The typical use is aggregating all of the actions applicable to a
859- * particular context into a single action group, with namespacing.
860- *
861- * Consider the case of two action groups -- one containing actions
862- * applicable to an entire application (such as 'quit') and one
863- * containing actions applicable to a particular window in the
864- * application (such as 'fullscreen').
865- *
866- * In this case, each of these action groups could be added to a
867- * #GActionMuxer with the prefixes "app" and "win", respectively. This
868- * would expose the actions as "app.quit" and "win.fullscreen" on the
869- * #GActionGroup interface presented by the #GActionMuxer.
870- *
871- * Activations and state change requests on the #GActionMuxer are wired
872- * through to the underlying action group in the expected way.
873- */
874-
875-typedef GObjectClass GActionMuxerClass;
876-
877-struct _GActionMuxer
878-{
879- GObject parent;
880- GActionGroup *global_actions;
881- GHashTable *groups; /* prefix -> subgroup */
882- GHashTable *reverse; /* subgroup -> prefix */
883-};
884-
885-
886-static void g_action_muxer_group_init (GActionGroupInterface *iface);
887-static void g_action_muxer_dispose (GObject *object);
888-static void g_action_muxer_finalize (GObject *object);
889-static void g_action_muxer_disconnect_group (GActionMuxer *muxer,
890- GActionGroup *subgroup);
891-static gchar ** g_action_muxer_list_actions (GActionGroup *group);
892-static void g_action_muxer_activate_action (GActionGroup *group,
893- const gchar *action_name,
894- GVariant *parameter);
895-static void g_action_muxer_change_action_state (GActionGroup *group,
896- const gchar *action_name,
897- GVariant *value);
898-static gboolean g_action_muxer_query_action (GActionGroup *group,
899- const gchar *action_name,
900- gboolean *enabled,
901- const GVariantType **parameter_type,
902- const GVariantType **state_type,
903- GVariant **state_hint,
904- GVariant **state);
905-static void g_action_muxer_action_added (GActionGroup *group,
906- gchar *action_name,
907- gpointer user_data);
908-static void g_action_muxer_action_removed (GActionGroup *group,
909- gchar *action_name,
910- gpointer user_data);
911-static void g_action_muxer_action_state_changed (GActionGroup *group,
912- gchar *action_name,
913- GVariant *value,
914- gpointer user_data);
915-static void g_action_muxer_action_enabled_changed (GActionGroup *group,
916- gchar *action_name,
917- gboolean enabled,
918- gpointer user_data);
919-
920-G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT,
921- G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_init));
922-
923-
924-static void
925-g_action_muxer_class_init (GObjectClass *klass)
926-{
927- klass->dispose = g_action_muxer_dispose;
928- klass->finalize = g_action_muxer_finalize;
929-}
930-
931-static void
932-g_action_muxer_init (GActionMuxer *muxer)
933-{
934- muxer->global_actions = NULL;
935- muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
936- muxer->reverse = g_hash_table_new (g_direct_hash, g_direct_equal);
937-}
938-
939-static void
940-g_action_muxer_group_init (GActionGroupInterface *iface)
941-{
942- iface->list_actions = g_action_muxer_list_actions;
943- iface->activate_action = g_action_muxer_activate_action;
944- iface->change_action_state = g_action_muxer_change_action_state;
945- iface->query_action = g_action_muxer_query_action;
946-}
947-
948-static void
949-g_action_muxer_dispose (GObject *object)
950-{
951- GActionMuxer *muxer = G_ACTION_MUXER (object);
952- GHashTableIter it;
953- GActionGroup *subgroup;
954-
955- if (muxer->global_actions)
956- {
957- g_action_muxer_disconnect_group (muxer, muxer->global_actions);
958- g_clear_object (&muxer->global_actions);
959- }
960-
961- g_hash_table_iter_init (&it, muxer->groups);
962- while (g_hash_table_iter_next (&it, NULL, (gpointer *) &subgroup))
963- g_action_muxer_disconnect_group (muxer, subgroup);
964-
965- g_hash_table_remove_all (muxer->groups);
966- g_hash_table_remove_all (muxer->reverse);
967-}
968-
969-static void
970-g_action_muxer_finalize (GObject *object)
971-{
972- GActionMuxer *muxer = G_ACTION_MUXER (object);
973-
974- g_hash_table_unref (muxer->groups);
975- g_hash_table_unref (muxer->reverse);
976-
977- G_OBJECT_CLASS (g_action_muxer_parent_class)->finalize (object);
978-}
979-
980-static GActionGroup *
981-g_action_muxer_lookup_group (GActionMuxer *muxer,
982- const gchar *full_name,
983- const gchar **action_name)
984-{
985- const gchar *sep;
986- GActionGroup *group;
987-
988- sep = strchr (full_name, '.');
989-
990- if (sep)
991- {
992- gchar *prefix;
993- prefix = g_strndup (full_name, sep - full_name);
994- group = g_hash_table_lookup (muxer->groups, prefix);
995- g_free (prefix);
996- if (action_name)
997- *action_name = sep + 1;
998- }
999- else
1000- {
1001- group = muxer->global_actions;
1002- if (action_name)
1003- *action_name = full_name;
1004- }
1005-
1006- return group;
1007-}
1008-
1009-static gchar *
1010-g_action_muxer_lookup_full_name (GActionMuxer *muxer,
1011- GActionGroup *subgroup,
1012- const gchar *action_name)
1013-{
1014- gpointer prefix;
1015-
1016- if (subgroup == muxer->global_actions)
1017- return g_strdup (action_name);
1018-
1019- if (g_hash_table_lookup_extended (muxer->reverse, subgroup, NULL, &prefix))
1020- return g_strdup_printf ("%s.%s", (gchar *) prefix, action_name);
1021-
1022- return NULL;
1023-}
1024-
1025-static void
1026-g_action_muxer_disconnect_group (GActionMuxer *muxer,
1027- GActionGroup *subgroup)
1028-{
1029- gchar **actions;
1030- gchar **action;
1031-
1032- actions = g_action_group_list_actions (subgroup);
1033- for (action = actions; *action; action++)
1034- g_action_muxer_action_removed (subgroup, *action, muxer);
1035- g_strfreev (actions);
1036-
1037- g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_added, muxer);
1038- g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_removed, muxer);
1039- g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_enabled_changed, muxer);
1040- g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_state_changed, muxer);
1041-}
1042-
1043-static gchar **
1044-g_action_muxer_list_actions (GActionGroup *group)
1045-{
1046- GActionMuxer *muxer = G_ACTION_MUXER (group);
1047- GHashTableIter it;
1048- GArray *all_actions;
1049- gchar *prefix;
1050- GActionGroup *subgroup;
1051- gchar **actions;
1052- gchar **a;
1053-
1054- all_actions = g_array_sized_new (TRUE, FALSE, sizeof (gchar *), 8);
1055-
1056- if (muxer->global_actions)
1057- {
1058- actions = g_action_group_list_actions (muxer->global_actions);
1059- for (a = actions; *a; a++)
1060- {
1061- gchar *name = g_strdup (*a);
1062- g_array_append_val (all_actions, name);
1063- }
1064- g_strfreev (actions);
1065- }
1066-
1067- g_hash_table_iter_init (&it, muxer->groups);
1068- while (g_hash_table_iter_next (&it, (gpointer *) &prefix, (gpointer *) &subgroup))
1069- {
1070- actions = g_action_group_list_actions (subgroup);
1071- for (a = actions; *a; a++)
1072- {
1073- gchar *full_name = g_strdup_printf ("%s.%s", prefix, *a);
1074- g_array_append_val (all_actions, full_name);
1075- }
1076- g_strfreev (actions);
1077- }
1078-
1079- return (gchar **) g_array_free (all_actions, FALSE);
1080-}
1081-
1082-static void
1083-g_action_muxer_activate_action (GActionGroup *group,
1084- const gchar *action_name,
1085- GVariant *parameter)
1086-{
1087- GActionMuxer *muxer = G_ACTION_MUXER (group);
1088- GActionGroup *subgroup;
1089- const gchar *action;
1090-
1091- g_return_if_fail (action_name != NULL);
1092-
1093- subgroup = g_action_muxer_lookup_group (muxer, action_name, &action);
1094-
1095- if (subgroup)
1096- g_action_group_activate_action (subgroup, action, parameter);
1097-}
1098-
1099-static void
1100-g_action_muxer_change_action_state (GActionGroup *group,
1101- const gchar *action_name,
1102- GVariant *value)
1103-{
1104- GActionMuxer *muxer = G_ACTION_MUXER (group);
1105- GActionGroup *subgroup;
1106- const gchar *action;
1107-
1108- g_return_if_fail (action_name != NULL);
1109-
1110- subgroup = g_action_muxer_lookup_group (muxer, action_name, &action);
1111-
1112- if (subgroup)
1113- g_action_group_change_action_state (subgroup, action, value);
1114-}
1115-
1116-static gboolean
1117-g_action_muxer_query_action (GActionGroup *group,
1118- const gchar *action_name,
1119- gboolean *enabled,
1120- const GVariantType **parameter_type,
1121- const GVariantType **state_type,
1122- GVariant **state_hint,
1123- GVariant **state)
1124-{
1125- GActionMuxer *muxer = G_ACTION_MUXER (group);
1126- GActionGroup *subgroup;
1127- const gchar *action;
1128-
1129- g_return_val_if_fail (action_name != NULL, FALSE);
1130-
1131- subgroup = g_action_muxer_lookup_group (muxer, action_name, &action);
1132-
1133- if (!subgroup)
1134- return FALSE;
1135-
1136- return g_action_group_query_action (subgroup, action, enabled, parameter_type,
1137- state_type, state_hint, state);
1138-}
1139-
1140-static void
1141-g_action_muxer_action_added (GActionGroup *group,
1142- gchar *action_name,
1143- gpointer user_data)
1144-{
1145- GActionMuxer *muxer = user_data;
1146- gchar *full_name;
1147-
1148- full_name = g_action_muxer_lookup_full_name (muxer, group, action_name);
1149-
1150- if (full_name)
1151- {
1152- g_action_group_action_added (G_ACTION_GROUP (muxer), full_name);
1153- g_free (full_name);
1154- }
1155-}
1156-
1157-static void
1158-g_action_muxer_action_removed (GActionGroup *group,
1159- gchar *action_name,
1160- gpointer user_data)
1161-{
1162- GActionMuxer *muxer = user_data;
1163- gchar *full_name;
1164-
1165- full_name = g_action_muxer_lookup_full_name (muxer, group, action_name);
1166-
1167- if (full_name)
1168- {
1169- g_action_group_action_removed (G_ACTION_GROUP (muxer), full_name);
1170- g_free (full_name);
1171- }
1172-}
1173-
1174-static void
1175-g_action_muxer_action_state_changed (GActionGroup *group,
1176- gchar *action_name,
1177- GVariant *value,
1178- gpointer user_data)
1179-{
1180- GActionMuxer *muxer = user_data;
1181- gchar *full_name;
1182-
1183- full_name = g_action_muxer_lookup_full_name (muxer, group, action_name);
1184-
1185- if (full_name)
1186- {
1187- g_action_group_action_state_changed (G_ACTION_GROUP (muxer), full_name, value);
1188- g_free (full_name);
1189- }
1190-}
1191-
1192-static void
1193-g_action_muxer_action_enabled_changed (GActionGroup *group,
1194- gchar *action_name,
1195- gboolean enabled,
1196- gpointer user_data)
1197-{
1198- GActionMuxer *muxer = user_data;
1199- gchar *full_name;
1200-
1201- full_name = g_action_muxer_lookup_full_name (muxer, group, action_name);
1202-
1203- if (full_name)
1204- {
1205- g_action_group_action_enabled_changed (G_ACTION_GROUP (muxer), full_name, enabled);
1206- g_free (full_name);
1207- }
1208-}
1209-
1210-/*
1211- * g_action_muxer_new:
1212- *
1213- * Creates a new #GActionMuxer.
1214- */
1215-GActionMuxer *
1216-g_action_muxer_new (void)
1217-{
1218- return g_object_new (G_TYPE_ACTION_MUXER, NULL);
1219-}
1220-
1221-/*
1222- * g_action_muxer_insert:
1223- * @muxer: a #GActionMuxer
1224- * @prefix: (allow-none): the prefix string for the action group, or NULL
1225- * @group: (allow-none): a #GActionGroup, or NULL
1226- *
1227- * Adds the actions in @group to the list of actions provided by @muxer.
1228- * @prefix is prefixed to each action name, such that for each action
1229- * <varname>x</varname> in @group, there is an equivalent action
1230- * @prefix<literal>.</literal><varname>x</varname> in @muxer.
1231- *
1232- * For example, if @prefix is "<literal>app</literal>" and @group contains an
1233- * action called "<literal>quit</literal>", then @muxer will now contain an
1234- * action called "<literal>app.quit</literal>".
1235- *
1236- * If @prefix is <literal>NULL</literal>, the actions in @group will be added
1237- * to @muxer without prefix.
1238- *
1239- * If @group is <literal>NULL</literal>, this function has the same effect as
1240- * calling g_action_muxer_remove() with @prefix.
1241- *
1242- * There may only be one group per prefix (including the
1243- * <literal>NULL</literal>-prefix). If a group has been added with @prefix in
1244- * a previous call to this function, it will be removed.
1245- *
1246- * @prefix must not contain a dot ('.').
1247- */
1248-void
1249-g_action_muxer_insert (GActionMuxer *muxer,
1250- const gchar *prefix,
1251- GActionGroup *group)
1252-{
1253- gchar *prefix_copy;
1254- gchar **actions;
1255- gchar **action;
1256-
1257- g_return_if_fail (G_IS_ACTION_MUXER (muxer));
1258- g_return_if_fail (G_IS_ACTION_GROUP (group));
1259-
1260- g_action_muxer_remove (muxer, prefix);
1261-
1262- if (prefix)
1263- {
1264- prefix_copy = g_strdup (prefix);
1265- g_hash_table_insert (muxer->groups, prefix_copy, g_object_ref (group));
1266- g_hash_table_insert (muxer->reverse, group, prefix_copy);
1267- }
1268- else
1269- muxer->global_actions = g_object_ref (group);
1270-
1271- actions = g_action_group_list_actions (group);
1272- for (action = actions; *action; action++)
1273- g_action_muxer_action_added (group, *action, muxer);
1274- g_strfreev (actions);
1275-
1276- g_signal_connect (group, "action-added", G_CALLBACK (g_action_muxer_action_added), muxer);
1277- g_signal_connect (group, "action-removed", G_CALLBACK (g_action_muxer_action_removed), muxer);
1278- g_signal_connect (group, "action-enabled-changed", G_CALLBACK (g_action_muxer_action_enabled_changed), muxer);
1279- g_signal_connect (group, "action-state-changed", G_CALLBACK (g_action_muxer_action_state_changed), muxer);
1280-}
1281-
1282-/*
1283- * g_action_muxer_remove:
1284- * @muxer: a #GActionMuxer
1285- * @prefix: (allow-none): the prefix of the action group to remove, or NULL
1286- *
1287- * Removes a #GActionGroup from the #GActionMuxer.
1288- */
1289-void
1290-g_action_muxer_remove (GActionMuxer *muxer,
1291- const gchar *prefix)
1292-{
1293- GActionGroup *subgroup;
1294-
1295- g_return_if_fail (G_IS_ACTION_MUXER (muxer));
1296-
1297- subgroup = prefix ? g_hash_table_lookup (muxer->groups, prefix) : muxer->global_actions;
1298- if (!subgroup)
1299- return;
1300-
1301- g_action_muxer_disconnect_group (muxer, subgroup);
1302-
1303- if (prefix)
1304- {
1305- g_hash_table_remove (muxer->groups, prefix);
1306- g_hash_table_remove (muxer->reverse, subgroup);
1307- }
1308- else
1309- g_clear_object (&muxer->global_actions);
1310-}
1311-
1312-/*
1313- * g_action_muxer_get:
1314- * @muxer: a #GActionMuxer
1315- * @prefix: (allow-none): the prefix of the action group to get, or NULL
1316- *
1317- * Looks for an action group and returns it if found
1318- *
1319- * Return value: (transfer none): Action group that matches @prefix
1320- */
1321-GActionGroup *
1322-g_action_muxer_get (GActionMuxer * muxer, const gchar * prefix)
1323-{
1324- g_return_val_if_fail (G_IS_ACTION_MUXER (muxer), NULL);
1325-
1326- return prefix ? g_hash_table_lookup (muxer->groups, prefix) : muxer->global_actions;
1327-}
1328
1329=== removed file 'network/action-muxer.h'
1330--- network/action-muxer.h 2013-07-25 16:38:48 +0000
1331+++ network/action-muxer.h 1970-01-01 00:00:00 +0000
1332@@ -1,47 +0,0 @@
1333-/*
1334- * Copyright 2012 Canonical Ltd.
1335- *
1336- * This program is free software: you can redistribute it and/or modify it
1337- * under the terms of the GNU General Public License version 3, as published
1338- * by the Free Software Foundation.
1339- *
1340- * This program is distributed in the hope that it will be useful, but
1341- * WITHOUT ANY WARRANTY; without even the implied warranties of
1342- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1343- * PURPOSE. See the GNU General Public License for more details.
1344- *
1345- * You should have received a copy of the GNU General Public License along
1346- * with this program. If not, see <http://www.gnu.org/licenses/>.
1347- *
1348- * Authors:
1349- * Lars Uebernickel <lars.uebernickel@canonical.com>
1350- * Ryan Lortie <desrt@desrt.ca>
1351- */
1352-
1353-#ifndef __G_ACTION_MUXER_H__
1354-#define __G_ACTION_MUXER_H__
1355-
1356-#include <gio/gio.h>
1357-
1358-#define G_TYPE_ACTION_MUXER (g_action_muxer_get_type ())
1359-#define G_ACTION_MUXER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ACTION_MUXER, GActionMuxer))
1360-#define G_IS_ACTION_MUXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ACTION_MUXER))
1361-
1362-typedef struct _GActionMuxer GActionMuxer;
1363-
1364-GType g_action_muxer_get_type (void) G_GNUC_CONST;
1365-
1366-GActionMuxer * g_action_muxer_new (void);
1367-
1368-void g_action_muxer_insert (GActionMuxer *muxer,
1369- const gchar *prefix,
1370- GActionGroup *group);
1371-
1372-void g_action_muxer_remove (GActionMuxer *muxer,
1373- const gchar *prefix);
1374-
1375-GActionGroup * g_action_muxer_get (GActionMuxer *muxer,
1376- const gchar *prefix);
1377-
1378-#endif
1379-
1380
1381=== removed file 'network/action-muxer.vapi'
1382--- network/action-muxer.vapi 2013-07-25 20:56:52 +0000
1383+++ network/action-muxer.vapi 1970-01-01 00:00:00 +0000
1384@@ -1,10 +0,0 @@
1385-[CCode (cprefix = "G", lower_case_cprefix = "g_")]
1386-namespace GLibLocal {
1387- [CCode (cheader_filename = "action-muxer.h", type_id = "G_TYPE_ACTION_MUXER")]
1388- public class ActionMuxer : GLib.Object {
1389- public ActionMuxer ();
1390- public void insert (string prefix, GLib.ActionGroup group);
1391- public void remove (string prefix);
1392- public GLib.ActionGroup get (string prefix);
1393- }
1394-}
1395
1396=== removed file 'network/config.vapi'
1397--- network/config.vapi 2013-08-25 18:53:54 +0000
1398+++ network/config.vapi 1970-01-01 00:00:00 +0000
1399@@ -1,8 +0,0 @@
1400-[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "../config.h")]
1401-namespace Config {
1402- public const string GETTEXT_PACKAGE;
1403- public const string GNOMELOCALEDIR;
1404- public const string PKGDATADIR;
1405- public const string PACKAGE_NAME;
1406- public const string PACKAGE_VERSION;
1407-}
1408
1409=== added directory 'network/dbus-cpp'
1410=== added directory 'network/dbus-cpp/services'
1411=== added file 'network/dbus-cpp/services/ofono.h'
1412--- network/dbus-cpp/services/ofono.h 1970-01-01 00:00:00 +0000
1413+++ network/dbus-cpp/services/ofono.h 2014-05-14 11:21:27 +0000
1414@@ -0,0 +1,1322 @@
1415+/*
1416+ * Copyright © 2014 Canonical Ltd.
1417+ *
1418+ * This program is free software: you can redistribute it and/or modify it
1419+ * under the terms of the GNU Lesser General Public License version 3,
1420+ * as published by the Free Software Foundation.
1421+ *
1422+ * This program is distributed in the hope that it will be useful,
1423+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1424+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1425+ * GNU Lesser General Public License for more details.
1426+ *
1427+ * You should have received a copy of the GNU Lesser General Public License
1428+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1429+ *
1430+ * Authors: Antti Kaijanmäki <antti.kaijanmaki@canonical.com
1431+ */
1432+#ifndef DBUS_CPP_SERVICES_OFONO_H
1433+#define DBUS_CPP_SERVICES_OFONO_H
1434+
1435+#include <core/dbus/bus.h>
1436+#include <core/dbus/object.h>
1437+#include <core/dbus/property.h>
1438+#include <core/dbus/service.h>
1439+#include <core/dbus/types/object_path.h>
1440+#include <core/dbus/types/struct.h>
1441+#include <core/dbus/types/stl/map.h>
1442+#include <core/dbus/types/stl/string.h>
1443+#include <core/dbus/types/stl/tuple.h>
1444+#include <core/dbus/types/stl/vector.h>
1445+
1446+#include <ofono/dbus.h>
1447+
1448+namespace org
1449+{
1450+namespace ofono
1451+{
1452+
1453+struct Interface
1454+{
1455+ struct NetworkRegistration
1456+ {
1457+ static const std::string& name()
1458+ {
1459+ static const std::string s{"org.ofono.NetworkRegistration"};
1460+ return s;
1461+ }
1462+
1463+ struct Method
1464+ {
1465+ struct GetProperties
1466+ {
1467+ static const std::string& name()
1468+ {
1469+ static const std::string s{"GetProperties"};
1470+ return s;
1471+ }
1472+
1473+ typedef NetworkRegistration Interface;
1474+ typedef std::map<std::string, core::dbus::types::Variant> ValueType;
1475+
1476+ static std::chrono::milliseconds default_timeout()
1477+ {
1478+ return std::chrono::seconds{1};
1479+ }
1480+ };
1481+ };
1482+
1483+ struct Property
1484+ {
1485+ struct Status {
1486+ static const std::string &name()
1487+ {
1488+ static const std::string s{"Status"};
1489+ return s;
1490+ }
1491+
1492+ typedef NetworkRegistration Interface;
1493+ typedef std::string ValueType;
1494+ static const bool readable = true;
1495+ static const bool writable = false;
1496+ };
1497+
1498+ struct Technology
1499+ {
1500+ static const std::string &name()
1501+ {
1502+ static const std::string s{"Technology"};
1503+ return s;
1504+ }
1505+
1506+ typedef NetworkRegistration Interface;
1507+ typedef std::string ValueType;
1508+ static const bool readable = true;
1509+ static const bool writable = false;
1510+ };
1511+
1512+ struct Strength
1513+ {
1514+ static const std::string &name()
1515+ {
1516+ static const std::string s{"Strength"};
1517+ return s;
1518+ }
1519+
1520+ typedef NetworkRegistration Interface;
1521+ typedef std::int8_t ValueType;
1522+ static const bool readable = true;
1523+ static const bool writable = false;
1524+ };
1525+
1526+ struct Name
1527+ {
1528+ static const std::string &name()
1529+ {
1530+ static const std::string s{"Name"};
1531+ return s;
1532+ }
1533+
1534+ typedef NetworkRegistration Interface;
1535+ typedef std::string ValueType;
1536+ static const bool readable = true;
1537+ static const bool writable = false;
1538+ };
1539+ };
1540+
1541+ struct Signal
1542+ {
1543+ struct PropertyChanged
1544+ {
1545+ static const std::string& name()
1546+ {
1547+ static const std::string s{"PropertyChanged"};
1548+ return s;
1549+ }
1550+
1551+ typedef NetworkRegistration Interface;
1552+ typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType;
1553+ };
1554+ };
1555+
1556+ enum class Status
1557+ {
1558+ unregistered,
1559+ registered,
1560+ searching,
1561+ denied,
1562+ unknown,
1563+ roaming
1564+ };
1565+
1566+ Status
1567+ str2status(std::string str)
1568+ {
1569+ if (str == "unregistered")
1570+ return Status::unregistered;
1571+ if (str == "registered")
1572+ return Status::registered;
1573+ if (str == "searching")
1574+ return Status::searching;
1575+ if (str == "denied")
1576+ return Status::denied;
1577+ if (str == "unknown")
1578+ return Status::unknown;
1579+ if (str == "roaming")
1580+ return Status::roaming;
1581+
1582+ throw std::runtime_error(std::string(__PRETTY_FUNCTION__) + ": Unknown status '" + str + "'");
1583+ }
1584+
1585+ enum class Technology
1586+ {
1587+ notAvailable,
1588+ gsm,
1589+ edge,
1590+ umts,
1591+ hspa,
1592+ lte
1593+ };
1594+
1595+ Technology
1596+ str2technology(std::string str)
1597+ {
1598+ if (str == "")
1599+ return Technology::notAvailable;
1600+ if (str == "gsm")
1601+ return Technology::gsm;
1602+ if (str == "edge")
1603+ return Technology::edge;
1604+ if (str == "umts")
1605+ return Technology::umts;
1606+ if (str == "hspa")
1607+ return Technology::hspa;
1608+ if (str == "lte")
1609+ return Technology::lte;
1610+
1611+ throw std::runtime_error(std::string(__PRETTY_FUNCTION__) + ": Unknown techonology '" + str + "'");
1612+ }
1613+
1614+ typedef std::shared_ptr<NetworkRegistration> Ptr;
1615+ NetworkRegistration(const std::shared_ptr<core::dbus::Object>& object)
1616+ : object(object),
1617+ propertyChanged(object->get_signal<Signal::PropertyChanged>())
1618+ {
1619+ status.set(Status::unknown);
1620+ strength.set(-1);
1621+ technology.set(Technology::notAvailable);
1622+
1623+ propertyChanged->connect([this](Signal::PropertyChanged::ArgumentType args){
1624+ _updateProperty(std::get<0>(args), std::get<1>(args));
1625+ });
1626+ auto result = object->invoke_method_synchronously<Method::GetProperties, Method::GetProperties::ValueType>();
1627+ if (result.is_error())
1628+ throw std::runtime_error(result.error().print());
1629+ for (auto element : result.value())
1630+ _updateProperty(element.first, element.second);
1631+ }
1632+
1633+ ~NetworkRegistration()
1634+ {}
1635+
1636+ void _updateProperty(std::string property, core::dbus::types::Variant value)
1637+ {
1638+ if (property == Property::Name::name()) {
1639+ operatorName.set(value.as<Property::Name::ValueType>());
1640+ } else if (property == Property::Status::name()) {
1641+ status.set(str2status(value.as<Property::Status::ValueType>()));
1642+ } else if (property == Property::Strength::name()) {
1643+ strength.set(value.as<Property::Strength::ValueType>());
1644+ } else if (property == Property::Technology::name()) {
1645+ technology.set(str2technology(value.as<Property::Technology::ValueType>()));
1646+ } else {
1647+ //throw std::runtime_error(std::string(__PRETTY_FUNCTION__) + ": unexpected property change: " + property);
1648+ std::cout << std::string(__PRETTY_FUNCTION__) + ": unhandled property change: " + property << std::endl;
1649+ }
1650+ }
1651+
1652+ std::shared_ptr<core::dbus::Object> object;
1653+ std::shared_ptr<core::dbus::Signal<Signal::PropertyChanged, Signal::PropertyChanged::ArgumentType>> propertyChanged;
1654+
1655+
1656+ core::Property<std::string> operatorName;
1657+ core::Property<Status> status;
1658+
1659+ /**
1660+ * Contains the current signal strength as a percentage
1661+ * between 0-100 percent.
1662+ *
1663+ * -1, not avalable
1664+ */
1665+ core::Property<std::int8_t> strength;
1666+
1667+ core::Property<Technology> technology;
1668+ };
1669+
1670+ struct SimManager
1671+ {
1672+ static const std::string& name()
1673+ {
1674+ static const std::string s{OFONO_SIM_MANAGER_INTERFACE};
1675+ return s;
1676+ }
1677+
1678+ struct Method
1679+ {
1680+ struct GetProperties
1681+ {
1682+ static const std::string& name()
1683+ {
1684+ static const std::string s{"GetProperties"};
1685+ return s;
1686+ }
1687+
1688+ typedef SimManager Interface;
1689+ typedef std::map<std::string, core::dbus::types::Variant> ResultType;
1690+
1691+ static std::chrono::milliseconds default_timeout()
1692+ {
1693+ return std::chrono::seconds{1};
1694+ }
1695+ };
1696+ struct SetProperty
1697+ {
1698+ static const std::string& name()
1699+ {
1700+ static const std::string s{"SetProperty"};
1701+ return s;
1702+ }
1703+
1704+ typedef SimManager Interface;
1705+ typedef void ResultType;
1706+
1707+ static std::chrono::milliseconds default_timeout()
1708+ {
1709+ return std::chrono::seconds{1};
1710+ }
1711+ };
1712+
1713+ struct ChangePin
1714+ {
1715+ static const std::string& name()
1716+ {
1717+ static const std::string s{"ChangePin"};
1718+ return s;
1719+ }
1720+
1721+ typedef SimManager Interface;
1722+ typedef void ResultType;
1723+
1724+ static std::chrono::milliseconds default_timeout()
1725+ {
1726+ return std::chrono::seconds{1};
1727+ }
1728+ };
1729+
1730+ struct EnterPin
1731+ {
1732+ static const std::string& name()
1733+ {
1734+ static const std::string s{"EnterPin"};
1735+ return s;
1736+ }
1737+
1738+ typedef SimManager Interface;
1739+ typedef void ResultType;
1740+
1741+ static std::chrono::milliseconds default_timeout()
1742+ {
1743+ return std::chrono::seconds{1};
1744+ }
1745+ };
1746+
1747+ struct ResetPin
1748+ {
1749+ static const std::string& name()
1750+ {
1751+ static const std::string s{"ResetPin"};
1752+ return s;
1753+ }
1754+
1755+ typedef SimManager Interface;
1756+ typedef void ResultType;
1757+
1758+ static std::chrono::milliseconds default_timeout()
1759+ {
1760+ return std::chrono::seconds{1};
1761+ }
1762+ };
1763+
1764+ struct LockPin
1765+ {
1766+ static const std::string& name()
1767+ {
1768+ static const std::string s{"LockPin"};
1769+ return s;
1770+ }
1771+
1772+ typedef SimManager Interface;
1773+ typedef void ResultType;
1774+
1775+ static std::chrono::milliseconds default_timeout()
1776+ {
1777+ return std::chrono::seconds{1};
1778+ }
1779+ };
1780+
1781+ struct UnlockPin
1782+ {
1783+ static const std::string& name()
1784+ {
1785+ static const std::string s{"UnlockPin"};
1786+ return s;
1787+ }
1788+
1789+ typedef SimManager Interface;
1790+ typedef void ResultType;
1791+
1792+ static std::chrono::milliseconds default_timeout()
1793+ {
1794+ return std::chrono::seconds{1};
1795+ }
1796+ };
1797+ };
1798+
1799+ struct Property
1800+ {
1801+ struct Present
1802+ {
1803+ static const std::string &name()
1804+ {
1805+ static const std::string s{"Present"};
1806+ return s;
1807+ }
1808+
1809+ typedef SimManager Interface;
1810+ typedef bool ValueType;
1811+ static const bool readable = true;
1812+ static const bool writable = false;
1813+ };
1814+
1815+ struct SubscriberIdentity
1816+ {
1817+ static const std::string &name()
1818+ {
1819+ static const std::string s{"SubscriberIdentity"};
1820+ return s;
1821+ }
1822+
1823+ typedef SimManager Interface;
1824+ typedef std::string ValueType;
1825+ static const bool readable = true;
1826+ static const bool writable = false;
1827+ };
1828+
1829+ struct PinRequired
1830+ {
1831+ static const std::string &name()
1832+ {
1833+ static const std::string s{"PinRequired"};
1834+ return s;
1835+ }
1836+
1837+ typedef SimManager Interface;
1838+ typedef std::string ValueType;
1839+ static const bool readable = true;
1840+ static const bool writable = false;
1841+ };
1842+
1843+ struct LockedPins
1844+ {
1845+ static const std::string &name()
1846+ {
1847+ static const std::string s{"LockedPins"};
1848+ return s;
1849+ }
1850+
1851+ typedef SimManager Interface;
1852+ typedef std::vector<std::string> ValueType;
1853+ static const bool readable = true;
1854+ static const bool writable = false;
1855+ };
1856+
1857+ struct Retries
1858+ {
1859+ static const std::string &name()
1860+ {
1861+ static const std::string s{"Retries"};
1862+ return s;
1863+ }
1864+
1865+ typedef SimManager Interface;
1866+ typedef std::map<std::string, std::int8_t> ValueType;
1867+ static const bool readable = true;
1868+ static const bool writable = false;
1869+ };
1870+ };
1871+
1872+ struct Signal
1873+ {
1874+ struct PropertyChanged
1875+ {
1876+ static const std::string& name()
1877+ {
1878+ static const std::string s{"PropertyChanged"};
1879+ return s;
1880+ }
1881+
1882+ typedef SimManager Interface;
1883+ typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType;
1884+ };
1885+ };
1886+
1887+ enum class PinType
1888+ {
1889+ none,
1890+ pin,
1891+ phone,
1892+ firstphone,
1893+ pin2,
1894+ network,
1895+ netsub,
1896+ service,
1897+ corp,
1898+ puk,
1899+ firstphonepuk,
1900+ puk2,
1901+ networkpuk,
1902+ netsubpuk,
1903+ servicepuk,
1904+ corppuk
1905+ };
1906+
1907+ static std::string
1908+ pin2str(PinType type)
1909+ {
1910+ switch(type){
1911+ case PinType::none:
1912+ return "none";
1913+ case PinType::pin:
1914+ return "pin";
1915+ case PinType::phone:
1916+ return "phone";
1917+ case PinType::firstphone:
1918+ return "firstphone";
1919+ case PinType::pin2:
1920+ return "pin2";
1921+ case PinType::network:
1922+ return "network";
1923+ case PinType::netsub:
1924+ return "netsub";
1925+ case PinType::service:
1926+ return "service";
1927+ case PinType::corp:
1928+ return "corp";
1929+ case PinType::puk:
1930+ return "puk";
1931+ case PinType::firstphonepuk:
1932+ return "firstphonepuk";
1933+ case PinType::puk2:
1934+ return "puk2";
1935+ case PinType::networkpuk:
1936+ return "networkpuk";
1937+ case PinType::netsubpuk:
1938+ return "netsubpuk";
1939+ case PinType::servicepuk:
1940+ return "servicepuk";
1941+ case PinType::corppuk:
1942+ return "corppuk";
1943+ }
1944+ throw std::runtime_error(std::string(__PRETTY_FUNCTION__) + ": unknown pinType: " + std::to_string(static_cast<int>(type)));
1945+ }
1946+
1947+ static PinType
1948+ str2pin(std::string str)
1949+ {
1950+ if (str == "none")
1951+ return PinType::none;
1952+ else if (str == "pin")
1953+ return PinType::pin;
1954+ else if (str == "phone")
1955+ return PinType::phone;
1956+ else if (str == "firstphone")
1957+ return PinType::firstphone;
1958+ else if (str == "pin2")
1959+ return PinType::pin2;
1960+ else if (str == "network")
1961+ return PinType::network;
1962+ else if (str == "netsub")
1963+ return PinType::netsub;
1964+ else if (str == "service")
1965+ return PinType::service;
1966+ else if (str == "corp")
1967+ return PinType::corp;
1968+ else if (str == "puk")
1969+ return PinType::puk;
1970+ else if (str == "firstphonepuk")
1971+ return PinType::firstphonepuk;
1972+ else if (str == "puk2")
1973+ return PinType::puk2;
1974+ else if (str == "networkpuk")
1975+ return PinType::networkpuk;
1976+ else if (str == "netsubpuk")
1977+ return PinType::netsubpuk;
1978+ else if (str == "servicepuk")
1979+ return PinType::servicepuk;
1980+ else if (str == "corppuk")
1981+ return PinType::corppuk;
1982+
1983+ /// @todo throw something.
1984+ std::cerr << "Unknown pin type: " << str << std::endl;
1985+ return PinType::none;
1986+ }
1987+
1988+ std::map<std::string, core::dbus::types::Variant>
1989+ getProperties()
1990+ {
1991+ auto result =
1992+ object->invoke_method_synchronously<
1993+ SimManager::Method::GetProperties, SimManager::Method::GetProperties::ResultType>();
1994+
1995+ if (result.is_error())
1996+ throw std::runtime_error(result.error().print());
1997+
1998+ return result.value();
1999+ }
2000+
2001+ bool
2002+ changePin(PinType type, std::string oldPin, std::string newPin)
2003+ {
2004+ auto result =
2005+ object->invoke_method_synchronously<
2006+ SimManager::Method::ChangePin, SimManager::Method::ChangePin::ResultType>
2007+ (pin2str(type), oldPin, newPin);
2008+
2009+ if (result.is_error()) {
2010+ auto &error = result.error();
2011+ if (error.name() == "org.ofono.Error.NotImplemented") {
2012+ throw std::runtime_error(result.error().print());
2013+ } else if (error.name() == "org.ofono.Error.InProgress") {
2014+ throw std::runtime_error(result.error().print());
2015+ } else if (error.name() == "org.ofono.Error.InvalidArguments") {
2016+ throw std::logic_error(result.error().print());
2017+ } else if (error.name() == "org.ofono.Error.InvalidFormat") {
2018+ throw std::logic_error(result.error().print());
2019+ } else if (error.name() == "org.ofono.Error.Failed") {
2020+ return false;
2021+ }
2022+ }
2023+ return true;
2024+ }
2025+
2026+ bool
2027+ enterPin(PinType type, std::string pin)
2028+ {
2029+ try {
2030+ auto result =
2031+ object->invoke_method_synchronously<
2032+ SimManager::Method::EnterPin, SimManager::Method::EnterPin::ResultType>
2033+ (pin2str(type), pin);
2034+ } catch(std::runtime_error &e) {
2035+ /// @todo dbus-cpp does not provide proper errors yet :/
2036+ return false;
2037+ }
2038+#if 0
2039+ if (result.is_error()) {
2040+ auto &error = result.error();
2041+ if (error.name() == "org.ofono.Error.NotImplemented") {
2042+ throw std::runtime_error(result.error().print());
2043+ } else if (error.name() == "org.ofono.Error.InProgress") {
2044+ throw std::runtime_error(result.error().print());
2045+ } else if (error.name() == "org.ofono.Error.InvalidArguments") {
2046+ throw std::logic_error(result.error().print());
2047+ } else if (error.name() == "org.ofono.Error.InvalidFormat") {
2048+ throw std::logic_error(result.error().print());
2049+ } else if (error.name() == "org.ofono.Error.Failed") {
2050+ return false;
2051+ }
2052+ }
2053+#endif
2054+ return true;
2055+ }
2056+
2057+ bool
2058+ resetPin(PinType type, std::string puk, std::string newPin)
2059+ {
2060+ try {
2061+ auto result =
2062+ object->invoke_method_synchronously<
2063+ SimManager::Method::ResetPin, SimManager::Method::ResetPin::ResultType>
2064+ (pin2str(type), puk, newPin);
2065+ } catch(std::runtime_error &e) {
2066+ /// @todo dbus-cpp does not provide proper errors yet :/
2067+ return false;
2068+ }
2069+#if 0
2070+ if (result.is_error()) {
2071+ auto &error = result.error();
2072+ if (error.name() == "org.ofono.Error.NotImplemented") {
2073+ throw std::runtime_error(result.error().print());
2074+ } else if (error.name() == "org.ofono.Error.InProgress") {
2075+ throw std::runtime_error(result.error().print());
2076+ } else if (error.name() == "org.ofono.Error.InvalidArguments") {
2077+ throw std::logic_error(result.error().print());
2078+ } else if (error.name() == "org.ofono.Error.InvalidFormat") {
2079+ throw std::logic_error(result.error().print());
2080+ } else if (error.name() == "org.ofono.Error.Failed") {
2081+ return false;
2082+ }
2083+ }
2084+#endif
2085+ return true;
2086+ }
2087+
2088+ bool
2089+ lockPin(PinType type, std::string pin)
2090+ {
2091+ auto result =
2092+ object->invoke_method_synchronously<
2093+ SimManager::Method::LockPin, SimManager::Method::LockPin::ResultType>
2094+ (pin2str(type), pin);
2095+
2096+ if (result.is_error()) {
2097+ auto &error = result.error();
2098+ if (error.name() == "org.ofono.Error.NotImplemented") {
2099+ throw std::runtime_error(result.error().print());
2100+ } else if (error.name() == "org.ofono.Error.InProgress") {
2101+ throw std::runtime_error(result.error().print());
2102+ } else if (error.name() == "org.ofono.Error.InvalidArguments") {
2103+ throw std::logic_error(result.error().print());
2104+ } else if (error.name() == "org.ofono.Error.InvalidFormat") {
2105+ throw std::logic_error(result.error().print());
2106+ } else if (error.name() == "org.ofono.Error.Failed") {
2107+ return false;
2108+ }
2109+ }
2110+ return true;
2111+ }
2112+
2113+ bool
2114+ unlockPin(PinType type, std::string pin)
2115+ {
2116+ auto result =
2117+ object->invoke_method_synchronously<
2118+ SimManager::Method::UnlockPin, SimManager::Method::UnlockPin::ResultType>
2119+ (pin2str(type), pin);
2120+
2121+ if (result.is_error()) {
2122+ auto &error = result.error();
2123+ if (error.name() == "org.ofono.Error.NotImplemented") {
2124+ throw std::runtime_error(result.error().print());
2125+ } else if (error.name() == "org.ofono.Error.InProgress") {
2126+ throw std::runtime_error(result.error().print());
2127+ } else if (error.name() == "org.ofono.Error.InvalidArguments") {
2128+ throw std::logic_error(result.error().print());
2129+ } else if (error.name() == "org.ofono.Error.InvalidFormat") {
2130+ throw std::logic_error(result.error().print());
2131+ } else if (error.name() == "org.ofono.Error.Failed") {
2132+ return false;
2133+ }
2134+ }
2135+ return true;
2136+ }
2137+
2138+ typedef std::shared_ptr<SimManager> Ptr;
2139+ SimManager(const std::shared_ptr<core::dbus::Object>& object)
2140+ : object(object),
2141+ propertyChanged(object->get_signal<Signal::PropertyChanged>())
2142+ {
2143+ pinRequired.set(PinType::none);
2144+ present.set(false);
2145+ present.changed().connect([this](bool value){
2146+ // when sim goes away all the other properties are invalidated.
2147+ if (!value) {
2148+ lockedPins.set(std::set<PinType>());
2149+ pinRequired.set(PinType::none);
2150+ retries.set(std::map<PinType, std::uint8_t>());
2151+ subscriberIdentity.set("");
2152+ }
2153+ });
2154+
2155+ propertyChanged->connect([this](Signal::PropertyChanged::ArgumentType args){
2156+ _updateProperty(std::get<0>(args), std::get<1>(args));
2157+ });
2158+ auto result =
2159+ object->invoke_method_synchronously<
2160+ SimManager::Method::GetProperties, SimManager::Method::GetProperties::ResultType>();
2161+ if (result.is_error())
2162+ throw std::runtime_error(result.error().print());
2163+ for (auto element : result.value())
2164+ _updateProperty(element.first, element.second);
2165+ }
2166+
2167+ ~SimManager()
2168+ {}
2169+
2170+ void _updateProperty(std::string property, core::dbus::types::Variant value)
2171+ {
2172+ if (property == Property::LockedPins::name()) {
2173+ std::set<PinType> tmp;
2174+ for (auto str : value.as<Property::LockedPins::ValueType>()) {
2175+ tmp.insert(str2pin(str));
2176+ }
2177+ lockedPins.set(tmp);
2178+ } else if (property == Property::PinRequired::name()) {
2179+ pinRequired.set(str2pin(value.as<Property::PinRequired::ValueType>()));
2180+ } else if (property == Property::Present::name()) {
2181+ present.set(value.as<Property::Present::ValueType>());
2182+ } else if (property == Property::Retries::name()) {
2183+ std::map<PinType, std::uint8_t> tmp;
2184+ for (auto element : value.as<Property::Retries::ValueType>()) {
2185+ tmp[str2pin(element.first)] = element.second;
2186+ }
2187+ retries.set(tmp);
2188+ } else if (property == Property::SubscriberIdentity::name()) {
2189+ subscriberIdentity.set(value.as<Property::SubscriberIdentity::ValueType>());
2190+ } else {
2191+ //std::cout << std::string(__PRETTY_FUNCTION__) + ": unhandled property change: " + property << std::endl;
2192+ }
2193+ }
2194+
2195+ std::shared_ptr<core::dbus::Object> object;
2196+ std::shared_ptr<core::dbus::Signal<Signal::PropertyChanged, Signal::PropertyChanged::ArgumentType>> propertyChanged;
2197+
2198+ core::Property<std::set<PinType>> lockedPins;
2199+ core::Property<PinType> pinRequired;
2200+ core::Property<bool> present;
2201+ core::Property<std::map<PinType, std::uint8_t>> retries;
2202+ core::Property<std::string> subscriberIdentity;
2203+ }; // Interface::SimManager
2204+
2205+ struct Modem
2206+ {
2207+ static const std::string& name()
2208+ {
2209+ static const std::string s{OFONO_MODEM_INTERFACE};
2210+ return s;
2211+ }
2212+
2213+ struct Method
2214+ {
2215+ struct GetProperties
2216+ {
2217+ static const std::string& name()
2218+ {
2219+ static const std::string s{"GetProperties"};
2220+ return s;
2221+ }
2222+
2223+ typedef Modem Interface;
2224+ typedef std::map<std::string, core::dbus::types::Variant> ResultType;
2225+
2226+ static std::chrono::milliseconds default_timeout()
2227+ {
2228+ return std::chrono::seconds{1};
2229+ }
2230+ };
2231+ struct SetProperty
2232+ {
2233+ static const std::string& name()
2234+ {
2235+ static const std::string s{"SetProperty"};
2236+ return s;
2237+ }
2238+
2239+ typedef Modem Interface;
2240+ typedef void ResultType;
2241+
2242+ static std::chrono::milliseconds default_timeout()
2243+ {
2244+ return std::chrono::seconds{1};
2245+ }
2246+ };
2247+ };
2248+
2249+ struct Property
2250+ {
2251+ struct Interfaces
2252+ {
2253+ static const std::string &name()
2254+ {
2255+ static const std::string s{"Interfaces"};
2256+ return s;
2257+ }
2258+
2259+ typedef Modem Interface;
2260+ typedef std::vector<std::string> ValueType;
2261+ static const bool readable = true;
2262+ static const bool writable = false;
2263+
2264+ enum class Type
2265+ {
2266+ AssistedSatelliteNavigation,
2267+ AudioSettings,
2268+ CallBarring,
2269+ CallForwarding,
2270+ CallMeter,
2271+ CallSettings,
2272+ CallVolume,
2273+ CellBroadcast,
2274+ ConnectionManager,
2275+ Handsfree,
2276+ LocationReporting,
2277+ MessageManager,
2278+ MessageWaiting,
2279+ NetworkRegistration,
2280+ Phonebook,
2281+ PushNotification,
2282+ RadioSettings,
2283+ SimManager,
2284+ SmartMessaging,
2285+ SimToolkit,
2286+ SupplementaryServices,
2287+ TextTelephony,
2288+ VoiceCallManager,
2289+ };
2290+ };
2291+
2292+ struct Online
2293+ {
2294+ static const std::string &name()
2295+ {
2296+ static const std::string s{"Online"};
2297+ return s;
2298+ }
2299+
2300+ typedef Modem Interface;
2301+ typedef bool ValueType;
2302+ static const bool readable = true;
2303+ static const bool writable = true;
2304+ };
2305+
2306+ struct Serial
2307+ {
2308+ static const std::string &name()
2309+ {
2310+ static const std::string s{"Serial"};
2311+ return s;
2312+ }
2313+
2314+ typedef Modem Interface;
2315+ typedef std::string ValueType;
2316+ static const bool readable = true;
2317+ static const bool writable = false;
2318+ };
2319+
2320+ struct Type
2321+ {
2322+ static const std::string &name()
2323+ {
2324+ static const std::string s{"Type"};
2325+ return s;
2326+ }
2327+
2328+ typedef Modem Interface;
2329+ typedef std::string ValueType;
2330+ static const bool readable = true;
2331+ static const bool writable = false;
2332+ };
2333+
2334+ };
2335+
2336+ struct Signal
2337+ {
2338+ struct PropertyChanged
2339+ {
2340+ static const std::string& name()
2341+ {
2342+ static const std::string s{"PropertyChanged"};
2343+ return s;
2344+ }
2345+
2346+ typedef Modem Interface;
2347+ typedef std::tuple<std::string, core::dbus::types::Variant> ArgumentType;
2348+ };
2349+ };
2350+
2351+ enum class Type
2352+ {
2353+ test,
2354+ hfp,
2355+ sap,
2356+ hardware
2357+ };
2358+
2359+ Type str2type(std::string str)
2360+ {
2361+ if (str == "test")
2362+ return Type::test;
2363+ if (str == "hfp")
2364+ return Type::hfp;
2365+ if (str == "sap")
2366+ return Type::sap;
2367+ if (str == "hardware")
2368+ return Type::hardware;
2369+
2370+ /// @todo throw something.
2371+ std::cerr << "Unknown modem type: " << str << std::endl;
2372+ return Type::test;
2373+ }
2374+
2375+
2376+ typedef std::shared_ptr<Modem> Ptr;
2377+ Modem(const std::shared_ptr<core::dbus::Service>& service,
2378+ const std::shared_ptr<core::dbus::Object>& object)
2379+ : service(service),
2380+ object(object),
2381+ propertyChanged(object->get_signal<Signal::PropertyChanged>())
2382+ {
2383+ knownInterfaces = {std::make_pair(OFONO_GNSS_INTERFACE, Property::Interfaces::Type::AssistedSatelliteNavigation),
2384+ std::make_pair(OFONO_AUDIO_SETTINGS_INTERFACE, Property::Interfaces::Type::AudioSettings ),
2385+ std::make_pair(OFONO_CALL_BARRING_INTERFACE, Property::Interfaces::Type::CallBarring ),
2386+ std::make_pair(OFONO_CALL_FORWARDING_INTERFACE, Property::Interfaces::Type::CallForwarding ),
2387+ std::make_pair(OFONO_CALL_METER_INTERFACE, Property::Interfaces::Type::CallMeter ),
2388+ std::make_pair(OFONO_CALL_SETTINGS_INTERFACE, Property::Interfaces::Type::CallSettings ),
2389+ std::make_pair(OFONO_CALL_VOLUME_INTERFACE, Property::Interfaces::Type::CallVolume ),
2390+ std::make_pair(OFONO_CELL_BROADCAST_INTERFACE, Property::Interfaces::Type::CellBroadcast ),
2391+ std::make_pair(OFONO_CONNECTION_MANAGER_INTERFACE, Property::Interfaces::Type::ConnectionManager ),
2392+ std::make_pair(OFONO_HANDSFREE_INTERFACE, Property::Interfaces::Type::Handsfree ),
2393+ std::make_pair(OFONO_LOCATION_REPORTING_INTERFACE, Property::Interfaces::Type::LocationReporting ),
2394+ std::make_pair(OFONO_MESSAGE_MANAGER_INTERFACE, Property::Interfaces::Type::MessageManager ),
2395+ std::make_pair(OFONO_MESSAGE_WAITING_INTERFACE, Property::Interfaces::Type::MessageWaiting ),
2396+ std::make_pair(OFONO_NETWORK_REGISTRATION_INTERFACE, Property::Interfaces::Type::NetworkRegistration ),
2397+ std::make_pair(OFONO_PHONEBOOK_INTERFACE, Property::Interfaces::Type::Phonebook ),
2398+ std::make_pair("org.ofono.PushNotification", Property::Interfaces::Type::PushNotification ),
2399+ std::make_pair(OFONO_RADIO_SETTINGS_INTERFACE, Property::Interfaces::Type::RadioSettings ),
2400+ std::make_pair(OFONO_SIM_MANAGER_INTERFACE, Property::Interfaces::Type::SimManager ),
2401+ std::make_pair("org.ofono.SmartMessaging", Property::Interfaces::Type::SmartMessaging ),
2402+ std::make_pair(OFONO_STK_INTERFACE, Property::Interfaces::Type::SimToolkit ),
2403+ std::make_pair(OFONO_SUPPLEMENTARY_SERVICES_INTERFACE, Property::Interfaces::Type::SupplementaryServices ),
2404+ std::make_pair(OFONO_TEXT_TELEPHONY_INTERFACE, Property::Interfaces::Type::TextTelephony ),
2405+ std::make_pair(OFONO_VOICECALL_MANAGER_INTERFACE, Property::Interfaces::Type::VoiceCallManager )
2406+ };
2407+
2408+ interfaces.changed().connect([this](Property::Interfaces::ValueType values)
2409+ {
2410+ std::vector<Property::Interfaces::Type> newInterfaces;
2411+ for (auto interface : values) {
2412+ auto iter = knownInterfaces.find(interface);
2413+ if (iter != knownInterfaces.end()) {
2414+ newInterfaces.push_back(iter->second);
2415+ } else {
2416+ // custom interface, we don't care
2417+ std::cout << "Unknown Interface: " << interface << std::endl;
2418+ }
2419+ }
2420+
2421+ // construct a list of known interface types
2422+ std::vector<Property::Interfaces::Type> knownInterfaceTypes;
2423+ for (auto element : knownInterfaces)
2424+ knownInterfaceTypes.push_back(element.second);
2425+
2426+ // check which interfaces have been removed
2427+ for (auto known : knownInterfaceTypes)
2428+ {
2429+ switch (known) {
2430+ case Property::Interfaces::Type::AssistedSatelliteNavigation:
2431+ case Property::Interfaces::Type::AudioSettings:
2432+ case Property::Interfaces::Type::CallBarring:
2433+ case Property::Interfaces::Type::CallForwarding:
2434+ case Property::Interfaces::Type::CallMeter:
2435+ case Property::Interfaces::Type::CallSettings:
2436+ case Property::Interfaces::Type::CallVolume:
2437+ case Property::Interfaces::Type::CellBroadcast:
2438+ case Property::Interfaces::Type::ConnectionManager:
2439+ case Property::Interfaces::Type::Handsfree:
2440+ case Property::Interfaces::Type::LocationReporting:
2441+ case Property::Interfaces::Type::MessageManager:
2442+ case Property::Interfaces::Type::MessageWaiting:
2443+ break;
2444+ case Property::Interfaces::Type::NetworkRegistration:
2445+ {
2446+ if (std::find(newInterfaces.begin(), newInterfaces.end(), known) == newInterfaces.end() &&
2447+ networkRegistration->get()) {
2448+ networkRegistration.set(std::shared_ptr<NetworkRegistration>());
2449+ }
2450+ break;
2451+ }
2452+ case Property::Interfaces::Type::Phonebook:
2453+ case Property::Interfaces::Type::PushNotification:
2454+ case Property::Interfaces::Type::RadioSettings:
2455+ break;
2456+ case Property::Interfaces::Type::SimManager:
2457+ {
2458+ if (std::find(newInterfaces.begin(), newInterfaces.end(), known) == newInterfaces.end() &&
2459+ simManager->get()) {
2460+ simManager.set(std::shared_ptr<SimManager>());
2461+ }
2462+ break;
2463+ }
2464+ case Property::Interfaces::Type::SmartMessaging:
2465+ case Property::Interfaces::Type::SimToolkit:
2466+ case Property::Interfaces::Type::SupplementaryServices:
2467+ case Property::Interfaces::Type::TextTelephony:
2468+ case Property::Interfaces::Type::VoiceCallManager:
2469+ break;
2470+ }
2471+ }
2472+
2473+ // add new interfaces
2474+ for (auto type : newInterfaces) {
2475+ switch (type) {
2476+ case Property::Interfaces::Type::AssistedSatelliteNavigation:
2477+ case Property::Interfaces::Type::AudioSettings:
2478+ case Property::Interfaces::Type::CallBarring:
2479+ case Property::Interfaces::Type::CallForwarding:
2480+ case Property::Interfaces::Type::CallMeter:
2481+ case Property::Interfaces::Type::CallSettings:
2482+ case Property::Interfaces::Type::CallVolume:
2483+ case Property::Interfaces::Type::CellBroadcast:
2484+ case Property::Interfaces::Type::ConnectionManager:
2485+ case Property::Interfaces::Type::Handsfree:
2486+ case Property::Interfaces::Type::LocationReporting:
2487+ case Property::Interfaces::Type::MessageManager:
2488+ case Property::Interfaces::Type::MessageWaiting:
2489+ break;
2490+ case Property::Interfaces::Type::NetworkRegistration:
2491+ {
2492+ if (!networkRegistration->get()) {
2493+ networkRegistration.set(std::make_shared<NetworkRegistration>(this->object));
2494+ }
2495+ break;
2496+ }
2497+ case Property::Interfaces::Type::Phonebook:
2498+ case Property::Interfaces::Type::PushNotification:
2499+ case Property::Interfaces::Type::RadioSettings:
2500+ case Property::Interfaces::Type::SimManager:
2501+ {
2502+ if (!simManager->get()) {
2503+ simManager.set(std::make_shared<SimManager>(this->object));
2504+ }
2505+ break;
2506+ }
2507+ case Property::Interfaces::Type::SmartMessaging:
2508+ case Property::Interfaces::Type::SimToolkit:
2509+ case Property::Interfaces::Type::SupplementaryServices:
2510+ case Property::Interfaces::Type::TextTelephony:
2511+ case Property::Interfaces::Type::VoiceCallManager:
2512+ break;
2513+ }
2514+ }
2515+ });
2516+
2517+ propertyChanged->connect([this](Signal::PropertyChanged::ArgumentType arg) {
2518+ _updateProperty(std::get<0>(arg), std::get<1>(arg));
2519+ });
2520+ for (auto element : getProperties()) {
2521+ _updateProperty(element.first, element.second);
2522+ }
2523+ }
2524+
2525+ std::map<std::string, core::dbus::types::Variant>
2526+ getProperties()
2527+ {
2528+ auto result =
2529+ object->invoke_method_synchronously<
2530+ Modem::Method::GetProperties, Modem::Method::GetProperties::ResultType>();
2531+
2532+ if (result.is_error())
2533+ throw std::runtime_error(result.error().print());
2534+
2535+ return result.value();
2536+ }
2537+
2538+ void setProperty(const std::string &property, core::dbus::types::Variant value)
2539+ {
2540+// Possible Errors: [service].Error.InProgress
2541+// [service].Error.NotImplemented
2542+// [service].Error.InvalidArguments
2543+// [service].Error.NotAvailable
2544+// [service].Error.AccessDenied
2545+// [service].Error.Failed
2546+ auto result =
2547+ object->invoke_method_synchronously<
2548+ Modem::Method::SetProperty, Modem::Method::SetProperty::ResultType>(property, value);
2549+
2550+ if (result.is_error())
2551+ throw std::runtime_error(result.error().print());
2552+ }
2553+
2554+ ~Modem()
2555+ {}
2556+
2557+ void _updateProperty(const std::string &property, core::dbus::types::Variant value)
2558+ {
2559+ if (property == Property::Interfaces::name()) {
2560+ auto newValue = value.as<Property::Interfaces::ValueType>();
2561+ interfaces.set(newValue);
2562+ } else if (property == Property::Online::name()) {
2563+ online.set(value.as<Property::Online::ValueType>());
2564+ } else if (property == Property::Serial::name()) {
2565+ serial.set(value.as<Property::Serial::ValueType>());
2566+ } else if (property == Property::Type::name()) {
2567+ type.set(str2type(value.as<Property::Type::ValueType>()));
2568+ } else {
2569+ //std::cout << std::string(__PRETTY_FUNCTION__) + ": unhandled property change: " + property << std::endl;
2570+ }
2571+ }
2572+
2573+ std::shared_ptr<core::dbus::Service> service;
2574+ std::shared_ptr<core::dbus::Object> object;
2575+
2576+ core::Property<Property::Interfaces::ValueType> interfaces;
2577+ core::Property<bool> online;
2578+ core::Property<std::string> serial;
2579+ core::Property<Type> type;
2580+
2581+ std::shared_ptr<core::dbus::Signal<Signal::PropertyChanged, Signal::PropertyChanged::ArgumentType>> propertyChanged;
2582+
2583+ core::Property<NetworkRegistration::Ptr> networkRegistration;
2584+ core::Property<SimManager::Ptr> simManager;
2585+
2586+ std::map<std::string, Property::Interfaces::Type> knownInterfaces;
2587+
2588+ }; // Interface::Modem
2589+
2590+ struct Manager
2591+ {
2592+ static const std::string& name()
2593+ {
2594+ static const std::string s{OFONO_MANAGER_INTERFACE};
2595+ return s;
2596+ }
2597+
2598+ struct Method
2599+ {
2600+ struct GetModems
2601+ {
2602+ static const std::string& name()
2603+ {
2604+ static const std::string s{"GetModems"};
2605+ return s;
2606+ }
2607+
2608+ typedef Manager Interface;
2609+ typedef std::vector<core::dbus::types::Struct<core::dbus::types::ObjectPath>> ResultType;
2610+
2611+ static std::chrono::milliseconds default_timeout()
2612+ {
2613+ return std::chrono::seconds{1};
2614+ }
2615+ };
2616+ };
2617+
2618+ struct Signal
2619+ {
2620+ struct ModemAdded
2621+ {
2622+ static const std::string& name()
2623+ {
2624+ static const std::string s{"ModemAdded"};
2625+ return s;
2626+ }
2627+
2628+ typedef Manager Interface;
2629+ typedef std::tuple<core::dbus::types::ObjectPath, std::map<std::string, core::dbus::types::Variant>> ArgumentType;
2630+ };
2631+
2632+ struct ModemRemoved
2633+ {
2634+ static const std::string& name()
2635+ {
2636+ static const std::string s{"ModemRemoved"};
2637+ return s;
2638+ }
2639+
2640+ typedef Manager Interface;
2641+ typedef core::dbus::types::ObjectPath ArgumentType;
2642+ };
2643+ };
2644+
2645+ Manager(std::shared_ptr<core::dbus::Service> &service,
2646+ std::shared_ptr<core::dbus::Object> &object)
2647+ : service(service),
2648+ object(object),
2649+ modem_added (object->get_signal<Signal::ModemAdded>()),
2650+ modem_removed(object->get_signal<Signal::ModemRemoved>())
2651+ {
2652+ auto result = object->invoke_method_synchronously<Method::GetModems, Method::GetModems::ResultType>();
2653+
2654+ if (result.is_error())
2655+ throw std::runtime_error(result.error().print());
2656+
2657+ std::map<core::dbus::types::ObjectPath, Modem::Ptr> tmp;
2658+ for (const auto& element : result.value())
2659+ {
2660+ tmp.insert(std::make_pair(element.value, std::make_shared<Modem>(service, service->object_for_path(element.value))));
2661+ }
2662+ modems.set(tmp);
2663+
2664+ modem_added->connect([this](const Signal::ModemAdded::ArgumentType& arg)
2665+ {
2666+ auto current = modems.get();
2667+ current.insert(std::make_pair(std::get<0>(arg),std::make_shared<Modem>(this->service, this->service->object_for_path(std::get<0>(arg)))));
2668+ modems.set(current);
2669+ });
2670+
2671+ modem_removed->connect([this](const Signal::ModemRemoved::ArgumentType& arg)
2672+ {
2673+ auto current = modems.get();
2674+ current.erase(arg);
2675+ modems.set(current);
2676+ });
2677+ }
2678+
2679+ ~Manager()
2680+ {}
2681+
2682+ std::shared_ptr<core::dbus::Service> service;
2683+ std::shared_ptr<core::dbus::Object> object;
2684+
2685+ std::shared_ptr<
2686+ core::dbus::Signal<Signal::ModemAdded,
2687+ Signal::ModemAdded::ArgumentType>
2688+ > modem_added;
2689+
2690+ std::shared_ptr<
2691+ core::dbus::Signal<Signal::ModemRemoved,
2692+ Signal::ModemRemoved::ArgumentType>
2693+ > modem_removed;
2694+
2695+ core::Property<std::map<core::dbus::types::ObjectPath, Modem::Ptr>> modems;
2696+ }; // Interface::Manager
2697+
2698+
2699+}; // Interface
2700+
2701+struct Service
2702+{
2703+ std::shared_ptr<Interface::Manager> manager;
2704+
2705+ static const std::string& name()
2706+ {
2707+ static const std::string s{OFONO_SERVICE};
2708+ return s;
2709+ }
2710+
2711+
2712+ Service(const core::dbus::Bus::Ptr& bus)
2713+ {
2714+ auto service = core::dbus::Service::use_service<Service>(bus);
2715+ auto object = service->object_for_path(core::dbus::types::ObjectPath(OFONO_MANAGER_PATH));
2716+ manager = std::make_shared<Interface::Manager>(service, object);
2717+ }
2718+
2719+ struct Mock
2720+ {
2721+ std::shared_ptr<Interface::Manager> manager;
2722+
2723+ Mock(const core::dbus::Bus::Ptr& bus)
2724+ {
2725+ auto service = core::dbus::Service::add_service<Service>(bus);
2726+ auto object = service->add_object_for_path(core::dbus::types::ObjectPath(OFONO_MANAGER_PATH));
2727+ manager = std::make_shared<Interface::Manager>(service, object);
2728+ }
2729+ };
2730+};
2731+
2732+}
2733+}
2734+
2735+#endif // DBUS_CPP_SERVICES_OFONO_H
2736+
2737
2738=== removed file 'network/device-base.vala'
2739--- network/device-base.vala 2013-10-25 18:35:27 +0000
2740+++ network/device-base.vala 1970-01-01 00:00:00 +0000
2741@@ -1,245 +0,0 @@
2742-// vim: tabstop=4 noexpandtab shiftwidth=4 softtabstop=4
2743-/*
2744- * Copyright 2013 Canonical Ltd.
2745- *
2746- * This program is free software; you can redistribute it and/or modify
2747- * it under the terms of the GNU General Public License as published by
2748- * the Free Software Foundation; version 3.
2749- *
2750- * This program is distributed in the hope that it will be useful,
2751- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2752- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2753- * GNU Lesser General Public License for more details.
2754- *
2755- * You should have received a copy of the GNU Lesser General Public License
2756- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2757- *
2758- * Authors:
2759- * Ted Gould <ted.gould@canonical.com>
2760- */
2761-
2762-namespace Network.Device
2763-{
2764-
2765- public class Base : MenuModel {
2766- NM.Client _client;
2767- NM.Device _device;
2768- string _namespace;
2769- GLibLocal.ActionMuxer _muxer;
2770- protected Menu _menu = new Menu();
2771-
2772- protected GLib.SimpleActionGroup actions = new GLib.SimpleActionGroup();
2773- protected GLib.SimpleAction enabled_action = new SimpleAction.stateful("device-enabled", null, new Variant.boolean(false));
2774- protected GLib.SimpleAction busy_action = new SimpleAction.stateful("device-busy", null, new Variant.boolean(false));
2775-
2776- private NM.ActiveConnection? active_connection = null;
2777- private ulong active_connection_notify = 0;
2778-
2779- /*****************************
2780- * Properties
2781- *****************************/
2782- public NM.Device device {
2783- construct {
2784- _device = value;
2785- return;
2786- }
2787- get {
2788- return _device;
2789- }
2790- }
2791-
2792- public NM.Client client {
2793- construct {
2794- _client = value;
2795- return;
2796- }
2797- get {
2798- return _client;
2799- }
2800- }
2801-
2802- public string namespace {
2803- construct {
2804- _namespace = value;
2805- return;
2806- }
2807- get {
2808- return _namespace;
2809- }
2810- }
2811-
2812- public GLibLocal.ActionMuxer muxer {
2813- construct {
2814- _muxer = value;
2815- return;
2816- }
2817- get {
2818- return _muxer;
2819- }
2820- }
2821-
2822- /*****************************
2823- * Functions
2824- *****************************/
2825-
2826- construct {
2827- _menu.items_changed.connect(menu_items_changed);
2828-
2829- actions.insert(enabled_action);
2830- actions.insert(busy_action);
2831-
2832- _muxer.insert(_namespace, actions);
2833-
2834- enabled_action.activate.connect((param) => {
2835- if (enabled_action.state.get_boolean()) {
2836- disable_device();
2837- } else {
2838- enable_device();
2839- }
2840- });
2841-
2842- device.state_changed.connect (device_state_changed);
2843-
2844- device.notify.connect((pspec) => {
2845- if (pspec.name == "active-connection") {
2846- active_connection_changed();
2847- }
2848- });
2849- active_connection_changed();
2850-
2851- }
2852-
2853- ~Base ()
2854- {
2855- muxer.remove(namespace);
2856- }
2857-
2858- protected virtual void enable_device ()
2859- {
2860- warning("Subclass doesn't have a way to enable the device");
2861- return;
2862- }
2863-
2864- protected virtual void disable_device ()
2865- {
2866- device.disconnect(null);
2867- return;
2868- }
2869-
2870- private void device_state_changed (NM.Device dev, uint old_state, uint new_state, uint reason) {
2871- switch (new_state) {
2872- case NM.DeviceState.PREPARE:
2873- case NM.DeviceState.CONFIG:
2874- case NM.DeviceState.NEED_AUTH:
2875- case NM.DeviceState.IP_CONFIG:
2876- case NM.DeviceState.IP_CHECK:
2877- case NM.DeviceState.SECONDARIES:
2878- debug("Marking '" + dev.get_iface() + "' as Activating");
2879- busy_action.set_state(new Variant.boolean(true));
2880- enabled_action.set_state(new Variant.boolean(true));
2881- break;
2882- case NM.DeviceState.ACTIVATED:
2883- debug("Marking '" + dev.get_iface() + "' as Active");
2884- busy_action.set_state(new Variant.boolean(false));
2885- enabled_action.set_state(new Variant.boolean(true));
2886- break;
2887- case NM.DeviceState.DEACTIVATING:
2888- debug("Marking '" + dev.get_iface() + "' as Deactivating");
2889- busy_action.set_state(new Variant.boolean(true));
2890- enabled_action.set_state(new Variant.boolean(false));
2891- break;
2892- default:
2893- debug("Marking '" + dev.get_iface() + "' as Disabled");
2894- busy_action.set_state(new Variant.boolean(false));
2895- enabled_action.set_state(new Variant.boolean(false));
2896- break;
2897- }
2898- }
2899-
2900- private void active_connection_changed () {
2901- if (active_connection != null) {
2902- active_connection.disconnect(active_connection_notify);
2903- }
2904-
2905- active_connection = this.device.get_active_connection();
2906-
2907- if (active_connection != null) {
2908- active_connection_notify = active_connection.notify.connect((pspec) => {
2909- if (pspec.name == "state") {
2910- active_connection_state_changed(active_connection.state);
2911- }
2912- });
2913-
2914- active_connection_state_changed(active_connection.state);
2915- }
2916- }
2917-
2918- private void active_connection_state_changed (uint new_state) {
2919- switch (new_state) {
2920- case NM.ActiveConnectionState.ACTIVATING:
2921- debug("Marking '" + device.get_iface() + "' as Activating");
2922- busy_action.set_state(new Variant.boolean(true));
2923- enabled_action.set_state(new Variant.boolean(true));
2924- break;
2925- case NM.ActiveConnectionState.ACTIVATED:
2926- debug("Marking '" + device.get_iface() + "' as Active");
2927- busy_action.set_state(new Variant.boolean(false));
2928- enabled_action.set_state(new Variant.boolean(true));
2929- break;
2930- case NM.ActiveConnectionState.DEACTIVATING:
2931- debug("Marking '" + device.get_iface() + "' as Deactivating");
2932- busy_action.set_state(new Variant.boolean(true));
2933- enabled_action.set_state(new Variant.boolean(false));
2934- break;
2935- default:
2936- debug("Marking '" + device.get_iface() + "' as Disabled");
2937- busy_action.set_state(new Variant.boolean(false));
2938- enabled_action.set_state(new Variant.boolean(false));
2939- break;
2940- }
2941- }
2942-
2943- void menu_items_changed (int position, int removed, int added) {
2944- (this as MenuModel).items_changed(position, removed, added);
2945- }
2946-
2947- /***********************************
2948- * Passing on functions to our menu
2949- ***********************************/
2950- public override GLib.Variant get_item_attribute_value (int item_index, string attribute, GLib.VariantType? expected_type) {
2951- return (_menu as MenuModel).get_item_attribute_value(item_index, attribute, expected_type);
2952- }
2953-
2954- public override void get_item_attributes (int item_index, [CCode (type = "GHashTable**")] out GLib.HashTable<string,GLib.Variant>? attributes) {
2955- (_menu as MenuModel).get_item_attributes(item_index, out attributes);
2956- }
2957-
2958- public override GLib.MenuModel get_item_link (int item_index, string link) {
2959- return (_menu as MenuModel).get_item_link(item_index, link);
2960- }
2961-
2962- public override void get_item_links (int item_index, [CCode (type = "GHashTable**")] out GLib.HashTable<string,GLib.MenuModel>? links) {
2963- (_menu as MenuModel).get_item_links(item_index, out links);
2964- }
2965-
2966- public override int get_n_items () {
2967- return (_menu as MenuModel).get_n_items();
2968- }
2969-
2970- public override bool is_mutable () {
2971- return (_menu as MenuModel).is_mutable();
2972- }
2973-
2974- public override GLib.MenuAttributeIter iterate_item_attributes (int item_index) {
2975- return (_menu as MenuModel).iterate_item_attributes(item_index);
2976- }
2977-
2978- public override GLib.MenuLinkIter iterate_item_links (int item_index) {
2979- return (_menu as MenuModel).iterate_item_links(item_index);
2980- }
2981-
2982-
2983- }
2984-
2985-} // namespace
2986-
2987
2988=== removed file 'network/device-ethernet.vala'
2989--- network/device-ethernet.vala 2013-08-25 19:00:08 +0000
2990+++ network/device-ethernet.vala 1970-01-01 00:00:00 +0000
2991@@ -1,64 +0,0 @@
2992-// vim: tabstop=4 noexpandtab shiftwidth=4 softtabstop=4
2993-/*
2994- * Copyright 2013 Canonical Ltd.
2995- *
2996- * This program is free software; you can redistribute it and/or modify
2997- * it under the terms of the GNU General Public License as published by
2998- * the Free Software Foundation; version 3.
2999- *
3000- * This program is distributed in the hope that it will be useful,
3001- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3002- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3003- * GNU Lesser General Public License for more details.
3004- *
3005- * You should have received a copy of the GNU Lesser General Public License
3006- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3007- *
3008- * Authors:
3009- * Ted Gould <ted.gould@canonical.com>
3010- */
3011-
3012-using NM;
3013-
3014-namespace Network.Device
3015-{
3016- public class Ethernet : Base {
3017- private GLib.MenuItem enabled_item;
3018-
3019- public Ethernet (NM.Client client, NM.DeviceEthernet device, GLibLocal.ActionMuxer muxer) {
3020- GLib.Object(
3021- client: client,
3022- device: device,
3023- namespace: device.get_iface(),
3024- muxer: muxer
3025- );
3026-
3027- enabled_item = new MenuItem(_("Wired"), "indicator." + device.get_iface() + ".device-enabled");
3028- enabled_item.set_attribute ("x-canonical-type" , "s", "com.canonical.indicator.switch");
3029- _menu.append_item(enabled_item);
3030- /* TODO: Need busy action */
3031- }
3032-
3033- ~Ethernet ()
3034- {
3035- muxer.remove(namespace);
3036- }
3037-
3038- protected override void enable_device ()
3039- {
3040- var conn = new NM.Connection();
3041-
3042- var swired = new NM.SettingWired();
3043- conn.add_setting(swired);
3044-
3045- var sconn = new NM.SettingConnection();
3046- sconn.id = "Auto Ethernet";
3047- sconn.type = NM.SettingWired.SETTING_NAME;
3048- sconn.autoconnect = true;
3049- sconn.uuid = NM.Utils.uuid_generate();
3050- conn.add_setting(sconn);
3051-
3052- client.add_and_activate_connection(conn, this.device, "/", null);
3053- }
3054- }
3055-}
3056
3057=== removed file 'network/device-mobile.vala'
3058--- network/device-mobile.vala 2013-09-16 14:03:30 +0000
3059+++ network/device-mobile.vala 1970-01-01 00:00:00 +0000
3060@@ -1,166 +0,0 @@
3061-// vim: tabstop=4 noexpandtab shiftwidth=4 softtabstop=4
3062-/*
3063- * Copyright 2013 Canonical Ltd.
3064- *
3065- * This program is free software; you can redistribute it and/or modify
3066- * it under the terms of the GNU General Public License as published by
3067- * the Free Software Foundation; version 3.
3068- *
3069- * This program is distributed in the hope that it will be useful,
3070- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3071- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3072- * GNU Lesser General Public License for more details.
3073- *
3074- * You should have received a copy of the GNU Lesser General Public License
3075- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3076- *
3077- * Authors:
3078- * Ted Gould <ted.gould@canonical.com>
3079- */
3080-
3081-using NM;
3082-
3083-namespace Network.Device
3084-{
3085- internal class MobileMenu
3086- {
3087- private NM.Client client;
3088- private NM.DeviceModem device;
3089- private Menu apsmenu;
3090- private string action_prefix;
3091- private MobileSimManager mobilesimmanager;
3092-
3093- private MenuItem device_item;
3094- private MenuItem settings_item;
3095- private MenuItem? unlock_sim_item = null;
3096-
3097- public MobileMenu (NM.Client client, DeviceModem device, Menu global_menu, string action_prefix, bool show_enable, MobileSimManager mobilesimmanager)
3098- {
3099- this.client = client;
3100- this.device = device;
3101- this.apsmenu = global_menu;
3102- this.action_prefix = action_prefix;
3103- this.mobilesimmanager = mobilesimmanager;
3104-
3105- if (show_enable) {
3106- device_item = create_item_for_mobile_device();
3107- this.apsmenu.append_item(device_item);
3108- }
3109-
3110- settings_item = new MenuItem(_("Cellular settings…"), "indicator.global.settings::cellular");
3111- this.apsmenu.append_item(settings_item);
3112-
3113- update_sim_lock_menu(mobilesimmanager.pin_required);
3114- mobilesimmanager.notify["pin-required"].connect((s, value) => {
3115- update_sim_lock_menu(mobilesimmanager.pin_required);
3116- });
3117- }
3118-
3119- ~MobileMenu ()
3120- {
3121- }
3122-
3123- private MenuItem create_item_for_mobile_device ()
3124- {
3125- var device_item = new MenuItem(_("Cellular"), action_prefix + ".device-enabled");
3126- device_item.set_attribute ("x-canonical-type" , "s", "com.canonical.indicator.switch");
3127-
3128- return device_item;
3129- }
3130-
3131- private void update_sim_lock_menu(bool pin_required)
3132- {
3133- string action_name = action_prefix + "unlock";
3134- debug(@"sim lock updated $(pin_required) - action $action_name");
3135- for (int i = 0; i < apsmenu.get_n_items(); i++)
3136- {
3137- string name;
3138-
3139- if (!apsmenu.get_item_attribute (i, "action", "s", out name))
3140- continue;
3141- debug(@"update_sim_lock_menu action $name");
3142-
3143- if (name == action_name) {
3144- if (!pin_required) {
3145- apsmenu.remove (i);
3146- }
3147- return;
3148- }
3149- }
3150-
3151- if (pin_required) {
3152- unlock_sim_item = new MenuItem(_("Unlock SIM…"), action_name);
3153- apsmenu.insert_item (0, unlock_sim_item);
3154- } else {
3155- unlock_sim_item = null;
3156- }
3157- }
3158- }
3159-
3160- internal class MobileActionManager
3161- {
3162- private SimpleActionGroup actions;
3163- private NM.Client client;
3164- private NM.DeviceModem device;
3165- private MobileSimManager mobilesimmanager;
3166- private SimpleAction unlock_action;
3167-
3168- public MobileActionManager (SimpleActionGroup actions, NM.Client client, NM.DeviceModem device, MobileSimManager mobilesimmanager)
3169- {
3170- this.actions = actions;
3171- this.client = client;
3172- this.device = device;
3173- this.mobilesimmanager = mobilesimmanager;
3174-
3175- unlock_action = new SimpleAction("unlock", null);
3176- unlock_action.activate.connect((ac,ps) => {
3177- if (mobilesimmanager.pin_unlocking) {
3178- debug(@"SIM unlock already in progress");
3179- return;
3180- }
3181- mobilesimmanager.send_unlock_notification();
3182- });
3183- actions.insert(unlock_action);
3184-
3185- unlock_action.set_enabled(mobilesimmanager.pin_required && !mobilesimmanager.pin_unlocking);
3186- mobilesimmanager.notify["pin-required"].connect((s, value) => {
3187- unlock_action.set_enabled(mobilesimmanager.pin_required && !mobilesimmanager.pin_unlocking);
3188- });
3189- mobilesimmanager.notify["pin-unlocking"].connect((s, value) => {
3190- unlock_action.set_enabled(mobilesimmanager.pin_required && !mobilesimmanager.pin_unlocking);
3191- });
3192- }
3193- }
3194-
3195- public class Mobile : Base {
3196- private MobileMenu mobilemenu;
3197- private MobileActionManager mobileactionmanager;
3198- private MobileSimManager mobilesimmanager;
3199-
3200- public Mobile (NM.Client client, NM.DeviceModem device, GLibLocal.ActionMuxer muxer, bool show_enable, GLib.DBusConnection conn) {
3201- GLib.Object(
3202- client: client,
3203- device: device,
3204- namespace: device.get_iface(),
3205- muxer: muxer
3206- );
3207-
3208- mobilesimmanager = new MobileSimManager(client, device, conn, this.namespace);
3209- mobilemenu = new MobileMenu(client, device, this._menu, "indicator." + this.namespace + ".", show_enable, mobilesimmanager);
3210- mobileactionmanager = new MobileActionManager(actions, client, device, mobilesimmanager);
3211- }
3212-
3213- protected override void disable_device ()
3214- {
3215- device.disconnect(null);
3216- client.wwan_set_enabled(false);
3217- }
3218-
3219- protected override void enable_device ()
3220- {
3221- client.wwan_set_enabled(true);
3222- device.set_autoconnect(true);
3223- }
3224- }
3225-
3226-}
3227
3228=== removed file 'network/device-wifi.vala'
3229--- network/device-wifi.vala 2013-10-15 10:09:59 +0000
3230+++ network/device-wifi.vala 1970-01-01 00:00:00 +0000
3231@@ -1,578 +0,0 @@
3232-// vim: tabstop=4 noexpandtab shiftwidth=4 softtabstop=4
3233-/*
3234- * Copyright 2013 Canonical Ltd.
3235- *
3236- * This program is free software; you can redistribute it and/or modify
3237- * it under the terms of the GNU General Public License as published by
3238- * the Free Software Foundation; version 3.
3239- *
3240- * This program is distributed in the hope that it will be useful,
3241- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3242- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3243- * GNU Lesser General Public License for more details.
3244- *
3245- * You should have received a copy of the GNU Lesser General Public License
3246- * along with this program. If not, see <http://www.gnu.org/licenses/>.
3247- *
3248- * Authors:
3249- * Ted Gould <ted.gould@canonical.com>
3250- */
3251-
3252-using NM;
3253-
3254-namespace Network.Device
3255-{
3256- internal class WifiMenu
3257- {
3258- private Menu apsmenu;
3259- private MenuItem device_item;
3260- private MenuItem settings_item;
3261- public DeviceWifi device;
3262- private NM.Client client;
3263- private string action_prefix;
3264- private bool show_settings;
3265- private HashTable<string, NM.AccessPoint> aps = new HashTable<string, NM.AccessPoint>(str_hash, str_equal);
3266-
3267- public WifiMenu (NM.Client client, DeviceWifi device, Menu global_menu, string action_prefix, bool show_settings)
3268- {
3269- this.apsmenu = global_menu;
3270- this.device = device;
3271- this.client = client;
3272- this.action_prefix = action_prefix;
3273- this.show_settings = show_settings;
3274-
3275- device_item = create_item_for_wifi_device ();
3276- this.apsmenu.append_item(device_item);
3277-
3278- if (show_settings) {
3279- settings_item = new MenuItem(_("Wi-Fi settings…"), "indicator.global.settings::wifi");
3280- this.apsmenu.append_item(settings_item);
3281- }
3282-
3283- device.access_point_added.connect (access_point_added_cb);
3284- device.access_point_removed.connect (access_point_removed_cb);
3285- device.notify.connect (active_access_point_changed);
3286-
3287- var aps = device.get_access_points ();
3288-
3289- if (aps == null)
3290- return;
3291-
3292- for (uint i = 0; i<aps.length; i++)
3293- {
3294- access_point_added_cb (device, aps.get (i));
3295- }
3296- }
3297-
3298- ~WifiMenu ()
3299- {
3300- /* Make sure to clean up! */
3301- foreach (var ap in aps.get_values()) {
3302- access_point_removed_cb(this.device, ap);
3303- }
3304-
3305- device.access_point_added.disconnect (access_point_added_cb);
3306- device.access_point_removed.disconnect (access_point_removed_cb);
3307- device.notify.disconnect (active_access_point_changed);
3308- }
3309-
3310-
3311- private void bind_ap_item (AccessPoint ap, MenuItem item)
3312- {
3313- var strength_action_id = action_prefix + ap.get_path () + "::strength";
3314- var activate_action_id = action_prefix + ap.get_path ();
3315-
3316- item.set_label (Utils.ssid_to_utf8 (ap.get_ssid ()));
3317- item.set_attribute ("x-canonical-type", "s", "unity.widgets.systemsettings.tablet.accesspoint");
3318- item.set_attribute ("x-canonical-wifi-ap-is-adhoc", "b", ap.get_mode () == NM.80211Mode.ADHOC);
3319- item.set_attribute ("x-canonical-wifi-ap-is-secure", "b", ap.get_flags () == NM.80211ApFlags.PRIVACY);
3320- item.set_attribute ("x-canonical-wifi-ap-bssid", "s", ap.get_bssid ());
3321- item.set_attribute ("x-canonical-wifi-ap-dbus-path", "s", ap.get_path ());
3322-
3323- item.set_attribute ("x-canonical-wifi-ap-strength-action", "s", strength_action_id);
3324- item.set_attribute ("action", "s", activate_action_id);
3325- }
3326-
3327- private void access_point_ssid_cb (GLib.Object obj, GLib.ParamSpec pspec)
3328- {
3329- AccessPoint ap = (AccessPoint)obj;
3330- remove_ap_item(ap);
3331- insert_ap_item(ap);
3332- }
3333-
3334- private void access_point_added_cb (NM.DeviceWifi device, GLib.Object user_data)
3335- {
3336- AccessPoint ap = (AccessPoint)user_data;
3337- string ap_path = ap.get_path();
3338-
3339- if (aps.lookup(ap_path) == null) {
3340- aps.insert(ap_path, ap);
3341- insert_ap_item (ap);
3342-
3343- ap.notify["ssid"].connect(access_point_ssid_cb);
3344- }
3345- }
3346-
3347- private void access_point_removed_cb (NM.DeviceWifi device, GLib.Object user_data)
3348- {
3349- AccessPoint ap = (AccessPoint)user_data;
3350- string ap_path = ap.get_path();
3351-
3352- if (aps.lookup(ap_path) != null) {
3353- ap.notify["ssid"].disconnect(access_point_ssid_cb);
3354- aps.remove(ap_path);
3355- remove_ap_item (ap);
3356- }
3357- }
3358-
3359- private void active_access_point_changed (GLib.Object obj, ParamSpec pspec)
3360- {
3361- if (pspec.get_name () != "active-access-point")
3362- return;
3363-
3364- if (apsmenu == null)
3365- return;
3366-
3367- set_active_ap (device.active_access_point);
3368- }
3369-
3370- private MenuItem create_item_for_wifi_device ()
3371- {
3372- var device_item = new MenuItem (_("Wi-Fi"), action_prefix + "device-enabled");
3373- device_item.set_attribute ("x-canonical-type" , "s", "com.canonical.indicator.switch");
3374- device_item.set_attribute ("x-canonical-busy-action", "s", action_prefix + "device-busy");
3375-
3376- return device_item;
3377- }
3378-
3379- /*
3380- * AccessPoints are inserted with the follow priority policy:
3381- * - The active access point of the device always goes first
3382- * - Previously used APs go first
3383- * - Previously used APs are ordered by signal strength
3384- * - Unused APs are ordered by signal strength
3385- */
3386- private void insert_ap_item (AccessPoint ap)
3387- {
3388- var rs = new NM.RemoteSettings (null);
3389- SList <NM.Connection>? dev_conns = null;
3390- bool has_connection = false;
3391- string label;
3392-
3393- if (ap == null)
3394- return;
3395-
3396- if (UtilWrapper.is_empty_ssid(ap.get_ssid ()))
3397- return;
3398-
3399- label = Utils.ssid_to_utf8(ap.get_ssid ());
3400- if (label == null || label[0] == '\0')
3401- return;
3402-
3403- //If it is the active access point it always goes first
3404- if (ap == device.active_access_point)
3405- {
3406- var item = new MenuItem (null, null);
3407- bind_ap_item (ap, item);
3408- apsmenu.insert_item (1, item);
3409- //TODO: Remove duplicates???
3410- return;
3411- }
3412-
3413- var conns = rs.list_connections ();
3414- if (conns.length () > 0)
3415- {
3416- dev_conns = device.filter_connections (conns);
3417- if (dev_conns.length () > 0)
3418- has_connection = ap_has_connections (ap, dev_conns);
3419- }
3420-
3421-
3422- //Remove duplicate SSID
3423- for (int i = 0; i < apsmenu.get_n_items(); i++)
3424- {
3425- string path;
3426-
3427- if (!apsmenu.get_item_attribute (i, "x-canonical-wifi-ap-dbus-path", "s", out path))
3428- continue;
3429-
3430- var i_ap = device.get_access_point_by_path (path);
3431- if (i_ap == null)
3432- continue;
3433-
3434- //If both have the same SSID and security flags they are a duplicate
3435- if (Utils.same_ssid (i_ap.get_ssid (), ap.get_ssid (), false) && i_ap.get_flags () == ap.get_flags ())
3436- {
3437-
3438- //The one AP with the srongest signal wins
3439- if (i_ap.get_strength () >= ap.get_strength ())
3440- return;
3441-
3442- apsmenu.remove (i);
3443- continue;
3444- }
3445- }
3446-
3447- //Find the right spot for the AP
3448- var item = new MenuItem (null, null);
3449- bind_ap_item (ap, item);
3450- for (int i = 0; i < apsmenu.get_n_items(); i++)
3451- {
3452- string path;
3453-
3454- if (!apsmenu.get_item_attribute (i, "x-canonical-wifi-ap-dbus-path", "s", out path))
3455- continue;
3456- var i_ap = device.get_access_point_by_path (path);
3457-
3458- if (i_ap == null)
3459- continue;
3460-
3461- //APs that have been used previously have priority
3462- if (ap_has_connections(i_ap, dev_conns))
3463- {
3464- if (!has_connection)
3465- continue;
3466- }
3467- //APs with higher strenght have priority
3468- if (ap.get_strength () > i_ap.get_strength ())
3469- {
3470- apsmenu.insert_item (i, item);
3471- return;
3472- }
3473- }
3474-
3475- //AP is last in the menu (avoid the settings item)
3476- if (show_settings) {
3477- apsmenu.insert_item (apsmenu.get_n_items() - 1, item);
3478- } else {
3479- apsmenu.append_item (item);
3480- }
3481- }
3482-
3483- private void set_active_ap (AccessPoint? ap)
3484- {
3485- //TODO: Set the previously active AP in the right order
3486- if (ap == null)
3487- return;
3488-
3489- for (int i = 1; i < apsmenu.get_n_items(); i++)
3490- {
3491- string path;
3492- if (!apsmenu.get_item_attribute (i, "action", "s", out path))
3493- continue;
3494- if (path != ap.get_path ())
3495- continue;
3496- apsmenu.remove (i);
3497- var item = new MenuItem (null, null);
3498- bind_ap_item (ap, item);
3499- apsmenu.append_item (item);
3500- }
3501- }
3502-
3503- private static bool ap_has_connections (AccessPoint ap, SList<NM.Connection>? dev_conns)
3504- {
3505- if (dev_conns.length () < 1)
3506- return false;
3507-
3508- var ap_conns = ap.filter_connections (dev_conns);
3509- return ap_conns.length () > 0;
3510- }
3511-
3512- private void remove_ap_item (AccessPoint ap)
3513- {
3514- for (int i = 1; i < apsmenu.get_n_items(); i++)
3515- {
3516- string path;
3517-
3518- if (!apsmenu.get_item_attribute (i, "x-canonical-wifi-ap-dbus-path", "s", out path))
3519- continue;
3520-
3521- if (path == ap.get_path ())
3522- {
3523- apsmenu.remove (i);
3524- return;
3525- }
3526- }
3527- }
3528- }
3529-
3530- internal class WifiActionManager
3531- {
3532- private SimpleActionGroup actions;
3533- private NM.Client client;
3534- public NM.RemoteSettings rs = null;
3535-
3536- public NM.DeviceWifi wifidev = null;
3537-
3538- public WifiActionManager (SimpleActionGroup actions, NM.Client client, NM.DeviceWifi dev)
3539- {
3540- this.client = client;
3541- this.actions = actions;
3542- this.wifidev = dev;
3543- this.rs = new NM.RemoteSettings (null);
3544-
3545- /* This object should be disposed by ActionManager on device removal
3546- * but we still disconnect signals if that signal is emmited before
3547- * this object was disposed
3548- */
3549- client.device_removed.connect (remove_device);
3550-
3551- wifidev.access_point_added.connect (access_point_added_cb);
3552- wifidev.access_point_removed.connect (access_point_removed_cb);
3553- wifidev.notify["active-access-point"].connect (active_access_point_changed);
3554- wifidev.state_changed.connect (device_state_changed_cb);
3555-
3556- var aps = wifidev.get_access_points ();
3557- if (aps != null)
3558- for (int i = 0; i < aps.length; i++)
3559- insert_ap (aps.get(i));
3560- }
3561-
3562- ~WifiActionManager ()
3563- {
3564- remove_device (client, wifidev);
3565-
3566- client.device_removed.disconnect (remove_device);
3567- }
3568-
3569- private void remove_device (NM.Client client, NM.Device device)
3570- {
3571- wifidev.access_point_added.disconnect (access_point_added_cb);
3572- wifidev.access_point_removed.disconnect (access_point_removed_cb);
3573- wifidev.notify["active-access-point"].disconnect (active_access_point_changed);
3574- wifidev.state_changed.disconnect (device_state_changed_cb);
3575- }
3576-
3577- private void device_state_changed_cb (NM.Device device,
3578- uint new_state,
3579- uint old_state,
3580- uint reason)
3581- {
3582- if (new_state != DeviceState.DISCONNECTED)
3583- return;
3584- var wifidev = (NM.DeviceWifi)device;
3585-
3586- var aps = wifidev.get_access_points ();
3587- if (aps == null)
3588- return;
3589-
3590- for (uint i = 0; i < aps.length; i++)
3591- {
3592- var ap = aps.get(i);
3593- var action = actions.lookup(ap.get_path());
3594- if (action != null) {
3595- action.change_state(new Variant.boolean (false));
3596- }
3597- }
3598- }
3599-
3600- private void access_point_added_cb (NM.DeviceWifi device, GLib.Object ap)
3601- {
3602- insert_ap ((AccessPoint)ap);
3603- }
3604-
3605- private void access_point_removed_cb (NM.DeviceWifi device, GLib.Object ap)
3606- {
3607- remove_ap ((AccessPoint)ap);
3608- }
3609-
3610- private void active_access_point_changed (GLib.Object obj, ParamSpec pspec)
3611- {
3612- string? active_ap = null;
3613-
3614- var aps = wifidev.get_access_points ();
3615- if (aps == null)
3616- return;
3617-
3618- if (wifidev.active_access_point != null)
3619- active_ap = wifidev.active_access_point.get_path ();
3620-
3621- for (uint i = 0; i < aps.length; i++)
3622- {
3623- var ap = aps.get(i);
3624- if (ap == null)
3625- continue;
3626-
3627- if (actions.lookup (ap.get_path ()) == null)
3628- {
3629- insert_ap (ap);
3630- continue;
3631- }
3632-
3633- var action = actions.lookup(ap.get_path());
3634- if (action == null)
3635- continue;
3636-
3637- action.change_state(new Variant.boolean (ap.get_path() == active_ap));
3638- }
3639- }
3640-
3641- private void insert_ap (NM.AccessPoint ap)
3642- {
3643- if (ap == null)
3644- return;
3645-
3646- bool is_active = false;
3647-
3648- /* If the ap is already included we skip this callback */
3649- if (actions.lookup (ap.get_path ()) != null)
3650- return;
3651-
3652- GLib.debug("Adding new access point: " + ap.get_bssid() + " at " + ap.get_path());
3653-
3654- //TODO: Add actions for each AP NM connection
3655- var strength_action_id = ap.get_path () + "::strength";
3656- ap.notify.connect (ap_strength_changed);
3657- if (wifidev.active_access_point != null)
3658- is_active = ap.get_path () == wifidev.active_access_point.get_path ();
3659-
3660- var strength = new SimpleAction.stateful (strength_action_id,
3661- null,
3662- new Variant.byte (ap.get_strength ()));
3663- var activate = new SimpleAction.stateful (ap.get_path (),
3664- null,
3665- new Variant.boolean (is_active));
3666- activate.activate.connect (ap_activated);
3667-
3668- actions.insert (strength);
3669- actions.insert (activate);
3670- }
3671-
3672- private void remove_ap (NM.AccessPoint ap)
3673- {
3674- GLib.debug("Removing access point: " + ap.get_bssid() + " at " + ap.get_path());
3675-
3676- //TODO: Check if AP has connection action
3677- actions.remove (ap.get_path ());
3678- actions.remove (ap.get_path () + "::strength");
3679- }
3680-
3681- private void ap_activated (SimpleAction ac, Variant? val)
3682- {
3683- /* If we're the selected access point, and we get clicked, then the user
3684- is trying to disconnect from that AP */
3685- if (ac.state.get_boolean () == true &&
3686- wifidev.active_access_point != null &&
3687- wifidev.active_access_point.get_path () == ac.name)
3688- {
3689- wifidev.disconnect (null);
3690- return;
3691- }
3692-
3693- /* If we're the active access point, we should just stay that way */
3694- if (wifidev.active_access_point != null &&
3695- wifidev.active_access_point.get_path () == ac.name)
3696- return;
3697-
3698- var ap = wifidev.get_access_point_by_path (ac.name);
3699- if (ap == null) {
3700- warning("Unable to access access point path: " + ac.name);
3701- return;
3702- }
3703-
3704- /* First we'll go ahead and mark all the other APs as inactive in the
3705- UI, it'll take a bit for NM to disconnect and reconnect to the other
3706- one which is confusing for users. */
3707- foreach (var action_name in actions.list_actions()) {
3708- if (action_name == ac.name)
3709- continue;
3710- if (!Variant.is_object_path(action_name))
3711- continue;
3712-
3713- var actionap = wifidev.get_access_point_by_path(action_name);
3714- if (actionap == null)
3715- continue;
3716-
3717- var action = actions.lookup_action(action_name);
3718- action.change_state(new Variant.boolean(false));
3719- }
3720-
3721- /* Now setup the connection and start connecting with this AP */
3722- var conns = rs.list_connections ();
3723- if (conns == null)
3724- {
3725- add_and_activate_ap (ac.name);
3726- return;
3727- }
3728-
3729- var dev_conns = wifidev.filter_connections (conns);
3730- if (dev_conns == null)
3731- {
3732- add_and_activate_ap (ac.name);
3733- return;
3734- }
3735-
3736- var ap_conns = ap.filter_connections (dev_conns);
3737- if (ap_conns == null)
3738- {
3739- add_and_activate_ap (ac.name);
3740- return;
3741- }
3742-
3743- client.activate_connection (ap_conns.data, wifidev, ac.name, null);
3744- return;
3745- }
3746-
3747- private void add_and_activate_ap (string ap_path)
3748- {
3749- client.add_and_activate_connection (null, wifidev, ap_path, null);
3750- }
3751-
3752- private void ap_strength_changed (GLib.Object obj, ParamSpec pspec)
3753- {
3754- var prop = pspec.get_name ();
3755- if (prop == "strength")
3756- {
3757- AccessPoint ap = (AccessPoint)obj;
3758- var action_name = ap.get_path() + "::strength";
3759- var action = actions.lookup(action_name);
3760- if (action != null)
3761- action.change_state (new Variant.byte(ap.get_strength ()));
3762- }
3763- }
3764- }
3765-
3766- public class Wifi : Base {
3767- private WifiMenu wifimenu;
3768- private WifiActionManager wifiactionmanager;
3769- private GLib.Settings settings;
3770-
3771- public Wifi (NM.Client client, NM.DeviceWifi device, GLibLocal.ActionMuxer muxer, bool show_settings) {
3772- GLib.Object(
3773- client: client,
3774- device: device,
3775- namespace: device.get_iface(),
3776- muxer: muxer
3777- );
3778-
3779- settings = new GLib.Settings ("com.canonical.indicator.network");
3780- settings.changed["auto-join-previous"].connect((k) => {
3781- if (client.wireless_get_enabled()) {
3782- device.set_autoconnect(settings.get_boolean("auto-join-previous"));
3783- }
3784- });
3785- device.set_autoconnect(settings.get_boolean("auto-join-previous"));
3786-
3787- wifimenu = new WifiMenu(client, device, this._menu, "indicator." + this.namespace + ".", show_settings);
3788- wifiactionmanager = new WifiActionManager(actions, client, device);
3789-
3790- client.notify["wireless-enabled"].connect((s, p) => {
3791- var wireless_enabled = false;
3792- s.get("wireless-enabled", out wireless_enabled);
3793- enabled_action.set_state(new Variant.boolean(wireless_enabled));
3794- });
3795- }
3796-
3797- protected override void disable_device ()
3798- {
3799- device.disconnect(null);
3800- client.wireless_set_enabled(false);
3801- }
3802-
3803- protected override void enable_device ()
3804- {
3805- client.wireless_set_enabled(true);
3806- device.set_autoconnect(settings.get_boolean("auto-join-previous"));
3807- }
3808- }
3809-}
3810
3811=== added file 'network/glib.supp'
3812--- network/glib.supp 1970-01-01 00:00:00 +0000
3813+++ network/glib.supp 2014-05-14 11:21:27 +0000
3814@@ -0,0 +1,141 @@
3815+{
3816+ default GMainContext allocation
3817+ Memcheck:Leak
3818+ ...
3819+ fun:g_main_context_new
3820+ fun:g_main_context_default
3821+ ...
3822+}
3823+
3824+{
3825+ g_main_context_default() mutex
3826+ Memcheck:Leak
3827+ ...
3828+ fun:g_mutex_lock
3829+ fun:g_main_context_default
3830+ ...
3831+}
3832+
3833+{
3834+ g_main_loop_run() thread
3835+ Memcheck:Leak
3836+ ...
3837+ fun:g_thread_self
3838+ fun:g_main_loop_run
3839+ ...
3840+}
3841+
3842+{
3843+ g_main_context_iterate() g_malloc()
3844+ Memcheck:Leak
3845+ ...
3846+ fun:g_malloc
3847+ fun:g_main_context_iterate.isra.23
3848+ fun:g_main_loop_run
3849+ ...
3850+}
3851+
3852+{
3853+ g_main_context_iterate() g_main_context_check()
3854+ Memcheck:Leak
3855+ ...
3856+ fun:g_main_context_check
3857+ fun:g_main_context_iterate.isra.23
3858+ ...
3859+}
3860+
3861+{
3862+ gobject_init_ctor()
3863+ Memcheck:Leak
3864+ ...
3865+ fun:gobject_init_ctor
3866+ ...
3867+}
3868+
3869+{
3870+ g_type_register_static()
3871+ Memcheck:Leak
3872+ ...
3873+ fun:g_type_register_static
3874+ ...
3875+}
3876+
3877+{
3878+ g_bus_get()
3879+ Memcheck:Leak
3880+ ...
3881+ fun:g_bus_get
3882+ ...
3883+}
3884+
3885+{
3886+ clone() start_thread() g_thread_proxy()
3887+ Memcheck:Leak
3888+ ...
3889+ fun:g_thread_proxy
3890+ fun:start_thread
3891+ fun:clone
3892+}
3893+
3894+
3895+
3896+{
3897+ g_main_context_push_thread_default()
3898+ Memcheck:Leak
3899+ ...
3900+ fun:g_main_context_push_thread_default
3901+ ...
3902+}
3903+
3904+{
3905+ g_type_class_ref()
3906+ Memcheck:Leak
3907+ ...
3908+ fun:g_type_class_ref
3909+ ...
3910+}
3911+
3912+{
3913+ g_bus_own_name_on_connection() g_hash_table_new_full()
3914+ Memcheck:Leak
3915+ ...
3916+ fun:g_hash_table_new_full
3917+ fun:g_bus_own_name_on_connection
3918+ ...
3919+}
3920+
3921+{
3922+ g_bus_own_name_on_connection() g_hash_table_insert_internal()
3923+ Memcheck:Leak
3924+ ...
3925+ fun:g_hash_table_insert_internal
3926+ fun:g_bus_own_name_on_connection
3927+ ...
3928+}
3929+
3930+{
3931+ g_bus_own_name_on_connection() g_mutex_lock()
3932+ Memcheck:Leak
3933+ ...
3934+ fun:g_mutex_lock
3935+ fun:g_bus_own_name_on_connection
3936+ ...
3937+}
3938+
3939+{
3940+ g_dbus_connection_export_menu_model()
3941+ Memcheck:Leak
3942+ ...
3943+ fun:g_dbus_node_info_new_for_xml
3944+ fun:g_dbus_connection_export_menu_model
3945+ ...
3946+}
3947+
3948+{
3949+ g_dbus_connection_export_menu_model() 2
3950+ Memcheck:Leak
3951+ ...
3952+ fun:g_dbus_connection_register_object
3953+ fun:g_dbus_connection_export_menu_model
3954+ ...
3955+}
3956
3957=== added file 'network/indicator-menu.h'
3958--- network/indicator-menu.h 1970-01-01 00:00:00 +0000
3959+++ network/indicator-menu.h 2014-05-14 11:21:27 +0000
3960@@ -0,0 +1,99 @@
3961+/*
3962+ * Copyright (C) 2014 Canonical, Ltd.
3963+ *
3964+ * This program is free software: you can redistribute it and/or modify it
3965+ * under the terms of the GNU General Public License version 3, as published
3966+ * by the Free Software Foundation.
3967+ *
3968+ * This program is distributed in the hope that it will be useful, but
3969+ * WITHOUT ANY WARRANTY; without even the implied warranties of
3970+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
3971+ * PURPOSE. See the GNU General Public License for more details.
3972+ *
3973+ * You should have received a copy of the GNU General Public License along
3974+ * with this program. If not, see <http://www.gnu.org/licenses/>.
3975+ *
3976+ * Authors:
3977+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
3978+ */
3979+
3980+#ifndef INDICATOR_MENU_H
3981+#define INDICATOR_MENU_H
3982+
3983+#include "menuitems/section.h"
3984+#include "menumodel-cpp/menu-merger.h"
3985+#include "menumodel-cpp/action-group-merger.h"
3986+#include "root-state.h"
3987+
3988+#include <vector>
3989+
3990+class IndicatorMenu
3991+{
3992+public:
3993+ typedef std::shared_ptr<IndicatorMenu> Ptr;
3994+
3995+ IndicatorMenu() = delete;
3996+ IndicatorMenu(RootState::Ptr rootState, const std::string &prefix)
3997+ : m_rootState{rootState},
3998+ m_prefix{prefix}
3999+ {
4000+ m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
4001+ m_actionGroup = std::make_shared<ActionGroup>();
4002+
4003+ m_actionGroupMerger->add(m_actionGroup);
4004+
4005+ m_rootAction = std::make_shared<Action>(prefix + ".network-status",
4006+ nullptr,
4007+ rootState->state().get());
4008+ rootState->state().changed().connect([this](const Variant &state){
4009+ m_rootAction->setState(state);
4010+ });
4011+ m_actionGroup->add(m_rootAction);
4012+
4013+ m_rootMenu = std::make_shared<Menu>();
4014+ m_subMenuMerger = std::make_shared<MenuMerger>();
4015+
4016+ m_rootItem = MenuItem::newSubmenu(m_subMenuMerger);
4017+
4018+ m_rootItem->setAction("indicator." + prefix + ".network-status");
4019+ m_rootItem->setAttribute("x-canonical-type", TypedVariant<std::string>("com.canonical.indicator.root"));
4020+ m_rootMenu->append(m_rootItem);
4021+ }
4022+
4023+ virtual void
4024+ addSection(Section::Ptr section)
4025+ {
4026+ m_sections.push_back(section);
4027+ m_actionGroupMerger->add(*section);
4028+ m_subMenuMerger->append(*section);
4029+ }
4030+
4031+ Menu::Ptr
4032+ menu() const
4033+ {
4034+ return m_rootMenu;
4035+ }
4036+
4037+ ActionGroup::Ptr
4038+ actionGroup() const
4039+ {
4040+ return m_actionGroupMerger->actionGroup();
4041+ }
4042+
4043+private:
4044+ RootState::Ptr m_rootState;
4045+ std::string m_prefix;
4046+
4047+ Action::Ptr m_rootAction;
4048+ MenuItem::Ptr m_rootItem;
4049+
4050+ Menu::Ptr m_rootMenu;
4051+ MenuMerger::Ptr m_subMenuMerger;
4052+
4053+ ActionGroupMerger::Ptr m_actionGroupMerger;
4054+ ActionGroup::Ptr m_actionGroup;
4055+
4056+ std::vector<Section::Ptr> m_sections;
4057+};
4058+
4059+#endif // INDICATOR_MENU_H
4060
4061=== added file 'network/indicator-network-service.cpp'
4062--- network/indicator-network-service.cpp 1970-01-01 00:00:00 +0000
4063+++ network/indicator-network-service.cpp 2014-05-14 11:21:27 +0000
4064@@ -0,0 +1,99 @@
4065+/*
4066+ * Copyright (C) 2014 Canonical, Ltd.
4067+ *
4068+ * This program is free software: you can redistribute it and/or modify it
4069+ * under the terms of the GNU General Public License version 3, as published
4070+ * by the Free Software Foundation.
4071+ *
4072+ * This program is distributed in the hope that it will be useful, but
4073+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4074+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4075+ * PURPOSE. See the GNU General Public License for more details.
4076+ *
4077+ * You should have received a copy of the GNU General Public License along
4078+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4079+ *
4080+ * Authors:
4081+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4082+ */
4083+
4084+#include "service.h"
4085+
4086+#include <iostream>
4087+#include <memory>
4088+
4089+#include <string.h>
4090+#include <libintl.h>
4091+
4092+#include <glib.h>
4093+#include <libnotify/notify.h>
4094+
4095+#include <config.h>
4096+
4097+static class MainLoop
4098+{
4099+ GMainLoop *ptr;
4100+public:
4101+ MainLoop() { ptr = g_main_loop_new(NULL, FALSE); }
4102+ ~MainLoop() { g_main_loop_unref(ptr); }
4103+
4104+ void run() { g_main_loop_run(ptr); }
4105+ void quit() { g_main_loop_quit(ptr); }
4106+} mainloop;
4107+
4108+
4109+struct sigaction act;
4110+static void
4111+signal_handler(int signo) {
4112+ std::cerr << "*** Received " << strsignal(signo) << ". ***"<< std::endl;
4113+
4114+ switch(signo) {
4115+ case SIGHUP:
4116+ case SIGINT:
4117+ case SIGQUIT:
4118+ case SIGTERM:
4119+ mainloop.quit();
4120+ break;
4121+ }
4122+}
4123+
4124+static gboolean
4125+stop_main_loop(gpointer)
4126+{
4127+ mainloop.quit();
4128+ return FALSE;
4129+}
4130+
4131+int
4132+main(int, char *[])
4133+{
4134+ act.sa_handler = signal_handler;
4135+ sigaction(SIGHUP, &act, 0);
4136+ sigaction(SIGINT, &act, 0);
4137+ sigaction(SIGQUIT, &act, 0);
4138+ sigaction(SIGTERM, &act, 0);
4139+ sigaction(SIGCONT, &act, 0);
4140+
4141+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
4142+ setlocale(LC_ALL, "");
4143+ bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
4144+ textdomain(GETTEXT_PACKAGE);
4145+
4146+ notify_init(GETTEXT_PACKAGE);
4147+
4148+ std::unique_ptr<Service> menu {new Service};
4149+
4150+ if (getenv("VALGRIND") != 0) {
4151+ g_timeout_add(1000, (GSourceFunc)stop_main_loop, NULL);
4152+ mainloop.run();
4153+
4154+ menu.reset();
4155+ // give gio time to do cleanup.
4156+ g_timeout_add(500, (GSourceFunc)stop_main_loop, NULL);
4157+ mainloop.run();
4158+ } else {
4159+ mainloop.run();
4160+ }
4161+
4162+ notify_uninit();
4163+}
4164
4165=== added directory 'network/menuitems'
4166=== added file 'network/menuitems/access-point-item.h'
4167--- network/menuitems/access-point-item.h 1970-01-01 00:00:00 +0000
4168+++ network/menuitems/access-point-item.h 2014-05-14 11:21:27 +0000
4169@@ -0,0 +1,128 @@
4170+/*
4171+ * Copyright (C) 2014 Canonical, Ltd.
4172+ *
4173+ * This program is free software: you can redistribute it and/or modify it
4174+ * under the terms of the GNU General Public License version 3, as published
4175+ * by the Free Software Foundation.
4176+ *
4177+ * This program is distributed in the hope that it will be useful, but
4178+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4179+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4180+ * PURPOSE. See the GNU General Public License for more details.
4181+ *
4182+ * You should have received a copy of the GNU General Public License along
4183+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4184+ *
4185+ * Authors:
4186+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4187+ */
4188+
4189+#ifndef ACCESS_POINT_ITEM_H
4190+#define ACCESS_POINT_ITEM_H
4191+
4192+#include "item.h"
4193+#include "menumodel-cpp/action.h"
4194+#include "menumodel-cpp/menu-item.h"
4195+#include "menumodel-cpp/gio-helpers/variant.h"
4196+
4197+#include <core/signal.h>
4198+
4199+#include <connectivity/networking/wifi/access-point.h>
4200+namespace networking = connectivity::networking;
4201+
4202+#include <functional>
4203+#include <vector>
4204+
4205+class AccessPointItem : public Item
4206+{
4207+
4208+public:
4209+ typedef std::shared_ptr<AccessPointItem> Ptr;
4210+
4211+ AccessPointItem() = delete;
4212+ AccessPointItem(networking::wifi::AccessPoint::Ptr accessPoint, bool isActive = false)
4213+ : m_accessPoint{accessPoint},
4214+ m_isActive{isActive}
4215+ {
4216+ static int id = 0;
4217+ ++id; /// @todo guard me.
4218+
4219+ std::string actionId = "accesspoint." + std::to_string(id);
4220+ std::string strengthActionId = actionId + "::strength";
4221+
4222+ m_item = std::make_shared<MenuItem>(m_accessPoint->ssid(),
4223+ "indicator." + actionId);
4224+
4225+
4226+
4227+ m_item->setAttribute("x-canonical-type", TypedVariant<std::string>("unity.widgets.systemsettings.tablet.accesspoint"));
4228+ m_item->setAttribute("x-canonical-wifi-ap-is-adhoc", TypedVariant<bool>(m_accessPoint->adhoc()));
4229+ m_item->setAttribute("x-canonical-wifi-ap-is-secure", TypedVariant<bool>(m_accessPoint->secured()));
4230+ m_item->setAttribute("x-canonical-wifi-ap-strength-action", TypedVariant<std::string>("indicator." + strengthActionId));
4231+
4232+ m_actionStrength = std::make_shared<Action>(strengthActionId,
4233+ nullptr,
4234+ TypedVariant<std::uint8_t>(m_accessPoint->strength().get()));
4235+
4236+ auto con = m_accessPoint->strength().changed().connect(std::bind(&AccessPointItem::setStrength,
4237+ this,
4238+ std::placeholders::_1));
4239+ m_connections.push_back(con);
4240+
4241+ m_actionActivate = std::make_shared<Action>(actionId,
4242+ nullptr,
4243+ TypedVariant<bool>(m_isActive),
4244+ [this](Variant){
4245+ ///@ todo something weird is happening as the unity8 side is not changing the state..
4246+ });
4247+ m_actionActivate->activated().connect([this](Variant){
4248+ m_activated();
4249+ });
4250+
4251+ m_actionGroup->add(m_actionActivate);
4252+ m_actionGroup->add(m_actionStrength);
4253+ }
4254+
4255+ virtual ~AccessPointItem()
4256+ {
4257+ for (auto con : m_connections)
4258+ con.disconnect();
4259+ }
4260+
4261+ void setStrength(double value)
4262+ {
4263+ /// @todo narrow_cast<>;
4264+ m_actionStrength->setState(TypedVariant<std::uint8_t>(value));
4265+ }
4266+
4267+ void setActive(bool value)
4268+ {
4269+ m_isActive = value;
4270+ m_actionActivate->setState(TypedVariant<bool>(m_isActive));
4271+ }
4272+
4273+ virtual MenuItem::Ptr
4274+ menuItem()
4275+ {
4276+ return m_item;
4277+ }
4278+
4279+ core::Signal<void> &activated()
4280+ {
4281+ return m_activated;
4282+ }
4283+
4284+private:
4285+ networking::wifi::AccessPoint::Ptr m_accessPoint;
4286+ bool m_isActive;
4287+
4288+ core::Signal<void> m_activated;
4289+
4290+ std::vector<core::Connection> m_connections;
4291+
4292+ Action::Ptr m_actionActivate;
4293+ Action::Ptr m_actionStrength;
4294+ MenuItem::Ptr m_item;
4295+};
4296+
4297+#endif // ACCESS_POINT_ITEM_H
4298
4299=== added file 'network/menuitems/item.h'
4300--- network/menuitems/item.h 1970-01-01 00:00:00 +0000
4301+++ network/menuitems/item.h 2014-05-14 11:21:27 +0000
4302@@ -0,0 +1,60 @@
4303+/*
4304+ * Copyright (C) 2014 Canonical, Ltd.
4305+ *
4306+ * This program is free software: you can redistribute it and/or modify it
4307+ * under the terms of the GNU General Public License version 3, as published
4308+ * by the Free Software Foundation.
4309+ *
4310+ * This program is distributed in the hope that it will be useful, but
4311+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4312+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4313+ * PURPOSE. See the GNU General Public License for more details.
4314+ *
4315+ * You should have received a copy of the GNU General Public License along
4316+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4317+ *
4318+ * Authors:
4319+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4320+ */
4321+
4322+#ifndef ITEM_H
4323+#define ITEM_H
4324+
4325+#include "menumodel-cpp/action-group-merger.h"
4326+#include "menumodel-cpp/menu-item.h"
4327+
4328+#include <memory>
4329+
4330+class Item
4331+{
4332+public:
4333+ typedef std::shared_ptr<Item> Ptr;
4334+
4335+ Item()
4336+ {
4337+ m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
4338+ m_actionGroup = std::make_shared<ActionGroup>();
4339+ m_actionGroupMerger->add(m_actionGroup);
4340+ }
4341+
4342+ virtual ~Item() = default;
4343+
4344+ virtual ActionGroup::Ptr actionGroup()
4345+ {
4346+ return m_actionGroupMerger->actionGroup();
4347+ }
4348+
4349+ virtual MenuItem::Ptr menuItem() = 0;
4350+
4351+ operator ActionGroup::Ptr() { return actionGroup(); }
4352+ operator MenuItem::Ptr() { return menuItem(); }
4353+
4354+protected:
4355+
4356+ ActionGroup::Ptr m_actionGroup;
4357+ ActionGroupMerger::Ptr m_actionGroupMerger;
4358+
4359+private:
4360+};
4361+
4362+#endif // ITEM_H
4363
4364=== added file 'network/menuitems/section.h'
4365--- network/menuitems/section.h 1970-01-01 00:00:00 +0000
4366+++ network/menuitems/section.h 2014-05-14 11:21:27 +0000
4367@@ -0,0 +1,39 @@
4368+/*
4369+ * Copyright (C) 2014 Canonical, Ltd.
4370+ *
4371+ * This program is free software: you can redistribute it and/or modify it
4372+ * under the terms of the GNU General Public License version 3, as published
4373+ * by the Free Software Foundation.
4374+ *
4375+ * This program is distributed in the hope that it will be useful, but
4376+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4377+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4378+ * PURPOSE. See the GNU General Public License for more details.
4379+ *
4380+ * You should have received a copy of the GNU General Public License along
4381+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4382+ *
4383+ * Authors:
4384+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4385+ */
4386+
4387+#ifndef SECTION_H
4388+#define SECTION_H
4389+
4390+#include <memory>
4391+#include "menumodel-cpp/action-group.h"
4392+#include "menumodel-cpp/menu-model.h"
4393+
4394+class Section
4395+{
4396+public:
4397+ typedef std::shared_ptr<Section> Ptr;
4398+
4399+ virtual ActionGroup::Ptr actionGroup() = 0;
4400+ virtual MenuModel::Ptr menuModel() = 0;
4401+
4402+ operator ActionGroup::Ptr() { return actionGroup(); }
4403+ operator MenuModel::Ptr() { return menuModel(); }
4404+};
4405+
4406+#endif
4407
4408=== added file 'network/menuitems/switch-item.h'
4409--- network/menuitems/switch-item.h 1970-01-01 00:00:00 +0000
4410+++ network/menuitems/switch-item.h 2014-05-14 11:21:27 +0000
4411@@ -0,0 +1,80 @@
4412+/*
4413+ * Copyright (C) 2014 Canonical, Ltd.
4414+ *
4415+ * This program is free software: you can redistribute it and/or modify it
4416+ * under the terms of the GNU General Public License version 3, as published
4417+ * by the Free Software Foundation.
4418+ *
4419+ * This program is distributed in the hope that it will be useful, but
4420+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4421+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4422+ * PURPOSE. See the GNU General Public License for more details.
4423+ *
4424+ * You should have received a copy of the GNU General Public License along
4425+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4426+ *
4427+ * Authors:
4428+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4429+ */
4430+
4431+#ifndef SWITCH_ITEM_H
4432+#define SWITCH_ITEM_H
4433+
4434+#include "item.h"
4435+#include "menumodel-cpp/menu-item.h"
4436+
4437+#include <core/property.h>
4438+
4439+class SwitchItem : public Item
4440+{
4441+public:
4442+ typedef std::shared_ptr<SwitchItem> Ptr;
4443+
4444+ SwitchItem() = delete;
4445+ SwitchItem(const std::string &label, const std::string &prefix, const std::string &name)
4446+ {
4447+ m_state.changed().connect([this](bool value){
4448+ if (m_action) {
4449+ Variant variant = TypedVariant<bool>(value);
4450+ m_action->setState(variant);
4451+ }
4452+ return true;
4453+ });
4454+ m_state.set(false);
4455+
4456+ std::string action_name = prefix + "." + name;
4457+ m_action = std::make_shared<Action>(action_name, nullptr, TypedVariant<bool>(m_state.get()));
4458+ m_actionGroup->add(m_action);
4459+ m_action->activated().connect([this](Variant){
4460+ bool value = m_action->state().as<bool>();
4461+ ///@ todo something weird is happening as the indicator side is not changing the state..
4462+ value = !value;
4463+ m_state.set(value);
4464+ });
4465+
4466+ m_item = std::make_shared<MenuItem>(label,
4467+ std::string("indicator.") + action_name);
4468+ m_item->setAttribute("x-canonical-type", TypedVariant<std::string>("com.canonical.indicator.switch"));
4469+
4470+ /// @todo state changes don't work properly
4471+ }
4472+
4473+ virtual MenuItem::Ptr
4474+ menuItem() {
4475+ return m_item;
4476+ }
4477+
4478+ core::Property<bool> &
4479+ state()
4480+ {
4481+ return m_state;
4482+ }
4483+
4484+private:
4485+ core::Property<bool> m_state;
4486+
4487+ Action::Ptr m_action;
4488+ MenuItem::Ptr m_item;
4489+};
4490+
4491+#endif // SWITCH_ITEM_H
4492
4493=== added file 'network/menuitems/text-item.h'
4494--- network/menuitems/text-item.h 1970-01-01 00:00:00 +0000
4495+++ network/menuitems/text-item.h 2014-05-14 11:21:27 +0000
4496@@ -0,0 +1,72 @@
4497+/*
4498+ * Copyright (C) 2014 Canonical, Ltd.
4499+ *
4500+ * This program is free software: you can redistribute it and/or modify it
4501+ * under the terms of the GNU General Public License version 3, as published
4502+ * by the Free Software Foundation.
4503+ *
4504+ * This program is distributed in the hope that it will be useful, but
4505+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4506+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4507+ * PURPOSE. See the GNU General Public License for more details.
4508+ *
4509+ * You should have received a copy of the GNU General Public License along
4510+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4511+ *
4512+ * Authors:
4513+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4514+ */
4515+
4516+#ifndef TEXT_ITEM_H
4517+#define TEXT_ITEM_H
4518+
4519+#include "item.h"
4520+
4521+#include "menumodel-cpp/menu-item.h"
4522+#include "menumodel-cpp/action.h"
4523+
4524+#include <core/signal.h>
4525+
4526+class TextItem : public Item
4527+{
4528+public:
4529+ typedef std::shared_ptr<TextItem> Ptr;
4530+
4531+ TextItem() = delete;
4532+ TextItem(const std::string &label, const std::string &prefix, const std::string &name)
4533+ {
4534+ std::string action_name = prefix + "." + name;
4535+
4536+ m_action = std::make_shared<Action>(action_name, nullptr);
4537+ m_actionGroup->add(m_action);
4538+ m_action->activated().connect([this](Variant){
4539+ m_activated();
4540+ });
4541+ m_item = std::make_shared<MenuItem>(label, std::string("indicator.") + action_name);
4542+ }
4543+
4544+ void
4545+ setLabel(const std::string &label)
4546+ {
4547+ m_item->setLabel(label);
4548+ }
4549+
4550+ virtual MenuItem::Ptr
4551+ menuItem() {
4552+ return m_item;
4553+ }
4554+
4555+ core::Signal<void> &
4556+ activated()
4557+ {
4558+ return m_activated;
4559+ }
4560+
4561+private:
4562+ core::Signal<void> m_activated;
4563+
4564+ Action::Ptr m_action;
4565+ MenuItem::Ptr m_item;
4566+};
4567+
4568+#endif // TEXT_ITEM_H
4569
4570=== added directory 'network/menumodel-cpp'
4571=== added file 'network/menumodel-cpp/CMakeLists.txt'
4572--- network/menumodel-cpp/CMakeLists.txt 1970-01-01 00:00:00 +0000
4573+++ network/menumodel-cpp/CMakeLists.txt 2014-05-14 11:21:27 +0000
4574@@ -0,0 +1,32 @@
4575+
4576+set(MENUMODEL_CPP_SOURCES
4577+ gio-helpers/util.cpp
4578+ gio-helpers/variant.h
4579+
4580+ action.cpp
4581+ action-group.h
4582+ action-group-exporter.h
4583+ action-group-merger.h
4584+ menu.h
4585+ menu-exporter.h
4586+ menu-item.h
4587+ menu-merger.h
4588+ menu-model.h
4589+)
4590+
4591+add_library(menumodel_cpp STATIC ${MENUMODEL_CPP_SOURCES})
4592+target_link_libraries(
4593+ menumodel_cpp
4594+ ${GLIB_LIBRARIES}
4595+ ${GIO_LIBRARIES}
4596+)
4597+
4598+###########################
4599+# Installation
4600+###########################
4601+
4602+#install(
4603+# TARGETS indicator-network-service
4604+# RUNTIME DESTINATION "${CMAKE_INSTALL_LIBEXECDIR}/indicator-network/"
4605+#)
4606+
4607
4608=== added file 'network/menumodel-cpp/action-group-exporter.h'
4609--- network/menumodel-cpp/action-group-exporter.h 1970-01-01 00:00:00 +0000
4610+++ network/menumodel-cpp/action-group-exporter.h 2014-05-14 11:21:27 +0000
4611@@ -0,0 +1,93 @@
4612+/*
4613+ * Copyright (C) 2014 Canonical, Ltd.
4614+ *
4615+ * This program is free software: you can redistribute it and/or modify it
4616+ * under the terms of the GNU General Public License version 3, as published
4617+ * by the Free Software Foundation.
4618+ *
4619+ * This program is distributed in the hope that it will be useful, but
4620+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4621+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4622+ * PURPOSE. See the GNU General Public License for more details.
4623+ *
4624+ * You should have received a copy of the GNU General Public License along
4625+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4626+ *
4627+ * Authors:
4628+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4629+ */
4630+
4631+#ifndef ACTION_GROUP_EXPORTER_H
4632+#define ACTION_GROUP_EXPORTER_H
4633+
4634+#include <memory>
4635+#include <gio/gio.h>
4636+
4637+#include "gio-helpers/util.h"
4638+
4639+#include "action-group.h"
4640+
4641+class ActionGroupExporter
4642+{
4643+ typedef std::shared_ptr<GSimpleActionGroup> GSimpleActionGroupPtr;
4644+ GSimpleActionGroupPtr make_gsimpleactiongroup_ptr() { return std::shared_ptr<GSimpleActionGroup>(g_simple_action_group_new(), GObjectDeleter()); }
4645+
4646+ std::shared_ptr<SessionBus> m_sessionBus;
4647+ GSimpleActionGroupPtr m_gSimpleActionGroup;
4648+ gint m_exportId;
4649+ ActionGroup::Ptr m_actionGroup;
4650+ std::string m_prefix;
4651+
4652+public:
4653+ typedef std::shared_ptr<ActionGroupExporter> Ptr;
4654+
4655+ ActionGroupExporter() = delete;
4656+ ActionGroupExporter(SessionBus::Ptr sessionBus, ActionGroup::Ptr actionGroup, const std::string &path, const std::string &prefix = "")
4657+ : m_sessionBus(sessionBus),
4658+ m_exportId {0},
4659+ m_actionGroup {actionGroup},
4660+ m_prefix {prefix}
4661+ {
4662+ m_gSimpleActionGroup = make_gsimpleactiongroup_ptr();
4663+
4664+ GError *error = NULL;
4665+ m_exportId = g_dbus_connection_export_action_group(m_sessionBus->bus().get(),
4666+ path.c_str(),
4667+ G_ACTION_GROUP(m_gSimpleActionGroup.get()),
4668+ &error);
4669+ if (error) {
4670+ if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) {
4671+ std::cerr << "Error exporting action group: " << error->message;
4672+ }
4673+ g_error_free(error);
4674+ /// @todo throw something
4675+ return;
4676+ }
4677+
4678+ GMainLoopDispatch([=](){
4679+ for (auto action : actionGroup->actions()) {
4680+ g_action_map_add_action(G_ACTION_MAP(m_gSimpleActionGroup.get()), action->gaction().get());
4681+ }
4682+ });
4683+ actionGroup->actionAdded().connect([this](Action::Ptr action){
4684+ GMainLoopDispatch([=](){
4685+ g_action_map_add_action(G_ACTION_MAP(m_gSimpleActionGroup.get()), action->gaction().get());
4686+ });
4687+ });
4688+ actionGroup->actionRemoved().connect([this](Action::Ptr action){
4689+ GMainLoopDispatch([=](){
4690+ g_action_map_remove_action(G_ACTION_MAP(m_gSimpleActionGroup.get()),
4691+ action->name().c_str());
4692+ });
4693+ });
4694+ }
4695+
4696+ ~ActionGroupExporter()
4697+ {
4698+ if (!m_exportId)
4699+ return;
4700+ g_dbus_connection_unexport_action_group(m_sessionBus->bus().get(), m_exportId);
4701+ }
4702+};
4703+
4704+#endif // ACTION_GROUP_EXPORTER_H
4705
4706=== added file 'network/menumodel-cpp/action-group-merger.h'
4707--- network/menumodel-cpp/action-group-merger.h 1970-01-01 00:00:00 +0000
4708+++ network/menumodel-cpp/action-group-merger.h 2014-05-14 11:21:27 +0000
4709@@ -0,0 +1,147 @@
4710+/*
4711+ * Copyright (C) 2014 Canonical, Ltd.
4712+ *
4713+ * This program is free software: you can redistribute it and/or modify it
4714+ * under the terms of the GNU General Public License version 3, as published
4715+ * by the Free Software Foundation.
4716+ *
4717+ * This program is distributed in the hope that it will be useful, but
4718+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4719+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4720+ * PURPOSE. See the GNU General Public License for more details.
4721+ *
4722+ * You should have received a copy of the GNU General Public License along
4723+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4724+ *
4725+ * Authors:
4726+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4727+ */
4728+
4729+#ifndef ACTION_GROUP_MERGER_H
4730+#define ACTION_GROUP_MERGER_H
4731+
4732+#include <memory>
4733+#include <gio/gio.h>
4734+#include <core/connection.h>
4735+
4736+#include "gio-helpers/util.h"
4737+#include "action-group.h"
4738+#include <set>
4739+#include <map>
4740+
4741+class ActionGroupMerger
4742+{
4743+ struct Connections
4744+ {
4745+ core::ScopedConnection actionAdded;
4746+ core::ScopedConnection actionRemoved;
4747+
4748+ Connections() = delete;
4749+ Connections(core::ScopedConnection added, core::ScopedConnection removed)
4750+ : actionAdded {std::move(added)},
4751+ actionRemoved {std::move(removed)}
4752+ {}
4753+ };
4754+
4755+ std::string m_prefix;
4756+ ActionGroup::Ptr m_actionGroup;
4757+
4758+ std::map<ActionGroup::Ptr, std::shared_ptr<Connections>> m_groups;
4759+
4760+ std::map<Action::Ptr, int> m_count;
4761+ std::map<std::string, Action::Ptr> m_names;
4762+
4763+ void addAction(Action::Ptr action)
4764+ {
4765+ auto name_iter = m_names.find(action->name());
4766+ if (name_iter != m_names.end()) {
4767+ // we have two actions with the same name.
4768+ // If they are from the same shared pointer, everything is OK and
4769+ // count is incremented below, but if they have different pointer
4770+ // then they will override each other in GActionGroup so let's catch that
4771+ // early on.
4772+ if (name_iter->second != action) {
4773+ std::cerr << "Conflicting action names." << std::endl;
4774+ /// @todo thow something.
4775+ return;
4776+ }
4777+ } else {
4778+ m_names[action->name()] = action;
4779+ }
4780+
4781+ auto count_iter = m_count.find(action);
4782+ if (count_iter != m_count.end()) {
4783+ count_iter->second += 1;
4784+ } else {
4785+ m_count[action] = 1;
4786+ m_actionGroup->add(action);
4787+ }
4788+ }
4789+
4790+ void removeAction(Action::Ptr action)
4791+ {
4792+ auto count_iter = m_count.find(action);
4793+ // it should not be possible for this function to be called for an action that
4794+ // was not added before
4795+ assert(count_iter != m_count.end());
4796+ count_iter->second -= 1;
4797+ if (count_iter->second == 0) {
4798+ m_actionGroup->remove(action);
4799+ m_names.erase(action->name());
4800+ m_count.erase(count_iter);
4801+ }
4802+ }
4803+
4804+
4805+public:
4806+ typedef std::shared_ptr<ActionGroupMerger> Ptr;
4807+
4808+ ActionGroupMerger(const std::string &prefix = "")
4809+ : m_prefix {prefix}
4810+ {
4811+ m_actionGroup = std::make_shared<ActionGroup>(m_prefix);
4812+ }
4813+
4814+ void add(ActionGroup::Ptr group)
4815+ {
4816+ auto iter = m_groups.find(group);
4817+ if (iter != m_groups.end()) {
4818+ /// @todo throw something.
4819+ std::cerr << "Trying to add action group which was already added before." << std::endl;
4820+ return;
4821+ }
4822+
4823+ for (auto action : group->actions()) {
4824+ addAction(action);
4825+ }
4826+ auto added = group->actionAdded().connect([this, group](Action::Ptr action){
4827+ addAction(action);
4828+ });
4829+ auto removed = group->actionRemoved().connect([this, group](Action::Ptr action){
4830+ removeAction(action);
4831+ });
4832+ m_groups[group] = std::make_shared<Connections>(added, removed);;
4833+ }
4834+
4835+ void remove(ActionGroup::Ptr group)
4836+ {
4837+ auto iter = m_groups.find(group);
4838+ if (iter == m_groups.end()) {
4839+ /// @todo throw something.
4840+ std::cerr << "Trying to remove action group which was not added before." << std::endl;
4841+ return;
4842+ }
4843+ m_groups.erase(group);
4844+ for (auto action : group->actions()) {
4845+ removeAction(action);
4846+ }
4847+ }
4848+
4849+ ActionGroup::Ptr actionGroup()
4850+ {
4851+ return m_actionGroup;
4852+ }
4853+ operator ActionGroup::Ptr() { return actionGroup(); }
4854+};
4855+
4856+#endif // ACTION_GROUP_MERGER_H
4857
4858=== added file 'network/menumodel-cpp/action-group.h'
4859--- network/menumodel-cpp/action-group.h 1970-01-01 00:00:00 +0000
4860+++ network/menumodel-cpp/action-group.h 2014-05-14 11:21:27 +0000
4861@@ -0,0 +1,92 @@
4862+/*
4863+ * Copyright (C) 2014 Canonical, Ltd.
4864+ *
4865+ * This program is free software: you can redistribute it and/or modify it
4866+ * under the terms of the GNU General Public License version 3, as published
4867+ * by the Free Software Foundation.
4868+ *
4869+ * This program is distributed in the hope that it will be useful, but
4870+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4871+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4872+ * PURPOSE. See the GNU General Public License for more details.
4873+ *
4874+ * You should have received a copy of the GNU General Public License along
4875+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4876+ *
4877+ * Authors:
4878+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4879+ */
4880+
4881+#ifndef ACTION_GROUP_H
4882+#define ACTION_GROUP_H
4883+
4884+#include <memory>
4885+#include <gio/gio.h>
4886+#include <set>
4887+
4888+#include "action.h"
4889+#include "gio-helpers/util.h"
4890+
4891+#include <core/signal.h>
4892+
4893+class ActionGroup
4894+{
4895+ std::string m_prefix;
4896+ std::set<Action::Ptr> m_actions;
4897+ core::Signal<Action::Ptr> m_actionAdded;
4898+ core::Signal<Action::Ptr> m_actionRemoved;
4899+
4900+public:
4901+ typedef std::shared_ptr<ActionGroup> Ptr;
4902+
4903+ ActionGroup(const std::string &prefix = "")
4904+ : m_prefix {prefix}
4905+ {
4906+ }
4907+
4908+ std::set<Action::Ptr> actions()
4909+ {
4910+ return m_actions;
4911+ }
4912+
4913+ void add(Action::Ptr action)
4914+ {
4915+ auto iter = m_actions.find(action);
4916+ if (iter != m_actions.end()) {
4917+ /// @todo throw something.
4918+ std::cerr << "Trying to add action which was already added before." << std::endl;
4919+ return;
4920+ }
4921+ m_actions.insert(action);
4922+ m_actionAdded(action);
4923+ }
4924+
4925+ void remove(Action::Ptr action)
4926+ {
4927+ auto iter = m_actions.find(action);
4928+ if (iter == m_actions.end()) {
4929+ /// @todo throw something.
4930+ std::cerr << "Trying to remove action which was not added before." << std::endl;
4931+ return;
4932+ }
4933+ m_actionRemoved(action);
4934+ m_actions.erase(action);
4935+ }
4936+
4937+ bool contains(Action::Ptr action)
4938+ {
4939+ return m_actions.find(action) != m_actions.end();
4940+ }
4941+
4942+ core::Signal<Action::Ptr> &actionAdded()
4943+ {
4944+ return m_actionAdded;
4945+ }
4946+
4947+ core::Signal<Action::Ptr> &actionRemoved()
4948+ {
4949+ return m_actionRemoved;
4950+ }
4951+};
4952+
4953+#endif // ACTION_GROUP_MERGER_H
4954
4955=== added file 'network/menumodel-cpp/action.cpp'
4956--- network/menumodel-cpp/action.cpp 1970-01-01 00:00:00 +0000
4957+++ network/menumodel-cpp/action.cpp 2014-05-14 11:21:27 +0000
4958@@ -0,0 +1,129 @@
4959+/*
4960+ * Copyright (C) 2014 Canonical, Ltd.
4961+ *
4962+ * This program is free software: you can redistribute it and/or modify it
4963+ * under the terms of the GNU General Public License version 3, as published
4964+ * by the Free Software Foundation.
4965+ *
4966+ * This program is distributed in the hope that it will be useful, but
4967+ * WITHOUT ANY WARRANTY; without even the implied warranties of
4968+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
4969+ * PURPOSE. See the GNU General Public License for more details.
4970+ *
4971+ * You should have received a copy of the GNU General Public License along
4972+ * with this program. If not, see <http://www.gnu.org/licenses/>.
4973+ *
4974+ * Authors:
4975+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
4976+ */
4977+
4978+#include "action.h"
4979+
4980+void
4981+Action::activate_cb(GSimpleAction *,
4982+ GVariant *parameter,
4983+ gpointer user_data)
4984+{
4985+ Variant param;
4986+ if (parameter != nullptr) {
4987+ param = Variant::fromGVariant(g_variant_ref(parameter));
4988+ }
4989+ Action *that = static_cast<Action *>(user_data);
4990+ that->m_activated(param);
4991+}
4992+
4993+void
4994+Action::change_state_cb(GSimpleAction *,
4995+ GVariant *value,
4996+ gpointer user_data)
4997+{
4998+ Variant new_value = Variant::fromGVariant(g_variant_ref(value));
4999+
5000+ Action *that = static_cast<Action *>(user_data);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches