package Ġcom . lo z an ov . vir id um . shared Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Context Wrapper Ċ import Ġandroidx . fragment . app . Fragment Ċ import Ġandroid . net . Connectivity Manager Ċ import Ġandroid . net . Network Capabilities Ċ import Ġandroid . os . Build Ċ import Ġandroid . util . Log Ċ import Ġandroid . view . Key Character Map Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . compose . foundation . layout . Box Ċ import Ġandroidx . compose . foundation . layout . fill MaxSize Ċ import Ġandroidx . compose . material . Snackbar Host Ċ import Ġandroidx . compose . material . Snackbar Host State Ċ import Ġandroidx . compose . runtime . Composable Ċ import Ġandroidx . compose . runtime . State Ċ import Ġandroidx . compose . runtime . remember Ċ import Ġandroidx . compose . runtime . remember Coroutine Scope Ċ import Ġandroidx . compose . ui . Alignment Ċ import Ġandroidx . compose . ui . Modifier Ċ import Ġandroidx . compose . ui . platform . Local Context Ċ import Ġandroidx . lifecycle . Lifecycle Ċ import Ġandroidx . navigation . Nav Back Stack Entry Ċ import Ġcom . google . ar . core . Ar Core A pk Ċ import Ġcom . lo z an ov . vir id um . R Ċ import Ġcom . lo z an ov . vir id um . state . AR Availability State Ċ import Ġkotlinx . coroutines .* Ċ import Ġpub . dev rel . eas yper missions . Easy Permissions Ċ Ċ fun ĠNav Back Stack Entry . lifecycle Is Res umed () Ġ= ĊĠĠĠ Ġthis . lifecycle . currentState Ġ== ĠLifecycle . State . RE SU MED Ċ Ċ fun ĠConnect ivity Manager . isConnected (): ĠBoolean Ġ{ ĊĠĠĠ Ġif ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . M ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Network Capabilities ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Network ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis Ġ!= Ġnull Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Capability ( Network Capabilities . NET _ CAP ABILITY _ INTER NET ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġactive Network Info ?. isConnected Ġ== Ġtrue Ġ// Ġnull Ġsafety Ġrequires Ġexplicit Ġcheck ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠActivity . request Permissions ( var arg Ġperms : ĠString , Ġrequest Code : ĠInt , Ġr ationale : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Permission Granted : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġif ( Easy Permissions . has Permissions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ* perms ĊĠĠĠĠĠĠĠ Ġ)) Ġ{ ĊĠĠĠĠĠĠĠ Ġon Permission Granted () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġshow Permission Dialog (* perms , Ġrequest Code Ġ= Ġrequest Code , Ġr ationale Ġ= Ġr ationale ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠFragment . request Permissions ( var arg Ġperms : ĠString , Ġrequest Code : ĠInt , Ġr ationale : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Permission Granted : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġif ( Easy Permissions . has Permissions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire Context (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ* perms ĊĠĠĠĠĠĠĠ Ġ)) Ġ{ ĊĠĠĠĠĠĠĠ Ġon Permission Granted () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġshow Permission Dialog (* perms , Ġrequest Code Ġ= Ġrequest Code , Ġr ationale Ġ= Ġr ationale ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠFragment . show Permission Dialog ( var arg Ġperms : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , Ġr ationale : ĠString ) Ġ{ ĊĠĠĠ ĠEasy Permissions . request Permissions ( ĊĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠ Ġr ationale , ĊĠĠĠĠĠĠĠ Ġrequest Code , ĊĠĠĠĠĠĠĠ Ġ* perms ĊĠĠĠ Ġ) Ċ } Ċ Ċ private Ġfun ĠActivity . show Permission Dialog ( var arg Ġperms : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Code : ĠInt , Ġr ationale : ĠString ) Ġ{ ĊĠĠĠ ĠEasy Permissions . request Permissions ( ĊĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠ Ġr ationale , ĊĠĠĠĠĠĠĠ Ġrequest Code , ĊĠĠĠĠĠĠĠ Ġ* perms ĊĠĠĠ Ġ) Ċ } Ċ Ċ // ĠTODO : ĠUse Ġin Ġentry Ġof Ġthe Ġapp ? Ċ fun ĠContext . is AR Core Supported And Up ToDate (): ĠAR Availability State Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( Ar Core A pk . getInstance (). check Availability ( this )) Ġ{ ĊĠĠĠĠĠĠĠ ĠAr Core A pk . Availability . SUPPORTED _ INST ALLED Ġ-> ĠAR Availability State . Installed ĊĠĠĠĠĠĠĠ ĠAr Core A pk . Availability . SUPPORTED _ AP K _ TOO _ OLD , ĠAr Core A pk . Availability . SUPPORTED _ NOT _ INST ALLED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRequest ĠAR Core Ġinstallation Ġor Ġupdate Ġif Ġneeded . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( Ar Core A pk . getInstance (). request Install ( getActivity (), Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAr Core A pk . Install Status . INSTALL _ REQUEST ED Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . i (" is AR Core Supported And Up ToDate ", Ġ" AR Core Ġinstallation Ġrequested .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAR Availability State . Not Installed And Should Take Action ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAr Core A pk . Install Status . INST ALLED Ġ-> ĠAR Availability State . Installed ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠKey Character Map . Unavailable Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" is AR Core Supported And Up ToDate ", Ġ" AR Core Ġnot Ġinstalled ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAR Availability State . Not Installed And Should Take Action ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠAr Core A pk . Availability . UNSUPPORTED _ DEVICE _ NOT _ CAP ABLE Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAR Availability State . Device Not Cap able ĊĊĠĠĠĠĠĠĠ ĠAr Core A pk . Availability . UNKNOWN _ CHECK ING Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAR Availability State . Checking ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠAr Core A pk . Availability . UNKNOWN _ ERROR , ĠAr Core A pk . Availability . UNKNOWN _ TIME D _ OUT Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAR Availability State . Error Or Timed Out ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠContext . determine AR Availability ( ĊĠĠĠ Ġasked : ĠState < Boolean >, ĊĠĠĠ Ġerror Sn ackBar Host State : ĠSn ackbar Host State , ĊĠĠĠ Ġcoroutine Scope : ĠCor outine Scope , Ċ ): ĠBoolean Ġ{ ĊĠĠĠ Ġif (! ask ed . value ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen ( is AR Core Supported And Up ToDate ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAR Availability State . Not Installed And Should Take Action Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠPrompt Ġinstall Ġ( prob ably Ġdon 't Ġhave Ġto Ġdo Ġanything ?) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAR Availability State . Device Not Cap able Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠAlertDialog Ġand Ġsuspend Ġapp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAR Availability State . Error Or Timed Out Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerror Sn ackBar Host State . show Snackbar ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġresources . getString ( R . string . error _ ar ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAR Availability State . Checking Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( 2 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetermine AR Availability ( ask ed , Ġerror Sn ackBar Host State , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Scope ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġtrue Ċ } Ċ Ċ interface ĠAR Core Installation Wrapper Scope Ġ{ ĊĠĠĠ Ġval Ġsn ackbar Host State : ĠSn ackbar Host State Ċ } Ċ Ċ @ Composable Ċ fun ĠAR Core Installation Wrapper ( ĊĠĠĠ Ġasked For AR Core Availability : ĠState < Boolean >, ĊĠĠĠ Ġmain Content Alignment : ĠAlignment Ġ= ĠAlignment . Center , ĊĠĠĠ Ġon Installed : Ġ@ Composable ĠAR Core Installation Wrapper Scope . () Ġ-> ĠUnit Ċ ) Ġ{ ĊĠĠĠ Ġval Ġcontext Ġ= ĠLocal Context . current ĊĠĠĠ Ġval Ġcoroutine Scope Ġ= Ġremember Coroutine Scope () ĊĠĠĠ Ġval Ġsn ackbar Host State Ġ= Ġremember Ġ{ ĠSn ackbar Host State () Ġ} ĊĠĠĠ Ġval Ġwrapper Scope Ġ= Ġremember Ġ{ Ġobject Ġ: ĠAR Core Installation Wrapper Scope Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġsn ackbar Host State : ĠSn ackbar Host State ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ= Ġsn ackbar Host State ĊĠĠĠ Ġ} Ġ} ĊĊĠĠĠ Ġ// ĠTODO : ĠPass Ġsn ackbar Ġstate Ġand Ġwhatever Ġelse Ġis Ġneeded Ġdown ĊĠĠĠ Ġif (! context . determine AR Availability ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġasked For AR Core Availability , Ġsn ackbar Host State , Ġcoroutine Scope )) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠBox ( ĊĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . fill MaxSize (), ĊĠĠĠĠĠĠĠ Ġcontent Alignment Ġ= Ġmain Content Alignment ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġon Installed ( p 1 Ġ= Ġwrapper Scope ) ĊĠĠĠĠĠĠĠ ĠSn ackbar Host ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhost State Ġ= Ġsn ackbar Host State , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodifier Ġ= ĠModifier . align ( Alignment . Bottom Center ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠContext . getActivity (): ĠAppCompatActivity ? Ġ{ ĊĠĠĠ Ġvar Ġcurrent Context Ġ= Ġthis ĊĠĠĠ Ġwhile Ġ( current Context Ġis ĠContext Wrapper ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( current Context Ġis ĠAppCompatActivity ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcurrent Context ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Context Ġ= Ġcurrent Context . base Context ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġnull Ċ } Ċ Ċ fun ĠCor outine Scope . nav Pop ( navigator : ĠNavigator , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuntil : ĠNav Destination ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġraw Pop : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Pop : Ġ(() Ġ-> ĠUnit )? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠ Ġnavigator . pop ( raw Pop Ġ= Ġraw Pop , Ġuntil Ġ= Ġuntil ) ĊĠĠĠĠĠĠĠ Ġon Pop ?. invoke () ĊĠĠĠ Ġ} Ċ } Ċ