Skip to content

Commit

Permalink
Merge pull request #317 from radarlabs/start-tracking-verified
Browse files Browse the repository at this point in the history
startTrackingVerified()
  • Loading branch information
nickpatrick authored Jan 31, 2024
2 parents 0faa952 + 8bc38dd commit 671be51
Show file tree
Hide file tree
Showing 6 changed files with 436 additions and 103 deletions.
12 changes: 11 additions & 1 deletion example/src/main/java/io/radar/example/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.radar.example

import android.Manifest
import android.content.Context
import android.location.Location
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -12,6 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import io.radar.sdk.Radar
import io.radar.sdk.RadarTrackingOptions
import io.radar.sdk.RadarTripOptions
import io.radar.sdk.RadarVerifiedReceiver
import org.json.JSONObject
import java.util.*

Expand All @@ -26,6 +28,14 @@ class MainActivity : AppCompatActivity() {
val receiver = MyRadarReceiver()
Radar.initialize(this, "prj_test_pk_0000000000000000000000000000000000000000", receiver, Radar.RadarLocationServicesProvider.GOOGLE, true)
Radar.sdkVersion()?.let { Log.i("version", it) }

val verifiedReceiver = object : RadarVerifiedReceiver() {
override fun onTokenUpdated(context: Context, token: String) {
Log.i("example", "Token updated to $token")
}
}
Radar.setVerifiedReceiver(verifiedReceiver)

requestLocationPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { isGrantedMap ->
Expand Down Expand Up @@ -239,4 +249,4 @@ class MainActivity : AppCompatActivity() {
}
}

}
}
2 changes: 1 addition & 1 deletion sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ apply plugin: "org.jetbrains.dokka"
apply plugin: 'io.radar.mvnpublish'

ext {
radarVersion = '3.9.1'
radarVersion = '3.9.2'
}

String buildNumber = ".${System.currentTimeMillis()}"
Expand Down
150 changes: 64 additions & 86 deletions sdk/src/main/java/io/radar/sdk/Radar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,6 @@ object Radar {
METRIC
}


/**
* The verification status of an address.
*/
Expand All @@ -425,8 +424,9 @@ object Radar {
internal var initialized = false
internal var isFlushingReplays = false
private lateinit var context: Context
private lateinit var handler: Handler
internal lateinit var handler: Handler
private var receiver: RadarReceiver? = null
private var verifiedReceiver: RadarVerifiedReceiver? = null
internal lateinit var logger: RadarLogger
internal lateinit var apiClient: RadarApiClient
internal lateinit var locationManager: RadarLocationManager
Expand Down Expand Up @@ -946,63 +946,24 @@ object Radar {
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[beacons] A boolean indicating whether to range beacons.
* @param[callback] An optional callback.
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JvmStatic
fun trackVerified(callback: RadarTrackCallback? = null) {
fun trackVerified(beacons: Boolean = false, callback: RadarTrackCallback? = null) {
if (!initialized) {
callback?.onComplete(RadarStatus.ERROR_PUBLISHABLE_KEY)

return
}
this.logger.i("trackVerified()", RadarLogType.SDK_CALL)

if (!this::verificationManager.isInitialized) {
this.verificationManager = RadarVerificationManager(this.context, this.logger)
}

val googlePlayProjectNumber = RadarSettings.getGooglePlayProjectNumber(this.context);

if (googlePlayProjectNumber == 0.toLong()) {
this.logger.e("Missing Google Play Services project number", RadarLogType.SDK_ERROR)
callback?.onComplete(RadarStatus.ERROR_BAD_REQUEST)
return
}

locationManager.getLocation(RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH, RadarLocationSource.FOREGROUND_LOCATION, object : RadarLocationCallback {
override fun onComplete(status: RadarStatus, location: Location?, stopped: Boolean) {
if (status != RadarStatus.SUCCESS || location == null) {
handler.post {
callback?.onComplete(status)
}

return
}

val requestHash = verificationManager.getRequestHash(location);

verificationManager.getIntegrityToken(googlePlayProjectNumber, requestHash) { integrityToken, integrityException ->
apiClient.track(location, RadarState.getStopped(context), RadarActivityLifecycleCallbacks.foreground, RadarLocationSource.FOREGROUND_LOCATION, false, null, true, integrityToken, integrityException, false, callback = object : RadarApiClient.RadarTrackApiCallback {
override fun onComplete(
status: RadarStatus,
res: JSONObject?,
events: Array<RadarEvent>?,
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
if (status == RadarStatus.SUCCESS ){
locationManager.updateTrackingFromMeta(config?.meta)
}
handler.post {
callback?.onComplete(status, location, events, user)
}
}
})
}
}
})
this.verificationManager.trackVerified(beacons, callback)
}

/**
Expand All @@ -1012,12 +973,13 @@ object Radar {
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[beacons] A boolean indicating whether to range beacons.
* @param[block] A block callback.
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JvmStatic
fun trackVerified(block: (status: RadarStatus, location: Location?, events: Array<RadarEvent>?, user: RadarUser?) -> Unit) {
trackVerified(object : RadarTrackCallback {
fun trackVerified(beacons: Boolean = false, block: (status: RadarStatus, location: Location?, events: Array<RadarEvent>?, user: RadarUser?) -> Unit) {
trackVerified(beacons, object : RadarTrackCallback {
override fun onComplete(status: RadarStatus, location: Location?, events: Array<RadarEvent>?, user: RadarUser?) {
block(status, location, events, user)
}
Expand All @@ -1031,57 +993,24 @@ object Radar {
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[beacons] A boolean indicating whether to range beacons.
* @param[callback] An optional callback.
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JvmStatic
fun trackVerifiedToken(callback: RadarTrackTokenCallback? = null) {
fun trackVerifiedToken(beacons: Boolean = false, callback: RadarTrackTokenCallback? = null) {
if (!initialized) {
callback?.onComplete(RadarStatus.ERROR_PUBLISHABLE_KEY)

return
}
this.logger.i("trackVerifiedToken()", RadarLogType.SDK_CALL)

if (!this::verificationManager.isInitialized) {
this.verificationManager = RadarVerificationManager(this.context, this.logger)
}

val googlePlayProjectNumber = RadarSettings.getGooglePlayProjectNumber(this.context);

locationManager.getLocation(RadarTrackingOptions.RadarTrackingOptionsDesiredAccuracy.HIGH, RadarLocationSource.FOREGROUND_LOCATION, object : RadarLocationCallback {
override fun onComplete(status: RadarStatus, location: Location?, stopped: Boolean) {
if (status != RadarStatus.SUCCESS || location == null) {
handler.post {
callback?.onComplete(status)
}

return
}

val requestHash = verificationManager.getRequestHash(location);

verificationManager.getIntegrityToken(googlePlayProjectNumber, requestHash) { integrityToken, integrityException ->
apiClient.track(location, RadarState.getStopped(context), RadarActivityLifecycleCallbacks.foreground, RadarLocationSource.FOREGROUND_LOCATION, false, null, true, integrityToken, integrityException, true, object : RadarApiClient.RadarTrackApiCallback {
override fun onComplete(
status: RadarStatus,
res: JSONObject?,
events: Array<RadarEvent>?,
user: RadarUser?,
nearbyGeofences: Array<RadarGeofence>?,
config: RadarConfig?,
token: String?
) {
if (status == RadarStatus.SUCCESS ){
locationManager.updateTrackingFromMeta(config?.meta)
}
handler.post {
callback?.onComplete(status, token)
}
}
})
}
}
})
this.verificationManager.trackVerifiedToken(beacons, callback)
}

/**
Expand All @@ -1091,18 +1020,45 @@ object Radar {
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[beacons] A boolean indicating whether to range beacons.
* @param[block] A block callback.
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JvmStatic
fun trackVerifiedToken(block: (status: RadarStatus, token: String?) -> Unit) {
trackVerifiedToken(object : RadarTrackTokenCallback {
fun trackVerifiedToken(beacons: Boolean = false, block: (status: RadarStatus, token: String?) -> Unit) {
trackVerifiedToken(beacons, object : RadarTrackTokenCallback {
override fun onComplete(status: RadarStatus, token: String?) {
block(status, token)
}
})
}

/**
* Starts tracking the user's location with device integrity information for location verification use cases.
*
* Note that you must configure SSL pinning before calling this method.
*
* @see [](https://radar.com/documentation/fraud)
*
* @param[token] A boolean indicating whether to return a JSON Web Token (JWT). If `true`, tokens are delivered to your `RadarVerifiedReceiver`. If `false`, location updates are delivered to your `RadarReceiver`.
* @param[interval] The interval in seconds between each location update.
* @param[beacons] A boolean indicating whether to range beacons.
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JvmStatic
fun startTrackingVerified(token: Boolean, interval: Int, beacons: Boolean) {
if (!initialized) {
return
}
this.logger.i("startTrackingVerified()", RadarLogType.SDK_CALL)

if (!this::verificationManager.isInitialized) {
this.verificationManager = RadarVerificationManager(this.context, this.logger)
}

this.verificationManager.startTrackingVerified(token, interval, beacons)
}

/**
* Starts tracking the user's location in the background.
*
Expand Down Expand Up @@ -1378,6 +1334,22 @@ object Radar {
this.receiver = receiver
}

/**
* Sets a receiver for client-side delivery of verified location tokens.
*
* @see [](https://radar.com/documentation/sdk/fraud)
*
* @param[verifiedReceiver] A delegate for client-side delivery of of verified location tokens. If `null`, the previous receiver will be cleared.
*/
@JvmStatic
fun setVerifiedReceiver(verifiedReceiver: RadarVerifiedReceiver?) {
if (!initialized) {
return
}

this.verifiedReceiver = verifiedReceiver
}

/**
* Accepts an event. Events can be accepted after user check-ins or other forms of verification. Event verifications will be used to improve the accuracy and confidence level of future events.
*
Expand Down Expand Up @@ -3419,6 +3391,12 @@ object Radar {
}
}

internal fun sendToken(token: String) {
verifiedReceiver?.onTokenUpdated(context, token)

logger.i("📍️ Radar token updated | token = $token")
}

internal fun setLogPersistenceFeatureFlag(enabled: Boolean) {
this.logBuffer.setPersistentLogFeatureFlag(enabled)
}
Expand Down
4 changes: 4 additions & 0 deletions sdk/src/main/java/io/radar/sdk/RadarApiClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@ internal class RadarApiClient(
if (encrypted == true) {
callback?.onComplete(status, res, null, null, null, null, token)

if (token != null) {
Radar.sendToken(token)
}

return
}

Expand Down
Loading

0 comments on commit 671be51

Please sign in to comment.