Fix some lockup caused by handles not being initialized to < 0...

...by default where they would be interpreted as valid but not actually
be which would cause calls to buffering while it was not initialized.

Add BUFFER_EVENT_BUFFER_RESET to inform users of buffering that the
buffer is being reinitialized. Basically, this wraps all the
functionality being provided by three events (...START_PLAYBACK,
RECORDING_EVENT_START, RECORDING_EVENT_STOP) into one for radioart.c,
the only user of those events (perhaps remove them?) and closes some
loopholes.

Change-Id: I99ec46b9b5fb4e36605db5944c60ed986163db3a
diff --git a/apps/appevents.h b/apps/appevents.h
index 5cb0ee5..a11e423 100644
--- a/apps/appevents.h
+++ b/apps/appevents.h
@@ -54,6 +54,7 @@
     BUFFER_EVENT_CLOSED,
     BUFFER_EVENT_MOVED,
     BUFFER_EVENT_FINISHED,
+    BUFFER_EVENT_BUFFER_RESET
 };
 
 /** Generic GUI class events **/
diff --git a/apps/buffering.c b/apps/buffering.c
index c47564b..b5bf427 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -389,7 +389,7 @@
    NULL if the handle wasn't found */
 static struct memory_handle *find_handle(int handle_id)
 {
-    if (handle_id < 0)
+    if (handle_id < 0 || !first_handle)
         return NULL;
 
     /* simple caching because most of the time the requested handle
@@ -1748,12 +1748,22 @@
        thus buf and buflen must be a aligned to an integer multiple of
        the storage alignment */
 
-    buflen -= GUARD_BUFSIZE;
+    if (buf) {
+        buflen -= MIN(buflen, GUARD_BUFSIZE);
+    
+        STORAGE_ALIGN_BUFFER(buf, buflen);
 
-    STORAGE_ALIGN_BUFFER(buf, buflen);
+        if (!buf || !buflen)
+            return false;
+    } else {
+        buflen = 0;
+    }
 
-    if (!buf || !buflen)
-        return false;
+    send_event(BUFFER_EVENT_BUFFER_RESET, NULL);
+
+    /* If handles weren't closed above, just do it */
+    while (num_handles != 0)
+        bufclose(first_handle->id);
 
     buffer = buf;
     buffer_len = buflen;
diff --git a/apps/playback.c b/apps/playback.c
index bd7dd81..21cc017 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -3621,6 +3621,9 @@
     audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
     buf = core_get_data(audiobuf_handle);
 
+    if (buffer_state == AUDIOBUF_STATE_INITIALIZED)
+        buffering_reset(NULL, 0); /* mark buffer invalid */
+
     if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
            || !talk_voice_required())
     {
diff --git a/apps/radio/radioart.c b/apps/radio/radioart.c
index 07fab81..53ed863 100644
--- a/apps/radio/radioart.c
+++ b/apps/radio/radioart.c
@@ -41,10 +41,9 @@
     char name[MAX_FMPRESET_LEN+1];
 };
 
+static char* buf;
 static struct radioart radioart[MAX_RADIOART_IMAGES];
-#ifdef HAVE_RECORDING
-static bool allow_buffer_access = true; /* If we are recording dont touch the buffers! */
-#endif
+
 static int find_oldest_image(void)
 {
     int i;
@@ -101,12 +100,10 @@
     int preset = radio_current_preset();
     int free_idx = -1;
     const char* preset_name;
-    if (radio_scan_mode() || preset < 0)
+
+    if (!buf || radio_scan_mode() || preset < 0)
         return -1;
-#ifdef HAVE_RECORDING
-    if (!allow_buffer_access)
-        return -1;
-#endif
+
     preset_name = radio_get_preset_name(preset);
     for (int i=0; i<MAX_RADIOART_IMAGES; i++)
     {
@@ -137,55 +134,38 @@
         
     return -1;
 }
-static void playback_restarting_handler(void *data)
+
+static void buffer_reset_handler(void *data)
 {
-    (void)data;
-    int i;
-    for(i=0;i<MAX_RADIOART_IMAGES;i++)
+    buf = NULL;
+    for(int i=0;i<MAX_RADIOART_IMAGES;i++)
     {
         if (radioart[i].handle >= 0)
             bufclose(radioart[i].handle);
         radioart[i].handle = -1;
         radioart[i].name[0] = '\0';
     }
-}
-#ifdef HAVE_RECORDING
-static void recording_started_handler(void *data)
-{
+
     (void)data;
-    allow_buffer_access = false;
-    playback_restarting_handler(NULL);
 }
-static void recording_stopped_handler(void *data)
-{
-    (void)data;
-    allow_buffer_access = true;
-}
-#endif
 
 void radioart_init(bool entering_screen)
 {
-    int i;
     if (entering_screen)
     {
-        for(i=0;i<MAX_RADIOART_IMAGES;i++)
+        /* grab control over buffering */
+        size_t bufsize;
+        buf = audio_get_buffer(false, &bufsize);
+        buffering_reset(buf, bufsize);
+        /* one-shot */
+        add_event(BUFFER_EVENT_BUFFER_RESET, true, buffer_reset_handler);
+    }
+    else /* init at startup */
+    {
+        for(int i=0;i<MAX_RADIOART_IMAGES;i++)
         {
             radioart[i].handle = -1;
             radioart[i].name[0] = '\0';
         }
-        add_event(PLAYBACK_EVENT_START_PLAYBACK, true, playback_restarting_handler);
-
-        /* grab control over buffering */
-        char* buf;
-        size_t bufsize;
-        buf = audio_get_buffer(false, &bufsize);
-        buffering_reset(buf, bufsize);
-    }
-    else
-    {
-#if defined(HAVE_RECORDING)
-        add_event(RECORDING_EVENT_START, false, recording_started_handler);
-        add_event(RECORDING_EVENT_STOP, false, recording_stopped_handler);
-#endif
     }
 }