package Ġcom . vm en on . mp o . player . framework Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Component Name Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . support . v 4 . media . Media Browser Compat Ċ import Ġandroid . support . v 4 . media . Media Metadata Compat Ċ import Ġandroid . support . v 4 . media . session . Media Controller Compat Ċ import Ġandroid . support . v 4 . media . session . Playback State Compat Ċ import Ġandroidx . fragment . app . Fragment Ċ import Ġcom . vm en on . mp o . player . domain .* Ċ import Ġcom . vm en on . mp o . player . domain . Playback State .* Ċ import Ġkotlinx . coroutines . Main Scope Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . Mutable Shared Flow Ċ import Ġkotlinx . coroutines . flow . as Shared Flow Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlin . coroutines . resume Ċ import Ġkotlin . coroutines . suspend Coroutine Ċ Ċ class ĠAndroid Media Browser Service Player Engine ( ĊĠĠĠ Ġprivate Ġval Ġcontext : ĠContext Ċ ) Ġ: ĠMedia Player Engine Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġmedia Browser : ĠMedia Browser Compat ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmedia Controller : ĠMedia Controller Compat ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġconnected Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġval Ġmain Scope Ġ= ĠMain Scope () ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġconnect To Session (): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġsuspend Coroutine Ġ{ Ġcont Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconnection Callback Ġ= Ġobject Ġ: ĠMedia Browser Compat . Connection Callback () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Connected () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcont . resume ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmedia Browser Ġ= ĠMedia Browser Compat ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠComponent Name ( context , ĠM PO Media Browser Service :: class . java ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconnection Callback , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Browser . connect () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAndroid X MediaPlayer Engine @ Ġthis . media Browser Ġ= Ġmedia Browser ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġplayback State Flow Ġ= ĠMutable Shared Flow < Playback State >() ĊĠĠĠ Ġprivate Ġval Ġcontroller Callback Ġ= Ġobject Ġ: ĠMedia Controller Compat . Callback () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Metadata Changed ( metadata : ĠMedia Metadata Compat ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Scope . launch Ġ{ Ġsend Playback State () Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Playback StateChanged ( state : ĠPlay back State Compat ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Scope . launch Ġ{ Ġsend Playback State () Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġconnect Client ( player Client : ĠPlayer Client ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġactivity Ġ= ĠgetActivity From Client ( player Client ) ĊĠĠĠĠĠĠĠ Ġconnected Ġ= Ġconnect To Session () ĊĠĠĠĠĠĠĠ Ġif Ġ( connected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Browser ?. let Ġ{ Ġmedia Browser Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmedia Controller Ġ= ĠMedia Controller Compat ( context , Ġmedia Browser . session Token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Controller Compat . set Media Controller ( activity , Ġmedia Controller ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Controller . register Callback ( controller Callback ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . media Controller Ġ= Ġmedia Controller ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEmit Ġa ĠPlay back State Ġin Ġthe Ġevent Ġthere Ġwere Ġno Ġmetadata Ġor Ġplayback Ġstate Ġchanges ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Playback State () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġconnected ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġplay ( request : ĠPlay back Media Request ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! connected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Cannot Ġplay Ġmedia Ġbefore Ġconnected ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġbundle Ġ= ĠBundle () ĊĠĠĠĠĠĠĠ Ġbundle . put Serializable ( MP O Media Browser Service . PLAY BACK _ MEDIA _ REQUEST _ EXTRA , Ġrequest ) ĊĠĠĠĠĠĠĠ Ġmedia Controller ?. transport Controls ?. play From Media Id ( request . media . media Id , Ġbundle ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġresume () Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Controller ?. transport Controls ?. play () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġpause () Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Controller ?. transport Controls ?. pause () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Controller ?. transport Controls ?. stop () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġseek To ( position : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Controller ?. transport Controls ?. seek To ( position ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġdisconnect Client ( player Client : ĠPlayer Client ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġactivity Ġ= ĠgetActivity From Client ( player Client ) ĊĠĠĠĠĠĠĠ Ġif Ġ( Media Controller Compat . get Media Controller ( activity ) Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Controller Compat . get Media Controller ( activity ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. unregister Callback ( controller Callback ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmedia Browser ?. disconnect () ĊĠĠĠĠĠĠĠ Ġmedia Browser Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġconnected Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun ĠgetCurrent Playback State (): ĠPlay back State ? Ġ= ĊĠĠĠĠĠĠĠ Ġmedia Controller ?. let Ġ{ Ġcontroller Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmetadata Ġ= Ġcontroller . metadata ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġplayback State Ġ= Ġcontroller . playback State ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( metadata Ġ!= Ġnull Ġ&& Ġplayback State Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPlay back State ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Ġ= ĠPlay back Media ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Id Ġ= Ġmetadata . getString ( Media Metadata Compat . METADATA _ KEY _ MEDIA _ ID ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġart work Url Ġ= Ġmetadata . getString ( Media Metadata Compat . METADATA _ KEY _ AL BU M _ ART _ URI ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtitle Ġ= Ġmetadata . getString ( Media Metadata Compat . METADATA _ KEY _ TITLE ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġalbum Ġ= Ġmetadata . getString ( Media Metadata Compat . METADATA _ KEY _ AL BU M ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġauthor Ġ= Ġmetadata . getString ( Media Metadata Compat . METADATA _ KEY _ AUTHOR ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduration In Millis Ġ= Ġmetadata . getLong ( Media Metadata Compat . METADATA _ KEY _ DURATION ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġposition In Millis Ġ= Ġplayback State . position , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplayback Speed Ġ= Ġplayback State . playback Speed , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ= Ġwhen Ġ( playback State . state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ PLAY ING Ġ-> ĠState . PLAY ING ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ BUFFER ING Ġ-> ĠState . BUFFER ING ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ PA USED Ġ-> ĠState . PA USED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ STOP PED Ġ-> ĠState . STOP PED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ FAST _ FORWARD ING Ġ-> ĠState . FAST _ FORWARD ING ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ RE W IND ING Ġ-> ĠState . RE W IND ING ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ ERROR Ġ-> ĠState . ERROR ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . STATE _ NONE Ġ-> ĠState . NONE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠState . UNKNOWN ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġplayback State Changes : ĠFlow < Playback State > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġplayback State Flow . as Shared Flow () ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġsend Playback State () Ġ{ ĊĠĠĠĠĠĠĠ ĠgetCurrent Playback State ()?. let Ġ{ Ġplayback State Flow . emit ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetActivity From Client ( player Client : ĠPlayer Client ) Ġ= Ġwhen Ġ( player Client ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠActivity Ġ-> Ġplayer Client ĊĠĠĠĠĠĠĠ Ġis ĠFragment Ġ-> Ġplayer Client . require Activity () ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" player Client Ġneeds Ġto Ġbe Ġan Ġactivity Ġor Ġfragment !") ĊĠĠĠ Ġ} Ċ }