diff --git a/tools/winscope/adb_proxy/winscope_proxy.py b/tools/winscope/adb_proxy/winscope_proxy.py
index 5bfc531e2..8c16e9647 100755
--- a/tools/winscope/adb_proxy/winscope_proxy.py
+++ b/tools/winscope/adb_proxy/winscope_proxy.py
@@ -55,6 +55,14 @@ WINSCOPE_TOKEN_HEADER = "Winscope-Token"
# Location to save the proxy security token
WINSCOPE_TOKEN_LOCATION = os.path.expanduser('~/.config/winscope/.token')
+# Winscope traces extensions
+WINSCOPE_EXT = ".winscope"
+WINSCOPE_EXT_LEGACY = ".pb"
+WINSCOPE_EXTS = [WINSCOPE_EXT, WINSCOPE_EXT_LEGACY]
+
+# Winscope traces directory
+WINSCOPE_DIR = "/data/misc/wmtrace/"
+
# Max interval between the client keep-alive requests in seconds
KEEP_ALIVE_INTERVAL_S = 5
@@ -85,12 +93,29 @@ class FileMatcher:
matchingFiles = call_adb(
f"shell su root find {self.path} -name {self.matcher}", device_id)
+ log.debug("Found file %s", matchingFiles.split('\n')[:-1])
return matchingFiles.split('\n')[:-1]
def get_filetype(self):
return self.type
+class WinscopeFileMatcher(FileMatcher):
+ def __init__(self, path, matcher, filetype) -> None:
+ self.path = path
+ self.internal_matchers = list(map(lambda ext: FileMatcher(path, f'{matcher}{ext}', filetype),
+ WINSCOPE_EXTS))
+ self.type = filetype
+
+ def get_filepaths(self, device_id):
+ for matcher in self.internal_matchers:
+ files = matcher.get_filepaths(device_id)
+ if len(files) > 0:
+ return files
+ log.debug("No files found")
+ return []
+
+
class TraceTarget:
"""Defines a single parameter to trace.
@@ -111,51 +136,50 @@ class TraceTarget:
# Order of files matters as they will be expected in that order and decoded in that order
TRACE_TARGETS = {
"window_trace": TraceTarget(
- File("/data/misc/wmtrace/wm_trace.pb", "window_trace"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "wm_trace", "window_trace"),
'su root cmd window tracing start\necho "WM trace started."',
'su root cmd window tracing stop >/dev/null 2>&1'
),
"accessibility_trace": TraceTarget(
- File("/data/misc/a11ytrace/a11y_trace.pb", "accessibility_trace"),
+ WinscopeFileMatcher("/data/misc/a11ytrace", "a11y_trace", "accessibility_trace"),
'su root cmd accessibility start-trace\necho "Accessibility trace started."',
'su root cmd accessibility stop-trace >/dev/null 2>&1'
),
"layers_trace": TraceTarget(
- File("/data/misc/wmtrace/layers_trace.pb", "layers_trace"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "layers_trace", "layers_trace"),
'su root service call SurfaceFlinger 1025 i32 1\necho "SF trace started."',
'su root service call SurfaceFlinger 1025 i32 0 >/dev/null 2>&1'
),
"screen_recording": TraceTarget(
- File("/data/local/tmp/screen.winscope.mp4", "screen_recording"),
- 'screenrecord --bit-rate 8M /data/local/tmp/screen.winscope.mp4 >/dev/null 2>&1 &\necho "ScreenRecorder started."',
+ File(f'/data/local/tmp/screen.mp4', "screen_recording"),
+ f'screenrecord --bit-rate 8M /data/local/tmp/screen.mp4 >/dev/null 2>&1 &\necho "ScreenRecorder started."',
'pkill -l SIGINT screenrecord >/dev/null 2>&1'
),
"transaction": TraceTarget(
[
- File("/data/misc/wmtrace/transaction_trace.pb", "transactions"),
- FileMatcher("/data/misc/wmtrace/", "transaction_merges_*.pb",
- "transaction_merges"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "transaction_trace", "transactions"),
+ FileMatcher(WINSCOPE_DIR, f'transaction_merges_*', "transaction_merges"),
],
'su root service call SurfaceFlinger 1020 i32 1\necho "SF transactions recording started."',
'su root service call SurfaceFlinger 1020 i32 0 >/dev/null 2>&1'
),
"proto_log": TraceTarget(
- File("/data/misc/wmtrace/wm_log.pb", "proto_log"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "wm_log", "proto_log"),
'su root cmd window logging start\necho "WM logging started."',
'su root cmd window logging stop >/dev/null 2>&1'
),
"ime_trace_clients": TraceTarget(
- File("/data/misc/wmtrace/ime_trace_clients.pb", "ime_trace_clients"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "ime_trace_clients", "ime_trace_clients"),
'su root ime tracing start\necho "Clients IME trace started."',
'su root ime tracing stop >/dev/null 2>&1'
),
"ime_trace_service": TraceTarget(
- File("/data/misc/wmtrace/ime_trace_service.pb", "ime_trace_service"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "ime_trace_service", "ime_trace_service"),
'su root ime tracing start\necho "Service IME trace started."',
'su root ime tracing stop >/dev/null 2>&1'
),
"ime_trace_managerservice": TraceTarget(
- File("/data/misc/wmtrace/ime_trace_managerservice.pb", "ime_trace_managerservice"),
+ WinscopeFileMatcher(WINSCOPE_DIR, "ime_trace_managerservice", "ime_trace_managerservice"),
'su root ime tracing start\necho "ManagerService IME trace started."',
'su root ime tracing stop >/dev/null 2>&1'
),
@@ -204,12 +228,12 @@ class DumpTarget:
DUMP_TARGETS = {
"window_dump": DumpTarget(
- File("/data/local/tmp/wm_dump.pb", "window_dump"),
- 'su root dumpsys window --proto > /data/local/tmp/wm_dump.pb'
+ File(f'/data/local/tmp/wm_dump{WINSCOPE_EXT}', "window_dump"),
+ f'su root dumpsys window --proto > /data/local/tmp/wm_dump{WINSCOPE_EXT}'
),
"layers_dump": DumpTarget(
- File("/data/local/tmp/sf_dump.pb", "layers_dump"),
- 'su root dumpsys SurfaceFlinger --proto > /data/local/tmp/sf_dump.pb'
+ File(f'/data/local/tmp/sf_dump{WINSCOPE_EXT}', "layers_dump"),
+ f'su root dumpsys SurfaceFlinger --proto > /data/local/tmp/sf_dump{WINSCOPE_EXT}'
)
}
@@ -425,6 +449,9 @@ class FetchFilesEndpoint(DeviceRequestEndpoint):
buf = base64.encodebytes(tmp.read()).decode("utf-8")
file_buffers[file_type].append(buf)
+ if (len(file_buffers) == 0):
+ log.error("Proxy didn't find any file to fetch")
+
# server.send_header('X-Content-Type-Options', 'nosniff')
# add_standard_headers(server)
j = json.dumps(file_buffers)
diff --git a/tools/winscope/spec/DiffSpec.js b/tools/winscope/spec/DiffSpec.js
index 68dfa4e82..a0600a263 100644
--- a/tools/winscope/spec/DiffSpec.js
+++ b/tools/winscope/spec/DiffSpec.js
@@ -1,10 +1,24 @@
import { DiffGenerator, DiffType } from "../src/utils/diff.js";
import { Node, DiffNode, toPlainObject } from "./utils/tree.js";
+const treeOne = new Node({ id: 1 }, [
+ new Node({ id: 2 }, []),
+ new Node({ id: 3 }, []),
+ new Node({ id: 4 }, []),
+]);
+const treeTwo = new Node({ id: 1 }, [
+ new Node({ id: 2 }, []),
+ new Node({ id: 3 }, [
+ new Node({ id: 5 }, []),
+ ]),
+ new Node({ id: 4 }, []),
+]);
+
function checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree) {
const diffTree = new DiffGenerator(newTree)
.compareWith(oldTree)
.withUniqueNodeId(node => node.id)
+ .withModifiedCheck(() => false)
.generateDiffTree();
expect(diffTree).toEqual(expectedDiffTree);
@@ -12,25 +26,8 @@ function checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree) {
describe("DiffGenerator", () => {
it("can generate a simple add diff", () => {
- const oldTree = new Node({ id: 1 }, [
- new Node({ id: 2 }, []),
- new Node({ id: 3 }, []),
- new Node({ id: 4 }, []),
- ]);
-
- const newTree = new Node({ id: 1 }, [
- new Node({ id: 2 }, []),
- new Node({ id: 3 }, [
- new Node({ id: 5 }, []),
- ]),
- new Node({ id: 4 }, []),
- ]);
-
- const diffTree = new DiffGenerator(newTree)
- .compareWith(oldTree)
- .withUniqueNodeId(node => node.id)
- .withModifiedCheck(() => false)
- .generateDiffTree();
+ const oldTree = treeOne;
+ const newTree = treeTwo;
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
@@ -46,19 +43,8 @@ describe("DiffGenerator", () => {
});
it("can generate a simple delete diff", () => {
- const oldTree = new Node({ id: 1 }, [
- new Node({ id: 2 }, []),
- new Node({ id: 3 }, [
- new Node({ id: 5 }, []),
- ]),
- new Node({ id: 4 }, []),
- ]);
-
- const newTree = new Node({ id: 1 }, [
- new Node({ id: 2 }, []),
- new Node({ id: 3 }, []),
- new Node({ id: 4 }, []),
- ]);
+ const oldTree = treeTwo;
+ const newTree = treeOne;
const expectedDiffTree = toPlainObject(
new DiffNode({ id: 1 }, DiffType.NONE, [
@@ -74,13 +60,7 @@ describe("DiffGenerator", () => {
});
it("can generate a simple move diff", () => {
- const oldTree = new Node({ id: 1 }, [
- new Node({ id: 2 }, []),
- new Node({ id: 3 }, [
- new Node({ id: 5 }, []),
- ]),
- new Node({ id: 4 }, []),
- ]);
+ const oldTree = treeTwo;
const newTree = new Node({ id: 1 }, [
new Node({ id: 2 }, []),
@@ -264,4 +244,4 @@ describe("DiffGenerator", () => {
checkDiffTreeWithNoModifiedCheck(oldTree, newTree, expectedDiffTree);
});
-});
\ No newline at end of file
+});
diff --git a/tools/winscope/spec/ObjectTransformerSpec.js b/tools/winscope/spec/ObjectTransformerSpec.js
index 4d84fd951..ab2a4c7c2 100644
--- a/tools/winscope/spec/ObjectTransformerSpec.js
+++ b/tools/winscope/spec/ObjectTransformerSpec.js
@@ -1,32 +1,6 @@
import { DiffType } from "../src/utils/diff.js";
import { ObjectTransformer } from "../src/transform.js";
-import { Node, DiffNode, toPlainObject } from "./utils/tree.js";
-
-class ObjNode extends Node {
- constructor(name, children, combined) {
- const nodeDef = {
- kind: '',
- name: name,
- };
- if (combined) {
- nodeDef.combined = true;
- }
- super(nodeDef, children);
- }
-}
-
-class ObjDiffNode extends DiffNode {
- constructor(name, diffType, children, combined) {
- const nodeDef = {
- kind: '',
- name: name,
- };
- if (combined) {
- nodeDef.combined = true;
- }
- super(nodeDef, diffType, children);
- }
-}
+import { ObjNode, ObjDiffNode, toPlainObject } from "./utils/tree.js";
describe("ObjectTransformer", () => {
it("can transform a simple object", () => {
@@ -46,19 +20,19 @@ describe("ObjectTransformer", () => {
const expectedTransformedObj = toPlainObject(
new ObjNode('root', [
new ObjNode('obj', [
- new ObjNode('string: string', [], true),
- new ObjNode('number: 3', [], true),
- ]),
+ new ObjNode('string: string', [], true, 'root.obj.string'),
+ new ObjNode('number: 3', [], true, 'root.obj.number'),
+ ], undefined, 'root.obj'),
new ObjNode('array', [
new ObjNode('0', [
- new ObjNode('nested: item', [], true),
- ]),
- new ObjNode("1: two", [], true),
- ]),
- ])
+ new ObjNode('nested: item', [], true, 'root.array.0.nested'),
+ ], undefined, 'root.array.0'),
+ new ObjNode("1: two", [], true, 'root.array.1'),
+ ], undefined, 'root.array'),
+ ], undefined, 'root')
);
- const transformedObj = new ObjectTransformer(obj, 'root')
+ const transformedObj = new ObjectTransformer(obj, 'root', 'root')
.setOptions({ formatter: () => { } })
.transform();
@@ -75,12 +49,12 @@ describe("ObjectTransformer", () => {
const expectedTransformedObj = toPlainObject(
new ObjNode('root', [
new ObjNode('obj', [
- new ObjNode('null: null', [], true),
- ]),
- ])
+ new ObjNode('null: null', [], true, 'root.obj.null'),
+ ], undefined, 'root.obj'),
+ ], undefined, 'root')
);
- const transformedObj = new ObjectTransformer(obj, 'root')
+ const transformedObj = new ObjectTransformer(obj, 'root', 'root')
.setOptions({ formatter: () => { } })
.transform();
@@ -106,14 +80,14 @@ describe("ObjectTransformer", () => {
const expectedTransformedObj = toPlainObject(
new ObjDiffNode('root', DiffType.NONE, [
new ObjDiffNode('a', DiffType.NONE, [
- new ObjDiffNode('b: 1', DiffType.NONE, [], true),
- new ObjDiffNode('d: 3', DiffType.ADDED, [], true),
- ]),
- new ObjDiffNode('c: 2', DiffType.NONE, [], true),
- ])
+ new ObjDiffNode('b: 1', DiffType.NONE, [], true, 'root.a.b'),
+ new ObjDiffNode('d: 3', DiffType.ADDED, [], true, 'root.a.d'),
+ ], false, 'root.a'),
+ new ObjDiffNode('c: 2', DiffType.NONE, [], true, 'root.c'),
+ ], false, 'root')
);
- const transformedObj = new ObjectTransformer(newObj, 'root')
+ const transformedObj = new ObjectTransformer(newObj, 'root', 'root')
.setOptions({ formatter: () => { } })
.withDiff(oldObj)
.transform();
@@ -133,13 +107,13 @@ describe("ObjectTransformer", () => {
const expectedTransformedObj = toPlainObject(
new ObjDiffNode('root', DiffType.NONE, [
new ObjDiffNode('a', DiffType.NONE, [
- new ObjDiffNode('1', DiffType.ADDED, []),
- new ObjDiffNode('null', DiffType.DELETED, []),
- ]),
- ])
+ new ObjDiffNode('1', DiffType.ADDED, [], false, 'root.a.1'),
+ new ObjDiffNode('null', DiffType.DELETED, [], false, 'root.a.null'),
+ ], false, 'root.a'),
+ ], false, 'root')
);
- const transformedObj = new ObjectTransformer(newObj, 'root')
+ const transformedObj = new ObjectTransformer(newObj, 'root', 'root')
.setOptions({ formatter: () => { } })
.withDiff(oldObj)
.transform();
@@ -166,19 +140,19 @@ describe("ObjectTransformer", () => {
new ObjDiffNode('root', DiffType.NONE, [
new ObjDiffNode('a', DiffType.NONE, [
new ObjDiffNode('b', DiffType.NONE, [
- new ObjDiffNode('1', DiffType.ADDED, []),
- new ObjDiffNode('null', DiffType.DELETED, []),
- ]),
- ]),
- new ObjDiffNode('c: 2', DiffType.NONE, [], true),
- ])
+ new ObjDiffNode('1', DiffType.ADDED, [], false, 'root.a.b.1'),
+ new ObjDiffNode('null', DiffType.DELETED, [], false, 'root.a.b.null'),
+ ], false, 'root.a.b'),
+ ], false, 'root.a'),
+ new ObjDiffNode('c: 2', DiffType.NONE, [], true, 'root.c'),
+ ], false, 'root')
);
- const transformedObj = new ObjectTransformer(newObj, 'root')
+ const transformedObj = new ObjectTransformer(newObj, 'root', 'root')
.setOptions({ formatter: () => { } })
.withDiff(oldObj)
.transform();
expect(transformedObj).toEqual(expectedTransformedObj);
});
-});
\ No newline at end of file
+});
diff --git a/tools/winscope/spec/ProtoTransformSpec.js b/tools/winscope/spec/ProtoTransformSpec.js
index 8db736b6e..7c554412f 100644
--- a/tools/winscope/spec/ProtoTransformSpec.js
+++ b/tools/winscope/spec/ProtoTransformSpec.js
@@ -1,25 +1,28 @@
-import { detectAndDecode, decodeAndTransformProto, FILE_TYPES } from '../src/decode';
+import { decodeAndTransformProto, FILE_TYPES, FILE_DECODERS } from '../src/decode';
import fs from 'fs';
import path from 'path';
-
-const layers_traces = [
- require('./traces/layers_trace/layers_trace_emptyregion.pb'),
- require('./traces/layers_trace/layers_trace_invalid_layer_visibility.pb'),
- require('./traces/layers_trace/layers_trace_orphanlayers.pb'),
- require('./traces/layers_trace/layers_trace_root.pb'),
- require('./traces/layers_trace/layers_trace_root_aosp.pb'),
-];
+import { expectedEntries, expectedLayers, layers_traces } from './traces/ExpectedTraces';
describe("Proto Transformations", () => {
it("can transform surface flinger traces", () => {
- for (const trace of layers_traces) {
- fs.readFileSync(path.resolve(__dirname, trace));
- const traceBuffer = fs.readFileSync(path.resolve(__dirname, trace));
+ for (var i = 0; i < layers_traces.length; i++) {
+ const trace = layers_traces[i];
+ const buffer = new Uint8Array(fs.readFileSync(path.resolve(__dirname, trace)));
+ const data = decodeAndTransformProto(buffer, FILE_DECODERS[FILE_TYPES.SURFACE_FLINGER_TRACE].decoderParams, true);
- const buffer = new Uint8Array(traceBuffer);
- const data = decodeAndTransformProto(buffer, FILE_TYPES.layers_trace, true);
+ // use final entry as this determines if there was any error in previous entry parsing
+ const transformedEntry = data.entries[data.entries.length-1];
+ const expectedEntry = expectedEntries[i];
+ for (const property in expectedEntry) {
+ expect(transformedEntry[property]).toEqual(expectedEntry[property]);
+ }
- expect(true).toBe(true);
+ // check final flattened layer
+ const transformedLayer = transformedEntry.flattenedLayers[transformedEntry.flattenedLayers.length-1];
+ const expectedLayer = expectedLayers[i];
+ for (const property in expectedLayer) {
+ expect(transformedLayer[property]).toEqual(expectedLayer[property]);
+ }
}
});
-});
\ No newline at end of file
+});
diff --git a/tools/winscope/spec/TagErrorSpec.js b/tools/winscope/spec/TagErrorSpec.js
new file mode 100644
index 000000000..e8919a0e9
--- /dev/null
+++ b/tools/winscope/spec/TagErrorSpec.js
@@ -0,0 +1,50 @@
+import { decodeAndTransformProto, FILE_TYPES, FILE_DECODERS } from '../src/decode';
+import Tag from '../src/flickerlib/tags/Tag';
+import Error from '../src/flickerlib/errors/Error';
+import fs from 'fs';
+import path from 'path';
+
+const tagTrace = '../spec/traces/tag_trace.winscope';
+const errorTrace = '../spec/traces/error_trace.winscope';
+
+describe("Tag Transformation", () => {
+ it("can transform tag traces", () => {
+ const buffer = new Uint8Array(fs.readFileSync(path.resolve(__dirname, tagTrace)));
+
+ const data = decodeAndTransformProto(buffer, FILE_DECODERS[FILE_TYPES.TAG_TRACE].decoderParams, true);
+
+ expect(data.entries[0].timestamp.toString()).toEqual('159979677861');
+ expect(data.entries[1].timestamp.toString()).toEqual('161268519083');
+ expect(data.entries[2].timestamp.toString()).toEqual('161126718496');
+ expect(data.entries[3].timestamp.toString()).toEqual('161613497398');
+ expect(data.entries[4].timestamp.toString()).toEqual('161227062777');
+ expect(data.entries[5].timestamp.toString()).toEqual('161268519083');
+ expect(data.entries[6].timestamp.toString()).toEqual('161825945076');
+ expect(data.entries[7].timestamp.toString()).toEqual('162261072567');
+
+ expect(data.entries[0].tags).toEqual([new Tag(12345,"PIP_ENTER",true,1,"",0)]);
+ expect(data.entries[1].tags).toEqual([new Tag(12345,"PIP_ENTER",false,2,"",2)]);
+ expect(data.entries[2].tags).toEqual([new Tag(67890,"ROTATION",true,3,"",3)]);
+ expect(data.entries[3].tags).toEqual([new Tag(67890,"ROTATION",false,4,"",4)]);
+ expect(data.entries[4].tags).toEqual([new Tag(9876,"PIP_EXIT",true,5,"",5)]);
+ expect(data.entries[5].tags).toEqual([new Tag(9876,"PIP_EXIT",false,6,"",6)]);
+ expect(data.entries[6].tags).toEqual([new Tag(54321,"IME_APPEAR",true,7,"",7)]);
+ expect(data.entries[7].tags).toEqual([new Tag(54321,"IME_APPEAR",false,8,"",8)]);
+ })
+});
+
+describe("Error Transformation", () => {
+ it("can transform error traces", () => {
+ const buffer = new Uint8Array(fs.readFileSync(path.resolve(__dirname, errorTrace)));
+
+ const data = decodeAndTransformProto(buffer, FILE_DECODERS[FILE_TYPES.ERROR_TRACE].decoderParams, true);
+
+ expect(data.entries[0].timestamp.toString()).toEqual('161401263106');
+ expect(data.entries[1].timestamp.toString()).toEqual('161126718496');
+ expect(data.entries[2].timestamp.toString()).toEqual('162261072567');
+
+ expect(data.entries[0].errors).toEqual([new Error("","",33,"",33)]);
+ expect(data.entries[1].errors).toEqual([new Error("","",66,"",66)]);
+ expect(data.entries[2].errors).toEqual([new Error("","",99,"",99)]);
+ })
+});
\ No newline at end of file
diff --git a/tools/winscope/spec/traces/ExpectedTraces.js b/tools/winscope/spec/traces/ExpectedTraces.js
new file mode 100644
index 000000000..1f01de07e
--- /dev/null
+++ b/tools/winscope/spec/traces/ExpectedTraces.js
@@ -0,0 +1,492 @@
+import { Buffer, RectF, Transform, Matrix, Color, Rect, Region } from '../../src/flickerlib/common.js';
+import { VISIBLE_CHIP } from '../../src/flickerlib/treeview/Chips';
+
+const standardTransform = new Transform(0, new Matrix(1, 0, 0, 0, 1, 0));
+const standardRect = new Rect(0, 0, 0, 0);
+const standardColor = new Color(0, 0, 0, 1);
+const standardCrop = new Rect(0, 0, -1, -1);
+
+const expectedEmptyRegionLayer = {
+ backgroundBlurRadius: 0,
+ chips: [],
+ cornerRadius: 0,
+ effectiveScalingMode: 0,
+ hwcCompositionType: "INVALID",
+ id: 580,
+ isOpaque: false,
+ isRelativeOf: false,
+ kind: "580",
+ name: "SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+ shadowRadius: 0,
+ shortName: "SurfaceView - com.android.(...).Main#0",
+ type: "BufferLayer",
+ z: -1,
+ zOrderRelativeOf: null,
+ parentId: 579,
+ activeBuffer: new Buffer(1440, 2614, 1472, 1),
+ bufferTransform: standardTransform,
+ color: new Color(0, 0, 0, 0.0069580078125),
+ crop: standardCrop,
+ hwcFrame: standardRect,
+ screenBounds: new RectF(37, 43, 146, 152),
+ transform: new Transform(0, new Matrix(1, 0, 37.37078094482422, 0, 1, -3.5995326042175293)),
+ visibleRegion: new Region([new Rect(37, 43, 146, 152)]),
+};
+const emptyRegionProto = {
+ 2: "\nparent=0\ntype=BufferLayer\nname=Display Root#0",
+ 3: "\nparent=0\ntype=BufferLayer\nname=Display Overlays#0",
+ 4: "\nparent=2\ntype=BufferLayer\nname=mBelowAppWindowsContainers#0",
+ 5: "\nparent=2\ntype=BufferLayer\nname=com.android.server.wm.DisplayContent$TaskStackContainers@193aa46#0",
+ 6: "\nparent=5\ntype=BufferLayer\nname=animationLayer#0",
+ 7: "\nparent=5\ntype=BufferLayer\nname=splitScreenDividerAnchor#0",
+ 8: "\nparent=2\ntype=BufferLayer\nname=mAboveAppWindowsContainers#0",
+ 9: "\nparent=2\ntype=BufferLayer\nname=mImeWindowsContainers#0",
+ 10: "\nparent=5\ntype=BufferLayer\nname=Stack=0#0",
+ 11: "\nparent=10\ntype=ColorLayer\nname=animation background stackId=0#0",
+ 12: "\nparent=9\ntype=BufferLayer\nname=WindowToken{f81e7fc android.os.Binder@7c880ef}#0",
+ 13: "\nparent=4\ntype=BufferLayer\nname=WallpaperWindowToken{3756850 token=android.os.Binder@25b3e13}#0",
+ 18: "\nparent=13\ntype=BufferLayer\nname=fd46a8e com.breel.wallpapers.dioramas.lagos.LagosWallpaperService#0",
+ 19: "\nparent=18\ntype=BufferLayer\nname=com.breel.wallpapers.dioramas.lagos.LagosWallpaperService#0",
+ 20: "\nparent=8\ntype=BufferLayer\nname=WindowToken{fc1aa98 android.os.BinderProxy@3517c7b}#0",
+ 21: "\nparent=20\ntype=BufferLayer\nname=10022f1 DockedStackDivider#0",
+ 22: "\nparent=8\ntype=BufferLayer\nname=WindowToken{49a6772 android.os.BinderProxy@7ba1c7d}#0",
+ 23: "\nparent=22\ntype=BufferLayer\nname=56ef7c3 AssistPreviewPanel#0",
+ 24: "\nparent=8\ntype=BufferLayer\nname=WindowToken{35f7d5c android.os.BinderProxy@8b38fcf}#0",
+ 25: "\nparent=24\ntype=BufferLayer\nname=9029865 NavigationBar#0",
+ 26: "\nparent=8\ntype=BufferLayer\nname=WindowToken{a9a69ab android.os.BinderProxy@f64ffa}#0",
+ 27: "\nparent=26\ntype=BufferLayer\nname=5334808 StatusBar#0",
+ 28: "\nparent=8\ntype=BufferLayer\nname=WindowToken{a63ca37 android.os.BinderProxy@435eb36}#0",
+ 29: "\nparent=28\ntype=BufferLayer\nname=1a40ba4 ScreenDecorOverlay#0",
+ 30: "\nparent=8\ntype=BufferLayer\nname=WindowToken{4ed84c2 android.os.BinderProxy@33d1d0d}#0",
+ 31: "\nparent=30\ntype=BufferLayer\nname=7a0d2d3 ScreenDecorOverlayBottom#0",
+ 32: "\nparent=25\ntype=BufferLayer\nname=NavigationBar#0",
+ 33: "\nparent=27\ntype=BufferLayer\nname=StatusBar#0",
+ 34: "\nparent=29\ntype=BufferLayer\nname=ScreenDecorOverlay#0",
+ 35: "\nparent=31\ntype=BufferLayer\nname=ScreenDecorOverlayBottom#0",
+ 36: "\nparent=10\ntype=BufferLayer\nname=Task=239#0",
+ 37: "\nparent=632\ntype=BufferLayer\nname=AppWindowToken{188ce21 token=Token{824488 ActivityRecord{b0d882b u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t239}}}#0",
+ 38: "\nparent=37\ntype=BufferLayer\nname=9f6e33d com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 44: "\nparent=37\ntype=BufferLayer\nname=81a00fc com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 88: "\nparent=5\ntype=BufferLayer\nname=Stack=2#0",
+ 89: "\nparent=88\ntype=ColorLayer\nname=animation background stackId=2#0",
+ 90: "\nparent=88\ntype=BufferLayer\nname=Task=241#0",
+ 91: "\nparent=633\ntype=BufferLayer\nname=AppWindowToken{a9f5144 token=Token{f102257 ActivityRecord{3a0fd6 u0 com.android.chrome/com.google.android.apps.chrome.Main t241}}}#0",
+ 96: "\nparent=91\ntype=BufferLayer\nname=87e310e com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 574: "\nparent=8\ntype=BufferLayer\nname=WindowToken{37eed7d android.os.Binder@6e217d4}#0",
+ 579: "\nparent=96\ntype=BufferLayer\nname=com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 580: "\nparent=579\ntype=BufferLayer\nname=SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 581: "\nparent=579\ntype=ColorLayer\nname=Background for -SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 583: "\nparent=44\ntype=BufferLayer\nname=com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 629: "\nparent=38\ntype=BufferLayer\nname=com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#2",
+ 632: "\nparent=6\ntype=BufferLayer\nname=Surface(name=AppWindowToken{188ce21 token=Token{824488 ActivityRecord{b0d882b u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t239}}})/@0x90c9c46 - animation-leash#1",
+ 633: "\nparent=6\ntype=BufferLayer\nname=Surface(name=AppWindowToken{a9f5144 token=Token{f102257 ActivityRecord{3a0fd6 u0 com.android.chrome/com.google.android.apps.chrome.Main t241}}})/@0xd9b9374 - animation-leash#1"
+};
+const expectedEmptyRegion = {
+ chips: [],
+ proto: emptyRegionProto,
+ hwcBlob: "",
+ isVisible: true,
+ kind: "entry",
+ rects: [],
+ shortName: "0d0h38m28s521ms",
+ timestampMs: "2308521813510",
+ where: "",
+ name: "0d0h38m28s521ms",
+ stableId: "LayerTraceEntry",
+ visibleLayers: [],
+};
+
+const expectedInvalidLayerVisibilityLayer = {
+ backgroundBlurRadius: 0,
+ chips: [],
+ cornerRadius: 0,
+ effectiveScalingMode: 0,
+ hwcCompositionType: "INVALID",
+ id: 1536,
+ isOpaque: false,
+ isRelativeOf: false,
+ kind: "1536",
+ name: "com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#2",
+ shadowRadius: 0,
+ shortName: "com.google.(...).NexusLauncherActivity#2",
+ type: "BufferLayer",
+ z: 0,
+ zOrderRelativeOf: null,
+ parentId: 1535,
+ stableId: "BufferLayer 1536 com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#2",
+ activeBuffer: new Buffer(1440, 2880, 1472, 1),
+ bufferTransform: standardTransform,
+ color: new Color(-1, -1, -1, 0),
+ hwcFrame: standardRect,
+ transform: standardTransform,
+ visibleRegion: new Region([standardRect]),
+};
+const invalidLayerVisibilityProto = {
+ 2: "\nparent=0\ntype=BufferLayer\nname=Display Root#0",
+ 3: "\nparent=0\ntype=BufferLayer\nname=Display Overlays#0",
+ 4: "\nparent=2\ntype=BufferLayer\nname=mBelowAppWindowsContainers#0",
+ 5: "\nparent=2\ntype=BufferLayer\nname=com.android.server.wm.DisplayContent$TaskStackContainers@4270eb4#0",
+ 6: "\nparent=5\ntype=BufferLayer\nname=animationLayer#0",
+ 7: "\nparent=5\ntype=BufferLayer\nname=boostedAnimationLayer#0",
+ 8: "\nparent=5\ntype=BufferLayer\nname=homeAnimationLayer#0",
+ 9: "\nparent=5\ntype=BufferLayer\nname=splitScreenDividerAnchor#0",
+ 10: "\nparent=2\ntype=BufferLayer\nname=mAboveAppWindowsContainers#0",
+ 11: "\nparent=2\ntype=BufferLayer\nname=mImeWindowsContainers#0",
+ 12: "\nparent=5\ntype=BufferLayer\nname=Stack=0#0",
+ 13: "\nparent=12\ntype=ColorLayer\nname=animation background stackId=0#0",
+ 14: "\nparent=11\ntype=BufferLayer\nname=WindowToken{268fcff android.os.Binder@6688c1e}#0",
+ 15: "\nparent=4\ntype=BufferLayer\nname=WallpaperWindowToken{6572e20 token=android.os.Binder@9543923}#0",
+ 20: "\nparent=15\ntype=BufferLayer\nname=5e2e96f com.breel.wallpapers.dioramas.lagos.LagosWallpaperService#0",
+ 21: "\nparent=20\ntype=BufferLayer\nname=com.breel.wallpapers.dioramas.lagos.LagosWallpaperService#0",
+ 26: "\nparent=10\ntype=BufferLayer\nname=WindowToken{68e3f31 android.os.BinderProxy@f018fd8}#0",
+ 27: "\nparent=26\ntype=BufferLayer\nname=2b80616 NavigationBar#0",
+ 28: "\nparent=10\ntype=BufferLayer\nname=WindowToken{4e20cae android.os.BinderProxy@9086129}#0",
+ 29: "\nparent=28\ntype=BufferLayer\nname=b09a4f StatusBar#0",
+ 30: "\nparent=3\ntype=BufferLayer\nname=WindowToken{501e3b8 android.os.BinderProxy@238661b}#0",
+ 31: "\nparent=30\ntype=BufferLayer\nname=d803591 ScreenDecorOverlay#0",
+ 32: "\nparent=3\ntype=BufferLayer\nname=WindowToken{56d48f7 android.os.BinderProxy@f0f2cf6}#0",
+ 33: "\nparent=32\ntype=BufferLayer\nname=1cd8364 ScreenDecorOverlayBottom#0",
+ 35: "\nparent=29\ntype=BufferLayer\nname=StatusBar#0",
+ 36: "\nparent=31\ntype=BufferLayer\nname=ScreenDecorOverlay#0",
+ 37: "\nparent=33\ntype=BufferLayer\nname=ScreenDecorOverlayBottom#0",
+ 38: "\nparent=12\ntype=BufferLayer\nname=Task=2#0",
+ 39: "\nparent=38\ntype=BufferLayer\nname=AppWindowToken{215b919 token=Token{104a060 ActivityRecord{7e30c63 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}}}#0",
+ 821: "\nparent=14\ntype=BufferLayer\nname=5c937c8 InputMethod#0",
+ 1078: "\nparent=10\ntype=BufferLayer\nname=WindowToken{7dc6283 android.os.BinderProxy@f83c532}#0",
+ 1079: "\nparent=1078\ntype=BufferLayer\nname=32c0c00 AssistPreviewPanel#0",
+ 1080: "\nparent=10\ntype=BufferLayer\nname=WindowToken{9f8a3df android.os.BinderProxy@825027e}#0",
+ 1081: "\nparent=1080\ntype=BufferLayer\nname=26d9efb DockedStackDivider#0",
+ 1403: "\nparent=10\ntype=BufferLayer\nname=WindowToken{dedcfff android.os.Binder@a80cb1e}#0",
+ 1447: "\nparent=39\ntype=BufferLayer\nname=39ca531 com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 1454: "\nparent=27\ntype=BufferLayer\nname=NavigationBar#0",
+ 1502: "\nparent=10\ntype=BufferLayer\nname=WindowToken{3ea357b android.os.Binder@6d9a90a}#0",
+ 1505: "\nparent=1518\ntype=BufferLayer\nname=Task=623#0",
+ 1506: "\nparent=1505\ntype=BufferLayer\nname=AppWindowToken{6deed44 token=Token{45cae57 ActivityRecord{7f14bd6 u0 com.android.server.wm.flicker.testapp/.SimpleActivity t623}}}#0",
+ 1518: "\nparent=5\ntype=BufferLayer\nname=Stack=51#0",
+ 1519: "\nparent=1518\ntype=ColorLayer\nname=animation background stackId=51#0",
+ 1521: "\nparent=1506\ntype=BufferLayer\nname=496d52e com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.SimpleActivity#0",
+ 1534: "\nparent=1447\ntype=BufferLayer\nname=com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 1535: "\nparent=39\ntype=BufferLayer\nname=e280197 com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 1536: "\nparent=1535\ntype=BufferLayer\nname=com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#2",
+};
+const expectedInvalidLayerVisibility = {
+ chips: [],
+ proto: invalidLayerVisibilityProto,
+ hwcBlob: "",
+ isVisible: true,
+ kind: "entry",
+ rects: [],
+ shortName: "2d22h13m17s233ms",
+ timestampMs: "252797233543024",
+ where: "",
+ name: "2d22h13m17s233ms",
+ stableId: "LayerTraceEntry",
+ visibleLayers: [],
+};
+
+const expectedOrphanLayersLayer = {
+ backgroundBlurRadius: 0,
+ chips: [],
+ cornerRadius: 0,
+ effectiveScalingMode: 0,
+ hwcCompositionType: "INVALID",
+ id: 1012,
+ isOpaque: true,
+ isRelativeOf: false,
+ kind: "1012",
+ name: "SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+ shadowRadius: 0,
+ shortName: "SurfaceView - com.android.(...).Main#0",
+ type: "BufferLayer",
+ z: -1,
+ zOrderRelativeOf: null,
+ parentId: 1011,
+ stableId: "BufferLayer 1012 SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+ activeBuffer: new Buffer(1440, 2614, 1472, 1),
+ bufferTransform: standardTransform,
+ color: standardColor,
+ crop: standardCrop,
+ hwcFrame: standardRect,
+ screenBounds: new RectF(0, 98, 1440, 2712),
+ transform: new Transform(0, new Matrix(1, 0, 0, 0, 1, 98)),
+ visibleRegion: new Region([new Rect(0, 98, 1440, 2712)]),
+};
+const expectedOrphanLayersProto = {
+ 2: "\nparent=0\ntype=BufferLayer\nname=Display Root#0",
+ 3: "\nparent=0\ntype=BufferLayer\nname=Display Overlays#0",
+ 4: "\nparent=2\ntype=BufferLayer\nname=mBelowAppWindowsContainers#0",
+ 5: "\nparent=2\ntype=BufferLayer\nname=com.android.server.wm.DisplayContent$TaskStackContainers@e7dd520#0",
+ 6: "\nparent=5\ntype=BufferLayer\nname=animationLayer#0",
+ 7: "\nparent=5\ntype=BufferLayer\nname=splitScreenDividerAnchor#0",
+ 8: "\nparent=2\ntype=BufferLayer\nname=mAboveAppWindowsContainers#0",
+ 9: "\nparent=2\ntype=BufferLayer\nname=mImeWindowsContainers#0",
+ 10: "\nparent=5\ntype=BufferLayer\nname=Stack=0#0",
+ 11: "\nparent=10\ntype=ColorLayer\nname=animation background stackId=0#0",
+ 12: "\nparent=9\ntype=BufferLayer\nname=WindowToken{1350b6f android.os.Binder@d1b0e4e}#0",
+ 13: "\nparent=4\ntype=BufferLayer\nname=WallpaperWindowToken{4537182 token=android.os.Binder@d87c4cd}#0",
+ 18: "\nparent=13\ntype=BufferLayer\nname=8d26107 com.breel.wallpapers.dioramas.lagos.LagosWallpaperService#0",
+ 19: "\nparent=18\ntype=BufferLayer\nname=com.breel.wallpapers.dioramas.lagos.LagosWallpaperService#0",
+ 20: "\nparent=8\ntype=BufferLayer\nname=WindowToken{fba948d android.os.BinderProxy@756b124}#0",
+ 21: "\nparent=20\ntype=BufferLayer\nname=dc26642 DockedStackDivider#0",
+ 22: "\nparent=8\ntype=BufferLayer\nname=WindowToken{45663b4 android.os.BinderProxy@5273887}#0",
+ 23: "\nparent=22\ntype=BufferLayer\nname=c617bdd AssistPreviewPanel#0",
+ 24: "\nparent=8\ntype=BufferLayer\nname=WindowToken{ef90888 android.os.BinderProxy@9d4dc2b}#0",
+ 25: "\nparent=24\ntype=BufferLayer\nname=1d24221 NavigationBar#0",
+ 26: "\nparent=8\ntype=BufferLayer\nname=WindowToken{6b1dca9 android.os.BinderProxy@a53d830}#0",
+ 27: "\nparent=26\ntype=BufferLayer\nname=eaca22e StatusBar#0",
+ 28: "\nparent=8\ntype=BufferLayer\nname=WindowToken{72e584c android.os.BinderProxy@3ba407f}#0",
+ 29: "\nparent=28\ntype=BufferLayer\nname=46af095 ScreenDecorOverlay#0",
+ 30: "\nparent=8\ntype=BufferLayer\nname=WindowToken{bc659b android.os.BinderProxy@f1405aa}#0",
+ 31: "\nparent=30\ntype=BufferLayer\nname=80ead38 ScreenDecorOverlayBottom#0",
+ 33: "\nparent=27\ntype=BufferLayer\nname=StatusBar#0",
+ 34: "\nparent=29\ntype=BufferLayer\nname=ScreenDecorOverlay#0",
+ 35: "\nparent=31\ntype=BufferLayer\nname=ScreenDecorOverlayBottom#0",
+ 36: "\nparent=10\ntype=BufferLayer\nname=Task=2#0",
+ 37: "\nparent=36\ntype=BufferLayer\nname=AppWindowToken{5162f77 token=Token{ac99d76 ActivityRecord{7749795 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t2}}}#0",
+ 38: "\nparent=37\ntype=BufferLayer\nname=2c19e73 com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 41: "\nparent=25\ntype=BufferLayer\nname=NavigationBar#1",
+ 43: "\nparent=37\ntype=BufferLayer\nname=2f0c80b com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 46: "\nparent=5\ntype=BufferLayer\nname=Stack=1#0",
+ 47: "\nparent=46\ntype=ColorLayer\nname=animation background stackId=1#0",
+ 48: "\nparent=46\ntype=BufferLayer\nname=Task=89#0",
+ 49: "\nparent=48\ntype=BufferLayer\nname=AppWindowToken{1d514da token=Token{d36fe85 ActivityRecord{e0ec0ef u0 com.android.chrome/com.google.android.apps.chrome.Main t89}}}#0",
+ 54: "\nparent=49\ntype=BufferLayer\nname=8ae6e06 com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 607: "\nparent=5\ntype=BufferLayer\nname=Stack=9#0",
+ 608: "\nparent=607\ntype=ColorLayer\nname=animation background stackId=9#0",
+ 609: "\nparent=607\ntype=BufferLayer\nname=Task=97#0",
+ 615: "\nparent=609\ntype=BufferLayer\nname=AppWindowToken{28730c9 token=Token{4d768d0 ActivityRecord{faf093 u0 com.google.android.gm/.welcome.WelcomeTourActivity t97}}}#0",
+ 616: "\nparent=615\ntype=BufferLayer\nname=44e6e5c com.google.android.gm/com.google.android.gm.welcome.WelcomeTourActivity#0",
+ 679: "\nparent=12\ntype=BufferLayer\nname=2d0b1e4 InputMethod#0",
+ 993: "\nparent=8\ntype=BufferLayer\nname=WindowToken{e425e58 android.os.Binder@6d9a73b}#0",
+ 1011: "\nparent=54\ntype=BufferLayer\nname=com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 1012: "\nparent=1011\ntype=BufferLayer\nname=SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+ 1013: "\nparent=1011\ntype=ColorLayer\nname=Background for -SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0",
+};
+const expectedOrphanLayers = {
+ chips: [],
+ proto: expectedOrphanLayersProto,
+ hwcBlob: "",
+ isVisible: true,
+ kind: "entry",
+ rects: [],
+ shortName: "3d23h30m9s820ms",
+ timestampMs: "343809820196384",
+ where: "",
+ name: "3d23h30m9s820ms",
+ stableId: "LayerTraceEntry",
+ visibleLayers: [],
+};
+
+const expectedRootLayer = {
+ backgroundBlurRadius: 0,
+ cornerRadius: 0,
+ effectiveScalingMode: 0,
+ hwcCompositionType: "INVALID",
+ id: 12545,
+ isOpaque: true,
+ isRelativeOf: false,
+ kind: "12545",
+ name: "com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.SimpleActivity#0",
+ shadowRadius: 0,
+ shortName: "com.android.(...).SimpleActivity#0",
+ type: "BufferQueueLayer",
+ z: 0,
+ zOrderRelativeOf: null,
+ parentId: 12541,
+ stableId: "BufferQueueLayer 12545 com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.SimpleActivity#0",
+ activeBuffer: new Buffer(1440, 2960, 1472, 1),
+ chips: [VISIBLE_CHIP],
+ bufferTransform: standardTransform,
+ color: standardColor,
+ crop: new Rect(0, 0, 1440, 2960),
+ hwcFrame: standardRect,
+ screenBounds: new RectF(0, 0, 1440, 2960),
+ sourceBounds: new RectF(0, 0, 1440, 2960),
+ transform: standardTransform,
+ visibleRegion: new Region([new Rect(0, 0, 1440, 2960)]),
+};
+const expectedRootProto = {
+ 2: "\nparent=-1\ntype=ContainerLayer\nname=Root#0",
+ 3: "\nparent=2\ntype=ContainerLayer\nname=mWindowContainers#0",
+ 4: "\nparent=2\ntype=ContainerLayer\nname=mOverlayContainers#0",
+ 5: "\nparent=3\ntype=ContainerLayer\nname=mBelowAppWindowsContainers#0",
+ 6: "\nparent=3\ntype=ContainerLayer\nname=com.android.server.wm.DisplayContent$TaskContainers@708b672#0",
+ 7: "\nparent=6\ntype=ContainerLayer\nname=animationLayer#0",
+ 8: "\nparent=6\ntype=ContainerLayer\nname=boostedAnimationLayer#0",
+ 9: "\nparent=6\ntype=ContainerLayer\nname=homeAnimationLayer#0",
+ 10: "\nparent=6\ntype=ContainerLayer\nname=splitScreenDividerAnchor#0",
+ 11: "\nparent=3\ntype=ContainerLayer\nname=mAboveAppWindowsContainers#0",
+ 12: "\nparent=3\ntype=ContainerLayer\nname=ImeContainer#0",
+ 13: "\nparent=6\ntype=ContainerLayer\nname=Task=1#0",
+ 18: "\nparent=5\ntype=ContainerLayer\nname=WallpaperWindowToken{4c3f8ef token=android.os.Binder@a0341ce}#0",
+ 19: "\nparent=18\ntype=ContainerLayer\nname=aa9ba7e com.breel.wallpapers18.soundviz.wallpaper.variations.SoundVizWallpaperV2#0",
+ 20: "\nparent=19\ntype=BufferQueueLayer\nname=com.breel.wallpapers18.soundviz.wallpaper.variations.SoundVizWallpaperV2#0",
+ 23: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{2e98b86 android.os.BinderProxy@6e5dbc8}#0",
+ 24: "\nparent=23\ntype=ContainerLayer\nname=5976c47 NavigationBar0#0",
+ 25: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{525aa4 android.os.BinderProxy@df1e236}#0",
+ 26: "\nparent=25\ntype=ContainerLayer\nname=986c00d NotificationShade#0",
+ 27: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{7ec5009 android.os.BinderProxy@de2add3}#0",
+ 28: "\nparent=27\ntype=ContainerLayer\nname=3a0542f StatusBar#0",
+ 31: "\nparent=-1\ntype=ContainerLayer\nname=WindowToken{eef604c android.os.BinderProxy@d3a687f}#0",
+ 32: "\nparent=31\ntype=ContainerLayer\nname=20b5895 ScreenDecorOverlay#0",
+ 33: "\nparent=-1\ntype=ContainerLayer\nname=WindowToken{4846f6f android.os.BinderProxy@39824e}#0",
+ 34: "\nparent=33\ntype=ContainerLayer\nname=1d714 ScreenDecorOverlayBottom#0",
+ 36: "\nparent=32\ntype=BufferQueueLayer\nname=ScreenDecorOverlay#0",
+ 38: "\nparent=34\ntype=BufferQueueLayer\nname=ScreenDecorOverlayBottom#0",
+ 40: "\nparent=28\ntype=BufferQueueLayer\nname=StatusBar#0",
+ 43: "\nparent=12\ntype=ContainerLayer\nname=WindowToken{fa12db9 android.os.Binder@4b88380}#0",
+ 46: "\nparent=13\ntype=ContainerLayer\nname=Task=4#0",
+ 47: "\nparent=46\ntype=ContainerLayer\nname=ActivityRecord{99bbfb0 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity#0",
+ 54: "\nparent=24\ntype=BufferQueueLayer\nname=NavigationBar0#0",
+ 71: "\nparent=43\ntype=ContainerLayer\nname=e8f94d2 InputMethod#0",
+ 11499: "\nparent=47\ntype=ContainerLayer\nname=6737b79 com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 11501: "\nparent=-1\ntype=ContainerLayer\nname=Input Consumer recents_animation_input_consumer#2",
+ 11759: "\nparent=6\ntype=ContainerLayer\nname=Task=873#0",
+ 11760: "\nparent=11759\ntype=ContainerLayer\nname=Task=874#0",
+ 11761: "\nparent=11760\ntype=ContainerLayer\nname=ActivityRecord{7398002 u0 com.android.server.wm.flicker.testapp/.ImeActivityAutoFocus#0",
+ 11785: "\nparent=11761\ntype=ColorLayer\nname=Letterbox - right#0",
+ 12131: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{bbffcfd android.os.Binder@547b554}#0",
+ 12379: "\nparent=47\ntype=ContainerLayer\nname=3f8f098 com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#0",
+ 12412: "\nparent=11761\ntype=ContainerLayer\nname=edca7c6 com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.ImeActivityAutoFocus#0",
+ 12448: "\nparent=2147483645\ntype=ContainerLayer\nname=Surface(name=ActivityRecord{99bbfb0 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity)/@0x2c3972c - animation-leash#0",
+ 12449: "\nparent=2147483645\ntype=ContainerLayer\nname=Surface(name=ActivityRecord{fc16c94 u0 com.android.server.wm.flicker.testapp/.ImeActivity)/@0x7049863 - animation-leash#0",
+ 12485: "\nparent=6\ntype=ContainerLayer\nname=Task=908#0",
+ 12486: "\nparent=12485\ntype=ContainerLayer\nname=Task=909#0",
+ 12487: "\nparent=12486\ntype=ContainerLayer\nname=ActivityRecord{4b3c5cb u0 com.android.server.wm.flicker.testapp/.ImeActivity#0",
+ 12500: "\nparent=2147483645\ntype=ContainerLayer\nname=Surface(name=ActivityRecord{99bbfb0 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity)/@0x2c3972c - animation-leash#0",
+ 12501: "\nparent=2147483645\ntype=ContainerLayer\nname=Surface(name=ActivityRecord{4b3c5cb u0 com.android.server.wm.flicker.testapp/.ImeActivity)/@0x4ad47a1 - animation-leash#0",
+ 12502: "\nparent=2147483645\ntype=ContainerLayer\nname=Surface(name=WallpaperWindowToken{4c3f8ef token=android.os.Binder@a0341ce})/@0xcde5e65 - animation-leash#0",
+ 12511: "\nparent=12487\ntype=ColorLayer\nname=Letterbox - right#1",
+ 12514: "\nparent=12487\ntype=ContainerLayer\nname=debe1ed com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.ImeActivity#0",
+ 12526: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{6b7d663 android.os.BinderProxy@391f21d}#0",
+ 12527: "\nparent=12526\ntype=ContainerLayer\nname=32aa260 AssistPreviewPanel#0",
+ 12529: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{31f7489 android.os.BinderProxy@67b1e53}#0",
+ 12530: "\nparent=12529\ntype=ContainerLayer\nname=cbb28bc DockedStackDivider#0",
+ 12536: "\nparent=6\ntype=ContainerLayer\nname=Task=910#0",
+ 12537: "\nparent=12536\ntype=ContainerLayer\nname=Task=911#0",
+ 12538: "\nparent=12537\ntype=ContainerLayer\nname=ActivityRecord{d3b8a44 u0 com.android.server.wm.flicker.testapp/.SimpleActivity#0",
+ 12541: "\nparent=12538\ntype=ContainerLayer\nname=a3583c5 com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.SimpleActivity#0",
+ 12545: "\nparent=12541\ntype=BufferQueueLayer\nname=com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.SimpleActivity#0",
+ 2147483645: "\nparent=-1\ntype=\nname=Offscreen Root",
+};
+const expectedRoot = {
+ chips: [],
+ proto: expectedRootProto,
+ hwcBlob: "",
+ isVisible: true,
+ kind: "entry",
+ shortName: "0d1h46m19s146ms",
+ timestampMs: "6379146308030",
+ where: "",
+ name: "0d1h46m19s146ms",
+ stableId: "LayerTraceEntry",
+};
+
+const expectedRootAospLayer = {
+ backgroundBlurRadius: 0,
+ cornerRadius: 0,
+ effectiveScalingMode: 0,
+ hwcCompositionType: "INVALID",
+ id: 876,
+ isOpaque: false,
+ isRelativeOf: false,
+ kind: "876",
+ name: "com.android.launcher3/com.android.launcher3.Launcher#0",
+ shadowRadius: 0,
+ shortName: "com.android.(...).Launcher#0",
+ type: "BufferLayer",
+ z: 0,
+ zOrderRelativeOf: null,
+ parentId: 41,
+ activeBuffer: new Buffer(1440, 2880, 1472, 1),
+ bufferTransform: standardTransform,
+ chips: [VISIBLE_CHIP],
+ color: standardColor,
+ crop: new Rect(0, 0, 1440, 2880),
+ hwcFrame: standardRect,
+ screenBounds: new RectF(0, 0, 1440, 2880),
+ sourceBounds: new RectF(0, 0, 1440, 2880),
+ transform: standardTransform,
+ visibleRegion: new Region([new Rect(0, 0, 1440, 2880)]),
+};
+const expectedRootAospProto = {
+ 2: "\nparent=-1\ntype=ContainerLayer\nname=Display Root#0",
+ 3: "\nparent=-1\ntype=ContainerLayer\nname=Display Overlays#0",
+ 4: "\nparent=2\ntype=ContainerLayer\nname=mBelowAppWindowsContainers#0",
+ 5: "\nparent=2\ntype=ContainerLayer\nname=com.android.server.wm.DisplayContent$TaskStackContainers@d8077b3#0",
+ 6: "\nparent=5\ntype=ContainerLayer\nname=animationLayer#0",
+ 7: "\nparent=5\ntype=ContainerLayer\nname=boostedAnimationLayer#0",
+ 8: "\nparent=5\ntype=ContainerLayer\nname=homeAnimationLayer#0",
+ 9: "\nparent=5\ntype=ContainerLayer\nname=splitScreenDividerAnchor#0",
+ 10: "\nparent=2\ntype=ContainerLayer\nname=mAboveAppWindowsContainers#0",
+ 11: "\nparent=2\ntype=ContainerLayer\nname=mImeWindowsContainers#0",
+ 12: "\nparent=5\ntype=ContainerLayer\nname=Stack=0#0",
+ 13: "\nparent=12\ntype=ColorLayer\nname=animation background stackId=0#0",
+ 18: "\nparent=4\ntype=ContainerLayer\nname=WallpaperWindowToken{5a7eaca token=android.os.Binder@438b635}#0",
+ 23: "\nparent=10\ntype=ContainerLayer\nname=WindowToken{d19e48 android.os.BinderProxy@560ac3a}#0",
+ 24: "\nparent=23\ntype=ContainerLayer\nname=b2a84e1 NavigationBar0#0",
+ 25: "\nparent=10\ntype=ContainerLayer\nname=WindowToken{74d6851 android.os.BinderProxy@8b22adb}#0",
+ 26: "\nparent=25\ntype=ContainerLayer\nname=16448b6 StatusBar#0",
+ 27: "\nparent=-1\ntype=ContainerLayer\nname=WindowToken{624863c android.os.BinderProxy@975b02f}#0",
+ 28: "\nparent=27\ntype=ContainerLayer\nname=cdb9fc5 ScreenDecorOverlay#0",
+ 29: "\nparent=-1\ntype=ContainerLayer\nname=WindowToken{cb7204b android.os.BinderProxy@b8f3d1a}#0",
+ 30: "\nparent=29\ntype=ContainerLayer\nname=ad1ca28 ScreenDecorOverlayBottom#0",
+ 31: "\nparent=28\ntype=BufferLayer\nname=ScreenDecorOverlay#0",
+ 32: "\nparent=30\ntype=BufferLayer\nname=ScreenDecorOverlayBottom#0",
+ 33: "\nparent=18\ntype=ContainerLayer\nname=4f4b23b com.android.systemui.ImageWallpaper#0",
+ 34: "\nparent=33\ntype=BufferLayer\nname=com.android.systemui.ImageWallpaper#0",
+ 36: "\nparent=26\ntype=BufferLayer\nname=StatusBar#0",
+ 37: "\nparent=12\ntype=ContainerLayer\nname=Task=144#0",
+ 38: "\nparent=37\ntype=ContainerLayer\nname=AppWindowToken{54e2de0 token=Token{f4c5fe3 ActivityRecord{6a9dc12 u0 com.android.launcher3/.Launcher t144}}}#0",
+ 40: "\nparent=-1\ntype=ContainerLayer\nname=Input Consumer recents_animation_input_consumer#1",
+ 41: "\nparent=38\ntype=ContainerLayer\nname=418b5c0 com.android.launcher3/com.android.launcher3.Launcher#0",
+ 45: "\nparent=11\ntype=ContainerLayer\nname=WindowToken{9158878 android.os.Binder@4f4a5db}#0",
+ 46: "\nparent=24\ntype=BufferLayer\nname=NavigationBar0#0",
+ 731: "\nparent=10\ntype=ContainerLayer\nname=WindowToken{c0ebbde android.os.BinderProxy@1af0e60}#0",
+ 732: "\nparent=731\ntype=ContainerLayer\nname=b37d1bf AssistPreviewPanel#0",
+ 733: "\nparent=10\ntype=ContainerLayer\nname=WindowToken{dc6b7ea android.os.BinderProxy@166b08c}#0",
+ 734: "\nparent=733\ntype=ContainerLayer\nname=2a1cadb DockedStackDivider#0",
+ 862: "\nparent=10\ntype=ContainerLayer\nname=WindowToken{f63efe6 android.os.Binder@d536e41}#0",
+ 865: "\nparent=887\ntype=ContainerLayer\nname=Task=170#0",
+ 866: "\nparent=865\ntype=ContainerLayer\nname=AppWindowToken{c829d40 token=Token{59970c3 ActivityRecord{36f2472 u0 com.android.server.wm.flicker.testapp/.PipActivity t170}}}#0",
+ 871: "\nparent=866\ntype=ContainerLayer\nname=8153ff7 com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp.PipActivity#0",
+ 876: "\nparent=41\ntype=BufferLayer\nname=com.android.launcher3/com.android.launcher3.Launcher#0",
+ 887: "\nparent=5\ntype=ContainerLayer\nname=Stack=78#0",
+ 888: "\nparent=887\ntype=ColorLayer\nname=animation background stackId=78#0",
+};
+const expectedRootAosp = {
+ chips: [],
+ proto: expectedRootAospProto,
+ hwcBlob: "",
+ isVisible: true,
+ kind: "entry",
+ shortName: "0d1h3m1s911ms",
+ timestampMs: "3781911657318",
+ where: "",
+ name: "0d1h3m1s911ms",
+ stableId: "LayerTraceEntry",
+};
+
+const expectedEntries = [
+ expectedEmptyRegion,
+ expectedInvalidLayerVisibility,
+ expectedOrphanLayers,
+ expectedRoot,
+ expectedRootAosp
+];
+const expectedLayers = [
+ expectedEmptyRegionLayer,
+ expectedInvalidLayerVisibilityLayer,
+ expectedOrphanLayersLayer,
+ expectedRootLayer,
+ expectedRootAospLayer
+];
+const layers_traces = [
+ '../spec/traces/layers_trace/layers_trace_emptyregion.pb',
+ '../spec/traces/layers_trace/layers_trace_invalid_layer_visibility.pb',
+ '../spec/traces/layers_trace/layers_trace_orphanlayers.pb',
+ '../spec/traces/layers_trace/layers_trace_root.pb',
+ '../spec/traces/layers_trace/layers_trace_root_aosp.pb',
+];
+
+export { expectedEntries, expectedLayers, layers_traces };
diff --git a/tools/winscope/spec/traces/error_trace.winscope b/tools/winscope/spec/traces/error_trace.winscope
new file mode 100644
index 000000000..fd970722d
Binary files /dev/null and b/tools/winscope/spec/traces/error_trace.winscope differ
diff --git a/tools/winscope/spec/traces/tag_trace.winscope b/tools/winscope/spec/traces/tag_trace.winscope
new file mode 100644
index 000000000..83459ba81
Binary files /dev/null and b/tools/winscope/spec/traces/tag_trace.winscope differ
diff --git a/tools/winscope/spec/utils/tree.js b/tools/winscope/spec/utils/tree.js
index 379ebaf46..63d0cb41d 100644
--- a/tools/winscope/spec/utils/tree.js
+++ b/tools/winscope/spec/utils/tree.js
@@ -9,6 +9,31 @@ class DiffNode extends Node {
constructor(nodeDef, diffType, children) {
super(nodeDef, children);
this.diff = { type: diffType };
+ this.name = undefined;
+ this.stableId = undefined;
+ this.kind = undefined;
+ this.shortName = undefined;
+ }
+}
+
+class ObjNode extends Node {
+ constructor(name, children, combined, stableId) {
+ const nodeDef = {
+ kind: '',
+ name: name,
+ stableId: stableId,
+ };
+ if (combined) {
+ nodeDef.combined = true;
+ }
+ super(nodeDef, children);
+ }
+}
+
+class ObjDiffNode extends ObjNode {
+ constructor(name, diffType, children, combined, stableId) {
+ super(name, children, combined, stableId);
+ this.diff = { type: diffType };
}
}
@@ -30,4 +55,4 @@ function toPlainObject(theClass) {
}
}
-export { Node, DiffNode, toPlainObject };
\ No newline at end of file
+export { Node, DiffNode, ObjNode, ObjDiffNode, toPlainObject };
diff --git a/tools/winscope/src/AccessibilityTraceView.vue b/tools/winscope/src/AccessibilityTraceView.vue
index 036699e94..63e7b3a9f 100644
--- a/tools/winscope/src/AccessibilityTraceView.vue
+++ b/tools/winscope/src/AccessibilityTraceView.vue
@@ -14,7 +14,13 @@
-->
-
+
\ No newline at end of file
+
diff --git a/tools/winscope/src/App.vue b/tools/winscope/src/App.vue
index 75d7b32bf..d7717613f 100644
--- a/tools/winscope/src/App.vue
+++ b/tools/winscope/src/App.vue
@@ -52,13 +52,20 @@
:ref="file.type"
:store="store"
:file="file"
+ :presentTags="Object.freeze(presentTags)"
+ :presentErrors="Object.freeze(presentErrors)"
+ :dataViewFiles="dataViewFiles"
@click="onDataViewFocus(file)"
/>
@@ -77,7 +84,8 @@ import FileType from './mixins/FileType.js';
import SaveAsZip from './mixins/SaveAsZip';
import FocusedDataViewFinder from './mixins/FocusedDataViewFinder';
import {DIRECTION} from './utils/utils';
-import {NAVIGATION_STYLE} from './utils/consts';
+import Searchbar from './Searchbar.vue';
+import {NAVIGATION_STYLE, SEARCH_TYPE} from './utils/consts';
const APP_NAME = 'Winscope';
@@ -97,11 +105,17 @@ export default {
simplifyNames: true,
displayDefaults: true,
navigationStyle: NAVIGATION_STYLE.GLOBAL,
+ flickerTraceView: false,
+ showFileTypes: [],
}),
overlayRef: 'overlay',
mainContentStyle: {
'padding-bottom': `${CONTENT_BOTTOM_PADDING}px`,
},
+ presentTags: [],
+ presentErrors: [],
+ searchTypes: [SEARCH_TYPE.TIMESTAMP],
+ tagAndErrorTraces: false,
};
},
created() {
@@ -113,8 +127,58 @@ export default {
window.removeEventListener('keydown', this.onKeyDown);
window.removeEventListener('scroll', this.onScroll);
},
+
methods: {
+ /** Get states from either tag files or error files */
+ getUpdatedStates(files) {
+ var states = [];
+ for (const file of files) {
+ states.push(...file.data);
+ }
+ return states;
+ },
+ /** Get tags from all uploaded tag files*/
+ getUpdatedTags() {
+ var tagStates = this.getUpdatedStates(this.tagFiles);
+ var tags = [];
+ tagStates.forEach(tagState => {
+ tagState.tags.forEach(tag => {
+ tag.timestamp = tagState.timestamp;
+ tags.push(tag);
+ });
+ });
+ return tags;
+ },
+ /** Get tags from all uploaded error files*/
+ getUpdatedErrors() {
+ var errorStates = this.getUpdatedStates(this.errorFiles);
+ var errors = [];
+ //TODO (b/196201487) add check if errors empty
+ errorStates.forEach(errorState => {
+ errorState.errors.forEach(error => {
+ error.timestamp = errorState.timestamp;
+ errors.push(error);
+ });
+ });
+ return errors;
+ },
+ /** Set flicker mode check for if there are tag/error traces uploaded*/
+ shouldUpdateTagAndErrorTraces() {
+ return this.tagFiles.length > 0 || this.errorFiles.length > 0;
+ },
+ /** Activate flicker search tab if tags/errors uploaded*/
+ updateSearchTypes() {
+ this.searchTypes = [SEARCH_TYPE.TIMESTAMP];
+ if (this.tagAndErrorTraces) this.searchTypes.push(SEARCH_TYPE.TAG);
+ },
+ /** Filter data view files by current show settings*/
+ updateShowFileTypes() {
+ this.store.showFileTypes = this.dataViewFiles
+ .filter((file) => file.show)
+ .map(file => file.type);
+ },
clear() {
+ this.store.showFileTypes = [];
this.$store.commit('clearFiles');
},
onDataViewFocus(file) {
@@ -139,7 +203,12 @@ export default {
},
onDataReady(files) {
this.$store.dispatch('setFiles', files);
+ this.tagAndErrorTraces = this.shouldUpdateTagAndErrorTraces();
+ this.presentTags = this.getUpdatedTags();
+ this.presentErrors = this.getUpdatedErrors();
+ this.updateSearchTypes();
this.updateFocusedView();
+ this.updateShowFileTypes();
},
setStatus(status) {
if (status) {
@@ -158,7 +227,10 @@ export default {
},
computed: {
files() {
- return this.$store.getters.sortedFiles;
+ return this.$store.getters.sortedFiles.map(file => {
+ if (this.hasDataView(file)) file.show = true;
+ return file;
+ });
},
prettyDump() {
return JSON.stringify(this.dump, null, 2);
@@ -174,7 +246,16 @@ export default {
return this.activeDataView;
},
dataViewFiles() {
- return this.files.filter((f) => this.hasDataView(f));
+ return this.files.filter((file) => this.hasDataView(file));
+ },
+ tagFiles() {
+ return this.$store.getters.tagFiles;
+ },
+ errorFiles() {
+ return this.$store.getters.errorFiles;
+ },
+ timelineFiles() {
+ return this.$store.getters.timelineFiles;
},
},
watch: {
@@ -187,6 +268,7 @@ export default {
dataview: DataView,
datainput: DataInput,
dataadb: DataAdb,
+ searchbar: Searchbar,
},
};
@@ -194,7 +276,7 @@ export default {
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@600&display=swap');
#app .md-app-container {
- /* Get rid of tranforms which prevent fixed position from being used */
+ /* Get rid of transforms which prevent fixed position from being used */
transform: none!important;
min-height: 100vh;
}
@@ -240,20 +322,10 @@ export default {
margin-top: 1em
}
-h1,
-h2 {
+h1 {
font-weight: normal;
}
-ul {
- list-style-type: none;
- padding: 0;
-}
-
-a {
- color: #42b983;
-}
-
.data-inputs {
display: flex;
flex-wrap: wrap;
@@ -281,16 +353,16 @@ a {
}
.snackbar-break-words {
- /* These are technically the same, but use both */
- overflow-wrap: break-word;
- word-wrap: break-word;
- -ms-word-break: break-all;
- word-break: break-word;
- /* Adds a hyphen where the word breaks, if supported (No Blink) */
- -ms-hyphens: auto;
- -moz-hyphens: auto;
- -webkit-hyphens: auto;
- hyphens: auto;
- padding: 10px 10px 10px 10px;
- }
-
+ /* These are technically the same, but use both */
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ -ms-word-break: break-all;
+ word-break: break-word;
+ /* Adds a hyphen where the word breaks, if supported (No Blink) */
+ -ms-hyphens: auto;
+ -moz-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+ padding: 10px 10px 10px 10px;
+}
+
\ No newline at end of file
diff --git a/tools/winscope/src/DataAdb.vue b/tools/winscope/src/DataAdb.vue
index 9b68c941c..0c34f2661 100644
--- a/tools/winscope/src/DataAdb.vue
+++ b/tools/winscope/src/DataAdb.vue
@@ -158,6 +158,9 @@ const TRACES = {
'window_trace': {
name: 'Window Manager',
},
+ 'accessibility_trace': {
+ name: 'Accessibility',
+ },
'layers_trace': {
name: 'Surface Flinger',
},
diff --git a/tools/winscope/src/DataView.vue b/tools/winscope/src/DataView.vue
index db3c07f5f..a2751f191 100644
--- a/tools/winscope/src/DataView.vue
+++ b/tools/winscope/src/DataView.vue
@@ -16,10 +16,15 @@
+
{{ TRACE_ICONS[file.type] }}
- {{file.type}}
+ {{ file.type }}
-
Unrecognized DataType
+ Unrecognized DataType
@@ -150,8 +161,23 @@ export default {
// to component.
this.$emit('click', e);
},
+ /** Filter data view files by current show settings */
+ updateShowFileTypes() {
+ this.store.showFileTypes = this.dataViewFiles
+ .filter((file) => file.show)
+ .map(file => file.type);
+ },
+ /** Expand or collapse data view */
+ toggleView() {
+ this.file.show = !this.file.show;
+ this.updateShowFileTypes();
+ },
+ /** Check if data view file should be shown */
+ isShowFileType(type) {
+ return this.store.showFileTypes.find(fileType => fileType===type);
+ },
},
- props: ['store', 'file'],
+ props: ['store', 'file', 'presentTags', 'presentErrors', 'dataViewFiles'],
mixins: [FileType],
components: {
'traceview': TraceView,
@@ -170,4 +196,18 @@ export default {
font-size: 4em;
color: red;
}
+
+.toggle-view-button {
+ background: none;
+ color: inherit;
+ border: none;
+ font: inherit;
+ cursor: pointer;
+ padding-right: 10px;
+ display: inline-block;
+}
+
+.md-title {
+ display: inline-block;
+}
diff --git a/tools/winscope/src/DefaultTreeElement.vue b/tools/winscope/src/DefaultTreeElement.vue
index 1df8d1769..96c7dcf09 100644
--- a/tools/winscope/src/DefaultTreeElement.vue
+++ b/tools/winscope/src/DefaultTreeElement.vue
@@ -43,13 +43,28 @@
{{c.long}}
+
+
@@ -100,4 +124,12 @@ span {
flex: 1 1 auto;
width: 0;
}
+
+.flicker-tags {
+ display: inline-block;
+}
+
+.error-arrow {
+ color: red;
+}
diff --git a/tools/winscope/src/NodeContextMenu.vue b/tools/winscope/src/NodeContextMenu.vue
index cba46eb5c..18d86e4bd 100644
--- a/tools/winscope/src/NodeContextMenu.vue
+++ b/tools/winscope/src/NodeContextMenu.vue
@@ -5,7 +5,7 @@
@@ -864,4 +920,8 @@ export default {
margin-bottom: 15px;
cursor: help;
}
+
+.drop-search:hover {
+ background-color: #9af39f;
+}
diff --git a/tools/winscope/src/Searchbar.vue b/tools/winscope/src/Searchbar.vue
new file mode 100644
index 000000000..50aca7b55
--- /dev/null
+++ b/tools/winscope/src/Searchbar.vue
@@ -0,0 +1,308 @@
+
+
+
+
+
+ Navigate to timestamp
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+ {{ transitionTags(item.id)[0].desc }}
+ |
+
+ {{ transitionTags(item.id)[1].desc }}
+ |
+
+ {{ transitionDesc(item.transition) }}
+ |
+
+
+ {{ errorDesc(item.timestamp) }}
+ |
+ - |
+
+ Error: {{item.message}}
+ |
+
+
+
+
+
+
+
+
+
+
+ {{ searchType }}
+
+
+
+
+
+
diff --git a/tools/winscope/src/SurfaceFlingerTraceView.vue b/tools/winscope/src/SurfaceFlingerTraceView.vue
index 94234ba71..5a848c10b 100644
--- a/tools/winscope/src/SurfaceFlingerTraceView.vue
+++ b/tools/winscope/src/SurfaceFlingerTraceView.vue
@@ -14,15 +14,21 @@
-->
-
+
+.error {
+ stroke: rgb(255, 0, 0);
+ stroke-width: 2px;
+}
+
\ No newline at end of file
diff --git a/tools/winscope/src/TraceView.vue b/tools/winscope/src/TraceView.vue
index 88bcabd3d..ab77d3542 100644
--- a/tools/winscope/src/TraceView.vue
+++ b/tools/winscope/src/TraceView.vue
@@ -42,6 +42,7 @@
Only visible
Flat
+ Flicker
@@ -55,6 +56,10 @@
:selected="hierarchySelected"
:filter="hierarchyFilter"
:flattened="store.flattened"
+ :onlyVisible="store.onlyVisible"
+ :flickerTraceView="store.flickerTraceView"
+ :presentTags="presentTags"
+ :presentErrors="presentErrors"
:items-clickable="true"
:useGlobalCollapsedState="true"
:simplify-names="store.simplifyNames"
@@ -165,7 +170,7 @@ function findEntryInTree(tree, id) {
export default {
name: 'traceview',
- props: ['store', 'file', 'summarizer'],
+ props: ['store', 'file', 'summarizer', 'presentTags', 'presentErrors'],
data() {
return {
propertyFilterString: '',
@@ -306,10 +311,30 @@ export default {
return prevEntry;
},
+
+ /** Performs check for id match between entry and present tags/errors
+ * must be carried out for every present tag/error
+ */
+ matchItems(flickerItems, entryItem) {
+ var match = false;
+ flickerItems.forEach(flickerItem => {
+ if (flickerItem.taskId===entryItem.taskId || flickerItem.layerId===entryItem.id) {
+ match = true;
+ }
+ });
+ return match;
+ },
+ /** Returns check for id match between entry and present tags/errors */
+ isEntryTagMatch(entryItem) {
+ return this.matchItems(this.presentTags, entryItem) || this.matchItems(this.presentErrors, entryItem);
+ },
},
created() {
this.setData(this.file.data[this.file.selectedIndex ?? 0]);
},
+ destroyed() {
+ this.store.flickerTraceView = false;
+ },
watch: {
selectedIndex() {
this.setData(this.file.data[this.file.selectedIndex ?? 0]);
@@ -337,9 +362,12 @@ export default {
hierarchyFilter() {
const hierarchyPropertyFilter =
getFilter(this.hierarchyPropertyFilterString);
- return this.store.onlyVisible ? (c) => {
+ var fil = this.store.onlyVisible ? (c) => {
return c.isVisible && hierarchyPropertyFilter(c);
} : hierarchyPropertyFilter;
+ return this.store.flickerTraceView ? (c) => {
+ return this.isEntryTagMatch(c);
+ } : fil;
},
propertyFilter() {
return getFilter(this.propertyFilterString);
@@ -363,6 +391,9 @@ export default {
return summary;
},
+ hasTagsOrErrors() {
+ return this.presentTags.length > 0 || this.presentErrors.length > 0;
+ },
},
components: {
'tree-view': TreeView,
diff --git a/tools/winscope/src/TreeView.vue b/tools/winscope/src/TreeView.vue
index ff574a59c..846924e6e 100644
--- a/tools/winscope/src/TreeView.vue
+++ b/tools/winscope/src/TreeView.vue
@@ -31,7 +31,7 @@