1/* 2 * Copyright 2017, 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 17import {transform, nanos_to_string, get_visible_chip} from './transform.js' 18 19function transform_window(entry) { 20 var chips = []; 21 var renderIdentifier = (id) => shortenComponentName(id.title) + "@" + id.hashCode; 22 var visible = entry.windowContainer.visible; 23 function transform_rect(rect, label) { 24 var r = rect || {}; 25 return { 26 left: r.left || 0, 27 right: r.right || 0, 28 top: r.top || 0, 29 bottom: r.bottom || 0, 30 label, 31 } 32 } 33 var name = renderIdentifier(entry.identifier) 34 var rect = transform_rect((entry.windowFrames || entry).frame, name); 35 36 if (visible) { 37 chips.push(get_visible_chip()); 38 } else { 39 rect = undefined; 40 } 41 42 return transform({ 43 obj: entry, 44 kind: 'window', 45 name, 46 children: [ 47 [entry.childWindows, transform_window], 48 [entry.windowContainer.children.reverse(), transform_window_container_child], 49 ], 50 rect, 51 highlight: rect, 52 chips: chips, 53 visible: visible, 54 }); 55} 56 57function transform_activity_record(entry) { 58 return transform({ 59 obj: entry, 60 kind: 'activityRecord', 61 name: entry.name, 62 children: [ 63 [entry.windowToken.windows, transform_window], 64 [entry.windowToken.windowContainer.children.reverse(), transform_window_container_child], 65 ], 66 }); 67} 68 69function transform_task(entry) { 70 return transform({ 71 obj: entry, 72 kind: 'task', 73 name: entry.id || 0, 74 children: [ 75 [entry.tasks, transform_task], 76 [entry.activities, transform_activity_record], 77 [entry.windowContainer.children.reverse(), transform_window_container_child], 78 ], 79 }); 80} 81 82function transform_stack(entry) { 83 return transform({ 84 obj: entry, 85 kind: 'stack', 86 name: entry.id || 0, 87 children: [ 88 [entry.tasks, transform_task], 89 ], 90 }); 91} 92 93function transform_window_token(entry) { 94 return transform({ 95 obj: entry, 96 kind: 'winToken', 97 name: '', 98 children: [ 99 [entry.windows, transform_window], 100 [entry.windowContainer.children.reverse(), transform_window_container_child], 101 ], 102 }); 103} 104 105function transform_below(entry) { 106 return transform({ 107 obj: entry, 108 kind: 'belowAppWindow', 109 name: '', 110 children: [ 111 [entry.windows, transform_window], 112 ], 113 }); 114} 115 116function transform_above(entry) { 117 return transform({ 118 obj: entry, 119 kind: 'aboveAppWindow', 120 name: '', 121 children: [ 122 [entry.windows, transform_window], 123 ], 124 }); 125} 126 127function transform_ime(entry) { 128 return transform({ 129 obj: entry, 130 kind: 'imeWindow', 131 name: '', 132 children: [ 133 [entry.windows, transform_window], 134 ], 135 }); 136} 137 138function transform_window_container_child(entry) { 139 if (entry.displayArea != null) {return transform_display_area(entry.displayArea)} 140 if (entry.displayContent != null) {return transform_display_content(entry.displayContent)} 141 if (entry.task != null) {return transform_task(entry.task)} 142 if (entry.activity != null) {return transform_activity_record(entry.activity)} 143 if (entry.windowToken != null) {return transform_window_token(entry.windowToken)} 144 if (entry.window != null) {return transform_window(entry.window)} 145 146 // The WindowContainerChild may be unknown 147 return transform({ 148 obj: entry, 149 kind: 'WindowContainerChild', 150 name: '', 151 children: [[entry.windowContainer.children.reverse(), transform_window_container_child],] 152 }); 153} 154 155 156function transform_display_area(entry) { 157 return transform({ 158 obj: entry, 159 kind: 'DisplayArea', 160 name: entry.name, 161 children: [ 162 [entry.windowContainer.children.reverse(), transform_window_container_child], 163 ], 164 }); 165} 166 167function transform_display_content(entry) { 168 var bounds = { 169 width: entry.displayInfo.logicalWidth || 0, 170 height: entry.displayInfo.logicalHeight || 0, 171 }; 172 173 return transform({ 174 obj: entry, 175 kind: 'display', 176 name: entry.id || 0, 177 children: [ 178 [entry.aboveAppWindows, transform_above], 179 [entry.imeWindows, transform_ime], 180 [entry.stacks, transform_stack], 181 [entry.tasks, transform_task], 182 [entry.belowAppWindows, transform_below], 183 [entry.windowContainer.children.reverse(), transform_window_container_child], 184 ], 185 bounds, 186 }); 187} 188 189function transform_policy(entry) { 190 return transform({ 191 obj: entry, 192 kind: 'policy', 193 name: 'policy', 194 children: [], 195 }); 196} 197 198function transform_window_service(entry) { 199 return transform({ 200 obj: entry, 201 kind: 'service', 202 name: '', 203 children: [ 204 [entry.rootWindowContainer.displays, transform_display_content], 205 [entry.rootWindowContainer.windowContainer.children.reverse(), 206 transform_window_container_child], 207 [[entry.policy], transform_policy], 208 ], 209 timestamp: entry.elapsedRealtimeNanos, 210 }); 211} 212 213function transform_entry(entry) { 214 return transform({ 215 obj: entry, 216 kind: 'entry', 217 name: nanos_to_string(entry.elapsedRealtimeNanos), 218 children: [ 219 [entry.windowManagerService.rootWindowContainer.displays, transform_display_content], 220 [entry.windowManagerService.rootWindowContainer.windowContainer.children.reverse(), 221 transform_window_container_child], 222 [[entry.windowManagerService.policy], transform_policy], 223 ], 224 timestamp: entry.elapsedRealtimeNanos, 225 stableId: 'entry', 226 }); 227} 228 229function transform_window_trace(entries) { 230 return transform({ 231 obj: entries, 232 kind: 'entries', 233 name: 'entries', 234 children: [ 235 [entries.entry, transform_entry], 236 ], 237 }); 238} 239 240function shortenComponentName(name) { 241 if (!name.includes('/')) { 242 return name 243 } 244 var split = name.split('/'); 245 var pkg = split[0]; 246 var clazz = split.slice(1).join('/'); 247 if (clazz.startsWith(pkg + '.')) { 248 clazz = clazz.slice(pkg.length + 1); 249 return [pkg, clazz].join('/'); 250 } 251 return name; 252} 253 254export {transform_window_service, transform_window_trace}; 255