blob: 2d43eba9ff2476c0c199c89df9ea2e763f844370 [file] [log] [blame]
David Sodmanbbcb0522014-09-19 10:34:07 -07001/*
2 * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
Dominik Behrf50c98f2016-03-31 14:05:29 -07007#if DBUS
8#include <dbus/dbus.h>
David Sodmanbbcb0522014-09-19 10:34:07 -07009#include <stdlib.h>
David Sodman8ef20062015-01-06 09:23:40 -080010
Stéphane Marchesin62561a12015-12-11 17:32:37 -080011#include "dbus.h"
David Sodman8ef20062015-01-06 09:23:40 -080012#include "dbus_interface.h"
13#include "image.h"
Dominik Behr46c567f2016-03-08 15:11:48 -080014#include "main.h"
David Sodman8ef20062015-01-06 09:23:40 -080015#include "term.h"
David Sodmanbbcb0522014-09-19 10:34:07 -070016#include "util.h"
17
David Sodman8ef20062015-01-06 09:23:40 -080018#define COMMAND_MAKE_VT "MakeVT"
19#define COMMAND_SWITCH_VT "SwitchVT"
20#define COMMAND_TERMINATE "Terminate"
21#define COMMAND_IMAGE "Image"
22
Dominik Behr5f6742f2016-03-10 18:03:54 -080023#define DBUS_WAIT_DELAY_US (50000)
David Sodman8ef20062015-01-06 09:23:40 -080024#define DBUS_DEFAULT_DELAY 3000
Dominik Behr5f6742f2016-03-10 18:03:54 -080025#define DBUS_INIT_TIMEOUT_MS (60*1000)
David Sodman8ef20062015-01-06 09:23:40 -080026
Dominik Behr797a3832016-01-11 15:53:11 -080027typedef struct _dbus_t dbus_t;
28
Dominik Behr46c567f2016-03-08 15:11:48 -080029static void (*login_prompt_visible_callback)(void*) = NULL;
30static void* login_prompt_visible_callback_userptr = NULL;
Dominik Behr1883c042016-04-27 12:31:02 -070031static void (*suspend_done_callback)(void*) = NULL;
32static void* suspend_done_callback_userptr = NULL;
Dominik Behr46c567f2016-03-08 15:11:48 -080033static bool chrome_is_already_up = false;
Dominik Behr5f6742f2016-03-10 18:03:54 -080034static bool dbus_connect_fail = false;
35static int64_t dbus_connect_fail_time;
36static bool dbus_first_init = true;
37static int64_t dbus_first_init_time;
Dominik Behr46c567f2016-03-08 15:11:48 -080038
David Sodmanbbcb0522014-09-19 10:34:07 -070039struct _dbus_t {
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080040 DBusConnection* conn;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080041 DBusWatch* watch;
David Sodman8ef20062015-01-06 09:23:40 -080042 int fd;
David Sodmanbbcb0522014-09-19 10:34:07 -070043};
44
Dominik Behr797a3832016-01-11 15:53:11 -080045static dbus_t *dbus = NULL;
46
Stéphane Marchesin8fc13522015-12-14 17:02:28 -080047static DBusHandlerResult handle_switchvt(DBusConnection* connection,
48 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -080049{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080050 DBusMessage* reply;
51 DBusMessage* msg;
David Sodman8ef20062015-01-06 09:23:40 -080052 DBusError error;
53 dbus_bool_t stat;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080054 terminal_t* terminal;
David Sodman8ef20062015-01-06 09:23:40 -080055 unsigned int vt;
56
57 dbus_error_init(&error);
58 stat = dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
59 &vt, DBUS_TYPE_INVALID);
60
61 if (!stat) {
Dominik Behr46755a42016-04-21 18:08:33 -070062 LOG(ERROR, "SwitchVT method error, no VT argument.");
David Sodman8ef20062015-01-06 09:23:40 -080063 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
64 }
65
Stéphane Marchesin92a297d2016-01-07 20:24:55 -080066 if (vt > term_get_max_terminals()) {
Dominik Behr46755a42016-04-21 18:08:33 -070067 LOG(ERROR, "SwtichVT: invalid terminal.");
David Sodman8ef20062015-01-06 09:23:40 -080068 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
69 }
70
71 if (vt == 0) {
Stéphane Marchesin0a7ce422016-01-07 20:45:47 -080072 terminal = term_create_term(vt);
David Sodman8ef20062015-01-06 09:23:40 -080073 if (term_is_active(terminal)) {
David Sodmanf0a925a2015-05-04 11:19:19 -070074 term_deactivate(terminal);
David Sodman8ef20062015-01-06 09:23:40 -080075 msg = dbus_message_new_method_call(
76 kLibCrosServiceName,
77 kLibCrosServicePath,
78 kLibCrosServiceInterface,
79 kTakeDisplayOwnership);
80 dbus_connection_send_with_reply_and_block(connection, msg,
81 DBUS_DEFAULT_DELAY, NULL);
82 }
83 reply = dbus_message_new_method_return(message);
84 dbus_connection_send(connection, reply, NULL);
85 return DBUS_HANDLER_RESULT_HANDLED;
86 } else {
87 /*
88 * If we are switching to a new term, and if a
89 * given term is active, then de-activate the
90 * current terminal
91 */
Dominik Behr4defb362016-01-13 12:36:14 -080092 terminal = term_get_current_terminal();
David Sodman8ef20062015-01-06 09:23:40 -080093 if (term_is_active(terminal))
David Sodmanf0a925a2015-05-04 11:19:19 -070094 term_deactivate(terminal);
David Sodman8ef20062015-01-06 09:23:40 -080095
Stéphane Marchesin0a7ce422016-01-07 20:45:47 -080096 terminal = term_create_term(vt);
David Sodman8ef20062015-01-06 09:23:40 -080097 if (term_is_valid(terminal)) {
98 msg = dbus_message_new_method_call(
99 kLibCrosServiceName,
100 kLibCrosServicePath,
101 kLibCrosServiceInterface,
102 kReleaseDisplayOwnership);
103 dbus_connection_send_with_reply_and_block(connection, msg,
104 DBUS_DEFAULT_DELAY, NULL);
105 term_activate(terminal);
106
107 reply = dbus_message_new_method_return(message);
108 dbus_connection_send(connection, reply, NULL);
109 return DBUS_HANDLER_RESULT_HANDLED;
110 }
111 }
112
113 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
114}
115
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800116static DBusHandlerResult handle_makevt(DBusConnection* connection,
117 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -0800118{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800119 DBusMessage* reply;
David Sodman8ef20062015-01-06 09:23:40 -0800120 DBusError error;
121 dbus_bool_t stat;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800122 terminal_t* terminal;
David Sodman8ef20062015-01-06 09:23:40 -0800123 unsigned int vt;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800124 const char* reply_str;
David Sodman8ef20062015-01-06 09:23:40 -0800125
126 dbus_error_init(&error);
127 stat = dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
128 &vt, DBUS_TYPE_INVALID);
129
130 if (!stat) {
Dominik Behr46755a42016-04-21 18:08:33 -0700131 LOG(ERROR, "SwitchVT method error, not VT argument.");
David Sodman8ef20062015-01-06 09:23:40 -0800132 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
133 }
134
Stéphane Marchesin92a297d2016-01-07 20:24:55 -0800135 if ((vt < 1) || (vt > term_get_max_terminals())) {
Dominik Behr46755a42016-04-21 18:08:33 -0700136 LOG(ERROR, "SwtichVT: invalid terminal.");
David Sodman8ef20062015-01-06 09:23:40 -0800137 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
138 }
139
Stéphane Marchesin0a7ce422016-01-07 20:45:47 -0800140 terminal = term_create_term(vt);
David Sodman8ef20062015-01-06 09:23:40 -0800141 reply_str = term_get_ptsname(terminal);
142
143 reply = dbus_message_new_method_return(message);
144 dbus_message_append_args(reply,
145 DBUS_TYPE_STRING, &reply_str,
146 DBUS_TYPE_INVALID);
147 dbus_connection_send(connection, reply, NULL);
148
149 return DBUS_HANDLER_RESULT_HANDLED;
150}
151
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800152static DBusHandlerResult handle_terminate(DBusConnection* connection,
153 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -0800154{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800155 DBusMessage* reply;
David Sodman8ef20062015-01-06 09:23:40 -0800156
157 reply = dbus_message_new_method_return(message);
158 dbus_connection_send(connection, reply, NULL);
159 exit(EXIT_SUCCESS);
160}
161
David Sodman8ef20062015-01-06 09:23:40 -0800162#define NUM_IMAGE_PARAMETERS (2)
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800163static DBusHandlerResult handle_image(DBusConnection* connection,
164 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -0800165{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800166 DBusMessage* reply;
David Sodman8ef20062015-01-06 09:23:40 -0800167 DBusError error;
168 dbus_bool_t stat;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800169 terminal_t* terminal;
170 image_t* image;
David Sodman8ef20062015-01-06 09:23:40 -0800171 int i;
172 int x, y;
173 char* option[NUM_IMAGE_PARAMETERS];
174 char* optname;
175 char* optval;
176 int status;
177
178 dbus_error_init(&error);
179 stat = dbus_message_get_args(message, &error,
180 DBUS_TYPE_STRING, &option[0],
181 DBUS_TYPE_STRING, &option[1],
182 DBUS_TYPE_INVALID);
183
184 image = image_create();
185 if (image == NULL) {
Dominik Behr46755a42016-04-21 18:08:33 -0700186 LOG(WARNING, "Failed to create image.");
David Sodman8ef20062015-01-06 09:23:40 -0800187 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
188 }
189
190 if (stat) {
191 for (i = 0; i < NUM_IMAGE_PARAMETERS; i++) {
192 optname = NULL;
193 optval = NULL;
194 parse_image_option(option[i], &optname, &optval);
195 if (strncmp(optname, "image", strlen("image")) == 0) {
196 image_set_filename(image, optval);
197 } else if (strncmp(optname, "location", strlen("location")) == 0) {
198 parse_location(optval, &x, &y);
199 image_set_location(image, x, y);
200 } else if (strncmp(optname, "offset", strlen("offset")) == 0) {
201 parse_location(optval, &x, &y);
202 image_set_offset(image, x, y);
203 }
204 if (optname)
205 free(optname);
206 if (optval)
207 free(optval);
208 }
209 } else {
David Sodmanf0a925a2015-05-04 11:19:19 -0700210 goto fail;
David Sodman8ef20062015-01-06 09:23:40 -0800211 }
212
213 status = image_load_image_from_file(image);
214 if (status != 0) {
Dominik Behr46755a42016-04-21 18:08:33 -0700215 LOG(WARNING, "image_load_image_from_file(dbus) %s failed: %d:%s.",
216 image_get_filename(image), status, strerror(status));
David Sodmanf0a925a2015-05-04 11:19:19 -0700217 goto fail;
David Sodman8ef20062015-01-06 09:23:40 -0800218 }
219
Dominik Behr4defb362016-01-13 12:36:14 -0800220 terminal = term_get_current_terminal();
David Sodman8ef20062015-01-06 09:23:40 -0800221 if (!terminal)
David Sodmanf0a925a2015-05-04 11:19:19 -0700222 goto fail;
David Sodman8ef20062015-01-06 09:23:40 -0800223
David Sodmanf0a925a2015-05-04 11:19:19 -0700224 status = term_show_image(terminal, image);
225 if (status != 0) {
Dominik Behr46755a42016-04-21 18:08:33 -0700226 LOG(WARNING, "term_show_image(dbus) failed: %d.", status);
David Sodmanf0a925a2015-05-04 11:19:19 -0700227 goto fail;
228 }
David Sodman8ef20062015-01-06 09:23:40 -0800229 image_release(image);
230
231 reply = dbus_message_new_method_return(message);
232 dbus_connection_send(connection, reply, NULL);
233
234 return DBUS_HANDLER_RESULT_HANDLED;
David Sodmanf0a925a2015-05-04 11:19:19 -0700235fail:
236 if (image)
237 image_release(image);
238 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
David Sodman8ef20062015-01-06 09:23:40 -0800239}
240
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800241static void frecon_dbus_unregister(DBusConnection* connection, void* user_data)
David Sodman8ef20062015-01-06 09:23:40 -0800242{
243}
244
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800245static DBusHandlerResult frecon_dbus_message_handler(DBusConnection* connection,
246 DBusMessage* message,
247 void* user_data)
David Sodman8ef20062015-01-06 09:23:40 -0800248{
249 if (dbus_message_is_method_call(message,
250 kFreconDbusInterface, COMMAND_SWITCH_VT)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800251 return handle_switchvt(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800252 } else if (dbus_message_is_method_call(message,
253 kFreconDbusInterface, COMMAND_MAKE_VT)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800254 return handle_makevt(connection, message);
Dominik Behr1883c042016-04-27 12:31:02 -0700255 } else if (dbus_message_is_method_call(message,
David Sodman8ef20062015-01-06 09:23:40 -0800256 kFreconDbusInterface, COMMAND_TERMINATE)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800257 return handle_terminate(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800258 } else if (dbus_message_is_method_call(message,
259 kFreconDbusInterface, COMMAND_IMAGE)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800260 return handle_image(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800261 }
262
263 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
David Sodman8ef20062015-01-06 09:23:40 -0800264}
265
266static DBusObjectPathVTable
267frecon_vtable = {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800268 frecon_dbus_unregister,
269 frecon_dbus_message_handler,
David Sodman8ef20062015-01-06 09:23:40 -0800270 NULL
271};
272
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800273static dbus_bool_t add_watch(DBusWatch* w, void* data)
David Sodman8ef20062015-01-06 09:23:40 -0800274{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800275 dbus_t* dbus = (dbus_t*)data;
David Sodman8ef20062015-01-06 09:23:40 -0800276 dbus->watch = w;
277
278 return TRUE;
279}
280
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800281static void remove_watch(DBusWatch* w, void* data)
David Sodman8ef20062015-01-06 09:23:40 -0800282{
283}
284
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800285static void toggle_watch(DBusWatch* w, void* data)
David Sodman8ef20062015-01-06 09:23:40 -0800286{
287}
288
Dominik Behr46c567f2016-03-08 15:11:48 -0800289static DBusHandlerResult handle_login_prompt_visible(DBusMessage* message)
290{
291 if (login_prompt_visible_callback) {
292 login_prompt_visible_callback(login_prompt_visible_callback_userptr);
293 login_prompt_visible_callback = NULL;
294 login_prompt_visible_callback_userptr = NULL;
295 }
296 chrome_is_already_up = true;
297
298 return DBUS_HANDLER_RESULT_HANDLED;
299}
300
Dominik Behr1883c042016-04-27 12:31:02 -0700301static DBusHandlerResult handle_suspend_done(DBusMessage* message)
302{
303 if (suspend_done_callback)
304 suspend_done_callback(suspend_done_callback_userptr);
305
306 return DBUS_HANDLER_RESULT_HANDLED;
307}
308
Dominik Behr46c567f2016-03-08 15:11:48 -0800309static DBusHandlerResult frecon_dbus_message_filter(DBusConnection* connection,
310 DBusMessage* message,
311 void* user_data)
312{
313 if (dbus_message_is_signal(message,
Dominik Behr5f6742f2016-03-10 18:03:54 -0800314 kSessionManagerInterface, kLoginPromptVisibleSignal))
Dominik Behr46c567f2016-03-08 15:11:48 -0800315 return handle_login_prompt_visible(message);
Dominik Behr1883c042016-04-27 12:31:02 -0700316 else if (dbus_message_is_signal(message,
317 kPowerManagerInterface, kSuspendDoneSignal))
318 return handle_suspend_done(message);
Dominik Behr46c567f2016-03-08 15:11:48 -0800319
320 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
321}
322
Dominik Behr797a3832016-01-11 15:53:11 -0800323bool dbus_is_initialized(void)
324{
325 return !!dbus;
326}
327
328bool dbus_init()
David Sodmanbbcb0522014-09-19 10:34:07 -0700329{
330 dbus_t* new_dbus;
331 DBusError err;
David Sodman8ef20062015-01-06 09:23:40 -0800332 int result;
333 dbus_bool_t stat;
David Sodmanbbcb0522014-09-19 10:34:07 -0700334
Dominik Behr5f6742f2016-03-10 18:03:54 -0800335 if (dbus_first_init) {
336 dbus_first_init = false;
337 dbus_first_init_time = get_monotonic_time_ms();
338 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700339 dbus_error_init(&err);
340
341 new_dbus = (dbus_t*)calloc(1, sizeof(*new_dbus));
Stéphane Marchesinc236e0b2015-12-14 15:29:15 -0800342
343 if (!new_dbus)
Dominik Behr797a3832016-01-11 15:53:11 -0800344 return false;
Stéphane Marchesinc236e0b2015-12-14 15:29:15 -0800345
David Sodman8ef20062015-01-06 09:23:40 -0800346 new_dbus->fd = -1;
David Sodmanbbcb0522014-09-19 10:34:07 -0700347
348 new_dbus->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
349 if (dbus_error_is_set(&err)) {
Dominik Behr5f6742f2016-03-10 18:03:54 -0800350 if (!dbus_connect_fail) {
351 LOG(ERROR, "Cannot get DBUS connection");
352 dbus_connect_fail = true;
353 dbus_connect_fail_time = get_monotonic_time_ms();
354 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700355 free(new_dbus);
Dominik Behr797a3832016-01-11 15:53:11 -0800356 return false;
David Sodmanbbcb0522014-09-19 10:34:07 -0700357 }
358
Dominik Behr5f6742f2016-03-10 18:03:54 -0800359 if (dbus_connect_fail) {
360 int64_t t = get_monotonic_time_ms() - dbus_connect_fail_time;
361 LOG(INFO, "DBUS connected after %.1f seconds", (float)t / 1000.0f);
362 }
363
David Sodman8ef20062015-01-06 09:23:40 -0800364 result = dbus_bus_request_name(new_dbus->conn, kFreconDbusInterface,
365 DBUS_NAME_FLAG_DO_NOT_QUEUE, &err);
366
367 if (result <= 0) {
368 LOG(ERROR, "Unable to get name for server");
369 }
370
371 stat = dbus_connection_register_object_path(new_dbus->conn,
372 kFreconDbusPath,
373 &frecon_vtable,
374 NULL);
375
376 if (!stat) {
377 LOG(ERROR, "failed to register object path");
378 }
379
Dominik Behr46c567f2016-03-08 15:11:48 -0800380 dbus_bus_add_match(new_dbus->conn, kLoginPromptVisibleRule, &err);
Dominik Behr1883c042016-04-27 12:31:02 -0700381 dbus_bus_add_match(new_dbus->conn, kSuspendDoneRule, &err);
Dominik Behr46c567f2016-03-08 15:11:48 -0800382
383 stat = dbus_connection_add_filter(new_dbus->conn, frecon_dbus_message_filter, NULL, NULL);
384 if (!stat) {
385 LOG(ERROR, "failed to add message filter");
386 }
387
David Sodman8ef20062015-01-06 09:23:40 -0800388 stat = dbus_connection_set_watch_functions(new_dbus->conn,
389 add_watch, remove_watch, toggle_watch,
390 new_dbus, NULL);
391
392 if (!stat) {
393 LOG(ERROR, "Failed to set watch functions");
394 }
395
David Sodmanbbcb0522014-09-19 10:34:07 -0700396 dbus_connection_set_exit_on_disconnect(new_dbus->conn, FALSE);
397
Dominik Behr797a3832016-01-11 15:53:11 -0800398 dbus = new_dbus;
399 return true;
David Sodmanbbcb0522014-09-19 10:34:07 -0700400}
401
Dominik Behr5f6742f2016-03-10 18:03:54 -0800402bool dbus_init_wait()
403{
404 while (!dbus_is_initialized()) {
405 if (!dbus_init()) {
406 int64_t t = get_monotonic_time_ms() - dbus_first_init_time;
407 if (t >= DBUS_INIT_TIMEOUT_MS) {
408 LOG(ERROR, "DBUS init failed after a timeout of %u sec", DBUS_INIT_TIMEOUT_MS/1000);
409 return false;
410 }
411 }
412 usleep(DBUS_WAIT_DELAY_US);
413 }
414 return true;
415}
416
Dominik Behr797a3832016-01-11 15:53:11 -0800417static bool dbus_method_call0(const char* service_name,
418 const char* service_path,
419 const char* service_interface,
420 const char* method)
David Sodman003faed2014-11-03 09:02:10 -0800421{
Dominik Behr797a3832016-01-11 15:53:11 -0800422 DBusMessage* msg = NULL;
423 if (!dbus) {
424 LOG(ERROR, "dbus not initialized");
425 return false;
426 }
David Sodman003faed2014-11-03 09:02:10 -0800427
428 msg = dbus_message_new_method_call(service_name,
429 service_path, service_interface, method);
430
431 if (!msg)
432 return false;
433
434 if (!dbus_connection_send_with_reply_and_block(dbus->conn,
David Sodman8ef20062015-01-06 09:23:40 -0800435 msg, DBUS_DEFAULT_DELAY, NULL)) {
David Sodman003faed2014-11-03 09:02:10 -0800436 dbus_message_unref(msg);
437 return false;
438 }
439
440 dbus_connection_flush(dbus->conn);
441 dbus_message_unref(msg);
442
443 return true;
444}
445
Dominik Behr797a3832016-01-11 15:53:11 -0800446static bool dbus_method_call1(const char* service_name,
447 const char* service_path,
448 const char* service_interface,
449 const char* method, int arg_type, void* param)
David Sodmanbbcb0522014-09-19 10:34:07 -0700450{
Dominik Behr797a3832016-01-11 15:53:11 -0800451 DBusMessage* msg = NULL;
452 if (!dbus) {
453 LOG(ERROR, "dbus not initialized");
454 return false;
455 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700456
457 msg = dbus_message_new_method_call(service_name,
458 service_path, service_interface, method);
459
460 if (!msg)
461 return false;
462
463 if (!dbus_message_append_args(msg,
David Sodman19e4f9d2015-03-10 11:11:09 -0700464 arg_type, param, DBUS_TYPE_INVALID)) {
David Sodmanbbcb0522014-09-19 10:34:07 -0700465 dbus_message_unref(msg);
466 return false;
467 }
468
469 if (!dbus_connection_send_with_reply_and_block(dbus->conn,
David Sodman8ef20062015-01-06 09:23:40 -0800470 msg, DBUS_DEFAULT_DELAY, NULL)) {
David Sodmanbbcb0522014-09-19 10:34:07 -0700471 dbus_message_unref(msg);
472 return false;
473 }
474
475 dbus_connection_flush(dbus->conn);
476 dbus_message_unref(msg);
477
478 return true;
479}
480
Dominik Behr797a3832016-01-11 15:53:11 -0800481void dbus_destroy(void)
David Sodmanbbcb0522014-09-19 10:34:07 -0700482{
483 /* FIXME - not sure what the right counterpart to
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800484 * dbus_bus_get() is, unref documentation is rather
485 * unclear. Not a big issue but it would be nice to
486 * clean up properly here
487 */
David Sodmanbbcb0522014-09-19 10:34:07 -0700488 /* dbus_connection_unref(dbus->conn); */
Dominik Behr797a3832016-01-11 15:53:11 -0800489 if (dbus) {
David Sodman8ef20062015-01-06 09:23:40 -0800490 free(dbus);
Dominik Behr797a3832016-01-11 15:53:11 -0800491 dbus = NULL;
492 }
David Sodman8ef20062015-01-06 09:23:40 -0800493}
494
Dominik Behrd7112672016-01-20 16:59:34 -0800495void dbus_add_fds(fd_set* read_set, fd_set* exception_set, int *maxfd)
David Sodman8ef20062015-01-06 09:23:40 -0800496{
Dominik Behr797a3832016-01-11 15:53:11 -0800497 if (!dbus)
Dominik Behrd7112672016-01-20 16:59:34 -0800498 return;
Dominik Behr797a3832016-01-11 15:53:11 -0800499
David Sodman8ef20062015-01-06 09:23:40 -0800500 if (dbus->fd < 0)
501 dbus->fd = dbus_watch_get_unix_fd(dbus->watch);
502
503 if (dbus->fd >= 0) {
504 FD_SET(dbus->fd, read_set);
505 FD_SET(dbus->fd, exception_set);
506 }
David Sodman8ef20062015-01-06 09:23:40 -0800507
Dominik Behrd7112672016-01-20 16:59:34 -0800508 if (dbus->fd > *maxfd)
509 *maxfd = dbus->fd;
David Sodman8ef20062015-01-06 09:23:40 -0800510}
511
Dominik Behr797a3832016-01-11 15:53:11 -0800512void dbus_dispatch_io(void)
David Sodman8ef20062015-01-06 09:23:40 -0800513{
Dominik Behr797a3832016-01-11 15:53:11 -0800514 if (!dbus)
515 return;
516
David Sodman8ef20062015-01-06 09:23:40 -0800517 dbus_watch_handle(dbus->watch, DBUS_WATCH_READABLE);
518 while (dbus_connection_get_dispatch_status(dbus->conn)
519 == DBUS_DISPATCH_DATA_REMAINS) {
520 dbus_connection_dispatch(dbus->conn);
521 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700522}
Dominik Behr797a3832016-01-11 15:53:11 -0800523
524void dbus_report_user_activity(int activity_type)
525{
526 dbus_bool_t allow_off = false;
527 if (!dbus)
528 return;
529
530 dbus_method_call1(kPowerManagerServiceName,
531 kPowerManagerServicePath,
532 kPowerManagerInterface,
533 kHandleUserActivityMethod,
534 DBUS_TYPE_INT32, &activity_type);
535
536 switch (activity_type) {
537 case USER_ACTIVITY_BRIGHTNESS_UP_KEY_PRESS:
538 (void)dbus_method_call0(kPowerManagerServiceName,
539 kPowerManagerServicePath,
540 kPowerManagerInterface,
541 kIncreaseScreenBrightnessMethod);
542 break;
543 case USER_ACTIVITY_BRIGHTNESS_DOWN_KEY_PRESS:
544 /*
545 * Shouldn't allow the screen to go
546 * completely off while frecon is active
547 * so passing false to allow_off
548 */
549 (void)dbus_method_call1(kPowerManagerServiceName,
550 kPowerManagerServicePath,
551 kPowerManagerInterface,
552 kDecreaseScreenBrightnessMethod,
553 DBUS_TYPE_BOOLEAN, &allow_off);
554 break;
555 }
556}
557
Dominik Behr46c567f2016-03-08 15:11:48 -0800558/*
559 * tell Chrome to take ownership of the display (DRM master)
560 */
Dominik Behr797a3832016-01-11 15:53:11 -0800561void dbus_take_display_ownership(void)
562{
563 if (!dbus)
564 return;
565 (void)dbus_method_call0(kLibCrosServiceName,
566 kLibCrosServicePath,
567 kLibCrosServiceInterface,
568 kTakeDisplayOwnership);
569}
570
Dominik Behr46c567f2016-03-08 15:11:48 -0800571/*
572 * ask Chrome to give up display ownership (DRM master)
573 */
Dominik Behr83864df2016-04-21 12:35:08 -0700574bool dbus_release_display_ownership(void)
Dominik Behr797a3832016-01-11 15:53:11 -0800575{
576 if (!dbus)
Dominik Behr83864df2016-04-21 12:35:08 -0700577 return true;
578 return dbus_method_call0(kLibCrosServiceName,
579 kLibCrosServicePath,
580 kLibCrosServiceInterface,
581 kReleaseDisplayOwnership);
Dominik Behr797a3832016-01-11 15:53:11 -0800582}
583
Dominik Behr46c567f2016-03-08 15:11:48 -0800584void dbus_set_login_prompt_visible_callback(void (*callback)(void*),
585 void* userptr)
586{
587 if (chrome_is_already_up) {
588 if (callback)
589 callback(userptr);
590 } else {
591 if (login_prompt_visible_callback && callback) {
592 LOG(ERROR, "trying to register login prompt visible callback multiple times");
593 return;
594 }
595 login_prompt_visible_callback = callback;
596 login_prompt_visible_callback_userptr = userptr;
597 }
598}
Dominik Behrf50c98f2016-03-31 14:05:29 -0700599
Dominik Behr1883c042016-04-27 12:31:02 -0700600void dbus_set_suspend_done_callback(void (*callback)(void*),
601 void* userptr)
602{
603 if (suspend_done_callback && callback) {
604 LOG(ERROR, "trying to register login prompt visible callback multiple times");
605 return;
606 }
607 suspend_done_callback = callback;
608 suspend_done_callback_userptr = userptr;
609}
610
Dominik Behrf50c98f2016-03-31 14:05:29 -0700611#else
612
613#include <stdlib.h>
614#include <stdbool.h>
615
616bool dbus_init()
617{
618 return true;
619}
620
621bool dbus_init_wait()
622{
623 return true;
624}
625
626void dbus_destroy(void)
627{
628}
629
630void dbus_add_fds(fd_set* read_set, fd_set* exception_set, int *maxfd)
631{
632}
633
634void dbus_dispatch_io(void)
635{
636}
637
638void dbus_report_user_activity(int activity_type)
639{
640}
641
642void dbus_take_display_ownership(void)
643{
644}
645
Dominik Behr83864df2016-04-21 12:35:08 -0700646bool dbus_release_display_ownership(void)
Dominik Behrf50c98f2016-03-31 14:05:29 -0700647{
Dominik Behr83864df2016-04-21 12:35:08 -0700648 return true;
Dominik Behrf50c98f2016-03-31 14:05:29 -0700649}
650
651bool dbus_is_initialized(void)
652{
653 return true;
654}
655
656void dbus_set_login_prompt_visible_callback(void (*callback)(void*),
657 void* userptr)
658{
659}
660
Dominik Behr1883c042016-04-27 12:31:02 -0700661void dbus_set_suspend_done_callback(void (*callback)(void*),
662 void* userptr)
663{
664}
665
Dominik Behrf50c98f2016-03-31 14:05:29 -0700666#endif