diff --git a/tools/winscope/adb_proxy/winscope_proxy.py b/tools/winscope/adb_proxy/winscope_proxy.py index 344c3cc5b..0fba4735b 100755 --- a/tools/winscope/adb_proxy/winscope_proxy.py +++ b/tools/winscope/adb_proxy/winscope_proxy.py @@ -183,6 +183,11 @@ TRACE_TARGETS = { 'su root ime tracing start\necho "ManagerService IME trace started."', 'su root ime tracing stop >/dev/null 2>&1' ), + "wayland_trace": TraceTarget( + WinscopeFileMatcher("/data/misc/wltrace", "wl_trace", "wl_trace"), + 'su root service call Wayland 26 i32 1 >/dev/null\necho "Wayland trace started."', + 'su root service call Wayland 26 i32 0 >/dev/null' + ), } @@ -440,6 +445,13 @@ def call_adb_outfile(params: str, outfile, device: str = None, stdin: bytes = No 'Error executing adb command: adb {}\n{}'.format(params, repr(ex))) +class CheckWaylandServiceEndpoint(RequestEndpoint): + def process(self, server, path): + raw_res = call_adb('shell service check Wayland') + res = 'false' if 'not found' in raw_res else 'true' + server.respond(HTTPStatus.OK, res.encode("utf-8"), "text/json") + + class ListDevicesEndpoint(RequestEndpoint): ADB_INFO_RE = re.compile("^([A-Za-z0-9.:\\-]+)\\s+(\\w+)(.*model:(\\w+))?") @@ -799,6 +811,8 @@ class ADBWinscopeProxy(BaseHTTPRequestHandler): RequestType.POST, "selectedsfconfigtrace", SurfaceFlingerSelectedConfigTrace()) self.router.register_endpoint( RequestType.POST, "selectedwmconfigtrace", WindowManagerSelectedConfigTrace()) + self.router.register_endpoint( + RequestType.GET, "checkwayland", CheckWaylandServiceEndpoint()) super().__init__(request, client_address, server) def respond(self, code: int, data: bytes, mime: str) -> None: diff --git a/tools/winscope/src/DataAdb.vue b/tools/winscope/src/DataAdb.vue index 6490f394b..0bbc60c26 100644 --- a/tools/winscope/src/DataAdb.vue +++ b/tools/winscope/src/DataAdb.vue @@ -84,7 +84,7 @@

Trace targets:

- {{TRACES[traceKey].name}} + {{ DYNAMIC_TRACES[traceKey].name }}

Surface Flinger config

@@ -173,35 +173,44 @@ const PROXY_ENDPOINTS = { DUMP: '/dump/', FETCH: '/fetch/', STATUS: '/status/', + CHECK_WAYLAND: '/checkwayland/', }; +// trace options should be added in a nested category const TRACES = { - 'window_trace': { - name: 'Window Manager', + 'default': { + 'window_trace': { + name: 'Window Manager', + }, + 'accessibility_trace': { + name: 'Accessibility', + }, + 'layers_trace': { + name: 'Surface Flinger', + }, + 'transaction': { + name: 'Transactions', + }, + 'proto_log': { + name: 'ProtoLog', + }, + 'screen_recording': { + name: 'Screen Recording', + }, + 'ime_trace_clients': { + name: 'Input Method Clients', + }, + 'ime_trace_service': { + name: 'Input Method Service', + }, + 'ime_trace_managerservice': { + name: 'Input Method Manager Service', + }, }, - 'accessibility_trace': { - name: 'Accessibility', - }, - 'layers_trace': { - name: 'Surface Flinger', - }, - 'transaction': { - name: 'Transactions', - }, - 'proto_log': { - name: 'ProtoLog', - }, - 'screen_recording': { - name: 'Screen Recording', - }, - 'ime_trace_clients': { - name: 'Input Method Clients', - }, - 'ime_trace_service': { - name: 'Input Method Service', - }, - 'ime_trace_managerservice': { - name: 'Input Method Manager Service', + 'arc': { + 'wayland_trace': { + name: 'Wayland', + }, }, }; @@ -275,6 +284,7 @@ export default { return { STATES, TRACES, + DYNAMIC_TRACES: TRACES['default'], TRACE_CONFIG, SF_SELECTED_CONFIG, WM_SELECTED_CONFIG, @@ -298,7 +308,7 @@ export default { proxyKey: '', lastDevice: '', }, - Object.keys(TRACES) + this.getAllTraceKeys(TRACES) .concat(Object.keys(DUMPS)) .concat(CONFIGS) .reduce(function(obj, key) { @@ -338,6 +348,34 @@ export default { } }); }, + getAllTraceKeys(traces) { + let keys = []; + for (let dict_key in traces) { + for (let key in traces[dict_key]) { + keys.push(key); + } + } + return keys; + }, + setAvailableTraces() { + this.DYNAMIC_TRACES = this.TRACES['default']; + this.callProxy('GET', PROXY_ENDPOINTS.CHECK_WAYLAND, this, function(request, view) { + try { + if(request.responseText == 'true') { + view.appendOptionalTraces('arc'); + } + } catch(err) { + console.error(err); + view.errorText = request.responseText; + view.status = STATES.ERROR; + } + }); + }, + appendOptionalTraces(device_key) { + for(let key in this.TRACES[device_key]) { + this.$set(this.DYNAMIC_TRACES, key, this.TRACES[device_key][key]); + } + }, keepAliveTrace() { if (this.status !== STATES.END_TRACE) { clearInterval(this.keep_alive_worker); @@ -428,7 +466,7 @@ export default { }, 'arraybuffer'); }, toTrace() { - return Object.keys(TRACES) + return Object.keys(this.DYNAMIC_TRACES) .filter((traceKey) => this.adbStore[traceKey]); }, toTraceConfig() { @@ -527,6 +565,9 @@ export default { if (st == STATES.CONNECTING) { this.getDevices(); } + if (st == STATES.START_TRACE) { + this.setAvailableTraces(); + } }, }, },