Loading app/src/androidTest/kotlin/at/bitfire/davdroid/HiltTestRunner.kt +5 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ import android.content.Context import android.os.Build import android.os.Bundle import androidx.test.runner.AndroidJUnitRunner import at.bitfire.davdroid.sync.SyncAdapterService import dagger.hilt.android.testing.HiltTestApplication @Suppress("unused") Loading @@ -20,8 +21,12 @@ class HiltTestRunner : AndroidJUnitRunner() { override fun onCreate(arguments: Bundle?) { super.onCreate(arguments) // MockK requirements if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) throw AssertionError("MockK requires Android P [https://mockk.io/ANDROID.html]") // disable sync adapters SyncAdapterService.syncActive.set(false) } } No newline at end of file app/src/main/kotlin/at/bitfire/davdroid/sync/SyncAdapterServices.kt +29 −24 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout import java.util.concurrent.atomic.AtomicBoolean import java.util.logging.Level import java.util.logging.Logger import javax.inject.Inject Loading @@ -54,17 +55,10 @@ abstract class SyncAdapterService: Service() { } override fun onBind(intent: Intent?): IBinder { try { // create sync adapter via Hilt val entryPoint = EntryPointAccessors.fromApplication<EntryPoint>(this) val syncAdapter = entryPoint.syncAdapter() return syncAdapter.syncAdapterBinder } catch (e: IllegalStateException) { if (BuildConfig.DEBUG) { // only for debug builds: handle "Hilt not initialized" exception if (BuildConfig.DEBUG && !syncActive.get()) { // only for debug builds/testing: syncActive flag val logger = Logger.getLogger(this@SyncAdapterService::class.java.name) logger.log(Level.WARNING, "SyncAdapterService.onBind() was called without Hilt initialization. Ignoring", e) logger.log(Level.WARNING, "SyncAdapterService.onBind() was called but syncActive = false. Ignoring") val fakeAdapter = object: AbstractThreadedSyncAdapter(this, false) { override fun onPerformSync(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) { Loading @@ -76,12 +70,23 @@ abstract class SyncAdapterService: Service() { } } return fakeAdapter.syncAdapterBinder } else // re-throw in production builds throw e } // create sync adapter via Hilt val entryPoint = EntryPointAccessors.fromApplication<EntryPoint>(this) val syncAdapter = entryPoint.syncAdapter() return syncAdapter.syncAdapterBinder } companion object { /** * Flag to indicate whether the sync adapter should be active. When it is `false`, synchronization will not be run * (only intended for tests). */ val syncActive = AtomicBoolean(true) } /** * Entry point for the Sync Adapter Framework. * Loading Loading
app/src/androidTest/kotlin/at/bitfire/davdroid/HiltTestRunner.kt +5 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ import android.content.Context import android.os.Build import android.os.Bundle import androidx.test.runner.AndroidJUnitRunner import at.bitfire.davdroid.sync.SyncAdapterService import dagger.hilt.android.testing.HiltTestApplication @Suppress("unused") Loading @@ -20,8 +21,12 @@ class HiltTestRunner : AndroidJUnitRunner() { override fun onCreate(arguments: Bundle?) { super.onCreate(arguments) // MockK requirements if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) throw AssertionError("MockK requires Android P [https://mockk.io/ANDROID.html]") // disable sync adapters SyncAdapterService.syncActive.set(false) } } No newline at end of file
app/src/main/kotlin/at/bitfire/davdroid/sync/SyncAdapterServices.kt +29 −24 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout import java.util.concurrent.atomic.AtomicBoolean import java.util.logging.Level import java.util.logging.Logger import javax.inject.Inject Loading @@ -54,17 +55,10 @@ abstract class SyncAdapterService: Service() { } override fun onBind(intent: Intent?): IBinder { try { // create sync adapter via Hilt val entryPoint = EntryPointAccessors.fromApplication<EntryPoint>(this) val syncAdapter = entryPoint.syncAdapter() return syncAdapter.syncAdapterBinder } catch (e: IllegalStateException) { if (BuildConfig.DEBUG) { // only for debug builds: handle "Hilt not initialized" exception if (BuildConfig.DEBUG && !syncActive.get()) { // only for debug builds/testing: syncActive flag val logger = Logger.getLogger(this@SyncAdapterService::class.java.name) logger.log(Level.WARNING, "SyncAdapterService.onBind() was called without Hilt initialization. Ignoring", e) logger.log(Level.WARNING, "SyncAdapterService.onBind() was called but syncActive = false. Ignoring") val fakeAdapter = object: AbstractThreadedSyncAdapter(this, false) { override fun onPerformSync(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) { Loading @@ -76,12 +70,23 @@ abstract class SyncAdapterService: Service() { } } return fakeAdapter.syncAdapterBinder } else // re-throw in production builds throw e } // create sync adapter via Hilt val entryPoint = EntryPointAccessors.fromApplication<EntryPoint>(this) val syncAdapter = entryPoint.syncAdapter() return syncAdapter.syncAdapterBinder } companion object { /** * Flag to indicate whether the sync adapter should be active. When it is `false`, synchronization will not be run * (only intended for tests). */ val syncActive = AtomicBoolean(true) } /** * Entry point for the Sync Adapter Framework. * Loading