diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index 3c4e3cae54960ab31e1cd98a7a93a5f75dbb5151..670470b23d88976b75347945767f5e1776151d26 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -1449,7 +1449,7 @@ export class SpApplication extends BaseElement { }, { title: 'Keyboard shortcuts', - icon: 'menu', + icon: 'smart-help', clickHandler: function (item: MenuItem) { SpStatisticsHttpUtil.addOrdinaryVisitAction({ event: 'Keyboard shortcuts', diff --git a/ide/src/trace/component/SpKeyboard.ts b/ide/src/trace/component/SpKeyboard.ts index 45a30f51affe9c3b6b124ed31e4f81053918c3d8..19341f17e435c3dcc5410cb6f2bf147f054a0fc5 100644 --- a/ide/src/trace/component/SpKeyboard.ts +++ b/ide/src/trace/component/SpKeyboard.ts @@ -137,6 +137,12 @@ export class SpKeyboard extends BaseElement { 展示快捷方式 + + +
v
+ + 展示/隐藏Vsync信号 + diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 2de3499312f183f627db7bcdf9f40a8146a1174f..3db03698763d9048a89b6b2dc2b9ebb125bdff74 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -84,6 +84,7 @@ import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.j import { SpChartList } from './trace/SpChartList.js'; import './trace/SpChartList.js'; import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup.js'; +import { AllAppStartupStruct } from '../database/ui-worker/ProcedureWorkerAllAppStartup.js'; import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit.js'; import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames.js'; import { FlagsConfig } from './SpFlags.js'; @@ -2571,6 +2572,10 @@ export class SpSystemTrace extends BaseElement { TraceRow.ROW_TYPE_APP_STARTUP, () => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined, ], + [ + TraceRow.ROW_TYPE_ALL_APPSTARTUPS, + () => AllAppStartupStruct.hoverStartupStruct !== null && AllAppStartupStruct.hoverStartupStruct !== undefined, + ], [TraceRow.ROW_TYPE_STATIC_INIT, () => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined], [TraceRow.ROW_TYPE_JANK, () => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined], [TraceRow.ROW_TYPE_HEAP, () => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined], @@ -3134,6 +3139,10 @@ export class SpSystemTrace extends BaseElement { AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct; this.traceSheetEL?.displayStartupData(AppStartupStruct.selectStartupStruct, scrollToFuncHandler); this.timerShaftEL?.modifyFlagList(undefined); + }else if(clickRowType === TraceRow.ROW_TYPE_ALL_APPSTARTUPS && AllAppStartupStruct.hoverStartupStruct){ + AllAppStartupStruct.selectStartupStruct = AllAppStartupStruct.hoverStartupStruct; + this.traceSheetEL?.displayAllStartupData(AllAppStartupStruct.selectStartupStruct!, scrollToFuncHandler) + this.timerShaftEL?.modifyFlagList(undefined); } else if (clickRowType === TraceRow.ROW_TYPE_STATIC_INIT && SoStruct.hoverSoStruct) { SoStruct.selectSoStruct = SoStruct.hoverSoStruct; this.traceSheetEL?.displayStaticInitData(SoStruct.selectSoStruct, scrollToFuncHandler); diff --git a/ide/src/trace/component/chart/SpAllAppStartups.ts b/ide/src/trace/component/chart/SpAllAppStartups.ts new file mode 100644 index 0000000000000000000000000000000000000000..d12ed401563a85540cd4c580024563dcd2985b74 --- /dev/null +++ b/ide/src/trace/component/chart/SpAllAppStartups.ts @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * 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. + */ + +import { SpSystemTrace } from '../SpSystemTrace.js'; +import { TraceRow } from '../trace/base/TraceRow.js'; +import { renders } from '../../database/ui-worker/ProcedureWorker.js'; +import { CpuFreqStruct } from '../../database/ui-worker/ProcedureWorkerFreq.js'; +import { + queryAppStartupProcessIds, + queryProcessStartup, + querySingleAppStartupsName, +} from '../../database/SqlLite.js'; +import { FlagsConfig } from '../SpFlags.js'; +import { AllAppStartupStruct, AllAppStartupRender } from '../../database/ui-worker/ProcedureWorkerAllAppStartup.js'; + +export class SpAllAppStartupsChart { + private readonly trace: SpSystemTrace | undefined; + static APP_STARTUP_PID_ARR: Array = []; + static jsonRow: TraceRow | undefined; + static trace: SpSystemTrace; + static AllAppStartupsNameArr: any[] = []; + static allAppStartupsAva: number[] = []; + + constructor(trace: SpSystemTrace) { + SpAllAppStartupsChart.trace = trace; + } + + + + + + async init() { + SpAllAppStartupsChart.APP_STARTUP_PID_ARR = []; + let appStartUpPids = await queryAppStartupProcessIds(); + appStartUpPids.forEach((it) => SpAllAppStartupsChart.APP_STARTUP_PID_ARR.push(it.pid)); + SpAllAppStartupsChart.AllAppStartupsNameArr = []; + SpAllAppStartupsChart.allAppStartupsAva = []; + for (let i = 0; i < SpAllAppStartupsChart.APP_STARTUP_PID_ARR.length; i++) { + let tmpSingleApp: any[] = await queryProcessStartup(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); + if (tmpSingleApp.length == 8) { + let avilSingleName = await querySingleAppStartupsName(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]!); + SpAllAppStartupsChart.allAppStartupsAva.push(SpAllAppStartupsChart.APP_STARTUP_PID_ARR[i]); + SpAllAppStartupsChart.AllAppStartupsNameArr.push(avilSingleName![0].name); + } + } + let loadAppStartup: boolean = FlagsConfig.getFlagsConfigEnableStatus('AppStartup'); + if (loadAppStartup && SpAllAppStartupsChart.allAppStartupsAva.length) await this.initFolder(); + } + + async initFolder() { + let row: TraceRow = TraceRow.skeleton(); + row.setAttribute('hasStartup', 'true'); + row.rowId = `all-app-start-${SpAllAppStartupsChart.APP_STARTUP_PID_ARR![0]}`; + row.index = 0; + row.rowType = TraceRow.ROW_TYPE_ALL_APPSTARTUPS; + row.rowParentId = ''; + row.folder = false; + row.style.height = '40px'; + row.name = `All App Startups`; + row.selectChangeHandler = SpAllAppStartupsChart.trace.selectChangeHandler; + row.favoriteChangeHandler = SpAllAppStartupsChart.trace.favoriteChangeHandler; + row.supplier = async (): Promise> => { + let sendRes: AllAppStartupStruct[] | PromiseLike = []; + for (let i = 0; i < SpAllAppStartupsChart.allAppStartupsAva.length; i++) { + let tmpResArr = await queryProcessStartup(SpAllAppStartupsChart.allAppStartupsAva[i]); + let maxStartTs: number | undefined = tmpResArr[0].startTs; + let minStartTs: number | undefined = tmpResArr[0].startTs; + let singleDur = tmpResArr[0].dur; + let endTs: number | undefined = tmpResArr[0].startTs; + if (tmpResArr.length > 1) { + for (let j = 0; j < tmpResArr.length; j++) { + if (Number(tmpResArr[j].startTs) > Number(maxStartTs)) { + maxStartTs = tmpResArr[j].startTs; + } else if (Number(tmpResArr[j].startTs) < Number(minStartTs)) { + minStartTs = tmpResArr[j].startTs; + } + } + tmpResArr.forEach((item) => { + if (item.startTs == maxStartTs) { + endTs = Number(item.startTs) + Number(item.dur); + singleDur = Number(endTs) - Number(minStartTs); + } + }) + } else if (tmpResArr.length === 1) { + minStartTs = tmpResArr[0].startTs; + singleDur = tmpResArr[0].dur; + } + sendRes.push( + { + dur: singleDur, + value: undefined, + startTs: minStartTs, + pid: SpAllAppStartupsChart.allAppStartupsAva[i], + process: undefined, + itid: undefined, + endItid: undefined, + tid: SpAllAppStartupsChart.allAppStartupsAva[i], + startName: undefined, + stepName: SpAllAppStartupsChart.AllAppStartupsNameArr[i], + translateY: undefined, + frame: undefined, + isHover: false + } + ) + } + return sendRes + } + + row.onThreadHandler = (useCache): void => { + let context: CanvasRenderingContext2D; + if (row.currentContext) { + context = row.currentContext; + } else { + context = row.collect ? SpAllAppStartupsChart.trace.canvasFavoritePanelCtx! : SpAllAppStartupsChart.trace.canvasPanelCtx!; + } + row.canvasSave(context); + (renders['all-app-start-up'] as AllAppStartupRender).renderMainThread( + { + appStartupContext: context, + useCache: useCache, + type: `app-startup ${row.rowId}`, + }, + row + ); + row.canvasRestore(context); + }; + SpAllAppStartupsChart.trace.rowsEL?.appendChild(row); + } +} diff --git a/ide/src/trace/component/chart/SpChartManager.ts b/ide/src/trace/component/chart/SpChartManager.ts index a8fa7c6f7162178c4390456f097393c2fbe1205d..04bb5137ad688c4513c13c00ccdf9d3ad8b4740f 100644 --- a/ide/src/trace/component/chart/SpChartManager.ts +++ b/ide/src/trace/component/chart/SpChartManager.ts @@ -49,6 +49,7 @@ import { MemoryConfig } from '../../bean/MemoryConfig.js'; import { FlagsConfig } from '../SpFlags.js'; import { SpLogChart } from './SpLogChart.js'; import { SpHiSysEventChart } from './SpHiSysEventChart.js'; +import { SpAllAppStartupsChart } from './SpAllAppStartups.js'; import {setVSyncData} from './VSync.js'; export class SpChartManager { @@ -69,6 +70,7 @@ export class SpChartManager { private smapsChart: VmTrackerChart; private clockChart: SpClockChart; private irqChart: SpIrqChart; + private SpAllAppStartupsChart!: SpAllAppStartupsChart; frameTimeChart: SpFrameTimeChart; public arkTsChart: SpArkTsChart; private logChart: SpLogChart; @@ -94,6 +96,7 @@ export class SpChartManager { this.arkTsChart = new SpArkTsChart(trace); this.logChart = new SpLogChart(trace); this.spHiSysEvent = new SpHiSysEventChart(trace); + this.SpAllAppStartupsChart = new SpAllAppStartupsChart(trace) } async init(progress: Function) { @@ -164,6 +167,7 @@ export class SpChartManager { progress('ark ts', 90); await this.arkTsChart.initFolder(); info('ark ts initialized'); + await this.SpAllAppStartupsChart.init(); await this.frameTimeChart.init(); progress('process', 92); await this.process.initAsyncFuncData(); diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index df8041dc4dcdea53f2e559dfc13c4f1379e4729c..39db22c5c292c9ddbc49278b5836732946cd247c 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -117,6 +117,7 @@ export class TraceRow extends HTMLElement { static ROW_TYPE_PURGEABLE_TOTAL_VM = 'purgeable-total-vm'; static ROW_TYPE_PURGEABLE_PIN_VM = 'purgeable-pin-vm'; static ROW_TYPE_LOGS = 'logs'; + static ROW_TYPE_ALL_APPSTARTUPS = 'all-appstartups' static FRAME_WIDTH: number = 0; static range: TimeRange | undefined | null; static rangeSelectObject: RangeSelectStruct | undefined; diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index 4ccf1157be4fbde68d10ab32f189df11f8f215b9..429072e1cb15b13bfb3da517df1081010084852c 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -42,6 +42,7 @@ import { type TabPaneNMStatisticAnalysis } from '../sheet/native-memory/TabPaneN import { type TabPaneCurrent } from '../sheet/TabPaneCurrent.js'; import { type SlicesTime } from '../timer-shaft/SportRuler.js'; import { type AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAppStartup.js'; +import { type AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup.js'; import { type SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js'; import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; import { type TraceRow } from './TraceRow.js'; @@ -498,6 +499,8 @@ export class TraceSheet extends BaseElement { this.displayTab('current-selection').setIrqData(data); displayStartupData = (data: AppStartupStruct, scrollCallback: Function): void => this.displayTab('current-selection').setStartupData(data, scrollCallback); + displayAllStartupData = (data: AllAppStartupStruct, scrollCallback: Function): void => + this.displayTab('current-selection').setAllStartupData(data, scrollCallback); displayStaticInitData = (data: SoStruct, scrollCallback: Function): void => this.displayTab('current-selection').setStaticInitData(data, scrollCallback); diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts index f57ea33eaf91b20bf5ef7c051642517d1c3e8528..c0a612866f45661284fd5bff794c5bed09651ac3 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts @@ -49,6 +49,7 @@ import { AppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerApp import { SoStruct } from '../../../database/ui-worker/ProcedureWorkerSoInit.js'; import { type SelectionParam } from '../../../bean/BoxSelection.js'; import { type FrameAnimationStruct } from '../../../database/ui-worker/ProcedureWorkerFrameAnimation.js'; +import { AllAppStartupStruct } from '../../../database/ui-worker/ProcedureWorkerAllAppStartup.js'; const INPUT_WORD = 'This is the interval from when the task became eligible to run \n(e.g.because of notifying a wait queue it was a suspended on) to\n when it started running.'; @@ -815,6 +816,41 @@ export class TabPaneCurrentSelection extends BaseElement { this.currentSelectionTbl!.dataSource = list; } } + setAllStartupData(data: AllAppStartupStruct,scrollCallback: Function): void{ + this.setTableHeight('550px'); + this.initCanvas(); + let allStartUpLeftTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#leftTitle'); + let allStartUpmiddleTitle: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightText'); + let allStartUpRightButton:HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#rightButton'); + if(allStartUpmiddleTitle) allStartUpmiddleTitle.style.visibility = 'hidden'; + if(allStartUpRightButton) allStartUpRightButton.style.visibility = 'hidden'; + if (allStartUpLeftTitle) { + allStartUpLeftTitle.innerText = 'Details'; + } + let list: any[] = []; + list.push({name: "Name", value: data.stepName!}) + list.push({ + name: "StartTime(Relative)", + value: getTimeString(data.startTs || 0) + }); + list.push({ + name: "StartTime(Absolute)", + value:((data.startTs || 0) + (window as any).recordStartNS) / 1000000000 + 's' + }); + list.push({ + name: "EndTime(Relative)", + value: getTimeString((data.startTs || 0) + (data.dur || 0)) + }); + list.push({ + name: "EndTime(Abslute)", + value: ((data.startTs || 0) + (data.dur || 0) + (window as any).recordStartNS) / 1000000000 + 's' + }) + list.push({ + name:"Dur", + value: getTimeString(data.dur || 0) + }) + this.currentSelectionTbl!.dataSource = list; + } setStartupData(data: AppStartupStruct, scrollCallback: Function): void { this.setTableHeight('550px'); diff --git a/ide/src/trace/database/SqlLite.ts b/ide/src/trace/database/SqlLite.ts index 354e6384a08b1d5831979e65fa891535a10848b0..772df4a2200f1e96fe702efec4071ed619209d4b 100644 --- a/ide/src/trace/database/SqlLite.ts +++ b/ide/src/trace/database/SqlLite.ts @@ -1428,6 +1428,35 @@ order by start_name;`, { $pid: pid } ); + export const queryProcessAllAppStartup = (pids: Array): Promise> => + query( + 'queryProcessStartup', + ` + select + P.pid, + A.tid, + A.call_id as itid, + (case when A.start_time < B.start_ts then 0 else (A.start_time - B.start_ts) end) as startTs, + (case + when A.start_time < B.start_ts then (A.end_time - B.start_ts) + when A.end_time = -1 then 0 + else (A.end_time - A.start_time) end) as dur, + A.start_name as startName +from app_startup A,trace_range B +left join process P on A.ipid = P.ipid +where P.pid in(${pids.join(',')}) +order by start_name;`, + { $pid: pids } + ); + + export const querySingleAppStartupsName = (pid:number): Promise> => + query( + 'queryAllAppStartupsName', + `select name from process + where pid=$pid`, + { $pid: pid } + ) + export const queryProcessSoMaxDepth = (): Promise> => query( 'queryProcessSoMaxDepth', diff --git a/ide/src/trace/database/ui-worker/ProcedureWorker.ts b/ide/src/trace/database/ui-worker/ProcedureWorker.ts index 0fd1daf60c0067887b73ad142550d9eab4f31e7b..1766c0d908f81717497b5cee8046efd5fc3cc782 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorker.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorker.ts @@ -58,6 +58,7 @@ import { SnapshotRender } from './ProcedureWorkerSnapshot.js'; import { LogRender } from './ProcedureWorkerLog.js'; import { HiPerfCallChartRender } from './ProcedureWorkerHiPerfCallChart.js'; import { HiSysEventRender } from './ProcedureWorkerHiSysEvent.js'; +import { AllAppStartupRender } from './ProcedureWorkerAllAppStartup.js'; let dataList: any = {}; let dataList2: any = {}; @@ -77,6 +78,7 @@ export let renders: any = { 'file-system-cell': new FileSystemRender(), process: new ProcessRender(), 'app-start-up': new AppStartupRender(), + 'all-app-start-up': new AllAppStartupRender(), 'app-so-init': new SoRender(), heap: new HeapRender(), 'heap-timeline': new HeapTimelineRender(), diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts new file mode 100644 index 0000000000000000000000000000000000000000..ede7a83695bda6e53ab64a5e799976ea3441e74c --- /dev/null +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerAllAppStartup.ts @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * 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. + */ + +import { BaseStruct, dataFilterHandler, drawString } from './ProcedureWorkerCommon.js'; +import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { querySingleAppStartupsName } from '../SqlLite.js'; + +export class AllAppStartupRender { + renderMainThread( + req: { + appStartupContext: CanvasRenderingContext2D; + useCache: boolean; + type: string; + }, + appStartUpRow: TraceRow + ): void { + let list = appStartUpRow.dataList; + let filter = appStartUpRow.dataListCache; + dataFilterHandler(list, filter, { + startKey: 'startTs', + durKey: 'dur', + startNS: TraceRow.range?.startNS ?? 0, + endNS: TraceRow.range?.endNS ?? 0, + totalNS: TraceRow.range?.totalNS ?? 0, + frame: appStartUpRow.frame, + paddingTop: 5, + useCache: req.useCache || !(TraceRow.range?.refresh ?? false), + }); + req.appStartupContext.globalAlpha = 0.6; + let find = false; + let offset = 3; + for (let re of filter) { + AllAppStartupStruct.draw(req.appStartupContext, re); + if (appStartUpRow.isHover) { + if ( + re.frame && + appStartUpRow.hoverX >= re.frame.x - offset && + appStartUpRow.hoverX <= re.frame.x + re.frame.width + offset + ) { + AllAppStartupStruct.hoverStartupStruct = re; + find = true; + } + } + } + if (!find && appStartUpRow.isHover) { + AllAppStartupStruct.hoverStartupStruct = undefined; + } + } +} + +const padding = 3; + +export class AllAppStartupStruct extends BaseStruct { + static hoverStartupStruct: AllAppStartupStruct | undefined; + static selectStartupStruct: AllAppStartupStruct | undefined; + dur: number | undefined; + value: string | undefined; + startTs: number | undefined; + pid: number | undefined; + process: string | undefined; + itid: number | undefined; + endItid: number | undefined; + tid: number | undefined; + startName: number | undefined; + stepName: string | undefined; + + static draw(ctx: CanvasRenderingContext2D, data: AllAppStartupStruct): void { + if (data.frame) { + ctx.globalAlpha = 1.0; + ctx.fillStyle = ColorUtils.colorForTid(data.startName!); + ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); + if (data.frame.width > 7) { + ctx.textBaseline = 'middle'; + ctx.lineWidth = 1; + let draAppName: string | undefined = ''; + if(data.stepName){ + draAppName = `${data.stepName} (${(data.dur! / 1000000).toFixed(2)}ms)`; + } + let textColor = + ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.stepName || '', 0, ColorUtils.FUNC_COLOR.length)]; + ctx.fillStyle = ColorUtils.funcTextColor(textColor); + drawString(ctx, draAppName, 2, data.frame, data); + } + if (data === AllAppStartupStruct.selectStartupStruct) { + ctx.strokeStyle = '#232c5d'; + ctx.lineWidth = 2; + ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); + } + } + } + + static async getStartupName(pid: number): Promise { + let singleAppName = await querySingleAppStartupsName(pid); + return singleAppName[0].name; + } +}