package Ġdev . k drag 0 n . android 1 2 ext . ui . mon et . quant izer Ċ Ċ import Ġandroid . annotation . Suppress Lint Ċ import Ġandroid . app . Wall paper Colors Ċ import Ġandroid . app . Wall paper Manager Ċ import Ġandroid . content . Context Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . graphics . Rect Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Looper Ċ import Ġandroidx . core . content . getSystem Service Ċ import Ġandroidx . core . graphics . drawable . to Bitmap Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġdagger . h ilt . android . lifecycle . H ilt ViewModel Ċ import Ġdagger . h ilt . android . qual ifiers . ApplicationContext Ċ import Ġdev . k drag 0 n . android 1 2 ext . mon et . extraction . main Colors Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . delay Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . sync . Mutex Ċ import Ġkotlinx . coroutines . sync . with Lock Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġtim ber . log . Tim ber Ċ import Ġjavax . inject . Inject Ċ import Ġkotlin . math . sqrt Ċ Ċ @ H ilt ViewModel Ċ class ĠQuant izer ViewModel Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġ@ ApplicationContext Ġcontext : ĠContext Ċ ) Ġ: ĠViewModel () Ġ{ ĊĠĠĠ Ġprivate Ġval Ġwall paper Manager Ġ= Ġcontext . getSystem Service < Wall paper Manager >() !! ĊĠĠĠ Ġprivate Ġval Ġcolor Scheme Class Ġ= Ġcontext . create Package Context ( ĊĠĠĠĠĠĠĠ Ġ" com . android . system ui ", ĊĠĠĠĠĠĠĠ ĠContext . CONTEXT _ INCLUDE _ CODE Ġor ĠContext . CONTEXT _ IGNORE _ SECURITY , ĊĠĠĠ Ġ). class Loader . let Ġ{ Ġloader Ġ-> ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġloader . load Class (" com . google . material . mon et . Color Scheme ") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠClass NotFoundException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġwall paper Bitmap Ġ= ĠMutable LiveData < Bitmap >() ĊĠĠĠ Ġval Ġwall paper Colors Ġ= ĠMutable LiveData < List < Int >? >( null ) ĊĠĠĠ Ġval Ġimage Rect Ġ= ĠMutable LiveData < Rect ? >( null ) ĊĊĠĠĠ Ġprivate Ġval Ġquant izer Lock Ġ= ĠMutex () ĊĊĠĠĠ Ġ// ĠPermissions Ġare Ġhandled Ġby Ġthe Ġfragment ĊĠĠĠ Ġ@ Suppress Lint (" Missing Permission ") ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġupdate Wall paper ( rect : ĠRect ? Ġ= Ġnull ) Ġ= Ġquant izer Lock . with Lock Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdrawable Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwall paper Manager . drawable ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Lock ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠShow Ġthe Ġwall paper Ġfirst Ġif Ġnot Ġa Ġrect Ġupdate ĊĠĠĠĠĠĠĠ Ġif Ġ( rect Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMake Ġa Ġcopy Ġof Ġthe Ġbitmap Ġbecause ĠSub sampling Scale ImageView Ġassumes Ġownership Ġand Ġre cycles Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġorig Ġ= Ġdrawable . to Bitmap () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwall paper Bitmap . value Ġ= Ġorig . copy ( orig . config , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠQuant ization Ġmay Ġtake Ġa Ġwhile , Ġso Ġshow Ġprogress Ġfirst ĊĠĠĠĠĠĠĠ Ġwall paper Colors . value Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠPre - render Ġbitmap Ġto Ġavoid Ġdist ort ing Ġbenchmark ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġdrawable . to Bitmap (). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġif Ġ( rect Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap . create Bitmap ( it , Ġrect . left , Ġrect . top , Ġrect . width (), Ġrect . height ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠScale Ġwith Ġthe Ġsame Ġlogic Ġas ĠWall paper Colors ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequested Area Ġ= Ġit . width Ġ* Ġit . height ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( requested Area Ġ> ĠMAX _ WALL P AP ER _ EX TR ACTION _ AREA ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġscale Ġ= Ġsqrt ( MAX _ WALL P AP ER _ EX TR ACTION _ AREA . toDouble () Ġ/ Ġrequested Area ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Width Ġ= Ġ( it . width Ġ* Ġscale ). toInt (). coerce At Least ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Height Ġ= Ġ( it . height Ġ* Ġscale ). toInt (). coerce At Least ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBitmap . create Scaled Bitmap ( bitmap , Ġnew Width , Ġnew Height , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbitmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbefore Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcolors Ġ= ĠWall paper Colors . from Bitmap ( bitmap ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġafter Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . i (" Quant ized Ġwall paper Ġin Ġ${ after Ġ- Ġbefore } Ġms . Ġrect =$ rect Ġ- Ġwidth =${ bitmap . width } Ġheight =${ bitmap . height }") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcolor Ints Ġ= Ġif Ġ( color Scheme Class Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompanion Ġ= Ġcolor Scheme Class . getDeclared Field (" Companion "). get ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseed Colors Ġ= Ġcompanion :: class . java ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getDeclared Method (" get Seed Colors ", ĠWall paper Colors :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. invoke ( comp anion , Ġcolors ) Ġas ĠList < Int > ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseed Colors . map Ġ{ Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNot Ġexactly Ġthe Ġsame , Ġbut Ġit 's Ġclose Ġenough Ġfor ĠA O SP ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolors . main Colors . map Ġ{ Ġit . to Argb () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwall paper Colors . post Value ( color Ints ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġreload Wall paper () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Wall paper () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġcolors Changed Listener Ġ= ĠWall paper Manager . On Colors Changed Listener Ġ{ Ġ_, Ġwhich Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( which Ġ!= ĠWall paper Manager . FLAG _ SYSTEM ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ On Colors Changed Listener ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Wall paper () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġrect Observer Ġ= ĠObserver < Rect ?> Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( UPDATE _ RECT _ DE BOUN CE _ DELAY ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( image Rect . value Ġ== Ġit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Wall paper ( rect Ġ= Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Wall paper () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġimage Rect . observe Fore ver ( rect Observer ) ĊĠĠĠĠĠĠĠ Ġwall paper Manager . add On Colors Changed Listener ( colors Changed Listener , ĠHandler ( Looper . get Main Looper ())) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Cle ared () Ġ{ ĊĠĠĠĠĠĠĠ Ġimage Rect . remove Observer ( rect Observer ) ĊĠĠĠĠĠĠĠ Ġwall paper Manager . remove On Colors Changed Listener ( colors Changed Listener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠUPDATE _ RECT _ DE BOUN CE _ DELAY Ġ= Ġ 2 5 0 L ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ WALL P AP ER _ EX TR ACTION _ AREA Ġ= Ġ 1 2 5 4 4 ĊĠĠĠ Ġ} Ċ } Ċ