package com.evsuite.abrp; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Collections; import org.junit.Test; public class NowPlayingTest { private static NowPlaying.Session session(String pkg, int state, String title, String artist, long updatedAt) { NowPlaying.Session s = new NowPlaying.Session(); s.packageName = pkg; s.state = state; s.title = title; s.artist = artist; s.positionUpdatedAt = updatedAt; return s; } @Test public void nothingToShow() { assertNull(NowPlaying.pick(null)); assertNull(NowPlaying.pick(Collections.emptyList())); // Bluetooth's empty session after the phone stopped, and one that only connects. assertNull(NowPlaying.pick(Arrays.asList( session("com.android.bluetooth", 1, "", "", 5), session("com.android.car.radio", 8, "Radio", null, 6), session("com.android.bluetooth", NowPlaying.STATE_PLAYING, " ", null, 7)))); } @Test public void whatPlaysWinsOverWhatIsPaused() { // As on the car on 2026-10-28: CarPlay paused, Bluetooth playing. NowPlaying.Track t = NowPlaying.pick(Arrays.asList( session("com.allgo.remoteui.mediabrowserservice", NowPlaying.STATE_PAUSED, "A Mix", "Bass Bangers", 900), session("com.android.bluetooth", NowPlaying.STATE_PLAYING, "Paramount", "Mark Petrie & Andrew Prahlow", 100))); assertEquals(NowPlaying.Source.BLUETOOTH, t.source); assertEquals("Paramount", t.title); assertEquals("Mark Petrie & Andrew Prahlow", t.subtitle); assertTrue(t.playing); } @Test public void ofTwoPlayingTheNewerWins() { NowPlaying.Track t = NowPlaying.pick(Arrays.asList( session("com.android.bluetooth", NowPlaying.STATE_PLAYING, "Old", null, 100), session("com.allgo.remoteui.mediabrowserservice", NowPlaying.STATE_BUFFERING, "New", null, 200))); assertEquals(NowPlaying.Source.CARPLAY, t.source); assertEquals("New", t.title); } @Test public void withNothingPlayingThePausedOneShows() { NowPlaying.Track t = NowPlaying.pick(Arrays.asList( session("com.android.bluetooth", NowPlaying.STATE_PAUSED, "Earlier", null, 100), session("com.allgo.remoteui.mediabrowserservice", NowPlaying.STATE_PAUSED, "Later", null, 300))); assertEquals("Later", t.title); assertFalse(t.playing); } @Test public void theRadioShowsItsTextWithTheStationBelow() { NowPlaying.Track t = NowPlaying.pick(Collections.singletonList( session("com.saicmotor.radio", NowPlaying.STATE_PLAYING, "Brillux Radio", "BLIND MELON - NO RAIN", 1))); assertEquals(NowPlaying.Source.RADIO, t.source); assertEquals("BLIND MELON - NO RAIN", t.title); assertEquals("Brillux Radio", t.subtitle); NowPlaying.Track station = NowPlaying.pick(Collections.singletonList( session("com.saicmotor.radio", NowPlaying.STATE_PLAYING, "Brillux Radio", "", 1))); assertEquals("Brillux Radio", station.title); assertNull(station.subtitle); assertEquals(-1f, station.progressAt(5), 0f); } @Test public void textIsCleaned() { assertEquals("A Letter to the Past (A Seasonal Feels Mix) Ft. Porter Robinson & Friends By SAINT", NowPlaying.clean("A Letter to the Past (A Seasonal Feels Mix) Ft. Porter Robinson & Friends By SAINT [X4nayMeMBuQ]")); assertEquals("Live [Remastered 2011]", NowPlaying.clean("Live [Remastered 2011]")); assertEquals("two lines", NowPlaying.clean(" two\n lines ")); assertNull(NowPlaying.clean(" ")); assertNull(NowPlaying.clean(null)); StringBuilder longText = new StringBuilder(); for (int i = 0; i < 300; i++) longText.append('x'); assertEquals(200, NowPlaying.clean(longText.toString()).length()); } @Test public void onlyAnArtistStillShows() { NowPlaying.Track t = NowPlaying.pick(Collections.singletonList( session("com.example.player", NowPlaying.STATE_PLAYING, null, "Someone", 1))); assertEquals(NowPlaying.Source.OTHER, t.source); assertEquals("Someone", t.title); assertNull(t.subtitle); } @Test public void thePositionRunsOnWhilePlayingAndStopsAtTheEnd() { NowPlaying.Session s = session("com.android.bluetooth", NowPlaying.STATE_PLAYING, "Paramount", "M", 10_000); s.positionMs = 3_000; s.durationMs = 215_000; NowPlaying.Track t = NowPlaying.pick(Collections.singletonList(s)); assertEquals(3_000, t.positionAt(10_000)); assertEquals(8_000, t.positionAt(15_000)); assertEquals(215_000, t.positionAt(10_000_000)); assertEquals(1f, t.progressAt(10_000_000), 0f); assertEquals(8_000 / 215_000f, t.progressAt(15_000), 1e-6f); } @Test public void aPausedPositionStaysPut() { NowPlaying.Session s = session("com.android.bluetooth", NowPlaying.STATE_PAUSED, "Paramount", null, 10_000); s.positionMs = 3_000; s.durationMs = 215_000; assertEquals(3_000, NowPlaying.pick(Collections.singletonList(s)).positionAt(99_000)); } @Test public void noPositionNoBar() { NowPlaying.Session s = session("com.android.bluetooth", NowPlaying.STATE_PLAYING, "Paramount", null, 10_000); s.durationMs = 215_000; assertEquals(-1f, NowPlaying.pick(Collections.singletonList(s)).progressAt(20_000), 0f); } @Test public void sourcesAreKnownByTheirApps() { assertEquals(NowPlaying.Source.BLUETOOTH, NowPlaying.source("com.android.bluetooth")); assertEquals(NowPlaying.Source.CARPLAY, NowPlaying.source("com.allgo.remoteui.mediabrowserservice")); assertEquals(NowPlaying.Source.RADIO, NowPlaying.source("com.saicmotor.radio")); assertEquals(NowPlaying.Source.OTHER, NowPlaying.source("com.android.music")); assertEquals(NowPlaying.Source.OTHER, NowPlaying.source(null)); } }