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.traces.component
18 
19 import android.tools.traces.surfaceflinger.Layer
20 import android.tools.traces.wm.Activity
21 import android.tools.traces.wm.WindowContainer
22 
23 /**
24  * A component matcher that matches the targeted window and layer with ids windowId and layerId
25  * respectively and all their children windows and layers.
26  *
27  * If you want to only match the window and layer with the specified ids then use
28  * ExactComponentIdMatcher instead.
29  */
30 class FullComponentIdMatcher(val windowId: Int, val layerId: Int) : IComponentMatcher {
31     /**
32      * @param windows to search
33      * @return if any of the components matches any of [windows]
34      */
windowMatchesAnyOfnull35     override fun windowMatchesAnyOf(windows: Collection<WindowContainer>): Boolean =
36         windows.any {
37             val parent = it.parent
38             when {
39                 it.token == windowId.toString(16) -> true
40                 parent != null -> windowMatchesAnyOf(parent)
41                 else -> false
42             }
43         }
44 
45     /**
46      * @param activities to search
47      * @return if any of the components matches any of [activities]
48      */
activityMatchesAnyOfnull49     override fun activityMatchesAnyOf(activities: Collection<Activity>) =
50         activities.any { it.token == windowId.toString(16) }
51 
52     /**
53      * @param layers to search
54      * @return if any of the components matches any of [layers]
55      */
layerMatchesAnyOfnull56     override fun layerMatchesAnyOf(layers: Collection<Layer>) =
57         layers.any {
58             val parent = it.parent
59             when {
60                 it.id == layerId -> true
61                 parent != null -> layerMatchesAnyOf(parent)
62                 else -> false
63             }
64         }
65 
66     /** {@inheritDoc} */
checknull67     override fun check(
68         layers: Collection<Layer>,
69         condition: (Collection<Layer>) -> Boolean
70     ): Boolean = condition(layers.filter { layerMatchesAnyOf(it) })
71 
72     /** {@inheritDoc} */
toActivityIdentifiernull73     override fun toActivityIdentifier() = toWindowIdentifier()
74 
75     /** {@inheritDoc} */
76     override fun toWindowIdentifier() = "Window#${windowId.toString(16)} & children"
77 
78     /** {@inheritDoc} */
79     override fun toLayerIdentifier(): String = "Layer#$layerId & children"
80 }
81