diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt new file mode 100644 index 0000000000..4eb04b3f93 --- /dev/null +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt @@ -0,0 +1,97 @@ +package com.example.llama.ui.components + +import android.content.Intent +import android.llama.cpp.ArmFeature +import android.llama.cpp.ArmFeaturesMapper +import android.llama.cpp.LLamaTier +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MultiChoiceSegmentedButtonRow +import androidx.compose.material3.SegmentedButton +import androidx.compose.material3.SegmentedButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontWeight +import androidx.core.net.toUri +import kotlin.math.sqrt + +/** + * ARM Features visualization using segmented buttons. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ArmFeaturesVisualizer( + detectedTier: LLamaTier?, + modifier: Modifier = Modifier, + onFeatureClick: ((ArmFeature) -> Unit)? = null +) { + val featuresData = remember(detectedTier) { + ArmFeaturesMapper.getFeatureDisplayData(detectedTier) + } + + Column( + modifier = modifier.fillMaxWidth() + ) { + // Segmented Button Row for Features + MultiChoiceSegmentedButtonRow( + modifier = Modifier.fillMaxWidth() + ) { + featuresData.forEachIndexed { index, item -> + val weight = sqrt(item.feature.displayName.length.toFloat()) + + SegmentedButton( + modifier = Modifier.weight(weight), + shape = SegmentedButtonDefaults.itemShape( + index = index, + count = featuresData.size + ), + icon = {}, + onCheckedChange = { onFeatureClick?.invoke(item.feature) }, + checked = item.isSupported, + ) { + Text( + text = item.feature.displayName, + style = MaterialTheme.typography.labelSmall, + fontWeight = if (item.isSupported) { + FontWeight.Medium + } else { + FontWeight.Light + }, + color = if (item.isSupported) { + MaterialTheme.colorScheme.onSurface + } else { + MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) + } + ) + } + } + } + } +} + +/** + * Alternative version with clickable features that open ARM documentation. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ArmFeaturesVisualizerClickable( + detectedTier: LLamaTier?, + modifier: Modifier = Modifier +) { + val context = LocalContext.current + + ArmFeaturesVisualizer( + detectedTier = detectedTier, + modifier = modifier, + onFeatureClick = { feature -> + // Open ARM documentation in browser + val intent = Intent(Intent.ACTION_VIEW, feature.armDocUrl.toUri()) + context.startActivity(intent) + } + ) +} diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt index 5f9fbad12d..de416fbe95 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.example.llama.APP_NAME import com.example.llama.data.preferences.UserPreferences +import com.example.llama.ui.components.ArmFeaturesVisualizerClickable import com.example.llama.viewmodel.SettingsViewModel /** @@ -38,6 +39,7 @@ fun SettingsGeneralScreen( val isMonitoringEnabled by viewModel.isMonitoringEnabled.collectAsState() val useFahrenheit by viewModel.useFahrenheitUnit.collectAsState() val themeMode by viewModel.themeMode.collectAsState() + val detectedTier = viewModel.detectedTier Column( modifier = Modifier @@ -110,33 +112,67 @@ fun SettingsGeneralScreen( } } - SettingsCategory(title = "About") { - Card( - modifier = Modifier.fillMaxWidth() + // ARM Features Visualizer with Tier Information description + SettingsCategory(title = "About your device") { + Column( + modifier = Modifier.padding(16.dp) ) { - Column( - modifier = Modifier.padding(16.dp) - ) { - Text( - text = APP_NAME, - style = MaterialTheme.typography.titleLarge - ) + Text( + text = "ARM Capabilities", + style = MaterialTheme.typography.titleLarge + ) - Text( - text = "Version 1.0.0", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurfaceVariant - ) + Text( + text = "Hardware-accelerated AI features", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + + detectedTier?.let { tier -> + Spacer(modifier = Modifier.height(8.dp)) + + ArmFeaturesVisualizerClickable(detectedTier = detectedTier) Spacer(modifier = Modifier.height(8.dp)) Text( - text = "Local inference for LLM models on your device.", - style = MaterialTheme.typography.bodyMedium + text = "Optimization Tier: ${tier.name}", + style = MaterialTheme.typography.bodyLarge + ) + + Text( + text = tier.description, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 4.dp) ) } } } + + SettingsCategory(title = "About this app") { + Column( + modifier = Modifier.padding(16.dp) + ) { + Text( + text = APP_NAME, + style = MaterialTheme.typography.titleLarge + ) + + Text( + text = "Version 1.0.0", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + + Spacer(modifier = Modifier.height(8.dp)) + + Text( + text = "Local inference for LLM models on your device powered by ArmĀ® technologies.", + style = MaterialTheme.typography.bodyLarge + ) + } + } } }