blob: bea38b7e48a71b90eb2365b04196dc05007217b6 [file] [log] [blame]
/*
* Copyright (C) 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
*
* http://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 android.tools.device.flicker
import android.tools.common.Scenario
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.traces.TRACE_CONFIG_REQUIRE_CHANGES
import android.tools.device.traces.io.ResultReader
import android.tools.device.traces.io.ResultWriter
import android.tools.device.traces.monitors.ScreenRecorder
import android.tools.device.traces.monitors.TraceMonitor
import android.tools.device.traces.monitors.events.EventLogMonitor
import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
import android.tools.device.traces.monitors.surfaceflinger.TransactionsTraceMonitor
import android.tools.device.traces.monitors.wm.ShellTransitionTraceMonitor
import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
import android.tools.device.traces.monitors.wm.WmTransitionTraceMonitor
import androidx.test.platform.app.InstrumentationRegistry
import java.io.File
import kotlin.io.path.createTempDirectory
object Utils {
fun componentNameMatcherHardcoded(str: String): ComponentNameMatcher? {
return when (true) {
str.contains("NavigationBar0") -> ComponentNameMatcher.NAV_BAR
str.contains("Taskbar") -> ComponentNameMatcher.TASK_BAR
str.contains("StatusBar") -> ComponentNameMatcher.STATUS_BAR
str.contains("RotationLayer") -> ComponentNameMatcher.ROTATION
str.contains("BackColorSurface") -> ComponentNameMatcher.BACK_SURFACE
str.contains("InputMethod") -> ComponentNameMatcher.IME
str.contains("IME-snapshot-surface") -> ComponentNameMatcher.IME_SNAPSHOT
str.contains("Splash Screen") -> ComponentNameMatcher.SPLASH_SCREEN
str.contains("SnapshotStartingWindow") -> ComponentNameMatcher.SNAPSHOT
str.contains("Letterbox") -> ComponentNameMatcher.LETTERBOX
str.contains("Wallpaper BBQ wrapper") -> ComponentNameMatcher.WALLPAPER_BBQ_WRAPPER
str.contains("PipContentOverlay") -> ComponentNameMatcher.PIP_CONTENT_OVERLAY
str.contains("com.google.android.apps.nexuslauncher") -> ComponentNameMatcher.LAUNCHER
str.contains("StageCoordinatorSplitDivider") -> ComponentNameMatcher.SPLIT_DIVIDER
else -> null
}
}
/**
* Obtains the component name matcher corresponding to a name (str) Returns null if the name is
* not found in the hardcoded list, and it does not contain both the package and class name
* (with a / separator)
*/
fun componentNameMatcherFromName(
str: String,
): ComponentNameMatcher? {
return try {
componentNameMatcherHardcoded(str)
?: ComponentNameMatcher.unflattenFromStringWithJunk(str)
} catch (err: IllegalStateException) {
null
}
}
fun componentNameMatcherToString(componentNameMatcher: ComponentNameMatcher): String {
return "ComponentNameMatcher(\"${componentNameMatcher.packageName}\", " +
"\"${componentNameMatcher.className}\")"
}
fun componentNameMatcherToStringSimplified(componentNameMatcher: ComponentNameMatcher): String {
var className = componentNameMatcher.className
val separatedByDots = className.split('.')
if (separatedByDots.isNotEmpty()) {
className = separatedByDots[separatedByDots.size - 1]
}
className = className.replace(' ', '_')
return className
}
fun componentNameMatcherAsStringFromName(str: String): String? {
val componentMatcher = componentNameMatcherFromName(str)
return componentMatcher?.componentNameMatcherToString()
}
fun captureTrace(
scenario: Scenario,
outputDir: File = createTempDirectory().toFile(),
monitors: List<TraceMonitor> =
listOf(
WmTransitionTraceMonitor(),
ShellTransitionTraceMonitor(),
TransactionsTraceMonitor(),
WindowManagerTraceMonitor(),
LayersTraceMonitor(),
EventLogMonitor(),
ScreenRecorder(InstrumentationRegistry.getInstrumentation().targetContext)
),
actions: (writer: ResultWriter) -> Unit
): ResultReader {
val writer = ResultWriter().forScenario(scenario).withOutputDir(outputDir).setRunComplete()
monitors.fold({ actions.invoke(writer) }) { action, monitor ->
{ monitor.withTracing(writer) { action() } }
}()
val result = writer.write()
return ResultReader(result, TRACE_CONFIG_REQUIRE_CHANGES)
}
}