summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-05-22 15:10:58 +0100
committerWilliam Wilgus <me.theuser@yahoo.com>2022-05-28 06:23:08 -0400
commit7345666d9ce52234236cc144062bdc75d3bcf23c (patch)
tree15a45dc1785e8f1e5288e27cf7920c3dbd0c1e33
parent85232fadbb1fa02f6abeee7bf28ac6e286c45a24 (diff)
downloadrockbox-7345666d9ce52234236cc144062bdc75d3bcf23c.tar.gz
rockbox-7345666d9ce52234236cc144062bdc75d3bcf23c.zip
plugins: use menu for lastfm scrobbler TSR exit callback
Use standard menus and yes/no screen for the TSR exit callback, similar to the recently added test_usb plugin. This removes the need to define key bindings and it provides a more consistent user experience. It also allows the "flush cache" message to be popped up in the main thread - doing it from the worker thread is unreliable and the message often disappeared because the main thread did a UI update immediately after leaving the plugin. One issue is that quitting the plugin by selecting the scrobbler plugin itself immediately restarts the scrobbler. This is because there is currently no way for TSR plugins to terminate themselves either through the exit_tsr callback or otherwise. Change-Id: I9690239d5bd58ad2fbb36fd15a10683757aff0ff
-rw-r--r--apps/plugins/lastfm_scrobbler.c195
1 files changed, 39 insertions, 156 deletions
diff --git a/apps/plugins/lastfm_scrobbler.c b/apps/plugins/lastfm_scrobbler.c
index 7bd213b6d2..5e9e903a82 100644
--- a/apps/plugins/lastfm_scrobbler.c
+++ b/apps/plugins/lastfm_scrobbler.c
@@ -39,7 +39,7 @@ http://www.audioscrobbler.net/wiki/Portable_Player_Logging
39 39
40/****************** constants ******************/ 40/****************** constants ******************/
41#define EV_EXIT MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0xFF) 41#define EV_EXIT MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0xFF)
42#define EV_OTHINSTANCE MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0xFE) 42#define EV_FLUSHCACHE MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0xFE)
43#define EV_STARTUP MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0x01) 43#define EV_STARTUP MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0x01)
44#define EV_TRACKCHANGE MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0x02) 44#define EV_TRACKCHANGE MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0x02)
45#define EV_TRACKFINISH MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0x03) 45#define EV_TRACKFINISH MAKE_SYS_EVENT(SYS_EVENT_CLS_PRIVATE, 0x03)
@@ -70,123 +70,6 @@ static time_t timestamp;
70 70
71#define THREAD_STACK_SIZE 4*DEFAULT_STACK_SIZE 71#define THREAD_STACK_SIZE 4*DEFAULT_STACK_SIZE
72 72
73#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
74 (CONFIG_KEYPAD == IRIVER_H300_PAD)
75#define SCROBBLE_OFF BUTTON_OFF
76#define SCROBBLE_OFF_TXT "STOP"
77#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
78 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
79 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
80#define SCROBBLE_OFF BUTTON_MENU
81#define SCROBBLE_OFF_TXT "MENU"
82#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD || \
83 CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
84#define SCROBBLE_OFF BUTTON_POWER
85#define SCROBBLE_OFF_TXT "POWER"
86#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
87 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
88 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
89 (CONFIG_KEYPAD == SANSA_M200_PAD)
90#define SCROBBLE_OFF BUTTON_POWER
91#define SCROBBLE_OFF_TXT "POWER"
92#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
93#define SCROBBLE_OFF BUTTON_HOME
94#define SCROBBLE_OFF_TXT "HOME"
95#elif (CONFIG_KEYPAD == IRIVER_H10_PAD || \
96 CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD || \
97 CONFIG_KEYPAD == SONY_NWZ_PAD || \
98 CONFIG_KEYPAD == XDUOO_X3_PAD || \
99 CONFIG_KEYPAD == IHIFI_770_PAD || \
100 CONFIG_KEYPAD == IHIFI_800_PAD || \
101 CONFIG_KEYPAD == XDUOO_X3II_PAD || \
102 CONFIG_KEYPAD == XDUOO_X20_PAD || \
103 CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD || \
104 CONFIG_KEYPAD == EROSQ_PAD)
105#define SCROBBLE_OFF BUTTON_POWER
106#define SCROBBLE_OFF_TXT "POWER"
107#elif CONFIG_KEYPAD == GIGABEAT_PAD
108#define SCROBBLE_OFF BUTTON_POWER
109#define SCROBBLE_OFF_TXT "POWER"
110#elif CONFIG_KEYPAD == GIGABEAT_S_PAD \
111 || CONFIG_KEYPAD == SAMSUNG_YPR0_PAD \
112 || CONFIG_KEYPAD == CREATIVE_ZEN_PAD
113#define SCROBBLE_OFF BUTTON_BACK
114#define SCROBBLE_OFF_TXT "BACK"
115#elif CONFIG_KEYPAD == MROBE500_PAD
116#define SCROBBLE_OFF BUTTON_POWER
117#define SCROBBLE_OFF_TXT "POWER"
118#elif CONFIG_KEYPAD == MROBE100_PAD
119#define SCROBBLE_OFF BUTTON_POWER
120#define SCROBBLE_OFF_TXT "POWER"
121#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
122#define SCROBBLE_OFF BUTTON_REC
123#define BATTERY_RC_OFF BUTTON_RC_REC
124#define SCROBBLE_OFF_TXT "REC"
125#elif CONFIG_KEYPAD == COWON_D2_PAD
126#define SCROBBLE_OFF BUTTON_POWER
127#define SCROBBLE_OFF_TXT "POWER"
128#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
129#define SCROBBLE_OFF BUTTON_BACK
130#define SCROBBLE_OFF_TXT "BACK"
131#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
132#define SCROBBLE_OFF BUTTON_POWER
133#define SCROBBLE_OFF_TXT "POWER"
134#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
135#define SCROBBLE_OFF BUTTON_POWER
136#define SCROBBLE_OFF_TXT "POWER"
137#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
138#define SCROBBLE_OFF BUTTON_POWER
139#define SCROBBLE_OFF_TXT "POWER"
140#elif CONFIG_KEYPAD == ONDAVX747_PAD
141#define SCROBBLE_OFF BUTTON_POWER
142#define SCROBBLE_OFF_TXT "POWER"
143#elif CONFIG_KEYPAD == ONDAVX777_PAD
144#define SCROBBLE_OFF BUTTON_POWER
145#define SCROBBLE_OFF_TXT "POWER"
146#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \
147 (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
148#define SCROBBLE_OFF BUTTON_RIGHT
149#define SCROBBLE_OFF_TXT "RIGHT"
150#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
151#define SCROBBLE_OFF BUTTON_REC
152#define SCROBBLE_OFF_TXT "REC"
153#elif CONFIG_KEYPAD == MPIO_HD200_PAD
154#define SCROBBLE_OFF BUTTON_REC
155#define SCROBBLE_OFF_TXT "REC"
156#elif CONFIG_KEYPAD == MPIO_HD300_PAD
157#define SCROBBLE_OFF BUTTON_REC
158#define SCROBBLE_OFF_TXT "REC"
159#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
160#define SCROBBLE_OFF BUTTON_POWER
161#define SCROBBLE_OFF_TXT "POWER"
162#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
163#define SCROBBLE_OFF BUTTON_POWER
164#define SCROBBLE_OFF_TXT "POWER"
165#elif (CONFIG_KEYPAD == HM60X_PAD) || (CONFIG_KEYPAD == HM801_PAD)
166#define SCROBBLE_OFF BUTTON_POWER
167#define SCROBBLE_OFF_TXT "POWER"
168#elif CONFIG_KEYPAD == DX50_PAD
169#define SCROBBLE_OFF BUTTON_POWER_LONG
170#define SCROBBLE_OFF_TXT "Power Long"
171#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
172#define SCROBBLE_OFF BUTTON_POWER
173#define SCROBBLE_OFF_TXT "Power"
174#elif CONFIG_KEYPAD == FIIO_M3K_PAD
175#define SCROBBLE_OFF BUTTON_POWER
176#define SCROBBLE_OFF_TXT "Power"
177#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
178/* use touchscreen */
179#else
180#error "No keymap defined!"
181#endif
182#if defined(HAVE_TOUCHSCREEN)
183#ifndef SCROBBLE_OFF
184#define SCROBBLE_OFF BUTTON_TOPLEFT
185#endif
186#ifndef SCROBBLE_OFF_TXT
187#define SCROBBLE_OFF_TXT "TOPLEFT"
188#endif
189#endif
190/****************** prototypes ******************/ 73/****************** prototypes ******************/
191int plugin_main(const void* parameter); /* main loop */ 74int plugin_main(const void* parameter); /* main loop */
192enum plugin_status plugin_start(const void* parameter); /* entry */ 75enum plugin_status plugin_start(const void* parameter); /* entry */
@@ -198,7 +81,8 @@ static struct
198{ 81{
199 bool exiting; /* signal to the thread that we want to exit */ 82 bool exiting; /* signal to the thread that we want to exit */
200 unsigned int id; /* worker thread id */ 83 unsigned int id; /* worker thread id */
201 struct event_queue queue; /* thread event queue */ 84 struct event_queue queue; /* thread event queue */
85 struct queue_sender_list queue_send;
202 long stack[THREAD_STACK_SIZE / sizeof(long)]; 86 long stack[THREAD_STACK_SIZE / sizeof(long)];
203} gThread; 87} gThread;
204 88
@@ -501,9 +385,9 @@ void thread(void)
501 scrobbler_flush_cache(); 385 scrobbler_flush_cache();
502#endif 386#endif
503 return; 387 return;
504 case EV_OTHINSTANCE: 388 case EV_FLUSHCACHE:
505 scrobbler_flush_cache(); 389 scrobbler_flush_cache();
506 rb->splashf(HZ * 2, "%s Cache Flushed", str(LANG_AUDIOSCROBBLER)); 390 rb->queue_reply(&gThread.queue, 0);
507 break; 391 break;
508 default: 392 default:
509 logf("default %ld", ev.id); 393 logf("default %ld", ev.id);
@@ -520,6 +404,7 @@ void thread_create(void)
520 0, "Last.Fm_TSR" 404 0, "Last.Fm_TSR"
521 IF_PRIO(, PRIORITY_BACKGROUND) 405 IF_PRIO(, PRIORITY_BACKGROUND)
522 IF_COP(, CPU)); 406 IF_COP(, CPU));
407 rb->queue_enable_queue_send(&gThread.queue, &gThread.queue_send, gThread.id);
523 rb->queue_post(&gThread.queue, EV_STARTUP, 0); 408 rb->queue_post(&gThread.queue, EV_STARTUP, 0);
524 rb->yield(); 409 rb->yield();
525} 410}
@@ -541,46 +426,44 @@ void thread_quit(void)
541/* callback to end the TSR plugin, called before a new one gets loaded */ 426/* callback to end the TSR plugin, called before a new one gets loaded */
542static bool exit_tsr(bool reenter) 427static bool exit_tsr(bool reenter)
543{ 428{
544 logf("%s", __func__); 429 MENUITEM_STRINGLIST(menu, ID2P(LANG_AUDIOSCROBBLER), NULL,
545 bool is_exit = false; 430 "Flush Cache", "Quit", "Back");
546 int button; 431
547 if (reenter) 432 const struct text_message quit_prompt = {
548 { 433 (const char*[]){ ID2P(LANG_AUDIOSCROBBLER),
549 logf(" reenter other instance "); 434 "is currently running.",
550 rb->queue_post(&gThread.queue, EV_OTHINSTANCE, 0); 435 "Quit scrobbler?" }, 3
551 return false; /* dont let it start again */ 436 };
552 } 437
553 rb->lcd_clear_display(); 438 while(true)
554 rb->lcd_puts_scroll(0, 0, "Scrobbler is currently running.");
555 rb->lcd_puts_scroll(0, 1, "Press " SCROBBLE_OFF_TXT " to exit");
556 rb->lcd_puts_scroll(0, 2, "Anything else will resume");
557
558 rb->lcd_update();
559 rb->button_clear_queue();
560 while (1)
561 { 439 {
562 button = rb->button_get(true); 440 int result = reenter ? rb->do_menu(&menu, NULL, NULL, false) : 1;
563 if (IS_SYSEVENT(button)) 441 switch(result)
564 continue;
565 if (button == SCROBBLE_OFF)
566 { 442 {
567 rb->queue_post(&gThread.queue, EV_EXIT, 0); 443 case 0: /* flush cache */
568 rb->thread_wait(gThread.id); 444 rb->queue_send(&gThread.queue, EV_FLUSHCACHE, 0);
569 /* remove the thread's queue from the broadcast list */ 445 rb->splashf(2*HZ, "%s Cache Flushed", str(LANG_AUDIOSCROBBLER));
570 rb->queue_delete(&gThread.queue); 446 break;
571 is_exit = true;
572 }
573 else is_exit = false;
574 447
575 break; 448 case 1: /* quit */
576 } 449 if(rb->gui_syncyesno_run(&quit_prompt, NULL, NULL) == YESNO_YES)
577 FOR_NB_SCREENS(idx) 450 {
578 rb->screens[idx]->scroll_stop(); 451 rb->queue_post(&gThread.queue, EV_EXIT, 0);
452 rb->thread_wait(gThread.id);
453 /* remove the thread's queue from the broadcast list */
454 rb->queue_delete(&gThread.queue);
455 return true;
456 }
579 457
580 if (is_exit) 458 if(!reenter)
581 thread_quit(); 459 return false;
582 460
583 return is_exit; 461 break;
462
463 case 2: /* back to menu */
464 return false;
465 }
466 }
584} 467}
585 468
586/****************** main ******************/ 469/****************** main ******************/