package Ġcom . example . music player . ex op layer Ċ Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . support . v 4 . media . Media Browser Compat Ċ import Ġandroid . support . v 4 . media . Media Description Compat Ċ import Ġandroid . support . v 4 . media . Media Metadata Compat Ċ import Ġandroid . support . v 4 . media . session . Media Session Compat Ċ import Ġandroidx . media . Media Browser Service Compat Ċ import Ġcom . example . music player . ex op layer . callbacks . Music Playback Prepared Ċ import Ġcom . example . music player . ex op layer . callbacks . Music Player EventListener Ċ import Ġcom . example . music player . ex op layer . callbacks . Music Player Notification Listener Ċ import Ġcom . example . music player . other . Constants . MEDIA _ ROOT _ ID Ċ import Ġcom . example . music player . other . Constants . NETWORK _ FAILURE Ċ import Ġcom . example . music player . other . Constants . SERVICE _ TAG Ċ import Ġcom . google . android . ex op layer 2 . Player Ċ import Ġcom . google . android . ex op layer 2 . Simple Exo Player Ċ import Ġcom . google . android . ex op layer 2 . ext . medi ase ssion . Media Session Connector Ċ import Ġcom . google . android . ex op layer 2 . ext . medi ase ssion . Timeline Queue Navigator Ċ import Ġcom . google . android . ex op layer 2 . upstream . Default DataSource Factory Ċ import Ġdagger . h ilt . android . Android EntryPoint Ċ import Ġkotlinx . coroutines .* Ċ import Ġjavax . inject . Inject Ċ Ċ @ Android EntryPoint Ċ class ĠMusic Service Ġ: ĠMedia Browser Service Compat () Ġ{ ĊĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar ĠdataSource Factory : ĠDefault DataSource Factory ĊĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar Ġex o Player : ĠSimple Exo Player ĊĊĠĠĠ Ġ@ Inject ĊĠĠĠ Ġlateinit Ġvar Ġmusic Source : ĠMusic Source ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġmusic Notification M anger : ĠMusic Notification M anger ĊĊĠĠĠ Ġprivate Ġval Ġservice Job Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġval Ġservice Scope Ġ= ĠCor outine Scope ( Dispatch ers . Main Ġ+ Ġservice Job ) ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġmedia Session Compat : ĠMedia Session Compat ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġmedia Session Connector : ĠMedia Session Connector ĊĊĠĠĠ Ġvar Ġis Foreground Service Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġvar Ġcurrent Playing Song : ĠMedia Metadata Compat ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġis Player Initialize Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġmusic Player Listener : ĠMusic Player EventListener ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" MediaPlayer Service " ĊĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Song Duration Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate () ĊĠĠĠĠĠĠĠ Ġservice Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmusic Source . fetch Media Data () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġactivity Intent Ġ= Ġpackage Manager ?. get Launch Intent For Package ( packageName )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPending Intent . getActivity ( this , Ġ 0 , Ġit , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmedia Session Compat Ġ= ĠMedia Session Compat ( this , ĠSERVICE _ TAG ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Session Activity ( activity Intent ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠisActive Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsession Token Ġ= Ġmedia Session Compat . session Token ĊĊĠĠĠĠĠĠĠ Ġmusic Notification M anger Ġ= ĠMusic Notification M anger ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Session Compat . session Token , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMusic Player Notification Listener ( this ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Song Duration Ġ= Ġex o Player . duration ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġmusic Playback Pre par er Ġ= ĠMusic Playback Prepared ( music Source ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Playing Song Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprepare Player ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmusic Source . songs , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmedia Session Connector Ġ= ĠMedia Session Connector ( media Session Compat ) ĊĠĠĠĠĠĠĠ Ġmedia Session Connector . set Playback Pre par er ( music Playback Pre par er ) ĊĠĠĠĠĠĠĠ Ġmedia Session Connector . set Queue Navigator ( Music Queue Navigator ()) ĊĠĠĠĠĠĠĠ Ġmedia Session Connector . set Player ( exo Player ) ĊĊĠĠĠĠĠĠĠ Ġmusic Player Listener Ġ= ĠMusic Player EventListener ( this ) ĊĠĠĠĠĠĠĠ Ġex o Player . addListener ( music Player Listener ) ĊĠĠĠĠĠĠĠ Ġmusic Notification M anger . show Notification ( exo Player ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠMusic Queue Navigator Ġ: ĠTimeline Queue Navigator ( media Session Compat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Media Description ( player : ĠPlayer , Ġwindow Index : ĠInt ): ĠMedia Description Compat Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmusic Source . songs [ window Index ]. description ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprepare Player ( ĊĠĠĠĠĠĠĠ Ġsongs : ĠList < Media Metadata Compat >, ĊĠĠĠĠĠĠĠ Ġitem To Play : ĠMedia Metadata Compat ?, ĊĠĠĠĠĠĠĠ Ġplay Now : ĠBoolean ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcur Song Index Ġ= Ġif ( current Playing Song Ġ== Ġnull ) Ġ 0 Ġelse Ġsongs . indexOf ( item To Play ) ĊĠĠĠĠĠĠĠ Ġex o Player . set Media Source ( music Source . as Media Source ( dataSource Factory )) ĊĠĠĠĠĠĠĠ Ġex o Player . prepare () ĊĠĠĠĠĠĠĠ Ġex o Player . seek To ( cur Song Index , Ġ 0 L ) ĊĠĠĠĠĠĠĠ Ġex o Player . play When Ready Ġ= Ġplay Now ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Task Removed ( root Intent : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Task Removed ( root Intent ) ĊĠĠĠĠĠĠĠ Ġex o Player . stop () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠĠĠĠĠ Ġservice Scope . cancel () ĊĠĠĠĠĠĠĠ Ġex o Player . remove Listener ( music Player Listener ) ĊĠĠĠĠĠĠĠ Ġex o Player . release () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Get Root ( ĊĠĠĠĠĠĠĠ Ġclient PackageName : ĠString , ĊĠĠĠĠĠĠĠ Ġclient Uid : ĠInt , ĊĠĠĠĠĠĠĠ Ġroot Hints : ĠBundle ? ĊĠĠĠ Ġ): ĠBrowser Root ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠBrowser Root ( MEDIA _ ROOT _ ID , Ġnull ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonLoad Children ( ĊĠĠĠĠĠĠĠ ĠparentId : ĠString , ĊĠĠĠĠĠĠĠ Ġresult : ĠResult < Mutable List < Media Browser Compat . Media Item >> ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( parentId ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMED IA _ ROOT _ ID Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresults Sent Ġ= Ġmusic Source . when Ready Ġ{ Ġis Initialized Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( isInitialized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . send Result ( music Source . as Media Items ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif (! is Player Initialize Ġ&& Ġmusic Source . songs . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprepare Player ( music Source . songs , Ġmusic Source . songs [ 0 ], Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Player Initialize Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Session Compat . send Session Event ( NETWORK _ FAILURE , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . send Result ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif (! results Sent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . detach () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }