6

I am trying to implement the Baseline profiles(official documentation) for my app. Following the steps indicated in this video(Improving Performance with Baseline Profiles) if I use the DebugBuildVariant I am able to create the baseline-prof.txt file to improve the startup time . But when I try to create the baseline-prof file for release I have this exception:

./gradlew :macrobenchmark:pixel2Api31BenchmarkAndroidTest -P android.testInstrumentationRunnerArguments.class=com.example.BaselineProfileGenerator
com.example.BaselineProfileGenerator > generate[pixel2Api31] FAILED
        java.lang.IllegalStateException: Unable to confirm activity launch completion [] Please report a bug with the output of `adb shell dumpsys gfxinfo com.leinardi.forlago framestats`
                at androidx.benchmark.macro.MacrobenchmarkScope.startActivityImpl(MacrobenchmarkScope.kt:179)
Tests on pixel2Api31 failed: There was 1 failure(s).

This is how it looks like our BaselineProfileGenerator:

@OptIn(ExperimentalBaselineProfilesApi::class)
@RunWith(AndroidJUnit4ClassRunner::class)
class BaselineProfileGenerator {
    @get:Rule
    val rule = BaselineProfileRule()

    @Test
    fun generate() {
        rule.collectBaselineProfile("com.leinardi.forlago") {
            pressHome()
            startActivityAndWait()
        }
    }
}

If I configure the benchmark for Debug it works well:

benchmark {
    initWith buildTypes.debug
    signingConfig signingConfigs.debug
    matchingFallbacks = ['debug']
    debuggable false
    proguardFiles('benchmark-rules.pro')
}

But configuring it for Release, benchmark throws the previous exception when you try to generate it.

benchmark {
    initWith buildTypes.release
    signingConfig signingConfigs.debug
    matchingFallbacks = ['release']
    debuggable false
    proguardFiles('benchmark-rules.pro')
}

Component used: Baseline Profiles

Version used: AGP=7.3.0-rc01, uiautomator=2.2.0 & benchmark-macro-junit4=1.1.0

Devices/Android versions reproduced on:

testOptions {
        managedDevices {
            devices {
                pixel2Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                    device = "Pixel 2"
                    apiLevel = 31
                    systemImageSource = "aosp"
                }
            }
        }
    }

Reported on Google Issue tracker: issue

Sample project to trigger the issue: https://github.com/leinardi/Forlago/tree/baseline-profiles

mlykotom
  • 4,850
  • 1
  • 22
  • 27
J.Arroyo
  • 176
  • 6

4 Answers4

1

Have you used SplashScreen.setKeepOnScreenCondition in your activity? If yes, commenting out the line could help.
You can disable it if the current build-type is benchmark.

if (!BuildConfig.BUILD_TYPE.contains("benchmark")) {
    splashScreen.setKeepOnScreenCondition { ... }
}
Darshan
  • 4,020
  • 2
  • 18
  • 49
mrhoibq
  • 11
  • 2
1

I checked the sample code and it looks like the problem is not within the library, but within the sample project itself.

You get exception during app launch, because FirebaseCrashlytics is not initialized in release build type

FATAL EXCEPTION: main
Process: com.leinardi.forlago, PID: 4684
java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.leinardi.forlago. Make sure to call FirebaseApp.initializeApp(Context) first.
at com.google.firebase.FirebaseApp.getInstance(FirebaseApp.java:47)
at com.leinardi.forlago.library.logging.CrashlyticsTree.log(CrashlyticsTree.kt:15)
at timber.log.Timber$Tree.prepareLog(Timber.kt:97)
at timber.log.Timber$Tree.e(Timber.kt:3)
at timber.log.Timber$Forest.e(Timber.kt:6)
at com.leinardi.forlago.library.android.interactor.android.GetAppUpdateInfoInteractor$invoke$2.invokeSuspend(GetAppUpdateInfoInteractor.kt:181)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:9)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:99)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:12)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:3)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:82)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@c988cf0, Dispatchers.Main.immediate]

Once I commented out CrashlyticsTree, the profile is generated properly.

mlykotom
  • 4,850
  • 1
  • 22
  • 27
1

if you are using pressHome() in your profileBlock field, then remove it. Use only startActivityAndWait. If you are using custom ui tests, then use startActivityAndWait with pressHome for generate profile file properly :)

Asaf
  • 61
  • 2
  • I actually found that adding a delay to the `pressHome()` call, i.e. `pressHome(delayDurationMs = 1000)`, is a better approach than outright removing the `pressHome()` call. – farmerbb Jul 07 '23 at 15:37
0

Baseline Profile generation requires a non-obfuscated build. Check here

Dilip Sharma
  • 41
  • 1
  • 6