diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-05-22 15:10:58 +0100 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2022-05-28 06:23:08 -0400 |
commit | 7345666d9ce52234236cc144062bdc75d3bcf23c (patch) | |
tree | 15a45dc1785e8f1e5288e27cf7920c3dbd0c1e33 | |
parent | 85232fadbb1fa02f6abeee7bf28ac6e286c45a24 (diff) | |
download | rockbox-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.c | 195 |
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 ******************/ |
191 | int plugin_main(const void* parameter); /* main loop */ | 74 | int plugin_main(const void* parameter); /* main loop */ |
192 | enum plugin_status plugin_start(const void* parameter); /* entry */ | 75 | enum 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 */ |
542 | static bool exit_tsr(bool reenter) | 427 | static 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 ******************/ |