From 895ec4c3372e995be68db388318b232f32b7db72 Mon Sep 17 00:00:00 2001 From: Ben Weiss Date: Fri, 20 May 2022 20:38:28 +0100 Subject: [PATCH] Inject JankStats with Hilt --- .../samples/apps/nowinandroid/MainActivity.kt | 31 ++++----- .../apps/nowinandroid/di/JankStatsModule.kt | 63 +++++++++++++++++++ .../samples/apps/nowinandroid/ui/NiaApp.kt | 2 +- 3 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/google/samples/apps/nowinandroid/di/JankStatsModule.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 28983303e..de63dad5d 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,32 +17,25 @@ 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 +import javax.inject.Inject @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) @AndroidEntryPoint class MainActivity : ComponentActivity() { - private lateinit var jankStats: JankStats + @Inject + lateinit var lazyStats: dagger.Lazy - private val jankFrameListener = JankStats.OnFrameListener { frameData -> - // Make sure to only log janky frames. - if (frameData.isJank) { - Log.v("NiA Jank", frameData.toString()) - } - } + @Inject + lateinit var jankFrameListener: JankStats.OnFrameListener override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -54,21 +47,19 @@ class MainActivity : ComponentActivity() { setContent { NiaApp(calculateWindowSizeClass(this)) } - - jankStats = JankStats.createAndTrack( - window, - Dispatchers.Default.asExecutor(), - jankFrameListener - ) } override fun onResume() { super.onResume() - jankStats.isTrackingEnabled = true + isTrackingEnabled(true) } override fun onPause() { super.onPause() - jankStats.isTrackingEnabled = false + isTrackingEnabled(false) + } + + private fun isTrackingEnabled(enabled: Boolean) { + lazyStats.get().isTrackingEnabled = enabled } } diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt new file mode 100644 index 000000000..6d11a9f68 --- /dev/null +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt @@ -0,0 +1,63 @@ +/* + * 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.di + +import android.app.Activity +import android.util.Log +import android.view.Window +import androidx.metrics.performance.JankStats +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ActivityComponent +import java.util.concurrent.Executor +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.asExecutor + +@Module +@InstallIn(ActivityComponent::class) +object JankStatsModule { + @Provides + fun providesOnFrameListener(): JankStats.OnFrameListener { + return JankStats.OnFrameListener { frameData -> + // Make sure to only log janky frames. + if (frameData.isJank) { + // We're currently logging this but would better report it to a backend. + Log.v("NiA Jank", frameData.toString()) + } + } + } + + @Provides + fun providesWindow(activity: Activity): Window { + return activity.window + } + + @Provides + fun providesDefaultExecutor(): Executor { + return Dispatchers.Default.asExecutor() + } + + @Provides + fun providesJankStats( + window: Window, + executor: Executor, + frameListener: JankStats.OnFrameListener + ): JankStats { + return JankStats.createAndTrack(window, executor, frameListener) + } +} 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 3b7feb9db..d1b647a8b 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 @@ -69,7 +69,7 @@ fun NiaApp(windowSizeClass: WindowSizeClass) { val metricsStateHolder = PerformanceMetricsState.getForHierarchy(LocalView.current) val navController = rememberNavController() navController.addOnDestinationChangedListener { _, destination, _ -> - metricsStateHolder.state?.addState("Navigation", "Jank at ${destination.route}") + metricsStateHolder.state?.addState("Navigation", "${destination.route}") } val niaTopLevelNavigation = remember(navController) { NiaTopLevelNavigation(navController)