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();
+ }
},
},
},