diff --git a/src/usb_moded-devicelock.c b/src/usb_moded-devicelock.c index 1ec6583..23e1986 100644 --- a/src/usb_moded-devicelock.c +++ b/src/usb_moded-devicelock.c @@ -114,29 +114,18 @@ gboolean usb_moded_get_export_permission(void) static void devicelock_state_changed(devicelock_state_t state) { - if( device_lock_state != state ) { - log_debug("devicelock state: %s -> %s", - devicelock_state_repr(device_lock_state), - devicelock_state_repr(state)); - device_lock_state = state; - - if( device_lock_state == DEVICE_LOCK_UNLOCKED && - get_usb_connection_state() == 1 ) - { - const char *usb_mode = get_usb_mode(); - log_debug("usb_mode %s\n", usb_mode); - - /* if the mode is MODE_CHARGING_FALLBACK we know the user - * has not selected any mode, in case it things are still - * undefined it cannot hurt to try again to set a mode */ - if(!strcmp(usb_mode, MODE_UNDEFINED) || - !strcmp(usb_mode, MODE_CHARGING_FALLBACK)) - { - log_debug("set_usb"); - set_usb_connected_state(); - } - } - } + if( device_lock_state == state ) + goto EXIT; + + log_debug("devicelock state: %s -> %s", + devicelock_state_repr(device_lock_state), + devicelock_state_repr(state)); + device_lock_state = state; + + rethink_usb_charging_fallback(); + +EXIT: + return; } static DBusPendingCall *devicelock_state_query_pc = 0; diff --git a/src/usb_moded-dsme.c b/src/usb_moded-dsme.c index 0b04414..1896781 100644 --- a/src/usb_moded-dsme.c +++ b/src/usb_moded-dsme.c @@ -26,6 +26,8 @@ #include #include "usb_moded-dsme.h" +#include "usb_moded.h" + #include "usb_moded-dbus-private.h" #include "usb_moded-log.h" @@ -87,11 +89,16 @@ static void device_state_changed(const char *state) log_debug("device state: %s", state ?: "(null)"); - if( in_user_state != to_user_state ) { - in_user_state = to_user_state; - log_debug("in user state: %s", - in_user_state ? "true" : "false"); - } + if( in_user_state == to_user_state ) + goto EXIT; + + in_user_state = to_user_state; + log_debug("in user state: %s", in_user_state ? "true" : "false"); + + rethink_usb_charging_fallback(); + +EXIT: + return; } static DBusPendingCall *device_state_query_pc = 0; diff --git a/src/usb_moded.c b/src/usb_moded.c index 1a32c71..0a1fbcd 100644 --- a/src/usb_moded.c +++ b/src/usb_moded.c @@ -251,6 +251,46 @@ void set_charger_connected(gboolean state) current_mode.connected = FALSE; } } +/** Check if we can/should leave charging fallback mode + */ +void +rethink_usb_charging_fallback(void) +{ + /* Cable must be connected and suitable usb-mode mode + * selected for any of this to apply. + */ + if( !get_usb_connection_state() ) + goto EXIT; + + const char *usb_mode = get_usb_mode(); + + if( strcmp(usb_mode, MODE_UNDEFINED) && + strcmp(usb_mode, MODE_CHARGING_FALLBACK) ) + goto EXIT; + + /* If device locking is supported, the device must be in + * unlocked state (or rescue mode must be active). + */ +#ifdef MEEGOLOCK + if( !usb_moded_get_export_permission() && !rescue_mode ) { + log_notice("device is locked; stay in %s", usb_mode); + goto EXIT; + } +#endif + + /* Device must be in USER state or in rescue mode + */ + if( !is_in_user_state() && !rescue_mode ) { + log_notice("device is not in USER mode; stay in %s", usb_mode); + goto EXIT; + } + + log_debug("attempt to leave %s", usb_mode); + set_usb_connected_state(); + +EXIT: + return; +} /** set the chosen usb state * diff --git a/src/usb_moded.h b/src/usb_moded.h index ed7be40..2abc46a 100644 --- a/src/usb_moded.h +++ b/src/usb_moded.h @@ -61,6 +61,7 @@ typedef struct usb_mode void set_usb_connected(gboolean connected); void set_usb_connected_state(void); void set_usb_mode(const char *mode); +void rethink_usb_charging_fallback(void); const char * get_usb_mode(void); void set_usb_module(const char *module); const char * get_usb_module(void);