diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 12247e54..01a07bbc 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -25,6 +25,7 @@ plugins { alias(libs.plugins.google.services) alias(libs.plugins.crashlytics) alias(libs.plugins.baselineprofile) + id("com.google.android.gms.oss-licenses-plugin") } android { @@ -111,6 +112,10 @@ dependencies { implementation(libs.firebase.appcheck.debug) implementation(libs.androidx.window) + implementation(libs.androidx.appcompat) + implementation(libs.google.oss.licenses) { + exclude(group = "androidx.appcompat") + } implementation(projects.feature.camera) implementation(projects.feature.creation) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9703a00c..800707ec 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -78,6 +78,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt b/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt index 1ff5936b..7327d87d 100644 --- a/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt +++ b/app/src/main/java/com/android/developers/androidify/navigation/MainNavigation.kt @@ -17,6 +17,7 @@ package com.android.developers.androidify.navigation +import android.content.Intent import androidx.compose.animation.ContentTransform import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.fadeIn @@ -29,6 +30,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.IntOffset import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator import androidx.navigation3.runtime.entry @@ -40,6 +42,8 @@ import com.android.developers.androidify.creation.CreationScreen import com.android.developers.androidify.home.AboutScreen import com.android.developers.androidify.home.HomeScreen import com.android.developers.androidify.theme.transitions.ColorSplashTransitionScreen +import com.google.android.gms.oss.licenses.OssLicensesActivity +import com.google.android.gms.oss.licenses.OssLicensesMenuActivity @ExperimentalMaterial3ExpressiveApi @Composable @@ -110,10 +114,14 @@ fun MainNavigation() { ) } entry { + val context = LocalContext.current AboutScreen( onBackPressed = { backStack.removeLastOrNull() }, + onLicensesClicked = { + context.startActivity(Intent(context, OssLicensesMenuActivity::class.java)) + } ) } }, diff --git a/app/src/main/res/values-v35/themes.xml b/app/src/main/res/values-v35/themes.xml new file mode 100644 index 00000000..4aea359f --- /dev/null +++ b/app/src/main/res/values-v35/themes.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 6e62f6c0..76d828e1 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -17,4 +17,12 @@ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 97047974..a6d51dc2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,15 @@ plugins { alias(libs.plugins.baselineprofile) apply false alias(libs.plugins.spotless) apply false } - +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath(libs.google.oss.licenses.plugin) + } +} subprojects { apply(plugin = "com.diffplug.spotless") diff --git a/feature/home/build.gradle.kts b/feature/home/build.gradle.kts index 857cb716..61ff0d12 100644 --- a/feature/home/build.gradle.kts +++ b/feature/home/build.gradle.kts @@ -59,6 +59,9 @@ dependencies { implementation(libs.androidx.hilt.navigation.compose) implementation(libs.androidx.media3.exoplayer) implementation(libs.androidx.media3.ui.compose) + implementation(libs.google.oss.licenses) { + exclude(group = "androidx.appcompat") + } ksp(libs.hilt.compiler) implementation(libs.ai.edge) { diff --git a/feature/home/src/main/java/com/android/developers/androidify/home/AboutScreen.kt b/feature/home/src/main/java/com/android/developers/androidify/home/AboutScreen.kt index 393d7b17..30ab9028 100644 --- a/feature/home/src/main/java/com/android/developers/androidify/home/AboutScreen.kt +++ b/feature/home/src/main/java/com/android/developers/androidify/home/AboutScreen.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -69,7 +70,7 @@ import com.android.developers.androidify.util.isAtLeastMedium @Composable private fun AboutPreviewCompact() { SharedElementContextPreview { - AboutScreen(isMediumWindowSize = false) {} + AboutScreen(isMediumWindowSize = false, {}, {}) } } @@ -77,7 +78,7 @@ private fun AboutPreviewCompact() { @Composable private fun AboutPreviewLargeScreens() { SharedElementContextPreview { - AboutScreen(isMediumWindowSize = true) {} + AboutScreen(isMediumWindowSize = true, {}, {}) } } @@ -85,6 +86,7 @@ private fun AboutPreviewLargeScreens() { fun AboutScreen( isMediumWindowSize: Boolean = isAtLeastMedium(), onBackPressed: () -> Unit, + onLicensesClicked: () -> Unit ) { val sharedElementScope = LocalSharedTransitionScope.current val navScope = LocalNavAnimatedContentScope.current @@ -163,7 +165,8 @@ fun AboutScreen( ) } Spacer(Modifier.size(48.dp)) - FooterButtons(modifier = Modifier.padding(bottom = 8.dp)) + FooterButtons(modifier = Modifier.padding(bottom = 8.dp), + onLicensesClicked) } } } else { @@ -197,7 +200,7 @@ fun AboutScreen( stringResource(R.string.about_step3_label), ) Spacer(modifier = Modifier.size(24.dp)) - FooterButtons(modifier = Modifier.padding(bottom = 8.dp)) + FooterButtons(modifier = Modifier.padding(bottom = 8.dp), onLicensesClicked) } } } @@ -205,22 +208,28 @@ fun AboutScreen( } @Composable -private fun FooterButtons(modifier: Modifier = Modifier) { +private fun FooterButtons(modifier: Modifier = Modifier, + onLicensesClicked: () -> Unit) { val uriHandler = LocalUriHandler.current - Row(modifier) { + FlowRow(modifier, horizontalArrangement = Arrangement.spacedBy(16.dp)) { SecondaryOutlinedButton( onClick = { uriHandler.openUri("https://policies.google.com/terms") }, buttonText = stringResource(R.string.terms), ) - Spacer(modifier = Modifier.size(16.dp)) SecondaryOutlinedButton( onClick = { uriHandler.openUri("https://policies.google.com/privacy") }, buttonText = stringResource(R.string.privacy), ) + SecondaryOutlinedButton( + onClick = { + onLicensesClicked() + }, + buttonText = stringResource(R.string.oss_license), + ) } } diff --git a/feature/home/src/main/res/values/strings.xml b/feature/home/src/main/res/values/strings.xml index dfc502a0..cdb99eed 100644 --- a/feature/home/src/main/res/values/strings.xml +++ b/feature/home/src/main/res/values/strings.xml @@ -36,4 +36,5 @@ Pause Terms Privacy + Licenses diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cfc0f5f5..8a0135d0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -28,6 +28,8 @@ espressoCore = "3.6.1" firebaseBom = "33.14.0" firebaseConfigKtx = "22.1.1" googleServices = "4.4.2" +googleOss = "17.1.0" +googleOssPlugin = "0.10.6" hiltAndroid = "2.56.2" hiltLifecycleViewmodel = "1.0.0-alpha03" hiltNavigationCompose = "1.2.0" @@ -130,7 +132,8 @@ androidx-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomato androidx-benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "benchmarkMacroJunit4" } androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "profileinstaller" } ai-edge = { group = "com.google.ai.edge.aicore", name = "aicore", version.ref = "aiEdge" } - +google-oss-licenses = { group = "com.google.android.gms", name = "play-services-oss-licenses", version.ref = "googleOss" } +google-oss-licenses-plugin = { group = "com.google.android.gms", name = "oss-licenses-plugin", version.ref = "googleOssPlugin" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" }