1 /*
2  * Copyright (C) 2023 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 android.tools.flicker.assertions
18 
19 import android.tools.Tag
20 import android.tools.flicker.subject.FlickerSubject
21 import android.tools.flicker.subject.FlickerTraceSubject
22 import android.tools.flicker.subject.events.EventLogSubject
23 import android.tools.flicker.subject.layers.LayerTraceEntrySubject
24 import android.tools.flicker.subject.layers.LayersTraceSubject
25 import android.tools.flicker.subject.region.RegionTraceSubject
26 import android.tools.flicker.subject.wm.WindowManagerStateSubject
27 import android.tools.flicker.subject.wm.WindowManagerTraceSubject
28 import android.tools.traces.component.IComponentMatcher
29 import android.tools.withTracing
30 
31 class AssertionFactory {
32     private val wmAssertionFactory =
33         AssertionDataFactory(WindowManagerStateSubject::class, WindowManagerTraceSubject::class)
34     private val layersAssertionFactory =
35         AssertionDataFactory(LayerTraceEntrySubject::class, LayersTraceSubject::class)
36     private val eventLogAssertionFactory = AssertionStateDataFactory(EventLogSubject::class)
37 
38     /**
39      * Create an [assertion] on the initial state of a WM trace (before transition)
40      *
41      * @param assertion Assertion predicate
42      */
createWmStartAssertionnull43     fun createWmStartAssertion(assertion: WindowManagerStateSubject.() -> Unit): AssertionData =
44         withTracing("createWmStartAssertion") {
45             wmAssertionFactory.createStartStateAssertion(assertion as FlickerSubject.() -> Unit)
46         }
47 
48     /**
49      * Create an [assertion] on the final state of a WM trace (after transition)
50      *
51      * @param assertion Assertion predicate
52      */
createWmEndAssertionnull53     fun createWmEndAssertion(assertion: WindowManagerStateSubject.() -> Unit): AssertionData =
54         withTracing("createWmEndAssertion") {
55             wmAssertionFactory.createEndStateAssertion(assertion as FlickerSubject.() -> Unit)
56         }
57 
58     /**
59      * Create an [assertion] on a WM trace
60      *
61      * @param assertion Assertion predicate
62      */
createWmAssertionnull63     fun createWmAssertion(assertion: WindowManagerTraceSubject.() -> Unit): AssertionData =
64         withTracing("createWmAssertion") {
65             wmAssertionFactory.createTraceAssertion(
66                 assertion as (FlickerTraceSubject<FlickerSubject>) -> Unit
67             )
68         }
69 
70     /**
71      * Create an [assertion] on a user defined moment ([tag]) of a WM trace
72      *
73      * @param assertion Assertion predicate
74      */
createWmTagAssertionnull75     fun createWmTagAssertion(
76         tag: String,
77         assertion: WindowManagerStateSubject.() -> Unit
78     ): AssertionData =
79         withTracing("createWmTagAssertion") {
80             wmAssertionFactory.createTagAssertion(tag, assertion as FlickerSubject.() -> Unit)
81         }
82 
83     /**
84      * Create an [assertion] on the visible region of WM state matching [componentMatcher]
85      *
86      * @param componentMatcher Components to search
87      * @param assertion Assertion predicate
88      */
createWmVisibleRegionAssertionnull89     fun createWmVisibleRegionAssertion(
90         componentMatcher: IComponentMatcher,
91         assertion: RegionTraceSubject.() -> Unit
92     ): AssertionData =
93         withTracing("createWmVisibleRegionAssertion") {
94             val closedAssertion: WindowManagerTraceSubject.() -> Unit = {
95                 require(!hasAssertions()) { "Subject was already used to execute assertions" }
96                 // convert WindowManagerTraceSubject to RegionTraceSubject
97                 val regionTraceSubject = visibleRegion(componentMatcher)
98                 // add assertions to the regionTraceSubject's AssertionChecker
99                 assertion(regionTraceSubject)
100                 // loop through all entries to validate assertions
101                 regionTraceSubject.forAllEntries()
102             }
103 
104             wmAssertionFactory.createTraceAssertion(
105                 closedAssertion as (FlickerTraceSubject<FlickerSubject>) -> Unit
106             )
107         }
108 
109     /**
110      * Create an [assertion] on the initial state of a SF trace (before transition)
111      *
112      * @param assertion Assertion predicate
113      */
createLayersStartAssertionnull114     fun createLayersStartAssertion(assertion: LayerTraceEntrySubject.() -> Unit): AssertionData =
115         withTracing("createLayersStartAssertion") {
116             layersAssertionFactory.createStartStateAssertion(assertion as FlickerSubject.() -> Unit)
117         }
118 
119     /**
120      * Create an [assertion] on the final state of a SF trace (after transition)
121      *
122      * @param assertion Assertion predicate
123      */
createLayersEndAssertionnull124     fun createLayersEndAssertion(assertion: LayerTraceEntrySubject.() -> Unit): AssertionData =
125         withTracing("createLayersEndAssertion") {
126             layersAssertionFactory.createEndStateAssertion(assertion as FlickerSubject.() -> Unit)
127         }
128 
129     /**
130      * Create an [assertion] on a SF trace
131      *
132      * @param assertion Assertion predicate
133      */
createLayersAssertionnull134     fun createLayersAssertion(assertion: LayersTraceSubject.() -> Unit): AssertionData =
135         withTracing("createLayersAssertion") {
136             layersAssertionFactory.createTraceAssertion(
137                 assertion as (FlickerTraceSubject<FlickerSubject>) -> Unit
138             )
139         }
140 
141     /**
142      * Create an [assertion] on a user defined moment ([tag]) of a SF trace
143      *
144      * @param assertion Assertion predicate
145      */
createLayersTagAssertionnull146     fun createLayersTagAssertion(
147         tag: String,
148         assertion: LayerTraceEntrySubject.() -> Unit
149     ): AssertionData =
150         withTracing("createLayersTagAssertion") {
151             layersAssertionFactory.createTagAssertion(tag, assertion as FlickerSubject.() -> Unit)
152         }
153 
154     /**
155      * Create an [assertion] on the visible region of a component on the layers trace matching
156      * [componentMatcher]
157      *
158      * @param componentMatcher Components to search
159      * @param useCompositionEngineRegionOnly If true, uses only the region calculated from the
160      *   Composition Engine (CE) -- visibleRegion in the proto definition. Otherwise, calculates the
161      *   visible region when the information is not available from the CE
162      * @param assertion Assertion predicate
163      */
createLayersVisibleRegionAssertionnull164     fun createLayersVisibleRegionAssertion(
165         componentMatcher: IComponentMatcher,
166         useCompositionEngineRegionOnly: Boolean = true,
167         assertion: RegionTraceSubject.() -> Unit
168     ): AssertionData =
169         withTracing("createLayersVisibleRegionAssertion") {
170             val closedAssertion: LayersTraceSubject.() -> Unit = {
171                 require(!hasAssertions()) { "Subject was already used to execute assertions" }
172                 // convert LayersTraceSubject to RegionTraceSubject
173                 val regionTraceSubject =
174                     visibleRegion(componentMatcher, useCompositionEngineRegionOnly)
175 
176                 // add assertions to the regionTraceSubject's AssertionChecker
177                 assertion(regionTraceSubject)
178                 // loop through all entries to validate assertions
179                 regionTraceSubject.forAllEntries()
180             }
181 
182             layersAssertionFactory.createTraceAssertion(
183                 closedAssertion as (FlickerTraceSubject<*>) -> Unit
184             )
185         }
186 
187     /**
188      * Create an [assertion] on a sequence of event logs
189      *
190      * @param assertion Assertion predicate
191      */
createEventLogAssertionnull192     fun createEventLogAssertion(assertion: EventLogSubject.() -> Unit): AssertionData =
193         withTracing("createEventLogAssertion") {
194             eventLogAssertionFactory.createTagAssertion(
195                 Tag.ALL,
196                 assertion as FlickerSubject.() -> Unit
197             )
198         }
199 }
200