mirror of
https://github.com/google-ai-edge/gallery.git
synced 2025-07-05 14:10:35 -04:00
Add a "view licenses" button in settings dialog to view open source licenses.
- Followed the instructions here: https://developers.google.com/android/guides/opensource - The plugin will automatically parse libs.versions.toml and store the licenses related data in the app bundle as resources. - Use the activities in play-services-oss-licenses library to view the licenses. PiperOrigin-RevId: 776826500
This commit is contained in:
parent
323124a628
commit
a58751eba4
7 changed files with 100 additions and 2 deletions
|
@ -21,6 +21,7 @@ plugins {
|
||||||
alias(libs.plugins.kotlin.serialization)
|
alias(libs.plugins.kotlin.serialization)
|
||||||
alias(libs.plugins.protobuf)
|
alias(libs.plugins.protobuf)
|
||||||
alias(libs.plugins.hilt.application)
|
alias(libs.plugins.hilt.application)
|
||||||
|
alias(libs.plugins.oss.licenses)
|
||||||
kotlin("kapt")
|
kotlin("kapt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ dependencies {
|
||||||
implementation(libs.protobuf.javalite)
|
implementation(libs.protobuf.javalite)
|
||||||
implementation(libs.hilt.android)
|
implementation(libs.hilt.android)
|
||||||
implementation(libs.hilt.navigation.compose)
|
implementation(libs.hilt.navigation.compose)
|
||||||
|
implementation(libs.play.services.oss.licenses)
|
||||||
kapt(libs.hilt.android.compiler)
|
kapt(libs.hilt.android.compiler)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
androidTestImplementation(libs.androidx.junit)
|
||||||
|
|
|
@ -47,12 +47,18 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Gallery"
|
android:theme="@style/Theme.Gallery"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<!--
|
||||||
|
android:configChanges="uiMode" tells the system don't destroy and
|
||||||
|
recreate the activity when UI mode changes (e.g. setting dark mode).
|
||||||
|
Instead, just recompose the view.
|
||||||
|
-->
|
||||||
<activity
|
<activity
|
||||||
android:name="com.google.ai.edge.gallery.MainActivity"
|
android:name="com.google.ai.edge.gallery.MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/Theme.Gallery.SplashScreen"
|
android:theme="@style/Theme.Gallery.SplashScreen"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
|
android:configChanges="uiMode"
|
||||||
tools:ignore="DiscouragedApi,LockedOrientationActivity">
|
tools:ignore="DiscouragedApi,LockedOrientationActivity">
|
||||||
<!-- This is for putting the app into launcher -->
|
<!-- This is for putting the app into launcher -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -71,6 +77,16 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- Set themes for activities that are used for viewing open source licenses -->
|
||||||
|
<activity
|
||||||
|
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@style/Theme.Gallery.OssLicenses" />
|
||||||
|
<activity
|
||||||
|
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:theme="@style/Theme.Gallery.OssLicenses" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.provider"
|
android:authorities="${applicationId}.provider"
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
package com.google.ai.edge.gallery.ui.home
|
package com.google.ai.edge.gallery.ui.home
|
||||||
|
|
||||||
|
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
|
||||||
|
import android.app.UiModeManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
@ -36,6 +41,7 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.rounded.CheckCircle
|
import androidx.compose.material.icons.rounded.CheckCircle
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
@ -55,6 +61,7 @@ import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
@ -73,6 +80,7 @@ import kotlin.math.min
|
||||||
|
|
||||||
private val THEME_OPTIONS = listOf(Theme.THEME_AUTO, Theme.THEME_LIGHT, Theme.THEME_DARK)
|
private val THEME_OPTIONS = listOf(Theme.THEME_AUTO, Theme.THEME_LIGHT, Theme.THEME_DARK)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsDialog(
|
fun SettingsDialog(
|
||||||
curThemeOverride: Theme,
|
curThemeOverride: Theme,
|
||||||
|
@ -127,6 +135,7 @@ fun SettingsDialog(
|
||||||
modifier = Modifier.verticalScroll(rememberScrollState()).weight(1f, fill = false),
|
modifier = Modifier.verticalScroll(rememberScrollState()).weight(1f, fill = false),
|
||||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
// Theme switcher.
|
// Theme switcher.
|
||||||
Column(modifier = Modifier.fillMaxWidth()) {
|
Column(modifier = Modifier.fillMaxWidth()) {
|
||||||
Text(
|
Text(
|
||||||
|
@ -147,6 +156,23 @@ fun SettingsDialog(
|
||||||
|
|
||||||
// Save to data store.
|
// Save to data store.
|
||||||
modelManagerViewModel.saveThemeOverride(theme)
|
modelManagerViewModel.saveThemeOverride(theme)
|
||||||
|
|
||||||
|
// Update ui mode.
|
||||||
|
//
|
||||||
|
// This is necessary to make other Activities launched from MainActivity to have
|
||||||
|
// the correct theme.
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
val uiModeManager =
|
||||||
|
context.applicationContext.getSystemService(Context.UI_MODE_SERVICE)
|
||||||
|
as UiModeManager
|
||||||
|
if (theme == Theme.THEME_AUTO) {
|
||||||
|
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_AUTO)
|
||||||
|
} else if (theme == Theme.THEME_LIGHT) {
|
||||||
|
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_NO)
|
||||||
|
} else {
|
||||||
|
uiModeManager.setApplicationNightMode(UiModeManager.MODE_NIGHT_YES)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
checked = theme == selectedTheme,
|
checked = theme == selectedTheme,
|
||||||
label = { Text(themeLabel(theme)) },
|
label = { Text(themeLabel(theme)) },
|
||||||
|
@ -166,7 +192,7 @@ fun SettingsDialog(
|
||||||
)
|
)
|
||||||
// Show the start of the token.
|
// Show the start of the token.
|
||||||
val curHfToken = hfToken
|
val curHfToken = hfToken
|
||||||
if (curHfToken != null) {
|
if (curHfToken != null && curHfToken.accessToken.isNotEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
curHfToken.accessToken.substring(0, min(16, curHfToken.accessToken.length)) + "...",
|
curHfToken.accessToken.substring(0, min(16, curHfToken.accessToken.length)) + "...",
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
@ -254,6 +280,24 @@ fun SettingsDialog(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Third party licenses.
|
||||||
|
Column(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
Text(
|
||||||
|
"Third-party libraries",
|
||||||
|
style = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Bold),
|
||||||
|
)
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = {
|
||||||
|
// Create an Intent to launch a license viewer that displays a list of
|
||||||
|
// third-party library names. Clicking a name will show its license content.
|
||||||
|
val intent = Intent(context, OssLicensesMenuActivity::class.java)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text("View licenses")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button row.
|
// Button row.
|
||||||
|
|
22
Android/src/app/src/main/res/values-night/themes.xml
Normal file
22
Android/src/app/src/main/res/values-night/themes.xml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2025 Google LLC
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
http://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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<style name="Theme.Gallery.OssLicenses" parent="Theme.AppCompat">
|
||||||
|
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
|
@ -15,10 +15,13 @@
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<resources>
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<style name="Theme.Gallery" parent="android:Theme.Material.Light.NoActionBar" />
|
<style name="Theme.Gallery" parent="android:Theme.Material.Light.NoActionBar" />
|
||||||
<style name="Theme.Gallery.SplashScreen" parent="Theme.SplashScreen">
|
<style name="Theme.Gallery.SplashScreen" parent="Theme.SplashScreen">
|
||||||
<item name="windowSplashScreenBackground">#2A2A34</item>
|
<item name="windowSplashScreenBackground">#2A2A34</item>
|
||||||
<item name="postSplashScreenTheme">@style/Theme.Gallery</item>
|
<item name="postSplashScreenTheme">@style/Theme.Gallery</item>
|
||||||
</style>
|
</style>
|
||||||
|
<style name="Theme.Gallery.OssLicenses" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
|
@ -31,6 +31,8 @@ netOpenidAppauth = "0.11.1"
|
||||||
splashscreen = "1.2.0-beta01"
|
splashscreen = "1.2.0-beta01"
|
||||||
hilt = "2.56.2"
|
hilt = "2.56.2"
|
||||||
hiltNavigation = "1.2.0"
|
hiltNavigation = "1.2.0"
|
||||||
|
ossLicenses = "0.10.6"
|
||||||
|
playServicesOssLicenses = "17.1.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
@ -73,6 +75,7 @@ hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt"
|
||||||
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigation" }
|
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigation" }
|
||||||
hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" }
|
hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" }
|
||||||
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
|
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
|
||||||
|
play-services-oss-licenses = { module = "com.google.android.gms:play-services-oss-licenses", version.ref = "playServicesOssLicenses"}
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
@ -81,3 +84,4 @@ kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "ko
|
||||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "serializationPlugin" }
|
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "serializationPlugin" }
|
||||||
protobuf = {id = "com.google.protobuf", version.ref = "protobuf"}
|
protobuf = {id = "com.google.protobuf", version.ref = "protobuf"}
|
||||||
hilt-application = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|
hilt-application = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
|
||||||
|
oss-licenses = {id = "com.google.android.gms.oss-licenses-plugin", version.ref = "ossLicenses"}
|
||||||
|
|
|
@ -26,6 +26,13 @@ pluginManagement {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
|
resolutionStrategy {
|
||||||
|
eachPlugin {
|
||||||
|
if (requested.id.id == "com.google.android.gms.oss-licenses-plugin") {
|
||||||
|
useModule("com.google.android.gms:oss-licenses-plugin:0.10.6")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue