package Ġapp . d apk . st . matrix . device . internal Ċ Ċ import Ġapp . d apk . st . matrix . common .* Ċ import Ġapp . d apk . st . matrix . device . Device Service Ċ import Ġapp . d apk . st . matrix . device . Device Service . One Time Keys . Key . Signed Curve . Ed 2 5 5 1 9 Signature Ċ import Ġapp . d apk . st . matrix . device . Known Device Store Ċ import Ġapp . d apk . st . matrix . device . To Device Payload Ċ import Ġapp . d apk . st . matrix . http . Matrix HttpClient Ċ import Ġkotlinx . serialization . Serial Name Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . json . JsonObject Ċ import Ġkotlinx . serialization . json . Json Primitive Ċ import Ġjava . util .* Ċ Ċ internal Ġclass ĠDefault Device Service ( ĊĠĠĠ Ġprivate Ġval ĠhttpClient : ĠMatrix HttpClient , ĊĠĠĠ Ġprivate Ġval Ġlogger : ĠMatrix Logger , ĊĠĠĠ Ġprivate Ġval Ġknown Device Store : ĠKnown Device Store , Ċ ) Ġ: ĠDevice Service Ġ{ ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġupload One Time Keys ( one Time Keys : ĠDevice Service . One Time Keys ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġjson Crypto Keys Ġ= Ġone Time Keys . keys . associate Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠDevice Service . One Time Keys . Key . Signed Curve Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" signed _ curve 2 5 5 1 9 :${ it . key Id }" Ġto ĠJsonObject ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" key " Ġto ĠJson Primitive ( it . value ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" signatures " Ġto Ġit . signature . toJson () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġkey Request Ġ= ĠUpload Key Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdevice Keys Ġ= Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġone Time Keys Ġ= Ġjson Crypto Keys ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġlogger . matrix Log (" upload ing Ġone Ġtime Ġkeys ") ĊĠĠĠĠĠĠĠ Ġlogger . matrix Log ( json Crypto Keys ) ĊĠĠĠĠĠĠĠ ĠhttpClient . execute ( upload Keys Request ( key Request )). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . matrix Log ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġupload Device Keys ( device Keys : ĠDevice Keys ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . matrix Log (" upload ing Ġdevice Ġkeys ") ĊĠĠĠĠĠĠĠ Ġval Ġkey Request Ġ= ĠUpload Key Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdevice Keys Ġ= Ġdevice Keys , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġone Time Keys Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġlogger . matrix Log ( key Request ) ĊĠĠĠĠĠĠĠ ĠhttpClient . execute ( upload Keys Request ( key Request )). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . matrix Log ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠEd 2 5 5 1 9 Signature . toJson () Ġ= ĠJsonObject ( ĊĠĠĠĠĠĠĠ Ġcontent Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . userId . value Ġto ĠJsonObject ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ed 2 5 5 1 9 :${ this . deviceId . value }" Ġto ĠJson Primitive ( this . value . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfetch Devices ( user Ids : ĠList < UserId >, Ġsync Token : ĠSync Token ?): ĠList < Device Keys > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠQuery Keys Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdevice Keys Ġ= Ġuser Ids . associate With Ġ{ Ġempty List () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtoken Ġ= Ġsync Token ?. value , ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġlogger . crypto (" query ing Ġkeys Ġfor : Ġ$ user Ids ") ĊĠĠĠĠĠĠĠ Ġval Ġapi Response Ġ= ĠhttpClient . execute ( query Keys ( request )) ĊĠĠĠĠĠĠĠ Ġlogger . crypto (" got Ġkeys Ġfor Ġ${ api Response . device Keys . keys }") ĊĊĠĠĠĠĠĠĠ Ġreturn Ġapi Response . device Keys . values . map Ġ{ Ġit . values Ġ}. flatten (). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġknown Device Store . update Devices ( api Response . device Keys ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġclaim Keys ( claims : ĠList < Device Service . Key Claim >): ĠClaim Keys Response Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠClaim Keys Request ( one Time Keys Ġ= Ġclaims . groupBy Ġ{ Ġit . userId Ġ}. map Values Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . value . associate Ġ{ Ġit . deviceId Ġto Ġit . algorithm Name Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġreturn ĠhttpClient . execute ( claim Keys ( request )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsend Room Key To Device ( sessionId : ĠSession Id , Ġmessages : ĠList < Device Service . To Device Message >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġassociate By Ġ= Ġmessages . groupBy Ġ{ Ġit . sender Id Ġ}. map Values Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . value . associate By Ġ{ Ġit . deviceId Ġ}. map Values Ġ{ Ġit . value . encrypted Message Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlogger . crypto (" sending Ġto Ġdevice : Ġ${ associate By . map Ġ{ Ġit . key Ġto Ġit . value . keys Ġ}} ") ĊĊĠĠĠĠĠĠĠ Ġval Ġtxn Id Ġ= ĠUUID . randomUUID (). toString () ĊĠĠĠĠĠĠĠ ĠhttpClient . execute ( send To Device Request ( EventType . ENCRYPT ED , Ġtxn Id , ĠSend To Device Request ( associate By ))) ĊĠĠĠĠĠĠĠ Ġknown Device Store . associate Session ( sessionId , Ġmessages . map Ġ{ Ġit . deviceId Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsend To Device ( eventType : ĠEventType , Ġtransaction Id : ĠString , ĠuserId : ĠUserId , ĠdeviceId : ĠDevice Id , Ġpayload : ĠTo Device Payload ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessages Ġ= Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠuserId Ġto Ġmap Of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠdeviceId Ġto Ġpayload ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ ĠhttpClient . execute ( send To Device Request ( eventType , Ġtransaction Id , ĠSend To Device Request ( messages ))) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġupdate St ale Devices ( user Ids : ĠList < UserId >) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . matrix Log (" devices Ġchanged : Ġ$ user Ids ") ĊĠĠĠĠĠĠĠ Ġknown Device Store . mark Out dated ( user Ids ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġcheck For New Devices ( self : ĠDevice Keys , Ġuser Ids : ĠList < UserId >, Ġid : ĠSession Id ): ĠList < Device Keys > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoutdated Users To Notify Ġ= Ġknown Device Store . maybe Consume Out dated ( user Ids ) ĊĠĠĠĠĠĠĠ Ġlogger . crypto (" found Ġoutdated Ġusers : Ġ$ out dated Users To Notify ") ĊĠĠĠĠĠĠĠ Ġval Ġnot Out dated Ids Ġ= Ġuser Ids . filter Not Ġ{ Ġoutdated Users To Notify . contains ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġknown Keys Ġ= Ġknown Device Store . devices Me gol m Session ( not Out dated Ids , Ġid ) ĊĊĠĠĠĠĠĠĠ Ġval Ġknown Users Ġ= Ġknown Keys . map Ġ{ Ġit . userId Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġusers Without Known Sessions Ġ= Ġnot Out dated Ids Ġ- Ġknown Users . toSet () ĊĠĠĠĠĠĠĠ Ġlogger . crypto (" found Ġusers Ġwithout Ġknown Ġsessions : Ġ$ users Without Known Sessions ") ĊĊĠĠĠĠĠĠĠ Ġval Ġusers ToUpdate Ġ= Ġoutdated Users To Notify Ġ+ Ġusers Without Known Sessions ĊĠĠĠĠĠĠĠ Ġval Ġnew Devices Ġ= Ġif Ġ( users ToUpdate . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfetch Devices ( users ToUpdate , Ġsync Token Ġ= Ġnull ). filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . deviceId Ġ!= Ġself . deviceId ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . crypto (" did n 't Ġfind Ġany Ġnew Ġdevices ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġempty List () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnew Devices ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġensure Device ( userId : ĠUserId , ĠdeviceId : ĠDevice Id ): ĠDevice Keys Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġknown Device Store . device ( userId , ĠdeviceId ) Ġ?: Ġfetch Devices ( listOf ( userId ), Ġsync Token Ġ= Ġnull ). first () ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Serializable Ċ sealed Ġclass ĠApi Message Ġ{ ĊĊĠĠĠ Ġ@ Serializable ĊĠĠĠ Ġ@ Serial Name (" text _ message ") ĊĠĠĠ Ġdata Ġclass ĠText Message ( ĊĠĠĠĠĠĠĠ Ġ@ Serial Name (" content ") Ġval Ġcontent : ĠText Content , ĊĠĠĠĠĠĠĠ Ġ@ Serial Name (" room _ id ") Ġval Ġroom Id : ĠRoom Id , ĊĠĠĠĠĠĠĠ Ġ@ Serial Name (" type ") Ġval Ġtype : ĠString , ĊĠĠĠ Ġ) Ġ: ĠApi Message () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ@ Serializable ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠText Content ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Serial Name (" body ") Ġval Ġbody : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Serial Name (" msg type ") Ġval Ġtype : ĠString Ġ= ĠMessageType . TEXT . value , ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ Ċ } Ċ