diff --git a/CODEOWNERS b/CODEOWNERS index 3e5ad6203..0d996c3e0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,8 +1,9 @@ * @yrezgui @kkuan2011 -/compose/ @android/devrel-compose +/ai/ @android/devrel-ai /car/ @android/devrel-car +/compose/ @android/devrel-compose +/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/ @android/devrel-adaptive-apps /watchface/ @android/devrel-wear /wear/ @android/devrel-wear /wearcompanion/ @android/devrel-wear /xr/ @android/devrel-xr -/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/ @android/devrel-adaptive-apps diff --git a/ai/build.gradle.kts b/ai/build.gradle.kts new file mode 100644 index 000000000..71a1f330c --- /dev/null +++ b/ai/build.gradle.kts @@ -0,0 +1,93 @@ + +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.ksp) + alias(libs.plugins.hilt) + alias(libs.plugins.compose.compiler) +} + +android { + compileSdk = libs.versions.compileSdk.get().toInt() + namespace = "com.example.snippets" + + defaultConfig { + applicationId = "com.example.snippets" + minSdk = libs.versions.minSdk.get().toInt() + targetSdk = libs.versions.targetSdk.get().toInt() + versionCode = 1 + versionName = "1.0" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + kotlin { + jvmToolchain(17) + } + + buildTypes { + getByName("debug") { + signingConfig = signingConfigs.getByName("debug") + } + + getByName("release") { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + buildFeatures { + compose = true + // Disable unused AGP features + viewBinding = true + } + +} +dependencies { + val composeBom = platform(libs.androidx.compose.bom) + implementation(composeBom) + androidTestImplementation(composeBom) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.activity.compose) + + implementation(libs.androidx.appfunctions) + implementation(libs.androidx.appfunctions.service) + ksp(libs.androidx.appfunctions.compiler) + + implementation(libs.androidx.compose.runtime) + implementation(libs.androidx.compose.foundation) + implementation(libs.androidx.compose.foundation.layout) + implementation(libs.androidx.compose.ui.util) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.media3.common) + implementation(libs.androidx.media3.exoplayer) + implementation(libs.androidx.tracing) + implementation(libs.androidx.work.runtime) + + implementation(libs.hilt.android) + implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.kotlinx.serialization.json) + ksp(libs.hilt.compiler) + ksp(libs.kotlinx.metadata.jvm) + + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.lifecycle.runtime) + implementation(libs.androidx.window) + implementation(libs.androidx.startup.runtime) + implementation(libs.androidx.window.java) + implementation(libs.appcompat) + implementation(platform(libs.firebase.bom)) + implementation(libs.firebase.ai) + implementation(libs.guava.android) + implementation(libs.reactive.streams) + testImplementation(libs.junit) + testImplementation(kotlin("test")) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.junit) + androidTestImplementation(libs.androidx.test.core) + androidTestImplementation(libs.androidx.test.runner) + androidTestImplementation(libs.androidx.test.espresso.core) +} diff --git a/ai/proguard-rules.pro b/ai/proguard-rules.pro new file mode 100644 index 000000000..2f9dc5a47 --- /dev/null +++ b/ai/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle.kts. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/ai/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestJavaSnippets.java b/ai/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestJavaSnippets.java new file mode 100644 index 000000000..ba249b0e6 --- /dev/null +++ b/ai/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestJavaSnippets.java @@ -0,0 +1,51 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import org.junit.Rule; +import org.junit.Test; +import static org.junit.Assert.assertFalse; + +public class DeviceCompatibilityModeTestJavaSnippets { + + // [START android_device_compatibility_mode_assert_isLetterboxed_java] + @Rule + public ActivityScenarioRule rule = new ActivityScenarioRule<>(MainActivity.class); + + @Test + public void activity_launched_notLetterBoxed() { + try (ActivityScenario scenario = + ActivityScenario.launch(MainActivity.class)) { + scenario.onActivity( activity -> { + assertFalse(activity.isLetterboxed()); + }); + } + } + // [END android_device_compatibility_mode_assert_isLetterboxed_java] + + + // Class used by snippets. + + class MainActivity extends AppCompatActivity { + public boolean isLetterboxed() { + return true; + } + } +} diff --git a/ai/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestKotlinSnippets.kt b/ai/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestKotlinSnippets.kt new file mode 100644 index 000000000..65f9a7f1f --- /dev/null +++ b/ai/src/androidTest/java/com/example/snippets/DeviceCompatibilityModeTestKotlinSnippets.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets + +import androidx.appcompat.app.AppCompatActivity +import androidx.test.ext.junit.rules.ActivityScenarioRule +import org.junit.Assert.assertFalse +import org.junit.Rule +import org.junit.Test + +class DeviceCompatibilityModeTestKotlinSnippets { + + // [START android_device_compatibility_mode_assert_isLetterboxed_kotlin] + @get:Rule + val activityRule = ActivityScenarioRule(MainActivity::class.java) + + @Test + fun activity_launched_notLetterBoxed() { + activityRule.scenario.onActivity { + assertFalse(it.isLetterboxed()) + } + } + // [END android_device_compatibility_mode_assert_isLetterboxed_kotlin] + + // Class used by snippets. + + class MainActivity : AppCompatActivity() { + fun isLetterboxed(): Boolean { + return true + } + } +} diff --git a/ai/src/main/AndroidManifest.xml b/ai/src/main/AndroidManifest.xml new file mode 100644 index 000000000..10d3b5e39 --- /dev/null +++ b/ai/src/main/AndroidManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ai/src/main/java/com/example/snippets/MainActivity.kt b/ai/src/main/java/com/example/snippets/MainActivity.kt new file mode 100644 index 000000000..d4f2e4389 --- /dev/null +++ b/ai/src/main/java/com/example/snippets/MainActivity.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.ui.Modifier +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.example.snippets.navigation.LandingScreen +import com.example.snippets.ui.theme.SnippetsTheme +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class MainActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + SnippetsTheme { + val navController = rememberNavController() + // A surface container using the 'background' color from the theme + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + NavHost(navController, startDestination = "LandingScreen") { + composable("LandingScreen") { + LandingScreen { navController.navigate(it.route) } + } + } + } + } + } + } +} diff --git a/misc/src/main/java/com/example/snippets/ai/AppFunctionsApiSnippets.kt b/ai/src/main/java/com/example/snippets/ai/AppFunctionsApiSnippets.kt similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/AppFunctionsApiSnippets.kt rename to ai/src/main/java/com/example/snippets/ai/AppFunctionsApiSnippets.kt diff --git a/misc/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippets.kt b/ai/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippets.kt similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippets.kt rename to ai/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippets.kt diff --git a/misc/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippetsJava.java b/ai/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippetsJava.java similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippetsJava.java rename to ai/src/main/java/com/example/snippets/ai/GeminiDeveloperApiSnippetsJava.java diff --git a/misc/src/main/java/com/example/snippets/ai/GeminiOverview.kt b/ai/src/main/java/com/example/snippets/ai/GeminiOverview.kt similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/GeminiOverview.kt rename to ai/src/main/java/com/example/snippets/ai/GeminiOverview.kt diff --git a/misc/src/main/java/com/example/snippets/ai/GeminiOverviewJava.java b/ai/src/main/java/com/example/snippets/ai/GeminiOverviewJava.java similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/GeminiOverviewJava.java rename to ai/src/main/java/com/example/snippets/ai/GeminiOverviewJava.java diff --git a/misc/src/main/java/com/example/snippets/ai/ImagenSnippets.kt b/ai/src/main/java/com/example/snippets/ai/ImagenSnippets.kt similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/ImagenSnippets.kt rename to ai/src/main/java/com/example/snippets/ai/ImagenSnippets.kt diff --git a/misc/src/main/java/com/example/snippets/ai/ImagenSnippetsJava.java b/ai/src/main/java/com/example/snippets/ai/ImagenSnippetsJava.java similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/ImagenSnippetsJava.java rename to ai/src/main/java/com/example/snippets/ai/ImagenSnippetsJava.java diff --git a/misc/src/main/java/com/example/snippets/ai/VertexAiGeminiApi.kt b/ai/src/main/java/com/example/snippets/ai/VertexAiGeminiApi.kt similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/VertexAiGeminiApi.kt rename to ai/src/main/java/com/example/snippets/ai/VertexAiGeminiApi.kt diff --git a/misc/src/main/java/com/example/snippets/ai/VertexAiGeminiApiJava.java b/ai/src/main/java/com/example/snippets/ai/VertexAiGeminiApiJava.java similarity index 100% rename from misc/src/main/java/com/example/snippets/ai/VertexAiGeminiApiJava.java rename to ai/src/main/java/com/example/snippets/ai/VertexAiGeminiApiJava.java diff --git a/ai/src/main/java/com/example/snippets/navigation/Destination.kt b/ai/src/main/java/com/example/snippets/navigation/Destination.kt new file mode 100644 index 000000000..64c44f400 --- /dev/null +++ b/ai/src/main/java/com/example/snippets/navigation/Destination.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets.navigation + +enum class Destination(val route: String, val title: String) { + // Add your example here +} diff --git a/ai/src/main/java/com/example/snippets/navigation/LandingScreen.kt b/ai/src/main/java/com/example/snippets/navigation/LandingScreen.kt new file mode 100644 index 000000000..f096906dd --- /dev/null +++ b/ai/src/main/java/com/example/snippets/navigation/LandingScreen.kt @@ -0,0 +1,101 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets.navigation + +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ListItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LandingScreen( + navigate: (Destination) -> Unit +) { + Scaffold( + topBar = { + TopAppBar(title = { + Text(text = "Android snippets",) + }) + } + ) { padding -> + NavigationItems(modifier = Modifier.padding(padding)) { navigate(it) } + } +} + +@Composable +fun NavigationItems( + modifier: Modifier = Modifier, + navigate: (Destination) -> Unit +) { + LazyColumn( + modifier = modifier + .fillMaxSize(), + verticalArrangement = Arrangement.spacedBy(8.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + items(Destination.entries) { destination -> + NavigationItem(destination) { + navigate( + destination + ) + } + } + } +} + +@Composable +fun NavigationItem(destination: Destination, onClick: () -> Unit) { + ListItem( + headlineContent = { + Text(destination.title) + }, + modifier = Modifier + .heightIn(min = 48.dp) + .clickable { + onClick() + } + ) +} diff --git a/ai/src/main/java/com/example/snippets/ui/theme/Color.kt b/ai/src/main/java/com/example/snippets/ui/theme/Color.kt new file mode 100644 index 000000000..662ef48ff --- /dev/null +++ b/ai/src/main/java/com/example/snippets/ui/theme/Color.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) diff --git a/ai/src/main/java/com/example/snippets/ui/theme/Theme.kt b/ai/src/main/java/com/example/snippets/ui/theme/Theme.kt new file mode 100644 index 000000000..4dcf62e85 --- /dev/null +++ b/ai/src/main/java/com/example/snippets/ui/theme/Theme.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets.ui.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun SnippetsTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} diff --git a/ai/src/main/java/com/example/snippets/ui/theme/Type.kt b/ai/src/main/java/com/example/snippets/ui/theme/Type.kt new file mode 100644 index 000000000..db2e63291 --- /dev/null +++ b/ai/src/main/java/com/example/snippets/ui/theme/Type.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.snippets.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) diff --git a/ai/src/main/res/drawable/ic_launcher_background.xml b/ai/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 000000000..e6202fbb1 --- /dev/null +++ b/ai/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ai/src/main/res/drawable/ic_launcher_foreground.xml b/ai/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 000000000..8760078c8 --- /dev/null +++ b/ai/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + diff --git a/ai/src/main/res/drawable/scones.xml b/ai/src/main/res/drawable/scones.xml new file mode 100644 index 000000000..2eafb40af --- /dev/null +++ b/ai/src/main/res/drawable/scones.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/ai/src/main/res/layout/activity_main.xml b/ai/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..778d7a011 --- /dev/null +++ b/ai/src/main/res/layout/activity_main.xml @@ -0,0 +1,54 @@ + + + + +