Loading cardinal-android/app/build.gradle.kts +0 −9 Original line number Diff line number Diff line Loading @@ -137,15 +137,6 @@ android { dependsOn("buildCargoNdkArm64Release", "buildCargoNdkX86_64Release") } applicationVariants.all { val variant = this // Add dependency from Java compilation to the UniFFI binding generation task tasks.named("compile${variant.name.capitalize()}JavaWithJavac") { dependsOn(generateUniFFIBindings) } } sourceSets { getByName("main") { java.srcDir(layout.buildDirectory.dir("generated/source/uniffi")) Loading cardinal-android/app/src/main/java/earth/maps/cardinal/ui/home/OfflineAreasViewModel.kt +45 −40 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.IBinder import android.util.Log import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf Loading @@ -39,6 +38,8 @@ import earth.maps.cardinal.tileserver.TileDownloadForegroundService import earth.maps.cardinal.tileserver.calculateTileRange import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.math.min Loading @@ -60,6 +61,10 @@ class OfflineAreasViewModel @Inject constructor( val unifiedProgress = mutableFloatStateOf(0f) // 0.0 to 1.0 val currentStage = mutableStateOf(DownloadStage.BASEMAP) // Error handling private val _errorMessage = MutableStateFlow<String?>(null) val errorMessage: StateFlow<String?> = _errorMessage // Service binding infrastructure private var serviceBinder: TileDownloadForegroundService.TileDownloadBinder? = null private var progressJob: Job? = null Loading @@ -67,14 +72,12 @@ class OfflineAreasViewModel @Inject constructor( private val serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { Log.d(TAG, "Connected to TileDownloadForegroundService") serviceBinder = service as TileDownloadForegroundService.TileDownloadBinder isBound = true syncWithOngoingDownloads() } override fun onServiceDisconnected(name: ComponentName?) { Log.d(TAG, "Disconnected from TileDownloadForegroundService") serviceBinder = null isBound = false progressJob?.cancel() Loading @@ -84,7 +87,6 @@ class OfflineAreasViewModel @Inject constructor( } override fun onBindingDied(name: ComponentName?) { Log.d(TAG, "Binding to TileDownloadForegroundService died") serviceBinder = null isBound = false progressJob?.cancel() Loading @@ -93,7 +95,6 @@ class OfflineAreasViewModel @Inject constructor( } override fun onNullBinding(name: ComponentName?) { Log.d(TAG, "Null binding to TileDownloadForegroundService") serviceBinder = null isBound = false resetProgressState() Loading @@ -118,13 +119,8 @@ class OfflineAreasViewModel @Inject constructor( // Check if service is currently downloading val isServiceDownloading = service.isDownloading.value if (isServiceDownloading) { Log.d(TAG, "Detected ongoing download in service, syncing UI state") // The StateFlow observations should handle the rest } else { Log.d(TAG, "No ongoing downloads detected in service") } } else { Log.d(TAG, "Service not bound yet, will sync when connection established") } } } Loading Loading @@ -184,9 +180,12 @@ class OfflineAreasViewModel @Inject constructor( */ private fun bindToService() { if (!isBound) { Log.d(TAG, "Binding to TileDownloadForegroundService") val intent = Intent(context, TileDownloadForegroundService::class.java) try { context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) } catch (e: Exception) { _errorMessage.value = "Failed to bind to download service: ${e.message}" } } } Loading @@ -195,8 +194,11 @@ class OfflineAreasViewModel @Inject constructor( */ private fun unbindFromService() { if (isBound) { Log.d(TAG, "Unbinding from TileDownloadForegroundService") try { context.unbindService(serviceConnection) } catch (e: Exception) { _errorMessage.value = "Failed to unbind from download service: ${e.message}" } serviceBinder = null isBound = false } Loading @@ -220,9 +222,6 @@ class OfflineAreasViewModel @Inject constructor( downloadProgress.intValue = 0 totalTiles.intValue = 0 currentAreaName.value = "" Log.d(TAG, "Reset progress state - no active downloads in database") } else { Log.d(TAG, "Not resetting progress state - active areas exist in database") } } Loading @@ -237,6 +236,12 @@ class OfflineAreasViewModel @Inject constructor( companion object { const val OFFLINE_AREA_MIN_ZOOM = 5 const val OFFLINE_AREA_MAX_ZOOM = 14 private const val TAG = "OfflineAreasViewModel" } /** * Clear any error message */ fun clearErrorMessage() { _errorMessage.value = null } } cardinal-android/app/src/main/java/earth/maps/cardinal/ui/settings/SettingsViewModel.kt +0 −8 Original line number Diff line number Diff line Loading @@ -158,12 +158,4 @@ class SettingsViewModel @Inject constructor( } return null } fun onCallToActionClicked() { val url = "https://github.com/ellenhp/cardinal" val i = Intent(Intent.ACTION_VIEW) i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) i.setData(url.toUri()) context.startActivity(i) } } cardinal-android/app/src/test/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModelTest.kt +0 −5 Original line number Diff line number Diff line Loading @@ -44,9 +44,4 @@ class TurnByTurnNavigationViewModelTest { fun `viewModel should have correct ferrostarWrapperRepository`() { assertEquals(mockFerrostarWrapperRepository, viewModel.ferrostarWrapperRepository) } @Test fun `viewModel should be instance of ViewModel`() { assertEquals(true, viewModel is androidx.lifecycle.ViewModel) } } No newline at end of file cardinal-android/app/src/test/java/earth/maps/cardinal/ui/home/HomeViewModelTest.kt +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ class HomeViewModelTest { @ExperimentalCoroutinesApi @get:Rule var mainCoroutineRule = MainCoroutineRule(UnconfinedTestDispatcher()) var mainCoroutineRule = MainCoroutineRule() private lateinit var viewModel: HomeViewModel private lateinit var mockPlaceDao: SavedPlaceDao Loading Loading
cardinal-android/app/build.gradle.kts +0 −9 Original line number Diff line number Diff line Loading @@ -137,15 +137,6 @@ android { dependsOn("buildCargoNdkArm64Release", "buildCargoNdkX86_64Release") } applicationVariants.all { val variant = this // Add dependency from Java compilation to the UniFFI binding generation task tasks.named("compile${variant.name.capitalize()}JavaWithJavac") { dependsOn(generateUniFFIBindings) } } sourceSets { getByName("main") { java.srcDir(layout.buildDirectory.dir("generated/source/uniffi")) Loading
cardinal-android/app/src/main/java/earth/maps/cardinal/ui/home/OfflineAreasViewModel.kt +45 −40 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.IBinder import android.util.Log import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf Loading @@ -39,6 +38,8 @@ import earth.maps.cardinal.tileserver.TileDownloadForegroundService import earth.maps.cardinal.tileserver.calculateTileRange import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.math.min Loading @@ -60,6 +61,10 @@ class OfflineAreasViewModel @Inject constructor( val unifiedProgress = mutableFloatStateOf(0f) // 0.0 to 1.0 val currentStage = mutableStateOf(DownloadStage.BASEMAP) // Error handling private val _errorMessage = MutableStateFlow<String?>(null) val errorMessage: StateFlow<String?> = _errorMessage // Service binding infrastructure private var serviceBinder: TileDownloadForegroundService.TileDownloadBinder? = null private var progressJob: Job? = null Loading @@ -67,14 +72,12 @@ class OfflineAreasViewModel @Inject constructor( private val serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { Log.d(TAG, "Connected to TileDownloadForegroundService") serviceBinder = service as TileDownloadForegroundService.TileDownloadBinder isBound = true syncWithOngoingDownloads() } override fun onServiceDisconnected(name: ComponentName?) { Log.d(TAG, "Disconnected from TileDownloadForegroundService") serviceBinder = null isBound = false progressJob?.cancel() Loading @@ -84,7 +87,6 @@ class OfflineAreasViewModel @Inject constructor( } override fun onBindingDied(name: ComponentName?) { Log.d(TAG, "Binding to TileDownloadForegroundService died") serviceBinder = null isBound = false progressJob?.cancel() Loading @@ -93,7 +95,6 @@ class OfflineAreasViewModel @Inject constructor( } override fun onNullBinding(name: ComponentName?) { Log.d(TAG, "Null binding to TileDownloadForegroundService") serviceBinder = null isBound = false resetProgressState() Loading @@ -118,13 +119,8 @@ class OfflineAreasViewModel @Inject constructor( // Check if service is currently downloading val isServiceDownloading = service.isDownloading.value if (isServiceDownloading) { Log.d(TAG, "Detected ongoing download in service, syncing UI state") // The StateFlow observations should handle the rest } else { Log.d(TAG, "No ongoing downloads detected in service") } } else { Log.d(TAG, "Service not bound yet, will sync when connection established") } } } Loading Loading @@ -184,9 +180,12 @@ class OfflineAreasViewModel @Inject constructor( */ private fun bindToService() { if (!isBound) { Log.d(TAG, "Binding to TileDownloadForegroundService") val intent = Intent(context, TileDownloadForegroundService::class.java) try { context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) } catch (e: Exception) { _errorMessage.value = "Failed to bind to download service: ${e.message}" } } } Loading @@ -195,8 +194,11 @@ class OfflineAreasViewModel @Inject constructor( */ private fun unbindFromService() { if (isBound) { Log.d(TAG, "Unbinding from TileDownloadForegroundService") try { context.unbindService(serviceConnection) } catch (e: Exception) { _errorMessage.value = "Failed to unbind from download service: ${e.message}" } serviceBinder = null isBound = false } Loading @@ -220,9 +222,6 @@ class OfflineAreasViewModel @Inject constructor( downloadProgress.intValue = 0 totalTiles.intValue = 0 currentAreaName.value = "" Log.d(TAG, "Reset progress state - no active downloads in database") } else { Log.d(TAG, "Not resetting progress state - active areas exist in database") } } Loading @@ -237,6 +236,12 @@ class OfflineAreasViewModel @Inject constructor( companion object { const val OFFLINE_AREA_MIN_ZOOM = 5 const val OFFLINE_AREA_MAX_ZOOM = 14 private const val TAG = "OfflineAreasViewModel" } /** * Clear any error message */ fun clearErrorMessage() { _errorMessage.value = null } }
cardinal-android/app/src/main/java/earth/maps/cardinal/ui/settings/SettingsViewModel.kt +0 −8 Original line number Diff line number Diff line Loading @@ -158,12 +158,4 @@ class SettingsViewModel @Inject constructor( } return null } fun onCallToActionClicked() { val url = "https://github.com/ellenhp/cardinal" val i = Intent(Intent.ACTION_VIEW) i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) i.setData(url.toUri()) context.startActivity(i) } }
cardinal-android/app/src/test/java/earth/maps/cardinal/ui/directions/TurnByTurnNavigationViewModelTest.kt +0 −5 Original line number Diff line number Diff line Loading @@ -44,9 +44,4 @@ class TurnByTurnNavigationViewModelTest { fun `viewModel should have correct ferrostarWrapperRepository`() { assertEquals(mockFerrostarWrapperRepository, viewModel.ferrostarWrapperRepository) } @Test fun `viewModel should be instance of ViewModel`() { assertEquals(true, viewModel is androidx.lifecycle.ViewModel) } } No newline at end of file
cardinal-android/app/src/test/java/earth/maps/cardinal/ui/home/HomeViewModelTest.kt +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ class HomeViewModelTest { @ExperimentalCoroutinesApi @get:Rule var mainCoroutineRule = MainCoroutineRule(UnconfinedTestDispatcher()) var mainCoroutineRule = MainCoroutineRule() private lateinit var viewModel: HomeViewModel private lateinit var mockPlaceDao: SavedPlaceDao Loading