/* Ċ Ċ Copyright Ġ 2 0 1 9 ĠSpl endo ĠConsult ing ĠB . V . ĠThe ĠNe therlands ĊĊĠĠ Ġ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 . spl endo . kal uga . permissions Ċ Ċ import Ġcom . spl endo . kal uga . base . flow . Special Flow Value Ċ import Ġcom . spl endo . kal uga . state . Col d State Flow Repo Ċ import Ġcom . spl endo . kal uga . state . State Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlin . coroutines . Coroutine Context Ċ Ċ /** Ċ Ġ* ĠState Ġof Ġa Ġ[ Permission ] Ċ Ġ*/ Ċ sealed Ġclass ĠPermission State < P Ġ: ĠPermission > Ġ: ĠState () Ġ{ ĊĊĠĠĠ Ġclass ĠUnknown < P Ġ: ĠPermission > Ġ: ĠPermission State < P >(), ĠSpecial Flow Value . Not Important ĊĊĠĠĠ Ġ// ĠTODO : Ġconsider Ġbelow Ġstates Ġcould Ġbe Ġwrapped Ġin Ġa Ġsealed ĠKnown , Ġand ĠFlow s Ġcould Ġexpose ĠPermission State . Known Ġwhere Ġapplicable ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġin Ġthis Ġstate Ġthe Ġ[ Permission ] Ġhas Ġbeen Ġgranted ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġclass ĠAllowed < P Ġ: ĠPermission > Ġ: ĠPermission State < P >() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġdeny ( locked : ĠBoolean ): ĠDen ied < P > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( locked ) ĠDen ied . Locked () Ġelse ĠDen ied . Request able () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġin Ġthis Ġstate Ġthe Ġ[ Permission ] Ġis Ġdenied . ĠIf Ġcan Ġeither Ġbe Ġrequest able Ġof Ġblocked Ġfrom Ġrequest . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsealed Ġclass ĠDen ied < P Ġ: ĠPermission > Ġ: ĠPermission State < P >() Ġ{ ĊĊĠĠĠĠĠĠĠ Ġinternal Ġval Ġallow : Ġsuspend Ġ() Ġ-> ĠAllowed < P > Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAllowed () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWhen Ġin Ġthis Ġstate Ġthe Ġ[ Permission ] Ġis Ġdenied Ġand Ġcannot Ġbe Ġrequested ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġclass ĠLocked < P Ġ: ĠPermission >() Ġ: ĠDen ied < P >() Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġinternal Ġval Ġunlock : Ġsuspend Ġ() Ġ-> ĠRequest able < P > Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRequest able () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠWhen Ġin Ġthis Ġstate Ġthe Ġ[ Permission ] Ġis Ġdenied Ġbut Ġcan Ġbe Ġrequested . ĠUse Ġ[ request ] Ġto Ġrequest Ġthe Ġpermission . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġclass ĠRequest able < P Ġ: ĠPermission > Ġ: ĠDen ied < P >() Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuspend Ġfun Ġrequest ( permission Manager : ĠPermission Manager < out ĠPermission >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpermission Manager . request Permission () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġinternal Ġval Ġlock : Ġsuspend Ġ() Ġ-> ĠLocked < P > Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocked () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠState Ġmachine Ġfor Ġmanaging Ġa Ġgiven Ġ[ Permission ]. Ċ Ġ* ĠSince Ġthis Ġis Ġa Ġ[ Col d State Flow Repo ], Ġit Ġwill Ġonly Ġmonitor Ġfor Ġchanges Ġto Ġpermissions Ġwhile Ġbeing Ġobserved . Ċ Ġ* Ġ@ param Ġmonitoring Interval ĠThe Ġinterval Ġin Ġmilliseconds Ġbetween Ġchecking Ġfor Ġa Ġchange Ġin Ġ[ Permission State ] Ċ Ġ*/ Ċ abstract Ġclass ĠPermission State Repo < P Ġ: ĠPermission >( ĊĠĠĠ Ġprivate Ġval Ġmonitoring Interval : ĠLong Ġ= Ġdefault Monitoring Interval , ĊĠĠĠ Ġcoroutine Context : ĠCor outine Context Ġ= ĠDispatch ers . Main . immediate Ċ ) Ġ: ĠC old State Flow Repo < Permission State < P >>( ĊĠĠĠ Ġcoroutine Context , ĊĠĠĠ Ġinit Change State With Repo Ġ= Ġ{ Ġstate , Ġrepo Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġpm Ġ= Ġ( repo Ġas ĠPermission State Repo < P >). permission Manager ĊĠĠĠĠĠĠĠ Ġpm . start Monitoring ( monitoring Interval ) ĊĠĠĠĠĠĠĠ Ġif Ġ( state Ġ== Ġnull Ġ|| Ġstate Ġis ĠPermission State . Unknown < P >) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuspend Ġ{ Ġpm . initialize State () Ġ} ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuspend Ġ{ Ġstate Ġ} ĊĠĠĠ Ġ}, ĊĠĠĠ Ġde init Change State With Repo Ġ= Ġ{ Ġstate , Ġrepo Ġ-> ĊĠĠĠĠĠĠĠ Ġ( repo Ġas ĠPermission State Repo < P >). permission Manager . stop Monitoring () Ġ// ĠTODO : Ġcould Ġalso Ġbe Ġreplaced Ġby Ġa Ġstate ĊĠĠĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ}, ĊĠĠĠ Ġfirst State Ġ= Ġ{ ĠPermission State . Unknown () Ġ} Ċ ) Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval Ġdefault Monitoring Interval : ĠLong Ġ= Ġ 1 0 0 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO Ġmove Ġto Ġconstructor , Ġso Ġno Ġexplicit Ġcast Ġis Ġneeded Ġin Ġinit Ġblock ĊĠĠĠ Ġabstract Ġval Ġpermission Manager : ĠPermission Manager < P > Ċ } Ċ