/** Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 ĠSK ĠTele com ĠCo ., ĠLtd . ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* Ġ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 Ġcom . sk t . n ugu . sdk . core . session Ċ Ċ import Ġcom . sk t . n ugu . sdk . core . interfaces . session . Session Manager Interface Ċ import Ġcom . sk t . n ugu . sdk . core . utils . Logger Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . Scheduled Future Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjava . util . concurrent . locks . Re entrant Lock Ċ import Ġkotlin . concurrent . with Lock Ċ Ċ class ĠSession Manager ( private Ġval Ġinactive Timeout In Millis : ĠLong Ġ= ĠDEFAULT _ IN ACTIVE _ TIMEOUT ) Ġ: ĠSession Manager Interface Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Session Manager " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠDEFAULT _ IN ACTIVE _ TIMEOUT Ġ= Ġ 6 0 Ġ* Ġ 1 0 0 0 L Ġ// Ġmillis ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġlock Ġ= ĠRe entrant Lock () ĊĊĠĠĠ Ġprivate Ġval Ġall Sessions Ġ= ĠLinkedHashMap < String , ĠSession Manager Interface . Session >() ĊĠĠĠ Ġprivate Ġval Ġsession Set Time Map Ġ= ĠHashMap < String , ĠLong >() ĊĠĠĠ Ġprivate Ġval Ġactive Sessions Map Ġ= ĠHashMap < String , ĠHashSet < Session Manager Interface . Request er >>() ĊĠĠĠ Ġprivate Ġval Ġlisteners Ġ= ĠLinked HashSet < Session Manager Interface . Listener >() ĊĊĠĠĠ Ġprivate Ġval Ġtimeout Future Map Ġ= ĠConcurrent HashMap < String , ĠScheduled Future <* >>() ĊĠĠĠ Ġprivate Ġval Ġtimeout Scheduler Ġ= ĠExec utors . new Single Thread Scheduled Executor () ĊĊĠĠĠ Ġoverride Ġfun Ġset ( key : ĠString , Ġsession : ĠSession Manager Interface . Session ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ set ] Ġkey : Ġ$ key , Ġsession : Ġ$ session ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġall Sessions [ key ] Ġ= Ġsession ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsession Set Time Map [ key ] Ġ= ĠSystem . currentTimeMillis () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġactivate Ġcalled Ġbefore Ġset , Ġdo Ġnot Ġschedule . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( active Sessions Map . containsKey ( key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Session Activated ( key , Ġsession ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġschedule Timeout ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġschedule Timeout ( key : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ schedule Timeout ] Ġkey : Ġ$ key ") ĊĠĠĠĠĠĠĠ Ġtimeout Future Map . remove ( key )?. cancel ( true ) ĊĠĠĠĠĠĠĠ Ġtimeout Future Map [ key ] Ġ= Ġtimeout Scheduler . schedule ({ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ schedule Timeout ] Ġoccur Ġtimeout Ġkey : Ġ$ key ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Sessions . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsession Set Time Map . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimeout Future Map . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}, Ġinactive Timeout In Millis , ĠTimeUnit . MILLISECONDS ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġactivate ( key : ĠString , Ġrequest er : ĠSession Manager Interface . Request er ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġsync Set Ġ= Ġactive Sessions Map [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( sync Set Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsync Set Ġ= ĠHashSet () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Sessions Map [ key ] Ġ= Ġsync Set ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( sync Set . add ( requester )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimeout Future Map . remove ( key )?. cancel ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ activate ] Ġkey : Ġ$ key , Ġrequest er : Ġ$ requester Ġ=> Ġactivated ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsession Ġ= Ġall Sessions [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( session Ġ!= Ġnull Ġ&& Ġsync Set . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Session Activated ( key , Ġsession ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ activate ] Ġkey : Ġ$ key , Ġrequest er : Ġ$ requester Ġ=> Ġalready Ġactivated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdeactivate ( key : ĠString , Ġrequest er : ĠSession Manager Interface . Request er ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsync Set Ġ= Ġactive Sessions Map [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( sync Set Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ deactivate ] Ġkey : Ġ$ key , Ġrequest er : Ġ$ requester Ġ=> Ġno Ġactive Ġsession ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Lock ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( sync Set . remove ( requester )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ deactivate ] Ġkey : Ġ$ key , Ġrequest er : Ġ$ requester Ġ=> Ġde activated ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( sync Set . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Sessions Map . remove ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġschedule Timeout ( key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ deactivate ] Ġkey : Ġ$ key , Ġsession Ġde activated ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsession Ġ= Ġall Sessions [ key ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( session Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . on Session De activated ( key , Ġsession ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLogger . d ( TAG , Ġ"[ deactivate ] Ġkey : Ġ$ key , Ġrequest er : Ġ$ requester Ġ=> Ġalready Ġde activated ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Active Sessions (): ĠMap < String , ĠSession Manager Interface . Session > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġact ives Ġ= ĠLinkedHashMap < String , ĠSession Manager Interface . Session >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Sessions Map . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Sessions [ it . key ]?. let Ġ{ Ġsession Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( it . key , Ġsession ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠshouldBe Removed Ġ= ĠHashSet < String >() ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġremove Ġduplicated Ġplay Service Id ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHashMap < String , ĠString >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġact ives . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Ġ= Ġget ( it . value . play Service Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcurrentTime Ġ= Ġsession Set Time Map [ current ] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Time Ġ= Ġsession Set Time Map [ it . key ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( current Ġ!= Ġnull Ġ&& ĠcurrentTime Ġ!= Ġnull Ġ&& Ġtarget Time Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( currentTime Ġ< Ġtarget Time ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( it . value . play Service Id , Ġit . key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠshouldBe Removed . add ( current ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠshouldBe Removed . add ( it . key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( it . value . play Service Id , Ġit . key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠshouldBe Removed . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġact ives . remove ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġact ives ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Listener ( listener : ĠSession Manager Interface . Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . add ( listener ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġremove Listener ( listener : ĠSession Manager Interface . Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlock . with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlisteners . remove ( listener ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }