Merge changes If2a053c4,Ic9e8f6e7,I0782ec52,I2a2747b5,If067cf73

* changes:
  Add tests for combining IME with WM / SF entries
  Fix SFLayer TypeErrors in Winscope
  [11] Change matching WM/SF entry to IME entry algo
  [10] Refine WM & SF Properties IME subpanel
  [9] Fix null targets in IME's 'WM & SF Properties'
This commit is contained in:
Hui Ling Shi
2022-08-04 04:02:53 +00:00
committed by Android (Google) Code Review
10 changed files with 590 additions and 75 deletions

View File

@@ -0,0 +1,363 @@
import fs from 'fs';
import path from 'path';
import {dataFile, decodeAndTransformProto, FILE_DECODERS, FILE_TYPES} from '../src/decode';
import {combineWmSfWithImeDataIfExisting} from '../src/ime_processing';
const inputMethodClientFile =
'../spec/traces/ime_processing_traces/input_method_clients_trace.winscope';
const inputMethodServiceFile =
'../spec/traces/ime_processing_traces/input_method_service_trace.winscope';
const inputMethodManagerServiceFile =
'../spec/traces/ime_processing_traces/input_method_manager_service_trace.winscope';
const sfFile = '../spec/traces/ime_processing_traces/sf_trace_for_ime.winscope';
const wmFile = '../spec/traces/ime_processing_traces/wm_trace_for_ime.winscope';
/**
* Copied from decode.js but with the blobUrl mocked (due to some issues faced
* with importing Blob, which is used in the decode.js version of this function)
*/
function protoDecoder(buffer, params, fileName, store) {
const transformed =
decodeAndTransformProto(buffer, params, store.displayDefaults);
// add tagGenerationTrace to dataFile for WM/SF traces so tags can be
// generated
var tagGenerationTrace = null;
if (params.type === FILE_TYPES.WINDOW_MANAGER_TRACE ||
params.type === FILE_TYPES.SURFACE_FLINGER_TRACE) {
tagGenerationTrace = transformed;
}
let data;
if (params.timeline) {
data = transformed.entries || transformed.children;
} else {
data = [transformed];
}
const blobUrl = '';
return dataFile(
fileName, data.map((x) => x.timestamp), data, blobUrl, params.type,
tagGenerationTrace);
}
describe('Ime Processing', () => {
it('can combine wm & sf properties into ime traces', () => {
const inputMethodClientBuffer = new Uint8Array(
fs.readFileSync(path.resolve(__dirname, inputMethodClientFile)));
const inputMethodServiceBuffer = new Uint8Array(
fs.readFileSync(path.resolve(__dirname, inputMethodServiceFile)));
const inputMethodManagerServiceBuffer = new Uint8Array(fs.readFileSync(
path.resolve(__dirname, inputMethodManagerServiceFile)));
const sfBuffer =
new Uint8Array(fs.readFileSync(path.resolve(__dirname, sfFile)));
const wmBuffer =
new Uint8Array(fs.readFileSync(path.resolve(__dirname, wmFile)));
// (buffer, params, fileName, store)
const store = {displayDefaults: true};
const inputMethodClientTrace = protoDecoder(
inputMethodClientBuffer,
FILE_DECODERS[FILE_TYPES.IME_TRACE_CLIENTS].decoderParams,
'input_method_clients_trace.winscope', store);
const inputMethodServiceTrace = protoDecoder(
inputMethodServiceBuffer,
FILE_DECODERS[FILE_TYPES.IME_TRACE_SERVICE].decoderParams,
'input_method_service_trace.winscope', store);
const inputMethodManagerServiceTrace = protoDecoder(
inputMethodManagerServiceBuffer,
FILE_DECODERS[FILE_TYPES.IME_TRACE_MANAGERSERVICE].decoderParams,
'input_method_manager_service_trace.winscope', store);
const wmTrace = protoDecoder(
wmBuffer, FILE_DECODERS[FILE_TYPES.WINDOW_MANAGER_TRACE].decoderParams,
'sf_trace.winscope', store);
const sfTrace = protoDecoder(
sfBuffer, FILE_DECODERS[FILE_TYPES.SURFACE_FLINGER_TRACE].decoderParams,
'wm_trace.winscope', store);
const dataFiles = {
'ImeTrace Clients': inputMethodClientTrace,
'ImeTrace InputMethodService': inputMethodServiceTrace,
'ImeTrace InputMethodManagerService': inputMethodManagerServiceTrace,
'WindowManagerTrace': wmTrace,
'SurfaceFlingerTrace': sfTrace,
};
combineWmSfWithImeDataIfExisting(dataFiles);
expect(dataFiles.length == 5);
const processedImeClientTrace = dataFiles['ImeTrace Clients'];
expect(processedImeClientTrace.type).toEqual('ImeTraceClients');
expect(processedImeClientTrace.data).toBeDefined();
expect(processedImeClientTrace.data[0].hasWmSfProperties).toBeTrue();
expect(processedImeClientTrace.data[1].wmProperties).toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.name)
.toEqual('0d0h8m22s938ms');
expect(processedImeClientTrace.data[1].wmProperties.focusedApp)
.toEqual(
'com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity');
expect(processedImeClientTrace.data[1].wmProperties.focusedActivity)
.toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.focusedWindow)
.toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.imeControlTarget)
.toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.imeInputTarget)
.toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.imeInsetsSourceProvider)
.toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.imeLayeringTarget)
.toBeDefined();
expect(
processedImeClientTrace.data[1].wmProperties.isInputMethodWindowVisible)
.toBeDefined();
expect(processedImeClientTrace.data[1].wmProperties.proto).toBeDefined();
expect(processedImeClientTrace.data[1].sfProperties.name)
.toEqual('0d0h8m22s942ms');
expect(processedImeClientTrace.data[1]
.sfProperties.isInputMethodSurfaceVisible)
.toEqual(false);
expect(processedImeClientTrace.data[1].sfProperties.imeContainer)
.toBeDefined();
expect(processedImeClientTrace.data[1].sfProperties.inputMethodSurface)
.toBeDefined();
expect(processedImeClientTrace.data[1].sfProperties.rect).toBeDefined();
expect(processedImeClientTrace.data[1].sfProperties.screenBounds)
.toBeDefined();
expect(processedImeClientTrace.data[1].sfProperties.z).toEqual(1);
expect(processedImeClientTrace.data[1].sfProperties.zOrderRelativeOfId)
.toEqual(115);
expect(processedImeClientTrace.data[1].sfProperties.focusedWindowRgba)
.toBeDefined();
expect(processedImeClientTrace.data[1].sfProperties.proto).toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties).toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties.name)
.toEqual('0d0h8m23s69ms');
expect(processedImeClientTrace.data[10].wmProperties.focusedApp)
.toEqual(
'com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity');
expect(processedImeClientTrace.data[10].wmProperties.focusedActivity)
.toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties.focusedWindow)
.toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties.imeControlTarget)
.toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties.imeInputTarget)
.toBeDefined();
expect(
processedImeClientTrace.data[10].wmProperties.imeInsetsSourceProvider)
.toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties.imeLayeringTarget)
.toBeDefined();
expect(processedImeClientTrace.data[10]
.wmProperties.isInputMethodWindowVisible)
.toBeDefined();
expect(processedImeClientTrace.data[10].wmProperties.proto).toBeDefined();
expect(processedImeClientTrace.data[10].sfProperties.name)
.toEqual('0d0h8m23s73ms');
expect(processedImeClientTrace.data[10]
.sfProperties.isInputMethodSurfaceVisible)
.toEqual(false);
expect(processedImeClientTrace.data[10].sfProperties.imeContainer)
.toBeDefined();
expect(processedImeClientTrace.data[10].sfProperties.inputMethodSurface)
.toBeDefined();
expect(processedImeClientTrace.data[10].sfProperties.rect).toBeDefined();
expect(processedImeClientTrace.data[10].sfProperties.screenBounds)
.toBeDefined();
expect(processedImeClientTrace.data[10].sfProperties.z).toEqual(1);
expect(processedImeClientTrace.data[10].sfProperties.zOrderRelativeOfId)
.toEqual(115);
expect(processedImeClientTrace.data[10].sfProperties.focusedWindowRgba)
.toBeDefined();
expect(processedImeClientTrace.data[10].sfProperties.proto).toBeDefined();
const processedInputMethodServiceTrace =
dataFiles['ImeTrace InputMethodService'];
expect(processedInputMethodServiceTrace.type)
.toEqual('ImeTrace InputMethodService');
expect(processedInputMethodServiceTrace.data[0].hasWmSfProperties)
.toBeTrue();
expect(processedInputMethodServiceTrace.data[1].wmProperties).toBeDefined();
expect(processedInputMethodServiceTrace.data[1].wmProperties.name)
.toEqual('0d0h8m23s6ms');
expect(processedInputMethodServiceTrace.data[1].wmProperties.focusedApp)
.toEqual(
'com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity');
expect(
processedInputMethodServiceTrace.data[1].wmProperties.focusedActivity)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].wmProperties.focusedWindow)
.toBeDefined();
expect(
processedInputMethodServiceTrace.data[1].wmProperties.imeControlTarget)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].wmProperties.imeInputTarget)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1]
.wmProperties.imeInsetsSourceProvider)
.toBeDefined();
expect(
processedInputMethodServiceTrace.data[1].wmProperties.imeLayeringTarget)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1]
.wmProperties.isInputMethodWindowVisible)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].wmProperties.proto)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].sfProperties.name)
.toEqual('0d0h8m23s26ms');
expect(processedInputMethodServiceTrace.data[1]
.sfProperties.isInputMethodSurfaceVisible)
.toEqual(false);
expect(processedInputMethodServiceTrace.data[1].sfProperties.imeContainer)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1]
.sfProperties.inputMethodSurface)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].sfProperties.rect)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].sfProperties.screenBounds)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].sfProperties.z).toEqual(1);
expect(processedInputMethodServiceTrace.data[1]
.sfProperties.zOrderRelativeOfId)
.toEqual(115);
expect(
processedInputMethodServiceTrace.data[1].sfProperties.focusedWindowRgba)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[1].sfProperties.proto)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].wmProperties)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].wmProperties.name)
.toEqual('0d0h8m23s186ms');
expect(processedInputMethodServiceTrace.data[10].wmProperties.focusedApp)
.toEqual(
'com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity');
expect(
processedInputMethodServiceTrace.data[10].wmProperties.focusedActivity)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].wmProperties.focusedWindow)
.toBeDefined();
expect(
processedInputMethodServiceTrace.data[10].wmProperties.imeControlTarget)
.toBeDefined();
expect(
processedInputMethodServiceTrace.data[10].wmProperties.imeInputTarget)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10]
.wmProperties.imeInsetsSourceProvider)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10]
.wmProperties.imeLayeringTarget)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10]
.wmProperties.isInputMethodWindowVisible)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].wmProperties.proto)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].sfProperties.name)
.toEqual('0d0h8m23s173ms');
expect(processedInputMethodServiceTrace.data[10]
.sfProperties.isInputMethodSurfaceVisible)
.toEqual(false);
expect(processedInputMethodServiceTrace.data[10].sfProperties.imeContainer)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10]
.sfProperties.inputMethodSurface)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].sfProperties.rect)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].sfProperties.screenBounds)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].sfProperties.z).toEqual(1);
expect(processedInputMethodServiceTrace.data[10]
.sfProperties.zOrderRelativeOfId)
.toEqual(260);
expect(processedInputMethodServiceTrace.data[10]
.sfProperties.focusedWindowRgba)
.toBeDefined();
expect(processedInputMethodServiceTrace.data[10].sfProperties.proto)
.toBeDefined();
const processedInputMethodManagerServiceTrace = dataFiles['ImeTrace' +
' InputMethodManagerService'];
expect(processedInputMethodManagerServiceTrace.type)
.toEqual(
'ImeTrace' +
' InputMethodManagerService');
expect(processedInputMethodManagerServiceTrace.data[0].hasWmSfProperties)
.toBeTrue();
expect(processedInputMethodManagerServiceTrace.data[1].wmProperties)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1].wmProperties.name)
.toEqual('0d0h8m23s52ms');
expect(
processedInputMethodManagerServiceTrace.data[1].wmProperties.focusedApp)
.toEqual(
'com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity');
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.focusedActivity)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.focusedWindow)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.imeControlTarget)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.imeInputTarget)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.imeInsetsSourceProvider)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.imeLayeringTarget)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1]
.wmProperties.isInputMethodWindowVisible)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[1].wmProperties.proto)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10].wmProperties)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10].wmProperties.name)
.toEqual('0d0h8m27s309ms');
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.focusedApp)
.toEqual(
'com.google.android.apps.messaging/.ui.search.ZeroStateSearchActivity');
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.focusedActivity)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.focusedWindow)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.imeControlTarget)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.imeInputTarget)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.imeInsetsSourceProvider)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.imeLayeringTarget)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10]
.wmProperties.isInputMethodWindowVisible)
.toBeDefined();
expect(processedInputMethodManagerServiceTrace.data[10].wmProperties.proto)
.toBeDefined();
});
});

View File

@@ -20,16 +20,29 @@
</div>
<div v-else-if="isImeManagerService">
<div class="group">
<span class="group-header">WMState</span>
<button
class="text-button group-header"
v-if="wmProtoOrNull"
:class="{ 'selected': isSelected(wmProtoOrNull) }"
@click="onClickShowInPropertiesPanel(wmProtoOrNull)">
WMState
</button>
<span class="group-header" v-else>WMState</span>
<div class="full-width">
<span class="value" v-if="entry.wmProperties">{{
entry.wmProperties.name }}</span>
<span v-else>There is no corresponding WMState entry.</span>
</div>
</div>
<div class="group">
<span class="group-header">IME Insets Source Provider</span>
<div class="group" v-if="wmInsetsSourceProviderOrNull">
<button
class="text-button group-header"
:class="{ 'selected': isSelected(wmInsetsSourceProviderOrNull) }"
@click="onClickShowInPropertiesPanel(wmInsetsSourceProviderOrNull)">
IME Insets Source Provider
</button>
<div class="full-width">
<div />
<span class="key">Source Frame:</span>
<CoordinatesTable
:coordinates="wmInsetsSourceProviderSourceFrameOrNull" />
@@ -56,40 +69,40 @@
</div>
</div>
<div class="group">
<span class="group-header">IMControl Target</span>
<span class="group-header">Control Target</span>
<div class="full-width">
<button
class="text-button"
:class="{ 'selected': isSelected(wmIMControlTargetOrNull) }"
v-if="wmIMControlTargetOrNull"
@click="onClickShowInPropertiesPanel(wmIMControlTargetOrNull)">
Input Method Control Target
:class="{ 'selected': isSelected(wmImeControlTargetOrNull) }"
v-if="wmImeControlTargetOrNull"
@click="onClickShowInPropertiesPanel(wmImeControlTargetOrNull)">
IME Control Target
</button>
<span class="value" v-else>null</span>
</div>
</div>
<div class="group">
<span class="group-header">IMInput Target</span>
<span class="group-header">Input Target</span>
<div class="full-width">
<button
class="text-button"
:class="{ 'selected': isSelected(wmIMInputTargetOrNull) }"
v-if="wmIMInputTargetOrNull"
@click="onClickShowInPropertiesPanel(wmIMInputTargetOrNull)">
Input Method Input Target
:class="{ 'selected': isSelected(wmImeInputTargetOrNull) }"
v-if="wmImeInputTargetOrNull"
@click="onClickShowInPropertiesPanel(wmImeInputTargetOrNull)">
IME Input Target
</button>
<span class="value" v-else>null</span>
</div>
</div>
<div class="group">
<span class="group-header">IM Target</span>
<span class="group-header">Layering Target</span>
<div class="full-width">
<button
class="text-button"
:class="{ 'selected': isSelected(wmIMTargetOrNull) }"
v-if="wmIMTargetOrNull"
@click="onClickShowInPropertiesPanel(wmIMTargetOrNull)">
Input Method Target
:class="{ 'selected': isSelected(wmImeLayeringTargetOrNull) }"
v-if="wmImeLayeringTargetOrNull"
@click="onClickShowInPropertiesPanel(wmImeLayeringTargetOrNull)">
IME Layering Target
</button>
<span class="value" v-else>null</span>
</div>
@@ -99,7 +112,14 @@
<div v-else>
<!-- Ime Client or Ime Service -->
<div class="group">
<span class="group-header">WMState</span>
<button
class="text-button group-header"
v-if="wmProtoOrNull"
:class="{ 'selected': isSelected(wmProtoOrNull) }"
@click="onClickShowInPropertiesPanel(wmProtoOrNull)">
WMState
</button>
<span class="group-header" v-else>WMState</span>
<div class="full-width">
<span class="value" v-if="entry.wmProperties">{{
entry.wmProperties.name }}</span>
@@ -109,8 +129,8 @@
<div class="group">
<span class="group-header">SFLayer</span>
<div class="full-width">
<span class="value" v-if="entry.sfImeContainerProperties">{{
entry.sfImeContainerProperties.name }}</span>
<span class="value" v-if="entry.sfProperties">{{
entry.sfProperties.name }}</span>
<span v-else>There is no corresponding SFLayer entry.</span>
</div>
</div>
@@ -126,29 +146,66 @@
<span class="key">Focused Window:</span>
<span class="value">{{ entry.wmProperties.focusedWindow }}</span>
<div />
<span class="key">Frame:</span>
<span class="key" v-if="entry.sfProperties">Focused Window Color:</span>
<span class="value" v-if="entry.sfProperties">{{
entry.sfProperties.focusedWindowRgba
}}</span>
<div />
<span class="key">Input Control Target Frame:</span>
<CoordinatesTable :coordinates="wmControlTargetFrameOrNull" />
<div />
</div>
</div>
<div class="group" v-if="entry.sfImeContainerProperties">
<span class="group-header">Ime Container</span>
<div class="group">
<span class="group-header">Visibility</span>
<div class="full-width">
<span class="key">ScreenBounds:</span>
<CoordinatesTable
:coordinates="sfImeContainerScreenBoundsOrNull" />
<span class="key" v-if="entry.wmProperties">InputMethod Window:</span>
<span class="value" v-if="entry.wmProperties">{{
entry.wmProperties.isInputMethodWindowVisible
}}</span>
<div />
<span class="key">Rect:</span>
<CoordinatesTable
:coordinates="sfImeContainerRectOrNull" />
<span class="key" v-if="entry.sfProperties">InputMethod Surface:</span>
<span class="value" v-if="entry.sfProperties">{{
entry.sfProperties.isInputMethodSurfaceVisible }}</span>
<div />
</div>
</div>
<div class="group" v-if="entry.sfProperties">
<button
class="text-button group-header"
:class="{ 'selected': isSelected(entry.sfProperties.imeContainer) }"
@click="onClickShowInPropertiesPanel(entry.sfProperties.imeContainer)">
Ime Container
</button>
<div class="full-width">
<span class="key">ZOrderRelativeOfId:</span>
<span class="value">{{
entry.sfImeContainerProperties.zOrderRelativeOfId
entry.sfProperties.zOrderRelativeOfId
}}</span>
<div />
<span class="key">Z:</span>
<span class="value">{{ entry.sfImeContainerProperties.z }}</span>
<span class="value">{{ entry.sfProperties.z }}</span>
<div />
</div>
</div>
<div class="group" v-if="entry.sfProperties">
<button
class="text-button group-header"
:class="{
'selected': isSelected(entry.sfProperties.inputMethodSurface)
}"
@click="onClickShowInPropertiesPanel(
entry.sfProperties.inputMethodSurface)">
Input Method Surface
</button>
<div class="full-width">
<span class="key">ScreenBounds:</span>
<CoordinatesTable
:coordinates="sfImeContainerScreenBoundsOrNull" />
<div />
<span class="key">Rect:</span>
<CoordinatesTable
:coordinates="sfImeContainerRectOrNull" />
<div />
</div>
</div>
@@ -209,6 +266,15 @@ export default {
},
computed: {
wmProtoOrNull() {
return this.entry.wmProperties?.proto;
},
wmInsetsSourceProviderOrNull() {
return this.entry.wmProperties?.imeInsetsSourceProvider ?
Object.assign({'name': 'Ime Insets Source Provider'},
this.entry.wmProperties.imeInsetsSourceProvider) :
null;
},
wmControlTargetFrameOrNull() {
return this.entry.wmProperties?.imeInsetsSourceProvider
?.insetsSourceProvider?.controlTarget?.windowFrames?.frame || 'null';
@@ -237,36 +303,36 @@ export default {
return this.entry.wmProperties?.imeInsetsSourceProvider
?.insetsSourceProvider?.source?.visibleFrame || 'null';
},
wmIMControlTargetOrNull() {
return this.entry?.wmProperties?.inputMethodControlTarget ?
Object.assign({'name': 'Input Method Control Target'},
this.entry.wmProperties.inputMethodControlTarget) :
wmImeControlTargetOrNull() {
return this.entry?.wmProperties?.imeControlTarget ?
Object.assign({'name': 'IME Control Target'},
this.entry.wmProperties.imeControlTarget) :
null;
},
wmIMInputTargetOrNull() {
return this.entry?.wmProperties?.inputMethodInputTarget ?
Object.assign({'name': 'Input Method Input Target'},
this.entry.wmProperties.inputMethodInputTarget) :
wmImeInputTargetOrNull() {
return this.entry?.wmProperties?.imeInputTarget ?
Object.assign({'name': 'IME Input Target'},
this.entry.wmProperties.imeInputTarget) :
null;
},
wmIMTargetOrNull() {
return this.entry?.wmProperties?.inputMethodTarget ?
Object.assign({'name': 'Input Method Target'},
this.entry.wmProperties.inputMethodTarget) :
wmImeLayeringTargetOrNull() {
return this.entry?.wmProperties?.imeLayeringTarget ?
Object.assign({'name': 'IME Layering Target'},
this.entry.wmProperties.imeLayeringTarget) :
null;
},
sfImeContainerScreenBoundsOrNull() {
return this.entry.sfImeContainerProperties?.screenBounds || 'null';
return this.entry.sfProperties?.screenBounds || 'null';
},
sfImeContainerRectOrNull() {
return this.entry.sfImeContainerProperties?.rect || 'null';
return this.entry.sfProperties?.rect || 'null';
},
isAllPropertiesNull() {
if (this.isImeManagerService) {
return !this.entry.wmProperties;
} else {
return !(this.entry.wmProperties ||
this.entry.sfImeContainerProperties);
this.entry.sfProperties);
}
},
},
@@ -301,6 +367,7 @@ export default {
.group-header {
justify-content: center;
text-align: left;
padding: 0px 5px;
width: 95px;
display: inline-block;

View File

@@ -37,7 +37,7 @@ export default {
summarizer(layer) {
const summary = [];
if (layer?.visibilityReason.length > 0) {
if (layer?.visibilityReason?.length > 0) {
let reason = "";
if (Array.isArray(layer.visibilityReason)) {
reason = layer.visibilityReason.join(", ");

View File

@@ -13,7 +13,7 @@
limitations under the License.
-->
<template>
<div class="matrix">
<div class="matrix" v-if="transform">
<md-tooltip>{{ transform.getTypeAsString() }}</md-tooltip>
<div class="cell">{{ formatFloat(transform.matrix.dsdx) }}</div>
<div class="cell">{{ formatFloat(transform.matrix.dsdy) }}</div>

View File

@@ -60,6 +60,7 @@ function combineWmSfWithImeDataIfExisting(dataFiles) {
combineWmSfPropertiesIntoImeData(
imeTraceFile, filesAsDict[TRACE_TYPES.SURFACE_FLINGER]);
}
processImeAfterCombiningWmAndSfProperties(imeTraceFile);
}
console.log('after combining', dataFiles);
}
@@ -84,17 +85,14 @@ function combineWmSfPropertiesIntoImeData(imeTraceFile, wmOrSfTraceFile) {
// hasWmSfProperties is added into data because the
// imeTraceFile object itself is inextensible if it's from file input
} else if (wmStateOrSfLayer) {
const sfImeContainerProperties =
extractImeContainerFields(wmStateOrSfLayer);
imeTraceFile.data[i].sfImeContainerProperties = Object.assign(
{'name': wmStateOrSfLayer.name}, sfImeContainerProperties);
// 'name' is the ..d..h..m..s..ms timestamp
const sfProperties = extractSfProperties(wmStateOrSfLayer);
imeTraceFile.data[i].sfProperties = sfProperties;
const sfSubtrees = filterSfLayerForIme(
wmStateOrSfLayer); // for display in Hierarchy sub-panel
imeTraceFile.data[i].children.push(...sfSubtrees);
if (sfImeContainerProperties || sfSubtrees.length > 0) {
if (sfProperties || sfSubtrees.length > 0) {
imeTraceFile.data[0].hasWmSfProperties = true;
}
}
@@ -102,40 +100,80 @@ function combineWmSfPropertiesIntoImeData(imeTraceFile, wmOrSfTraceFile) {
}
function matchCorrespondingTimestamps(imeTimestamps, wmOrSfTimestamps) {
// find the latest sf / wm timestamp that comes before current ime timestamp
// we want to take the earliest sf / wm entry that is within
// +-[FAULT_TOLERANCE] ns of the ime entry as the corresponding sf / wm entry
const FAULT_TOLERANCE = 200000000; // 200ms in ns
let wmOrSfIndex = 0;
const intersectWmOrSfIndices = [];
for (let imeIndex = 0; imeIndex < imeTimestamps.length; imeIndex++) {
const currImeTimestamp = imeTimestamps[imeIndex];
let currWmOrSfTimestamp = wmOrSfTimestamps[wmOrSfIndex];
while (currWmOrSfTimestamp < currImeTimestamp) {
let wmOrSfTimestamp = wmOrSfTimestamps[wmOrSfIndex];
while (wmOrSfTimestamp < currImeTimestamp) {
wmOrSfIndex++;
currWmOrSfTimestamp = wmOrSfTimestamps[wmOrSfIndex];
wmOrSfTimestamp = wmOrSfTimestamps[wmOrSfIndex];
}
// wmOrSfIndex should now be at the first entry that is past
// [currImeTimestamp] ns. We want the most recent entry that comes
// before [currImeTimestamp] ns if it's within
// [currImeTimestamp - FAULT_TOLERANCE] ns. Otherwise, we want the most
// recent entry that comes after [currImeTimestamp] ns if it's within
// [currImeTimestamp + FAULT_TOLERANCE] ns.
const previousWmOrSfTimestamp = wmOrSfTimestamps[wmOrSfIndex - 1];
if (previousWmOrSfTimestamp >= currImeTimestamp - FAULT_TOLERANCE) {
intersectWmOrSfIndices.push(wmOrSfIndex - 1);
} else if (wmOrSfTimestamp <= currImeTimestamp + FAULT_TOLERANCE) {
intersectWmOrSfIndices.push(wmOrSfIndex);
} else {
intersectWmOrSfIndices.push(null);
}
intersectWmOrSfIndices.push(wmOrSfIndex - 1);
}
console.log('done matching corresponding timestamps');
console.log('done matching corresponding timestamps', intersectWmOrSfIndices);
return intersectWmOrSfIndices;
}
function filterWmStateForIme(wmState) {
// create and return a custom entry that just contains relevant properties
const displayContent = wmState.children[0];
const displayContent = wmState.root.children[0];
const controlTargetActualName = getActualFieldNameFromPossibilities(
'controlTarget', displayContent.proto);
const inputTargetActualName =
getActualFieldNameFromPossibilities('inputTarget', displayContent.proto);
const layeringTargetActualName = getActualFieldNameFromPossibilities(
'layeringTarget', displayContent.proto);
const isInputMethodWindowVisible = findInputMethodVisibility(displayContent);
return {
'kind': 'WM State Properties',
'name': wmState.name, // this is the ..d..h..m..s..ms timestamp
'name': wmState.name, // 'name' is a timestamp of ..d..h..m..s..ms format
'stableId': wmState.stableId,
'focusedApp': wmState.focusedApp,
'focusedWindow': wmState.focusedWindow,
'focusedActivity': wmState.focusedActivity,
'inputMethodControlTarget': displayContent.proto.inputMethodControlTarget,
'inputMethodInputTarget': displayContent.proto.inputMethodInputTarget,
'inputMethodTarget': displayContent.proto.inputMethodTarget,
'isInputMethodWindowVisible': isInputMethodWindowVisible,
'imeControlTarget': displayContent.proto[controlTargetActualName],
'imeInputTarget': displayContent.proto[inputTargetActualName],
'imeLayeringTarget': displayContent.proto[layeringTargetActualName],
'imeInsetsSourceProvider': displayContent.proto.imeInsetsSourceProvider,
'proto': wmState,
};
}
function getActualFieldNameFromPossibilities(wantedKey, protoObject) {
// for backwards compatibility purposes: find the actual name in the
// protoObject out of a list of possible names, as field names may change
const possibleNamesMap = {
// inputMethod...Target is legacy name, ime...Target is new name
'controlTarget': ['inputMethodControlTarget', 'imeControlTarget'],
'inputTarget': ['inputMethodInputTarget', 'imeInputTarget'],
'layeringTarget': ['inputMethodTarget', 'imeLayeringTarget'],
};
const possibleNames = possibleNamesMap[wantedKey];
const actualName =
Object.keys(protoObject).find((el) => possibleNames.includes(el));
return actualName;
}
function filterSfLayerForIme(sfLayer) {
const parentTaskOfImeContainer =
findParentTaskOfNode(sfLayer, 'ImeContainer');
@@ -175,19 +213,41 @@ function findParentTaskOfNode(curr, nodeName) {
return null;
}
function extractImeContainerFields(curr) {
function extractSfProperties(curr) {
const imeFields = extractImeFields(curr);
if (imeFields == null) {
return null;
}
return Object.assign({'name': curr.name, 'proto': curr}, imeFields);
// 'name' is a timestamp of ..d..h..m..s..ms format
}
function extractImeFields(curr) {
const isImeContainer = getFilter('ImeContainer');
if (isImeContainer(curr)) {
const imeContainer = findWindowOrLayerMatch(isImeContainer, curr);
if (imeContainer != null) {
const isInputMethodSurface = getFilter('InputMethod');
const inputMethodSurface =
findWindowOrLayerMatch(isInputMethodSurface, imeContainer);
return {
'screenBounds': curr.screenBounds,
'rect': curr.rect,
'zOrderRelativeOfId': curr.zOrderRelativeOfId,
'z': curr.z,
'imeContainer': imeContainer,
'inputMethodSurface': inputMethodSurface,
'screenBounds': inputMethodSurface.screenBounds,
'rect': inputMethodSurface.rect,
'isInputMethodSurfaceVisible': inputMethodSurface.isVisible,
'zOrderRelativeOfId': imeContainer.zOrderRelativeOfId,
'z': imeContainer.z,
};
}
// search for ImeContainer in children
return null;
}
function findWindowOrLayerMatch(filter, curr) {
if (filter(curr)) {
return curr;
}
for (const child of curr.children) {
const result = extractImeContainerFields(child);
const result = findWindowOrLayerMatch(filter, child);
if (result) {
return result;
}
@@ -195,4 +255,29 @@ function extractImeContainerFields(curr) {
return null;
}
function findInputMethodVisibility(windowOrLayer) {
const isInputMethod = getFilter('InputMethod');
const inputMethodWindowOrLayer =
findWindowOrLayerMatch(isInputMethod, windowOrLayer);
return inputMethodWindowOrLayer && inputMethodWindowOrLayer.isVisible;
}
function processImeAfterCombiningWmAndSfProperties(imeTraceFile) {
for (const imeEntry of imeTraceFile.data) {
if (imeEntry.wmProperties?.focusedWindow && imeEntry.sfProperties?.proto) {
const focusedWindowRgba = findFocusedWindowRgba(
imeEntry.wmProperties.focusedWindow, imeEntry.sfProperties.proto);
imeEntry.sfProperties.focusedWindowRgba = focusedWindowRgba;
}
}
}
function findFocusedWindowRgba(focusedWindow, sfLayer) {
const focusedWindowToken = focusedWindow.token;
console.log(focusedWindowToken);
const isFocusedWindow = getFilter(focusedWindowToken);
const focusedWindowLayer = findWindowOrLayerMatch(isFocusedWindow, sfLayer);
return focusedWindowLayer.color;
}
export {combineWmSfWithImeDataIfExisting};