Skip to content

Commit

Permalink
Merge branch 'jb35683_mode_change' into 'master'
Browse files Browse the repository at this point in the history
Mode change and cable detection fixes

Also contains fixes for various issues spotted while debugging.

See merge request !12
  • Loading branch information
spiiroin committed Jul 7, 2016
2 parents ed512dc + 931f01a commit 899ce52
Show file tree
Hide file tree
Showing 13 changed files with 336 additions and 160 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Expand Up @@ -22,7 +22,7 @@ test_gcc_flag() {

# We use gnu99 instead of c99 because many have interpreted the standard
# in a way that int64_t isn't defined on non-64 bit platforms.
CFLAGS="-Os -std=gnu99 -Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter -finline-small-functions -Wno-unused-result -fstack-protector -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now -fPIE -fpie -pie"
CFLAGS="-Os -std=gnu99 -Wall -W -Wextra -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter -finline-small-functions -Wno-unused-result -fstack-protector -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now -fPIE -fpie -pie"

AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug],[Enable debug @<:@default=false@:>@]),
[case "${enableval}" in
Expand Down
4 changes: 4 additions & 0 deletions src/usb_moded-android.c
Expand Up @@ -81,6 +81,10 @@ void android_init_values(void)
}
/* For rndis to be discovered correctly in M$ Windows (vista and later) */
write_to_file("/sys/class/android_usb/f_rndis/wceis", "1");

/* Make sure android_usb does not stay disabled in case usb moded
* has crashed / been killed in inconvenient time. */
write_to_file("/sys/class/android_usb/android0/enable", "1");
}

/* Set a charging mode for the android gadget
Expand Down
150 changes: 99 additions & 51 deletions src/usb_moded-appsync.c
Expand Up @@ -41,12 +41,14 @@
#include "usb_moded-systemd.h"

static struct list_elem *read_file(const gchar *filename, int diag);
static gboolean enumerate_usb(gpointer data);
static void enumerate_usb(void);
static gboolean enumerate_usb_cb(gpointer data);
static void start_enumerate_usb_timer(void);
static void cancel_enumerate_usb_timer(void);

static GList *sync_list = NULL;

static unsigned sync_tag = 0;
static unsigned enum_tag = 0;
static guint enumerate_usb_id = 0;
static struct timeval sync_tv;
#ifdef APP_SYNC_DBUS
static int no_dbus = 0;
Expand All @@ -55,21 +57,26 @@ static int no_dbus = 0;
#endif /* APP_SYNC_DBUS */


static void free_elem(gpointer aptr)
static void free_elem(struct list_elem *elem)
{
struct list_elem *elem = aptr;
free(elem->name);
free(elem->launch);
free(elem->mode);
g_free(elem->name);
g_free(elem->launch);
g_free(elem->mode);
free(elem);
}

static void free_elem_cb(gpointer elem, gpointer user_data)
{
(void)user_data;
free_elem(elem);
}

void free_appsync_list(void)
{
if( sync_list != 0 )
{
/*g_list_free_full(sync_list, free_elem); */
g_list_foreach (sync_list, (GFunc) free_elem, NULL);
g_list_foreach (sync_list, free_elem_cb, NULL);
g_list_free (sync_list);
sync_list = 0;
log_debug("Appsync list freed\n");
Expand Down Expand Up @@ -163,6 +170,7 @@ static struct list_elem *read_file(const gchar *filename, int diag)
list_item->systemd = g_key_file_get_integer(settingsfile, APP_INFO_ENTRY, APP_INFO_SYSTEMD_KEY, NULL);
log_debug("Systemd control = %d\n", list_item->systemd);
list_item->post = g_key_file_get_integer(settingsfile, APP_INFO_ENTRY, APP_INFO_POST, NULL);
list_item->state = APP_STATE_DONTCARE;

cleanup:

Expand All @@ -185,41 +193,42 @@ static struct list_elem *read_file(const gchar *filename, int diag)
int activate_sync(const char *mode)
{
GList *iter;
int count = 0, count2 = 0;
int count = 0;

log_debug("activate sync");

/* Bump tag, see enumerate_usb() */
++sync_tag; gettimeofday(&sync_tv, 0);
/* Get start of activation timestamp */
gettimeofday(&sync_tv, 0);

if( sync_list == 0 )
{
log_debug("No sync list! Enumerating\n");
enumerate_usb(NULL);
enumerate_usb();
return 0;
}

/* set list to inactive, mark other modes as active already */
/* Count apps that need to be activated for this mode and
* mark them as currently inactive */
for( iter = sync_list; iter; iter = g_list_next(iter) )
{
struct list_elem *data = iter->data;

count++;
if(!strcmp(data->mode, mode))
data->active = 0;
{
++count;
data->state = APP_STATE_INACTIVE;
}
else
{
count2++;
data->active = 1;
data->state = APP_STATE_DONTCARE;
}
}

/* if the number of active modes is equal to the number of existing modes
we enumerate immediately */
if(count == count2)
/* If there is nothing to activate, enumerate immediately */
if(count <= 0)
{
log_debug("Nothing to launch.\n");
enumerate_usb(NULL);
enumerate_usb();
return(0);
}

Expand All @@ -233,8 +242,7 @@ int activate_sync(const char *mode)
#endif /* APP_SYNC_DBUS */

/* start timer */
log_debug("Starting appsync timer\n");
g_timeout_add_seconds(2, enumerate_usb, NULL);
start_enumerate_usb_timer();

/* go through list and launch apps */
for( iter = sync_list; iter; iter = g_list_next(iter) )
Expand All @@ -245,10 +253,9 @@ int activate_sync(const char *mode)
/* do not launch items marked as post, will be launched after usb is up */
if(data->post)
{
mark_active(data->name, data->post);
continue;
}
log_debug("launching app %s\n", data->name);
log_debug("launching pre-enum-app %s\n", data->name);
if(data->systemd)
{
if(!systemd_control_service(data->name, SYSTEMD_START))
Expand Down Expand Up @@ -310,11 +317,12 @@ int activate_sync_post(const char *mode)
/* launch only items marked as post, others are already running */
if(!data->post)
continue;
log_debug("launching app %s\n", data->name);
log_debug("launching post-enum-app %s\n", data->name);
if(data->systemd)
{
if(systemd_control_service(data->name, SYSTEMD_START))
goto error;
mark_active(data->name, 1);
}
else if(data->launch)
{
Expand Down Expand Up @@ -345,56 +353,72 @@ int mark_active(const gchar *name, int post)

GList *iter;

if(post)
log_debug("App %s notified it is ready\n", name);
log_debug("%s-enum-app %s is started\n", post ? "post" : "pre", name);

for( iter = sync_list; iter; iter = g_list_next(iter) )
{
struct list_elem *data = iter->data;

if(!strcmp(data->name, name))
{
/* TODO: do we need to worry about duplicate names in the list? */
ret = !data->active;
data->active = 1;
ret = (data->state != APP_STATE_ACTIVE);
data->state = APP_STATE_ACTIVE;

/* updated + missing -> not going to enumerate */
if( missing ) break;
}
else if( data->active == 0 )
else if( data->state == APP_STATE_INACTIVE && data->post == post )
{
missing = 1;

/* updated + missing -> not going to enumerate */
if( ret != -1 ) break;
}
}
if( !missing )
if( !post && !missing )
{
log_debug("All apps active. Let's enumerate\n");
enumerate_usb(NULL);
log_debug("All pre-enum-apps active. Let's enumerate\n");
enumerate_usb();
}

/* -1=not found, 0=already active, 1=activated now */
return ret;
}

static gboolean enumerate_usb(gpointer data)
static gboolean enumerate_usb_cb(gpointer data)
{
struct timeval tv;
(void)data;
enumerate_usb_id = 0;
log_debug("handling enumeration timeout");
enumerate_usb();
/* return false to stop the timer from repeating */
return FALSE;
}

/* We arrive here twice: when app sync is done
* and when the app sync timeout gets triggered.
* The tags are used to filter out these repeats.
*/
static void start_enumerate_usb_timer(void)
{
log_debug("scheduling enumeration timeout");
if( enumerate_usb_id )
g_source_remove(enumerate_usb_id), enumerate_usb_id = 0;
enumerate_usb_id = g_timeout_add_seconds(2, enumerate_usb_cb, NULL);
}

if( enum_tag == sync_tag )
static void cancel_enumerate_usb_timer(void)
{
if( enumerate_usb_id )
{
log_debug("ignoring enumeration trigger");
log_debug("canceling enumeration timeout");
g_source_remove(enumerate_usb_id), enumerate_usb_id = 0;
}
else
}

static void enumerate_usb(void)
{
struct timeval tv;

enum_tag = sync_tag;
/* Stop the timer in case of explicit enumeration call */
cancel_enumerate_usb_timer();

/* Debug: how long it took from sync start to get here */
gettimeofday(&tv, 0);
Expand All @@ -406,24 +430,48 @@ static gboolean enumerate_usb(gpointer data)
usb_moded_appsync_cleanup();
#endif /* APP_SYNC_DBUS */
}
/* return false to stop the timer from repeating */
return FALSE;
}

int appsync_stop(void)
static void appsync_stop_apps(int post)
{
GList *iter = 0;

for( iter = sync_list; iter; iter = g_list_next(iter) )
{
struct list_elem *data = iter->data;

if(data->systemd)
if(data->systemd && data->state == APP_STATE_ACTIVE && data->post == post)
{
if(!systemd_control_service(data->name, SYSTEMD_STOP))
log_debug("stopping %s-enum-app %s", post ? "post" : "pre", data->name);
if(systemd_control_service(data->name, SYSTEMD_STOP))
log_debug("Failed to stop %s\n", data->name);
data->state = APP_STATE_DONTCARE;
}
}
}

int appsync_stop(int force)
{
/* If force arg is used, stop all applications that
* could have been started by usb-moded */
if(force)
{
GList *iter;
log_debug("assuming all applications are active");

for( iter = sync_list; iter; iter = g_list_next(iter) )
{
struct list_elem *data = iter->data;
data->state = APP_STATE_ACTIVE;
}
}

/* Stop post-apps 1st */
appsync_stop_apps(1);

/* Then pre-apps */
appsync_stop_apps(0);

/* Do not leave active timers behind */
cancel_enumerate_usb_timer();
return(0);
}
13 changes: 11 additions & 2 deletions src/usb_moded-appsync.h
Expand Up @@ -29,6 +29,15 @@
#define APP_INFO_SYSTEMD_KEY "systemd"
#define APP_INFO_POST "post"

typedef enum {
/** Application is not relevant for the current mode */
APP_STATE_DONTCARE = 0,
/** Application should be started */
APP_STATE_INACTIVE = 1,
/** Application should be stopped when exiting the mode */
APP_STATE_ACTIVE = 2,
} app_state_t;

/**
* keep all the needed info together for launching an app
*/
Expand All @@ -38,7 +47,7 @@ typedef struct list_elem
char *name; /* name of the app to launch */
char *mode; /* mode in which to launch the app */
char *launch; /* dbus launch command/address */
int active; /* marker to check if the app has started sucessfully */
app_state_t state; /* marker to check if the app has started sucessfully */
int systemd; /* marker to know if we start it with systemd or not */
int post; /* marker to indicate when to start the app */
/*@}*/
Expand All @@ -48,6 +57,6 @@ void readlist(int diag);
int activate_sync(const char *mode);
int activate_sync_post(const char *mode);
int mark_active(const gchar *name, int post);
int appsync_stop(void);
int appsync_stop(int force);
void free_appsync_list(void);
void usb_moded_appsync_cleanup(void);

0 comments on commit 899ce52

Please sign in to comment.