/* Ċ Copyright Ġ 2 0 2 0 ĠRe think DNS Ġand Ġits Ġauthors Ċ Ċ 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 Ċ Ċ https :// 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 . cel zero . br aved ns . ui Ċ Ċ import Ġandroid . app . Dialog Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . Count Down Timer Ċ import Ġandroid . util . Log Ċ import Ġandroid . view . View Ċ import Ġandroid . view . Window Ċ import Ġandroid . view . WindowManager Ċ import Ġandroid . widget . Compound Button Ċ import Ġandroidx . appcompat . widget . Search View Ċ import Ġandroidx . recyclerview . widget . Linear LayoutManager Ċ import Ġandroidx . recyclerview . widget . RecyclerView Ċ import Ġcom . cel zero . br aved ns . R Ċ import Ġcom . cel zero . br aved ns . database . App Info Repository Ċ import Ġcom . cel zero . br aved ns . database . App Info View Repository Ċ import Ġcom . cel zero . br aved ns . database . Category Info Repository Ċ import Ġcom . cel zero . br aved ns . databinding . Exclude App Dialog Layout Binding Ċ import Ġcom . cel zero . br aved ns . service . Persistent State Ċ import Ġcom . cel zero . br aved ns . ui . Home Screen Activity . Global Variable . DEBUG Ċ import Ġcom . cel zero . br aved ns . util . Constants . Companion . LOG _ TAG Ċ import Ġcom . cel zero . br aved ns . view model . Excluded App ViewModel Ċ import Ġcom . google . android . material . chip . Chip Ċ import Ġjava . util . stream . Collectors Ċ Ċ class ĠExclude App Dialog ( private Ġvar Ġactivity : ĠContext , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġapp Info Repository : ĠApp Info Repository , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġapp Info View Repository : ĠApp Info View Repository , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġcategory Info Repository : ĠCategory Info Repository , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġpersistent State : ĠPersistent State , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinternal Ġvar Ġadapter : ĠRecyclerView . Adapter <* >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar ĠviewModel : ĠExclude d App ViewModel , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtheme ID Ġ: Int ) ĊĠĠĠ Ġ: ĠDialog ( activity , Ġtheme ID ), ĠView . OnClickListener , ĠSearch View . On Query Text Listener Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġb : ĠExclude App Dialog Layout Binding ĊĊĠĠĠ Ġprivate Ġvar Ġm LayoutManager : ĠRecyclerView . LayoutManager ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġfilter Categories : ĠMutable List < String > Ġ= ĠArrayList () ĊĠĠĠ Ġprivate Ġvar Ġcategory : ĠList < String > Ġ= ĠArrayList () ĊĊĠĠĠ Ġvar Ġfilter State : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĊĠĠĠĠĠĠĠ Ġrequest Window Feature ( Window . FEATURE _ NO _ TITLE ) ĊĠĠĠĠĠĠĠ Ġb Ġ= ĠExclude App Dialog Layout Binding . inflate ( layout Inflater ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( b . root ) ĊĠĠĠĠĠĠĠ Ġset Cancel able ( false ) ĊĊĠĠĠĠĠĠĠ Ġwindow ?. setLayout ( WindowManager . LayoutParams . MATCH _ PARENT , ĠWindow Manager . LayoutParams . MATCH _ PARENT ) ĊĊĠĠĠĠĠĠĠ Ġm LayoutManager Ġ= ĠLinearLayoutManager ( activity ) ĊĊĠĠĠĠĠĠĠ Ġb . exclude App RecyclerView Dialog . layout Manager Ġ= Ġm LayoutManager ĊĠĠĠĠĠĠĠ Ġb . exclude App RecyclerView Dialog . adapter Ġ= Ġadapter ĊĊĠĠĠĠĠĠĠ Ġb . exclude App Dialog Ok Button . setOnClickListener ( this ) ĊĊĠĠĠĠĠĠĠ Ġb . exclude App Dialog Whitelist Search View . setOn Query Text Listener ( this ) ĊĠĠĠĠĠĠĠ Ġb . exclude App Dialog Whitelist Search View . setOn Search ClickListener ( this ) ĊĊĠĠĠĠĠĠĠ Ġb . exclude App Dialog Whitelist Search View . setOn Close Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Category Chips () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġapp Count Ġ= ĠHome Screen Activity . Global Variable . app List . size ĊĠĠĠĠĠĠĠ Ġval Ġact : ĠHome Screen Activity Ġ= Ġactivity Ġas ĠHome Screen Activity ĊĠĠĠĠĠĠĠ Ġapp Info View Repository . get Excluded App List Count LiveData (). observe ( act , Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . exclude App Select Count Text . text Ġ= Ġact . getString ( R . string . ex _ dialog _ count , Ġit . toString (), Ġapp Count . toString ()) ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĊĠĠĠĠĠĠĠ Ġb . exclude App Select All Option Checkbox . setOn Checked ChangeListener Ġ{ Ġ_: ĠCompound Button , Ġb : ĠBoolean Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodify Apps In Excluded App List ( b ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠCount Down Timer ( 1 0 0 0 , Ġ 1 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Tick ( millis Until Finished : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Finish () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadapter . notify DataSet Changed () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. start () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġb . exclude App Dialog Whitelist Search Filter . setOnClickListener ( this ) ĊĊĠĠĠĠĠĠĠ Ġcategory ListBy AppName From DB ("") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmodify Apps In Excluded App List ( checked : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( filter Categories . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Info Repository . update Excluded ForAll App ( checked ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Info Repository . update Excluded Count ForAll App ( checked ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( checked ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Info Repository . update Whitelist Count ForAll (! checked ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Info Repository . update Excluded For Categories ( it , Ġchecked ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Info Repository . update Excluded Count For Category ( it , Ġchecked ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( checked ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Info Repository . update Whitelist For Category ( it , Ġ! checked ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġcategory ListBy AppName From DB ( name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcategory Ġ= Ġapp Info Repository . getApp Category For AppName ("% $ name % ") ĊĠĠĠĠĠĠĠ Ġif Ġ( DEBUG ) ĠLog . d ( LOG _ TAG , Ġ" Category Ġ- Ġ${ category . size }") ĊĠĠĠĠĠĠĠ Ġset Category Chips ( category ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonClick ( v : ĠView ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( v . id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . exclude _ app _ dialog _ ok _ button Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapply Changes () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . set Filter ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdismiss () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . exclude _ app _ dialog _ whitelist _ search _ filter Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Category Chips () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . exclude _ app _ dialog _ whitelist _ search _ view Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Category Chips () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . set Filter ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdismiss () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġapply Changes () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexcluded Apps Ġ= Ġapp Info Repository . get Excluded App List () ĊĠĠĠĠĠĠĠ Ġpersistent State . excluded Apps From VPN Ġ= Ġexcluded Apps . to Mutable Set () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Category Chips () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! filter State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfilter State Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . exclude App Dialog Chip Group . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfilter State Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . exclude App Dialog Chip Group . visibility Ġ= ĠView . GONE ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Query Text Submit ( query : ĠString ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġcategory ListBy AppName From DB ( query !! ) ĊĠĠĠĠĠĠĠ ĠviewModel . set Filter ( query ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Query Text Change ( query : ĠString ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġcategory ListBy AppName From DB ( query !! ) ĊĠĠĠĠĠĠĠ ĠviewModel . set Filter ( query ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Category Chips ( categories : ĠList < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġb . exclude App Dialog Chip Group . removeAll Views () ĊĠĠĠĠĠĠĠ Ġfor Ġ( category Ġin Ġcategories ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Chip Ġ= Ġthis . layout Inflater . inflate ( R . layout . item _ chip _ category , Ġnull , Ġfalse ) Ġas ĠCh ip ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Chip . text Ġ= Ġcategory ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Chip . setOn Checked ChangeListener Ġ{ Ġcompound Button : ĠCompound Button , Ġb : ĠBoolean Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcategory Name Ġ= Ġcompound Button . text . toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( b ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . add ( category Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filter Categories . contains ( category Name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . remove ( category Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfilter String Ġ= Ġif Ġ( android . os . Build . VERSION . SDK _ INT Ġ>= Ġandroid . os . Build . VERSION _ CODES . N ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . stream (). collect ( Collectors . join ing ("," )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġcat Title Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfilter Categories . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcat Title Ġ= Ġ"$ it ,$ cat Title " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cat Title . length Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcat Title . substring ( 0 , Ġcat Title . length Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcat Title ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( filter String . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . set Filter (" category :$ filter String ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . set Filter ("") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb . exclude App Dialog Chip Group . addView ( m Chip ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊ Ċ }