Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ material3WindowSizeClass = "1.3.2"
richtext = "1.0.0-alpha02"
glimmer = "1.0.0-alpha08"
projected = "1.0.0-alpha05"
coreKtxVersion = "1.6.1"
truth = "1.4.4"
robolectric = "4.16.1"
mockitoKotlin = "4.1.0"
runner = "1.6.1"


[libraries]
Expand Down Expand Up @@ -89,6 +94,12 @@ androidx-lifecycle-viewmodel-android = { group = "androidx.lifecycle", name = "l
androidx-exifinterface = { group = "androidx.exifinterface", name = "exifinterface", version.ref = "exifinterface" }
androidx-xr-glimmer = { group = "androidx.xr.glimmer", name = "glimmer", version.ref = "glimmer" }
androidx-xr-projected = { group = "androidx.xr.projected", name = "projected", version.ref = "projected" }
androidx-projected-testing = { group = "androidx.xr.projected", name = "projected-testing", version.ref = "projected" }
core-ktx = { group = "androidx.test", name = "core-ktx", version.ref = "coreKtxVersion" }
truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "robolectric" }
mockito-kotlin = { group = "org.mockito.kotlin", name = "mockito-kotlin", version.ref = "mockitoKotlin" }
androidx-runner = { group = "androidx.test", name = "runner", version.ref = "runner" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
Expand Down
14 changes: 14 additions & 0 deletions samples/gemini-live-todo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ android {
kotlinOptions {
jvmTarget = "17"
}
testOptions {
unitTests {
isIncludeAndroidResources = true
}
}
}

dependencies {
Expand All @@ -69,7 +74,16 @@ dependencies {
implementation(libs.hilt.navigation.compose)
implementation(libs.androidx.activity.compose)
implementation(libs.kotlinx.serialization.json)


testImplementation(libs.junit)
testImplementation(libs.androidx.junit)
testImplementation(libs.androidx.projected.testing)
testImplementation(libs.truth)
testImplementation(libs.robolectric)
testImplementation(libs.core.ktx)
testImplementation(libs.mockito.kotlin)

androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.android.ai.samples.geminilivetodo

import android.content.Context
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.xr.projected.ProjectedContext
import androidx.xr.projected.ProjectedDeviceController
import androidx.xr.projected.ProjectedDeviceController.Capability.Companion.CAPABILITY_VISUAL_UI
import androidx.xr.projected.experimental.ExperimentalProjectedApi
import androidx.xr.projected.testing.ProjectedTestRule
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertThrows
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
import kotlin.intArrayOf

@OptIn(ExperimentalProjectedApi::class)
@Config(sdk = [Build.VERSION_CODES.BAKLAVA])
@RunWith(AndroidJUnit4::class)
class ProjectedContextTests {
@get:Rule
val projectedTestRule = ProjectedTestRule()

private val context: Context
get() = ApplicationProvider.getApplicationContext()

@Test
fun app_initializesProjectedContext_whenDeviceIsConnected() {
val projectedContext = ProjectedContext.createProjectedDeviceContext(context)
assertThat(projectedContext).isNotNull()
}

@Test
fun app_throwsException_whenDeviceDisconnected() {
projectedTestRule.isDeviceConnected = false

assertThrows(IllegalStateException::class.java) {
ProjectedContext.createProjectedDeviceContext(context)
}
}


@Test
fun capabilities_includesVisualUiByDefault_returnsCapabilityVisualUi() {
projectedTestRule.launchTestProjectedDeviceActivity { activity ->
val projectedDeviceController = runBlocking {
ProjectedDeviceController.create(activity)
}

assertThat(projectedDeviceController.capabilities).contains(CAPABILITY_VISUAL_UI)
}
}

@Test
fun capabilities_emptyCapabilities_doesNotReturnCapabilityVisualUi() {
projectedTestRule.launchTestProjectedDeviceActivity { activity ->
projectedTestRule.capabilities = setOf()

val projectedDeviceController = runBlocking {
ProjectedDeviceController.create(activity)
}

assertThat(projectedDeviceController.capabilities).doesNotContain(CAPABILITY_VISUAL_UI)
}
}
}