Skip to content
Merged
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
23 changes: 14 additions & 9 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ plugins {
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.jetbrains.kotlin.serialization)
alias(libs.plugins.google.gms.google.services)
alias(libs.plugins.hilt.plugin)
alias(libs.plugins.ksp)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt.plugin)
}

android {
namespace = "com.android.ai.catalog"
compileSdk = 35
compileSdk = 37

defaultConfig {
applicationId = "com.android.ai.catalog"
minSdk = 26
targetSdk = 35
targetSdk = 36
versionCode = 1
versionName = "1.0"

Expand Down Expand Up @@ -61,12 +61,6 @@ android {
}
}

tasks.whenTaskAdded {
if (name.contains("Check", ignoreCase = true) && name.contains("AarMetadata", ignoreCase = true)) {
enabled = false
}
}

dependencies {

implementation(libs.androidx.core.ktx)
Expand All @@ -87,7 +81,18 @@ dependencies {
ksp(libs.hilt.compiler)

implementation(project(":ui-component"))
implementation(project(":samples:gemini-multimodal"))
implementation(project(":samples:gemini-chatbot"))
implementation(project(":samples:genai-summarization"))
implementation(project(":samples:genai-image-description"))
implementation(project(":samples:genai-writing-assistance"))
implementation(project(":samples:nanobanana"))
implementation(project(":samples:magic-selfie"))
implementation(project(":samples:gemini-video-summarization"))
implementation(project(":samples:gemini-live-todo"))
implementation(project(":samples:gemini-video-metadata-creation"))
implementation(project(":samples:gemini-image-chat"))
implementation(project(":samples:gemini-hybrid"))

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
Expand Down
5 changes: 0 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="androidx.xr.projected.CATEGORY_PROJECTED"/>
<category android:name="android.intent.category.XR_PROJECTED_LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.XR_PROJECTED_LAUNCHER"/>
</intent-filter>
</activity>
</application>
Expand Down
110 changes: 110 additions & 0 deletions app/src/main/java/com/android/ai/catalog/domain/SampleCatalog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,123 @@ import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import com.android.ai.catalog.R
import com.android.ai.samples.geminichatbot.GeminiChatbotScreen
import com.android.ai.samples.geminiimagechat.GeminiImageChatScreen
import com.android.ai.samples.geminilivetodo.ui.TodoScreen
import com.android.ai.samples.geminimultimodal.ui.GeminiMultimodalScreen
import com.android.ai.samples.geminivideometadatacreation.ui.VideoMetadataCreationScreen
import com.android.ai.samples.geminivideosummary.ui.VideoSummarizationScreen
import com.android.ai.samples.genai_image_description.GenAIImageDescriptionScreen
import com.android.ai.samples.genai_summarization.GenAISummarizationScreen
import com.android.ai.samples.genai_writing_assistance.GenAIWritingAssistanceScreen
import com.android.ai.samples.geminihybrid.GeminiHybridScreen
import com.android.ai.samples.nanobanana.ui.NanobananaScreen
import com.android.ai.samples.magicselfie.ui.MagicSelfieScreen
import com.android.ai.theme.extendedColorScheme
import com.google.firebase.ai.type.PublicPreviewAPI

@OptIn(PublicPreviewAPI::class)
@RequiresPermission(Manifest.permission.RECORD_AUDIO)
val sampleCatalog = listOf(
SampleCatalogItem(
title = R.string.gemini_hybrid_sample_list_title,
description = R.string.gemini_hybrid_sample_list_description,
route = "GeminiHybridScreen",
sampleEntryScreen = { GeminiHybridScreen() },
tags = listOf(SampleTags.GEMINI_NANO, SampleTags.GEMINI_FLASH, SampleTags.ML_KIT, SampleTags.FIREBASE),
needsFirebase = true,
keyArt = R.drawable.img_keyart_text,
isFeatured = true,
),
SampleCatalogItem(
title = R.string.gemini_image_chat_list_title,
description = R.string.gemini_image_chat_list_description,
route = "GeminiImageChatScreen",
sampleEntryScreen = { GeminiImageChatScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE),
keyArt = R.drawable.img_keyart_chatbot,
needsFirebase = true,
isFeatured = true,
),
SampleCatalogItem(
title = R.string.gemini_multimodal_sample_list_title,
description = R.string.gemini_multimodal_sample_list_description,
route = "GeminiMultimodalScreen",
sampleEntryScreen = { GeminiMultimodalScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE),
needsFirebase = true,
isFeatured = false,
keyArt = R.drawable.img_keyart_multimodal,
),
SampleCatalogItem(
title = R.string.gemini_chatbot_sample_title,
description = R.string.gemini_chatbot_sample_description,
route = "GeminiChitchatScreen",
sampleEntryScreen = { GeminiChatbotScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE),
needsFirebase = true,
keyArt = R.drawable.img_keyart_chatbot,
),
SampleCatalogItem(
title = R.string.genai_summarization_sample_list_title,
description = R.string.genai_summarization_sample_list_description,
route = "GenAISummarizationScreen",
sampleEntryScreen = { GenAISummarizationScreen() },
tags = listOf(SampleTags.GEMINI_NANO, SampleTags.ML_KIT),
keyArt = R.drawable.img_keyart_summary,
),
SampleCatalogItem(
title = R.string.genai_image_description_sample_list_title,
description = R.string.genai_image_description_sample_list_description,
route = "GenAIImageDescriptionScreen",
sampleEntryScreen = { GenAIImageDescriptionScreen() },
tags = listOf(SampleTags.GEMINI_NANO, SampleTags.ML_KIT),
keyArt = R.drawable.img_keyart_img_desc,
),
SampleCatalogItem(
title = R.string.genai_writing_assistance_sample_list_title,
description = R.string.genai_writing_assistance_sample_list_description,
route = "GenAIWritingAssistanceScreen",
sampleEntryScreen = { GenAIWritingAssistanceScreen() },
tags = listOf(SampleTags.GEMINI_NANO, SampleTags.ML_KIT),
keyArt = R.drawable.img_keyart_text,
),
SampleCatalogItem(
title = R.string.nanobanana_sample_list_title,
description = R.string.nanobanana_sample_list_description,
route = "NanobananaImageGenerationScreen",
sampleEntryScreen = { NanobananaScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE),
needsFirebase = true,
keyArt = R.drawable.img_keyart_imagen,
),
SampleCatalogItem(
title = R.string.magic_selfie_sample_list_title,
description = R.string.magic_selfie_sample_list_description,
route = "MagicSelfieScreen",
sampleEntryScreen = { MagicSelfieScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE),
needsFirebase = true,
keyArt = R.drawable.img_keyart_magic_selfie,
),
SampleCatalogItem(
title = R.string.gemini_video_summarization_sample_list_title,
description = R.string.gemini_video_summarization_sample_list_description,
route = "VideoSummarizationScreen",
sampleEntryScreen = { VideoSummarizationScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE, SampleTags.MEDIA3),
keyArt = R.drawable.img_keyart_video_summary,
needsFirebase = true,
),
SampleCatalogItem(
title = R.string.gemini_video_metadata_creation_sample_list_title,
description = R.string.gemini_video_metadata_creation_sample_list_description,
route = "VideoMetadataCreationScreen",
sampleEntryScreen = { VideoMetadataCreationScreen() },
tags = listOf(SampleTags.GEMINI_FLASH, SampleTags.FIREBASE, SampleTags.MEDIA3),
needsFirebase = true,
keyArt = R.drawable.img_keyart_video_summary,
),
SampleCatalogItem(
title = R.string.gemini_live_todo_list_title,
description = R.string.gemini_live_todo_list_description,
Expand Down
7 changes: 0 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ plugins {

subprojects {
apply(plugin = "com.diffplug.spotless")

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "17"
}
}

configure<com.diffplug.gradle.spotless.SpotlessExtension> {
kotlin {
target("**/*.kt")
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ android.uniquePackageNames=false
android.dependency.useConstraints=true
android.r8.strictFullModeForKeepRules=false
android.r8.optimizedResourceShrinking=false
android.aarMetadataCheck.enabled=false
android.builtInKotlin=false
android.newDsl=false
10 changes: 4 additions & 6 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[versions]
agp = "8.9.1"
agp = "9.2.0"
coilCompose = "3.1.0"
firebaseAiOndevice = "16.0.0-beta01"
firebaseBom = "34.11.0"
lifecycleRuntimeCompose = "2.9.1"
mlkitGenAi = "1.0.0-beta1"
kotlin = "2.1.0"
kotlin = "2.2.10"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
Expand All @@ -14,7 +14,7 @@ kotlinxCoroutinesGuava = "1.10.2"
kotlinxSerializationJson = "1.6.2"
lifecycleRuntimeKtx = "2.8.7"
activityCompose = "1.10.1"
composeBom = "2026.03.01"
composeBom = "2025.06.01"
navigationCompose = "2.9.0"
navigationRuntimeKtx = "2.9.0"
appcompat = "1.7.0"
Expand All @@ -36,7 +36,7 @@ uiTextGoogleFonts = "1.8.1"
exifinterface = "1.4.1"
material3WindowSizeClass = "1.3.2"
richtext = "1.0.0-alpha02"
glimmer = "1.0.0-alpha11"
glimmer = "1.0.0-alpha12"
projected = "1.0.0-alpha07"

[libraries]
Expand All @@ -51,7 +51,6 @@ genai-image-description = { module = "com.google.mlkit:genai-image-description",
genai-proofreading = { module = "com.google.mlkit:genai-proofreading", version.ref = "mlkitGenAi" }
genai-rewrite = { module = "com.google.mlkit:genai-rewriting", version.ref = "mlkitGenAi" }
genai-summarization = { module = "com.google.mlkit:genai-summarization", version.ref = "mlkitGenAi" }
mlkit-segmentation = { module = "com.google.android.gms:play-services-mlkit-subject-segmentation", version.ref = "mlkitSegmentation" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
Expand Down Expand Up @@ -89,7 +88,6 @@ ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref =
androidx-lifecycle-viewmodel-android = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-android", version.ref = "lifecycleViewmodelAndroid" }
androidx-exifinterface = { group = "androidx.exifinterface", name = "exifinterface", version.ref = "exifinterface" }
androidx-xr-glimmer = { group = "androidx.xr.glimmer", name = "glimmer", version.ref = "glimmer" }
androidx-xr-glimmer-google-fonts = { group = "androidx.xr.glimmer", name = "glimmer-google-fonts", version.ref = "glimmer" }
androidx-xr-projected = { group = "androidx.xr.projected", name = "projected", version.ref = "projected" }

[plugins]
Expand Down
3 changes: 1 addition & 2 deletions samples/gemini-live-todo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ plugins {

android {
namespace = "com.android.ai.samples.geminilivetodo"
compileSdk = 37
compileSdk = 36

defaultConfig {
minSdk = 24
Expand Down Expand Up @@ -52,7 +52,6 @@ android {

dependencies {
implementation(libs.androidx.xr.glimmer)
implementation(libs.androidx.xr.glimmer.google.fonts)
implementation(libs.androidx.xr.projected)
implementation("com.google.firebase:firebase-ai:17.5.0")
implementation(libs.androidx.core.ktx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.xr.glimmer.GlimmerTheme
import androidx.xr.glimmer.googlefonts.createGoogleSansFlexTypography
import com.android.ai.samples.geminilivetodo.ui.AudioExperience
import com.android.ai.samples.geminilivetodo.ui.GlimmerTodoScreen
import com.android.ai.samples.geminilivetodo.ui.TodoScreenViewModel
import androidx.compose.ui.ComposeUiFlags
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.xr.projected.ProjectedDeviceController
import androidx.xr.projected.ProjectedDeviceController.Capability
import androidx.xr.projected.ProjectedDisplayController
Expand Down Expand Up @@ -60,10 +57,9 @@ class GlassesActivity : ComponentActivity() {
setupContent()
}

@OptIn(ExperimentalComposeUiApi::class, ExperimentalProjectedApi::class)
@OptIn(ExperimentalProjectedApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ComposeUiFlags.isInitialFocusOnFocusableAvailable = true

viewModel.initializeGeminiLive(this)

Expand Down Expand Up @@ -101,20 +97,16 @@ class GlassesActivity : ComponentActivity() {
}
}

@OptIn(ExperimentalProjectedApi::class)
private fun setupContent() {
setContent {
GlimmerTheme(
typography = createGoogleSansFlexTypography(),
content = {
RootScreen(
isGranted = isPermissionsGranted,
isDisplayCapable = isDisplayCapable,
areVisualsOn = areVisualsOn,
viewModel = viewModel
)
}
)
GlimmerTheme {
RootScreen(
isGranted = isPermissionsGranted,
isDisplayCapable = isDisplayCapable,
areVisualsOn = areVisualsOn,
viewModel = viewModel
)
}
}
}

Expand All @@ -129,13 +121,6 @@ class GlassesActivity : ComponentActivity() {
)
)
}

override fun onStop() {
super.onStop()
// Release high-drain resources (camera, mic, sensors)
// to prevent battery drain
viewModel.stopLiveSession()
}
}


Expand Down Expand Up @@ -165,15 +150,12 @@ fun RootScreen(
@Preview(showBackground = true)
@Composable
fun PreviewRootScreen() {
GlimmerTheme(
typography = createGoogleSansFlexTypography(),
content = {
RootScreen(
isGranted = false,
isDisplayCapable = true,
areVisualsOn = true,
viewModel = TodoScreenViewModel(com.android.ai.samples.geminilivetodo.data.TodoRepository())
)
}
)
}
GlimmerTheme {
RootScreen(
isGranted = false,
isDisplayCapable = true,
areVisualsOn = true,
viewModel = TodoScreenViewModel(com.android.ai.samples.geminilivetodo.data.TodoRepository())
)
}
}
Loading