Skip to content

Commit

Permalink
Merge branch 'main' into feat/android/google-play
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthetechie authored Sep 18, 2024
2 parents 0635326 + 7494ec1 commit bff3bb4
Show file tree
Hide file tree
Showing 60 changed files with 1,257 additions and 377 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ android/demo-app/** -linguist-detectable

apple/DemoApp/** -linguist-detectable

apple/Sources/UniFFI/** -linguist-detectable
apple/Sources/UniFFI/** linguist-generated=true
11 changes: 11 additions & 0 deletions .github/workflows/ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,21 @@ jobs:
- name: Checkout repo
uses: actions/checkout@v4

- name: Ensure that Package.swift is NOT configured for local development at this stage (easy to forget)
run: sed -i '' 's/let useLocalFramework = true/let useLocalFramework = false/' Package.swift

- name: Commit changed files (it is easy to forget useLocalFramework in Package.swift)
uses: stefanzweifel/git-auto-commit-action@v5
with:
file_pattern: 'Package.swift'

- name: Build iOS XCFramework
run: ./build-ios.sh --release
working-directory: common

- name: Ensure that Package.swift is NOT configured for local development at this stage (easy to forget)
run: sed -i '' 's/let useLocalFramework = true/let useLocalFramework = false/' Package.swift

- name: Commit changed files (it is easy to forget about ferrostar.swift)
uses: stefanzweifel/git-auto-commit-action@v5
with:
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ if useLocalFramework {
path: "./common/target/ios/libferrostar-rs.xcframework"
)
} else {
let releaseTag = "0.10.1"
let releaseChecksum = "cc959191f3d066f628264c103e5ea0c3544664ffd0e61907e082d7f1a4d8c5d2"
let releaseTag = "0.11.0"
let releaseChecksum = "32a28d66933b6dc7f9b206c79e265767fc51339a9a81f81304c3f15cd7722d19"
binaryTarget = .binaryTarget(
name: "FerrostarCoreRS",
url: "https://github.com/stadiamaps/ferrostar/releases/download/\(releaseTag)/libferrostar-rs.xcframework.zip",
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ plugins {

allprojects {
group = "com.stadiamaps.ferrostar"
version = "0.10.1"
version = "0.11.0"
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
package com.stadiamaps.ferrostar.composeui.runtime

import android.app.Activity
import android.view.Window
import android.view.WindowManager
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.platform.LocalContext

/** Get the Window for the current scene (Activity). */
@Composable
private fun window(): Window? {
val context = LocalContext.current
return (context as? Activity)?.window ?: return null
}

/**
* A Composable that keeps the screen on while the hosting Composable is in the view hierarchy. On
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.stadiamaps.ferrostar.composeui.runtime

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp

@Composable
fun paddingForGridView(horizontal: Dp = 16.dp, vertical: Dp = 16.dp): PaddingValues {
val rawLayoutDirection = LocalConfiguration.current.layoutDirection
val layoutDirection: LayoutDirection = LayoutDirection.entries[rawLayoutDirection]
val safeDrawingPadding = WindowInsets.safeDrawing.asPaddingValues()

val topPadding =
if (safeDrawingPadding.calculateTopPadding() > vertical) {
0.dp
} else {
vertical
}

val bottomPadding =
if (safeDrawingPadding.calculateBottomPadding() > vertical) {
0.dp
} else {
vertical
}

val systemStartPadding = safeDrawingPadding.calculateStartPadding(layoutDirection)
val startPadding =
if (systemStartPadding > horizontal) {
systemStartPadding
} else {
horizontal
}

val systemEndPadding = safeDrawingPadding.calculateEndPadding(layoutDirection)
val endPadding =
if (systemEndPadding > horizontal) {
systemEndPadding
} else {
horizontal
}

return PaddingValues(
top = topPadding, start = startPadding, end = endPadding, bottom = bottomPadding)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.stadiamaps.ferrostar.composeui.runtime

import android.app.Activity
import android.view.Window
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

/**
* Get the Window for the current scene (Activity).
*
* @return The Window for the current scene, or null if the current context is not an Activity.
*/
@Composable
internal fun window(): Window? {
val context = LocalContext.current
return (context as? Activity)?.window ?: return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.fail
import org.junit.Test
import uniffi.ferrostar.BoundingBox
import uniffi.ferrostar.CourseFiltering
import uniffi.ferrostar.GeographicCoordinate
import uniffi.ferrostar.ManeuverModifier
import uniffi.ferrostar.ManeuverType
Expand All @@ -41,13 +42,20 @@ private val valhallaEndpointUrl = "https://api.stadiamaps.com/navigate/v1"

// Simple test to ensure that the extensibility with native code is working.

class MockRouteRequestGenerator : RouteRequestGenerator {
class MockPostRouteRequestGenerator : RouteRequestGenerator {
override fun generateRequest(
userLocation: UserLocation,
waypoints: List<Waypoint>
): RouteRequest = RouteRequest.HttpPost(valhallaEndpointUrl, mapOf(), byteArrayOf())
}

class MockGetRouteRequestGenerator : RouteRequestGenerator {
override fun generateRequest(
userLocation: UserLocation,
waypoints: List<Waypoint>
): RouteRequest = RouteRequest.HttpGet(valhallaEndpointUrl, mapOf())
}

class MockRouteResponseParser(private val routes: List<Route>) : RouteResponseParser {
override fun parseResponse(response: ByteArray): List<Route> = routes
}
Expand Down Expand Up @@ -119,20 +127,21 @@ class FerrostarCoreTest {
MockInterceptor().apply {
rule(post, url eq valhallaEndpointUrl) { respond(401, errorBody) }

rule(get) { respond { throw IllegalStateException("an IO error") } }
rule(get) { respond { throw IllegalStateException("Unexpected GET request") } }
}

val core =
FerrostarCore(
routeAdapter =
RouteAdapter(
requestGenerator = MockRouteRequestGenerator(),
requestGenerator = MockPostRouteRequestGenerator(),
responseParser = MockRouteResponseParser(routes = listOf())),
httpClient = OkHttpClient.Builder().addInterceptor(interceptor).build(),
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))

try {
// Tests that the core generates a request and attempts to process it, but throws due to the
Expand Down Expand Up @@ -161,25 +170,69 @@ class FerrostarCoreTest {
}

@Test
fun test200MockRouteResponse() = runTest {
fun test200MockRouteResponsePost() = runTest {
val interceptor =
MockInterceptor().apply {
rule(post, url eq valhallaEndpointUrl) { respond(200, "".toResponseBody()) }

rule(get) { respond { throw IllegalStateException("an IO error") } }
rule(get) { respond { throw IllegalStateException("unexpected GET request") } }
}

val core =
FerrostarCore(
routeAdapter =
RouteAdapter(
requestGenerator = MockPostRouteRequestGenerator(),
responseParser = MockRouteResponseParser(routes = listOf(mockRoute))),
httpClient = OkHttpClient.Builder().addInterceptor(interceptor).build(),
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))
val routes =
core.getRoutes(
initialLocation =
UserLocation(
coordinates =
GeographicCoordinate(
lat = 60.5347155,
lng = -149.543469,
),
horizontalAccuracy = 6.0,
courseOverGround = null,
timestamp = Instant.now(),
speed = null),
waypoints =
listOf(
Waypoint(
coordinate = GeographicCoordinate(lat = 60.5349908, lng = -149.5485806),
kind = WaypointKind.BREAK)))

assertEquals(listOf(mockRoute), routes)
}

@Test
fun test200MockRouteResponseGet() = runTest {
val interceptor =
MockInterceptor().apply {
rule(get, url eq valhallaEndpointUrl) { respond(200, "".toResponseBody()) }

rule(post) { respond { throw IllegalStateException("unexpected POST request") } }
}

val core =
FerrostarCore(
routeAdapter =
RouteAdapter(
requestGenerator = MockRouteRequestGenerator(),
requestGenerator = MockGetRouteRequestGenerator(),
responseParser = MockRouteResponseParser(routes = listOf(mockRoute))),
httpClient = OkHttpClient.Builder().addInterceptor(interceptor).build(),
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))
val routes =
core.getRoutes(
initialLocation =
Expand All @@ -206,7 +259,7 @@ class FerrostarCoreTest {
fun testCustomRouteProvider() = runTest {
val interceptor =
MockInterceptor().apply {
rule(post) { respond { throw IllegalStateException("Unexpected call") } }
rule(post) { respond { throw IllegalStateException("Unexpected network call") } }
}

val routeProvider =
Expand All @@ -229,7 +282,8 @@ class FerrostarCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))
val routes =
core.getRoutes(
initialLocation =
Expand Down Expand Up @@ -293,13 +347,14 @@ class FerrostarCoreTest {
FerrostarCore(
routeAdapter =
RouteAdapter(
requestGenerator = MockRouteRequestGenerator(),
requestGenerator = MockPostRouteRequestGenerator(),
responseParser = MockRouteResponseParser(routes = listOf(mockRoute))),
httpClient = OkHttpClient.Builder().addInterceptor(interceptor).build(),
locationProvider = locationProvider,
foregroundServiceManager = foregroundServiceManager,
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))

val deviationHandler = DeviationHandler()
core.deviationHandler = deviationHandler
Expand Down Expand Up @@ -348,7 +403,8 @@ class FerrostarCoreTest {
): RouteDeviation {
return RouteDeviation.OffRoute(42.0)
}
})))
}),
CourseFiltering.RAW))

assert(foregroundServiceManager.startCalled)
assert(deviationHandler.called)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import okhttp3.mock.rule
import okhttp3.mock.url
import org.junit.Assert.assertEquals
import org.junit.Test
import uniffi.ferrostar.CourseFiltering
import uniffi.ferrostar.GeographicCoordinate
import uniffi.ferrostar.NavigationControllerConfig
import uniffi.ferrostar.RouteDeviationTracking
Expand Down Expand Up @@ -252,7 +253,8 @@ class ValhallaCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None))
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW))

return runTest {
val routes =
Expand Down Expand Up @@ -299,7 +301,8 @@ class ValhallaCoreTest {
locationProvider = SimulatedLocationProvider(),
foregroundServiceManager = MockForegroundNotificationManager(),
navigationControllerConfig =
NavigationControllerConfig(StepAdvanceMode.Manual, RouteDeviationTracking.None),
NavigationControllerConfig(
StepAdvanceMode.Manual, RouteDeviationTracking.None, CourseFiltering.RAW),
costingOptions = mapOf("auto" to mapOf("useTolls" to 0)))

return runTest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
package com.stadiamaps.ferrostar.core

import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import uniffi.ferrostar.Route
import uniffi.ferrostar.RouteRequest
import uniffi.ferrostar.getRoutePolyline

@Throws fun Route.getPolyline(precision: UInt): String = getRoutePolyline(this, precision)

@Throws
fun RouteRequest.toOkhttp3Request(): Request {
val headers: Map<String, String>
return when (this) {
is RouteRequest.HttpPost -> {
headers = this.headers
Request.Builder().url(url).post(body.toRequestBody())
}

is RouteRequest.HttpGet -> {
headers = this.headers
Request.Builder().url(url).get()
}
}
.apply { headers.map { (name, value) -> header(name, value) } }
.build()
}
Loading

0 comments on commit bff3bb4

Please sign in to comment.