Skip to content

Commit

Permalink
Fix setting the Liveness user agent string
Browse files Browse the repository at this point in the history
  • Loading branch information
mattcreaser committed Sep 11, 2023
1 parent 58eb461 commit 4cd41d8
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.amplifyframework.annotations.InternalAmplifyApi;
Expand Down Expand Up @@ -310,6 +311,45 @@ public InterpretOperation<?> interpret(
return operation;
}

/**
* Starts a Liveness session.
* @param sessionId ID for the session to start.
* @param sessionInformation Information about the face liveness session.
* @param onSessionStarted Called when the face liveness session has been started.
* @param onComplete Called when the session is complete.
* @param onError Called when an error occurs during the session.
*/
@InternalAmplifyApi
public static void startFaceLivenessSession(@NonNull String sessionId,
@NonNull FaceLivenessSessionInformation sessionInformation,
@NonNull Consumer<FaceLivenessSession> onSessionStarted,
@NonNull Action onComplete,
@NonNull Consumer<PredictionsException> onError) {
startFaceLivenessSession(sessionId, sessionInformation, FaceLivenessSessionOptions.defaults(),
onSessionStarted, onComplete, onError);
}

/**
* Starts a Liveness session with the given options.
* @param sessionId ID for the session to start.
* @param sessionInformation Information about the face liveness session.
* @param options The options for this session.
* @param onSessionStarted Called when the face liveness session has been started.
* @param onComplete Called when the session is complete.
* @param onError Called when an error occurs during the session.
*/
@InternalAmplifyApi
public static void startFaceLivenessSession(@NonNull String sessionId,
@NonNull FaceLivenessSessionInformation sessionInformation,
@NonNull FaceLivenessSessionOptions options,
@NonNull Consumer<FaceLivenessSession> onSessionStarted,
@NonNull Action onComplete,
@NonNull Consumer<PredictionsException> onError) {

startFaceLivenessSession(sessionId, sessionInformation, options, null,
onSessionStarted, onComplete, onError);
}

/**
* Starts a Liveness session.
* @param sessionId ID for the session to start.
Expand All @@ -322,7 +362,7 @@ public InterpretOperation<?> interpret(
@InternalAmplifyApi
public static void startFaceLivenessSession(@NonNull String sessionId,
@NonNull FaceLivenessSessionInformation sessionInformation,
@NonNull String livenessVersion,
@Nullable String livenessVersion,
@NonNull Consumer<FaceLivenessSession> onSessionStarted,
@NonNull Action onComplete,
@NonNull Consumer<PredictionsException> onError) {
Expand All @@ -344,7 +384,7 @@ public static void startFaceLivenessSession(@NonNull String sessionId,
public static void startFaceLivenessSession(@NonNull String sessionId,
@NonNull FaceLivenessSessionInformation sessionInformation,
@NonNull FaceLivenessSessionOptions options,
@NonNull String livenessVersion,
@Nullable String livenessVersion,
@NonNull Consumer<FaceLivenessSession> onSessionStarted,
@NonNull Action onComplete,
@NonNull Consumer<PredictionsException> onError) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal class LivenessWebSocket(
val endpoint: String,
val region: String,
val sessionInformation: FaceLivenessSessionInformation,
val livenessVersion: String = "",
val livenessVersion: String?,
val onSessionInformationReceived: Consumer<SessionInformation>,
val onErrorReceived: Consumer<PredictionsException>,
val onComplete: Action
Expand Down Expand Up @@ -199,14 +199,14 @@ internal class LivenessWebSocket(
}

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun getUserAgent(livenessVersion: String = ""): String {
fun getUserAgent(): String {
val amplifyVersion = BuildConfig.VERSION_NAME
val deviceManufacturer = Build.MANUFACTURER.replace(" ", "_")
val deviceName = Build.MODEL.replace(" ", "_")
var userAgent = "${UserAgent.string()} os/Android/${Build.VERSION.SDK_INT} md/device/$deviceName " +
"md/device-manufacturer/$deviceManufacturer api/rekognitionstreaming/$amplifyVersion"

if (livenessVersion != "") {
if (!livenessVersion.isNullOrBlank()) {
userAgent += " api/liveness/$livenessVersion"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ internal class RunFaceLivenessSession(
sessionId: String,
sessionInformation: FaceLivenessSessionInformation,
val credentialsProvider: CredentialsProvider,
livenessVersion: String,
livenessVersion: String?,
onSessionStarted: Consumer<FaceLivenessSession>,
onComplete: Action,
onError: Consumer<PredictionsException>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ import org.robolectric.RobolectricTestRunner
internal class LivenessWebSocketTest {
private val json = Json { encodeDefaults = true }

private lateinit var livenessWebSocket: LivenessWebSocket
private lateinit var server: MockWebServer

private val onComplete = mockk<Action>(relaxed = true)
Expand All @@ -79,7 +78,11 @@ internal class LivenessWebSocketTest {
private val credentialsProvider = object : CredentialsProvider {
override suspend fun resolve(attributes: Attributes): Credentials {
return Credentials(
"", "", "", null, ""
"",
"",
"",
null,
""
)
}
}
Expand All @@ -88,19 +91,7 @@ internal class LivenessWebSocketTest {
@Before
fun setUp() {
Dispatchers.setMain(Dispatchers.Unconfined)

server = MockWebServer()

livenessWebSocket = LivenessWebSocket(
credentialsProvider,
server.url("/").toString(),
"",
sessionInformation,
"",
onSessionInformationReceived,
onErrorReceived,
onComplete
)
}

@After
Expand All @@ -112,6 +103,7 @@ internal class LivenessWebSocketTest {
@Test
fun `onClosing informs webSocket`() {
val webSocket = mockk<WebSocket>(relaxed = true)
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.webSocket = webSocket

livenessWebSocket.webSocketListener.onClosing(webSocket, 4, "closing")
Expand All @@ -121,20 +113,23 @@ internal class LivenessWebSocketTest {

@Test
fun `normal status onClosed calls onComplete`() {
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.webSocketListener.onClosed(mockk(), 1000, "closing")

verify { onComplete.call() }
}

@Test
fun `bad status onClosed calls onError`() {
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.webSocketListener.onClosed(mockk(), 5000, "closing")

verify { onErrorReceived.accept(any()) }
}

@Test
fun `onClosed does not call onError if client stopped`() {
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.clientStoppedSession = true

livenessWebSocket.webSocketListener.onClosed(mockk(), 5000, "closing")
Expand All @@ -144,6 +139,7 @@ internal class LivenessWebSocketTest {

@Test
fun `onFailure calls onError`() {
val livenessWebSocket = createLivenessWebSocket()
// Response does noted like to be mockk
val response = Response.Builder()
.code(200)
Expand All @@ -159,6 +155,7 @@ internal class LivenessWebSocketTest {

@Test
fun `onFailure does not call onError if client stopped`() {
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.clientStoppedSession = true
// Response does noted like to be mockk
val response = Response.Builder()
Expand All @@ -175,6 +172,7 @@ internal class LivenessWebSocketTest {

@Test
fun `web socket assigned on open`() {
val livenessWebSocket = createLivenessWebSocket()
val openLatch = CountDownLatch(1)
val latchingListener = LatchingWebSocketResponseListener(
livenessWebSocket.webSocketListener,
Expand Down Expand Up @@ -203,6 +201,7 @@ internal class LivenessWebSocketTest {

@Test
fun `server session event tracked`() {
val livenessWebSocket = createLivenessWebSocket()
val event = ServerSessionInformationEvent(
sessionInformation = SessionInformation(
challenge = ServerChallenge(
Expand Down Expand Up @@ -244,6 +243,7 @@ internal class LivenessWebSocketTest {

@Test
fun `disconnect event stops websocket`() {
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.webSocket = mockk()
val event = DisconnectionEvent(1)
val headers = mapOf(
Expand All @@ -262,6 +262,7 @@ internal class LivenessWebSocketTest {

@Test
fun `web socket error closes websocket`() {
val livenessWebSocket = createLivenessWebSocket()
livenessWebSocket.webSocket = mockk()
val event = ValidationException("ValidationException")
val headers = mapOf(
Expand All @@ -279,7 +280,20 @@ internal class LivenessWebSocketTest {
}

@Test
fun `web socket user agent base`() {
fun `web socket user agent with null UI version`() {
val livenessWebSocket = createLivenessWebSocket(livenessVersion = null)
livenessWebSocket.webSocket = mockk()

val version = BuildConfig.VERSION_NAME
val os = Build.VERSION.SDK_INT
val baseline = "amplify-android:$version md/unknown/robolectric md/locale/en_UNKNOWN os/Android/$os " +
"md/device/robolectric md/device-manufacturer/unknown api/rekognitionstreaming/$version"
assertEquals(livenessWebSocket.getUserAgent(), baseline)
}

@Test
fun `web socket user agent with blank UI version`() {
val livenessWebSocket = createLivenessWebSocket(livenessVersion = " ")
livenessWebSocket.webSocket = mockk()

val version = BuildConfig.VERSION_NAME
Expand All @@ -291,14 +305,15 @@ internal class LivenessWebSocketTest {

@Test
fun `web socket user agent includes added UI version`() {
val livenessWebSocket = createLivenessWebSocket(livenessVersion = "1.1.1")
livenessWebSocket.webSocket = mockk()

val version = BuildConfig.VERSION_NAME
val os = Build.VERSION.SDK_INT
val baseline = "amplify-android:$version md/unknown/robolectric md/locale/en_UNKNOWN os/Android/$os " +
"md/device/robolectric md/device-manufacturer/unknown api/rekognitionstreaming/$version"
val additional = "api/liveness/1.1.1"
assertEquals(livenessWebSocket.getUserAgent("1.1.1"), "$baseline $additional")
assertEquals(livenessWebSocket.getUserAgent(), "$baseline $additional")
}

@Test
Expand All @@ -325,6 +340,19 @@ internal class LivenessWebSocketTest {
@Ignore("Need to work on parsing the onMessage byteString from ServerWebSocketListener")
fun `sendVideoEvent test`() {
}

private fun createLivenessWebSocket(
livenessVersion: String? = null
) = LivenessWebSocket(
credentialsProvider,
server.url("/").toString(),
"",
sessionInformation,
livenessVersion,
onSessionInformationReceived,
onErrorReceived,
onComplete
)
}

class LatchingWebSocketResponseListener(
Expand Down

0 comments on commit 4cd41d8

Please sign in to comment.