Extract `ProfileVerifier` logs from `MainActivity` to `NiaApplication`

- Prevent logging multiple times (because of `onResume()` callback)
- Remove unnecessary io dispatcher: `ListenableFuture<T>.await()` is already main-safe and prevent acquiring io slot.
- Merge comments into a single javadoc comment on the `ProfileVerifierLogger` type.
- Add proper javadoc format with markdown specific blocks.
- Update logs & tag to be more uniform.

Closes #945
pull/951/head
Simon Marquis 1 year ago
parent 151f877bbe
commit 03ba943632

@ -17,7 +17,6 @@
package com.google.samples.apps.nowinandroid package com.google.samples.apps.nowinandroid
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
@ -37,7 +36,6 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import androidx.metrics.performance.JankStats import androidx.metrics.performance.JankStats
import androidx.profileinstaller.ProfileVerifier
import com.google.samples.apps.nowinandroid.MainActivityUiState.Loading import com.google.samples.apps.nowinandroid.MainActivityUiState.Loading
import com.google.samples.apps.nowinandroid.MainActivityUiState.Success import com.google.samples.apps.nowinandroid.MainActivityUiState.Success
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
@ -49,12 +47,9 @@ import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand
import com.google.samples.apps.nowinandroid.ui.NiaApp import com.google.samples.apps.nowinandroid.ui.NiaApp
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject import javax.inject.Inject
private const val TAG = "MainActivity" private const val TAG = "MainActivity"
@ -152,48 +147,12 @@ class MainActivity : ComponentActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
lazyStats.get().isTrackingEnabled = true lazyStats.get().isTrackingEnabled = true
lifecycleScope.launch {
logCompilationStatus()
}
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
lazyStats.get().isTrackingEnabled = false lazyStats.get().isTrackingEnabled = false
} }
/**
* Logs the app's Baseline Profile Compilation Status using [ProfileVerifier].
*/
private suspend fun logCompilationStatus() {
/*
When delivering through Google Play, the baseline profile is compiled during installation.
In this case you will see the correct state logged without any further action necessary.
To verify baseline profile installation locally, you need to manually trigger baseline
profile installation.
For immediate compilation, call:
`adb shell cmd package compile -f -m speed-profile com.example.macrobenchmark.target`
You can also trigger background optimizations:
`adb shell pm bg-dexopt-job`
Both jobs run asynchronously and might take some time complete.
To see quick turnaround of the ProfileVerifier, we recommend using `speed-profile`.
If you don't do either of these steps, you might only see the profile status reported as
"enqueued for compilation" when running the sample locally.
*/
withContext(Dispatchers.IO) {
val status = ProfileVerifier.getCompilationStatusAsync().await()
Log.d(TAG, "ProfileInstaller status code: ${status.profileInstallResultCode}")
Log.d(
TAG,
when {
status.isCompiledWithProfile -> "ProfileInstaller: is compiled with profile"
status.hasProfileEnqueuedForCompilation() ->
"ProfileInstaller: Enqueued for compilation"
else -> "Profile not compiled or enqueued"
},
)
}
}
} }
/** /**

@ -20,6 +20,7 @@ import android.app.Application
import coil.ImageLoader import coil.ImageLoader
import coil.ImageLoaderFactory import coil.ImageLoaderFactory
import com.google.samples.apps.nowinandroid.sync.initializers.Sync import com.google.samples.apps.nowinandroid.sync.initializers.Sync
import com.google.samples.apps.nowinandroid.util.ProfileVerifierLogger
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider import javax.inject.Provider
@ -32,10 +33,14 @@ class NiaApplication : Application(), ImageLoaderFactory {
@Inject @Inject
lateinit var imageLoader: Provider<ImageLoader> lateinit var imageLoader: Provider<ImageLoader>
@Inject
lateinit var profileVerifierLogger: ProfileVerifierLogger
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
// Initialize Sync; the system responsible for keeping data in the app up to date. // Initialize Sync; the system responsible for keeping data in the app up to date.
Sync.initialize(context = this) Sync.initialize(context = this)
profileVerifierLogger()
} }
override fun newImageLoader(): ImageLoader = imageLoader.get() override fun newImageLoader(): ImageLoader = imageLoader.get()

@ -0,0 +1,70 @@
/*
* 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.util
import android.util.Log
import androidx.profileinstaller.ProfileVerifier
import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
* Logs the app's Baseline Profile Compilation Status using [ProfileVerifier].
*
* When delivering through Google Play, the baseline profile is compiled during installation.
* In this case you will see the correct state logged without any further action necessary.
* To verify baseline profile installation locally, you need to manually trigger baseline
* profile installation.
*
* For immediate compilation, call:
* ```bash
* adb shell cmd package compile -f -m speed-profile com.example.macrobenchmark.target
* ```
* You can also trigger background optimizations:
* ```bash
* adb shell pm bg-dexopt-job
* ```
* Both jobs run asynchronously and might take some time complete.
*
* To see quick turnaround of the ProfileVerifier, we recommend using `speed-profile`.
* If you don't do either of these steps, you might only see the profile status reported as
* "enqueued for compilation" when running the sample locally.
*
* @see androidx.profileinstaller.ProfileVerifier.CompilationStatus.ResultCode
*/
class ProfileVerifierLogger @Inject constructor(
@ApplicationScope private val scope: CoroutineScope,
) {
companion object {
private const val TAG = "ProfileInstaller"
}
operator fun invoke() = scope.launch {
val status = ProfileVerifier.getCompilationStatusAsync().await()
Log.d(TAG, "Status code: ${status.profileInstallResultCode}")
Log.d(
TAG,
when {
status.isCompiledWithProfile -> "App compiled with profile"
status.hasProfileEnqueuedForCompilation() -> "Profile enqueued for compilation"
else -> "Profile not compiled nor enqueued"
},
)
}
}
Loading…
Cancel
Save