diff --git a/tools/winscope-ng/package-lock.json b/tools/winscope-ng/package-lock.json index 71bad18b8..abf723a2e 100644 --- a/tools/winscope-ng/package-lock.json +++ b/tools/winscope-ng/package-lock.json @@ -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", diff --git a/tools/winscope-ng/package.json b/tools/winscope-ng/package.json index eee118a98..1872e570b 100644 --- a/tools/winscope-ng/package.json +++ b/tools/winscope-ng/package.json @@ -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", diff --git a/tools/winscope-ng/src/app/app.component.ts b/tools/winscope-ng/src/app/app.component.ts index 0e66ed4f2..717009ea1 100644 --- a/tools/winscope-ng/src/app/app.component.ts +++ b/tools/winscope-ng/src/app/app.component.ts @@ -24,21 +24,33 @@ import {Core} from "./core";
Winscope Viewer 2.0
+
+ + + + + Upload Traces +
+ +
+
+
- -
- -
+
- ` + +
+
+ `, + styles: [".card-container{width: 100%; display:flex; flex-direction: row; overflow: auto;}"] }) export class AppComponent { title = "winscope-ng"; diff --git a/tools/winscope-ng/src/app/app.module.ts b/tools/winscope-ng/src/app/app.module.ts index 9f6140299..74952603e 100644 --- a/tools/winscope-ng/src/app/app.module.ts +++ b/tools/winscope-ng/src/app/app.module.ts @@ -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] diff --git a/tools/winscope-ng/src/styles.css b/tools/winscope-ng/src/styles.css index 50e45553c..db918bf1a 100644 --- a/tools/winscope-ng/src/styles.css +++ b/tools/winscope-ng/src/styles.css @@ -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; +} \ No newline at end of file diff --git a/tools/winscope-ng/src/trace_collection/adb_proxy.component.spec.ts b/tools/winscope-ng/src/trace_collection/adb_proxy.component.spec.ts new file mode 100644 index 000000000..20ddb46cb --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/adb_proxy.component.spec.ts @@ -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; + 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(); + }); + + +}); diff --git a/tools/winscope-ng/src/trace_collection/adb_proxy.component.ts b/tools/winscope-ng/src/trace_collection/adb_proxy.component.ts new file mode 100644 index 000000000..35bcc455c --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/adb_proxy.component.ts @@ -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: ` +
+
Unable to connect to Winscope ADB proxy
+
+

Launch the Winscope ADB Connect proxy to capture traces directly from your browser.

+

Python 3.5+ and ADB are required.

+

Run:

+
python3
+
$ANDROID_BUILD_TOP/development/tools/winscope/adb_proxy/winscope_proxy.py
+

Or get it from the AOSP repository.

+
+
+ + +
+
+ +
+
Your local version of the ADB Connect proxy is incompatible with Winscope.
+
+

Please update the proxy to version {{ proxyVersion }}.

+

Run:

+
python3
+
$ANDROID_BUILD_TOP/development/tools/winscope/adb_proxy/winscope_proxy.py
+

Or get it from the AOSP repository.

+
+
+ + +
+
+ +
+
Proxy authorisation required
+
+

Enter Winscope proxy token:

+ + + +

The proxy token is printed to console on proxy launch, copy and paste it above.

+
+
+ +
+
+ `, + 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(); + + 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); + } +} diff --git a/tools/winscope-ng/src/trace_collection/collect_traces.component.spec.ts b/tools/winscope-ng/src/trace_collection/collect_traces.component.spec.ts new file mode 100644 index 000000000..381d01ff3 --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/collect_traces.component.spec.ts @@ -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; + 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(); + }); + +}); diff --git a/tools/winscope-ng/src/trace_collection/collect_traces.component.ts b/tools/winscope-ng/src/trace_collection/collect_traces.component.ts new file mode 100644 index 000000000..78702e8e3 --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/collect_traces.component.ts @@ -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, + selectionConfigs: Array +} + +export interface SelectionConfiguration { + name: string, + options: Array, + value: string +} + +export type configMap = { +[key: string]: Array | string; +} + +interface Device { + authorised: boolean; + id: string; +} + + +@Component({ + selector: "collect-traces", + template: ` + Collect Traces + +
+ + + + +
+ +
+
+ + + {{ device.authorised ? "smartphone" : "screen_lock_portrait" }} + selected device name + + +
+ +
+
+ + + +
+

Trace targets:

+ +
+ +
+

Dump targets:

+
+ {{DUMPS[dumpKey]}} +
+
+
+
+ `, +}) +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 = [ + { + 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 { + 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]; + } +} diff --git a/tools/winscope-ng/src/trace_collection/proxy_client.ts b/tools/winscope-ng/src/trace_collection/proxy_client.ts new file mode 100644 index 000000000..93cdc7c12 --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/proxy_client.ts @@ -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, +} diff --git a/tools/winscope-ng/src/trace_collection/trace_config.component.spec.ts b/tools/winscope-ng/src/trace_collection/trace_config.component.spec.ts new file mode 100644 index 000000000..c2110fa4c --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/trace_config.component.spec.ts @@ -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; + 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(); + }); + +}); diff --git a/tools/winscope-ng/src/trace_collection/trace_config.component.ts b/tools/winscope-ng/src/trace_collection/trace_config.component.ts new file mode 100644 index 000000000..8bdac72a9 --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/trace_config.component.ts @@ -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: ` +
+ {{name}} +
+ {{enableConfig}} +
+ + {{con.name}} + + {{ option }} + + +
+
+
+ `, + 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(); + + public traceEnableConfigs(): Array { + if (this.configs && this.configs.enableConfigs) { + return this.configs.enableConfigs; + } else { + return []; + } + } + + public traceSelectionConfigs(): Array { + 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(); + } +} diff --git a/tools/winscope-ng/src/trace_collection/web_adb.component.spec.ts b/tools/winscope-ng/src/trace_collection/web_adb.component.spec.ts new file mode 100644 index 000000000..0021a9e26 --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/web_adb.component.spec.ts @@ -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; + 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"); + }); + +}); diff --git a/tools/winscope-ng/src/trace_collection/web_adb.component.ts b/tools/winscope-ng/src/trace_collection/web_adb.component.ts new file mode 100644 index 000000000..9dd26ab9e --- /dev/null +++ b/tools/winscope-ng/src/trace_collection/web_adb.component.ts @@ -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: ` +
Unable to connect to Web ADB
+
+

Instructions for connecting via Web ADB.

+
+
+ +
+ `, +}) +export class WebAdbComponent { + public restart() { + console.log("Try connecting again"); + } +}