// ĠFor Ġtesting Ġpurposes Ġyou Ġmay Ġneed Ġto Ġretrieve Ġdata Ġfrom Ġthis Ġencrypted ĠRel m . io Ġdatabase Ċ // ĠDirection s Ġon Ġhow Ġto Ġexport Ġthe Ġencryption Ġkey Ġand Ġuse Ġit Ġto Ġopen Ġthe Ġdatabase Ġfile : Ċ // Ġhttps :// path check . atlassian . net / wiki / spaces / TEST / pages / 5 0 8 2 4 8 7 9 / Secure + Storage + Testing Ċ // Ġ- or - Ċ // Ġhttps :// gist . github . com / tro ach - sf / f 2 5 7 bb 7 b 8 0 e 6 dddd 4 f 3 b ade 8 1 b 7 b 1 4 1 0 ĊĊ Ċ package Ġorg . path check . cov ids af ep ath s . storage Ċ Ċ import Ġandroid . util . Base 6 4 Ċ import Ġandroid . util . Log Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġcom . bot t ler ocket stud ios . vault . Shared Preference Vault Ċ import Ġcom . bot t ler ocket stud ios . vault . Shared Preference Vault Factory Ċ import Ġcom . facebook . react . bridge . Promise Ċ import Ġcom . facebook . react . bridge . Readable Array Ċ import Ġcom . facebook . react . bridge . Writable Native Array Ċ import Ġcom . mar ian hello . bg loc . data . Background Location Ċ import Ġio . realm . Realm Ċ import Ġio . realm . Realm Configuration Ċ import Ġio . realm . Sort . ASC ENDING Ċ import Ġio . realm . Sort . DESC ENDING Ċ import Ġio . realm . kotlin . where Ċ import Ġorg . path check . cov ids af ep ath s . Main Application Ċ import Ġorg . path check . cov ids af ep ath s . storage . Location . Companion . are Locations Near by Ċ import Ġorg . path check . cov ids af ep ath s . storage . Location . Companion . create Ass umed Location Ċ import Ġorg . path check . cov ids af ep ath s . util . getC utoff Timestamp Ċ import Ġjava . security . Secure Random Ċ import Ġjava . util . UUID Ċ Ċ class ĠRealm Secure Storage ( in Memory : ĠBoolean ?) Ġ{ ĊĠ Ġconstructor (): Ġthis ( false ) ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Realm Secure Storage " ĊĠĠĠ Ġprivate Ġconst Ġval ĠMIN IMUM _ TIME _ INTERVAL Ġ= Ġ 6 0 0 0 0 Ġ* Ġ 4 ĊĠĠĠ Ġconst Ġval ĠLOC ATION _ INTERVAL : ĠLong Ġ= Ġ 6 0 0 0 0 Ġ* Ġ 5 ĊĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ BACK FILL _ TIME Ġ= Ġ 6 0 0 0 0 Ġ* Ġ 6 0 Ġ* Ġ 2 4 ĊĠĠĠ Ġprivate Ġconst Ġval ĠDAY S _ TO _ KEEP Ġ= Ġ 1 4 ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠMAN U ALLY _ KEY ED _ PRE F _ FILE _ NAME Ġ= Ġ" saf ep ath s _ enc _ prefs " ĊĠĠĠ Ġprivate Ġconst Ġval ĠMAN U ALLY _ KEY ED _ KEY _ FILE _ NAME Ġ= Ġ" saf ep ath s _ enc _ key " ĊĠĠĠ Ġprivate Ġconst Ġval ĠMAN U ALLY _ KEY ED _ KEY _ ALIAS Ġ= Ġ" saf ep ath s " ĊĠĠĠ Ġprivate Ġconst Ġval ĠMAN U ALLY _ KEY ED _ KEY _ INDEX Ġ= Ġ 2 ĊĠĠĠ Ġprivate Ġconst Ġval ĠMAN U ALLY _ KEY ED _ PRE SHARED _ SECRET Ġ= Ġ"" Ġ// ĠThis Ġwill Ġnot Ġbe Ġused Ġas Ġwe Ġdo Ġnot Ġsupport Ġ< Ġ 1 8 ĊĠĠĠ Ġprivate Ġconst Ġval ĠKEY _ REAL M _ ENCRYPT ION _ KEY Ġ= Ġ" KEY _ REAL M _ ENCRYPT ION _ KEY " ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġrealm Config : ĠRealm Configuration ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġval Ġencryption Key Ġ= Ġget Encryption Key () ĊĊĠĠĠ Ġval Ġbuilder Ġ= ĠRealm Configuration . Builder () ĊĠĠĠĠĠĠĠ Ġ. encryption Key ( encryption Key ) ĊĠĠĠĠĠĠĠ Ġ. add Module ( Safe Paths Realm Module ()) ĊĊĠĠĠ Ġif Ġ( in Memory Ġ!= Ġnull Ġ&& Ġin Memory ) Ġ{ ĊĠĠĠĠĠ Ġbuilder . name ( UUID . randomUUID (). toString ()). in Memory () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġbuilder . name (" saf ep ath s . realm ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrealm Config Ġ= Ġbuilder . build () ĊĠ Ġ} ĊĊĠ Ġfun Ġsave Device Location ( background Location : ĠBackground Location ) Ġ{ ĊĠĠĠ Ġval Ġrealm Ġ= Ġget Realm Instance () ĊĊĠĠĠ Ġrealm . execute Transaction Ġ{ ĊĠĠĠĠĠ Ġval Ġrealm Result Ġ= Ġit . where < Location >() ĊĠĠĠĠĠĠĠĠĠ Ġ. equalTo ( Location . KEY _ SOURCE , ĠLocation . SOURCE _ DEVICE ) ĊĠĠĠĠĠĠĠĠĠ Ġ. sort ( Location . KEY _ TIME , ĠDESC ENDING ) ĊĠĠĠĠĠĠĠĠĠ Ġ. limit ( 1 ) ĊĠĠĠĠĠĠĠĠĠ Ġ. findAll () ĊĊĠĠĠĠĠ Ġval Ġprevious Location Ġ= Ġrealm Result . get OrNull ( 0 ) ĊĠĠĠĠĠ Ġval Ġprevious Time Ġ= Ġprevious Location ?. time Ġ?: Ġ 0 ĊĠĠĠĠĠ Ġif Ġ( background Location . time Ġ- Ġprevious Time Ġ> ĠMIN IMUM _ TIME _ INTERVAL ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġassumed Locations Ġ= Ġcreate Ass umed Locations ( previous Location , Ġbackground Location ) ĊĠĠĠĠĠĠĠ Ġif Ġ( ass umed Locations . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Inser ting Ġ${ ass umed Locations . size } Ġassumed Ġlocations ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġit . insert ( ass umed Locations ) ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Inser ting ĠNew ĠLocation ") ĊĠĠĠĠĠĠĠ Ġit . insert ( Location . from Background Location ( background Location )) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Ign oring Ġsave . ĠMinimum Ġtime Ġthreshold Ġnot Ġexceeded ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrealm . close () ĊĠ Ġ} ĊĊĠ Ġfun Ġimport Locations ( locations : ĠRead able Array , Ġsource : ĠInt , Ġpromise : ĠPromise ) Ġ{ ĊĠĠĠ Ġval Ġrealm Ġ= Ġget Realm Instance () ĊĊĠĠĠ Ġval Ġlocations To Insert Ġ= Ġmutable ListOf < Location >() ĊĠĠĠ Ġrealm . execute Transaction Ġ{ ĊĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġlocations . size ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġmap Ġ= Ġlocations . getMap ( i ) ĊĠĠĠĠĠĠĠĠĠ ĠLocation . from Import Location ( map , Ġsource )?. let Ġ{ Ġlocation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( location . time Ġ>= ĠgetC utoff Timestamp ( DAYS _ TO _ KEEP )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocations To Insert . add ( location ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġpossible Ġreact Ġtype - safe Ġissues Ġhere ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġit . insert OrUpdate ( locations To Insert ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrealm . close () ĊĠĠĠ Ġpromise . resolve ( true ) ĊĠ Ġ} ĊĊĠ Ġfun Ġtrim Locations () Ġ{ ĊĠĠĠ Ġval Ġrealm Ġ= Ġget Realm Instance () ĊĊĠĠĠ Ġrealm . execute Transaction Ġ{ ĊĠĠĠĠĠ Ġrealm . where < Location >() ĊĠĠĠĠĠĠĠĠĠ Ġ. less Than ( Location . KEY _ TIME , ĠgetC utoff Timestamp ( DAYS _ TO _ KEEP )) ĊĠĠĠĠĠĠĠĠĠ Ġ. findAll () ĊĠĠĠĠĠĠĠĠĠ Ġ. delete All From Realm () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrealm . close () ĊĠ Ġ} ĊĊĠ Ġfun Ġget Locations ( promise : ĠPromise ) Ġ{ ĊĠĠĠ Ġval Ġrealm Ġ= Ġget Realm Instance () ĊĊĠĠĠ Ġval Ġdevice Results Ġ= Ġrealm . where < Location >() ĊĠĠĠĠĠĠĠ Ġ. greater Than OrEqualTo ( Location . KEY _ TIME , ĠgetC utoff Timestamp ( DAYS _ TO _ KEEP )) ĊĠĠĠĠĠĠĠ Ġ. sort ( Location . KEY _ TIME , ĠASC ENDING ) ĊĠĠĠĠĠĠĠ Ġ. findAll () ĊĊĠĠĠ Ġval Ġwrite able Array Ġ= ĠWrit able Native Array () ĊĠĠĠ Ġdevice Results . map Ġ{ ĊĠĠĠĠĠ Ġwrite able Array . push Map ( it . to Writable Map ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġpromise . resolve ( write able Array ) ĊĠĠĠ Ġrealm . close () ĊĠ Ġ} ĊĊĠ Ġfun Ġcreate Ass umed Locations ( previous Location : ĠLocation ?, Ġnew Location : ĠBackground Location ): ĠList < Location > Ġ{ ĊĠĠĠ Ġval Ġassumed Locations To Insert Ġ= Ġmutable ListOf < Location >() ĊĠĠĠ Ġprevious Location ?. let Ġ{ Ġprevious Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġval Ġis Near by Previous Ġ= Ġare Locations Near by ( previous . latitude , Ġprevious . longitude , Ġnew Location . latitude , Ġnew Location . longitude ) ĊĠĠĠĠĠĠĠĠĠ Ġval Ġis Time Within Threshold Ġ= Ġnew Location . time Ġ- Ġprevious . time Ġ<= ĠMAX _ BACK FILL _ TIME ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Near by Previous Ġ&& Ġis Time Within Threshold ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Timestamp Ġ= Ġnew Location . time ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlatest Desired Back fill Ġ= Ġnew Timestamp Ġ- ĠLOC ATION _ INTERVAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġear liest Desired Back fill Ġ= ĠMath . max ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Location . time Ġ- ĠMAX _ BACK FILL _ TIME , Ġprevious . time Ġ+ ĠLOC ATION _ INTERVAL ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( time Ġin Ġlatest Desired Back fill Ġdown To Ġear liest Desired Back fill Ġstep ĠLOC ATION _ INTERVAL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassumed Locations To Insert . add ( create Ass umed Location ( time , Ġprevious . latitude , Ġprevious . longitude )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ}} ĊĠĠĠ Ġreturn Ġassumed Locations To Insert ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġget Encryption Key (): ĠByteArray Ġ{ ĊĠĠĠ Ġval Ġvault : ĠShared Preference Vault Ġ= ĊĠĠĠĠĠ ĠShared Preference Vault Factory . getApp Key ed Compat Aes 2 5 6 Vault ( ĊĠĠĠĠĠĠĠĠĠ ĠMain Application . getContext (), ĠMAN U ALLY _ KEY ED _ PRE F _ FILE _ NAME , ĊĠĠĠĠĠĠĠĠĠ ĠMAN U ALLY _ KEY ED _ KEY _ FILE _ NAME , ĊĠĠĠĠĠĠĠĠĠ ĠMAN U ALLY _ KEY ED _ KEY _ ALIAS , ĠMAN U ALLY _ KEY ED _ KEY _ INDEX , ĊĠĠĠĠĠĠĠĠĠ ĠMAN U ALLY _ KEY ED _ PRE SHARED _ SECRET ĊĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġval Ġexisting Key String Ġ= Ġvault . getString ( KEY _ REAL M _ ENCRYPT ION _ KEY , Ġnull ) ĊĊĠĠĠ Ġreturn Ġif Ġ( existing Key String Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ ĠBase 6 4 . decode ( existing Key String , ĠBase 6 4 . DEFAULT ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġval Ġnew Key Ġ= ĠByteArray ( 6 4 ) ĊĠĠĠĠĠ ĠSecure Random (). next Bytes ( new Key ) ĊĠĠĠĠĠ Ġval Ġnew Key String Ġ= ĠBase 6 4 . encode ToString ( new Key , ĠBase 6 4 . DEFAULT ) ĊĠĠĠĠĠ Ġvault . edit (). putString ( KEY _ REAL M _ ENCRYPT ION _ KEY , Ġnew Key String ). apply () ĊĠĠĠĠĠ Ġnew Key ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ@ Visible ForTesting ĊĠ Ġfun Ġget Realm Instance (): ĠRealm Ġ{ ĊĠĠĠ Ġreturn ĠRealm . getInstance ( realm Config ) ĊĠ Ġ} Ċ } Ċ