@@ -77,6 +77,7 @@ import com.android.ai.uicomponent.GenerateButton
7777import com.android.ai.uicomponent.SampleDetailTopAppBar
7878import com.android.ai.uicomponent.UndoButton
7979import com.google.firebase.ai.InferenceMode
80+ import com.google.firebase.ai.OnDeviceModelOption
8081import com.google.firebase.ai.type.PublicPreviewAPI
8182
8283
@@ -135,6 +136,9 @@ fun GeminiHybridScreen(viewModel: GeminiHybridViewModel = hiltViewModel()) {
135136 onTagToggle = viewModel::toggleTag,
136137 selectedMode = uiState.selectedMode,
137138 onModeSelected = viewModel::setInferenceMode,
139+ selectedModelOption = uiState.selectedModelOption,
140+ onModelOptionSelected = viewModel::setModelOption,
141+ isPreviewModelAvailable = uiState.isPreviewModelAvailable,
138142 onGenerate = {
139143 val tagStrings =
140144 uiState.selectedTags.map { ContextCompat .getString(context, it) }
@@ -185,6 +189,9 @@ fun InitialReviewUi(
185189 onTagToggle : (Int ) -> Unit ,
186190 selectedMode : InferenceMode ,
187191 onModeSelected : (InferenceMode ) -> Unit ,
192+ selectedModelOption : OnDeviceModelOption ? ,
193+ onModelOptionSelected : (OnDeviceModelOption ? ) -> Unit ,
194+ isPreviewModelAvailable : Boolean ,
188195 onGenerate : () -> Unit ,
189196) {
190197 Text (
@@ -219,6 +226,12 @@ fun InitialReviewUi(
219226 selectedMode = selectedMode,
220227 onModeSelected = onModeSelected,
221228 )
229+ if (isPreviewModelAvailable) {
230+ ModelOptionDropdown (
231+ selectedOption = selectedModelOption,
232+ onOptionSelected = onModelOptionSelected,
233+ )
234+ }
222235
223236 GenerateButton (
224237 text = stringResource(R .string.gemini_hybrid_generate_btn),
@@ -457,6 +470,66 @@ fun InferenceModeDropdown(
457470 }
458471}
459472
473+ @PublicPreviewAPI
474+ @Composable
475+ fun ModelOptionDropdown (
476+ selectedOption : OnDeviceModelOption ? ,
477+ onOptionSelected : (OnDeviceModelOption ? ) -> Unit ,
478+ modifier : Modifier = Modifier ,
479+ ) {
480+ var expanded by remember { mutableStateOf(false ) }
481+ val options = listOf (
482+ null to stringResource(R .string.gemini_hybrid_model_default),
483+ OnDeviceModelOption .PREVIEW to stringResource(R .string.gemini_hybrid_model_preview),
484+ OnDeviceModelOption .PREVIEW_FAST to stringResource(R .string.gemini_hybrid_model_preview_fast),
485+ )
486+ val selectedText = options.find { it.first == selectedOption }?.second ? : " "
487+
488+ Box (modifier = modifier.padding(start = 8 .dp, top = 12 .dp)) {
489+ SplitButtonLayout (
490+ leadingButton = {
491+ SplitButtonDefaults .LeadingButton (
492+ onClick = { expanded = true },
493+ colors = ButtonDefaults .buttonColors(
494+ containerColor = MaterialTheme .colorScheme.tertiaryContainer,
495+ contentColor = MaterialTheme .colorScheme.onTertiaryContainer,
496+ ),
497+ ) {
498+ Text (selectedText)
499+ }
500+ },
501+ trailingButton = {
502+ SplitButtonDefaults .TrailingButton (
503+ onClick = { expanded = true },
504+ colors = ButtonDefaults .buttonColors(
505+ containerColor = MaterialTheme .colorScheme.tertiaryContainer,
506+ contentColor = MaterialTheme .colorScheme.onTertiaryContainer,
507+ ),
508+ ) {
509+ Icon (
510+ imageVector = Icons .Default .ArrowDropDown ,
511+ contentDescription = null ,
512+ )
513+ }
514+ },
515+ )
516+ DropdownMenu (
517+ expanded = expanded,
518+ onDismissRequest = { expanded = false },
519+ ) {
520+ options.forEach { (option, label) ->
521+ DropdownMenuItem (
522+ text = { Text (label) },
523+ onClick = {
524+ onOptionSelected(option)
525+ expanded = false
526+ },
527+ )
528+ }
529+ }
530+ }
531+ }
532+
460533@Composable
461534fun StatusText (text : String ) {
462535 Text (
0 commit comments