Add SplashScreen component matcher

Test: atest FlickerLibTest
Change-Id: I9ddc61ff5e3e04414f3f5359a9c4b5c6f526ee8a
diff --git a/libraries/flicker/src/com/android/server/wm/flicker/helpers/StandardAppHelper.kt b/libraries/flicker/src/com/android/server/wm/flicker/helpers/StandardAppHelper.kt
index 8a0d393..084ecc0 100644
--- a/libraries/flicker/src/com/android/server/wm/flicker/helpers/StandardAppHelper.kt
+++ b/libraries/flicker/src/com/android/server/wm/flicker/helpers/StandardAppHelper.kt
@@ -42,7 +42,7 @@
 open class StandardAppHelper(
     instr: Instrumentation,
     val appName: String,
-    val componentMatcher: IComponentNameMatcher
+    val componentMatcher: ComponentNameMatcher
 ) : AbstractStandardAppHelper(instr), IComponentNameMatcher by componentMatcher {
     constructor(
         instr: Instrumentation,
diff --git a/libraries/flicker/src/com/android/server/wm/traces/common/ComponentSplashScreenMatcher.kt b/libraries/flicker/src/com/android/server/wm/traces/common/ComponentSplashScreenMatcher.kt
new file mode 100644
index 0000000..9b32d24
--- /dev/null
+++ b/libraries/flicker/src/com/android/server/wm/traces/common/ComponentSplashScreenMatcher.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.wm.traces.common
+
+import com.android.server.wm.traces.common.layers.Layer
+import com.android.server.wm.traces.common.windowmanager.windows.Activity
+import com.android.server.wm.traces.common.windowmanager.windows.WindowState
+
+class ComponentSplashScreenMatcher(val componentNameMatcher: ComponentNameMatcher) :
+    IComponentMatcher {
+    override fun windowMatchesAnyOf(windows: Array<WindowState>): Boolean {
+        error("Unimplemented - There are no splashscreen windows")
+    }
+
+    override fun activityMatchesAnyOf(activities: Array<Activity>): Boolean {
+        error("Unimplemented - There are no splashscreen windows")
+    }
+
+    override fun layerMatchesAnyOf(layers: Array<Layer>): Boolean {
+        return layers.any {
+            if (!it.name.contains("Splash Screen")) {
+                return@any false
+            }
+            if (it.children.isNotEmpty()) {
+                // Not leaf splash screen layer but container of the splash screen layer
+                return@any false
+            }
+            val grandParent = it.parent?.parent
+            requireNotNull(grandParent) { "Splash screen layer's grandparent shouldn't be null" }
+            return@any componentNameMatcher.layerMatchesAnyOf(grandParent)
+        }
+    }
+
+    override fun toActivityIdentifier(): String {
+        error("Unimplemented - There are no splashscreen windows")
+    }
+
+    override fun toWindowIdentifier(): String {
+        error("Unimplemented - There are no splashscreen windows")
+    }
+
+    override fun toLayerIdentifier(): String {
+        return "Splash Screen ${componentNameMatcher.className}"
+    }
+
+    override fun check(
+        layers: Collection<Layer>,
+        condition: (Collection<Layer>) -> Boolean
+    ): Boolean {
+        val splashScreenLayer = layers.filter { layerMatchesAnyOf(it) }
+        require(splashScreenLayer.size < 1) {
+            "More than on SplashScreen layer found. Only up to 1 match was expected."
+        }
+        return condition(splashScreenLayer)
+    }
+}