From 4f5797565770d4b2b7241e4f87fb340e7bebf8ff Mon Sep 17 00:00:00 2001 From: Ben Weiss Date: Fri, 20 May 2022 16:24:32 +0100 Subject: [PATCH] Add jankStats and rudamentary jank logging --- .../samples/apps/nowinandroid/MainActivity.kt | 36 ++++++++++++++++- .../samples/apps/nowinandroid/ui/NiaApp.kt | 6 +++ .../core/navigation/NavigationExtensions.kt | 39 ------------------- core-ui/build.gradle.kts | 1 + gradle/libs.versions.toml | 2 + 5 files changed, 44 insertions(+), 40 deletions(-) delete mode 100644 core-navigation/src/main/java/com/google/samples/apps/nowinandroid/core/navigation/NavigationExtensions.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivity.kt index c4dea1f2b..28983303e 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -17,17 +17,33 @@ package com.google.samples.apps.nowinandroid import android.os.Bundle +import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass +import androidx.compose.runtime.remember import androidx.core.view.WindowCompat +import androidx.metrics.performance.JankStats +import androidx.metrics.performance.PerformanceMetricsState import com.google.samples.apps.nowinandroid.ui.NiaApp import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.asExecutor @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) @AndroidEntryPoint class MainActivity : ComponentActivity() { + + private lateinit var jankStats: JankStats + + private val jankFrameListener = JankStats.OnFrameListener { frameData -> + // Make sure to only log janky frames. + if (frameData.isJank) { + Log.v("NiA Jank", frameData.toString()) + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -35,6 +51,24 @@ class MainActivity : ComponentActivity() { // including IME animations WindowCompat.setDecorFitsSystemWindows(window, false) - setContent { NiaApp(calculateWindowSizeClass(this)) } + setContent { + NiaApp(calculateWindowSizeClass(this)) + } + + jankStats = JankStats.createAndTrack( + window, + Dispatchers.Default.asExecutor(), + jankFrameListener + ) + } + + override fun onResume() { + super.onResume() + jankStats.isTrackingEnabled = true + } + + override fun onPause() { + super.onPause() + jankStats.isTrackingEnabled = false } } diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index 3a3e25b66..3b7feb9db 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -46,8 +46,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.metrics.performance.PerformanceMetricsState import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.compose.currentBackStackEntryAsState @@ -64,7 +66,11 @@ import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination @Composable fun NiaApp(windowSizeClass: WindowSizeClass) { NiaTheme { + val metricsStateHolder = PerformanceMetricsState.getForHierarchy(LocalView.current) val navController = rememberNavController() + navController.addOnDestinationChangedListener { _, destination, _ -> + metricsStateHolder.state?.addState("Navigation", "Jank at ${destination.route}") + } val niaTopLevelNavigation = remember(navController) { NiaTopLevelNavigation(navController) } diff --git a/core-navigation/src/main/java/com/google/samples/apps/nowinandroid/core/navigation/NavigationExtensions.kt b/core-navigation/src/main/java/com/google/samples/apps/nowinandroid/core/navigation/NavigationExtensions.kt deleted file mode 100644 index cda2341a7..000000000 --- a/core-navigation/src/main/java/com/google/samples/apps/nowinandroid/core/navigation/NavigationExtensions.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2022 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.core.navigation - -import androidx.compose.runtime.Composable -import androidx.navigation.NamedNavArgument -import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavDeepLink -import androidx.navigation.NavGraphBuilder -import androidx.navigation.compose.composable -import androidx.tracing.trace - -/** - * Wrapping a [NavGraphBuilder.composable] in a trace block. - */ -fun NavGraphBuilder.tracedComposable( - route: String, - arguments: List = emptyList(), - deepLinks: List = emptyList(), - content: @Composable (NavBackStackEntry) -> Unit -) { - trace("Navigation: $route") { - composable(route, arguments, deepLinks, content) - } -} diff --git a/core-ui/build.gradle.kts b/core-ui/build.gradle.kts index b25eeb9eb..3d47cb9ee 100644 --- a/core-ui/build.gradle.kts +++ b/core-ui/build.gradle.kts @@ -43,5 +43,6 @@ dependencies { api(libs.androidx.compose.ui.util) api(libs.androidx.compose.runtime) api(libs.androidx.compose.runtime.livedata) + api(libs.androidx.metrics) api(libs.androidx.tracing.ktx) } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c4ebe2131..5949dba81 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,7 @@ androidxEspresso = "3.3.0" androidxHiltNavigationCompose = "1.0.0" androidxLifecycle = "2.5.0-beta01" androidxMacroBenchmark = "1.1.0-rc02" +androidxMetrics = "1.0.0-alpha01" androidxNavigation = "2.4.0-rc01" androidxProfileinstaller = "1.2.0-beta01" androidxSavedState = "1.1.0" @@ -71,6 +72,7 @@ androidx-dataStore-core = { group = "androidx.datastore", name = "datastore", ve androidx-dataStore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "androidxDataStore" } androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltNavigationCompose" } androidx-lifecycle-viewModelCompose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" } +androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" } androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" } androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstaller" } androidx-savedstate-ktx = { group = "androidx.savedstate", name = "savedstate-ktx", version.ref= "androidxSavedState"}