/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠNew ĠVector ĠLtd Ċ Ġ* Ċ Ġ* Ġ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 Ġim . vector . app . features . notifications Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Handler Thread Ċ import Ġandroidx . annotation . Worker Thread Ċ import Ġim . vector . app . Active Session DataSource Ċ import Ġim . vector . app . Build Config Ċ import Ġim . vector . app . R Ċ import Ġim . vector . app . core . utils . First Th rott ler Ċ import Ġim . vector . app . features . display name . get Best Name Ċ import Ġim . vector . app . features . settings . Vector Preferences Ċ import Ġorg . matrix . android . sdk . api . session . Session Ċ import Ġorg . matrix . android . sdk . api . session . content . Content Url Resolver Ċ import Ġorg . matrix . android . sdk . api . session . getUser Ċ import Ġorg . matrix . android . sdk . api . util . to Matrix Item Ċ import Ġtim ber . log . Tim ber Ċ import Ġjavax . inject . Inject Ċ import Ġjavax . inject . Singleton Ċ Ċ /** Ċ Ġ* ĠThe ĠNotification Drawer Manager Ġreceives Ġnotification Ġevents Ġas Ġthey Ġar rived Ġ( from Ġevent Ġstream Ġor Ġf cm ) Ġand Ċ Ġ* Ġorgan ise Ġthem Ġin Ġorder Ġto Ġdisplay Ġthem Ġin Ġthe Ġnotification Ġdrawer . Ċ Ġ* ĠEvents Ġcan Ġbe Ġgrouped Ġinto Ġthe Ġsame Ġnotification , Ġold Ġ( already Ġread ) Ġevents Ġcan Ġbe Ġremoved Ġto Ġdo Ġsome Ġcleaning . Ċ Ġ*/ Ċ @ Singleton Ċ class ĠNotification Drawer Manager Ġ@ Inject Ġconstructor ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġcontext : ĠContext , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġnotification Dis player : ĠNotification Dis player , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġvector Preferences : ĠVector Preferences , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġactive Session DataSource : ĠActive Session DataSource , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġnot ifiable Event Processor : ĠNot ifiable Event Processor , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġnotification Renderer : ĠNotification Renderer , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġnotification Event Persistence : ĠNotification Event Persistence Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġhandler Thread : ĠHandler Thread Ġ= ĠHandler Thread (" Notification Drawer Manager ", ĠThread . MIN _ PRIORITY ) ĊĠĠĠ Ġprivate Ġvar Ġbackground Handler : ĠHandler ĊĊĠĠĠ Ġ// ĠTODO ĠMulti - session : Ġthis Ġwill Ġhave Ġto Ġbe Ġimproved ĊĠĠĠ Ġprivate Ġval Ġcurrent Session : ĠSession ? ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġactive Session DataSource . current Value ?. or Null () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠL az ily Ġinitializes Ġthe ĠNotification State Ġas Ġwe Ġrely Ġon Ġhaving Ġa Ġcurrent Ġsession Ġin Ġorder Ġto Ġfetch Ġthe Ġpersisted Ġqueue Ġof Ġevents . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġnotification State Ġby Ġlazy Ġ{ Ġcreate Initial Notification State () Ġ} ĊĠĠĠ Ġprivate Ġval Ġavatar Size Ġ= Ġcontext . resources . get Dimension Pixel Size ( R . dim en . profile _ avatar _ size ) ĊĠĠĠ Ġprivate Ġvar Ġcurrent Room Id : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġfirst Th rott ler Ġ= ĠFirst Th rott ler ( 2 0 0 ) ĊĊĠĠĠ Ġprivate Ġvar Ġuse Complete Notification Format Ġ= Ġvector Preferences . use Complete Notification Format () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġhandler Thread . start () ĊĠĠĠĠĠĠĠ Ġbackground Handler Ġ= ĠHandler ( handler Thread . lo oper ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Initial Notification State (): ĠNotification State Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġqueued Events Ġ= Ġnotification Event Persistence . load Events ( current Session , Ġfactory Ġ= Ġ{ Ġraw Events Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNotification EventQueue ( raw Events . to Mutable List (), Ġseen Event Ids Ġ= ĠCircular Cache . create ( cache Size Ġ= Ġ 2 5 )) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġval Ġrendered Events Ġ= Ġqueued Events . raw Events (). map Ġ{ ĠPro cessed Event ( Processed Event . Type . KEEP , Ġit ) Ġ}. to Mutable List () ĊĠĠĠĠĠĠĠ Ġreturn ĠNotification State ( queued Events , Ġrendered Events ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠ ĠShould Ġbe Ġcalled Ġas Ġsoon Ġas Ġa Ġnew Ġevent Ġis Ġready Ġto Ġbe Ġdisplayed . ĊĠĠĠ ĠThe Ġnotification Ġcorresponding Ġto Ġthis Ġevent Ġwill Ġnot Ġbe Ġdisplayed Ġuntil ĊĠĠĠ Ġ# refresh Notification Drawer () Ġis Ġcalled . ĊĠĠĠ ĠEvents Ġmight Ġbe Ġgrouped Ġand Ġthere Ġmight Ġnot Ġbe Ġone Ġnotification Ġper Ġevent ! ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠNotification EventQueue . on Not ifiable Event Received ( not ifiable Event : ĠNot ifiable Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! vector Preferences . are Notification Enabled For Device ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Notification Ġare Ġdisabled Ġfor Ġthis Ġdevice ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġwe Ġsupport Ġmulti Ġsession , Ġevent Ġlist Ġshould Ġbe Ġper ĠuserId ĊĠĠĠĠĠĠĠ Ġ// ĠCurrently Ġonly Ġmanage Ġsingle Ġsession ĊĠĠĠĠĠĠĠ Ġif Ġ( Build Config . LOW _ PRIV ACY _ LOG _ ENABLE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" on Not ifiable Event Received (): Ġ$ not ifiable Event ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" on Not ifiable Event Received (): Ġis Ġpush : Ġ${ not ifiable Event . can Be Re placed }") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġadd ( not ifiable Event ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠClear Ġall Ġknown Ġevents Ġand Ġrefresh Ġthe Ġnotification Ġdrawer . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġclear All Events () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Events Ġ{ Ġit . clear () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠShould Ġbe Ġcalled Ġwhen Ġthe Ġapplication Ġis Ġcurrently Ġopened Ġand Ġshowing Ġtimeline Ġfor Ġthe Ġgiven Ġroom Id . ĊĠĠĠĠ Ġ* ĠUsed Ġto Ġignore Ġevents Ġrelated Ġto Ġthat Ġroom Ġ( no Ġneed Ġto Ġdisplay Ġnotification ) Ġand Ġclean Ġany Ġexisting Ġnotification Ġon Ġthis Ġroom . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun ĠsetCurrent Room ( roomId : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Events Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhas Changed Ġ= Ġroom Id Ġ!= Ġcurrent Room Id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Room Id Ġ= Ġroom Id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Changed Ġ&& Ġroom Id Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . clear Messages For Room ( roomId ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġnotification Style Changed () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Events Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Settings Ġ= Ġvector Preferences . use Complete Notification Format () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( new Settings Ġ!= Ġuse Complete Notification Format ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSettings Ġhas Ġchanged , Ġremove Ġall Ġcurrent Ġnotifications ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotification Dis player . cancel All Notifications () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuse Complete Notification Format Ġ= Ġnew Settings ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Events ( action : ĠNotification Drawer Manager .( Notification EventQueue ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnotification State . update Queued Events ( this ) Ġ{ Ġqueued Events , Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaction ( queued Events ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrefresh Notification Drawer () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrefresh Notification Drawer () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠImplement Ġlast Ġth rott ler ĊĠĠĠĠĠĠĠ Ġval Ġcan Handle Ġ= Ġfirst Th rott ler . can Handle () ĊĠĠĠĠĠĠĠ ĠTim ber . v (" refresh Notification Drawer (), Ġdelay : Ġ${ can Handle . wait Millis ()} Ġms ") ĊĠĠĠĠĠĠĠ Ġbackground Handler . remove Callbacks And Messages ( null ) ĊĊĠĠĠĠĠĠĠ Ġbackground Handler . post Delayed ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrefresh Notification Drawer Bg () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIt Ġcan Ġhappen Ġif Ġfor Ġinstance Ġsession Ġhas Ġbeen Ġdestroyed . ĠIt 's Ġa Ġbit Ġugly Ġto Ġtry Ġcatch Ġlike Ġthis , Ġbut Ġit 's Ġsa fer ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . w ( throwable , Ġ" refresh Notification Drawer Bg Ġfailure ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcan Handle . wait Millis () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprivate Ġfun Ġrefresh Notification Drawer Bg () Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . v (" refresh Notification Drawer Bg () ") ĊĠĠĠĠĠĠĠ Ġval Ġevents To Render Ġ= Ġnotification State . update Queued Events ( this ) Ġ{ Ġqueued Events , Ġrendered Events Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnot ifiable Event Processor . process ( queued Events . raw Events (), Ġcurrent Room Id , Ġrendered Events ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueued Events . clear And Add ( it . only Ke pt Events ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( notification State . has Already Rendered ( events To Render )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Skipping Ġnotification Ġupdate Ġdue Ġto Ġevent Ġlist Ġnot Ġchanging ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotification State . clear And Add Rendered Events ( events To Render ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsession Ġ= Ġcurrent Session Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrender Events ( session , Ġevents To Render ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpersist Events ( session ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpersist Events ( session : ĠSession ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnotification State . queued Events Ġ{ Ġqueued Events Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotification Event Persistence . persist Events ( queued Events , Ġsession ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrender Events ( session : ĠSession , Ġevents To Render : ĠList < Processed Event < Not ifiable Event >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġuser Ġ= Ġsession . getUser ( session . my UserId ) ĊĠĠĠĠĠĠĠ Ġ// Ġmy User DisplayName Ġcannot Ġbe Ġempty Ġelse ĠNotification Compat . Messaging Style () Ġwill Ġcrash ĊĠĠĠĠĠĠĠ Ġval Ġmy User DisplayName Ġ= Ġuser ?. to Matrix Item ()?. get Best Name () Ġ?: Ġsession . my UserId ĊĠĠĠĠĠĠĠ Ġval Ġmy User Avatar Url Ġ= Ġsession . content Url Resolver (). resolve Thumbnail ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Url Ġ= Ġuser ?. avatar Url , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwidth Ġ= Ġavatar Size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġheight Ġ= Ġavatar Size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod Ġ= ĠContent Url Resolver . Thumbnail Method . SCALE ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġnotification Renderer . render ( session . my UserId , Ġmy User DisplayName , Ġmy User Avatar Url , Ġuse Complete Notification Format , Ġevents To Render ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġshould Ignore Message Event In Room ( roomId : ĠString ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcurrent Room Id Ġ!= Ġnull Ġ&& Ġroom Id Ġ== Ġcurrent Room Id ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSUMMARY _ NOTIFICATION _ ID Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠRO OM _ MESSAGES _ NOTIFICATION _ ID Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠRO OM _ EVENT _ NOTIFICATION _ ID Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠRO OM _ INV IT ATION _ NOTIFICATION _ ID Ġ= Ġ 3 ĊĠĠĠ Ġ} Ċ } Ċ