blob: 12d5ec37fa90a4388daa0cc9b29d9e3c43884288 [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
7#include <stdlib.h>
David Sodman8ef20062015-01-06 09:23:40 -08008
Stéphane Marchesin62561a12015-12-11 17:32:37 -08009#include "dbus.h"
David Sodman8ef20062015-01-06 09:23:40 -080010#include "dbus_interface.h"
11#include "image.h"
Dominik Behr46c567f2016-03-08 15:11:48 -080012#include "main.h"
David Sodman8ef20062015-01-06 09:23:40 -080013#include "term.h"
David Sodmanbbcb0522014-09-19 10:34:07 -070014#include "util.h"
15
David Sodman8ef20062015-01-06 09:23:40 -080016#define COMMAND_MAKE_VT "MakeVT"
17#define COMMAND_SWITCH_VT "SwitchVT"
18#define COMMAND_TERMINATE "Terminate"
19#define COMMAND_IMAGE "Image"
20
Dominik Behr5f6742f2016-03-10 18:03:54 -080021#define DBUS_WAIT_DELAY_US (50000)
David Sodman8ef20062015-01-06 09:23:40 -080022#define DBUS_DEFAULT_DELAY 3000
Dominik Behr5f6742f2016-03-10 18:03:54 -080023#define DBUS_INIT_TIMEOUT_MS (60*1000)
David Sodman8ef20062015-01-06 09:23:40 -080024
Dominik Behr797a3832016-01-11 15:53:11 -080025typedef struct _dbus_t dbus_t;
26
Dominik Behr46c567f2016-03-08 15:11:48 -080027static void (*login_prompt_visible_callback)(void*) = NULL;
28static void* login_prompt_visible_callback_userptr = NULL;
29static bool chrome_is_already_up = false;
Dominik Behr5f6742f2016-03-10 18:03:54 -080030static bool dbus_connect_fail = false;
31static int64_t dbus_connect_fail_time;
32static bool dbus_first_init = true;
33static int64_t dbus_first_init_time;
Dominik Behr46c567f2016-03-08 15:11:48 -080034
David Sodmanbbcb0522014-09-19 10:34:07 -070035struct _dbus_t {
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080036 DBusConnection* conn;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080037 DBusWatch* watch;
David Sodman8ef20062015-01-06 09:23:40 -080038 int fd;
David Sodmanbbcb0522014-09-19 10:34:07 -070039};
40
Dominik Behr797a3832016-01-11 15:53:11 -080041static dbus_t *dbus = NULL;
42
Stéphane Marchesin8fc13522015-12-14 17:02:28 -080043static DBusHandlerResult handle_switchvt(DBusConnection* connection,
44 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -080045{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080046 DBusMessage* reply;
47 DBusMessage* msg;
David Sodman8ef20062015-01-06 09:23:40 -080048 DBusError error;
49 dbus_bool_t stat;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080050 terminal_t* terminal;
David Sodman8ef20062015-01-06 09:23:40 -080051 unsigned int vt;
52
53 dbus_error_init(&error);
54 stat = dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
55 &vt, DBUS_TYPE_INVALID);
56
57 if (!stat) {
58 LOG(ERROR, "SwitchVT method error, no VT argument");
59 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
60 }
61
Stéphane Marchesin92a297d2016-01-07 20:24:55 -080062 if (vt > term_get_max_terminals()) {
David Sodman8ef20062015-01-06 09:23:40 -080063 LOG(ERROR, "SwtichVT: invalid terminal");
64 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
65 }
66
67 if (vt == 0) {
Stéphane Marchesin0a7ce422016-01-07 20:45:47 -080068 terminal = term_create_term(vt);
David Sodman8ef20062015-01-06 09:23:40 -080069 if (term_is_active(terminal)) {
David Sodmanf0a925a2015-05-04 11:19:19 -070070 term_deactivate(terminal);
David Sodman8ef20062015-01-06 09:23:40 -080071 msg = dbus_message_new_method_call(
72 kLibCrosServiceName,
73 kLibCrosServicePath,
74 kLibCrosServiceInterface,
75 kTakeDisplayOwnership);
76 dbus_connection_send_with_reply_and_block(connection, msg,
77 DBUS_DEFAULT_DELAY, NULL);
78 }
79 reply = dbus_message_new_method_return(message);
80 dbus_connection_send(connection, reply, NULL);
81 return DBUS_HANDLER_RESULT_HANDLED;
82 } else {
83 /*
84 * If we are switching to a new term, and if a
85 * given term is active, then de-activate the
86 * current terminal
87 */
Dominik Behr4defb362016-01-13 12:36:14 -080088 terminal = term_get_current_terminal();
David Sodman8ef20062015-01-06 09:23:40 -080089 if (term_is_active(terminal))
David Sodmanf0a925a2015-05-04 11:19:19 -070090 term_deactivate(terminal);
David Sodman8ef20062015-01-06 09:23:40 -080091
Stéphane Marchesin0a7ce422016-01-07 20:45:47 -080092 terminal = term_create_term(vt);
David Sodman8ef20062015-01-06 09:23:40 -080093 if (term_is_valid(terminal)) {
94 msg = dbus_message_new_method_call(
95 kLibCrosServiceName,
96 kLibCrosServicePath,
97 kLibCrosServiceInterface,
98 kReleaseDisplayOwnership);
99 dbus_connection_send_with_reply_and_block(connection, msg,
100 DBUS_DEFAULT_DELAY, NULL);
101 term_activate(terminal);
102
103 reply = dbus_message_new_method_return(message);
104 dbus_connection_send(connection, reply, NULL);
105 return DBUS_HANDLER_RESULT_HANDLED;
106 }
107 }
108
109 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
110}
111
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800112static DBusHandlerResult handle_makevt(DBusConnection* connection,
113 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -0800114{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800115 DBusMessage* reply;
David Sodman8ef20062015-01-06 09:23:40 -0800116 DBusError error;
117 dbus_bool_t stat;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800118 terminal_t* terminal;
David Sodman8ef20062015-01-06 09:23:40 -0800119 unsigned int vt;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800120 const char* reply_str;
David Sodman8ef20062015-01-06 09:23:40 -0800121
122 dbus_error_init(&error);
123 stat = dbus_message_get_args(message, &error, DBUS_TYPE_UINT32,
124 &vt, DBUS_TYPE_INVALID);
125
126 if (!stat) {
127 LOG(ERROR, "SwitchVT method error, not VT argument");
128 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
129 }
130
Stéphane Marchesin92a297d2016-01-07 20:24:55 -0800131 if ((vt < 1) || (vt > term_get_max_terminals())) {
David Sodman8ef20062015-01-06 09:23:40 -0800132 LOG(ERROR, "SwtichVT: invalid terminal");
133 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
134 }
135
Stéphane Marchesin0a7ce422016-01-07 20:45:47 -0800136 terminal = term_create_term(vt);
David Sodman8ef20062015-01-06 09:23:40 -0800137 reply_str = term_get_ptsname(terminal);
138
139 reply = dbus_message_new_method_return(message);
140 dbus_message_append_args(reply,
141 DBUS_TYPE_STRING, &reply_str,
142 DBUS_TYPE_INVALID);
143 dbus_connection_send(connection, reply, NULL);
144
145 return DBUS_HANDLER_RESULT_HANDLED;
146}
147
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800148static DBusHandlerResult handle_terminate(DBusConnection* connection,
149 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -0800150{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800151 DBusMessage* reply;
David Sodman8ef20062015-01-06 09:23:40 -0800152
153 reply = dbus_message_new_method_return(message);
154 dbus_connection_send(connection, reply, NULL);
155 exit(EXIT_SUCCESS);
156}
157
David Sodman8ef20062015-01-06 09:23:40 -0800158#define NUM_IMAGE_PARAMETERS (2)
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800159static DBusHandlerResult handle_image(DBusConnection* connection,
160 DBusMessage* message)
David Sodman8ef20062015-01-06 09:23:40 -0800161{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800162 DBusMessage* reply;
David Sodman8ef20062015-01-06 09:23:40 -0800163 DBusError error;
164 dbus_bool_t stat;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800165 terminal_t* terminal;
166 image_t* image;
David Sodman8ef20062015-01-06 09:23:40 -0800167 int i;
168 int x, y;
169 char* option[NUM_IMAGE_PARAMETERS];
170 char* optname;
171 char* optval;
172 int status;
173
174 dbus_error_init(&error);
175 stat = dbus_message_get_args(message, &error,
176 DBUS_TYPE_STRING, &option[0],
177 DBUS_TYPE_STRING, &option[1],
178 DBUS_TYPE_INVALID);
179
180 image = image_create();
181 if (image == NULL) {
182 LOG(WARNING, "failed to create image");
183 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
184 }
185
186 if (stat) {
187 for (i = 0; i < NUM_IMAGE_PARAMETERS; i++) {
188 optname = NULL;
189 optval = NULL;
190 parse_image_option(option[i], &optname, &optval);
191 if (strncmp(optname, "image", strlen("image")) == 0) {
192 image_set_filename(image, optval);
193 } else if (strncmp(optname, "location", strlen("location")) == 0) {
194 parse_location(optval, &x, &y);
195 image_set_location(image, x, y);
196 } else if (strncmp(optname, "offset", strlen("offset")) == 0) {
197 parse_location(optval, &x, &y);
198 image_set_offset(image, x, y);
199 }
200 if (optname)
201 free(optname);
202 if (optval)
203 free(optval);
204 }
205 } else {
David Sodmanf0a925a2015-05-04 11:19:19 -0700206 goto fail;
David Sodman8ef20062015-01-06 09:23:40 -0800207 }
208
209 status = image_load_image_from_file(image);
210 if (status != 0) {
211 LOG(WARNING, "image_load_image_from_file failed: %d", status);
David Sodmanf0a925a2015-05-04 11:19:19 -0700212 goto fail;
David Sodman8ef20062015-01-06 09:23:40 -0800213 }
214
Dominik Behr4defb362016-01-13 12:36:14 -0800215 terminal = term_get_current_terminal();
David Sodman8ef20062015-01-06 09:23:40 -0800216 if (!terminal)
David Sodmanf0a925a2015-05-04 11:19:19 -0700217 goto fail;
David Sodman8ef20062015-01-06 09:23:40 -0800218
David Sodmanf0a925a2015-05-04 11:19:19 -0700219 status = term_show_image(terminal, image);
220 if (status != 0) {
221 LOG(WARNING, "term_show_image failed: %d", status);
222 goto fail;
223 }
David Sodman8ef20062015-01-06 09:23:40 -0800224 image_release(image);
225
226 reply = dbus_message_new_method_return(message);
227 dbus_connection_send(connection, reply, NULL);
228
229 return DBUS_HANDLER_RESULT_HANDLED;
David Sodmanf0a925a2015-05-04 11:19:19 -0700230fail:
231 if (image)
232 image_release(image);
233 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
David Sodman8ef20062015-01-06 09:23:40 -0800234}
235
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800236static void frecon_dbus_unregister(DBusConnection* connection, void* user_data)
David Sodman8ef20062015-01-06 09:23:40 -0800237{
238}
239
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800240static DBusHandlerResult frecon_dbus_message_handler(DBusConnection* connection,
241 DBusMessage* message,
242 void* user_data)
David Sodman8ef20062015-01-06 09:23:40 -0800243{
244 if (dbus_message_is_method_call(message,
245 kFreconDbusInterface, COMMAND_SWITCH_VT)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800246 return handle_switchvt(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800247 } else if (dbus_message_is_method_call(message,
248 kFreconDbusInterface, COMMAND_MAKE_VT)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800249 return handle_makevt(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800250 }
251 else if (dbus_message_is_method_call(message,
252 kFreconDbusInterface, COMMAND_TERMINATE)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800253 return handle_terminate(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800254 } else if (dbus_message_is_method_call(message,
255 kFreconDbusInterface, COMMAND_IMAGE)) {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800256 return handle_image(connection, message);
David Sodman8ef20062015-01-06 09:23:40 -0800257 }
258
259 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
David Sodman8ef20062015-01-06 09:23:40 -0800260}
261
262static DBusObjectPathVTable
263frecon_vtable = {
Stéphane Marchesinaf9e9ff2015-12-11 17:49:12 -0800264 frecon_dbus_unregister,
265 frecon_dbus_message_handler,
David Sodman8ef20062015-01-06 09:23:40 -0800266 NULL
267};
268
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800269static dbus_bool_t add_watch(DBusWatch* w, void* data)
David Sodman8ef20062015-01-06 09:23:40 -0800270{
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800271 dbus_t* dbus = (dbus_t*)data;
David Sodman8ef20062015-01-06 09:23:40 -0800272 dbus->watch = w;
273
274 return TRUE;
275}
276
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800277static void remove_watch(DBusWatch* w, void* data)
David Sodman8ef20062015-01-06 09:23:40 -0800278{
279}
280
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800281static void toggle_watch(DBusWatch* w, void* data)
David Sodman8ef20062015-01-06 09:23:40 -0800282{
283}
284
Dominik Behr46c567f2016-03-08 15:11:48 -0800285static DBusHandlerResult handle_login_prompt_visible(DBusMessage* message)
286{
287 if (login_prompt_visible_callback) {
288 login_prompt_visible_callback(login_prompt_visible_callback_userptr);
289 login_prompt_visible_callback = NULL;
290 login_prompt_visible_callback_userptr = NULL;
291 }
292 chrome_is_already_up = true;
293
294 return DBUS_HANDLER_RESULT_HANDLED;
295}
296
297static DBusHandlerResult frecon_dbus_message_filter(DBusConnection* connection,
298 DBusMessage* message,
299 void* user_data)
300{
301 if (dbus_message_is_signal(message,
Dominik Behr5f6742f2016-03-10 18:03:54 -0800302 kSessionManagerInterface, kLoginPromptVisibleSignal))
Dominik Behr46c567f2016-03-08 15:11:48 -0800303 return handle_login_prompt_visible(message);
Dominik Behr46c567f2016-03-08 15:11:48 -0800304
305 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
306}
307
Dominik Behr797a3832016-01-11 15:53:11 -0800308bool dbus_is_initialized(void)
309{
310 return !!dbus;
311}
312
313bool dbus_init()
David Sodmanbbcb0522014-09-19 10:34:07 -0700314{
315 dbus_t* new_dbus;
316 DBusError err;
David Sodman8ef20062015-01-06 09:23:40 -0800317 int result;
318 dbus_bool_t stat;
David Sodmanbbcb0522014-09-19 10:34:07 -0700319
Dominik Behr5f6742f2016-03-10 18:03:54 -0800320 if (dbus_first_init) {
321 dbus_first_init = false;
322 dbus_first_init_time = get_monotonic_time_ms();
323 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700324 dbus_error_init(&err);
325
326 new_dbus = (dbus_t*)calloc(1, sizeof(*new_dbus));
Stéphane Marchesinc236e0b2015-12-14 15:29:15 -0800327
328 if (!new_dbus)
Dominik Behr797a3832016-01-11 15:53:11 -0800329 return false;
Stéphane Marchesinc236e0b2015-12-14 15:29:15 -0800330
David Sodman8ef20062015-01-06 09:23:40 -0800331 new_dbus->fd = -1;
David Sodmanbbcb0522014-09-19 10:34:07 -0700332
333 new_dbus->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
334 if (dbus_error_is_set(&err)) {
Dominik Behr5f6742f2016-03-10 18:03:54 -0800335 if (!dbus_connect_fail) {
336 LOG(ERROR, "Cannot get DBUS connection");
337 dbus_connect_fail = true;
338 dbus_connect_fail_time = get_monotonic_time_ms();
339 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700340 free(new_dbus);
Dominik Behr797a3832016-01-11 15:53:11 -0800341 return false;
David Sodmanbbcb0522014-09-19 10:34:07 -0700342 }
343
Dominik Behr5f6742f2016-03-10 18:03:54 -0800344 if (dbus_connect_fail) {
345 int64_t t = get_monotonic_time_ms() - dbus_connect_fail_time;
346 LOG(INFO, "DBUS connected after %.1f seconds", (float)t / 1000.0f);
347 }
348
David Sodman8ef20062015-01-06 09:23:40 -0800349 result = dbus_bus_request_name(new_dbus->conn, kFreconDbusInterface,
350 DBUS_NAME_FLAG_DO_NOT_QUEUE, &err);
351
352 if (result <= 0) {
353 LOG(ERROR, "Unable to get name for server");
354 }
355
356 stat = dbus_connection_register_object_path(new_dbus->conn,
357 kFreconDbusPath,
358 &frecon_vtable,
359 NULL);
360
361 if (!stat) {
362 LOG(ERROR, "failed to register object path");
363 }
364
Dominik Behr46c567f2016-03-08 15:11:48 -0800365 dbus_bus_add_match(new_dbus->conn, kLoginPromptVisibleRule, &err);
366
367 stat = dbus_connection_add_filter(new_dbus->conn, frecon_dbus_message_filter, NULL, NULL);
368 if (!stat) {
369 LOG(ERROR, "failed to add message filter");
370 }
371
David Sodman8ef20062015-01-06 09:23:40 -0800372 stat = dbus_connection_set_watch_functions(new_dbus->conn,
373 add_watch, remove_watch, toggle_watch,
374 new_dbus, NULL);
375
376 if (!stat) {
377 LOG(ERROR, "Failed to set watch functions");
378 }
379
David Sodmanbbcb0522014-09-19 10:34:07 -0700380 dbus_connection_set_exit_on_disconnect(new_dbus->conn, FALSE);
381
Dominik Behr797a3832016-01-11 15:53:11 -0800382 dbus = new_dbus;
383 return true;
David Sodmanbbcb0522014-09-19 10:34:07 -0700384}
385
Dominik Behr5f6742f2016-03-10 18:03:54 -0800386bool dbus_init_wait()
387{
388 while (!dbus_is_initialized()) {
389 if (!dbus_init()) {
390 int64_t t = get_monotonic_time_ms() - dbus_first_init_time;
391 if (t >= DBUS_INIT_TIMEOUT_MS) {
392 LOG(ERROR, "DBUS init failed after a timeout of %u sec", DBUS_INIT_TIMEOUT_MS/1000);
393 return false;
394 }
395 }
396 usleep(DBUS_WAIT_DELAY_US);
397 }
398 return true;
399}
400
Dominik Behr797a3832016-01-11 15:53:11 -0800401static bool dbus_method_call0(const char* service_name,
402 const char* service_path,
403 const char* service_interface,
404 const char* method)
David Sodman003faed2014-11-03 09:02:10 -0800405{
Dominik Behr797a3832016-01-11 15:53:11 -0800406 DBusMessage* msg = NULL;
407 if (!dbus) {
408 LOG(ERROR, "dbus not initialized");
409 return false;
410 }
David Sodman003faed2014-11-03 09:02:10 -0800411
412 msg = dbus_message_new_method_call(service_name,
413 service_path, service_interface, method);
414
415 if (!msg)
416 return false;
417
418 if (!dbus_connection_send_with_reply_and_block(dbus->conn,
David Sodman8ef20062015-01-06 09:23:40 -0800419 msg, DBUS_DEFAULT_DELAY, NULL)) {
David Sodman003faed2014-11-03 09:02:10 -0800420 dbus_message_unref(msg);
421 return false;
422 }
423
424 dbus_connection_flush(dbus->conn);
425 dbus_message_unref(msg);
426
427 return true;
428}
429
Dominik Behr797a3832016-01-11 15:53:11 -0800430static bool dbus_method_call1(const char* service_name,
431 const char* service_path,
432 const char* service_interface,
433 const char* method, int arg_type, void* param)
David Sodmanbbcb0522014-09-19 10:34:07 -0700434{
Dominik Behr797a3832016-01-11 15:53:11 -0800435 DBusMessage* msg = NULL;
436 if (!dbus) {
437 LOG(ERROR, "dbus not initialized");
438 return false;
439 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700440
441 msg = dbus_message_new_method_call(service_name,
442 service_path, service_interface, method);
443
444 if (!msg)
445 return false;
446
447 if (!dbus_message_append_args(msg,
David Sodman19e4f9d2015-03-10 11:11:09 -0700448 arg_type, param, DBUS_TYPE_INVALID)) {
David Sodmanbbcb0522014-09-19 10:34:07 -0700449 dbus_message_unref(msg);
450 return false;
451 }
452
453 if (!dbus_connection_send_with_reply_and_block(dbus->conn,
David Sodman8ef20062015-01-06 09:23:40 -0800454 msg, DBUS_DEFAULT_DELAY, NULL)) {
David Sodmanbbcb0522014-09-19 10:34:07 -0700455 dbus_message_unref(msg);
456 return false;
457 }
458
459 dbus_connection_flush(dbus->conn);
460 dbus_message_unref(msg);
461
462 return true;
463}
464
Dominik Behr797a3832016-01-11 15:53:11 -0800465void dbus_destroy(void)
David Sodmanbbcb0522014-09-19 10:34:07 -0700466{
467 /* FIXME - not sure what the right counterpart to
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800468 * dbus_bus_get() is, unref documentation is rather
469 * unclear. Not a big issue but it would be nice to
470 * clean up properly here
471 */
David Sodmanbbcb0522014-09-19 10:34:07 -0700472 /* dbus_connection_unref(dbus->conn); */
Dominik Behr797a3832016-01-11 15:53:11 -0800473 if (dbus) {
David Sodman8ef20062015-01-06 09:23:40 -0800474 free(dbus);
Dominik Behr797a3832016-01-11 15:53:11 -0800475 dbus = NULL;
476 }
David Sodman8ef20062015-01-06 09:23:40 -0800477}
478
Dominik Behrd7112672016-01-20 16:59:34 -0800479void dbus_add_fds(fd_set* read_set, fd_set* exception_set, int *maxfd)
David Sodman8ef20062015-01-06 09:23:40 -0800480{
Dominik Behr797a3832016-01-11 15:53:11 -0800481 if (!dbus)
Dominik Behrd7112672016-01-20 16:59:34 -0800482 return;
Dominik Behr797a3832016-01-11 15:53:11 -0800483
David Sodman8ef20062015-01-06 09:23:40 -0800484 if (dbus->fd < 0)
485 dbus->fd = dbus_watch_get_unix_fd(dbus->watch);
486
487 if (dbus->fd >= 0) {
488 FD_SET(dbus->fd, read_set);
489 FD_SET(dbus->fd, exception_set);
490 }
David Sodman8ef20062015-01-06 09:23:40 -0800491
Dominik Behrd7112672016-01-20 16:59:34 -0800492 if (dbus->fd > *maxfd)
493 *maxfd = dbus->fd;
David Sodman8ef20062015-01-06 09:23:40 -0800494}
495
Dominik Behr797a3832016-01-11 15:53:11 -0800496void dbus_dispatch_io(void)
David Sodman8ef20062015-01-06 09:23:40 -0800497{
Dominik Behr797a3832016-01-11 15:53:11 -0800498 if (!dbus)
499 return;
500
David Sodman8ef20062015-01-06 09:23:40 -0800501 dbus_watch_handle(dbus->watch, DBUS_WATCH_READABLE);
502 while (dbus_connection_get_dispatch_status(dbus->conn)
503 == DBUS_DISPATCH_DATA_REMAINS) {
504 dbus_connection_dispatch(dbus->conn);
505 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700506}
Dominik Behr797a3832016-01-11 15:53:11 -0800507
508void dbus_report_user_activity(int activity_type)
509{
510 dbus_bool_t allow_off = false;
511 if (!dbus)
512 return;
513
514 dbus_method_call1(kPowerManagerServiceName,
515 kPowerManagerServicePath,
516 kPowerManagerInterface,
517 kHandleUserActivityMethod,
518 DBUS_TYPE_INT32, &activity_type);
519
520 switch (activity_type) {
521 case USER_ACTIVITY_BRIGHTNESS_UP_KEY_PRESS:
522 (void)dbus_method_call0(kPowerManagerServiceName,
523 kPowerManagerServicePath,
524 kPowerManagerInterface,
525 kIncreaseScreenBrightnessMethod);
526 break;
527 case USER_ACTIVITY_BRIGHTNESS_DOWN_KEY_PRESS:
528 /*
529 * Shouldn't allow the screen to go
530 * completely off while frecon is active
531 * so passing false to allow_off
532 */
533 (void)dbus_method_call1(kPowerManagerServiceName,
534 kPowerManagerServicePath,
535 kPowerManagerInterface,
536 kDecreaseScreenBrightnessMethod,
537 DBUS_TYPE_BOOLEAN, &allow_off);
538 break;
539 }
540}
541
Dominik Behr46c567f2016-03-08 15:11:48 -0800542/*
543 * tell Chrome to take ownership of the display (DRM master)
544 */
Dominik Behr797a3832016-01-11 15:53:11 -0800545void dbus_take_display_ownership(void)
546{
547 if (!dbus)
548 return;
549 (void)dbus_method_call0(kLibCrosServiceName,
550 kLibCrosServicePath,
551 kLibCrosServiceInterface,
552 kTakeDisplayOwnership);
553}
554
Dominik Behr46c567f2016-03-08 15:11:48 -0800555/*
556 * ask Chrome to give up display ownership (DRM master)
557 */
Dominik Behr797a3832016-01-11 15:53:11 -0800558void dbus_release_display_ownership(void)
559{
560 if (!dbus)
561 return;
562 (void)dbus_method_call0(kLibCrosServiceName,
563 kLibCrosServicePath,
564 kLibCrosServiceInterface,
565 kReleaseDisplayOwnership);
566}
567
Dominik Behr46c567f2016-03-08 15:11:48 -0800568void dbus_set_login_prompt_visible_callback(void (*callback)(void*),
569 void* userptr)
570{
571 if (chrome_is_already_up) {
572 if (callback)
573 callback(userptr);
574 } else {
575 if (login_prompt_visible_callback && callback) {
576 LOG(ERROR, "trying to register login prompt visible callback multiple times");
577 return;
578 }
579 login_prompt_visible_callback = callback;
580 login_prompt_visible_callback_userptr = userptr;
581 }
582}