1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {BaseElement, element} from "../../../base-ui/BaseElement.js"; 17import {LitSelectV} from "../../../base-ui/select/LitSelectV.js"; 18import LitSwitch from "../../../base-ui/switch/lit-switch.js"; 19import "../../../base-ui/select/LitSelectV.js"; 20import "../../../base-ui/select/LitSelect.js"; 21 22import "../../../base-ui/switch/lit-switch.js"; 23import {LitSelect} from "../../../base-ui/select/LitSelect.js"; 24import {SpRecordTrace} from "../SpRecordTrace.js"; 25import {Cmd} from "../../../command/Cmd.js"; 26import {CmdConstant} from "../../../command/CmdConstant.js"; 27import {HdcDeviceManager} from "../../../hdc/HdcDeviceManager.js"; 28 29@element("sp-file-system") 30export class SpFileSystem extends BaseElement { 31 private processInput: LitSelectV | undefined | null; 32 private maximum: HTMLInputElement | undefined | null; 33 private selectProcess: HTMLInputElement | undefined | null; 34 35 private configList: Array<any> = []; 36 private list: Array<any> = []; 37 38 private eventList: Array<any> = [ 39 "open", 40 "close", 41 "read", 42 "write" 43 ]; 44 45 set startRecord(start: boolean) { 46 if (start) { 47 this.unDisable(); 48 this.setAttribute("startRecord", ""); 49 this.selectProcess!.removeAttribute("readonly"); 50 } else { 51 if(!this.startFileSystem && !this.startVirtualMemory) { 52 this.removeAttribute("startRecord") 53 this.disable(); 54 this.selectProcess!.setAttribute("readonly", "readonly") 55 } 56 } 57 } 58 59 get startRecord(): boolean { 60 return this.hasAttribute("startRecord"); 61 } 62 63 set startFileSystem(start: boolean) { 64 if (start) { 65 this.setAttribute("startSamp", ""); 66 } else { 67 this.removeAttribute("startSamp") 68 } 69 this.startRecord = start; 70 } 71 72 get startFileSystem(): boolean { 73 return this.hasAttribute("startSamp"); 74 } 75 76 set startVirtualMemory(start: boolean) { 77 if (start) { 78 this.setAttribute("virtual", ""); 79 } else { 80 this.removeAttribute("virtual") 81 } 82 this.startRecord = start; 83 } 84 85 get startVirtualMemory(): boolean { 86 return this.hasAttribute("virtual"); 87 } 88 89 set startIo(start: boolean) { 90 if (start) { 91 this.setAttribute("io", ""); 92 } else { 93 this.removeAttribute("io") 94 } 95 this.startRecord = start; 96 } 97 98 get startIo(): boolean { 99 return this.hasAttribute("io"); 100 } 101 102 getSystemConfig(): SystemConfig | undefined { 103 let configVal = this.shadowRoot?.querySelectorAll<HTMLElement>(".config"); 104 let systemConfig: SystemConfig = { 105 process: "", 106 }; 107 configVal!.forEach(value => { 108 switch (value.title) { 109 case "Process": 110 let processSelect = value as LitSelectV; 111 if (processSelect.all) { 112 systemConfig.process = "ALL" 113 break 114 } 115 if (processSelect.value.length > 0) { 116 let result = processSelect.value.match(/\((.+?)\)/g) 117 if (result) { 118 systemConfig.process = result.toString().replaceAll("(", "").replaceAll(")", "") 119 } else { 120 systemConfig.process = processSelect.value; 121 } 122 } 123 break; 124 } 125 }); 126 return systemConfig; 127 } 128 129 initElements(): void { 130 this.initConfigList(); 131 let configList = this.shadowRoot?.querySelector<HTMLDivElement>(".configList"); 132 this.configList.forEach(config => { 133 let div = document.createElement("div"); 134 if (config.hidden) { 135 div.className = "config-div hidden"; 136 } else { 137 div.className = "config-div"; 138 } 139 let headDiv = document.createElement("div"); 140 div.appendChild(headDiv); 141 let title = document.createElement("span"); 142 title.className = "title"; 143 title.textContent = config.title; 144 headDiv.appendChild(title); 145 let des = document.createElement("span"); 146 des.textContent = config.des; 147 des.className = "des"; 148 headDiv.appendChild(des); 149 switch (config.type) { 150 case "select-multiple": 151 let html = ''; 152 let placeholder = config.selectArray[0]; 153 if (config.title == "Process") { 154 } else if (config.title == "SystemCall Event") { 155 placeholder = "ALL-Event" 156 } 157 html += `<lit-select-v default-value="" rounded="" class="select config" mode="multiple" canInsert="" title="${config.title}" rounded placement = "bottom" placeholder="${placeholder}">` 158 config.selectArray.forEach((value: string) => { 159 html += `<lit-select-option value="${value}">${value}</lit-select-option>` 160 }); 161 html += `</lit-select-v>`; 162 div.innerHTML = div.innerHTML + html; 163 break; 164 case "input": 165 let input = document.createElement("input"); 166 input.className = "input config"; 167 input.textContent = config.value; 168 input.value = config.value; 169 input.title = config.title; 170 if (config.title == "Record Time") { 171 input.oninput = (ev) => { 172 input.value = input.value.replace(/\D/g, '') 173 }; 174 } 175 div.appendChild(input); 176 break; 177 case "select": 178 let html1 = ''; 179 html1 += `<lit-select rounded="" default-value="" class="select config" placement="bottom" title="${config.title}" placeholder="${config.selectArray[0]}">` 180 config.selectArray.forEach((value: string) => { 181 html1 += `<lit-select-option value="${value}">${value}</lit-select-option>` 182 }) 183 html1 += `</lit-select>` 184 div.innerHTML = div.innerHTML + html1; 185 break; 186 case "switch": 187 let switch1 = document.createElement("lit-switch") as LitSwitch; 188 switch1.className = "config"; 189 switch1.title = config.title; 190 if (config.value) { 191 switch1.checked = true; 192 } else { 193 switch1.checked = false; 194 } 195 if (config.title == "Start FileSystem Record") { 196 switch1.addEventListener("change", (event: any) => { 197 let detail = event.detail; 198 if (detail.checked) { 199 this.startFileSystem = true; 200 } else { 201 this.startFileSystem = false; 202 } 203 }) 204 } 205 if (config.title == "Start Virtual Memory Record") { 206 switch1.addEventListener("change", (event: any) => { 207 let detail = event.detail; 208 if (detail.checked) { 209 this.startVirtualMemory = true; 210 } else { 211 this.startVirtualMemory = false; 212 } 213 }) 214 } 215 headDiv.appendChild(switch1); 216 break; 217 default: 218 break; 219 } 220 configList!.appendChild(div); 221 }); 222 this.processInput = this.shadowRoot?.querySelector<LitSelectV>("lit-select-v[title='Process']"); 223 this.maximum = this.shadowRoot?.querySelector<HTMLInputElement>("input[title='Max Unwind Level']"); 224 this.selectProcess = this.processInput!.shadowRoot?.querySelector("input") as HTMLInputElement; 225 let processData: Array<string> = [] 226 this.selectProcess!.addEventListener('mousedown', ev => { 227 if (SpRecordTrace.serialNumber == '') { 228 this.processInput!.dataSource([], '') 229 } 230 }) 231 this.selectProcess!.addEventListener('mouseup', () => { 232 if (SpRecordTrace.serialNumber == '') { 233 this.processInput?.dataSource([], 'ALL-Process') 234 } else { 235 if (SpRecordTrace.isVscode) { 236 let cmd = Cmd.formatString(CmdConstant.CMD_GET_PROCESS_DEVICES, [SpRecordTrace.serialNumber]) 237 Cmd.execHdcCmd(cmd, (res: string) => { 238 processData = [] 239 let lineValues: string[] = res.replace(/\r\n/g, "\r").replace(/\n/g, "\r").split(/\r/); 240 for (let lineVal of lineValues) { 241 if (lineVal.indexOf("__progname") != -1 || lineVal.indexOf("PID CMD") != -1) { 242 continue; 243 } 244 let process: string[] = lineVal.trim().split(" "); 245 if (process.length == 2) { 246 let processId = process[0] 247 let processName = process[1] 248 processData.push(processName + "(" + processId + ")") 249 } 250 } 251 if(processData.length > 0 && this.startRecord){ 252 this.processInput!.setAttribute("readonly", "readonly") 253 } 254 this.processInput?.dataSource(processData, 'ALL-Process') 255 }) 256 } else { 257 HdcDeviceManager.connect(SpRecordTrace.serialNumber).then(conn => { 258 if (conn) { 259 HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_PROCESS, false).then(res => { 260 processData = [] 261 if (res) { 262 let lineValues: string[] = res.replace(/\r\n/g, "\r").replace(/\n/g, "\r").split(/\r/); 263 for (let lineVal of lineValues) { 264 if (lineVal.indexOf("__progname") != -1 || lineVal.indexOf("PID CMD") != -1) { 265 continue; 266 } 267 let process: string[] = lineVal.trim().split(" "); 268 if (process.length == 2) { 269 let processId = process[0] 270 let processName = process[1] 271 processData.push(processName + "(" + processId + ")") 272 } 273 } 274 } 275 if(processData.length > 0 && this.startRecord){ 276 this.selectProcess!.setAttribute("readonly", "readonly") 277 } 278 this.processInput?.dataSource(processData, 'ALL-Process') 279 }) 280 } 281 }) 282 } 283 } 284 }); 285 this.disable(); 286 } 287 288 private unDisable() { 289 let configVal = this.shadowRoot?.querySelectorAll<HTMLElement>(".config"); 290 configVal!.forEach(configVal1 => { 291 configVal1.removeAttribute("disabled") 292 }) 293 } 294 295 private disable() { 296 let configVal = this.shadowRoot?.querySelectorAll<HTMLElement>(".config"); 297 configVal!.forEach(configVal1 => { 298 if (configVal1.title == "Start FileSystem Record" || configVal1.title == "Start Virtual Memory Record") { 299 } else { 300 configVal1.setAttribute("disabled", '') 301 } 302 }) 303 } 304 305 initConfigList(): void { 306 this.configList = [ 307 { 308 title: "Start FileSystem Record", 309 des: "", 310 hidden: false, 311 type: "switch", 312 value: false 313 }, 314 { 315 title: "Start Virtual Memory Record", 316 des: "", 317 hidden: false, 318 type: "switch", 319 value: false 320 }, 321 { 322 title: "Process", 323 des: "Record process", 324 hidden: false, 325 type: "select-multiple", 326 selectArray: [ 327 "" 328 ] 329 } 330 ] 331 } 332 333 initHtml(): string { 334 return ` 335 <style> 336 :host{ 337 display: inline-block; 338 width: 100%; 339 height: 100%; 340 background: var(--dark-background3,#FFFFFF); 341 border-radius: 0px 16px 16px 0px; 342 } 343 344 .root { 345 padding-top: 30px; 346 padding-left: 54px; 347 margin-right: 30px; 348 font-size:16px; 349 margin-bottom: 30px; 350 } 351 352 .config-div { 353 width: 80%; 354 display: flex; 355 flex-direction: column; 356 margin-top: 5vh; 357 margin-bottom: 5vh; 358 gap: 25px; 359 } 360 361 .title { 362 opacity: 0.9; 363 font-family: Helvetica-Bold; 364 font-size: 18px; 365 text-align: center; 366 line-height: 40px; 367 font-weight: 700; 368 margin-right: 10px; 369 } 370 371 .des { 372 opacity: 0.6; 373 font-family: Helvetica; 374 font-size: 14px; 375 text-align: center; 376 line-height: 35px; 377 font-weight: 400; 378 } 379 380 .select { 381 border-radius: 15px; 382 } 383 384 lit-switch { 385 display:inline; 386 float: right; 387 height: 38px; 388 margin-top: 10px; 389 } 390 input { 391 height: 25px; 392 outline:none; 393 border-radius: 16px; 394 text-indent:2% 395 } 396 input::-webkit-input-placeholder{ 397 color:var(--bark-prompt,#999999); 398 } 399 400 .input { 401 border: 1px solid var(--dark-background5,#ccc); 402 font-family: Helvetica; 403 font-size: 14px; 404 color: var(--dark-color1,#212121); 405 text-align: left; 406 line-height: 20px; 407 font-weight: 400; 408 } 409 410 :host([startSamp]) .input { 411 background: var(--dark-background5,#FFFFFF); 412 } 413 414 :host(:not([startSamp])) .input { 415 color: #999999; 416 } 417 </style> 418 <div class="root"> 419 <div class="configList"> 420 </div> 421 </div> 422 `; 423 } 424} 425 426export interface SystemConfig { 427 process: string; 428} 429