• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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.traces.common
18 
19 import kotlin.text.Regex.Companion.escape
20 
21 /**
22  * Create a new component identifier.
23  *
24  * This is a version of Android's ComponentName class for flicker. This is necessary because
25  * flicker codebase it also compiled into KotlinJS for use into Winscope
26  *
27  * @param packageName The name of the package that the component exists in.  Can
28  * not be null.
29  * @param className The name of the class inside of <var>pkg</var> that
30  * implements the component.  Can not be null.
31  */
32 data class FlickerComponentName(
33     val packageName: String,
34     val className: String
35 ) {
36     /**
37      * Obtains the activity name from the component name.
38      *
39      * See [ComponentName.toWindowName] for additional information
40      */
toActivityNamenull41     fun toActivityName(): String {
42         return when {
43             packageName.isNotEmpty() && className.isNotEmpty() -> {
44                 val sb = StringBuilder(packageName.length + className.length)
45                 appendShortString(sb, packageName, className)
46                 return sb.toString()
47             }
48             packageName.isNotEmpty() -> packageName
49             className.isNotEmpty() -> className
50             else -> error("Component name should have an activity of class name")
51         }
52     }
53 
54     /**
55      * Obtains the window name from the component name.
56      *
57      * [ComponentName] builds the string representation as PKG/CLASS, however this doesn't
58      * work for system components such as IME, NavBar and StatusBar, Toast.
59      *
60      * If the component doesn't have a package name, assume it's a system component and return only
61      * the class name
62      */
toWindowNamenull63     fun toWindowName(): String {
64         return when {
65             packageName.isNotEmpty() && className.isNotEmpty() -> "$packageName/$className"
66             packageName.isNotEmpty() -> packageName
67             className.isNotEmpty() -> className
68             else -> error("Component name should have an activity of class name")
69         }
70     }
71 
toShortWindowNamenull72     fun toShortWindowName(): String {
73         return when {
74             packageName.isNotEmpty() && className.isNotEmpty() ->
75                 "$packageName/${className.removePrefix(packageName)}"
76             packageName.isNotEmpty() -> packageName
77             className.isNotEmpty() -> className
78             else -> error("Component name should have an activity of class name")
79         }
80     }
81 
82     /**
83      * Obtains the layer name from the component name.
84      *
85      * See [toWindowName] for additional information
86      */
toLayerNamenull87     fun toLayerName(): String {
88         var result = this.toWindowName()
89         if (result.contains("/") && !result.contains("#")) {
90             result = "$result#"
91         }
92 
93         return result
94     }
95 
toActivityRecordFilternull96     fun toActivityRecordFilter(): Regex {
97         return Regex("ActivityRecord\\{.*${escape(this.toShortWindowName())}")
98     }
99 
appendShortStringnull100     private fun appendShortString(sb: StringBuilder, packageName: String, className: String) {
101         sb.append(packageName).append('/')
102         appendShortClassName(sb, packageName, className)
103     }
104 
appendShortClassNamenull105     private fun appendShortClassName(sb: StringBuilder, packageName: String, className: String) {
106         if (className.startsWith(packageName)) {
107             val packageNameLength = packageName.length
108             val classNameLength = className.length
109             if (classNameLength > packageNameLength && className[packageNameLength] == '.') {
110                 sb.append(className, packageNameLength, classNameLength)
111                 return
112             }
113         }
114         sb.append(className)
115     }
116 
117     companion object {
118         val NAV_BAR = FlickerComponentName("", "NavigationBar0")
119         val STATUS_BAR = FlickerComponentName("", "StatusBar")
120         val ROTATION = FlickerComponentName("", "RotationLayer")
121         val BACK_SURFACE = FlickerComponentName("", "BackColorSurface")
122         val IME = FlickerComponentName("", "InputMethod")
123         val IME_SNAPSHOT = FlickerComponentName("", "IME-snapshot-surface")
124         val SPLASH_SCREEN = FlickerComponentName("", "Splash Screen")
125         val SNAPSHOT = FlickerComponentName("", "SnapshotStartingWindow")
126         val LETTERBOX = FlickerComponentName("", "Letterbox")
127         val WALLPAPER_BBQ_WRAPPER =
128                 FlickerComponentName("", "Wallpaper BBQ wrapper")
129         val PIP_CONTENT_OVERLAY = FlickerComponentName("", "PipContentOverlay")
130 
unflattenFromStringnull131         fun unflattenFromString(str: String): FlickerComponentName {
132             val sep = str.indexOf('/')
133             if (sep < 0 || sep + 1 >= str.length) {
134                 error("Missing package/class separator")
135             }
136             val pkg = str.substring(0, sep)
137             var cls = str.substring(sep + 1)
138             if (cls.isNotEmpty() && cls[0] == '.') {
139                 cls = pkg + cls
140             }
141             return FlickerComponentName(pkg, cls)
142         }
143     }
144 }