/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 ĠNam ĠN gu yen , Ġnam @ ene . im Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġk oh ii . v 1 . ex op layer Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . util . Log Ċ import Ġandroid . widget . Toast Ċ import Ġcom . google . android . ex op layer 2 . C Ċ import Ġcom . google . android . ex op layer 2 . Exo Playback Exception Ċ import Ġcom . google . android . ex op layer 2 . Exo Player Ċ import Ġcom . google . android . ex op layer 2 . Playback Parameters Ċ import Ġcom . google . android . ex op layer 2 . Player Ċ import Ġcom . google . android . ex op layer 2 . medi ac ode c . Media Codec Renderer . Decoder Initialization Exception Ċ import Ġcom . google . android . ex op layer 2 . medi ac ode c . Media Codec Util Ċ import Ġcom . google . android . ex op layer 2 . source . Be hind Live Window Exception Ċ import Ġcom . google . android . ex op layer 2 . source . Media Source Ċ import Ġcom . google . android . ex op layer 2 . source . Track Group Array Ċ import Ġcom . google . android . ex op layer 2 . track selection . Mapping Track Selector . Mapped Track Info . RENDER ER _ SUPPORT _ UNSUPPORTED _ TRACK S Ċ import Ġcom . google . android . ex op layer 2 . track selection . Track Selection Array Ċ import Ġcom . google . android . ex op layer 2 . ui . Player View Ċ import Ġk oh ii . v 1 . core . Abstract Bridge Ċ import Ġk oh ii . v 1 . core . Common Ċ import Ġk oh ii . v 1 . core . Default Track Selector Holder Ċ import Ġk oh ii . v 1 . core . Player EventListener Ċ import Ġk oh ii . v 1 . core . Player Parameters Ċ import Ġk oh ii . v 1 . core . Volume Info Controller Ċ import Ġk oh ii . v 1 . ex op layer . internal . addEventListener Ċ import Ġk oh ii . v 1 . ex op layer . internal . get Volume Info Ċ import Ġk oh ii . v 1 . ex op layer . internal . removeEventListener Ċ import Ġk oh ii . v 1 . ex op layer . internal . set Volume Info Ċ import Ġk oh ii . v 1 . log Info Ċ import Ġk oh ii . v 1 . media . Media Ċ import Ġk oh ii . v 1 . media . Playback Info Ċ import Ġk oh ii . v 1 . media . Playback Info . Companion . INDEX _ UN SET Ċ import Ġk oh ii . v 1 . media . Volume Info Ċ import Ġkotlin . math . max Ċ Ċ /** Ċ Ġ* Ġ@ author Ġen e im Ġ( 2 0 1 8 / 0 6 / 2 4 ). Ċ Ġ*/ Ċ class ĠPlayer View Bridge ( ĊĠ Ġcontext : ĠContext , ĊĠ Ġprivate Ġval Ġmedia : ĠMedia , ĊĠ Ġprivate Ġval Ġplayer Provider : ĠEx o Player Provider , ĊĠ Ġmedia Source Factory Provider : ĠMedia Source Factory Provider Ċ ) Ġ: ĠAbstract Bridge < Player View >(), ĠPlayer EventListener Ġ{ ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġinternal Ġfun Ġis Be hind Live Window ( error : ĠEx o Playback Exception ?): ĠBoolean Ġ{ ĊĠĠĠĠĠ Ġif Ġ( error ?. type Ġ!= ĠEx o Playback Exception . TYPE _ SOURCE ) Ġreturn Ġfalse ĊĠĠĠĠĠ Ġvar Ġcause : ĠThrowable ? Ġ= Ġerror . source Exception ĊĠĠĠĠĠ Ġwhile Ġ( cause Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( cause Ġis ĠBe hind Live Window Exception ) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġcause Ġ= Ġcause . cause ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġcontext Ġ= Ġcontext . application Context ĊĠ Ġprivate Ġval Ġmedia Source Factory Ġ= Ġmedia Source Factory Provider . provide Media Source Factory ( media ) ĊĊĠ Ġprivate Ġvar Ġlistener Applied Ġ= Ġfalse ĊĠ Ġprivate Ġvar Ġsource Prepared Ġ= Ġfalse ĊĊĠ Ġprivate Ġvar Ġ_ playback Info Ġ= ĠPlay back Info () Ġ// ĠBack ing Ġfield Ġfor ĠPlay back Info Ġset / get ĊĠ Ġprivate Ġvar Ġ_ repeat Mode Ġ= ĠCommon . REPEAT _ MODE _ OFF Ġ// ĠBack ing Ġfield ĊĠ Ġprivate Ġvar Ġ_ playback Params Ġ= ĠPlay back Parameters . DEFAULT Ġ// ĠBack ing Ġfield ĊĠ Ġprivate Ġvar Ġmedia Source : ĠMedia Source ? Ġ= Ġnull ĊĊĠ Ġprivate Ġvar Ġlast Seen Track Group Array : ĠTrack Group Array ? Ġ= Ġnull ĊĠ Ġprivate Ġvar Ġin Error State Ġ= Ġfalse ĊĊĠ Ġinternal Ġvar Ġplayer : ĠPlayer ? Ġ= Ġnull ĊĊĠ Ġoverride Ġval Ġplayer State : ĠInt ĊĠĠĠ Ġget () Ġ= Ġplayer ?. playback State Ġ?: ĠCommon . STATE _ IDLE ĊĊĠ Ġoverride Ġfun Ġprepare ( load Source : ĠBoolean ) Ġ{ ĊĠĠĠ Ġsuper . addEventListener ( this ) ĊĊĠĠĠ Ġif Ġ( player Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġsource Prepared Ġ= Ġfalse ĊĠĠĠĠĠ Ġlistener Applied Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( load Source ) Ġ{ ĊĠĠĠĠĠ Ġprepare Media Source () ĊĠĠĠĠĠ Ġensure Player View () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġthis . last Seen Track Group Array Ġ= Ġnull ĊĠĠĠ Ġthis . in Error State Ġ= Ġfalse ĊĠ Ġ} ĊĊĠ Ġoverride Ġvar Ġrenderer : ĠPlayer View ? Ġ= Ġnull ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( field Ġ=== Ġvalue ) Ġreturn Ġ// Ġsame Ġreference ĊĠĠĠĠĠ Ġthis . last Seen Track Group Array Ġ= Ġnull ĊĠĠĠĠĠ Ġthis . in Error State Ġ= Ġfalse ĊĠĠĠĠĠ Ġif Ġ( value Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire NotNull ( field ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġ' field ' Ġmust Ġbe Ġnot Ġnull Ġhere ĊĠĠĠĠĠĠĠĠĠ Ġit . player Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠ Ġit . set ErrorMessage Provider ( null ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . player ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠPlayer View . switch Target View ( it , Ġfield , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġready () Ġ{ ĊĠĠĠ Ġprepare Media Source () ĊĠĠĠ Ġrequire NotNull ( player ) Ġ{ Ġ" Player Ġmust Ġbe Ġavailable ." Ġ} ĊĠĠĠ Ġensure Player View () ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġplay () Ġ{ ĊĠĠĠ Ġsuper . play () ĊĠĠĠ Ġif Ġ( player Parameters . player Should Start ()) Ġ{ ĊĠĠĠĠĠ Ġrequire NotNull ( player ). play When Ready Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġpause () Ġ{ ĊĠĠĠ Ġsuper . pause () ĊĠĠĠ Ġif Ġ( source Prepared ) Ġplayer ?. play When Ready Ġ= Ġfalse ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġreset ( reset Player : ĠBoolean ) Ġ{ ĊĠĠĠ Ġif Ġ( reset Player ) Ġ_ playback Info Ġ= ĠPlay back Info () ĊĠĠĠ Ġelse Ġupdate Playback Info () ĊĠĠĠ Ġplayer ?. also Ġ{ ĊĠĠĠĠĠ Ġit . set Volume Info ( Volume Info ( false , Ġ 1 . 0 F )) ĊĠĠĠĠĠ Ġit . stop ( reset Player ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġthis . media Source Ġ= Ġnull Ġ// ĠSo Ġit Ġwill Ġbe Ġre - prepared Ġlater . ĊĠĠĠ Ġthis . source Prepared Ġ= Ġfalse ĊĠĠĠ Ġthis . last Seen Track Group Array Ġ= Ġnull ĊĠĠĠ Ġthis . in Error State Ġ= Ġfalse ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġrelease () Ġ{ ĊĠĠĠ Ġthis . removeEventListener ( this ) ĊĠĠĠ Ġ// Ġthis . player View Ġ= Ġnull Ġ// ĠBridge 's Ġowner Ġmust Ġdo Ġthis . ĊĠĠĠ Ġthis . renderer ?. player Ġ= Ġnull ĊĠĠĠ Ġ_ playback Info Ġ= ĠPlay back Info () ĊĠĠĠ Ġplayer ?. also Ġ{ ĊĠĠĠĠĠ Ġif Ġ( listener Applied ) Ġ{ ĊĠĠĠĠĠĠĠ Ġit . removeEventListener ( event Listeners ) ĊĠĠĠĠĠĠĠ Ġlistener Applied Ġ= Ġfalse ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ( it Ġas ? ĠVolume Info Controller )?. remove Volume Changed Listener ( volume Listeners ) ĊĠĠĠĠĠ Ġit . stop ( true ) ĊĠĠĠĠĠ Ġplayer Provider . release Player ( this . media , Ġit ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġthis . player Ġ= Ġnull ĊĠĠĠ Ġthis . media Source Ġ= Ġnull ĊĠĠĠ Ġthis . source Prepared Ġ= Ġfalse ĊĠĠĠ Ġthis . last Seen Track Group Array Ġ= Ġnull ĊĠĠĠ Ġthis . in Error State Ġ= Ġfalse ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġis Playing (): ĠBoolean Ġ{ ĊĠĠĠ Ġreturn Ġplayer ?. run Ġ{ ĊĠĠĠĠĠ Ġplay When Ready Ġ&& ĊĠĠĠĠĠĠĠĠĠ Ġplayback State Ġin ĠPlayer . STATE _ BUFFER ING .. Player . STATE _ READY Ġ&& ĊĠĠĠĠĠĠĠĠĠ Ġplayback Sup pression Reason Ġ== ĠPlayer . PLAY BACK _ SUP PRESS ION _ REASON _ NONE ĊĠĠĠ Ġ} Ġ?: Ġfalse ĊĠ Ġ} ĊĊĠ Ġoverride Ġvar Ġvolume Info : ĠVolume Info Ġ= Ġplayer ?. get Volume Info () Ġ?: ĠVolume Info () ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġ" Bridge # volume Info : Ġ$ field Ġ-> Ġ$ value , Ġ$ this ". log Info () ĊĠĠĠĠĠ Ġif Ġ( field Ġ== Ġvalue ) Ġreturn ĊĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠ Ġplayer ?. set Volume Info ( value ) ĊĠĠĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġseek To ( position Ms : ĠLong ) Ġ{ ĊĠĠĠ Ġval Ġplayback Info Ġ= Ġthis . playback Info ĊĠĠĠ Ġplayback Info . resume Position Ġ= Ġposition Ms ĊĠĠĠ Ġplayback Info . resume Window Ġ= Ġplayer ?. current Window Index Ġ?: Ġplayback Info . resume Window ĊĠĠĠ Ġthis . playback Info Ġ= Ġplayback Info ĊĠ Ġ} ĊĊĠ Ġoverride Ġvar Ġplayback Info : ĠPlay back Info ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠ Ġupdate Playback Info () ĊĠĠĠĠĠ Ġreturn Ġ_ playback Info ĊĠĠĠ Ġ} ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġthis . set Playback Info ( value , Ġfalse ) ĊĠĠĠ Ġ} ĊĊĠ Ġoverride Ġvar Ġplayer Parameters : ĠPlayer Parameters Ġ= ĠPlayer Parameters () ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠ Ġapply Player Parameters ( value ) ĊĠĠĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġapply Player Parameters ( parameters : ĠPlayer Parameters ) Ġ{ ĊĠĠĠ Ġval Ġplayer Ġ= Ġthis . player ĊĠĠĠ Ġif Ġ( player Ġis ĠDefault Track Selector Holder ) Ġ{ ĊĠĠĠĠĠ Ġplayer . track Selector . parameters Ġ= Ġplayer . track Selector . parameters . build Up on () ĊĠĠĠĠĠĠĠĠĠ Ġ. setMax Video Size ( parameters . max Video Width , Ġparameters . max Video Height ) ĊĠĠĠĠĠĠĠĠĠ Ġ. setMax Video Bit rate ( parameters . max Video Bit rate ) ĊĠĠĠĠĠĠĠĠĠ Ġ. setMax Audio Bit rate ( parameters . max Audio Bit rate ) ĊĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġset Playback Info ( ĊĠĠĠ Ġplayback Info : ĠPlay back Info , ĊĠĠĠ Ġvolume Only : ĠBoolean ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ_ playback Info Ġ= Ġplayback Info ĊĊĠĠĠ Ġplayer ?. also Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! volume Only ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhave Resume Position Ġ= Ġ_ playback Info . resume Window Ġ!= ĠINDEX _ UN SET ĊĠĠĠĠĠĠĠ Ġif Ġ( have Resume Position ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġit . seek To (_ playback Info . resume Window , Ġ_ playback Info . resume Position ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġvar Ġrepeat Mode : ĠInt ĊĠĠĠ Ġget () Ġ= Ġ_ repeat Mode ĊĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠ Ġ_ repeat Mode Ġ= Ġvalue ĊĠĠĠĠĠ Ġthis . player ?. also Ġ{ Ġit . repeat Mode Ġ= Ġvalue Ġ} ĊĠĠĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġupdate Playback Info () Ġ{ ĊĠĠĠ Ġplayer ?. also Ġ{ ĊĠĠĠĠĠ Ġif Ġ( it . playback State Ġ== ĠCommon . STATE _ IDLE ) Ġreturn ĊĠĠĠĠĠ Ġ_ playback Info Ġ= ĠPlay back Info ( ĊĠĠĠĠĠĠĠĠĠ Ġit . current Window Index , ĊĠĠĠĠĠĠĠĠĠ Ġmax ( 0 , Ġit . current Position ) ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġensure Player View () Ġ{ ĊĠĠĠ Ġrenderer ?. also Ġ{ Ġif Ġ( it . player Ġ!== Ġthis . player ) Ġit . player Ġ= Ġthis . player Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġprepare Media Source () Ġ{ ĊĠĠĠ Ġval Ġmedia Source : ĠMedia Source Ġ= Ġthis . media Source Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠ Ġsource Prepared Ġ= Ġfalse ĊĠĠĠĠĠ Ġmedia Source Factory . create Media Source ( this . media . uri ). also Ġ{ Ġthis . media Source Ġ= Ġit Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠPlayer Ġwas Ġreset , Ġneed Ġto Ġprepare Ġagain . ĊĠĠĠ Ġif Ġ( player ?. playback State Ġ== ĠCommon . STATE _ IDLE ) Ġ{ ĊĠĠĠĠĠ Ġsource Prepared Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ(! source Prepared ) Ġ{ ĊĠĠĠĠĠ Ġensure Player () ĊĠĠĠĠĠ Ġ( player Ġas ? ĠEx o Player )?. also Ġ{ ĊĠĠĠĠĠĠĠ Ġit . prepare ( media Source , Ġplayback Info . resume Window Ġ== ĠINDEX _ UN SET , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġsource Prepared Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġensure Player () Ġ{ ĊĠĠĠ Ġif Ġ( player Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġsource Prepared Ġ= Ġfalse ĊĠĠĠĠĠ Ġlistener Applied Ġ= Ġfalse ĊĠĠĠĠĠ Ġval Ġplayer Ġ= Ġplayer Provider . acquire Player ( this . media ) ĊĠĠĠĠĠ Ġapply Player Parameters ( player Parameters ) ĊĠĠĠĠĠ Ġthis . player Ġ= Ġplayer ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrequire NotNull ( player ). also Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! listener Applied ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ( player Ġas ? ĠVolume Info Controller )?. add Volume Changed Listener ( volume Listeners ) ĊĠĠĠĠĠĠĠ Ġit . addEventListener ( event Listeners ) ĊĠĠĠĠĠĠĠ Ġlistener Applied Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġit . set Playback Parameters (_ playback Params ) ĊĠĠĠĠĠ Ġval Ġhas Resume Position Ġ= Ġ_ playback Info . resume Window Ġ!= ĠINDEX _ UN SET ĊĠĠĠĠĠ Ġif Ġ( has Resume Position ) Ġ{ ĊĠĠĠĠĠĠĠ Ġit . seek To (_ playback Info . resume Window , Ġ_ playback Info . resume Position ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġit . set Volume Info ( volume Info ) ĊĠĠĠĠĠ Ġit . repeat Mode Ġ= Ġ_ repeat Mode ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġon ErrorMessage ( ĊĠĠĠ Ġmessage : ĠString , ĊĠĠĠ Ġcause : ĠThrowable ? ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġ// ĠSub Ġclass Ġcan Ġhave Ġcustom Ġreaction Ġabout Ġthe Ġerror Ġhere , Ġincluding Ġnot Ġto Ġshow Ġthis Ġtoast ĊĠĠĠ Ġ// Ġ( by Ġnot Ġcalling Ġsuper . on ErrorMessage ( message )). ĊĠĠĠ Ġif Ġ( this . error Listeners . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġthis . error Listeners . onError ( RuntimeException ( message , Ġcause )) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠToast . makeText ( context , Ġmessage , ĠToast . LENGTH _ SHORT ) ĊĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ// ĠDefault EventListener Ġâ ¬ ĩ ï¸ İ ĊĊĠ Ġoverride Ġfun Ġon Player Error ( error : ĠEx o Playback Exception ) Ġ{ ĊĠĠĠ ĠLog . e (" K oh ii :: Bridge ", Ġ" Error : Ġ${ error . cause }") ĊĠĠĠ Ġif Ġ( renderer Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġvar Ġerror String : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠ Ġif Ġ( error . type Ġ== ĠEx o Playback Exception . TYPE _ RENDER ER ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexception Ġ= Ġerror . renderer Exception ĊĠĠĠĠĠĠĠ Ġif Ġ( exception Ġis ĠDecoder Initialization Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠSpecial Ġcase Ġfor Ġdecoder Ġinitialization Ġfailures . ĊĠĠĠĠĠĠĠĠĠ Ġerror String Ġ= Ġif Ġ( exception . codec Info Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception . cause Ġis ĠMedia Codec Util . Decoder Query Exception Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . getString ( R . string . error _ query ing _ de coders ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception . secure Decoder Required Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . getString ( R . string . error _ no _ secure _ decoder , Ġexception . mime Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcontext . getString ( R . string . error _ no _ decoder , Ġexception . mime Type ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . getString ( R . string . error _ inst anti ating _ decoder , Ġexception . codec Info ?. name Ġ?: Ġ"") ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġif Ġ( error String Ġ!= Ġnull ) Ġon ErrorMessage ( error String , Ġerror ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġin Error State Ġ= Ġtrue ĊĠĠĠ Ġif Ġ( is Be hind Live Window ( error )) Ġ{ ĊĠĠĠĠĠ Ġreset () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġupdate Playback Info () ĊĠĠĠ Ġ} ĊĠĠĠ Ġthis . error Listeners . onError ( error ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġon Position Dis continu ity ( reason : ĠInt ) Ġ{ ĊĠĠĠ Ġif Ġ( in Error State ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠAdapt Ġfrom ĠEx o Player Ġdemo . ĊĠĠĠĠĠ Ġ// Ġ" This Ġwill Ġonly Ġoccur Ġif Ġthe Ġuser Ġhas Ġperformed Ġa Ġseek Ġwh il st Ġin Ġthe Ġerror Ġstate . ĠUpdate ĊĠĠĠĠĠ Ġ// Ġthe Ġresume Ġposition Ġso Ġthat Ġif Ġthe Ġuser Ġthen Ġretries , Ġplayback Ġwill Ġresume Ġfrom Ġthe ĊĠĠĠĠĠ Ġ// Ġposition Ġto Ġwhich Ġthey Ġseek ." Ġ- ĠEx o Player ĊĠĠĠĠĠ Ġupdate Playback Info () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġon Tracks Changed ( ĊĠĠĠ Ġtrack Groups : ĠTrack Group Array , ĊĠĠĠ Ġtrack Selections : ĠTrack Selection Array ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġif Ġ( track Groups Ġ== Ġlast Seen Track Group Array ) Ġreturn ĊĠĠĠ Ġlast Seen Track Group Array Ġ= Ġtrack Groups ĊĠĠĠ Ġval Ġplayer Ġ= Ġthis . player Ġas ? ĠK oh ii Exo Player Ġ?: Ġreturn ĊĠĠĠ Ġval Ġtrack Info Ġ= Ġplayer . track Selector . current Mapped Track Info ĊĠĠĠ Ġif Ġ( track Info Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( track Info . getType Support ( C . TRACK _ TYPE _ VIDEO ) Ġ== ĠR ENDER ER _ SUPPORT _ UNSUPPORTED _ TRACK S ) Ġ{ ĊĠĠĠĠĠĠĠ Ġon ErrorMessage ( context . getString ( R . string . error _ unsupported _ video ), Ġplayer . playback Error ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġif Ġ( track Info . getType Support ( C . TRACK _ TYPE _ AUDIO ) Ġ== ĠR ENDER ER _ SUPPORT _ UNSUPPORTED _ TRACK S ) Ġ{ ĊĠĠĠĠĠĠĠ Ġon ErrorMessage ( context . getString ( R . string . error _ unsupported _ audio ), Ġplayer . playback Error ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ