trace collection UI
Created new UI components for trace collection. Since the proxy is not yet migrated, click through the buttons to automatically cycle through the components. Bug: b/238981126 Test: npm run start Click Web ADB tab to see basic component. Click ADB proxy tab to see proxy component. Click Retry to get to authorisation options. Click Connect to get to trace configuration component. Change-Id: I1e7a9895ece06856c095d8c85c28d22bbfa94b31
This commit is contained in:
69
tools/winscope-ng/package-lock.json
generated
69
tools/winscope-ng/package-lock.json
generated
@@ -14,6 +14,7 @@
|
||||
"@angular/core": "^14.0.1",
|
||||
"@angular/elements": "^14.0.1",
|
||||
"@angular/forms": "^14.0.0",
|
||||
"@angular/material": "^14.0.4",
|
||||
"@angular/platform-browser": "^14.0.0",
|
||||
"@angular/platform-browser-dynamic": "^14.0.0",
|
||||
"@angular/router": "^14.0.0",
|
||||
@@ -460,6 +461,30 @@
|
||||
"@angular/core": "14.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/cdk": {
|
||||
"version": "14.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-14.0.4.tgz",
|
||||
"integrity": "sha512-zPM4VZadoKzTF9TZ7Yx5gJ7GtQpt62f8ofdH/BF2atG+TaNzOEFqtzogP4WuJDFAxJXOPMePobhth4YjUk0Wbw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"parse5": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^14.0.0 || ^15.0.0",
|
||||
"@angular/core": "^14.0.0 || ^15.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/cdk/node_modules/parse5": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
|
||||
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@angular/cli": {
|
||||
"version": "14.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.0.6.tgz",
|
||||
@@ -607,6 +632,23 @@
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/material": {
|
||||
"version": "14.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular/material/-/material-14.0.4.tgz",
|
||||
"integrity": "sha512-Ysz6oPbpLH7CvRR6oxQwpUImSbFqxL4+eiH0LPc7vkaOSrvGdZ/7cWhAfT6hVnw3bEY+eq5qBSMgyVUB44z4eg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/animations": "^14.0.0 || ^15.0.0",
|
||||
"@angular/cdk": "14.0.4",
|
||||
"@angular/common": "^14.0.0 || ^15.0.0",
|
||||
"@angular/core": "^14.0.0 || ^15.0.0",
|
||||
"@angular/forms": "^14.0.0 || ^15.0.0",
|
||||
"@angular/platform-browser": "^14.0.0 || ^15.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/platform-browser": {
|
||||
"version": "14.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.0.6.tgz",
|
||||
@@ -15269,6 +15311,25 @@
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@angular/cdk": {
|
||||
"version": "14.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-14.0.4.tgz",
|
||||
"integrity": "sha512-zPM4VZadoKzTF9TZ7Yx5gJ7GtQpt62f8ofdH/BF2atG+TaNzOEFqtzogP4WuJDFAxJXOPMePobhth4YjUk0Wbw==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"parse5": "^5.0.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"parse5": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
|
||||
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@angular/cli": {
|
||||
"version": "14.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.0.6.tgz",
|
||||
@@ -15355,6 +15416,14 @@
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@angular/material": {
|
||||
"version": "14.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular/material/-/material-14.0.4.tgz",
|
||||
"integrity": "sha512-Ysz6oPbpLH7CvRR6oxQwpUImSbFqxL4+eiH0LPc7vkaOSrvGdZ/7cWhAfT6hVnw3bEY+eq5qBSMgyVUB44z4eg==",
|
||||
"requires": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"@angular/platform-browser": {
|
||||
"version": "14.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-14.0.6.tgz",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"@angular/core": "^14.0.1",
|
||||
"@angular/elements": "^14.0.1",
|
||||
"@angular/forms": "^14.0.0",
|
||||
"@angular/material": "^14.0.4",
|
||||
"@angular/platform-browser": "^14.0.0",
|
||||
"@angular/platform-browser-dynamic": "^14.0.0",
|
||||
"@angular/router": "^14.0.0",
|
||||
|
||||
@@ -24,21 +24,33 @@ import {Core} from "./core";
|
||||
<div id="title">
|
||||
<span>Winscope Viewer 2.0</span>
|
||||
</div>
|
||||
<div class="card-container" fxLayout="row wrap" fxLayoutGap="10px grid">
|
||||
<mat-card class="homepage-card">
|
||||
<collect-traces></collect-traces>
|
||||
</mat-card>
|
||||
<mat-card class="homepage-card">
|
||||
<mat-card-title>Upload Traces</mat-card-title>
|
||||
<div id="inputfile">
|
||||
<input mat-input type="file" (change)="onInputFile($event)" #fileUpload>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<div id="inputfile">
|
||||
<input type="file" (change)="onInputFile($event)" #fileUpload>
|
||||
</div>
|
||||
|
||||
<div id="timescrub">
|
||||
<button (click)="notifyCurrentTimestamp()">Update current timestamp</button>
|
||||
</div>
|
||||
|
||||
<div id="viewers">
|
||||
<button mat-raised-button (click)="notifyCurrentTimestamp()">Update current timestamp</button>
|
||||
</div>
|
||||
|
||||
<div id="timestamps">
|
||||
</div>
|
||||
`
|
||||
|
||||
<div id="viewers">
|
||||
</div>
|
||||
`,
|
||||
styles: [".card-container{width: 100%; display:flex; flex-direction: row; overflow: auto;}"]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = "winscope-ng";
|
||||
|
||||
@@ -1,16 +1,50 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { BrowserModule } from "@angular/platform-browser";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatCardModule } from "@angular/material/card";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
import { MatGridListModule } from "@angular/material/grid-list";
|
||||
import { MatListModule } from "@angular/material/list";
|
||||
import {MatProgressSpinnerModule} from "@angular/material/progress-spinner";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatSelectModule } from "@angular/material/select";
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
|
||||
import { AppComponent } from "./app.component";
|
||||
import { ViewerWindowManagerComponent} from "viewers/viewer_window_manager/viewer_window_manager.component";
|
||||
import { ViewerWindowManagerComponent } from "viewers/viewer_window_manager/viewer_window_manager.component";
|
||||
import { CollectTracesComponent } from "trace_collection/collect_traces.component";
|
||||
import { AdbProxyComponent } from "trace_collection/adb_proxy.component";
|
||||
import { WebAdbComponent } from "trace_collection/web_adb.component";
|
||||
import { TraceConfigComponent } from "trace_collection/trace_config.component";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
ViewerWindowManagerComponent
|
||||
ViewerWindowManagerComponent,
|
||||
CollectTracesComponent,
|
||||
AdbProxyComponent,
|
||||
WebAdbComponent,
|
||||
TraceConfigComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
BrowserModule,
|
||||
CommonModule,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
MatGridListModule,
|
||||
FormsModule,
|
||||
MatListModule,
|
||||
MatCheckboxModule,
|
||||
MatIconModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
BrowserAnimationsModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
||||
@@ -13,6 +13,49 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
|
||||
#title {
|
||||
color: aqua;
|
||||
font-weight: bold;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color:rgb(194, 65, 108);
|
||||
font-size: 20;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.homepage-card {
|
||||
border: 1px solid rgb(129, 129, 129);
|
||||
width: 45rem;
|
||||
height: 30rem;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
margin: 10px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.card-block {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
button.mat-raised-button {
|
||||
background-color:rgb(194, 65, 108);
|
||||
color: white;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.tab.inactive {
|
||||
background-color:white;
|
||||
color: black;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import {ComponentFixture, TestBed} from "@angular/core/testing";
|
||||
import {AdbProxyComponent} from "./adb_proxy.component";
|
||||
|
||||
describe("AdbProxyComponent", () => {
|
||||
let fixture: ComponentFixture<AdbProxyComponent>;
|
||||
let component: AdbProxyComponent;
|
||||
let htmlElement: HTMLElement;
|
||||
|
||||
beforeAll(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [AdbProxyComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AdbProxyComponent);
|
||||
component = fixture.componentInstance;
|
||||
htmlElement = fixture.nativeElement;
|
||||
});
|
||||
|
||||
it("can be created", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import { Component, Input, Output, EventEmitter } from "@angular/core";
|
||||
import { ProxyState } from "./proxy_client";
|
||||
|
||||
@Component({
|
||||
selector: "adb-proxy",
|
||||
template: `
|
||||
<div *ngIf="status===states.NO_PROXY">
|
||||
<div class="title">Unable to connect to Winscope ADB proxy</div>
|
||||
<div class="md-body-2" layout="layout-md">
|
||||
<p>Launch the Winscope ADB Connect proxy to capture traces directly from your browser.</p>
|
||||
<p>Python 3.5+ and ADB are required.</p>
|
||||
<p>Run:</p>
|
||||
<pre>python3</pre>
|
||||
<pre>$ANDROID_BUILD_TOP/development/tools/winscope/adb_proxy/winscope_proxy.py</pre>
|
||||
<p>Or get it from the AOSP repository.</p>
|
||||
</div>
|
||||
<div class="md-layout">
|
||||
<button mat-raised-button class="md-accent">
|
||||
<a href="{{downloadProxyUrl}}" target='_blank'>Download from AOSP</a>
|
||||
</button>
|
||||
<button mat-raised-button class="md-accent" (click)="triggerUnauthComponent()">Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="status===states.INVALID_VERSION">
|
||||
<div class="title">Your local version of the ADB Connect proxy is incompatible with Winscope.</div>
|
||||
<div class="md-body-2" layout="layout-md">
|
||||
<p>Please update the proxy to version {{ proxyVersion }}.</p>
|
||||
<p>Run:</p>
|
||||
<pre>python3</pre>
|
||||
<pre>$ANDROID_BUILD_TOP/development/tools/winscope/adb_proxy/winscope_proxy.py</pre>
|
||||
<p>Or get it from the AOSP repository.</p>
|
||||
</div>
|
||||
<div class="md-layout">
|
||||
<button mat-raised-button class="md-accent">
|
||||
<a href="{{downloadProxyUrl}}" target='_blank'>Download from AOSP</a>
|
||||
</button>
|
||||
<button mat-raised-button class="md-accent" (click)="restart()">Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="status===states.UNAUTH">
|
||||
<div class="title">Proxy authorisation required</div>
|
||||
<div class="md-body-2" layout="layout-md">
|
||||
<p>Enter Winscope proxy token:</p>
|
||||
<mat-form-field class="proxy-key-field">
|
||||
<input matInput [(ngModel)]="proxyKey" name="proxy-key" (keyup.enter)="onEnter()"/>
|
||||
</mat-form-field>
|
||||
<p>The proxy token is printed to console on proxy launch, copy and paste it above.</p>
|
||||
</div>
|
||||
<div class="md-layout">
|
||||
<button mat-raised-button class="md-accent" (click)="restart()">Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [".proxy-key-field {width: 30rem}"]
|
||||
})
|
||||
export class AdbProxyComponent {
|
||||
readonly proxyVersion = "0.8";
|
||||
states = ProxyState;
|
||||
|
||||
@Input()
|
||||
status = this.states.NO_PROXY;
|
||||
|
||||
@Output()
|
||||
statusChange = new EventEmitter<ProxyState>();
|
||||
|
||||
proxyKey = "";
|
||||
readonly downloadProxyUrl: string = "https://android.googlesource.com/platform/development/+/master/tools/winscope/adb_proxy/winscope_proxy.py";
|
||||
|
||||
public onEnter() {
|
||||
console.log("this is the key,", this.proxyKey);
|
||||
}
|
||||
|
||||
public restart() {
|
||||
this.status = ProxyState.START_TRACE;
|
||||
this.statusChange.emit(this.status);
|
||||
}
|
||||
|
||||
public triggerUnauthComponent() {
|
||||
this.status = ProxyState.UNAUTH;
|
||||
this.statusChange.emit(this.status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import {ComponentFixture, TestBed} from "@angular/core/testing";
|
||||
import {CollectTracesComponent} from "./collect_traces.component";
|
||||
|
||||
describe("CollectTracesComponent", () => {
|
||||
let fixture: ComponentFixture<CollectTracesComponent>;
|
||||
let component: CollectTracesComponent;
|
||||
let htmlElement: HTMLElement;
|
||||
|
||||
beforeAll(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [CollectTracesComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CollectTracesComponent);
|
||||
component = fixture.componentInstance;
|
||||
htmlElement = fixture.nativeElement;
|
||||
});
|
||||
|
||||
it("can be created", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import {Component} from "@angular/core";
|
||||
import { ProxyState } from "./proxy_client";
|
||||
|
||||
interface TraceConfiguration {
|
||||
name: string,
|
||||
defaultCheck?: boolean,
|
||||
config?: ConfigurationOptions
|
||||
}
|
||||
|
||||
export interface ConfigurationOptions {
|
||||
enableConfigs: Array<string>,
|
||||
selectionConfigs: Array<SelectionConfiguration>
|
||||
}
|
||||
|
||||
export interface SelectionConfiguration {
|
||||
name: string,
|
||||
options: Array<string>,
|
||||
value: string
|
||||
}
|
||||
|
||||
export type configMap = {
|
||||
[key: string]: Array<string> | string;
|
||||
}
|
||||
|
||||
interface Device {
|
||||
authorised: boolean;
|
||||
id: string;
|
||||
}
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "collect-traces",
|
||||
template: `
|
||||
<mat-card-title>Collect Traces</mat-card-title>
|
||||
<mat-card-content>
|
||||
<div id="set-up-adb" *ngIf="!proxySuccess()">
|
||||
<button mat-raised-button [ngClass]="tabClass(true)" (click)="displayAdbProxyTab()">ADB Proxy</button>
|
||||
<button mat-raised-button [ngClass]="tabClass(false)" (click)="displayWebAdbTab()">Web ADB</button>
|
||||
<adb-proxy *ngIf="isAdbProxy" [(status)]="status"></adb-proxy>
|
||||
<web-adb *ngIf="!isAdbProxy"></web-adb>
|
||||
</div>
|
||||
|
||||
<div id="trace-collection-config" *ngIf="proxySuccess()">
|
||||
<div class="device-list">
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let device of devices()" (click)="selectDevice(device.id)">
|
||||
<mat-icon>{{ device.authorised ? "smartphone" : "screen_lock_portrait" }}</mat-icon>
|
||||
<span class="md-list-item-text">selected device name</span>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
|
||||
<div class="trace-section">
|
||||
<div class="md-layout">
|
||||
<button mat-raised-button class="md-accent" (click)="startTracing()">Start Trace</button>
|
||||
<button mat-raised-button (click)="dumpState()">Dump State</button>
|
||||
<button mat-raised-button class="md-primary" (click)="resetLastDevice()">Change Device</button>
|
||||
</div>
|
||||
<h3>Trace targets:</h3>
|
||||
<trace-config
|
||||
*ngFor="let trace of traceConfigurations"
|
||||
[name]="trace.name"
|
||||
[defaultCheck]="trace.defaultCheck"
|
||||
[configs]="trace.config ? trace.config : null"
|
||||
[(status)]="status"
|
||||
></trace-config>
|
||||
</div>
|
||||
|
||||
<div class="dump-section">
|
||||
<h3>Dump targets:</h3>
|
||||
<div class="selection">
|
||||
<mat-checkbox class="md-primary" *ngFor="let dumpKey of objectKeys(DUMPS)" >{{DUMPS[dumpKey]}}</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
`,
|
||||
})
|
||||
export class CollectTracesComponent {
|
||||
objectKeys = Object.keys;
|
||||
isAdbProxy = true;
|
||||
startTrace = false;
|
||||
startDump = false;
|
||||
downloadProxyUrl = "https://android.googlesource.com/platform/development/+/master/tools/winscope/adb_proxy/winscope_proxy.py";
|
||||
|
||||
DUMPS: configMap = {
|
||||
"window_dump": "Window Manager",
|
||||
"layers_dump": "Surface Flinger"
|
||||
};
|
||||
|
||||
wmTraceSelectionConfigs = [
|
||||
{
|
||||
name: "wmbuffersize (KB)",
|
||||
options: [
|
||||
"4000",
|
||||
"8000",
|
||||
"16000",
|
||||
"32000",
|
||||
],
|
||||
value: "4000"
|
||||
},
|
||||
{
|
||||
name: "tracingtype",
|
||||
options: [
|
||||
"frame",
|
||||
"transaction",
|
||||
],
|
||||
value: "frame"
|
||||
},
|
||||
{
|
||||
name: "tracinglevel",
|
||||
options: [
|
||||
"verbose",
|
||||
"debug",
|
||||
"critical",
|
||||
],
|
||||
value: "verbose"
|
||||
},
|
||||
];
|
||||
|
||||
traceConfigurations: Array<TraceConfiguration> = [
|
||||
{
|
||||
name: "Surface Flinger",
|
||||
defaultCheck: true,
|
||||
config: {
|
||||
enableConfigs: ["composition","metadata","hwc","tracebuffers"],
|
||||
selectionConfigs: [
|
||||
{
|
||||
name: "sfbuffersize (KB)",
|
||||
options: ["4000","8000","16000","32000",],
|
||||
value: "4000"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Window Manager",
|
||||
defaultCheck: true,
|
||||
config: {
|
||||
enableConfigs: [],
|
||||
selectionConfigs: this.wmTraceSelectionConfigs,
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Screen Recording",
|
||||
},
|
||||
{
|
||||
name: "Accessibility",
|
||||
},
|
||||
{
|
||||
name: "Transaction",
|
||||
},
|
||||
{
|
||||
name: "Input Method Clients",
|
||||
defaultCheck: true,
|
||||
},
|
||||
{
|
||||
name: "Input Method Service",
|
||||
defaultCheck: true,
|
||||
},
|
||||
{
|
||||
name: "Input Method Manager Service",
|
||||
defaultCheck: true,
|
||||
},
|
||||
];
|
||||
|
||||
states = ProxyState;
|
||||
status = this.states.NO_PROXY;
|
||||
|
||||
public devices(): Array<Device> {
|
||||
return [
|
||||
{authorised: true, id: "1"},
|
||||
];
|
||||
}
|
||||
|
||||
public restart() {
|
||||
this.status === this.states.START_TRACE;
|
||||
}
|
||||
|
||||
public proxySuccess() {
|
||||
return this.status === this.states.START_TRACE;
|
||||
}
|
||||
|
||||
public resetLastDevice() {
|
||||
this.restart();
|
||||
}
|
||||
|
||||
public selectDevice(id: string) {
|
||||
console.log("selected", id);
|
||||
}
|
||||
|
||||
public displayAdbProxyTab() {
|
||||
this.isAdbProxy = true;
|
||||
console.log("Adb Proxy options?", this.isAdbProxy);
|
||||
}
|
||||
|
||||
public displayWebAdbTab() {
|
||||
this.isAdbProxy = false;
|
||||
console.log("Web ADB options?", !this.isAdbProxy);
|
||||
}
|
||||
|
||||
public startTracing() {
|
||||
this.startTrace = true;
|
||||
console.log("begin tracing");
|
||||
}
|
||||
|
||||
public dumpState() {
|
||||
this.startDump = true;
|
||||
console.log("begin dump");
|
||||
}
|
||||
|
||||
public tabClass(adbTab: boolean) {
|
||||
let isActive: string;
|
||||
if (adbTab) {
|
||||
isActive = this.isAdbProxy ? "active" : "inactive";
|
||||
} else {
|
||||
isActive = !this.isAdbProxy ? "active" : "inactive";
|
||||
}
|
||||
return ["tab", isActive];
|
||||
}
|
||||
}
|
||||
26
tools/winscope-ng/src/trace_collection/proxy_client.ts
Normal file
26
tools/winscope-ng/src/trace_collection/proxy_client.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
export enum ProxyState {
|
||||
ERROR = 0,
|
||||
CONNECTING = 1,
|
||||
NO_PROXY = 2,
|
||||
INVALID_VERSION = 3,
|
||||
UNAUTH = 4,
|
||||
DEVICES = 5,
|
||||
START_TRACE = 6,
|
||||
END_TRACE = 7,
|
||||
LOAD_DATA = 8,
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import {ComponentFixture, TestBed} from "@angular/core/testing";
|
||||
import {TraceConfigComponent} from "./trace_config.component";
|
||||
|
||||
describe("TraceConfigComponent", () => {
|
||||
let fixture: ComponentFixture<TraceConfigComponent>;
|
||||
let component: TraceConfigComponent;
|
||||
let htmlElement: HTMLElement;
|
||||
|
||||
beforeAll(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [TraceConfigComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TraceConfigComponent);
|
||||
component = fixture.componentInstance;
|
||||
htmlElement = fixture.nativeElement;
|
||||
});
|
||||
|
||||
it("can be created", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import { Component, Input, Output, EventEmitter } from "@angular/core";
|
||||
import { ProxyState } from "./proxy_client";
|
||||
import { ConfigurationOptions, SelectionConfiguration } from "./collect_traces.component";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "trace-config",
|
||||
template: `
|
||||
<div class="card-block" *ngIf="status===states.START_TRACE">
|
||||
<mat-checkbox class="md-primary" [checked]="defaultCheck">{{name}}</mat-checkbox>
|
||||
<div class="adv-config" *ngIf="configs">
|
||||
<mat-checkbox class="md-primary" *ngFor="let enableConfig of traceEnableConfigs()">{{enableConfig}}</mat-checkbox>
|
||||
<div class="selection">
|
||||
<mat-form-field appearance="fill" class="config-selection" *ngFor="let con of traceSelectionConfigs()">
|
||||
<mat-label>{{con.name}}</mat-label>
|
||||
<mat-select>
|
||||
<mat-option
|
||||
*ngFor="let option of con.options"
|
||||
[value]="con.value"
|
||||
>{{ option }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [".adv-config {margin-left: 5rem;}"],
|
||||
})
|
||||
|
||||
export class TraceConfigComponent {
|
||||
states = ProxyState;
|
||||
objectKeys = Object.keys;
|
||||
|
||||
@Input()
|
||||
name = "";
|
||||
|
||||
@Input()
|
||||
configs: ConfigurationOptions | null = null;
|
||||
|
||||
@Input()
|
||||
defaultCheck: boolean | undefined = false;
|
||||
|
||||
@Input()
|
||||
status = this.states.UNAUTH;
|
||||
|
||||
@Output()
|
||||
statusChange = new EventEmitter<ProxyState>();
|
||||
|
||||
public traceEnableConfigs(): Array<string> {
|
||||
if (this.configs && this.configs.enableConfigs) {
|
||||
return this.configs.enableConfigs;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public traceSelectionConfigs(): Array<SelectionConfiguration> {
|
||||
if (this.configs) {
|
||||
return this.configs.selectionConfigs;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public restart() {
|
||||
this.status = this.states.CONNECTING;
|
||||
this.statusChange.emit(this.status);
|
||||
}
|
||||
|
||||
public resetLastDevice() {
|
||||
this.restart();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import {ComponentFixture, TestBed} from "@angular/core/testing";
|
||||
import {WebAdbComponent} from "./web_adb.component";
|
||||
|
||||
describe("WebAdbComponent", () => {
|
||||
let fixture: ComponentFixture<WebAdbComponent>;
|
||||
let component: WebAdbComponent;
|
||||
let htmlElement: HTMLElement;
|
||||
|
||||
beforeAll(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [WebAdbComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(WebAdbComponent);
|
||||
component = fixture.componentInstance;
|
||||
htmlElement = fixture.nativeElement;
|
||||
});
|
||||
|
||||
it("can be created", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders the title", () => {
|
||||
const divTitle = htmlElement.querySelector(".web-adb div.title");
|
||||
expect(divTitle?.innerHTML).toContain("Unable to connect to Web ADB");
|
||||
});
|
||||
|
||||
});
|
||||
35
tools/winscope-ng/src/trace_collection/web_adb.component.ts
Normal file
35
tools/winscope-ng/src/trace_collection/web_adb.component.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
import {Component} from "@angular/core";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "web-adb",
|
||||
template: `
|
||||
<div class="title">Unable to connect to Web ADB</div>
|
||||
<div class="md-body-2">
|
||||
<p>Instructions for connecting via Web ADB.</p>
|
||||
</div>
|
||||
<div class="md-layout">
|
||||
<button mat-raised-button class="md-accent" (click)="restart()">Retry</button>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class WebAdbComponent {
|
||||
public restart() {
|
||||
console.log("Try connecting again");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user