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 import java.util.function.Predicate 23 24 class ComponentSplashScreenMatcher(val componentNameMatcher: IComponentNameMatcher) : 25 IComponentMatcher { windowMatchesAnyOfnull26 override fun windowMatchesAnyOf(windows: Collection<WindowContainer>): Boolean { 27 error("Unimplemented - There are no splashscreen windows") 28 } 29 activityMatchesAnyOfnull30 override fun activityMatchesAnyOf(activities: Collection<Activity>): Boolean { 31 error("Unimplemented - There are no splashscreen windows") 32 } 33 layerMatchesAnyOfnull34 override fun layerMatchesAnyOf(layers: Collection<Layer>): Boolean { 35 return layers.any { 36 if (!it.name.contains("Splash Screen")) { 37 return@any false 38 } 39 if (it.children.isNotEmpty()) { 40 // Not leaf splash screen layer but container of the splash screen layer 41 return@any false 42 } 43 44 var ancestor: Layer? = it.parent?.parent 45 requireNotNull(ancestor) { "Splash screen layer's grandparent shouldn't be null" } 46 47 var hasActivityRecord = componentNameMatcher.activityRecordMatchesAnyOf(ancestor) 48 var count = 0 49 while (!hasActivityRecord && ancestor != null && count++ < 5) { 50 ancestor = ancestor.parent 51 hasActivityRecord = 52 ancestor != null && componentNameMatcher.activityRecordMatchesAnyOf(ancestor) 53 } 54 return@any hasActivityRecord 55 } 56 } 57 toActivityIdentifiernull58 override fun toActivityIdentifier(): String { 59 error("Unimplemented - There are no splashscreen windows") 60 } 61 toWindowIdentifiernull62 override fun toWindowIdentifier(): String { 63 error("Unimplemented - There are no splashscreen windows") 64 } 65 toLayerIdentifiernull66 override fun toLayerIdentifier(): String { 67 return "Splash Screen ${componentNameMatcher.className}" 68 } 69 checknull70 override fun check( 71 layers: Collection<Layer>, 72 condition: Predicate<Collection<Layer>>, 73 ): Boolean { 74 val splashScreenLayer = layers.filter { layerMatchesAnyOf(it) } 75 require(splashScreenLayer.size <= 1) { 76 "More than on SplashScreen layer found. Only up to 1 match was expected." 77 } 78 return condition.test(splashScreenLayer) 79 } 80 } 81