From 87936ffc80ba681069f61125c0fd7690d0859b56 Mon Sep 17 00:00:00 2001 From: Simo Piiroinen Date: Thu, 7 Feb 2019 09:28:02 +0200 Subject: [PATCH] [dbus] Add target mode signaling. JB#44479 Some transitions such as activating mtp mode can take so long that giving user feedback becomes necessary. However as usb-moded exposes only what has happened, there is no reliable source of information for what is going on. Also, the "sig_usb_state_ind" D-Bus signal is used for transmitting both mode change notifications and transient events - which is confusing and can cause problems if new signals are ever added as there is no backwards compatible ways to tell apart mode names from event names. Add dbus query / change notifications for target mode. The target mode is changed before starting mode transition, so that processes listening to signals from usb-moded know what kind of transition is happening when the current mode changes to "busy". Add separate dbus signals for mode changes and events. The legacy "sig_usb_state_ind" is retained as-is for the sake of backwards compatibility. Also synchronize the content of D-Bus Introspect xml data provided as a file in development package and made available at runtime via D-Bus method call. Signed-off-by: Simo Piiroinen --- src/com.meego.usb_moded.xml | 12 ++++ src/usb_moded-control.c | 62 ++++++++++++++++++-- src/usb_moded-control.h | 4 +- src/usb_moded-dbus-private.h | 6 +- src/usb_moded-dbus.c | 107 ++++++++++++++++++++++++++++------- src/usb_moded-dbus.h | 6 +- src/usb_moded-modesetting.c | 6 +- src/usb_moded-udev.c | 10 ++-- src/usb_moded.c | 3 +- 9 files changed, 178 insertions(+), 38 deletions(-) diff --git a/src/com.meego.usb_moded.xml b/src/com.meego.usb_moded.xml index 9f94112..c25d883 100644 --- a/src/com.meego.usb_moded.xml +++ b/src/com.meego.usb_moded.xml @@ -5,6 +5,9 @@ + + + @@ -56,8 +59,17 @@ + + + + + + + + + diff --git a/src/usb_moded-control.c b/src/usb_moded-control.c index 4e1dfdf..514870d 100644 --- a/src/usb_moded-control.c +++ b/src/usb_moded-control.c @@ -1,7 +1,7 @@ /** * @file usb_moded-control.c * - * Copyright (C) 2013-2018 Jolla. All rights reserved. + * Copyright (C) 2013-2019 Jolla. All rights reserved. * * @author: Philippe De Swert * @author: Simo Piiroinen @@ -44,10 +44,13 @@ const char *control_get_external_mode (void); static void control_set_external_mode (const char *mode); void control_clear_external_mode (void); static void control_update_external_mode (void); +const char *control_get_target_mode (void); +static void control_set_target_mode (const char *mode); +void control_clear_target_mode (void); const char *control_get_usb_mode (void); void control_clear_internal_mode (void); void control_set_usb_mode (const char *mode); -void control_mode_switched (const char *override); +void control_mode_switched (const char *mode); void control_select_usb_mode (void); void control_set_cable_state (cable_state_t cable_state); cable_state_t control_get_cable_state (void); @@ -60,10 +63,16 @@ bool control_get_connection_state (void); /* The external mode; * - * What was the last mode signaled over D-Bus. + * What was the last current mode signaled over D-Bus. */ static char *control_external_mode = NULL; +/* The target mode; + * + * What was the last target mode signaled over D-Bus. + */ +static char *control_target_mode = NULL; + /** The logical mode name * * Full set of valid modes can occur here @@ -136,10 +145,21 @@ static void control_set_external_mode(const char *mode) if( !strcmp(control_external_mode, MODE_ASK) ) { /* send signal, mode will be set when the dialog service calls * the set_mode method call. */ - umdbus_send_state_signal(USB_CONNECTED_DIALOG_SHOW); + umdbus_send_event_signal(USB_CONNECTED_DIALOG_SHOW); } - umdbus_send_state_signal(control_external_mode); + umdbus_send_current_state_signal(control_external_mode); + + if( strcmp(control_external_mode, MODE_BUSY) ) { + /* Stable state reached. Synchronize target state. + * + * Note that normally this ends up being a nop, + * but might be needed if the originally scheduled + * target could not be reached due to errors / user + * disconnecting the cable. + */ + control_set_target_mode(control_external_mode); + } EXIT: return; @@ -159,6 +179,35 @@ static void control_update_external_mode(void) control_set_external_mode(external_mode); } +const char *control_get_target_mode(void) +{ + return control_target_mode ?: MODE_UNDEFINED; +} + +static void control_set_target_mode(const char *mode) +{ + gchar *previous = control_target_mode; + if( !g_strcmp0(previous, mode) ) + goto EXIT; + + log_debug("target_mode: %s -> %s", + previous, mode); + + control_target_mode = g_strdup(mode); + g_free(previous); + + umdbus_send_target_state_signal(control_target_mode); + +EXIT: + return; +} + +void control_clear_target_mode(void) +{ + g_free(control_target_mode), + control_target_mode = 0; +} + /** get the usb mode * * @return the currently set mode @@ -191,6 +240,9 @@ void control_set_usb_mode(const char *mode) control_internal_mode = g_strdup(mode); g_free(previous); + /* Update target mode before declaring busy */ + control_set_target_mode(control_internal_mode); + /* Invalidate current mode for the duration of mode transition */ control_set_external_mode(MODE_BUSY); diff --git a/src/usb_moded-control.h b/src/usb_moded-control.h index 0ad22e3..bc09f44 100644 --- a/src/usb_moded-control.h +++ b/src/usb_moded-control.h @@ -1,7 +1,7 @@ /** * @file usb_moded-control.h * - * Copyright (C) 2013-2018 Jolla. All rights reserved. + * Copyright (C) 2013-2019 Jolla. All rights reserved. * * @author: Philippe De Swert * @author: Simo Piiroinen @@ -32,6 +32,8 @@ void control_rethink_usb_charging_fallback(void); const char *control_get_external_mode (void); void control_clear_external_mode (void); +const char *control_get_target_mode (void); +void control_clear_target_mode (void); const char *control_get_usb_mode (void); void control_clear_internal_mode (void); void control_set_usb_mode (const char *mode); diff --git a/src/usb_moded-dbus-private.h b/src/usb_moded-dbus-private.h index cf55720..dc6da43 100644 --- a/src/usb_moded-dbus-private.h +++ b/src/usb_moded-dbus-private.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * Copyright (C) 2013-2018 Jolla Ltd. + * Copyright (C) 2013-2019 Jolla Ltd. * * Author: Philippe De Swert * Author: Philippe De Swert @@ -59,7 +59,9 @@ DBusConnection *umdbus_get_connection (void); gboolean umdbus_init_connection (void); gboolean umdbus_init_service (void); void umdbus_cleanup (void); -int umdbus_send_state_signal (const char *state_ind); +void umdbus_send_current_state_signal (const char *state_ind); +void umdbus_send_target_state_signal (const char *state_ind); +void umdbus_send_event_signal (const char *state_ind); int umdbus_send_error_signal (const char *error); int umdbus_send_supported_modes_signal (const char *supported_modes); int umdbus_send_available_modes_signal (const char *available_modes); diff --git a/src/usb_moded-dbus.c b/src/usb_moded-dbus.c index b7274a0..b7db115 100644 --- a/src/usb_moded-dbus.c +++ b/src/usb_moded-dbus.c @@ -2,7 +2,7 @@ * @file usb_moded-dbus.c * * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * Copyright (C) 2012-2018 Jolla. All rights reserved. + * Copyright (C) 2012-2019 Jolla. All rights reserved. * * @author: Philippe De Swert * @author: Philippe De Swert @@ -65,7 +65,10 @@ gboolean umdbus_init_service (void); static void umdbus_cleanup_service (void); void umdbus_cleanup (void); static int umdbus_send_signal_ex (const char *signal_type, const char *content); -int umdbus_send_state_signal (const char *state_ind); +static void umdbus_send_legacy_signal (const char *state_ind); +void umdbus_send_current_state_signal (const char *state_ind); +void umdbus_send_target_state_signal (const char *state_ind); +void umdbus_send_event_signal (const char *state_ind); int umdbus_send_error_signal (const char *error); int umdbus_send_supported_modes_signal (const char *supported_modes); int umdbus_send_available_modes_signal (const char *available_modes); @@ -119,6 +122,9 @@ static const char umdbus_introspect_usbmoded[] = " \n" " \n" " \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" @@ -147,20 +153,40 @@ static const char umdbus_introspect_usbmoded[] = " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" -" " -" " -" " -" " -" " -" " -" " +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" @@ -168,16 +194,19 @@ static const char umdbus_introspect_usbmoded[] = " \n" " \n" " \n" -" \n" -" \n" -" \n" -" \n" +" \n" " \n" " \n" " \n" " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" "\n"; @@ -274,6 +303,12 @@ static DBusHandlerResult umdbus_msg_handler(DBusConnection *const connection, DB if((reply = dbus_message_new_method_return(msg))) dbus_message_append_args (reply, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID); } + else if(!strcmp(member, USB_MODE_TARGET_STATE_GET)) + { + const char *mode = control_get_target_mode(); + if((reply = dbus_message_new_method_return(msg))) + dbus_message_append_args (reply, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID); + } else if(!strcmp(member, USB_MODE_STATE_SET)) { const char *mode = control_get_external_mode(); @@ -801,16 +836,48 @@ static int umdbus_send_signal_ex(const char *signal_type, const char *content) return result; } -/** - * Send regular usb_moded state signal +/** Send legacy usb_moded state_or_event signal * - * @return 0 on success, 1 on failure - * @param state_ind the signal name + * The legacy USB_MODE_SIGNAL_NAME signal is used for + * both mode changes and stateless events. * -*/ -int umdbus_send_state_signal(const char *state_ind) + * @param state_ind mode name or event name + */ +static void umdbus_send_legacy_signal(const char *state_ind) +{ + umdbus_send_signal_ex(USB_MODE_SIGNAL_NAME, state_ind); +} + +/** Send usb_moded current state signal + * + * @param state_ind mode name + */ +void umdbus_send_current_state_signal(const char *state_ind) +{ + umdbus_send_signal_ex(USB_MODE_CURRENT_STATE_SIGNAL_NAME, + state_ind); + umdbus_send_legacy_signal(state_ind); +} + +/** Send usb_moded target state signal + * + * @param state_ind mode name + */ +void umdbus_send_target_state_signal(const char *state_ind) +{ + umdbus_send_signal_ex(USB_MODE_TARGET_STATE_SIGNAL_NAME, + state_ind); +} + +/** Send usb_moded event signal + * + * @param state_ind event name + */ +void umdbus_send_event_signal(const char *state_ind) { - return umdbus_send_signal_ex(USB_MODE_SIGNAL_NAME, state_ind); + umdbus_send_signal_ex(USB_MODE_EVENT_SIGNAL_NAME, + state_ind); + umdbus_send_legacy_signal(state_ind); } /** diff --git a/src/usb_moded-dbus.h b/src/usb_moded-dbus.h index 4a26f68..278f7a6 100644 --- a/src/usb_moded-dbus.h +++ b/src/usb_moded-dbus.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * Copyright (C) 2012-2018 Jolla. All rights reserved. + * Copyright (C) 2012-2019 Jolla. All rights reserved. * * Author: Philippe De Swert * Author: Philippe De Swert @@ -47,6 +47,9 @@ * states listed in usb_moded-modes.h. **/ # define USB_MODE_SIGNAL_NAME "sig_usb_state_ind" +# define USB_MODE_CURRENT_STATE_SIGNAL_NAME "sig_usb_current_state_ind" +# define USB_MODE_TARGET_STATE_SIGNAL_NAME "sig_usb_target_state_ind" +# define USB_MODE_EVENT_SIGNAL_NAME "sig_usb_event_ind" # define USB_MODE_CONFIG_SIGNAL_NAME "sig_usb_config_ind" # define USB_MODE_ERROR_SIGNAL_NAME "sig_usb_state_error_ind" # define USB_MODE_SUPPORTED_MODES_SIGNAL_NAME "sig_usb_supported_modes_ind" @@ -56,6 +59,7 @@ /* supported methods */ # define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */ +# define USB_MODE_TARGET_STATE_GET "get_target_state" /* returns the target mode */ # define USB_MODE_RESCUE_OFF "rescue_off" /* turns rescue mode off so normal mode selection is restored */ # define USB_MODE_CONFIG_GET "get_config" /* returns the mode set in the config */ # define USB_MODE_LIST "get_modes" /* returns a comma-separated list of supported modes for ui's */ diff --git a/src/usb_moded-modesetting.c b/src/usb_moded-modesetting.c index 3c99836..b309ade 100644 --- a/src/usb_moded-modesetting.c +++ b/src/usb_moded-modesetting.c @@ -2,7 +2,7 @@ * @file usb_moded-modesetting.c * * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * Copyright (C) 2013-2018 Jolla Ltd. + * Copyright (C) 2013-2019 Jolla Ltd. * * @author: Philippe De Swert * @author: Philippe De Swert @@ -419,7 +419,7 @@ static bool modesetting_enter_mass_storage_mode(mode_list_elem_t *data) goto EXIT; /* send unmount signal so applications can release their grasp on the fs, do this here so they have time to act */ - umdbus_send_state_signal(USB_PRE_UNMOUNT); + umdbus_send_event_signal(USB_PRE_UNMOUNT); /* Get "No Force Unit Access" from config */ nofua = config_find_sync(); @@ -531,7 +531,7 @@ static bool modesetting_enter_mass_storage_mode(mode_list_elem_t *data) if( ack ) { /* only send data in use signal in case we actually succeed */ - umdbus_send_state_signal(DATA_IN_USE); + umdbus_send_event_signal(DATA_IN_USE); } else { /* Try to undo any unmounts we might have managed to make */ diff --git a/src/usb_moded-udev.c b/src/usb_moded-udev.c index 5142d85..b2aedea 100644 --- a/src/usb_moded-udev.c +++ b/src/usb_moded-udev.c @@ -2,7 +2,7 @@ * @file usb_moded-udev.c * * Copyright (C) 2011 Nokia Corporation. All rights reserved. - * Copyright (C) 2013-2018 Jolla Ltd. + * Copyright (C) 2013-2019 Jolla Ltd. * * @author: Philippe De Swert * @author: Philippe De Swert @@ -182,10 +182,10 @@ static void umudev_cable_state_changed(void) /* dontcare */ break; case CABLE_STATE_CHARGER_CONNECTED: - umdbus_send_state_signal(CHARGER_DISCONNECTED); + umdbus_send_event_signal(CHARGER_DISCONNECTED); break; case CABLE_STATE_PC_CONNECTED: - umdbus_send_state_signal(USB_DISCONNECTED); + umdbus_send_event_signal(USB_DISCONNECTED); break; } @@ -199,10 +199,10 @@ static void umudev_cable_state_changed(void) /* dontcare */ break; case CABLE_STATE_CHARGER_CONNECTED: - umdbus_send_state_signal(CHARGER_CONNECTED); + umdbus_send_event_signal(CHARGER_CONNECTED); break; case CABLE_STATE_PC_CONNECTED: - umdbus_send_state_signal(USB_CONNECTED); + umdbus_send_event_signal(USB_CONNECTED); break; } diff --git a/src/usb_moded.c b/src/usb_moded.c index 87c5080..d42e904 100644 --- a/src/usb_moded.c +++ b/src/usb_moded.c @@ -2,7 +2,7 @@ * @file usb_moded.c * * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * Copyright (C) 2012-2018 Jolla. All rights reserved. + * Copyright (C) 2012-2019 Jolla. All rights reserved. * * @author: Philippe De Swert * @author: Philippe De Swert @@ -659,6 +659,7 @@ static void usbmoded_cleanup(void) control_clear_cable_state(); control_clear_internal_mode(); control_clear_external_mode(); + control_clear_target_mode(); modesetting_quit();