Merge branch 'main' into lifecycle2.7.0

* main:
  Bump protobuf from 3.24.4 to 3.25.2 (#1214)
  Remove legacy benchmark build type (#1207)
  Use androidx.tracing everywhere
  Revert fast initialization of Coil
  Add comment for Retrofit async OkHttp
  Optimize OkHttp initialization for Retrofit
  Add braces
  Inline initialization
  Don't use runBlocking if async init completed
  Launch loader directly without additional coroutine scope
  Fix comment
  Improve lazy loading for Coil + OkHttp
  Restores screenshot tests in foryou (#1199)
  Fix name and message of dependency guard actions (#1196)

Change-Id: Ifcbfcfba4b7d8c24599e207b4a05dfea6125fde7
pull/1210/head
Don Turner 4 months ago
commit 69f4287ab5

@ -55,11 +55,10 @@ jobs:
continue-on-error: false
if: steps.dependencyguard_verify.outcome == 'failure' && github.event.pull_request.head.repo.full_name != github.repository
run: |
echo "::error::Dependency Guard failed, please run the following to update baselines:\n" \
" ./gradlew dependencyGuardBaseline" && exit 1
echo "::error::Dependency Guard failed, please update baselines with: ./gradlew dependencyGuardBaseline" && exit 1
# Runs if previous job failed
- name: Generate new screenshots if verification failed and it's a PR
- name: Generate new Dependency Guard baselines if verification failed and it's a PR
id: dependencyguard_baseline
if: steps.dependencyguard_verify.outcome == 'failure' && github.event_name == 'pull_request'
run: |
@ -110,13 +109,9 @@ jobs:
- name: Build all build type and flavor permutations
run: ./gradlew :app:assemble :benchmarks:assemble
-x pixel6Api33ProdNonMinifiedReleaseAndroidTest
-x pixel6Api33ProdNonMinifiedBenchmarkAndroidTest
-x pixel6Api33DemoNonMinifiedReleaseAndroidTest
-x pixel6Api33DemoNonMinifiedBenchmarkAndroidTest
-x collectDemoNonMinifiedReleaseBaselineProfile
-x collectDemoNonMinifiedBenchmarkBaselineProfile
-x collectProdNonMinifiedReleaseBaselineProfile
-x collectProdNonMinifiedBenchmarkBaselineProfile
- name: Upload build outputs (APKs)
uses: actions/upload-artifact@v4

@ -70,7 +70,8 @@ androidx.profileinstaller:profileinstaller:1.3.1
androidx.savedstate:savedstate-ktx:1.2.1
androidx.savedstate:savedstate:1.2.1
androidx.startup:startup-runtime:1.1.1
androidx.tracing:tracing:1.0.0
androidx.tracing:tracing-ktx:1.3.0-alpha02
androidx.tracing:tracing:1.3.0-alpha02
androidx.vectordrawable:vectordrawable-animated:1.1.0
androidx.vectordrawable:vectordrawable:1.1.0
androidx.versionedparcelable:versionedparcelable:1.1.1

@ -57,17 +57,6 @@ android {
// Ensure Baseline Profile is fresh for release builds.
baselineProfile.automaticGenerationDuringBuild = true
}
create("benchmark") {
// Enable all the optimizations from release build through initWith(release).
initWith(release)
matchingFallbacks.add("release")
// Debug key signing is available to everyone.
signingConfig = signingConfigs.getByName("debug")
// Only use benchmark proguard rules
proguardFiles("benchmark-rules.pro")
isMinifyEnabled = true
applicationIdSuffix = NiaBuildType.BENCHMARK.applicationIdSuffix
}
}
packaging {

@ -105,8 +105,8 @@ androidx.savedstate:savedstate:1.2.1
androidx.sqlite:sqlite-framework:2.4.0
androidx.sqlite:sqlite:2.4.0
androidx.startup:startup-runtime:1.1.1
androidx.tracing:tracing-ktx:1.1.0
androidx.tracing:tracing:1.1.0
androidx.tracing:tracing-ktx:1.3.0-alpha02
androidx.tracing:tracing:1.3.0-alpha02
androidx.vectordrawable:vectordrawable-animated:1.1.0
androidx.vectordrawable:vectordrawable:1.1.0
androidx.versionedparcelable:versionedparcelable:1.1.1
@ -168,8 +168,8 @@ com.google.guava:failureaccess:1.0.1
com.google.guava:guava:31.1-android
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.google.protobuf:protobuf-javalite:3.24.4
com.google.protobuf:protobuf-kotlin-lite:3.24.4
com.google.protobuf:protobuf-javalite:3.25.2
com.google.protobuf:protobuf-kotlin-lite:3.25.2
com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0
com.squareup.okhttp3:logging-interceptor:4.12.0
com.squareup.okhttp3:okhttp:4.12.0

@ -23,7 +23,6 @@ import com.google.samples.apps.nowinandroid.sync.initializers.Sync
import com.google.samples.apps.nowinandroid.util.ProfileVerifierLogger
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
import javax.inject.Provider
/**
* [Application] class for NiA
@ -31,7 +30,7 @@ import javax.inject.Provider
@HiltAndroidApp
class NiaApplication : Application(), ImageLoaderFactory {
@Inject
lateinit var imageLoader: Provider<ImageLoader>
lateinit var imageLoader: dagger.Lazy<ImageLoader>
@Inject
lateinit var profileVerifierLogger: ProfileVerifierLogger

@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.google.samples.apps.nowinandroid.NiaBuildType
import com.google.samples.apps.nowinandroid.configureFlavors
plugins {
@ -35,23 +34,6 @@ android {
buildConfig = true
}
buildTypes {
// This benchmark buildType is used for benchmarking, and should function like your
// release build (for example, with minification on). It's signed with a debug key
// for easy local/CI testing.
create("benchmark") {
// Keep the build type debuggable so we can attach a debugger if needed.
isDebuggable = true
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks.add("release")
buildConfigField(
"String",
"APP_BUILD_TYPE_SUFFIX",
"\"${NiaBuildType.BENCHMARK.applicationIdSuffix ?: ""}\""
)
}
}
// Use the same flavor dimensions as the application to allow generating Baseline Profiles on prod,
// which is more close to what will be shipped to users (no fake data), but has ability to run the
// benchmarks on demo, so we benchmark on stable data.

@ -30,7 +30,6 @@ import java.io.ByteArrayOutputStream
val PACKAGE_NAME = buildString {
append("com.google.samples.apps.nowinandroid")
append(BuildConfig.APP_FLAVOR_SUFFIX)
append(BuildConfig.APP_BUILD_TYPE_SUFFIX)
}
fun UiDevice.flingElementDownUp(element: UiObject2) {

@ -44,6 +44,7 @@ class AndroidFeatureConventionPlugin : Plugin<Project> {
add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get())
add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get())
add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get())
add("implementation", libs.findLibrary("androidx.tracing.ktx").get())
add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get())
}

@ -21,6 +21,7 @@ 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.kotlin.dsl.configure
@ -51,6 +52,8 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
}
dependencies {
add("testImplementation", kotlin("test"))
add("implementation", libs.findLibrary("androidx.tracing.ktx").get())
}
}
}

@ -22,5 +22,4 @@ package com.google.samples.apps.nowinandroid
enum class NiaBuildType(val applicationIdSuffix: String? = null) {
DEBUG(".debug"),
RELEASE,
BENCHMARK(".benchmark")
}

@ -17,6 +17,7 @@
package com.google.samples.apps.nowinandroid.core.network.di
import android.content.Context
import androidx.tracing.trace
import coil.ImageLoader
import coil.decode.SvgDecoder
import coil.util.DebugLogger
@ -51,16 +52,18 @@ internal object NetworkModule {
@Provides
@Singleton
fun okHttpCallFactory(): Call.Factory = OkHttpClient.Builder()
.addInterceptor(
HttpLoggingInterceptor()
.apply {
if (BuildConfig.DEBUG) {
setLevel(HttpLoggingInterceptor.Level.BODY)
}
},
)
.build()
fun okHttpCallFactory(): Call.Factory = trace("NiaOkHttpClient") {
OkHttpClient.Builder()
.addInterceptor(
HttpLoggingInterceptor()
.apply {
if (BuildConfig.DEBUG) {
setLevel(HttpLoggingInterceptor.Level.BODY)
}
},
)
.build()
}
/**
* Since we're displaying SVGs in the app, Coil needs an ImageLoader which supports this
@ -72,20 +75,21 @@ internal object NetworkModule {
@Provides
@Singleton
fun imageLoader(
okHttpCallFactory: Call.Factory,
// We specifically request dagger.Lazy here, so that it's not instantiated from Dagger.
okHttpCallFactory: dagger.Lazy<Call.Factory>,
@ApplicationContext application: Context,
): ImageLoader = ImageLoader.Builder(application)
.callFactory(okHttpCallFactory)
.components {
add(SvgDecoder.Factory())
}
// Assume most content images are versioned urls
// but some problematic images are fetching each time
.respectCacheHeaders(false)
.apply {
if (BuildConfig.DEBUG) {
logger(DebugLogger())
): ImageLoader = trace("NiaImageLoader") {
ImageLoader.Builder(application)
.callFactory { okHttpCallFactory.get() }
.components { add(SvgDecoder.Factory()) }
// Assume most content images are versioned urls
// but some problematic images are fetching each time
.respectCacheHeaders(false)
.apply {
if (BuildConfig.DEBUG) {
logger(DebugLogger())
}
}
}
.build()
.build()
}
}

@ -16,6 +16,7 @@
package com.google.samples.apps.nowinandroid.core.network.retrofit
import androidx.tracing.trace
import com.google.samples.apps.nowinandroid.core.network.BuildConfig
import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource
import com.google.samples.apps.nowinandroid.core.network.model.NetworkChangeList
@ -73,17 +74,21 @@ private data class NetworkResponse<T>(
@Singleton
internal class RetrofitNiaNetwork @Inject constructor(
networkJson: Json,
okhttpCallFactory: Call.Factory,
okhttpCallFactory: dagger.Lazy<Call.Factory>,
) : NiaNetworkDataSource {
private val networkApi = Retrofit.Builder()
.baseUrl(NIA_BASE_URL)
.callFactory(okhttpCallFactory)
.addConverterFactory(
networkJson.asConverterFactory("application/json".toMediaType()),
)
.build()
.create(RetrofitNiaNetworkApi::class.java)
private val networkApi = trace("RetrofitNiaNetwork") {
Retrofit.Builder()
.baseUrl(NIA_BASE_URL)
// We use callFactory lambda here with dagger.Lazy<Call.Factory>
// to prevent initializing OkHttp on the main thread.
.callFactory { okhttpCallFactory.get().newCall(it) }
.addConverterFactory(
networkJson.asConverterFactory("application/json".toMediaType()),
)
.build()
.create(RetrofitNiaNetworkApi::class.java)
}
override suspend fun getTopics(ids: List<String>?): List<NetworkTopic> =
networkApi.getTopics(ids = ids).data

@ -18,6 +18,7 @@ plugins {
alias(libs.plugins.nowinandroid.android.feature)
alias(libs.plugins.nowinandroid.android.library.compose)
alias(libs.plugins.nowinandroid.android.library.jacoco)
alias(libs.plugins.roborazzi)
}
android {
@ -32,6 +33,7 @@ dependencies {
testImplementation(libs.hilt.android.testing)
testImplementation(libs.robolectric)
testImplementation(projects.core.testing)
testDemoImplementation(libs.roborazzi)
androidTestImplementation(projects.core.testing)
}

@ -81,9 +81,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.max
import androidx.compose.ui.unit.sp
import androidx.compose.ui.util.trace
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.tracing.trace
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionStatus.Denied
import com.google.accompanist.permissions.rememberPermissionState

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

@ -24,7 +24,7 @@ androidxTestCore = "1.5.0"
androidxTestExt = "1.1.5"
androidxTestRules = "1.5.0"
androidxTestRunner = "1.5.2"
androidxTracing = "1.1.0"
androidxTracing = "1.3.0-alpha02"
androidxUiAutomator = "2.2.0"
androidxWindowManager = "1.2.0"
androidxWork = "2.9.0"
@ -46,7 +46,7 @@ kotlinxDatetime = "0.5.0"
kotlinxSerializationJson = "1.6.0"
ksp = "1.9.21-1.0.16"
okhttp = "4.12.0"
protobuf = "3.24.4"
protobuf = "3.25.2"
protobufPlugin = "0.9.4"
retrofit = "2.9.0"
retrofitKotlinxSerializationJson = "1.0.0"

Loading…
Cancel
Save