Merge branch 'main' into lint/sarif

pull/759/head
Simon Marquis 1 year ago
commit d136965a0d

@ -131,8 +131,8 @@ jobs:
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Accept Android licenses
run: yes | "$ANDROID_HOME"/cmdline-tools/latest/bin/sdkmanager --licenses || true
- name: Build AndroidTest apps
run: ./gradlew packageDemoDebug packageDemoDebugAndroidTest

@ -45,11 +45,6 @@ understanding of which libraries and tools are being used, the reasoning behind
UI, testing, architecture and more, and how all of these different pieces of the project fit
together to create a complete app.
NOTE: Building the app using an M1 Mac will require the use of
[Rosetta](https://support.apple.com/en-gb/HT211861). See
[the following bug](https://github.com/protocolbuffers/protobuf/issues/9397#issuecomment-1086138036)
for more details.
# Architecture
The **Now in Android** app follows the

@ -1,21 +0,0 @@
# 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

@ -1,30 +1,3 @@
# Keep `Companion` object fields of serializable classes.
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
static <1>$Companion Companion;
}
# Keep `serializer()` on companion objects (both default and named) of serializable classes.
-if @kotlinx.serialization.Serializable class ** {
static **$* *;
}
-keepclassmembers class <2>$<3> {
kotlinx.serialization.KSerializer serializer(...);
}
# Keep `INSTANCE.serializer()` of serializable objects.
-if @kotlinx.serialization.Serializable class ** {
public static ** INSTANCE;
}
-keepclassmembers class <1> {
public static <1> INSTANCE;
kotlinx.serialization.KSerializer serializer(...);
}
# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
-dontwarn org.bouncycastle.jsse.BCSSLParameters
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider

@ -16,12 +16,11 @@
import com.android.build.api.dsl.ApplicationExtension
import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
@ -32,7 +31,6 @@ class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
apply("com.google.firebase.crashlytics")
}
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
val bom = libs.findLibrary("firebase-bom").get()
add("implementation", platform(bom))

@ -14,15 +14,13 @@
* limitations under the License.
*/
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.gradle.LibraryExtension
import com.google.samples.apps.nowinandroid.configureGradleManagedDevices
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.kotlin
class AndroidFeatureConventionPlugin : Plugin<Project> {
@ -40,8 +38,6 @@ class AndroidFeatureConventionPlugin : Plugin<Project> {
configureGradleManagedDevices(this)
}
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
add("implementation", project(":core:model"))
add("implementation", project(":core:ui"))

@ -14,11 +14,10 @@
* limitations under the License.
*/
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
class AndroidHiltConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
@ -30,7 +29,6 @@ class AndroidHiltConventionPlugin : Plugin<Project> {
apply("org.jetbrains.kotlin.kapt")
}
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
"implementation"(libs.findLibrary("hilt.android").get())
"kapt"(libs.findLibrary("hilt.compiler").get())

@ -21,12 +21,11 @@ import com.google.samples.apps.nowinandroid.configureGradleManagedDevices
import com.google.samples.apps.nowinandroid.configureKotlinAndroid
import com.google.samples.apps.nowinandroid.configurePrintApksTask
import com.google.samples.apps.nowinandroid.disableUnnecessaryAndroidTests
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.kotlin
class AndroidLibraryConventionPlugin : Plugin<Project> {
@ -48,7 +47,6 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
configurePrintApksTask(this)
disableUnnecessaryAndroidTests(target)
}
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
configurations.configureEach {
resolutionStrategy {
force(libs.findLibrary("junit4").get())

@ -15,15 +15,14 @@
*/
import com.google.devtools.ksp.gradle.KspExtension
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.process.CommandLineArgumentProvider
import java.io.File
@ -40,7 +39,6 @@ class AndroidRoomConventionPlugin : Plugin<Project> {
arg(RoomSchemaArgProvider(File(projectDir, "schemas")))
}
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
add("implementation", libs.findLibrary("room.runtime").get())
add("implementation", libs.findLibrary("room.ktx").get())

@ -18,9 +18,7 @@ package com.google.samples.apps.nowinandroid
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.File
@ -31,8 +29,6 @@ import java.io.File
internal fun Project.configureAndroidCompose(
commonExtension: CommonExtension<*, *, *, *>,
) {
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
commonExtension.apply {
buildFeatures {
compose = true

@ -18,10 +18,8 @@ package com.google.samples.apps.nowinandroid
import com.android.build.api.variant.AndroidComponentsExtension
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.withType
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
@ -44,8 +42,6 @@ private fun String.capitalize() = replaceFirstChar {
internal fun Project.configureJacoco(
androidComponentsExtension: AndroidComponentsExtension<*, *, *>,
) {
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
configure<JacocoPluginExtension> {
toolVersion = libs.findVersion("jacoco").get().toString()
}

@ -19,11 +19,9 @@ package com.google.samples.apps.nowinandroid
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@ -52,8 +50,6 @@ internal fun Project.configureKotlinAndroid(
configureKotlin()
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
}
@ -88,6 +84,9 @@ private fun Project.configureKotlin() {
allWarningsAsErrors = warningsAsErrors.toBoolean()
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=kotlin.RequiresOptIn",
// Enable experimental coroutines APIs, including Flow
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlinx.coroutines.FlowPreview",
)
}
}

@ -0,0 +1,25 @@
/*
* 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.
*/
package com.google.samples.apps.nowinandroid
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.getByType
val Project.libs
get(): VersionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")

@ -57,7 +57,11 @@ fun LazyGridScope.newsFeed(
when (feedState) {
NewsFeedUiState.Loading -> Unit
is NewsFeedUiState.Success -> {
items(feedState.feed, key = { it.id }) { userNewsResource ->
items(
items = feedState.feed,
key = { it.id },
contentType = { "newsFeedItem" },
) { userNewsResource ->
val resourceUrl by remember {
mutableStateOf(Uri.parse(userNewsResource.url))
}

@ -159,13 +159,21 @@ Using the above modularization strategy, the Now in Android app has the followin
<td><code>TopicsRepository</code><br>
</td>
</tr>
<tr>
<td><code>core:designsystem</code>
</td>
<td>Design system which includes Core UI components (many of which are customized Material 3 components), app theme and icons. The design system can be viewed by running the <code>app-nia-catalog</code> run configuration.
</td>
<td>
<code>NiaIcons</code> <code>NiaButton</code> <code>NiaTheme</code>
</td>
</tr>
<tr>
<td><code>core:ui</code>
</td>
<td>UI components, composables and resources, such as icons, used by different features.
<td>Composite UI components and resources used by feature modules, such as the news feed. Unlike the <code>designsystem</code> module, it is dependent on the data layer since it renders models, like news resources.
</td>
<td><code>NiaIcons</code><br>
<code>NewsResourceCardExpanded</code>
<td> <code>NewsFeed</code> <code>NewsResourceCardExpanded</code>
</td>
</tr>
<tr>

@ -182,7 +182,7 @@ internal fun ForYouScreen(
onTopicClick = onTopicClick,
)
item(span = { GridItemSpan(maxLineSpan) }) {
item(span = { GridItemSpan(maxLineSpan) }, contentType = "bottomSpacing") {
Column {
Spacer(modifier = Modifier.height(8.dp))
// Add space for the content to clear the "offline" snackbar.
@ -240,7 +240,7 @@ private fun LazyGridScope.onboarding(
-> Unit
is OnboardingUiState.Shown -> {
item(span = { GridItemSpan(maxLineSpan) }) {
item(span = { GridItemSpan(maxLineSpan) }, contentType = "onboarding") {
Column(modifier = interestsItemModifier) {
Text(
text = stringResource(R.string.onboarding_guidance_title),

@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# 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

@ -17,9 +17,11 @@
package com.google.samples.apps.nowinandroid.feature.settings
import android.content.Intent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
@ -149,8 +151,9 @@ fun SettingsDialog(
)
}
// [ColumnScope] is used for using the [ColumnScope.AnimatedVisibility] extension overload composable.
@Composable
private fun SettingsPanel(
private fun ColumnScope.SettingsPanel(
settings: UserEditableSettings,
supportDynamicColor: Boolean,
onChangeThemeBrand: (themeBrand: ThemeBrand) -> Unit,
@ -170,19 +173,21 @@ private fun SettingsPanel(
onClick = { onChangeThemeBrand(ANDROID) },
)
}
if (settings.brand == DEFAULT && supportDynamicColor) {
SettingsDialogSectionTitle(text = stringResource(R.string.dynamic_color_preference))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.dynamic_color_yes),
selected = settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(true) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.dynamic_color_no),
selected = !settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(false) },
)
AnimatedVisibility(visible = settings.brand == DEFAULT && supportDynamicColor) {
Column {
SettingsDialogSectionTitle(text = stringResource(R.string.dynamic_color_preference))
Column(Modifier.selectableGroup()) {
SettingsDialogThemeChooserRow(
text = stringResource(string.dynamic_color_yes),
selected = settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(true) },
)
SettingsDialogThemeChooserRow(
text = stringResource(string.dynamic_color_no),
selected = !settings.useDynamicColor,
onClick = { onChangeDynamicColorPreference(false) },
)
}
}
}
SettingsDialogSectionTitle(text = stringResource(R.string.dark_mode_preference))

@ -22,7 +22,7 @@ org.gradle.configureondemand=false
org.gradle.caching=true
# Enable configuration caching between builds.
org.gradle.unsafe.configuration-cache=true
org.gradle.configuration-cache=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
@ -35,9 +35,6 @@ kotlin.code.style=official
android.nonTransitiveRClass=true
# Disable build features that are enabled by default,
# https://developer.android.com/studio/releases/gradle-plugin#buildFeatures
android.defaults.buildfeatures.buildconfig=false
android.defaults.buildfeatures.aidl=false
android.defaults.buildfeatures.renderscript=false
# https://developer.android.com/build/releases/gradle-plugin#default-changes
android.defaults.buildfeatures.resvalues=false
android.defaults.buildfeatures.shaders=false

Loading…
Cancel
Save