Skip to content

Commit a099493

Browse files
committed
add background dispatcher
1 parent 7f071cd commit a099493

File tree

7 files changed

+40
-18
lines changed

7 files changed

+40
-18
lines changed

firebase-vertexai/api.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -818,14 +818,6 @@ package com.google.firebase.vertexai.type {
818818
property public final com.google.firebase.vertexai.type.Voices voice;
819819
}
820820

821-
public final class StreamOutput {
822-
ctor public StreamOutput(boolean interrupted, com.google.firebase.vertexai.type.Content? data);
823-
method public com.google.firebase.vertexai.type.Content? getData();
824-
method public boolean getInterrupted();
825-
property public final com.google.firebase.vertexai.type.Content? data;
826-
property public final boolean interrupted;
827-
}
828-
829821
public abstract class StringFormat {
830822
}
831823

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/FirebaseVertexAI.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package com.google.firebase.vertexai
1919
import android.util.Log
2020
import com.google.firebase.Firebase
2121
import com.google.firebase.FirebaseApp
22+
import com.google.firebase.annotations.concurrent.Background
2223
import com.google.firebase.app
2324
import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider
2425
import com.google.firebase.auth.internal.InternalAuthProvider
@@ -34,11 +35,13 @@ import com.google.firebase.vertexai.type.RequestOptions
3435
import com.google.firebase.vertexai.type.SafetySetting
3536
import com.google.firebase.vertexai.type.Tool
3637
import com.google.firebase.vertexai.type.ToolConfig
38+
import kotlin.coroutines.CoroutineContext
3739

3840
/** Entry point for all _Vertex AI for Firebase_ functionality. */
3941
public class FirebaseVertexAI
4042
internal constructor(
4143
private val firebaseApp: FirebaseApp,
44+
@Background private val backgroundDispatcher: CoroutineContext,
4245
private val location: String,
4346
private val appCheckProvider: Provider<InteropAppCheckTokenProvider>,
4447
private val internalAuthProvider: Provider<InternalAuthProvider>,
@@ -130,6 +133,7 @@ internal constructor(
130133
"projects/${firebaseApp.options.projectId}/locations/${location}/publishers/google/models/${modelName}",
131134
firebaseApp.options.apiKey,
132135
firebaseApp,
136+
backgroundDispatcher,
133137
generationConfig,
134138
tools,
135139
systemInstruction,

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/FirebaseVertexAIMultiResourceComponent.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ package com.google.firebase.vertexai
1818

1919
import androidx.annotation.GuardedBy
2020
import com.google.firebase.FirebaseApp
21+
import com.google.firebase.annotations.concurrent.Background
2122
import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider
2223
import com.google.firebase.auth.internal.InternalAuthProvider
2324
import com.google.firebase.inject.Provider
25+
import kotlin.coroutines.CoroutineContext
2426

2527
/**
2628
* Multi-resource container for Firebase Vertex AI.
@@ -29,17 +31,23 @@ import com.google.firebase.inject.Provider
2931
*/
3032
internal class FirebaseVertexAIMultiResourceComponent(
3133
private val app: FirebaseApp,
34+
@Background val backgroundDispatcher: CoroutineContext,
3235
private val appCheckProvider: Provider<InteropAppCheckTokenProvider>,
33-
private val internalAuthProvider: Provider<InternalAuthProvider>
36+
private val internalAuthProvider: Provider<InternalAuthProvider>,
3437
) {
3538

3639
@GuardedBy("this") private val instances: MutableMap<String, FirebaseVertexAI> = mutableMapOf()
3740

3841
fun get(location: String): FirebaseVertexAI =
3942
synchronized(this) {
4043
instances[location]
41-
?: FirebaseVertexAI(app, location, appCheckProvider, internalAuthProvider).also {
42-
instances[location] = it
43-
}
44+
?: FirebaseVertexAI(
45+
app,
46+
backgroundDispatcher,
47+
location,
48+
appCheckProvider,
49+
internalAuthProvider
50+
)
51+
.also { instances[location] = it }
4452
}
4553
}

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/FirebaseVertexAIRegistrar.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ package com.google.firebase.vertexai
1818

1919
import androidx.annotation.Keep
2020
import com.google.firebase.FirebaseApp
21+
import com.google.firebase.annotations.concurrent.Background
2122
import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider
2223
import com.google.firebase.auth.internal.InternalAuthProvider
2324
import com.google.firebase.components.Component
2425
import com.google.firebase.components.ComponentRegistrar
2526
import com.google.firebase.components.Dependency
27+
import com.google.firebase.components.Qualified
2628
import com.google.firebase.components.Qualified.unqualified
2729
import com.google.firebase.platforminfo.LibraryVersionComponent
30+
import kotlinx.coroutines.CoroutineDispatcher
2831

2932
/**
3033
* [ComponentRegistrar] for setting up [FirebaseVertexAI] and its internal dependencies.
@@ -38,11 +41,13 @@ internal class FirebaseVertexAIRegistrar : ComponentRegistrar {
3841
Component.builder(FirebaseVertexAIMultiResourceComponent::class.java)
3942
.name(LIBRARY_NAME)
4043
.add(Dependency.required(firebaseApp))
44+
.add(Dependency.required(backgroundDispatcher))
4145
.add(Dependency.optionalProvider(appCheckInterop))
4246
.add(Dependency.optionalProvider(internalAuthProvider))
4347
.factory { container ->
4448
FirebaseVertexAIMultiResourceComponent(
4549
container[firebaseApp],
50+
container.get(backgroundDispatcher),
4651
container.getProvider(appCheckInterop),
4752
container.getProvider(internalAuthProvider)
4853
)
@@ -57,5 +62,7 @@ internal class FirebaseVertexAIRegistrar : ComponentRegistrar {
5762
private val firebaseApp = unqualified(FirebaseApp::class.java)
5863
private val appCheckInterop = unqualified(InteropAppCheckTokenProvider::class.java)
5964
private val internalAuthProvider = unqualified(InternalAuthProvider::class.java)
65+
private val backgroundDispatcher =
66+
Qualified.qualified(Background::class.java, CoroutineDispatcher::class.java)
6067
}
6168
}

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/LiveGenerativeModel.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.firebase.vertexai
1818

1919
import com.google.firebase.FirebaseApp
20+
import com.google.firebase.annotations.concurrent.Background
2021
import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider
2122
import com.google.firebase.auth.internal.InternalAuthProvider
2223
import com.google.firebase.vertexai.common.APIController
@@ -31,6 +32,7 @@ import com.google.firebase.vertexai.type.Tool
3132
import io.ktor.websocket.Frame
3233
import io.ktor.websocket.close
3334
import io.ktor.websocket.readBytes
35+
import kotlin.coroutines.CoroutineContext
3436
import kotlinx.serialization.encodeToString
3537
import kotlinx.serialization.json.Json
3638

@@ -41,6 +43,7 @@ import kotlinx.serialization.json.Json
4143
public class LiveGenerativeModel
4244
internal constructor(
4345
private val modelName: String,
46+
@Background private val backgroundDispatcher: CoroutineContext,
4447
private val config: LiveGenerationConfig? = null,
4548
private val tools: List<Tool>? = null,
4649
private val systemInstruction: Content? = null,
@@ -51,6 +54,7 @@ internal constructor(
5154
modelName: String,
5255
apiKey: String,
5356
firebaseApp: FirebaseApp,
57+
backgroundDispatcher: CoroutineContext,
5458
config: LiveGenerationConfig? = null,
5559
tools: List<Tool>? = null,
5660
systemInstruction: Content? = null,
@@ -60,6 +64,7 @@ internal constructor(
6064
internalAuthProvider: InternalAuthProvider? = null,
6165
) : this(
6266
modelName,
67+
backgroundDispatcher,
6368
config,
6469
tools,
6570
systemInstruction,
@@ -94,7 +99,11 @@ internal constructor(
9499
val receivedJson = webSession.incoming.receive().readBytes().toString(Charsets.UTF_8)
95100
// TODO: Try to decode the json instead of string matching.
96101
return if (receivedJson.contains("setupComplete")) {
97-
LiveSession(session = webSession, isRecording = false)
102+
LiveSession(
103+
session = webSession,
104+
backgroundDispatcher = backgroundDispatcher,
105+
isRecording = false
106+
)
98107
} else {
99108
webSession.close()
100109
throw GeminiConnectionHandshakeFailed()

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/type/LiveSession.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ package com.google.firebase.vertexai.type
1818

1919
import android.media.AudioFormat
2020
import android.media.AudioTrack
21+
import com.google.firebase.annotations.concurrent.Background
2122
import io.ktor.client.plugins.websocket.ClientWebSocketSession
2223
import io.ktor.websocket.Frame
2324
import io.ktor.websocket.close
2425
import io.ktor.websocket.readBytes
2526
import java.util.concurrent.ConcurrentLinkedQueue
27+
import kotlin.coroutines.CoroutineContext
2628
import kotlinx.coroutines.CoroutineScope
2729
import kotlinx.coroutines.Dispatchers
2830
import kotlinx.coroutines.cancel
@@ -42,6 +44,7 @@ import kotlinx.serialization.json.JsonNull
4244
public class LiveSession
4345
internal constructor(
4446
private val session: ClientWebSocketSession?,
47+
@Background private val backgroundDispatcher: CoroutineContext,
4548
private var isRecording: Boolean,
4649
private var audioHelper: AudioHelper? = null
4750
) {
@@ -133,7 +136,7 @@ internal constructor(
133136
}
134137

135138
private fun fillRecordedAudioQueue() {
136-
CoroutineScope(Dispatchers.IO).launch {
139+
CoroutineScope(backgroundDispatcher).launch {
137140
audioHelper!!.startRecording().collect {
138141
if (!isRecording) {
139142
cancel()
@@ -159,7 +162,7 @@ internal constructor(
159162
}
160163

161164
private fun fillServerResponseAudioQueue() {
162-
CoroutineScope(Dispatchers.Default).launch {
165+
CoroutineScope(backgroundDispatcher).launch {
163166
receive(listOf(ContentModality.AUDIO)).collect {
164167
if (!isRecording) {
165168
cancel()
@@ -182,7 +185,7 @@ internal constructor(
182185
}
183186

184187
private fun playServerResponseAudio() {
185-
CoroutineScope(Dispatchers.IO).launch {
188+
CoroutineScope(backgroundDispatcher).launch {
186189
while (isRecording) {
187190
val x = playBackQueue.poll() ?: continue
188191
audioHelper?.playAudio(x)
@@ -202,7 +205,6 @@ internal constructor(
202205
isRecording = true
203206
audioHelper = AudioHelper()
204207
audioHelper!!.setupAudioTrack()
205-
val scope = CoroutineScope(Dispatchers.Default)
206208
fillRecordedAudioQueue()
207209
CoroutineScope(Dispatchers.Default).launch { sendAudioDataToServer() }
208210
fillServerResponseAudioQueue()

firebase-vertexai/src/main/kotlin/com/google/firebase/vertexai/type/MediaData.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import android.util.Base64
2020
import kotlinx.serialization.SerialName
2121
import kotlinx.serialization.Serializable
2222

23-
/* Class to represent the media data that needs to be sent to the server. */
23+
/* Represent the media data that needs to be sent to the server. */
2424
public class MediaData(public val mimeType: String, public val data: ByteArray) {
2525
@Serializable
2626
internal class Internal(@SerialName("mimeType") val mimeType: String, val data: String)

0 commit comments

Comments
 (0)