diff --git a/debian/usb_moded.conf b/debian/usb_moded.conf
index 4e84892..714e50b 100644
--- a/debian/usb_moded.conf
+++ b/debian/usb_moded.conf
@@ -25,6 +25,10 @@
send_interface="com.meego.usb_moded" send_member="get_net_config"/>
+
+
diff --git a/src/com.meego.usb_moded.xml b/src/com.meego.usb_moded.xml
index 2d66797..9f94112 100644
--- a/src/com.meego.usb_moded.xml
+++ b/src/com.meego.usb_moded.xml
@@ -30,6 +30,9 @@
+
+
+
@@ -41,6 +44,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -51,6 +64,9 @@
+
+
+
@@ -59,5 +75,8 @@
+
+
+
diff --git a/src/usb_moded-config-private.h b/src/usb_moded-config-private.h
index bf217bd..362104d 100644
--- a/src/usb_moded-config-private.h
+++ b/src/usb_moded-config-private.h
@@ -30,3 +30,7 @@ set_config_result_t set_hide_mode_setting(const char *mode);
set_config_result_t set_unhide_mode_setting(const char *mode);
char * get_hidden_modes(void);
set_config_result_t set_network_setting(const char *config, const char *setting);
+char * get_mode_whitelist(void);
+set_config_result_t set_mode_whitelist(const char *whitelist);
+set_config_result_t set_mode_in_whitelist(const char *mode, int allowed);
+
diff --git a/src/usb_moded-config.c b/src/usb_moded-config.c
index 423cf0a..bc5d301 100644
--- a/src/usb_moded-config.c
+++ b/src/usb_moded-config.c
@@ -41,6 +41,7 @@
#include "usb_moded-config-private.h"
#include "usb_moded-log.h"
#include "usb_moded-modes.h"
+#include "usb_moded-modesetting.h"
#ifdef USE_MER_SSU
# include "usb_moded-ssu.h"
@@ -403,75 +404,77 @@ set_config_result_t set_config_setting(const char *entry, const char *key, const
set_config_result_t set_mode_setting(const char *mode)
{
+ if (strcmp(mode, MODE_ASK) && valid_mode(mode))
+ return SET_CONFIG_ERROR;
return (set_config_setting(MODE_SETTING_ENTRY, MODE_SETTING_KEY, mode));
}
/* Builds the string used for hidden modes, when hide set to one builds the
new string of hidden modes when adding one, otherwise it will remove one */
-static char * make_hidden_modes_string(const char *mode_name, int hide)
+static char * make_modes_string(const char *key, const char *mode_name, int include)
{
- char *hidden_new = 0;
- char *hidden_old = 0;
- gchar **hidden_arr = 0;
- GString *hidden_tmp = 0;
+ char *modes_new = 0;
+ char *modes_old = 0;
+ gchar **modes_arr = 0;
+ GString *modes_tmp = 0;
int i;
/* Get current comma separated list of hidden modes */
- hidden_old = get_hidden_modes();
- if(!hidden_old)
+ modes_old = get_conf_string(MODE_SETTING_ENTRY, key);
+ if(!modes_old)
{
- hidden_old = g_strdup("");
+ modes_old = g_strdup("");
}
- hidden_arr = g_strsplit(hidden_old, ",", 0);
+ modes_arr = g_strsplit(modes_old, ",", 0);
- hidden_tmp = g_string_new(NULL);
+ modes_tmp = g_string_new(NULL);
- for(i = 0; hidden_arr[i] != NULL; i++)
+ for(i = 0; modes_arr[i] != NULL; i++)
{
- if(strlen(hidden_arr[i]) == 0)
+ if(strlen(modes_arr[i]) == 0)
{
/* Skip any empty strings */
continue;
}
- if(!strcmp(hidden_arr[i], mode_name))
+ if(!strcmp(modes_arr[i], mode_name))
{
/* When unhiding, just skip all matching entries */
- if(!hide)
+ if(!include)
continue;
/* When hiding, keep the 1st match and ignore the rest */
- hide = 0;
+ include = 0;
}
- if(hidden_tmp->len > 0)
- hidden_tmp = g_string_append(hidden_tmp, ",");
- hidden_tmp = g_string_append(hidden_tmp, hidden_arr[i]);
+ if(modes_tmp->len > 0)
+ modes_tmp = g_string_append(modes_tmp, ",");
+ modes_tmp = g_string_append(modes_tmp, modes_arr[i]);
}
- if(hide)
+ if(include)
{
/* Adding a hidden mode and no matching entry was found */
- if(hidden_tmp->len > 0)
- hidden_tmp = g_string_append(hidden_tmp, ",");
- hidden_tmp = g_string_append(hidden_tmp, mode_name);
+ if(modes_tmp->len > 0)
+ modes_tmp = g_string_append(modes_tmp, ",");
+ modes_tmp = g_string_append(modes_tmp, mode_name);
}
- hidden_new = g_string_free(hidden_tmp, FALSE), hidden_tmp = 0;
+ modes_new = g_string_free(modes_tmp, FALSE), modes_tmp = 0;
- g_strfreev(hidden_arr), hidden_arr = 0;
+ g_strfreev(modes_arr), modes_arr = 0;
- g_free(hidden_old), hidden_old = 0;
+ g_free(modes_old), modes_old = 0;
- return hidden_new;
+ return modes_new;
}
set_config_result_t set_hide_mode_setting(const char *mode)
{
set_config_result_t ret = SET_CONFIG_UNCHANGED;
- char *hidden_modes = make_hidden_modes_string(mode, 1);
+ char *hidden_modes = make_modes_string(MODE_HIDE_KEY, mode, 1);
if( hidden_modes ) {
ret = set_config_setting(MODE_SETTING_ENTRY, MODE_HIDE_KEY, hidden_modes);
@@ -480,6 +483,7 @@ set_config_result_t set_hide_mode_setting(const char *mode)
if(ret == SET_CONFIG_UPDATED) {
send_hidden_modes_signal();
send_supported_modes_signal();
+ send_available_modes_signal();
}
g_free(hidden_modes);
@@ -491,7 +495,7 @@ set_config_result_t set_unhide_mode_setting(const char *mode)
{
set_config_result_t ret = SET_CONFIG_UNCHANGED;
- char *hidden_modes = make_hidden_modes_string(mode, 0);
+ char *hidden_modes = make_modes_string(MODE_HIDE_KEY, mode, 0);
if( hidden_modes ) {
ret = set_config_setting(MODE_SETTING_ENTRY, MODE_HIDE_KEY, hidden_modes);
@@ -500,6 +504,7 @@ set_config_result_t set_unhide_mode_setting(const char *mode)
if(ret == SET_CONFIG_UPDATED) {
send_hidden_modes_signal();
send_supported_modes_signal();
+ send_available_modes_signal();
}
g_free(hidden_modes);
@@ -507,6 +512,47 @@ set_config_result_t set_unhide_mode_setting(const char *mode)
return(ret);
}
+set_config_result_t set_mode_whitelist(const char *whitelist)
+{
+ set_config_result_t ret = set_config_setting(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY, whitelist);
+
+ if(ret == SET_CONFIG_UPDATED) {
+ char *mode_setting;
+ const char *current_mode;
+
+ mode_setting = get_mode_setting();
+ if (strcmp(mode_setting, MODE_ASK) && valid_mode(mode_setting))
+ set_mode_setting(MODE_ASK);
+ g_free(mode_setting);
+
+ current_mode = get_usb_mode();
+ if (strcmp(current_mode, MODE_CHARGING_FALLBACK) && strcmp(current_mode, MODE_ASK) && valid_mode(current_mode)) {
+ usb_moded_mode_cleanup(get_usb_module());
+ set_usb_mode(MODE_CHARGING_FALLBACK);
+ }
+
+ usb_moded_send_whitelisted_modes_signal(whitelist);
+ send_available_modes_signal();
+ }
+
+ return ret;
+}
+
+set_config_result_t set_mode_in_whitelist(const char *mode, int allowed)
+{
+ set_config_result_t ret = SET_CONFIG_UNCHANGED;
+
+ char *whitelist = make_modes_string(MODE_WHITELIST_KEY, mode, allowed);
+
+ if (whitelist) {
+ ret = set_mode_whitelist(whitelist);
+ }
+
+ g_free(whitelist);
+
+ return(ret);
+}
+
/*
* @param config : the key to be set
* @param setting : The value to be set
@@ -808,6 +854,10 @@ char * get_hidden_modes(void)
{
return(get_conf_string(MODE_SETTING_ENTRY, MODE_HIDE_KEY));
}
+char * get_mode_whitelist(void)
+{
+ return(get_conf_string(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY));
+}
int check_android_section(void)
{
diff --git a/src/usb_moded-config.h b/src/usb_moded-config.h
index b23e3c7..9f71325 100644
--- a/src/usb_moded-config.h
+++ b/src/usb_moded-config.h
@@ -58,6 +58,7 @@
#define ANDROID_PRODUCT_KEY "iProduct"
#define ANDROID_PRODUCT_ID_KEY "idProduct"
#define MODE_HIDE_KEY "hide"
+#define MODE_WHITELIST_KEY "whitelist"
char * find_mounts(void);
int find_sync(void);
@@ -80,6 +81,7 @@ char * get_android_product(void);
char * get_android_product_id(void);
char * get_hidden_modes(void);
+char * get_mode_whitelist(void);
int check_android_section(void);
diff --git a/src/usb_moded-dbus-private.h b/src/usb_moded-dbus-private.h
index ee44dd2..6c23677 100644
--- a/src/usb_moded-dbus-private.h
+++ b/src/usb_moded-dbus-private.h
@@ -50,9 +50,15 @@ int usb_moded_send_error_signal(const char *error);
/* send supported modes signal system bus */
int usb_moded_send_supported_modes_signal(const char *supported_modes);
+/* send available modes signal system bus */
+int usb_moded_send_available_modes_signal(const char *available_modes);
+
/* send hidden modes signal system bus */
int usb_moded_send_hidden_modes_signal(const char *hidden_modes);
+/* send whitelisted modes signal system bus */
+int usb_moded_send_whitelisted_modes_signal(const char *hidden_modes);
+
/* Callback function type used with usb_moded_get_name_owner_async() */
typedef void (*usb_moded_get_name_owner_fn)(const char *owner);
diff --git a/src/usb_moded-dbus.c b/src/usb_moded-dbus.c
index 8d5c5a3..56b48a6 100644
--- a/src/usb_moded-dbus.c
+++ b/src/usb_moded-dbus.c
@@ -137,6 +137,19 @@ static const char introspect_usb_moded[] =
" \n"
" \n"
" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" "
+" "
+" "
+" "
+" "
+" "
+" "
" \n"
" \n"
" \n"
@@ -147,6 +160,12 @@ static const char introspect_usb_moded[] =
" \n"
" \n"
" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
+" \n"
" \n"
" \n"
" \n"
@@ -368,18 +387,85 @@ static DBusHandlerResult msg_handler(DBusConnection *const connection, DBusMessa
}
else if(!strcmp(member, USB_MODE_LIST))
{
- gchar *mode_list = get_mode_list();
+ gchar *mode_list = get_mode_list(SUPPORTED_MODES_LIST);
if((reply = dbus_message_new_method_return(msg)))
dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
g_free(mode_list);
}
+ else if(!strcmp(member, USB_MODE_AVAILABLE_MODES_GET))
+ {
+ gchar *mode_list = get_mode_list(AVAILABLE_MODES_LIST);
+
+ if((reply = dbus_message_new_method_return(msg)))
+ dbus_message_append_args (reply, DBUS_TYPE_STRING, (const char *) &mode_list, DBUS_TYPE_INVALID);
+ g_free(mode_list);
+ }
else if(!strcmp(member, USB_MODE_RESCUE_OFF))
{
rescue_mode = FALSE;
log_debug("Rescue mode off\n ");
reply = dbus_message_new_method_return(msg);
}
+ else if(!strcmp(member, USB_MODE_WHITELISTED_MODES_GET))
+ {
+ gchar *mode_list = get_mode_whitelist();
+
+ if(!mode_list)
+ mode_list = g_strdup("");
+
+ if((reply = dbus_message_new_method_return(msg)))
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &mode_list, DBUS_TYPE_INVALID);
+ g_free(mode_list);
+ }
+ else if(!strcmp(member, USB_MODE_WHITELISTED_MODES_SET))
+ {
+ const char *whitelist = 0;
+ DBusError err = DBUS_ERROR_INIT;
+
+ if (!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &whitelist, DBUS_TYPE_INVALID))
+ reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
+ else
+ {
+ int ret = set_mode_whitelist(whitelist);
+ if (ret == SET_CONFIG_UPDATED)
+ usb_moded_send_config_signal(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY, whitelist);
+ if (SET_CONFIG_OK(ret))
+ {
+ if ((reply = dbus_message_new_method_return(msg)))
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &whitelist, DBUS_TYPE_INVALID);
+ }
+ else
+ reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, whitelist);
+ }
+ dbus_error_free(&err);
+ }
+ else if (!strcmp(member, USB_MODE_WHITELISTED_SET))
+ {
+ const char *mode = 0;
+ dbus_bool_t enabled = FALSE;
+ DBusError err = DBUS_ERROR_INIT;
+
+ if (!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &mode, DBUS_TYPE_BOOLEAN, &enabled, DBUS_TYPE_INVALID))
+ reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
+ else
+ {
+ int ret = set_mode_in_whitelist(mode, enabled);
+ if (ret == SET_CONFIG_UPDATED)
+ {
+ char *whitelist = get_mode_whitelist();
+ if (!whitelist)
+ whitelist = g_strdup(MODE_UNDEFINED);
+ usb_moded_send_config_signal(MODE_SETTING_ENTRY, MODE_WHITELIST_KEY, whitelist);
+ g_free(whitelist);
+ }
+ if (SET_CONFIG_OK(ret))
+ reply = dbus_message_new_method_return(msg);
+ else
+ reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, mode);
+ }
+ dbus_error_free(&err);
+ }
else
{
/*unknown methods are handled here */
@@ -681,6 +767,18 @@ int usb_moded_send_supported_modes_signal(const char *supported_modes)
return(usb_moded_dbus_signal(USB_MODE_SUPPORTED_MODES_SIGNAL_NAME, supported_modes));
}
+/**
+ * Send regular usb_moded mode list signal
+ *
+ * @return 0 on success, 1 on failure
+ * @param available_modes list of available modes
+ *
+*/
+int usb_moded_send_available_modes_signal(const char *available_modes)
+{
+ return(usb_moded_dbus_signal(USB_MODE_AVAILABLE_MODES_SIGNAL_NAME, available_modes));
+}
+
/**
* Send regular usb_moded hidden mode list signal
*
@@ -693,6 +791,17 @@ int usb_moded_send_hidden_modes_signal(const char *hidden_modes)
return(usb_moded_dbus_signal(USB_MODE_HIDDEN_MODES_SIGNAL_NAME, hidden_modes));
}
+/**
+ * Send regular usb_moded whitelisted mode list signal
+ *
+ * @return 0 on success, 1 on failure
+ * @param whitelist list of allowed modes
+ */
+int usb_moded_send_whitelisted_modes_signal(const char *whitelist)
+{
+ return(usb_moded_dbus_signal(USB_MODE_WHITELISTED_MODES_SIGNAL_NAME, whitelist));
+}
+
/** Async reply handler for usb_moded_get_name_owner_async()
*
* @param pc Pending call object pointer
diff --git a/src/usb_moded-dbus.h b/src/usb_moded-dbus.h
index 7046258..6d7c427 100644
--- a/src/usb_moded-dbus.h
+++ b/src/usb_moded-dbus.h
@@ -38,6 +38,8 @@
#define USB_MODE_ERROR_SIGNAL_NAME "sig_usb_state_error_ind"
#define USB_MODE_SUPPORTED_MODES_SIGNAL_NAME "sig_usb_supported_modes_ind"
#define USB_MODE_HIDDEN_MODES_SIGNAL_NAME "sig_usb_hidden_modes_ind"
+#define USB_MODE_WHITELISTED_MODES_SIGNAL_NAME "sig_usb_whitelisted_modes_ind"
+#define USB_MODE_AVAILABLE_MODES_SIGNAL_NAME "sig_usb_available_modes_ind"
/* supported methods */
#define USB_MODE_STATE_REQUEST "mode_request" /* returns the current mode */
@@ -51,6 +53,10 @@
#define USB_MODE_CONFIG_SET "set_config" /* set the mode that needs to be activated in the config file */
#define USB_MODE_NETWORK_SET "net_config" /* set the network config in the config file */
#define USB_MODE_NETWORK_GET "get_net_config" /* get the network config from the config file */
+#define USB_MODE_WHITELISTED_MODES_GET "get_whitelisted_modes" /* get the list of whitelisted modes */
+#define USB_MODE_WHITELISTED_MODES_SET "set_whitelisted_modes" /* set the list of whitelisted modes */
+#define USB_MODE_WHITELISTED_SET "set_whitelisted" /* sets whether an specific mode is in the whitelist */
+#define USB_MODE_AVAILABLE_MODES_GET "get_available_modes" /* returns a comma separated list of modes which are currently available for selection */
/**
* (Transient) states reported by "sig_usb_state_ind" that are not modes.
diff --git a/src/usb_moded-modes.h b/src/usb_moded-modes.h
index b39893a..77a4330 100644
--- a/src/usb_moded-modes.h
+++ b/src/usb_moded-modes.h
@@ -46,4 +46,6 @@
#define MODE_CHARGER "dedicated_charger"
void send_supported_modes_signal(void);
+void send_available_modes_signal(void);
void send_hidden_modes_signal(void);
+void send_whitelisted_modes_signal(void);
diff --git a/src/usb_moded.c b/src/usb_moded.c
index 9a1a31f..22e9172 100644
--- a/src/usb_moded.c
+++ b/src/usb_moded.c
@@ -338,6 +338,19 @@ void set_usb_connected_state(void)
if(!strcmp(mode_to_set, current_mode.mode))
goto end;
+ if (!strcmp(MODE_ASK, mode_to_set))
+ {
+ /*! If charging mode is the only available selection, don't ask
+ just select it */
+ gchar *available_modes = get_mode_list(AVAILABLE_MODES_LIST);
+ if (!strcmp(MODE_CHARGING, available_modes)) {
+ gchar *temp = mode_to_set;
+ mode_to_set = available_modes;
+ available_modes = temp;
+ }
+ g_free(available_modes);
+ }
+
if(!strcmp(MODE_ASK, mode_to_set))
{
/* send signal, mode will be set when the dialog service calls
@@ -479,6 +492,22 @@ void set_usb_mode(const char *mode)
usb_moded_send_signal(get_usb_mode());
}
+/* check if a mode is in a list */
+static bool mode_in_list(const char *mode, char * const *modes)
+{
+ int i;
+
+ if (!modes)
+ return false;
+
+ for(i = 0; modes[i] != NULL; i++)
+ {
+ if(!strcmp(modes[i], mode))
+ return true;
+ }
+ return false;
+}
+
/** check if a given usb_mode exists
*
* @param mode The mode to look for
@@ -487,13 +516,23 @@ void set_usb_mode(const char *mode)
*/
int valid_mode(const char *mode)
{
-
+ int valid = 1;
/* MODE_ASK, MODE_CHARGER and MODE_CHARGING_FALLBACK are not modes that are settable seen their special 'internal' status
so we only check the modes that are announed outside. Only exception is the built in MODE_CHARGING */
if(!strcmp(MODE_CHARGING, mode))
- return(0);
+ valid = 0;
else
{
+ char *whitelist;
+ gchar **whitelist_split = NULL;
+
+ whitelist = get_mode_whitelist();
+ if (whitelist)
+ {
+ whitelist_split = g_strsplit(whitelist, ",", 0);
+ g_free(whitelist);
+ }
+
/* check dynamic modes */
if(modelist)
{
@@ -502,34 +541,30 @@ int valid_mode(const char *mode)
for( iter = modelist; iter; iter = g_list_next(iter) )
{
struct mode_list_elem *data = iter->data;
- if(!strcmp(mode, data->mode_name))
- return(0);
+ if(!strcmp(mode, data->mode_name))
+ {
+ if (!whitelist_split || mode_in_list(data->mode_name, whitelist_split))
+ valid = 0;
+ break;
+ }
}
+
+ g_strfreev(whitelist_split);
}
}
- return(1);
+ return valid;
}
/** make a list of all available usb modes
*
+ * @param type The type of list to return. Supported or available.
* @return a comma-separated list of modes (MODE_ASK not included as it is not a real mode)
*
*/
-gchar *get_mode_list(void)
+gchar *get_mode_list(mode_list_type_t type)
{
-
GString *modelist_str;
- char *hidden_modes_list;
- gchar **hidden_mode_split = NULL;
- int hiddenmode = 0, i;
-
-
- hidden_modes_list = get_hidden_modes();
- if(hidden_modes_list)
- {
- hidden_mode_split = g_strsplit(hidden_modes_list, ",", 0);
- }
modelist_str = g_string_new(NULL);
@@ -539,29 +574,45 @@ gchar *get_mode_list(void)
if(modelist)
{
GList *iter;
+ char *hidden_modes_list, *whitelist;
+ gchar **hidden_mode_split = NULL, **whitelist_split = NULL;
+
+ hidden_modes_list = get_hidden_modes();
+ if(hidden_modes_list)
+ {
+ hidden_mode_split = g_strsplit(hidden_modes_list, ",", 0);
+ g_free(hidden_modes_list);
+ }
+
+ if (type == AVAILABLE_MODES_LIST)
+ {
+ whitelist = get_mode_whitelist();
+ if (whitelist)
+ {
+ whitelist_split = g_strsplit(whitelist, ",", 0);
+ g_free(whitelist);
+ }
+ }
for( iter = modelist; iter; iter = g_list_next(iter) )
{
struct mode_list_elem *data = iter->data;
- if(hidden_modes_list && hidden_mode_split)
- for(i = 0; hidden_mode_split[i] != NULL; i++)
- {
- if(!strcmp(hidden_mode_split[i], data->mode_name))
- hiddenmode = 1;
- }
-
- if(hiddenmode)
- {
- hiddenmode = 0;
- continue;
- }
+
+ /* skip items in the hidden list */
+ if (mode_in_list(data->mode_name, hidden_mode_split))
+ continue;
+
+ /* if there is a whitelist skip items not in the list */
+ if (whitelist_split && !mode_in_list(data->mode_name, whitelist_split))
+ continue;
+
modelist_str = g_string_append(modelist_str, data->mode_name);
modelist_str = g_string_append(modelist_str, ", ");
}
- }
- if(hidden_mode_split)
- g_strfreev(hidden_mode_split);
+ g_strfreev(hidden_mode_split);
+ g_strfreev(whitelist_split);
+ }
/* end with charging mode */
g_string_append(modelist_str, MODE_CHARGING);
@@ -763,6 +814,7 @@ static void sigint_handler(int signum)
modelist = read_mode_list(diag_mode);
send_supported_modes_signal();
+ send_available_modes_signal();
}
else
{
@@ -797,11 +849,18 @@ static void usage(void)
void send_supported_modes_signal(void)
{
/* Send supported modes signal */
- gchar *mode_list = get_mode_list();
+ gchar *mode_list = get_mode_list(SUPPORTED_MODES_LIST);
usb_moded_send_supported_modes_signal(mode_list);
g_free(mode_list);
}
+void send_available_modes_signal(void)
+{
+ gchar *mode_list = get_mode_list(AVAILABLE_MODES_LIST);
+ usb_moded_send_available_modes_signal(mode_list);
+ g_free(mode_list);
+}
+
void send_hidden_modes_signal(void)
{
/* Send hidden modes signal */
@@ -812,6 +871,15 @@ void send_hidden_modes_signal(void)
}
}
+void send_whitelisted_modes_signal(void)
+{
+ gchar *mode_list = get_mode_whitelist();
+ if(mode_list) {
+ usb_moded_send_whitelisted_modes_signal(mode_list);
+ g_free(mode_list);
+ }
+}
+
/** Pipe fd for transferring signals to mainloop context */
static int sigpipe_fd = -1;
@@ -1384,7 +1452,9 @@ int main(int argc, char* argv[])
/* Broadcast supported / hidden modes */
// TODO: should this happen before hwal_init()?
send_supported_modes_signal();
+ send_available_modes_signal();
send_hidden_modes_signal();
+ send_whitelisted_modes_signal();
/* Act on '--fallback' commandline option */
if(hw_fallback)
diff --git a/src/usb_moded.h b/src/usb_moded.h
index 7088ff7..e4912b7 100644
--- a/src/usb_moded.h
+++ b/src/usb_moded.h
@@ -58,6 +58,11 @@ typedef struct usb_mode
/*@}*/
}usb_mode;
+typedef enum mode_list_type_t {
+ SUPPORTED_MODES_LIST,
+ AVAILABLE_MODES_LIST
+} mode_list_type_t;
+
void set_usb_connected(gboolean connected);
void set_usb_connected_state(void);
void set_usb_mode(const char *mode);
@@ -70,7 +75,8 @@ struct mode_list_elem * get_usb_mode_data(void);
gboolean get_usb_connection_state(void);
void set_usb_connection_state(gboolean state);
void set_charger_connected(gboolean state);
-gchar *get_mode_list(void);
+gchar *get_mode_list(mode_list_type_t type);
+gchar *get_available_mode_list(void);
int valid_mode(const char *mode);
/** Name of the wakelock usb_moded uses for temporary suspend delay */