| /* |
| * Copyright (C) 2023 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.component |
| |
| import kotlin.js.JsName |
| |
| /** |
| * Create a new component identifier. |
| * |
| * This is a version of Android's ComponentName class for flicker. This is necessary because flicker |
| * codebase it also compiled into KotlinJS for use into Winscope |
| * |
| * @param packageName The name of the package that the component exists in. Can not be null. |
| * @param className The name of the class inside <var>pkg</var> that implements the component. |
| */ |
| data class ComponentName(override val packageName: String, override val className: String) : |
| IComponentName { |
| /** |
| * Obtains the activity name from the component name. |
| * |
| * See [ComponentName.toWindowName] for additional information |
| */ |
| override fun toActivityName(): String { |
| return when { |
| packageName.isNotEmpty() && className.isNotEmpty() -> { |
| val sb = StringBuilder(packageName.length + className.length) |
| appendShortString(sb, packageName, className) |
| return sb.toString() |
| } |
| packageName.isNotEmpty() -> packageName |
| className.isNotEmpty() -> className |
| else -> error("Component name should have an activity of class name") |
| } |
| } |
| |
| /** |
| * Obtains the window name from the component name. |
| * |
| * [ComponentName] builds the string representation as PKG/CLASS, however this doesn't work for |
| * system components such as IME, NavBar and StatusBar, Toast. |
| * |
| * If the component doesn't have a package name, assume it's a system component and return only |
| * the class name |
| */ |
| override fun toWindowName(): String { |
| return when { |
| packageName.isNotEmpty() && className.isNotEmpty() -> "$packageName/$className" |
| packageName.isNotEmpty() -> packageName |
| className.isNotEmpty() -> className |
| else -> error("Component name should have an activity of class name") |
| } |
| } |
| |
| @JsName("toShortWindowName") |
| private fun toShortWindowName(): String { |
| return when { |
| packageName.isNotEmpty() && className.isNotEmpty() -> |
| "$packageName/${className.removePrefix(packageName)}" |
| packageName.isNotEmpty() -> packageName |
| className.isNotEmpty() -> className |
| else -> error("Component name should have an activity of class name") |
| } |
| } |
| |
| /** |
| * Obtains the layer name from the component name. |
| * |
| * See [toWindowName] for additional information |
| */ |
| override fun toLayerName(): String { |
| var result = this.toWindowName() |
| if (result.contains("/") && !result.contains("#")) { |
| result = "$result#" |
| } |
| |
| return result |
| } |
| |
| @JsName("appendShortString") |
| private fun appendShortString(sb: StringBuilder, packageName: String, className: String) { |
| sb.append(packageName).append('/') |
| appendShortClassName(sb, packageName, className) |
| } |
| |
| @JsName("appendShortClassName") |
| private fun appendShortClassName(sb: StringBuilder, packageName: String, className: String) { |
| if (className.startsWith(packageName)) { |
| val packageNameLength = packageName.length |
| val classNameLength = className.length |
| if (classNameLength > packageNameLength && className[packageNameLength] == '.') { |
| sb.append(className, packageNameLength, classNameLength) |
| return |
| } |
| } |
| sb.append(className) |
| } |
| |
| @JsName("toActivityRecordFilter") |
| fun toActivityRecordFilter(): Regex = |
| Regex("ActivityRecord\\{.*${Regex.escape(this.toShortWindowName())}") |
| |
| @JsName("toActivityNameRegex") |
| fun toActivityNameRegex(): Regex = Regex(".*${Regex.escape(this.toActivityName())}.*") |
| |
| @JsName("toWindowNameRegex") |
| fun toWindowNameRegex(): Regex = Regex(".*${Regex.escape(this.toWindowName())}.*") |
| |
| @JsName("toLayerNameRegex") |
| fun toLayerNameRegex(): Regex = Regex(".*${Regex.escape(this.toLayerName())}.*") |
| |
| override fun toString(): String = toShortWindowName() |
| } |