Skip to content

Commit 7ec6773

Browse files
Merge pull request #5466 from simpledotorg/master
2 parents 765dc2b + 8fd8af2 commit 7ec6773

File tree

20 files changed

+185
-313
lines changed

20 files changed

+185
-313
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
- Migrate assigned facility view to Jetpack Compose
1818
- Migrate next appointment view to Jetpack Compose
1919
- Migrate patient status view to Jetpack Compose
20+
- Migrate clinical decision support alert to Jetpack Compose
21+
- Bump sqlite-android version to 3.49.0
22+
- Replace `android-database-sqlcipher` library with `sqlcipher-android`
23+
- Replace Flipper with Chucker for network inspection
2024

2125
## 2025.05.20
2226

README.md

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -163,22 +163,6 @@ There are currently 2 ways to build an app pointing to different environments:
163163
Simple Server is in a separate repository, and you should follow
164164
the [instructions there](https://github.com/simpledotorg/simple-server/blob/master/README.md).
165165

166-
## Execute SQL Queries
167-
168-
You can use [Flipper](https://fbflipper.com/) to run SQL queries on Simple:
169-
170-
1. Install Flipper using brew or download from their [website](https://fbflipper.com/).
171-
172-
```sh
173-
brew install Flipper
174-
```
175-
176-
2. Launch Flipper (you might have to allow Flipper to launch from System Preferences > Security > General as it’s from an unknown developer to Apple).
177-
3. Run the Simple app in an emulator or your physical device(as Flipper loads the data from your device's local database).
178-
4. In the Plugins section in the sidebar menu click on Disabled and enable the Database plugin.
179-
5. Click on Databases, select `red-db` and choose whichever table’s data you want to inspect.
180-
6. Click on SQL at the top to execute SQL queries.
181-
182166
## Resources
183167

184168
Check out the following documents for more information.

app/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,8 @@ dependencies {
285285
* Debug dependencies
286286
*/
287287
debugImplementation(libs.faker)
288-
debugImplementation(libs.bundles.flipper)
289288
debugImplementation(libs.leakcanary)
290-
debugImplementation(libs.soloader)
289+
debugImplementation(libs.chucker)
291290

292291
/**
293292
* Prod dependencies
@@ -476,6 +475,8 @@ dependencies {
476475
runtimeOnly(libs.jackson.core)
477476

478477
androidTestImplementation(libs.apache.commons.math)
478+
479+
releaseImplementation(libs.chucker.no.op)
479480
}
480481

481482
tasks.withType<Test> {

app/src/androidTest/java/org/simple/clinic/storage/DatabaseEncryptorTest.kt

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import android.app.Application
44
import androidx.room.Room
55
import com.google.common.truth.Truth.assertThat
66
import com.squareup.moshi.Moshi
7-
import net.sqlcipher.database.SupportFactory
7+
import net.zetetic.database.sqlcipher.SupportOpenHelperFactory
88
import org.junit.After
99
import org.junit.Before
1010
import org.junit.Test
1111
import org.simple.clinic.AppDatabase
1212
import org.simple.clinic.FakeMinimumMemoryChecker
1313
import org.simple.clinic.TestClinicApp
14+
import org.simple.clinic.TestData
1415
import org.simple.clinic.questionnaire.component.BaseComponentData
1516
import org.simple.clinic.storage.DatabaseEncryptor.State.DOES_NOT_EXIST
1617
import org.simple.clinic.storage.DatabaseEncryptor.State.ENCRYPTED
@@ -19,7 +20,6 @@ import org.simple.clinic.storage.DatabaseEncryptor.State.UNENCRYPTED
1920
import org.simple.clinic.user.User
2021
import org.simple.clinic.user.UserStatus
2122
import org.simple.clinic.util.MinimumMemoryChecker
22-
import org.simple.clinic.TestData
2323
import java.time.Instant
2424
import java.util.UUID
2525
import javax.inject.Inject
@@ -94,7 +94,7 @@ class DatabaseEncryptorTest {
9494
val encryptedDatabase = Room.databaseBuilder(appContext, AppDatabase::class.java, DB_NAME)
9595
.allowMainThreadQueries()
9696
.addTypeConverter(BaseComponentData.RoomTypeConverter(moshi))
97-
.openHelperFactory(SupportFactory(passphrase, null, false))
97+
.openHelperFactory(SupportOpenHelperFactory(passphrase))
9898
.build()
9999

100100
val encryptedUser = encryptedDatabase.userDao().userImmediate()
@@ -104,7 +104,7 @@ class DatabaseEncryptorTest {
104104
}
105105

106106
@Test
107-
fun if_device_doesnt_have_min_req_memory_then_skip_database_encryption() {
107+
fun if_device_does_not_have_min_req_memory_then_skip_database_encryption() {
108108
// given
109109
(minimumMemoryChecker as FakeMinimumMemoryChecker).hasMinMemory = false
110110

@@ -114,4 +114,49 @@ class DatabaseEncryptorTest {
114114
// then
115115
assertThat(databaseEncryptor.databaseState(DB_NAME)).isEqualTo(SKIPPED)
116116
}
117+
118+
@Test
119+
fun when_database_is_already_encrypted_it_should_do_nothing() {
120+
// given
121+
val passphrase = databaseEncryptor.passphrase
122+
val encryptedDatabase = Room.databaseBuilder(appContext, AppDatabase::class.java, DB_NAME)
123+
.allowMainThreadQueries()
124+
.addTypeConverter(BaseComponentData.RoomTypeConverter(moshi))
125+
.openHelperFactory(SupportOpenHelperFactory(passphrase))
126+
.build()
127+
128+
val expectedUser = TestData.loggedInUser(uuid = UUID.randomUUID())
129+
encryptedDatabase.userDao().createOrUpdate(expectedUser)
130+
encryptedDatabase.close()
131+
132+
assertThat(databaseEncryptor.databaseState(DB_NAME)).isEqualTo(ENCRYPTED)
133+
134+
// when
135+
databaseEncryptor.execute(databaseName = DB_NAME)
136+
137+
// then
138+
assertThat(databaseEncryptor.databaseState(DB_NAME)).isEqualTo(ENCRYPTED)
139+
140+
val reOpenedEncryptedDb = Room.databaseBuilder(appContext, AppDatabase::class.java, DB_NAME)
141+
.allowMainThreadQueries()
142+
.addTypeConverter(BaseComponentData.RoomTypeConverter(moshi))
143+
.openHelperFactory(SupportOpenHelperFactory(passphrase))
144+
.build()
145+
146+
val actualUser = reOpenedEncryptedDb.userDao().userImmediate()
147+
assertThat(actualUser).isEqualTo(expectedUser)
148+
reOpenedEncryptedDb.close()
149+
}
150+
151+
@Test
152+
fun when_database_does_not_exist_it_should_do_nothing() {
153+
// given
154+
assertThat(databaseEncryptor.databaseState(DB_NAME)).isEqualTo(DOES_NOT_EXIST)
155+
156+
// when
157+
databaseEncryptor.execute(databaseName = DB_NAME)
158+
159+
// then
160+
assertThat(databaseEncryptor.databaseState(DB_NAME)).isEqualTo(DOES_NOT_EXIST)
161+
}
117162
}

app/src/debug/AndroidManifest.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
android:name=".playground.AwaitActivity"
2424
android:exported="true" />
2525

26-
<activity
27-
android:name="com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity"
28-
android:exported="true" />
29-
3026
<activity
3127
android:name=".WebviewTestActivity"
3228
android:enabled="false"

app/src/debug/java/org/simple/clinic/DebugClinicApp.kt

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ package org.simple.clinic
33
import android.annotation.SuppressLint
44
import android.app.Activity
55
import android.os.StrictMode
6-
import com.facebook.flipper.android.AndroidFlipperClient
7-
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin
8-
import com.facebook.flipper.plugins.inspector.DescriptorMapping
9-
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin
10-
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
11-
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin
12-
import com.facebook.soloader.SoLoader
136
import hu.akarnokd.rxjava3.debug.RxJavaAssemblyTracking
147
import io.github.inflationx.viewpump.ViewPump
158
import org.simple.clinic.activity.SimpleActivityLifecycleCallbacks
@@ -21,19 +14,10 @@ import org.simple.clinic.main.TheActivity
2114
import org.simple.clinic.util.AppSignature
2215
import org.simple.clinic.widgets.ProxySystemKeyboardEnterToImeOption
2316
import timber.log.Timber
24-
import javax.inject.Inject
2517

2618
@SuppressLint("Registered")
2719
class DebugClinicApp : ClinicApp() {
2820

29-
/*
30-
We are injecting this because we need to share the same instance with the OkHttp interceptor.
31-
32-
See debug/HttpInterceptorsModule for more info.
33-
*/
34-
@Inject
35-
lateinit var networkFlipperPlugin: NetworkFlipperPlugin
36-
3721
private lateinit var signature: AppSignature
3822

3923
companion object {
@@ -46,12 +30,9 @@ class DebugClinicApp : ClinicApp() {
4630
addStrictModeChecks()
4731
RxJavaAssemblyTracking.enable()
4832
super.onCreate()
49-
SoLoader.init(this, false)
5033

5134
appComponent().inject(this)
5235

53-
setupFlipper()
54-
5536
Timber.plant(Timber.DebugTree())
5637
showDebugNotification()
5738

@@ -62,22 +43,6 @@ class DebugClinicApp : ClinicApp() {
6243
signature = AppSignature(this)
6344
}
6445

65-
private fun setupFlipper() {
66-
val context = this
67-
68-
with(AndroidFlipperClient.getInstance(this)) {
69-
addPlugin(InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()))
70-
addPlugin(networkFlipperPlugin)
71-
72-
val databasePlugin = DatabasesFlipperPlugin(ReadOnlySqliteDatabaseDriver(context))
73-
addPlugin(databasePlugin)
74-
75-
addPlugin(SharedPreferencesFlipperPlugin(context, "${context.packageName}_preferences"))
76-
77-
start()
78-
}
79-
}
80-
8146
private fun showDebugNotification() {
8247
registerActivityLifecycleCallbacks(object : SimpleActivityLifecycleCallbacks() {
8348
override fun onActivityStarted(activity: Activity) {

app/src/debug/java/org/simple/clinic/ReadOnlySqliteDatabaseDriver.kt

Lines changed: 0 additions & 55 deletions
This file was deleted.

app/src/debug/java/org/simple/clinic/di/FlipperModule.kt

Lines changed: 0 additions & 15 deletions
This file was deleted.

app/src/debug/java/org/simple/clinic/di/network/HttpInterceptorsModule.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.simple.clinic.di.network
22

3-
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor
4-
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
3+
import android.app.Application
4+
import com.chuckerteam.chucker.api.ChuckerInterceptor
55
import dagger.Module
66
import dagger.Provides
77
import io.sentry.okhttp.SentryOkHttpInterceptor
@@ -13,12 +13,17 @@ import org.simple.clinic.user.LoggedInUserHttpInterceptor
1313
@Module
1414
class HttpInterceptorsModule {
1515

16+
@Provides
17+
fun chuckerInterceptor(context: Application): ChuckerInterceptor {
18+
return ChuckerInterceptor(context)
19+
}
20+
1621
@Provides
1722
fun providerInterceptors(
1823
loggedInInterceptor: LoggedInUserHttpInterceptor,
1924
appInfoHttpInterceptor: AppInfoHttpInterceptor,
20-
networkPlugin: NetworkFlipperPlugin,
21-
compressRequestInterceptor: CompressRequestInterceptor
25+
compressRequestInterceptor: CompressRequestInterceptor,
26+
chuckerInterceptor: ChuckerInterceptor,
2227
): List<Interceptor> {
2328
val loggingInterceptor = HttpLoggingInterceptor().apply {
2429
level = BODY
@@ -29,8 +34,8 @@ class HttpInterceptorsModule {
2934
loggedInInterceptor,
3035
appInfoHttpInterceptor,
3136
loggingInterceptor,
32-
FlipperOkhttpInterceptor(networkPlugin),
33-
compressRequestInterceptor
37+
compressRequestInterceptor,
38+
chuckerInterceptor,
3439
)
3540
}
3641
}

app/src/main/java/org/simple/clinic/di/AppModule.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ import javax.inject.Named
8686
HttpInterceptorsModule::class,
8787
RetrofitModule::class,
8888
ClearPatientDataModule::class,
89-
FlipperModule::class,
9089
PinVerificationModule::class,
9190
SessionModule::class,
9291
UuidGeneratorModule::class,

0 commit comments

Comments
 (0)