239
by Osmo Antero
Moving to GPL3 license. All src/*.c should now comply to GPL3. |
1 |
/*
|
1424
by Osmo Antero
Version 3.0.0 |
2 |
* Copyright (c) 2011- Osmo Antero.
|
239
by Osmo Antero
Moving to GPL3 license. All src/*.c should now comply to GPL3. |
3 |
*
|
4 |
* This library is free software; you can redistribute it and/or
|
|
5 |
* modify it under the terms of the GNU Library General Public
|
|
6 |
* License as published by the Free Software Foundation; either
|
|
7 |
* version 3 of the License (GPL3), or any later version.
|
|
8 |
*
|
|
9 |
* This library is distributed in the hope that it will be useful,
|
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
463
by Osmo Antero
Updated README and INSTALL files. |
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
239
by Osmo Antero
Moving to GPL3 license. All src/*.c should now comply to GPL3. |
12 |
* See the GNU Library General Public License 3 for more details.
|
13 |
*
|
|
14 |
* You should have received a copy of the GNU Library General Public
|
|
15 |
* License 3 along with this program; if not, see /usr/share/common-licenses/GPL file
|
|
1012.1.5
by David Rabel
GPL boilerplate updated in source files. |
16 |
* or <http://www.gnu.org/licenses/>.
|
239
by Osmo Antero
Moving to GPL3 license. All src/*.c should now comply to GPL3. |
17 |
*/
|
101
by Osmo Antero
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c. |
18 |
#include "log.h" |
19 |
#include "support.h" |
|
20 |
#include "about.h" |
|
21 |
#include "rec-manager.h" |
|
22 |
#include <gst/gst.h> |
|
23 |
||
24 |
// This module creates a DBus-server for this program.
|
|
25 |
// Other programs can control the recorder by calling methods via this DBus interface.
|
|
26 |
//
|
|
27 |
// Audio-recorder itself can send messages to the running instance of this program.
|
|
28 |
// See audio-recorder --help for more information.
|
|
29 |
//
|
|
30 |
// Exported DBus methods are:
|
|
31 |
// get_state(), returns current recording state: "not running" | "on" | off" | "paused".
|
|
32 |
//
|
|
33 |
// set_state(state), set new state. The state can be one of: "start"|"stop"|"pause"|"hide"|"show"|"quit".
|
|
34 |
// returns "OK" if success. NULL if error.
|
|
35 |
//
|
|
1012.1.4
by David Rabel
Replaced http by https wherever it was reasonable. Also replaced some broken links and link that where only redirecting. |
36 |
// Ref: https://developer.gnome.org/gio/stable/GDBusServer.html
|
101
by Osmo Antero
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c. |
37 |
//
|
38 |
// Notice: This module has nothing to do with dbus-player.[ch], dbus-mpris2.[ch] modules.
|
|
39 |
//
|
|
40 |
||
41 |
#define R_DBUS_SERVER_ADDRESS "unix:abstract=audiorecorder"
|
|
42 |
||
43 |
#define R_DBUS_OBJECT_PATH "/org/gnome/API/AudioRecorder"
|
|
44 |
#define R_DBUS_INTERFACE_NAME "org.gnome.API.AudioRecorderInterface"
|
|
45 |
||
46 |
static GDBusServer *g_dbus_server = NULL; |
|
47 |
static GDBusNodeInfo *g_introspection_data = NULL; |
|
48 |
||
49 |
// Signatures for the methods we are exporting.
|
|
50 |
// DBus clients can get information or control the recorder by calling these functions.
|
|
51 |
static const gchar g_introspection_xml[] = |
|
52 |
"<node>"
|
|
53 |
" <interface name='org.gnome.API.AudioRecorderInterface'>"
|
|
54 |
" <method name='get_state'>"
|
|
55 |
" <arg type='s' name='response' direction='out'/>" // Returns current recording state: "not running"|"on"|off"|"paused" |
|
56 |
" </method>"
|
|
57 |
" <method name='set_state'>"
|
|
58 |
" <arg type='s' name='state' direction='in'/>" // Set new state. Input argument:"start"|"stop"|"pause"|"hide"|"show"|"quit". |
|
59 |
" <arg type='s' name='response' direction='out'/>" // Returns "OK" or NULL if error. |
|
60 |
" </method>"
|
|
61 |
" </interface>"
|
|
62 |
"</node>"; |
|
63 |
||
64 |
static gboolean dbus_service_start(); |
|
65 |
static void dbus_service_set_state(gchar *new_state); |
|
66 |
||
67 |
// -----------------------------------------------------------------------------------
|
|
68 |
||
69 |
void dbus_service_module_init() { |
|
70 |
LOG_DEBUG("Init dbus_service.c\n"); |
|
71 |
||
72 |
g_dbus_server = NULL; |
|
73 |
||
74 |
// Start service
|
|
75 |
dbus_service_start(); |
|
76 |
}
|
|
77 |
||
78 |
void dbus_service_module_exit() { |
|
79 |
LOG_DEBUG("Clean up dbus_service.c.\n"); |
|
80 |
||
81 |
if (g_introspection_data) { |
|
82 |
g_dbus_node_info_unref(g_introspection_data); |
|
83 |
}
|
|
84 |
g_introspection_data = NULL; |
|
85 |
||
86 |
if (g_dbus_server) { |
|
207
by osmoma at gmail
Just more small changes. |
87 |
g_dbus_server_stop(g_dbus_server); |
101
by Osmo Antero
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c. |
88 |
g_object_unref(g_dbus_server); |
89 |
}
|
|
90 |
g_dbus_server = NULL; |
|
91 |
}
|
|
92 |
||
93 |
static void handle_method_call(GDBusConnection *connection, |
|
94 |
const gchar *sender, |
|
95 |
const gchar *object_path, |
|
96 |
const gchar *interface_name, |
|
97 |
const gchar *method_name, |
|
98 |
GVariant *parameters, |
|
99 |
GDBusMethodInvocation *invocation, |
|
100 |
gpointer user_data) { |
|
101 |
||
102 |
// DBus method call: get_state.
|
|
103 |
// Returns "not running" | "on" | "off" | "paused"
|
|
104 |
if (g_strcmp0(method_name, "get_state") == 0) { |
|
105 |
||
106 |
// Get recording state
|
|
107 |
gint state = -1; |
|
108 |
gint pending = -1; |
|
109 |
rec_manager_get_state(&state, &pending); |
|
110 |
||
111 |
const gchar *state_str = NULL; |
|
112 |
||
113 |
switch (state) { |
|
114 |
case GST_STATE_PAUSED: |
|
115 |
state_str = "paused"; |
|
116 |
break; |
|
117 |
||
118 |
case GST_STATE_PLAYING: |
|
119 |
state_str = "on"; |
|
120 |
break; |
|
121 |
||
122 |
default: |
|
123 |
state_str = "off"; |
|
124 |
}
|
|
125 |
||
126 |
g_dbus_method_invocation_return_value(invocation, g_variant_new ("(s)", state_str)); |
|
127 |
LOG_DEBUG("Audio recorder (DBus-server) executed method get_state().\n"); |
|
128 |
}
|
|
129 |
||
130 |
// DBus method call: set_state(new_state).
|
|
131 |
// new_state can be: "start" | "stop" | "pause" | "show" | "hide" | "quit".
|
|
132 |
// Returns "OK" | NULL
|
|
133 |
else if (g_strcmp0 (method_name, "set_state") == 0) { |
|
134 |
gchar *response = g_strdup("OK"); |
|
135 |
||
136 |
gchar *new_state = NULL; |
|
137 |
g_variant_get(parameters, "(&s)", &new_state); |
|
138 |
||
139 |
g_dbus_method_invocation_return_value(invocation, g_variant_new ("(s)", response)); |
|
140 |
g_free(response); |
|
141 |
LOG_DEBUG("Audio recorder (Dbus-server) executed method set_state(%s).\n", new_state); |
|
142 |
||
143 |
// Set recorder to new_state
|
|
144 |
dbus_service_set_state(new_state); |
|
145 |
}
|
|
146 |
}
|
|
147 |
||
148 |
static void dbus_service_set_state(gchar *new_state) { |
|
149 |
// Set recorder to new_state
|
|
150 |
||
151 |
// $ audio-recorder --command start
|
|
152 |
if (!g_strcmp0(new_state, "start")) { |
|
153 |
rec_manager_start_recording(); |
|
154 |
}
|
|
155 |
||
156 |
// $ audio-recorder --command stop
|
|
157 |
else if (!g_strcmp0(new_state, "stop")) { |
|
158 |
rec_manager_stop_recording(); |
|
159 |
}
|
|
160 |
||
161 |
// $ audio-recorder --command pause
|
|
162 |
else if (!g_strcmp0(new_state, "pause")) { |
|
163 |
rec_manager_pause_recording(); |
|
164 |
}
|
|
165 |
||
166 |
// $ audio-recorder --command show
|
|
167 |
else if (!g_strcmp0(new_state, "show")) { |
|
168 |
rec_manager_show_window(TRUE); |
|
169 |
}
|
|
170 |
||
171 |
// $ audio-recorder --command hide
|
|
172 |
else if (!g_strcmp0(new_state, "hide")) { |
|
173 |
rec_manager_show_window(FALSE); |
|
174 |
}
|
|
175 |
||
176 |
// $ audio-recorder --command quit
|
|
177 |
else if (!g_strcmp0(new_state, "quit")) { |
|
178 |
rec_manager_quit_application(); |
|
179 |
}
|
|
180 |
}
|
|
181 |
||
182 |
static const GDBusInterfaceVTable interface_vtable = { |
|
183 |
handle_method_call, |
|
184 |
NULL, |
|
185 |
NULL, |
|
186 |
};
|
|
187 |
||
188 |
// ---------------------------------------------------------------------------------
|
|
189 |
||
190 |
static gboolean on_new_connection(GDBusServer *server, GDBusConnection *connection, gpointer user_data) { |
|
191 |
/*
|
|
192 |
GCredentials *credentials = NULL;
|
|
193 |
credentials = g_dbus_connection_get_peer_credentials(connection);
|
|
194 |
||
195 |
gchar *s = NULL;
|
|
196 |
if (credentials == NULL)
|
|
197 |
s = g_strdup ("(no credentials received)");
|
|
198 |
else
|
|
199 |
s = g_credentials_to_string(credentials);
|
|
200 |
||
201 |
||
202 |
LOG_DEBUG("Client connected.\n"
|
|
203 |
"Peer credentials: %s\n"
|
|
204 |
"Negotiated capabilities: unix-fd-passing=%d\n",
|
|
205 |
s,
|
|
206 |
g_dbus_connection_get_capabilities(connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
|
|
207 |
*/
|
|
208 |
||
209 |
g_object_ref(connection); |
|
210 |
||
211 |
gint registration_id = g_dbus_connection_register_object(connection, |
|
212 |
R_DBUS_OBJECT_PATH, |
|
213 |
g_introspection_data->interfaces[0], |
|
214 |
&interface_vtable, |
|
215 |
NULL, /* user_data */ |
|
216 |
NULL, /* user_data_free_func */ |
|
217 |
NULL); /* GError */ |
|
218 |
||
219 |
return (registration_id > 0); |
|
220 |
}
|
|
221 |
||
222 |
||
223 |
static gboolean dbus_service_start() { |
|
224 |
// Start DBus-server for this application.
|
|
225 |
// This will receive method calls from external programs.
|
|
226 |
||
227 |
// Build introspection data from XML
|
|
228 |
g_introspection_data = g_dbus_node_info_new_for_xml(g_introspection_xml, NULL); |
|
229 |
||
230 |
// Server flags
|
|
231 |
GDBusServerFlags server_flags = G_DBUS_SERVER_FLAGS_NONE; |
|
232 |
server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; |
|
233 |
||
234 |
gchar *guid = g_dbus_generate_guid(); |
|
235 |
||
236 |
// Create a new D-Bus server that listens on R_DBUS_SERVER_ADDRESS
|
|
237 |
GError *error = NULL; |
|
238 |
g_dbus_server = g_dbus_server_new_sync(R_DBUS_SERVER_ADDRESS, |
|
239 |
server_flags, |
|
240 |
guid, |
|
241 |
NULL, /* GDBusAuthObserver */ |
|
242 |
NULL, /* GCancellable */ |
|
243 |
&error); |
|
244 |
||
245 |
g_dbus_server_start(g_dbus_server); |
|
246 |
g_free(guid); |
|
247 |
||
248 |
if (g_dbus_server == NULL) { |
|
249 |
LOG_ERROR("Cannot create server address %s for DBus. %s\n", R_DBUS_SERVER_ADDRESS, error->message); |
|
250 |
g_error_free(error); |
|
251 |
return FALSE; |
|
252 |
}
|
|
253 |
||
254 |
LOG_DEBUG("This Audio Recorder is listening on DBus at: %s\n", g_dbus_server_get_client_address(g_dbus_server)); |
|
255 |
||
256 |
// Set up callback method (for client calls)
|
|
257 |
g_signal_connect(g_dbus_server, "new-connection", G_CALLBACK (on_new_connection), NULL); |
|
258 |
||
259 |
return (g_dbus_server != NULL); |
|
260 |
}
|
|
261 |
||
262 |
gchar *dbus_service_client_request(gchar *method_name, gchar *arg) { |
|
263 |
// Execute method call on the server.
|
|
264 |
// Audio-recorder itself can call methods on the server.
|
|
265 |
// DBus-server will most likely return a value. We will pass it to the calling function.
|
|
266 |
||
267 |
GError *error = NULL; |
|
268 |
||
269 |
GDBusConnection *connection = g_dbus_connection_new_for_address_sync(R_DBUS_SERVER_ADDRESS, |
|
270 |
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, |
|
271 |
NULL, // GDBusAuthObserver |
|
272 |
NULL, // GCancellable |
|
273 |
&error); |
|
274 |
||
275 |
if (!connection) { |
|
276 |
LOG_DEBUG("Cannot connect to DBus address %s. %s\n", R_DBUS_SERVER_ADDRESS, error->message); |
|
277 |
g_error_free(error); |
|
278 |
return NULL; |
|
279 |
}
|
|
280 |
||
281 |
// Optional argument
|
|
282 |
GVariant *argument = NULL; |
|
283 |
if (arg) { |
|
284 |
argument = g_variant_new("(s)", arg); |
|
285 |
}
|
|
286 |
||
287 |
GVariant *value = NULL; |
|
288 |
value = g_dbus_connection_call_sync(connection, |
|
289 |
NULL, // bus_name |
|
290 |
R_DBUS_OBJECT_PATH, |
|
291 |
R_DBUS_INTERFACE_NAME, |
|
292 |
method_name, // method_name |
|
293 |
argument, // input parm |
|
294 |
G_VARIANT_TYPE ("(s)"), // return value (one string) |
|
295 |
G_DBUS_CALL_FLAGS_NONE, |
|
296 |
-1, |
|
297 |
NULL, |
|
298 |
&error); |
|
299 |
||
300 |
if (!value) { |
|
301 |
LOG_ERROR("Error invoking %s(%s). %s\n", method_name, arg, error->message); |
|
302 |
g_error_free(error); |
|
207
by osmoma at gmail
Just more small changes. |
303 |
g_object_unref(connection); |
101
by Osmo Antero
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c. |
304 |
return NULL; |
305 |
}
|
|
306 |
||
307 |
gchar *server_response = NULL; |
|
308 |
g_variant_get(value, "(&s)", &server_response); |
|
309 |
||
310 |
// Take copy of the value
|
|
311 |
gchar *ret = g_strdup(server_response); |
|
312 |
||
313 |
if (value) { |
|
314 |
g_variant_unref(value); |
|
315 |
}
|
|
316 |
||
173
by Osmo Antero
Support new systems; Ubuntu 12.10, Fedora 18. Improved timer and VAD-modules. Better gst-pipeline. |
317 |
//Notice: "argument" is floating and consumed by g_dbus_connection_call_sync().
|
318 |
//if (argument)
|
|
319 |
// g_variant_unref(argument);
|
|
320 |
//}
|
|
101
by Osmo Antero
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c. |
321 |
|
207
by osmoma at gmail
Just more small changes. |
322 |
g_object_unref(connection); |
463
by Osmo Antero
Updated README and INSTALL files. |
323 |
|
101
by Osmo Antero
New media-player interface that's based on the MediaPlayer2 standard. See src/dbus-mpris2.c. |
324 |
// Return ret
|
325 |
return ret; |
|
326 |
}
|
|
327 |
||
328 |