Skip to content

Commit

Permalink
Merge pull request #18 from XYOracleNetwork/feature/deferred-observer
Browse files Browse the repository at this point in the history
Feature/deferred observer
  • Loading branch information
jonesmac authored Nov 11, 2024
2 parents e6679e7 + 4a862c8 commit 908a452
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 67 deletions.
19 changes: 12 additions & 7 deletions sdk/src/androidTest/java/network/xyo/client/LocationWitnessTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.rule.GrantPermissionRule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import network.xyo.client.witness.location.info.LocationActivity
import network.xyo.client.witness.location.info.XyoLocationPayload
import network.xyo.client.witness.location.info.XyoLocationWitness
Expand All @@ -26,13 +29,15 @@ class LocationWitnessTest {
// Get the application context
val context = ApplicationProvider.getApplicationContext<Context>()

val witness = XyoLocationWitness()
val payload = witness.observe(context)
CoroutineScope(Dispatchers.Main).launch {
val witness = XyoLocationWitness()
val payload = witness.observe(context)

assertInstanceOf<XyoLocationPayload>(payload)
assert(payload.schema == "network.xyo.location.android")
assert((payload.currentLocation) !== null)
assert(payload.currentLocation?.coords?.latitude !== null)
assert(payload.currentLocation?.coords?.longitude !== null)
assertInstanceOf<XyoLocationPayload>(payload)
assert(payload.schema == "network.xyo.location.android")
assert((payload.currentLocation) !== null)
assert(payload.currentLocation?.coords?.latitude !== null)
assert(payload.currentLocation?.coords?.longitude !== null)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package network.xyo.client

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import network.xyo.client.witness.system.info.XyoSystemInfoPayload
import network.xyo.client.witness.system.info.XyoSystemInfoWitness
import org.junit.Test
Expand All @@ -13,12 +16,14 @@ class SystemInfoWitnessTest {
// Get the application context
val context = ApplicationProvider.getApplicationContext<Context>()

val witness = XyoSystemInfoWitness()
val payload = witness.observe(context)
CoroutineScope(Dispatchers.Main).launch {
val witness = XyoSystemInfoWitness()
val payload = witness.observe(context)

assertInstanceOf<XyoSystemInfoPayload>(payload)
assert(payload.os != null)
assert(payload.device != null)
assert(payload.network != null)
assertInstanceOf<XyoSystemInfoPayload>(payload)
assert(payload.os != null)
assert(payload.device != null)
assert(payload.network != null)
}
}
}
24 changes: 15 additions & 9 deletions sdk/src/androidTest/java/network/xyo/client/XyoPayloadTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package network.xyo.client
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import network.xyo.client.address.XyoAccount
import network.xyo.client.boundwitness.XyoBoundWitnessBuilder
import network.xyo.client.payload.XyoPayload
Expand Down Expand Up @@ -93,14 +96,17 @@ class XyoPayloadTest {
val witness = XyoWitness(address, fun(_: Context, _: String?): XyoPayload {
return BasicPayload()
})
val response = arrayListOf(witness.observe(appContext))
val payloads = response.mapNotNull { payload -> payload }
val bwJson = XyoBoundWitnessBuilder()
.payloads(payloads)
.witnesses(arrayListOf(witness))
.build()
val bwJsonString = XyoSerializable.toJson(bwJson)
val bwMirrored = XyoSerializable.fromJson(bwJsonString, bwJson)
assertNotNull(bwMirrored)

CoroutineScope(Dispatchers.Main).launch {
val response = arrayListOf(witness.observe(appContext))
val payloads = response.mapNotNull { payload -> payload }
val bwJson = XyoBoundWitnessBuilder()
.payloads(payloads)
.witnesses(arrayListOf(witness))
.build()
val bwJsonString = XyoSerializable.toJson(bwJson)
val bwMirrored = XyoSerializable.fromJson(bwJsonString, bwJson)
assertNotNull(bwMirrored)
}
}
}
4 changes: 2 additions & 2 deletions sdk/src/main/java/network/xyo/client/XyoPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class XyoPanel(val context: Context, private val archivists: List<XyoArchivistAp
}
}

private fun generateBoundWitnessJson(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): XyoBoundWitnessJson {
private suspend fun generateBoundWitnessJson(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): XyoBoundWitnessJson {
val witnesses: List<XyoWitness<XyoPayload>> = (this.witnesses ?: emptyList()).plus(adhocWitnesses)
val payloads = generatePayloads()
return XyoBoundWitnessBuilder()
Expand All @@ -143,7 +143,7 @@ class XyoPanel(val context: Context, private val archivists: List<XyoArchivistAp
}


private fun generatePayloads(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): List<XyoPayload> {
private suspend fun generatePayloads(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): List<XyoPayload> {
val witnesses: List<XyoWitness<XyoPayload>> = (this.witnesses ?: emptyList()).plus(adhocWitnesses)
val payloads = witnesses.map { witness ->
witness.observe(context)
Expand Down
21 changes: 18 additions & 3 deletions sdk/src/main/java/network/xyo/client/XyoWitness.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,35 @@ import androidx.annotation.RequiresApi
import network.xyo.client.address.XyoAccount
import network.xyo.client.payload.XyoPayload

abstract class DeferredObserver<out T: XyoPayload> {
suspend abstract fun deferredDetect(context: Context, previousHash: String?): T?
}

@RequiresApi(Build.VERSION_CODES.M)
open class XyoWitness<out T: XyoPayload> (
val address: XyoAccount = XyoAccount(),
private val observer: ((context: Context, previousHash: String) -> T?)? = null,
var previousHash: String = ""
var previousHash: String = "",
val deferredObserver: DeferredObserver<T>? = null
) {

constructor(
observer: ((context: Context, previousHash: String) -> T?)?,
previousHash: String = "",
account: XyoAccount = XyoAccount()
): this(account, observer, previousHash)
): this(account, observer, previousHash, null)

open fun observe(context: Context): T? {
constructor(
observer: DeferredObserver<T>?,
previousHash: String = "",
account: XyoAccount = XyoAccount()
): this(account, null, previousHash, observer)

open suspend fun observe(context: Context): T? {
if (deferredObserver !== null) {
val payload = deferredObserver.deferredDetect(context, previousHash)
return payload
}
observer?.let {
val payload = it(context, previousHash)
payload?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,36 @@ import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
import android.util.Log
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.squareup.moshi.JsonClass
import kotlinx.coroutines.suspendCancellableCoroutine
import network.xyo.client.XyoSerializable
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.coroutines.resumeWithException

@JsonClass(generateAdapter = true)
class XyoLocationCurrent {
companion object {

@SuppressLint("MissingPermission")
fun detect(context: Context): CurrentLocation? {
suspend fun detect(context: Context): CurrentLocation? {
if (LocationPermissions.check((context)) && LocationPermissions.checkGooglePlayServices(context)) {
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
var coordinates: Coordinates? = null

try {
val latch = CountDownLatch(1)

fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
if (location != null) {
Log.w("xyoClient", "Location was found")
Log.w("xyoClient", "lat: ${location.latitude}, long: ${location.longitude}")
coordinates = setCoordinatesFromLocation(location)
// countDown to zero to lift the latch
latch.countDown()
} else {
// countDown to zero to lift the latch
// latch.countDown()
Log.e("xyoClient","Location not available")
}
val fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context)
return suspendCancellableCoroutine { continuation ->
fusedLocationProviderClient.lastLocation
.addOnSuccessListener { location ->
val coordinates = setCoordinatesFromLocation(location)
val currentLocation = CurrentLocation(coordinates, System.currentTimeMillis())
// Resume the coroutine with the retrieved location
continuation.resumeWith(Result.success(currentLocation))
}
.addOnFailureListener {
Log.e("xyoClient","Failed to get location: ${it.message}")
.addOnFailureListener { exception ->
// Resume the coroutine with an exception if the task fails
continuation.resumeWithException(exception)
}
// Wait for up to 5 seconds for the location
latch.await(15, TimeUnit.SECONDS)

if (coordinates == null) {
return null
} else {
val currentLocation = CurrentLocation(coordinates!!, System.currentTimeMillis())
val serialized = XyoSerializable.toJson(currentLocation)
Log.i("xyoClient", "serialized currentLocation: ${serialized}")
return currentLocation
}
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class XyoLocationPayload (
companion object {

@SuppressLint("MissingPermission")
fun detect(context: Context): XyoLocationPayload? {
suspend fun detect(context: Context): XyoLocationPayload? {
return XyoLocationPayload(
XyoLocationCurrent.detect(context)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ package network.xyo.client.witness.location.info
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import network.xyo.client.DeferredObserver
import network.xyo.client.XyoWitness
import network.xyo.client.address.XyoAccount

class DeferredLocationObserver : DeferredObserver<XyoLocationPayload>() {
override suspend fun deferredDetect(
context: Context,
previousHash: String?
): XyoLocationPayload? {
return XyoLocationPayload.detect(context)
}
}

@RequiresApi(Build.VERSION_CODES.M)
class XyoLocationWitness(address: XyoAccount = XyoAccount()) : XyoWitness<XyoLocationPayload>(
address,
fun (context: Context, _: String?): XyoLocationPayload? {
return XyoLocationPayload.detect(context)
})
DeferredLocationObserver(),
"",
address
)

0 comments on commit 908a452

Please sign in to comment.