package Ġnet . atos . vcs . realtime . demo Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . media . Audio Manager Ċ import Ġandroid . util . Log Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . flow . Mutable Shared Flow Ċ import Ġkotlinx . coroutines . flow . Shared Flow Ċ import Ġnet . atos . vcs . realtime . demo . service . Active Call Service Ċ import Ġnet . atos . vcs . realtime . sdk .* Ċ import Ġjava . lang . Exception Ċ Ċ class ĠRoom Manager ( private Ġval Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġdefault Dispatcher : ĠCor outine Dispatcher Ġ= ĠDispatch ers . IO Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval ĠTAG Ġ= Ġ"${ this . java Class . kotlin . qualified Name }" ĊĊĠĠĠ Ġprivate Ġval Ġmutable Room Events : ĠMutable Shared Flow < Room Event > Ġ= ĠMutable Shared Flow () ĊĠĠĠ Ġval Ġroom Events : ĠShared Flow < Room Event > Ġ= Ġmutable Room Events ĊĊĠĠĠ Ġprivate Ġvar Ġroom : ĠRoom ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġjoin InProgress Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġval Ġroom Listener Ġ Ġby Ġlazy Ġ{ ĠRoom Listener () Ġ} ĊĠĠĠ Ġinternal Ġval Ġevent Scope Ġby Ġlazy Ġ{ ĠCor outine Scope ( default Dispatcher ) Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġjoin Room ( token : ĠString , Ġoptions : ĠRoom Options ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( room Ġ!= Ġnull Ġ|| Ġjoin InProgress ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Room Ġalready Ġjoined Ġor Ġbeing Ġjoined , Ġignore .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġwith Context ( default Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠReal time Sdk . join Room ( token , Ġoptions , Ġroom Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e . cause Ġis ĠC ancellation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Subscription Ġcancelled ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Error Ġjoining Ġwaiting Ġroom : Ġ$ e ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . room Join Error (" Error Ġjoining Ġwaiting Ġroom : Ġ$ e ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġleave Room () Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Context ( default Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroom ?. also Ġ{ Ġr Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġr . leave () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġcase Ġjoin Ġwas Ġun successful , Ġjust Ġsignal Ġthe ĠUI Ġthe Ġroom Ġwas Ġleft . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . room Left ( null , Ġnull )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Failed Ġto Ġleave Ġroom : Ġ${ e . message Ġ?: Ġe }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . error (" Failed Ġto Ġleave Ġroom : Ġ${ e . message Ġ?: Ġe } ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtoggle Mute () Ġ{ ĊĠĠĠĠĠĠĠ Ġroom ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmut ed Ġ= Ġit . toggle Mute () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , Ġ" User Ġis Ġnow Ġ${ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( muted ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" muted " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" un muted " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . muted ( muted )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Failed Ġto Ġset Ġmute Ġstate : Ġ${ e . message Ġ?: Ġe }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . error (" Failed Ġto Ġset Ġmute Ġstate : Ġ${ e . message Ġ?: Ġe } ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtoggle Video () Ġ{ ĊĠĠĠĠĠĠĠ Ġroom ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvideo Enabled Ġ= Ġit . toggle Video () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" Video Ġis Ġnow Ġ${ if Ġ( video Enabled ) Ġ{ Ġ" enabled " Ġ} Ġelse Ġ{ Ġ" disabled " Ġ}} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . video Enabled ( video Enabled )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Failed Ġto Ġtoggle Ġvideo : Ġ${ e . message Ġ?: Ġe }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . error (" Failed Ġto Ġtoggle Ġvideo : Ġ${ e . message Ġ?: Ġe } ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtoggle Speaker phone () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġaudio Manager Ġ= Ġcontext . getSystem Service ( Context . AUDIO _ SERVICE ) Ġas ĠAudio Manager ĊĠĠĠĠĠĠĠ Ġaudio Manager . is Speaker phone On Ġ= Ġ! audio Manager . is Speaker phone On ĊĠĠĠĠĠĠĠ ĠLog . d ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTAG , Ġ" Speaker Ġset : Ġ${ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( audio Manager . is Speaker phone On ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ON " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" OFF " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}" ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . speaker On ( audio Manager . is Speaker phone On )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġswitch Camera () Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroom ?. switch Camera () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Failed Ġto Ġswitch Ġcamera : Ġ${ e . message Ġ?: Ġe }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . error (" Failed Ġto Ġswitch Ġcamera : Ġ${ e . message Ġ?: Ġe } ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpause Video Rendering () Ġ{ ĊĠĠĠĠĠĠĠ Ġroom ?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Participant (). detach () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremote Participants (). forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp . detach () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġresume Video Rendering () Ġ{ ĊĠĠĠĠĠĠĠ Ġroom ?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Participant (). attach () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremote Participants (). forEach Ġ{ Ġp Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġp . attach () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġlocal Participant (): ĠLocal Participant ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġroom ?. local Participant () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Room Event ( room Event : ĠRoom Event ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG ," send Room Event : Ġ$ room Event ") ĊĠĠĠĠĠĠĠ Ġevent Scope . launch Ġ{ Ġmutable Room Events . emit ( room Event ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinner Ġclass ĠRoom Listener : ĠReal time Sdk Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Room Initialized ( room : ĠRoom ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ Room Manager . room Ġ= Ġroom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠActive Call Service . start Service ( context , Ġroom . name () Ġ?: Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . room Joined ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroom Name Ġ= Ġroom . name () Ġ?: Ġ"", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Participant Ġ= Ġroom . local Participant (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Participants Ġ= Ġroom . remote Participants (). toList (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Ġ= Ġroom . has Video ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Room Init Error ( error : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Error Ġinitializing Ġroom : Ġ$ error ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠActive Call Service . stop Service ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . room Join Error ( error )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Room Left ( room : ĠRoom , Ġparticipant : ĠLocal Participant ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ Room Manager . room Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġan Ġerror Ġoccurs Ġduring Ġthe Ġjoin Ġwe Ġwon 't Ġyet Ġhave Ġthe Ġroom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( room . roomId () Ġ== Ġthis @ Room Manager . room ?. roomId () Ġ?: Ġroom . roomId ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ"${ participant . name ()} Ġleft Ġthe Ġroom Ġ${ room . name () }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . room Left ( room . name (), Ġparticipant )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠActive Call Service . stop Service ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Ign oring Ġthe ĠRoom ĠLeft Ġevent Ġfor Ġroom Name Ġ= Ġ${ room . name ()} Ġ- Ġuser Ġis Ġnot Ġpart Ġof Ġit ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Participant Joined ( room : ĠRoom , Ġparticipant : ĠRemote Participant ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( room . roomId () Ġ== Ġthis @ Room Manager . room ?. roomId ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Participant Ġjoined Ġthe Ġroom , Ġparticipant : Ġ${ participant . name ()}, Ġroom Name : Ġ${ room . name () }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . participant Joined ( participant )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Participant Ġjoined , Ġno Ġmatching Ġroom ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Participant Left ( room : ĠRoom , Ġparticipant : ĠRemote Participant ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( room . roomId () Ġ== Ġthis @ Room Manager . room ?. roomId ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Participant Ġleft Ġthe Ġroom , Ġparticipant : Ġ${ participant . address ()}, Ġroom Name : Ġ${ room . name () }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . participant Left ( participant )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Participant Ġleft , Ġno Ġmatching Ġroom ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Local Stream Updated ( room : ĠRoom , Ġparticipant : ĠLocal Participant ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvideo Enabled Ġ= Ġroom . has Video () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Local Ġstream Ġupdated , Ġvideo Ġ${ if Ġ( video Enabled ) Ġ{" enabled "} Ġelse Ġ{" disabled "}} ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . video Enabled ( video Enabled )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Remote Stream Updated ( room : ĠRoom , Ġparticipant : ĠRemote Participant ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġif Ġ( participant . has Video ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" enabled " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" disabled " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Remote Stream Ġvideo Ġ($ value )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . remote Stream Updated ( participant )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Registration Rejected ( room : ĠRoom , Ġreason : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w ( TAG , Ġ" Registration Ġto Ġroom Ġ(${ room . name () }) Ġrejected : Ġ$ reason ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjoin InProgress Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Room Event ( Room Event . registration Rejected ( room . name () Ġ?: Ġ"", Ġreason )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} Ċ Ċ } Ċ