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:
363
tools/winscope/spec/ImeProcessingSpec.js
Normal file
363
tools/winscope/spec/ImeProcessingSpec.js
Normal 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();
|
||||
});
|
||||
});
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||
|
||||
@@ -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(", ");
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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};
|
||||
|
||||
Reference in New Issue
Block a user