summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2025-09-02 11:25:10 +0200
committerDavid Göransson <david.goransson@mullvad.net>2025-09-02 11:25:10 +0200
commit51621e6faf71b83937b115b1b281eb9aa9816679 (patch)
tree8504f0c90c0b23c7bb591056bfd51e2ef7ee5186 /android
parenteb6671a1d7801f8e10411fbd022679066249ed39 (diff)
parentaa0b4882bec6a3bd87228b5e538eeb37ead9af7a (diff)
downloadmullvadvpn-51621e6faf71b83937b115b1b281eb9aa9816679.tar.xz
mullvadvpn-51621e6faf71b83937b115b1b281eb9aa9816679.zip
Merge branch 'rework-map-lifecycle'
Diffstat (limited to 'android')
-rw-r--r--android/gradle/verification-metadata.keys.xml8
-rw-r--r--android/gradle/verification-metadata.xml8
-rw-r--r--android/lib/map/build.gradle.kts3
-rw-r--r--android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt81
-rw-r--r--android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt16
5 files changed, 85 insertions, 31 deletions
diff --git a/android/gradle/verification-metadata.keys.xml b/android/gradle/verification-metadata.keys.xml
index 81b1e8649f..c26fed8ba7 100644
--- a/android/gradle/verification-metadata.keys.xml
+++ b/android/gradle/verification-metadata.keys.xml
@@ -251,6 +251,9 @@
</artifact>
</component>
<component group="androidx.activity" name="activity-compose" version="1.7.0">
+ <artifact name="activity-compose-1.7.0.aar">
+ <sha256 value="caa72885d1ce7979c1d6c59a8b255c6097b770780d4d4da95d56979a348646cd" origin="Generated by Gradle" reason="Artifact is not signed"/>
+ </artifact>
<artifact name="activity-compose-1.7.0.module">
<sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
@@ -350,6 +353,11 @@
<sha256 value="2bfc54475c047131913361f56d0f7f019c6e5bee53eeb0eb7d94a7c499a05227" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
+ <component group="androidx.compose.animation" name="animation-core" version="1.0.0">
+ <artifact name="animation-core-1.0.0.module">
+ <sha256 value="2e3502f0deaf56b098b0412075fcc3e7c2d85b95ae9bf4230ec92c2a9008f842" origin="Generated by Gradle" reason="Artifact is not signed"/>
+ </artifact>
+ </component>
<component group="androidx.compose.animation" name="animation-core" version="1.2.1">
<artifact name="animation-core-1.2.1.module">
<sha256 value="9083ac53ad162f4167ecfb895469943504f4cd6a624e612936a5209144c5b6bf" origin="Generated by Gradle" reason="Artifact is not signed"/>
diff --git a/android/gradle/verification-metadata.xml b/android/gradle/verification-metadata.xml
index 052a7dbabb..2a76827fe1 100644
--- a/android/gradle/verification-metadata.xml
+++ b/android/gradle/verification-metadata.xml
@@ -92,6 +92,9 @@
</artifact>
</component>
<component group="androidx.activity" name="activity-compose" version="1.7.0">
+ <artifact name="activity-compose-1.7.0.aar">
+ <sha256 value="caa72885d1ce7979c1d6c59a8b255c6097b770780d4d4da95d56979a348646cd" origin="Generated by Gradle"/>
+ </artifact>
<artifact name="activity-compose-1.7.0.module">
<sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" origin="Generated by Gradle"/>
</artifact>
@@ -431,6 +434,11 @@
<sha256 value="788eeac00159aaedd97f685067cf2c87cbf114c21746732653970e3055231322" origin="Generated by Gradle"/>
</artifact>
</component>
+ <component group="androidx.compose.animation" name="animation-core" version="1.0.0">
+ <artifact name="animation-core-1.0.0.module">
+ <sha256 value="2e3502f0deaf56b098b0412075fcc3e7c2d85b95ae9bf4230ec92c2a9008f842" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
<component group="androidx.compose.animation" name="animation-core" version="1.2.1">
<artifact name="animation-core-1.2.1.module">
<sha256 value="9083ac53ad162f4167ecfb895469943504f4cd6a624e612936a5209144c5b6bf" origin="Generated by Gradle"/>
diff --git a/android/lib/map/build.gradle.kts b/android/lib/map/build.gradle.kts
index 347adb4d31..bc43c56bce 100644
--- a/android/lib/map/build.gradle.kts
+++ b/android/lib/map/build.gradle.kts
@@ -43,5 +43,8 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime)
implementation(libs.compose.ui)
implementation(libs.compose.foundation)
+ // UI tooling
+ implementation(libs.compose.ui.tooling.preview)
+ debugImplementation(libs.compose.ui.tooling)
implementation(libs.kermit)
}
diff --git a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt
index 05b8d59701..2e7627c962 100644
--- a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt
+++ b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/Map.kt
@@ -1,12 +1,15 @@
package net.mullvad.mullvadvpn.lib.map
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.rememberInfiniteTransition
+import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.viewinterop.AndroidView
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import net.mullvad.mullvadvpn.lib.map.data.CameraPosition
import net.mullvad.mullvadvpn.lib.map.data.GlobeColors
@@ -14,6 +17,40 @@ import net.mullvad.mullvadvpn.lib.map.data.MapViewState
import net.mullvad.mullvadvpn.lib.map.data.Marker
import net.mullvad.mullvadvpn.lib.map.internal.MapGLSurfaceView
import net.mullvad.mullvadvpn.lib.model.LatLong
+import net.mullvad.mullvadvpn.lib.model.Latitude
+import net.mullvad.mullvadvpn.lib.model.Longitude
+
+@Preview
+@Composable
+fun MapPreview() {
+ val infinite = rememberInfiniteTransition()
+ val spin =
+ infinite.animateFloat(
+ 0f,
+ 360f,
+ infiniteRepeatable(animation = tween(30000, easing = LinearEasing)),
+ )
+
+ Map(
+ modifier = Modifier,
+ cameraLocation =
+ CameraPosition(
+ LatLong(Latitude(0f), Longitude.fromFloat(spin.value)),
+ 2f,
+ verticalBias = 0.5f,
+ ),
+ markers = emptyList(),
+ globeColors =
+ GlobeColors(
+ // Green
+ landColor = Color(0xFF26513C),
+ // Blue
+ oceanColor = Color(0xFF161E50),
+ // Darker green
+ contourColor = Color(0xFF1B3626),
+ ),
+ )
+}
@Composable
fun Map(
@@ -51,33 +88,15 @@ fun AnimatedMap(
@Composable
internal fun Map(modifier: Modifier = Modifier, mapViewState: MapViewState) {
- var view: MapGLSurfaceView? = remember { null }
-
val lifeCycleState = LocalLifecycleOwner.current.lifecycle
- DisposableEffect(key1 = lifeCycleState) {
- val observer = LifecycleEventObserver { _, event ->
- when (event) {
- Lifecycle.Event.ON_RESUME -> {
- view?.onResume()
- }
- Lifecycle.Event.ON_PAUSE -> {
- view?.onPause()
- }
- else -> {}
- }
- }
- lifeCycleState.addObserver(observer)
-
- onDispose {
- lifeCycleState.removeObserver(observer)
- view?.onPause()
- view = null
- }
- }
-
- AndroidView(modifier = modifier, factory = { MapGLSurfaceView(it) }) { glSurfaceView ->
- view = glSurfaceView
- glSurfaceView.setData(mapViewState)
- }
+ AndroidView(
+ modifier = modifier,
+ factory = { MapGLSurfaceView(it) },
+ update = { glSurfaceView ->
+ glSurfaceView.lifecycle = lifeCycleState
+ glSurfaceView.setData(mapViewState)
+ },
+ onRelease = { it.lifecycle = null },
+ )
}
diff --git a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt
index 19dd085524..32b8cfe8e3 100644
--- a/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt
+++ b/android/lib/map/src/main/kotlin/net/mullvad/mullvadvpn/lib/map/internal/MapGLSurfaceView.kt
@@ -2,12 +2,28 @@ package net.mullvad.mullvadvpn.lib.map.internal
import android.content.Context
import android.opengl.GLSurfaceView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
import net.mullvad.mullvadvpn.lib.map.BuildConfig
import net.mullvad.mullvadvpn.lib.map.data.MapViewState
internal class MapGLSurfaceView(context: Context) : GLSurfaceView(context) {
private val renderer: MapGLRenderer
+ var lifecycle: Lifecycle? = null
+ set(value) {
+ field?.removeObserver(observer)
+ value?.addObserver(observer)
+ field = value
+ }
+
+ private val observer = LifecycleEventObserver { source, event ->
+ when (event) {
+ Lifecycle.Event.ON_RESUME -> onResume()
+ Lifecycle.Event.ON_PAUSE -> onPause()
+ else -> {}
+ }
+ }
init {
// Create an OpenGL ES 2.0 context