Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[usb-moded] Sanitize default and current mode after settings reload. …
…JB#45312

Removing dynamic mode configuration files can invalidate default mode
setting and/or currently active mode.

If currently selected default mode is no longer available after
configuration file refresh, select "ask" as default mode.

If currently active mode is no longer available after configuration file
refresh, re-evaluate appropriate mode similarly as what is done on cable
connect.

Also document mode names in a bit more detail.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Apr 9, 2019
1 parent 83df308 commit 7f42931
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 20 deletions.
20 changes: 20 additions & 0 deletions src/usb_moded-common.c
Expand Up @@ -59,6 +59,7 @@ FILE *common_popen_ (const char *file, int line, co
waitres_t common_wait (unsigned tot_ms, bool (*ready_cb)(void *aptr), void *aptr);
bool common_msleep_ (const char *file, int line, const char *func, unsigned msec);
static bool common_mode_in_list (const char *mode, char *const *modes);
bool common_modename_is_internal (const char *modename);
int common_valid_mode (const char *mode);
gchar *common_get_mode_list (mode_list_type_t type);

Expand Down Expand Up @@ -443,6 +444,25 @@ static bool common_mode_in_list(const char *mode, char * const *modes)
return false;
}

/** Check if given usb mode is internal
*
* @param modename name of a more
*
* @return true if mode is internal, false otherwise
*/
bool
common_modename_is_internal(const char *modename)
{
LOG_REGISTER_CONTEXT;

return (!g_strcmp0(modename, MODE_UNDEFINED) ||
!g_strcmp0(modename, MODE_CHARGER) ||
!g_strcmp0(modename, MODE_CHARGING_FALLBACK) ||
!g_strcmp0(modename, MODE_ASK) ||
!g_strcmp0(modename, MODE_CHARGING) ||
!g_strcmp0(modename, MODE_BUSY));
}

/** check if a given usb_mode exists
*
* @param mode The mode to look for
Expand Down
1 change: 1 addition & 0 deletions src/usb_moded-common.h
Expand Up @@ -59,6 +59,7 @@ int common_system_ (const char *file, int line, con
FILE *common_popen_ (const char *file, int line, const char *func, const char *command, const char *type);
waitres_t common_wait (unsigned tot_ms, bool (*ready_cb)(void *aptr), void *aptr);
bool common_msleep_ (const char *file, int line, const char *func, unsigned msec);
bool common_modename_is_internal (const char *modename);
int common_valid_mode (const char *mode);
gchar *common_get_mode_list (mode_list_type_t type);

Expand Down
66 changes: 49 additions & 17 deletions src/usb_moded-modes.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 <philippe.de-swert@nokia.com>
* Author: Philippe De Swert <philippedeswert@gmail.com>
Expand Down Expand Up @@ -32,12 +32,57 @@
* Constants
* ========================================================================= */

/* possible values for the mode
* the first two are internal only.
*/
/* ------------------------------------------------------------------------- *
* Internal modes
*
* These modes are defined internally within usb-moded and are thus
* always available.
*
* Generally speaking these are also activated automatically and thus
* not really selectable - except:
* - MODE_ASK which can be set as default mode
* - MODE_CHARGING which can be acticated on request too
* ------------------------------------------------------------------------- */

/** No cable connected */
# define MODE_UNDEFINED "undefined"

/** Pending mode activation
*
* Used for signaling "in between modes" state.
*/
# define MODE_BUSY "busy"

/** Connected to a dedicated charger */
# define MODE_CHARGER "dedicated_charger"

/** Blocked mode selection
*
* While prerequisites for dynamic mode activation are not met e.g.
* device is locked, pc connection is used for charging.
*/
# define MODE_CHARGING_FALLBACK "charging_only_fallback"

/** Pending mode selection
*
* While mode selection dialog is shown to user, pc connection
* is used for charging.
*/
# define MODE_ASK "ask"

/** Charging only selected */
# define MODE_CHARGING "charging_only"

/* ------------------------------------------------------------------------- *
* Dynamic modes
*
* These modes are defined in usb-moded configuration files.
*
* From usb-moded point of view mode names have no special meaning,
* but a set of known values is still defined (and are likely to
* have localized name presentation in UI context).
* ------------------------------------------------------------------------- */

# define MODE_MASS_STORAGE "mass_storage"
# define MODE_DEVELOPER "developer_mode"
# define MODE_MTP "mtp_mode"
Expand All @@ -46,18 +91,5 @@
# define MODE_DIAG "diag_mode"
# define MODE_ADB "adb_mode"
# define MODE_PC_SUITE "pc_suite"
# define MODE_CHARGING "charging_only"
# define MODE_BUSY "busy"

/**
*
* MODE_CHARGING : user manually selected charging mode
* MODE_CHARGING_FALLBACK : mode selection is not done by the user so we fallback to a charging mode to get some power
* MODE_CHARGER : there is a dedicated charger connected to the USB port
*
* the two last ones cannot be set and are not full modes
**/
# define MODE_CHARGING_FALLBACK "charging_only_fallback"
# define MODE_CHARGER "dedicated_charger"

#endif /* USB_MODED_MODES_H_ */
50 changes: 47 additions & 3 deletions src/usb_moded.c
Expand Up @@ -53,6 +53,7 @@
#include "usb_moded-trigger.h"
#include "usb_moded-udev.h"
#include "usb_moded-worker.h"
#include "usb_moded-modes.h"

#ifdef MEEGOLOCK
# include "usb_moded-dsme.h"
Expand Down Expand Up @@ -491,14 +492,57 @@ void usbmoded_handle_signal(int signum)
}
else if( signum == SIGHUP )
{
/* free and read in modelist again */
/* Reload mode list */
log_debug("reloading dynamic mode configuration");
usbmoded_free_modelist();
usbmoded_load_modelist();

/* If default mode selection became invalid,
* revert setting to "ask" */
gchar *config = config_get_mode_setting();
if( g_strcmp0(config, MODE_ASK) &&
common_valid_mode(config) ) {
log_warning("default mode '%s' is not valid, reset to '%s'",
config, MODE_ASK);
config_set_mode_setting(MODE_ASK);
}
else {
log_debug("default mode '%s' is still valid", config);
}
g_free(config);

/* If current mode became invalid, select appropriate mode.
*
* Use target mode so that we catch also situations where
* we are making transition to invalid state.
*/
const char *current = control_get_target_mode();
if( common_modename_is_internal(current) ) {
/* Internal modes are not affected by configuration
* file changes - no changes required. */
log_debug("current mode '%s' is internal", current);
}
else if( common_valid_mode(current) ) {
/* Dynamic mode that is no longer valid - choose
* something else. */
log_warning("current mode '%s' is not valid, re-evaluating",
current);
control_select_usb_mode();
}
else {
/* Dynamic mode that is still valid - do nothing.
*
* Note: While the mode details /might/ have changed,
* skipping immediate usb reprogramming is assumed to
* be less harmful than potentially cutting developer
* mode connection during upgrade, etc. */
log_debug("current mode '%s' is still valid", current);
}

/* Signal availability */
log_debug("broadcast mode availability lists");
common_send_supported_modes_signal();
common_send_available_modes_signal();

// FIXME invalidate current mode
}
else
{
Expand Down

0 comments on commit 7f42931

Please sign in to comment.