package Ġio . live kit . android . room Ċ Ċ import Ġcom . github . aj alt . tim ber kt . Tim ber Ċ import Ġdagger . ass isted . Ass isted Ċ import Ġdagger . ass isted . Ass isted Factory Ċ import Ġdagger . ass isted . Ass isted Inject Ċ import Ġio . live kit . android . d agger . Injection Names Ċ import Ġio . live kit . android . room . util .* Ċ import Ġio . live kit . android . util . Either Ċ import Ġio . live kit . android . util . de bounce Ċ import Ġkotlinx . coroutines . Coroutine Dispatcher Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Supervisor Job Ċ import Ġorg . webrtc .* Ċ import Ġjavax . inject . Named Ċ Ċ /** Ċ Ġ* Ġ@ suppress Ċ Ġ*/ Ċ internal Ġclass ĠPeer Connection Transport Ċ @ Ass isted Inject Ċ constructor ( ĊĠĠĠ Ġ@ Ass isted Ġconfig : ĠPeer Connection . RTC Configuration , ĊĠĠĠ Ġ@ Ass isted Ġpc Observer : ĠPeer Connection . Observer , ĊĠĠĠ Ġ@ Ass isted Ġprivate Ġval Ġlistener : ĠListener ?, ĊĠĠĠ Ġ@ Named ( Injection Names . DISPATCH ER _ IO ) ĊĠĠĠ Ġprivate Ġval Ġio Dispatcher : ĠCor outine Dispatcher , ĊĠĠĠ Ġconnection Factory : ĠPeer ConnectionFactory Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcoroutine Scope Ġ= ĠCor outine Scope ( io Dispatcher Ġ+ ĠSuper visor Job ()) ĊĠĠĠ Ġinternal Ġval Ġpeer Connection : ĠPeer Connection Ġ= Ġconnection Factory . create Peer Connection ( ĊĠĠĠĠĠĠĠ Ġconfig , ĊĠĠĠĠĠĠĠ Ġpc Observer ĊĠĠĠ Ġ) Ġ?: Ġthrow ĠIllegalStateException (" peer Ġconnection Ġcreation Ġfailed ?") ĊĠĠĠ Ġprivate Ġval Ġpending Candidates Ġ= Ġmutable ListOf < Ice Candidate >() ĊĠĠĠ Ġprivate Ġvar Ġrestart ing Ice : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġvar Ġre neg otiate Ġ= Ġfalse ĊĊĠĠĠ Ġinterface ĠListener Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġon Offer ( sd : ĠSession Description ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Ice Candidate ( candidate : ĠI ce Candidate ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( peer Connection . remote Description Ġ!= Ġnull Ġ&& Ġ! restart ing Ice ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpeer Connection . add Ice Candidate ( candidate ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Candidates . add ( candidate ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġset Remote Description ( sd : ĠSession Description ): ĠEither < Unit , ĠString ?> Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġpeer Connection . set Remote Description ( sd ) ĊĠĠĠĠĠĠĠ Ġif Ġ( result Ġis ĠEither . Left ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Candidates . forEach Ġ{ Ġpending Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeer Connection . add Ice Candidate ( pending ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpending Candidates . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrestart ing Ice Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( this . re neg otiate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . re neg otiate Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . create And Send Offer () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġneg otiate Ġ= Ġdebounce < Unit , ĠUnit >( 1 0 0 , Ġcoroutine Scope ) Ġ{ Ġcreate And Send Offer () Ġ} ĊĠĠĠ Ġsuspend Ġfun Ġcreate And Send Offer ( constraints : ĠMedia Constraints Ġ= ĠMedia Constraints ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( listener Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġice Restart Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconstraints . find Constraint ( Media Constraint Keys . ICE _ RE START ) Ġ== ĠMedia Constraint Keys . TRUE ĊĠĠĠĠĠĠĠ Ġif Ġ( ice Restart ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d Ġ{ Ġ" restart ing Ġice " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrestart ing Ice Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( this . peer Connection . signal ing State () Ġ== ĠPeer Connection . Signal ing State . HAVE _ LOCAL _ OFF ER ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe 're Ġwaiting Ġfor Ġthe Ġpeer Ġto Ġaccept Ġour Ġoffer , Ġso Ġwe 'll Ġjust Ġwait ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġonly Ġexception Ġto Ġthis Ġis Ġwhen ĠI CE Ġrestart Ġis Ġneeded ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcur Sd Ġ= Ġpeer Connection . remote Description ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ice Restart Ġ&& Ġcur Sd Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġhandle Ġwhen ĠI CE Ġrestart Ġis Ġneeded Ġbut Ġwe Ġdon 't Ġhave Ġa Ġremote Ġdescription ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġbest Ġthing Ġto Ġdo Ġis Ġto Ġrecreate Ġthe Ġpeer connection ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeer Connection . set Remote Description ( cur Sd ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre neg otiate Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġactually Ġneg otiate ĊĠĠĠĠĠĠĠ ĠTim ber . d Ġ{ Ġ" starting Ġto Ġneg otiate " Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġs dp Offer Ġ= Ġwhen Ġ( val Ġoutcome Ġ= Ġpeer Connection . create Offer ( constraints )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEither . Left Ġ-> Ġoutcome . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEither . Right Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d Ġ{ Ġ" error Ġcreating Ġoffer : Ġ${ outcome . value }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠTim ber . v Ġ{ Ġ" sdp Ġoffer Ġ= Ġ$ sdp Offer , Ġdescription : Ġ${ sdp Offer . description }, Ġtype : Ġ${ sdp Offer . type }" Ġ} ĊĠĠĠĠĠĠĠ Ġpeer Connection . set Local Description ( sdp Offer ) ĊĠĠĠĠĠĠĠ Ġlistener ?. on Offer ( sdp Offer ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġprepare For Ice Restart () Ġ{ ĊĠĠĠĠĠĠĠ Ġrestart ing Ice Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġpeer Connection . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Ass isted Factory ĊĠĠĠ Ġinterface ĠFactory Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconfig : ĠPeer Connection . RTC Configuration , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpc Observer : ĠPeer Connection . Observer , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlistener : ĠListener ? ĊĠĠĠĠĠĠĠ Ġ): ĠPeer Connection Transport ĊĠĠĠ Ġ} Ċ }