35 #if defined SAILFISH_ACCESS_CONTROL && !defined SYSTEMD
36 # error if SAILFISH_ACCESS_CONTROL is defined, SYSTEMD must be defined as well
53 #define CONTROL_PENDING_USER_CHANGE_TIMEOUT (3000)
65 const char *control_get_external_mode (
void);
66 static void control_set_external_mode (
const char *mode);
67 void control_clear_external_mode (
void);
68 static void control_update_external_mode (
void);
69 const char *control_get_target_mode (
void);
70 static void control_set_target_mode (
const char *mode);
71 void control_clear_target_mode (
void);
76 void control_clear_internal_mode (
void);
77 static void control_set_usb_mode (
const char *mode);
78 void control_mode_switched (
const char *mode);
79 static gboolean control_pending_user_change_cb (gpointer aptr);
80 static bool control_have_pending_user_change (
void);
81 static void control_begin_pending_user_change(
void);
82 static void control_end_pending_user_change (
void);
88 static bool control_get_enabled (
void);
90 static bool control_get_in_rescue_mode (
void);
91 static void control_set_in_rescue_mode (
bool in_rescue_mode);
92 static void control_rethink_usb_mode (
void);
95 void control_clear_cable_state (
void);
106 static char *control_external_mode = NULL;
112 static char *control_target_mode = NULL;
118 static char *control_internal_mode = NULL;
122 static char *control_selected_mode = NULL;
130 static cable_state_t control_cable_state = CABLE_STATE_UNKNOWN;
134 static uid_t control_user_for_mode = UID_UNKNOWN;
138 static guint control_pending_user_change_id = 0;
142 static bool control_in_rescue_mode =
false;
146 static bool control_is_enabled =
false;
159 return control_user_for_mode;
169 LOG_REGISTER_CONTEXT;
171 if( control_user_for_mode != uid ) {
172 log_debug(
"control_user_for_mode: %d -> %d",
173 (
int)control_user_for_mode, (
int)uid);
174 control_user_for_mode = uid;
178 const char *control_get_external_mode(
void)
180 LOG_REGISTER_CONTEXT;
185 static void control_set_external_mode(
const char *mode)
187 LOG_REGISTER_CONTEXT;
189 gchar *previous = control_external_mode;
190 if( !g_strcmp0(previous, mode) )
193 log_debug(
"external_mode: %s -> %s",
196 control_external_mode = g_strdup(mode);
201 if( !strcmp(control_external_mode,
MODE_ASK) ) {
209 if( strcmp(control_external_mode,
MODE_BUSY) ) {
217 control_set_target_mode(control_external_mode);
224 void control_clear_external_mode(
void)
226 LOG_REGISTER_CONTEXT;
228 g_free(control_external_mode),
229 control_external_mode = 0;
232 static void control_update_external_mode(
void)
234 LOG_REGISTER_CONTEXT;
237 const char *external_mode = common_map_mode_to_external(internal_mode);
239 control_set_external_mode(external_mode);
242 const char *control_get_target_mode(
void)
244 LOG_REGISTER_CONTEXT;
249 static void control_set_target_mode(
const char *mode)
251 LOG_REGISTER_CONTEXT;
253 gchar *previous = control_target_mode;
254 if( !g_strcmp0(previous, mode) )
257 log_debug(
"target_mode: %s -> %s",
260 control_target_mode = g_strdup(mode);
269 void control_clear_target_mode(
void)
271 LOG_REGISTER_CONTEXT;
273 g_free(control_target_mode),
274 control_target_mode = 0;
283 LOG_REGISTER_CONTEXT;
284 return control_selected_mode;
293 LOG_REGISTER_CONTEXT;
294 char *prev = control_selected_mode;
295 if( g_strcmp0(prev, mode) ) {
296 log_debug(
"requested: %s -> %s", prev, mode);
297 control_selected_mode = mode ? g_strdup(mode) : 0;
309 LOG_REGISTER_CONTEXT;
315 control_rethink_usb_mode();
328 LOG_REGISTER_CONTEXT;
330 return control_internal_mode;
333 void control_clear_internal_mode(
void)
335 LOG_REGISTER_CONTEXT;
337 g_free(control_internal_mode),
338 control_internal_mode = 0;
345 static void control_set_usb_mode(
const char *mode)
347 LOG_REGISTER_CONTEXT;
352 gchar *previous = control_internal_mode;
353 if( !g_strcmp0(previous, mode) )
356 log_debug(
"internal_mode: %s -> %s",
359 control_internal_mode = g_strdup(mode);
363 control_set_target_mode(control_internal_mode);
369 worker_request_hardware_mode(control_internal_mode);
379 void control_mode_switched(
const char *mode)
381 LOG_REGISTER_CONTEXT;
385 if( g_strcmp0(control_internal_mode, mode) ) {
386 log_debug(
"internal_mode: %s -> %s",
387 control_internal_mode, mode);
388 g_free(control_internal_mode),
389 control_internal_mode = g_strdup(mode);
393 control_update_external_mode();
400 static gboolean control_pending_user_change_cb(gpointer aptr)
404 if( control_pending_user_change_id ) {
405 log_debug(
"pending user change timeout");
406 control_pending_user_change_id = 0;
407 control_rethink_usb_mode();
410 return G_SOURCE_REMOVE;
415 static bool control_have_pending_user_change(
void)
417 return control_pending_user_change_id != 0;
422 static void control_begin_pending_user_change(
void)
424 if( !control_pending_user_change_id ) {
425 log_debug(
"pending user change started");
426 control_pending_user_change_id =
428 control_pending_user_change_cb, 0);
434 static void control_end_pending_user_change(
void)
436 if( control_pending_user_change_id ) {
437 log_debug(
"pending user change stopped");
438 g_source_remove(control_pending_user_change_id),
439 control_pending_user_change_id = 0;
460 control_begin_pending_user_change();
462 control_end_pending_user_change();
468 control_rethink_usb_mode();
479 control_end_pending_user_change();
481 control_rethink_usb_mode();
488 log_debug(
"in_usermode = %d; in_shutdown = %d",
491 control_rethink_usb_mode();
498 log_debug(
"settings changed");
500 control_rethink_usb_mode();
509 control_rethink_usb_mode();
514 static bool control_get_enabled(
void)
516 return control_is_enabled;
523 if( control_is_enabled != enable ) {
524 control_is_enabled = enable;
525 log_debug(
"control_enabled = %d", control_is_enabled);
527 control_rethink_usb_mode();
533 static bool control_get_in_rescue_mode(
void)
535 return control_in_rescue_mode;
540 static void control_set_in_rescue_mode(
bool in_rescue_mode)
542 if( control_in_rescue_mode != in_rescue_mode ) {
543 log_debug(
"in_rescue_mode: %d -> %d",
544 control_in_rescue_mode, in_rescue_mode);
545 control_in_rescue_mode = in_rescue_mode;
554 static void control_rethink_usb_mode(
void)
556 LOG_REGISTER_CONTEXT;
561 const char *mode_to_use = 0;
562 char *mode_to_free = 0;
565 auto const char *use_mode(
const char *mode) {
566 if( g_strcmp0(mode_to_use, mode) ) {
567 log_debug(
"mode_to_use: %s -> %s",
568 mode_to_use ?:
"unset",
575 log_debug(
"re-evaluating usb mode ...");
578 auto const char *use_allocated_mode(
char *mode) {
579 g_free(mode_to_free), mode_to_free = mode;
580 return use_mode(mode_to_free);
587 if( !control_get_enabled() ) {
588 log_debug(
"starting up; mode changes blocked");
597 if( cable_state != CABLE_STATE_PC_CONNECTED ) {
600 control_set_in_rescue_mode(
false);
602 if( cable_state == CABLE_STATE_CHARGER_CONNECTED ) {
621 if( usbmoded_get_rescue_mode() || control_get_in_rescue_mode() ) {
627 use_mode(MODE_DEVELOPER);
628 control_set_in_rescue_mode(
true);
632 control_set_in_rescue_mode(
false);
636 if( usbmoded_get_diag_mode() ) {
641 log_err(
"Diagnostic mode is not configured!");
645 log_debug(
"Entering diagnostic mode!");
661 log_debug(
"in bootup; dynamic modes blocked");
680 log_debug(
"in shutdown, retaining '%s' mode", current_mode);
694 log_debug(
"mode '%s' is not valid", mode_to_use);
697 else if( !usbmoded_is_mode_permitted(mode_to_use, current_user) ) {
700 log_debug(
"mode '%s' is not permitted", mode_to_use);
712 uid_t uid = (current_user == UID_UNKNOWN) ? 0 : current_user;
713 use_allocated_mode(config_get_mode_setting(uid));
720 if( !g_strcmp0(mode_to_use,
MODE_ASK) ) {
721 if( current_user == UID_UNKNOWN ) {
724 log_debug(
"mode '%s' is not applicable", mode_to_use);
729 if( *available && !strchr(available,
',') ) {
730 use_allocated_mode(available), available = 0;
749 else if( !usbmoded_is_mode_permitted(mode_to_use, current_user) ) {
750 log_debug(
"mode '%s' is not permitted", mode_to_use);
766 if( !g_strcmp0(current_mode, mode_to_use) ) {
771 log_debug(
"mode '%s' must be terminated", mode_to_use);
784 if( !g_strcmp0(mode_to_use,
MODE_ASK) ) {
787 log_debug(
"mode '%s' is not applicable", mode_to_use);
790 else if( g_strcmp0(current_mode, mode_to_use) ) {
795 log_debug(
"mode '%s' is not applicable", mode_to_use);
807 log_debug(
"selected mode = %s", mode_to_use);
808 control_set_usb_mode(mode_to_use);
815 g_free(mode_to_free);
824 LOG_REGISTER_CONTEXT;
826 cable_state_t prev = control_cable_state;
827 control_cable_state = cable_state;
829 if( control_cable_state == prev )
832 log_debug(
"control_cable_state: %s -> %s",
833 cable_state_repr(prev),
834 cable_state_repr(control_cable_state));
836 control_rethink_usb_mode();
848 LOG_REGISTER_CONTEXT;
850 return control_cable_state;
853 void control_clear_cable_state(
void)
855 LOG_REGISTER_CONTEXT;
857 control_cable_state = CABLE_STATE_UNKNOWN;
866 LOG_REGISTER_CONTEXT;
868 bool connected =
false;
870 case CABLE_STATE_CHARGER_CONNECTED:
871 case CABLE_STATE_PC_CONNECTED: