1 /* <lambda>null2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wm.flicker.service.assertors 18 19 import android.util.Log 20 import com.android.server.wm.flicker.FLICKER_TAG 21 import com.android.server.wm.flicker.traces.FlickerSubjectException 22 import com.android.server.wm.flicker.traces.layers.LayersTraceSubject 23 import com.android.server.wm.flicker.traces.windowmanager.WindowManagerTraceSubject 24 import com.android.server.wm.traces.common.errors.Error 25 import com.android.server.wm.traces.common.errors.ErrorState 26 import com.android.server.wm.traces.common.errors.ErrorTrace 27 import com.android.server.wm.traces.common.layers.LayersTrace 28 import com.android.server.wm.traces.common.service.ITransitionAssertor 29 import com.android.server.wm.traces.common.tags.Tag 30 import com.android.server.wm.traces.common.windowmanager.WindowManagerTrace 31 32 /** 33 * Class that runs FASS assertions. 34 */ 35 class TransitionAssertor( 36 private val assertions: List<AssertionData>, 37 private val logger: (String) -> Unit 38 ) : ITransitionAssertor { 39 /** {@inheritDoc} */ 40 override fun analyze( 41 tag: Tag, 42 wmTrace: WindowManagerTrace, 43 layersTrace: LayersTrace 44 ): ErrorTrace { 45 val errorStates = mutableMapOf<Long, MutableList<Error>>() 46 47 errorStates.putAll( 48 runCategoryAssertions(tag, wmTrace, layersTrace, AssertionConfigParser.PRESUBMIT_KEY)) 49 errorStates.putAll( 50 runCategoryAssertions(tag, wmTrace, layersTrace, AssertionConfigParser.POSTSUBMIT_KEY)) 51 errorStates.putAll( 52 runCategoryAssertions(tag, wmTrace, layersTrace, AssertionConfigParser.FLAKY_KEY)) 53 54 return buildErrorTrace(errorStates) 55 } 56 57 private fun runCategoryAssertions( 58 tag: Tag, 59 wmTrace: WindowManagerTrace, 60 layersTrace: LayersTrace, 61 categoryKey: String 62 ): Map<Long, MutableList<Error>> { 63 logger.invoke("Running assertions for $tag $categoryKey") 64 val wmSubject = WindowManagerTraceSubject.assertThat(wmTrace) 65 val layersSubject = LayersTraceSubject.assertThat(layersTrace) 66 val assertions = assertions.filter { it.category == categoryKey } 67 return runAssertionsOnSubjects(tag, wmSubject, layersSubject, assertions) 68 } 69 70 private fun runAssertionsOnSubjects( 71 tag: Tag, 72 wmSubject: WindowManagerTraceSubject, 73 layerSubject: LayersTraceSubject, 74 assertions: List<AssertionData> 75 ): Map<Long, MutableList<Error>> { 76 val errors = mutableMapOf<Long, MutableList<Error>>() 77 78 try { 79 assertions.forEach { 80 val assertion = it.assertion 81 logger.invoke("Running assertion $assertion") 82 val result = assertion.runCatching { evaluate(tag, wmSubject, layerSubject) } 83 if (result.isFailure) { 84 val layer = assertion.getFailureLayer(tag, wmSubject, layerSubject) 85 val window = assertion.getFailureWindow(tag, wmSubject, layerSubject) 86 val exception = result.exceptionOrNull() as FlickerSubjectException 87 88 errors.putIfAbsent(exception.timestamp, mutableListOf()) 89 val errorEntry = Error( 90 stacktrace = exception.stackTraceToString(), 91 message = exception.message, 92 layerId = layer?.id ?: 0, 93 windowToken = window?.token ?: "", 94 assertionName = assertion.name 95 ) 96 errors.getValue(exception.timestamp).add(errorEntry) 97 } 98 } 99 } catch (e: NoSuchMethodException) { 100 Log.e("$FLICKER_TAG-ASSERT", "Assertion method not found", e) 101 } catch (e: SecurityException) { 102 Log.e("$FLICKER_TAG-ASSERT", "Unable to get assertion method", e) 103 } 104 105 return errors 106 } 107 108 private fun buildErrorTrace(errors: MutableMap<Long, MutableList<Error>>): ErrorTrace { 109 val errorStates = errors.map { entry -> 110 val timestamp = entry.key 111 val stateTags = entry.value 112 ErrorState(stateTags.toTypedArray(), timestamp.toString()) 113 } 114 return ErrorTrace(errorStates.toTypedArray(), source = "") 115 } 116 }