1 /*
2  * Copyright 2019 Google Inc.
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  *     https://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 trebuchet.util.slices
18 
19 data class SliceContents(val name: String, val value: String?)
20 
21 const val SLICE_NAME_ACTIVITY_DESTROY = "activityDestroy"
22 const val SLICE_NAME_ACTIVITY_PAUSE = "activityPause"
23 const val SLICE_NAME_ACTIVITY_RESUME = "activityResume"
24 const val SLICE_NAME_ACTIVITY_START = "activityStart"
25 const val SLICE_NAME_ACTIVITY_THREAD_MAIN = "ActivityThreadMain"
26 const val SLICE_NAME_APP_IMAGE_INTERN_STRING = "AppImage:InternString"
27 const val SLICE_NAME_APP_IMAGE_LOADING = "AppImage:Loading"
28 const val SLICE_NAME_APP_LAUNCH = "launching"
29 const val SLICE_NAME_ALTERNATE_DEX_OPEN_START = "Dex file open"
30 const val SLICE_NAME_BIND_APPLICATION = "bindApplication"
31 const val SLICE_NAME_DRAWING = "drawing"
32 const val SLICE_NAME_INFLATE = "inflate"
33 const val SLICE_NAME_OPEN_DEX_FILE_FUNCTION = "std::unique_ptr<const DexFile> art::OatDexFile::OpenDexFile(std::string *) const"
34 const val SLICE_NAME_OBFUSCATED_TRACE_START = "X."
35 const val SLICE_NAME_POST_FORK = "PostFork"
36 const val SLICE_NAME_PROC_START = "Start proc"
37 const val SLICE_NAME_REPORT_FULLY_DRAWN = "ActivityManager:ReportingFullyDrawn"
38 const val SLICE_NAME_ZYGOTE_INIT = "ZygoteInit"
39 
40 val SLICE_MAPPERS = arrayOf(
41     Regex("^(Collision check)"),
42     Regex("^(launching):\\s+([\\w\\.])+"),
43     Regex("^(Lock contention).*"),
44     Regex("^(monitor contention).*"),
45     Regex("^(NetworkSecurityConfigProvider.install)"),
46     Regex("^(notifyContentCapture\\((?:true|false)\\))\\sfor\\s(.*)"),
47     Regex("^(Open dex file)(?: from RAM)? ([\\w\\./]*)"),
48     Regex("^(Open oat file)\\s+(.*)"),
49     Regex("^(RegisterDexFile)\\s+(.*)"),
50     Regex("^($SLICE_NAME_REPORT_FULLY_DRAWN)\\s+(.*)"),
51     Regex("^(serviceCreate):.*className=([\\w\\.]+)"),
52     Regex("^(serviceStart):.*cmp=([\\w\\./]+)"),
53     Regex("^(Setup proxies)"),
54     Regex("^($SLICE_NAME_PROC_START):\\s+(.*)"),
55     Regex("^(SuspendThreadByThreadId) suspended (.+)$"),
56     Regex("^(VerifyClass)(.*)"),
57 
58     // Default pattern for slices with a single-word name.
59     Regex("^([\\w:]+)$")
60 )
61 
parseSliceNamenull62 fun parseSliceName(sliceString: String): SliceContents {
63     when {
64     // Handle special cases.
65         sliceString == SLICE_NAME_OPEN_DEX_FILE_FUNCTION -> return SliceContents("Open dex file function invocation", null)
66         sliceString.startsWith(SLICE_NAME_ALTERNATE_DEX_OPEN_START) -> return SliceContents("Open dex file", sliceString.split(" ").last().trim())
67         sliceString.startsWith(SLICE_NAME_OBFUSCATED_TRACE_START) -> return SliceContents("Obfuscated trace point", null)
68         sliceString[0] == '/' -> return SliceContents("Load Dex files from classpath", null)
69 
70         else -> {
71             // Search the slice mapping patterns.
72             for (pattern in SLICE_MAPPERS) {
73                 val matchResult = pattern.find(sliceString)
74 
75                 if (matchResult != null) {
76                     val sliceType = matchResult.groups[1]!!.value.trim()
77 
78                     val sliceDetails =
79                         if (matchResult.groups.size > 2 && !matchResult.groups[2]!!.value.isEmpty()) {
80                             matchResult.groups[2]!!.value.trim()
81                         } else {
82                             null
83                         }
84 
85                     return SliceContents(sliceType, sliceDetails)
86                 }
87             }
88 
89             return SliceContents("Unknown Slice", sliceString)
90         }
91     }
92 
93 }