Instead of fixing the root issue (parsing sql by regexp), we are going to pass
a 'nicer' query to the 'optimizer' so that it is able to catch our intent.
calling setSong(0); is not required as changing the mode will already broadcast a change which causes us to pick up a new song from scratch.
The old code caused 2 threads to touch the PlaybackService + SongTimeline at the same time, resulting in a deadlock in the worst case.
Trace for historical reasons:
DALVIK THREADS (21):
"main" prio=5 tid=1 Blocked
| group="main" sCount=1 dsCount=0 obj=0x73d5b000 self=0xb4827800
| sysTid=14357 nice=0 cgrp=default sched=0/0 handle=0xb6f74bec
| state=S schedstat=( 321573745 82720575 681 ) utm=21 stm=11 core=3 HZ=100
| stack=0xbe5a4000-0xbe5a6000 stackSize=8MB
| held mutexes=
at ch.blinkenlights.android.vanilla.SongTimeline.shiftCurrentSong(SongTimeline.java:669)
- waiting to lock <0x30e74b87> (a ch.blinkenlights.android.vanilla.SongTimeline) held by thread 16
at ch.blinkenlights.android.vanilla.PlaybackService.setCurrentSong(PlaybackService.java:1298)
at ch.blinkenlights.android.vanilla.PlaybackService.play(PlaybackService.java:1184)
- locked <0x3ce87ab4> (a java.lang.Object[])
at ch.blinkenlights.android.vanilla.PlaybackService.playPause(PlaybackService.java:1221)
- locked <0x3ce87ab4> (a java.lang.Object[])
at ch.blinkenlights.android.vanilla.PlaybackActivity.playPause(PlaybackActivity.java:186)
at ch.blinkenlights.android.vanilla.PlaybackActivity.onClick(PlaybackActivity.java:206)
at ch.blinkenlights.android.vanilla.LibraryActivity.onClick(LibraryActivity.java:544)
at android.view.View.performClick(View.java:4789)
at android.view.View$PerformClick.run(View.java:19881)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5294)
at java.lang.reflect.Method.invoke!(Native method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
"PlaybackService" prio=5 tid=16 Blocked
| group="main" sCount=1 dsCount=0 obj=0x12d52900 self=0xb4a1c400
| sysTid=14379 nice=0 cgrp=default sched=0/0 handle=0xb4929400
| state=S schedstat=( 25323853 1519584 33 ) utm=2 stm=0 core=3 HZ=100
| stack=0xaeafe000-0xaeb00000 stackSize=1036KB
| held mutexes=
at ch.blinkenlights.android.vanilla.PlaybackService.setCurrentSong(PlaybackService.java:1315)
- waiting to lock <0x3ce87ab4> (a java.lang.Object[]) held by thread 1
at ch.blinkenlights.android.vanilla.PlaybackService.activeSongReplaced(PlaybackService.java:1659)
at ch.blinkenlights.android.vanilla.SongTimeline.broadcastChangedSongs(SongTimeline.java:906)
at ch.blinkenlights.android.vanilla.SongTimeline.setFinishAction(SongTimeline.java:511)
- locked <0x30e74b87> (a ch.blinkenlights.android.vanilla.SongTimeline)
at ch.blinkenlights.android.vanilla.PlaybackService.processNewState(PlaybackService.java:1039)
at ch.blinkenlights.android.vanilla.PlaybackService.handleMessage(PlaybackService.java:1543)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
setData() might get called late after a queue update. If the listview already started to draw, it might trigger a panic if a count mismatch was detected
setData() might get called late after a queue update. If the listview already started to draw, it might trigger a panic if a count mismatch was detected