Edit SF and WM config from winscope. am: 5284e5a483
Original change: https://googleplex-android-review.googlesource.com/c/platform/development/+/16047809 Change-Id: I2b50e786984ca93f5d5803522f9bf49b41caf30a
This commit is contained in:
@@ -203,6 +203,52 @@ class SurfaceFlingerTraceConfig:
|
||||
def command(self) -> str:
|
||||
return f'su root service call SurfaceFlinger 1033 i32 {self.flags}'
|
||||
|
||||
class SurfaceFlingerTraceSelectedConfig:
|
||||
"""Handles optional selected configuration for surfaceflinger traces.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# defaults set for all configs
|
||||
self.selectedConfigs = {
|
||||
"sfbuffersize": "16000"
|
||||
}
|
||||
|
||||
def add(self, configType, configValue) -> None:
|
||||
self.selectedConfigs[configType] = configValue
|
||||
|
||||
def is_valid(self, configType) -> bool:
|
||||
return configType in CONFIG_SF_SELECTION
|
||||
|
||||
def setBufferSize(self) -> str:
|
||||
return f'su root service call SurfaceFlinger 1029 i32 {self.selectedConfigs["sfbuffersize"]}'
|
||||
|
||||
class WindowManagerTraceSelectedConfig:
|
||||
"""Handles optional selected configuration for windowmanager traces.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# defaults set for all configs
|
||||
self.selectedConfigs = {
|
||||
"wmbuffersize": "16000",
|
||||
"tracinglevel": "all",
|
||||
"tracingtype": "frame",
|
||||
}
|
||||
|
||||
def add(self, configType, configValue) -> None:
|
||||
self.selectedConfigs[configType] = configValue
|
||||
|
||||
def is_valid(self, configType) -> bool:
|
||||
return configType in CONFIG_WM_SELECTION
|
||||
|
||||
def setBufferSize(self) -> str:
|
||||
return f'su root cmd window tracing size {self.selectedConfigs["wmbuffersize"]}'
|
||||
|
||||
def setTracingLevel(self) -> str:
|
||||
return f'su root cmd window tracing level {self.selectedConfigs["tracinglevel"]}'
|
||||
|
||||
def setTracingType(self) -> str:
|
||||
return f'su root cmd window tracing {self.selectedConfigs["tracingtype"]}'
|
||||
|
||||
|
||||
CONFIG_FLAG = {
|
||||
"composition": 1 << 2,
|
||||
@@ -210,6 +256,17 @@ CONFIG_FLAG = {
|
||||
"hwc": 1 << 4
|
||||
}
|
||||
|
||||
#Keep up to date with options in DataAdb.vue
|
||||
CONFIG_SF_SELECTION = [
|
||||
"sfbuffersize",
|
||||
]
|
||||
|
||||
#Keep up to date with options in DataAdb.vue
|
||||
CONFIG_WM_SELECTION = [
|
||||
"wmbuffersize",
|
||||
"tracingtype",
|
||||
"tracinglevel",
|
||||
]
|
||||
|
||||
class DumpTarget:
|
||||
"""Defines a single parameter to trace.
|
||||
@@ -610,6 +667,18 @@ class EndTrace(DeviceRequestEndpoint):
|
||||
"utf-8"))
|
||||
|
||||
|
||||
def execute_command(server, device_id, shell, configType, configValue):
|
||||
process = subprocess.Popen(shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE, start_new_session=True)
|
||||
log.debug(f"Changing trace config on device {device_id} {configType}:{configValue}")
|
||||
out, err = process.communicate(configValue.encode('utf-8'))
|
||||
if process.returncode != 0:
|
||||
raise AdbError(
|
||||
f"Error executing command:\n {configValue}\n\n### OUTPUT ###{out.decode('utf-8')}\n{err.decode('utf-8')}")
|
||||
log.debug(f"Changing trace config finished on device {device_id}")
|
||||
server.respond(HTTPStatus.OK, b'', "text/plain")
|
||||
|
||||
|
||||
class ConfigTrace(DeviceRequestEndpoint):
|
||||
def process_with_device(self, server, path, device_id):
|
||||
try:
|
||||
@@ -630,15 +699,50 @@ class ConfigTrace(DeviceRequestEndpoint):
|
||||
command = config.command()
|
||||
shell = ['adb', '-s', device_id, 'shell']
|
||||
log.debug(f"Starting shell {' '.join(shell)}")
|
||||
process = subprocess.Popen(shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE, start_new_session=True)
|
||||
log.debug(f"Changing trace config on device {device_id} cmd:{command}")
|
||||
out, err = process.communicate(command.encode('utf-8'))
|
||||
if process.returncode != 0:
|
||||
raise AdbError(
|
||||
f"Error executing command:\n {command}\n\n### OUTPUT ###{out.decode('utf-8')}\n{err.decode('utf-8')}")
|
||||
log.debug(f"Changing trace config finished on device {device_id}")
|
||||
server.respond(HTTPStatus.OK, b'', "text/plain")
|
||||
execute_command(server, device_id, shell, "sf buffer size", command)
|
||||
|
||||
|
||||
def add_selected_request_to_config(self, server, device_id, config):
|
||||
try:
|
||||
requested_configs = self.get_request(server)
|
||||
for requested_config in requested_configs:
|
||||
if config.is_valid(requested_config):
|
||||
config.add(requested_config, requested_configs[requested_config])
|
||||
else:
|
||||
raise BadRequest(
|
||||
f"Unsupported config {requested_config}\n")
|
||||
except KeyError as err:
|
||||
raise BadRequest("Unsupported trace target\n" + str(err))
|
||||
if device_id in TRACE_THREADS:
|
||||
BadRequest(f"Trace in progress for {device_id}")
|
||||
if not check_root(device_id):
|
||||
raise AdbError(
|
||||
f"Unable to acquire root privileges on the device - check the output of 'adb -s {device_id} shell su root id'")
|
||||
return config
|
||||
|
||||
|
||||
class SurfaceFlingerSelectedConfigTrace(DeviceRequestEndpoint):
|
||||
def process_with_device(self, server, path, device_id):
|
||||
config = SurfaceFlingerTraceSelectedConfig()
|
||||
config = add_selected_request_to_config(self, server, device_id, config)
|
||||
setBufferSize = config.setBufferSize()
|
||||
shell = ['adb', '-s', device_id, 'shell']
|
||||
log.debug(f"Starting shell {' '.join(shell)}")
|
||||
execute_command(server, device_id, shell, "sf buffer size", setBufferSize)
|
||||
|
||||
|
||||
class WindowManagerSelectedConfigTrace(DeviceRequestEndpoint):
|
||||
def process_with_device(self, server, path, device_id):
|
||||
config = WindowManagerTraceSelectedConfig()
|
||||
config = add_selected_request_to_config(self, server, device_id, config)
|
||||
setBufferSize = config.setBufferSize()
|
||||
setTracingType = config.setTracingType()
|
||||
setTracingLevel = config.setTracingLevel()
|
||||
shell = ['adb', '-s', device_id, 'shell']
|
||||
log.debug(f"Starting shell {' '.join(shell)}")
|
||||
execute_command(server, device_id, shell, "wm buffer size", setBufferSize)
|
||||
execute_command(server, device_id, shell, "tracing type", setTracingType)
|
||||
execute_command(server, device_id, shell, "tracing level", setTracingLevel)
|
||||
|
||||
|
||||
class StatusEndpoint(DeviceRequestEndpoint):
|
||||
@@ -691,6 +795,10 @@ class ADBWinscopeProxy(BaseHTTPRequestHandler):
|
||||
self.router.register_endpoint(RequestType.POST, "dump", DumpEndpoint())
|
||||
self.router.register_endpoint(
|
||||
RequestType.POST, "configtrace", ConfigTrace())
|
||||
self.router.register_endpoint(
|
||||
RequestType.POST, "selectedsfconfigtrace", SurfaceFlingerSelectedConfigTrace())
|
||||
self.router.register_endpoint(
|
||||
RequestType.POST, "selectedwmconfigtrace", WindowManagerSelectedConfigTrace())
|
||||
super().__init__(request, client_address, server)
|
||||
|
||||
def respond(self, code: int, data: bytes, mime: str) -> None:
|
||||
|
||||
@@ -86,10 +86,29 @@
|
||||
<div class="selection">
|
||||
<md-checkbox class="md-primary" v-for="traceKey in Object.keys(TRACES)" :key="traceKey" v-model="adbStore[traceKey]">{{TRACES[traceKey].name}}</md-checkbox>
|
||||
</div>
|
||||
<div class="trace-config" v-for="traceKey in Object.keys(TRACE_CONFIG)" :key="traceKey">
|
||||
<h4>{{TRACES[traceKey].name}} config</h4>
|
||||
<div class="trace-config">
|
||||
<h4>Surface Flinger config</h4>
|
||||
<div class="selection">
|
||||
<md-checkbox class="md-primary" v-for="config in TRACE_CONFIG[traceKey]" :key="config" v-model="adbStore[config]">{{config}}</md-checkbox>
|
||||
<md-checkbox class="md-primary" v-for="config in TRACE_CONFIG['layers_trace']" :key="config" v-model="adbStore[config]">{{config}}</md-checkbox>
|
||||
<div class="selection">
|
||||
<md-field class="config-selection" v-for="selectConfig in Object.keys(SF_SELECTED_CONFIG)" :key="selectConfig">
|
||||
<md-select v-model="SF_SELECTED_CONFIG_VALUES[selectConfig]" :placeholder="selectConfig">
|
||||
<md-option value="">{{selectConfig}}</md-option>
|
||||
<md-option v-for="option in SF_SELECTED_CONFIG[selectConfig]" :key="option" :value="option">{{ option }}</md-option>
|
||||
</md-select>
|
||||
</md-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="trace-config">
|
||||
<h4>Window Manager config</h4>
|
||||
<div class="selection">
|
||||
<md-field class="config-selection" v-for="selectConfig in Object.keys(WM_SELECTED_CONFIG)" :key="selectConfig">
|
||||
<md-select v-model="WM_SELECTED_CONFIG_VALUES[selectConfig]" :placeholder="selectConfig">
|
||||
<md-option value="">{{selectConfig}}</md-option>
|
||||
<md-option v-for="option in WM_SELECTED_CONFIG[selectConfig]" :key="option" :value="option">{{ option }}</md-option>
|
||||
</md-select>
|
||||
</md-field>
|
||||
</div>
|
||||
</div>
|
||||
<md-button class="md-primary trace-btn" @click="startTrace">Start trace</md-button>
|
||||
@@ -149,6 +168,8 @@ const PROXY_ENDPOINTS = {
|
||||
START_TRACE: '/start/',
|
||||
END_TRACE: '/end/',
|
||||
CONFIG_TRACE: '/configtrace/',
|
||||
SELECTED_WM_CONFIG_TRACE: '/selectedwmconfigtrace/',
|
||||
SELECTED_SF_CONFIG_TRACE: '/selectedsfconfigtrace/',
|
||||
DUMP: '/dump/',
|
||||
FETCH: '/fetch/',
|
||||
STATUS: '/status/',
|
||||
@@ -192,6 +213,33 @@ const TRACE_CONFIG = {
|
||||
],
|
||||
};
|
||||
|
||||
const SF_SELECTED_CONFIG = {
|
||||
'sfbuffersize': [
|
||||
'4000',
|
||||
'8000',
|
||||
'16000',
|
||||
'32000',
|
||||
],
|
||||
};
|
||||
|
||||
const WM_SELECTED_CONFIG = {
|
||||
'wmbuffersize': [
|
||||
'4000',
|
||||
'8000',
|
||||
'16000',
|
||||
'32000',
|
||||
],
|
||||
'tracingtype': [
|
||||
'frame',
|
||||
'transaction',
|
||||
],
|
||||
'tracinglevel': [
|
||||
'all',
|
||||
'trim',
|
||||
'critical',
|
||||
],
|
||||
};
|
||||
|
||||
const DUMPS = {
|
||||
'window_dump': {
|
||||
name: 'Window Manager',
|
||||
@@ -228,6 +276,10 @@ export default {
|
||||
STATES,
|
||||
TRACES,
|
||||
TRACE_CONFIG,
|
||||
SF_SELECTED_CONFIG,
|
||||
WM_SELECTED_CONFIG,
|
||||
SF_SELECTED_CONFIG_VALUES: {},
|
||||
WM_SELECTED_CONFIG_VALUES: {},
|
||||
DUMPS,
|
||||
FILE_DECODERS,
|
||||
WINSCOPE_PROXY_VERSION,
|
||||
@@ -292,7 +344,7 @@ export default {
|
||||
this.keep_alive_worker = null;
|
||||
return;
|
||||
}
|
||||
this.callProxy('GET', PROXY_ENDPOINTS.STATUS + this.deviceId() + '/', this, function(request, view) {
|
||||
this.callProxy('GET', `${PROXY_ENDPOINTS.STATUS}${this.deviceId()}/`, this, function(request, view) {
|
||||
if (request.responseText !== 'True') {
|
||||
view.endTrace();
|
||||
} else if (view.keep_alive_worker === null) {
|
||||
@@ -303,16 +355,21 @@ export default {
|
||||
startTrace() {
|
||||
const requested = this.toTrace();
|
||||
const requestedConfig = this.toTraceConfig();
|
||||
const requestedSelectedSfConfig = this.toSelectedSfTraceConfig();
|
||||
const requestedSelectedWmConfig = this.toSelectedWmTraceConfig();
|
||||
if (requested.length < 1) {
|
||||
this.errorText = 'No targets selected';
|
||||
this.status = STATES.ERROR;
|
||||
this.newEventOccurred("No targets selected");
|
||||
return;
|
||||
}
|
||||
|
||||
this.newEventOccurred("Start Trace");
|
||||
this.callProxy('POST', PROXY_ENDPOINTS.CONFIG_TRACE + this.deviceId() + '/', this, null, null, requestedConfig);
|
||||
this.callProxy('POST', `${PROXY_ENDPOINTS.CONFIG_TRACE}${this.deviceId()}/`, this, null, null, requestedConfig);
|
||||
this.callProxy('POST', `${PROXY_ENDPOINTS.SELECTED_SF_CONFIG_TRACE}${this.deviceId()}/`, this, null, null, requestedSelectedSfConfig);
|
||||
this.callProxy('POST', `${PROXY_ENDPOINTS.SELECTED_WM_CONFIG_TRACE}${this.deviceId()}/`, this, null, null, requestedSelectedWmConfig);
|
||||
this.status = STATES.END_TRACE;
|
||||
this.callProxy('POST', PROXY_ENDPOINTS.START_TRACE + this.deviceId() + '/', this, function(request, view) {
|
||||
this.callProxy('POST', `${PROXY_ENDPOINTS.START_TRACE}${this.deviceId()}/`, this, function(request, view) {
|
||||
view.keepAliveTrace();
|
||||
}, null, requested);
|
||||
},
|
||||
@@ -326,19 +383,19 @@ export default {
|
||||
return;
|
||||
}
|
||||
this.status = STATES.LOAD_DATA;
|
||||
this.callProxy('POST', PROXY_ENDPOINTS.DUMP + this.deviceId() + '/', this, function(request, view) {
|
||||
this.callProxy('POST', `${PROXY_ENDPOINTS.DUMP}${this.deviceId()}/`, this, function(request, view) {
|
||||
view.loadFile(requested, 0);
|
||||
}, null, requested);
|
||||
},
|
||||
endTrace() {
|
||||
this.status = STATES.LOAD_DATA;
|
||||
this.callProxy('POST', PROXY_ENDPOINTS.END_TRACE + this.deviceId() + '/', this, function(request, view) {
|
||||
this.callProxy('POST', `${PROXY_ENDPOINTS.END_TRACE}${this.deviceId()}/`, this, function(request, view) {
|
||||
view.loadFile(view.toTrace(), 0);
|
||||
});
|
||||
this.newEventOccurred("Ended Trace");
|
||||
},
|
||||
loadFile(files, idx) {
|
||||
this.callProxy('GET', PROXY_ENDPOINTS.FETCH + this.deviceId() + '/' + files[idx] + '/', this, function(request, view) {
|
||||
this.callProxy('GET', `${PROXY_ENDPOINTS.FETCH}${this.deviceId()}/${files[idx]}/`, this, function(request, view) {
|
||||
try {
|
||||
const enc = new TextDecoder('utf-8');
|
||||
const resp = enc.decode(request.response);
|
||||
@@ -380,6 +437,24 @@ export default {
|
||||
.flatMap((file) => TRACE_CONFIG[file])
|
||||
.filter((config) => this.adbStore[config]);
|
||||
},
|
||||
toSelectedSfTraceConfig() {
|
||||
const requestedSelectedConfig = {};
|
||||
for (const config in this.SF_SELECTED_CONFIG_VALUES) {
|
||||
if (this.SF_SELECTED_CONFIG_VALUES[config] !== "") {
|
||||
requestedSelectedConfig[config] = this.SF_SELECTED_CONFIG_VALUES[config];
|
||||
}
|
||||
}
|
||||
return requestedSelectedConfig;
|
||||
},
|
||||
toSelectedWmTraceConfig() {
|
||||
const requestedSelectedConfig = {};
|
||||
for (const config in this.WM_SELECTED_CONFIG_VALUES) {
|
||||
if (this.WM_SELECTED_CONFIG_VALUES[config] !== "") {
|
||||
requestedSelectedConfig[config] = this.WM_SELECTED_CONFIG_VALUES[config];
|
||||
}
|
||||
}
|
||||
return requestedSelectedConfig;
|
||||
},
|
||||
toDump() {
|
||||
return Object.keys(DUMPS)
|
||||
.filter((dumpKey) => this.adbStore[dumpKey]);
|
||||
@@ -459,6 +534,12 @@ export default {
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.config-selection {
|
||||
width: 150px;
|
||||
display: inline-flex;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.device-choice {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user