diff --git a/tools/winscope/src/Overlay.vue b/tools/winscope/src/Overlay.vue index e123d7c23..2bfb8cae7 100644 --- a/tools/winscope/src/Overlay.vue +++ b/tools/winscope/src/Overlay.vue @@ -344,6 +344,9 @@ export default { timelineFiles() { return this.$store.getters.timelineFiles; }, + tagFiles() { + return this.$store.getters.tagFiles; + }, focusedFile() { return this.$store.state.focusedFile; }, diff --git a/tools/winscope/src/decode.js b/tools/winscope/src/decode.js index 953971478..a665fe168 100644 --- a/tools/winscope/src/decode.js +++ b/tools/winscope/src/decode.js @@ -26,6 +26,8 @@ import jsonProtoDefsWl from 'WaylandSafePath/waylandtrace.proto'; import jsonProtoDefsSysUi from 'frameworks/base/packages/SystemUI/src/com/android/systemui/tracing/sysui_trace.proto'; import jsonProtoDefsLauncher from 'packages/apps/Launcher3/protos/launcher_trace_file.proto'; import jsonProtoDefsIme from 'frameworks/base/core/proto/android/view/inputmethod/inputmethodeditortrace.proto'; +import jsonProtoDefsTags from 'platform_testing/libraries/flicker/src/com/android/server/wm/proto/tags.proto'; +import jsonProtoDefsErrors from 'platform_testing/libraries/flicker/src/com/android/server/wm/proto/errors.proto'; import protobuf from 'protobufjs'; import {transform_accessibility_trace} from './transform_accessibility.js'; import {transform_transaction_trace} from './transform_transaction.js'; @@ -53,6 +55,9 @@ import SurfaceFlingerDump from '@/dumps/SurfaceFlinger.ts'; import WindowManagerDump from '@/dumps/WindowManager.ts'; import WaylandDump from '@/dumps/Wayland.ts'; +import TagTrace from '@/traces/TraceTag.ts'; +import ErrorTrace from '@/traces/TraceError.ts'; + const AccessibilityTraceMessage = lookup_type(jsonProtoDefsAccessibility, 'com.android.server.accessibility.AccessibilityTraceFileProto'); const WmTraceMessage = lookup_type(jsonProtoDefsWm, 'com.android.server.wm.WindowManagerTraceFileProto'); const WmDumpMessage = lookup_type(jsonProtoDefsWm, 'com.android.server.wm.WindowManagerServiceDumpProto'); @@ -67,6 +72,8 @@ const LauncherTraceMessage = lookup_type(jsonProtoDefsLauncher, 'com.android.lau const InputMethodClientsTraceMessage = lookup_type(jsonProtoDefsIme, 'android.view.inputmethod.InputMethodClientsTraceFileProto'); const InputMethodServiceTraceMessage = lookup_type(jsonProtoDefsIme, 'android.view.inputmethod.InputMethodServiceTraceFileProto'); const InputMethodManagerServiceTraceMessage = lookup_type(jsonProtoDefsIme, 'android.view.inputmethod.InputMethodManagerServiceTraceFileProto'); +const TagTraceMessage = lookup_type(jsonProtoDefsTags, 'com.android.server.wm.flicker.FlickerTagTraceProto'); +const ErrorTraceMessage = lookup_type(jsonProtoDefsErrors, 'com.android.server.wm.flicker.FlickerErrorTraceProto'); const ACCESSIBILITY_MAGIC_NUMBER = [0x09, 0x41, 0x31, 0x31, 0x59, 0x54, 0x52, 0x41, 0x43]; // .A11YTRAC const LAYER_TRACE_MAGIC_NUMBER = [0x09, 0x4c, 0x59, 0x52, 0x54, 0x52, 0x41, 0x43, 0x45]; // .LYRTRACE @@ -79,6 +86,8 @@ const LAUNCHER_MAGIC_NUMBER = [0x09, 0x4C, 0x4E, 0x43, 0x48, 0x52, 0x54, 0x52, 0 const IMC_TRACE_MAGIC_NUMBER = [0x09, 0x49, 0x4d, 0x43, 0x54, 0x52, 0x41, 0x43, 0x45]; // .IMCTRACE const IMS_TRACE_MAGIC_NUMBER = [0x09, 0x49, 0x4d, 0x53, 0x54, 0x52, 0x41, 0x43, 0x45]; // .IMSTRACE const IMM_TRACE_MAGIC_NUMBER = [0x09, 0x49, 0x4d, 0x4d, 0x54, 0x52, 0x41, 0x43, 0x45]; // .IMMTRACE +const TAG_TRACE_MAGIC_NUMBER = [0x09, 0x54, 0x41, 0x47, 0x54, 0x52, 0x41, 0x43, 0x45]; //.TAGTRACE +const ERROR_TRACE_MAGIC_NUMBER = [0x09, 0x45, 0x52, 0x52, 0x54, 0x52, 0x41, 0x43, 0x45]; //.ERRORTRACE const FILE_TYPES = Object.freeze({ ACCESSIBILITY_TRACE: 'AccessibilityTrace', @@ -96,6 +105,8 @@ const FILE_TYPES = Object.freeze({ IME_TRACE_CLIENTS: 'ImeTraceClients', IME_TRACE_SERVICE: 'ImeTrace InputMethodService', IME_TRACE_MANAGERSERVICE: 'ImeTrace InputMethodManagerService', + TAG_TRACE: 'TagTrace', + ERROR_TRACE: 'ErrorTrace', }); const WINDOW_MANAGER_ICON = 'view_compact'; @@ -108,6 +119,8 @@ const SYSTEM_UI_ICON = 'filter_none'; const LAUNCHER_ICON = 'filter_none'; const IME_ICON = 'keyboard'; const ACCESSIBILITY_ICON = 'filter_none'; +const TAG_ICON = 'details'; +const TRACE_ERROR_ICON = 'warning'; const FILE_ICONS = { [FILE_TYPES.ACCESSIBILITY_TRACE]: ACCESSIBILITY_ICON, @@ -125,6 +138,8 @@ const FILE_ICONS = { [FILE_TYPES.IME_TRACE_CLIENTS]: IME_ICON, [FILE_TYPES.IME_TRACE_SERVICE]: IME_ICON, [FILE_TYPES.IME_TRACE_MANAGERSERVICE]: IME_ICON, + [FILE_TYPES.TAG_TRACE]: TAG_ICON, + [FILE_TYPES.ERROR_TRACE]: TRACE_ERROR_ICON, }; function oneOf(dataType) { @@ -144,6 +159,8 @@ const TRACE_TYPES = Object.freeze({ IME_CLIENTS: 'ImeTrace Clients', IME_SERVICE: 'ImeTrace InputMethodService', IME_MANAGERSERVICE: 'ImeTrace InputMethodManagerService', + TAG: 'TagTrace', + ERROR: 'ErrorTrace', }); const TRACE_INFO = { @@ -221,6 +238,18 @@ const TRACE_INFO = { files: [oneOf(FILE_TYPES.IME_TRACE_MANAGERSERVICE)], constructor: ImeTraceManagerService, }, + [TRACE_TYPES.TAG]: { + name: 'Tag', + icon: TAG_ICON, + files: [oneOf(FILE_TYPES.TAG_TRACE)], + constructor: TagTrace, + }, + [TRACE_TYPES.ERROR]: { + name: 'Error', + icon: TRACE_ERROR_ICON, + files: [oneOf(FILE_TYPES.ERROR_TRACE)], + constructor: ErrorTrace, + }, }; const DUMP_TYPES = Object.freeze({ @@ -262,6 +291,8 @@ export const TRACE_ICONS = { [TRACE_TYPES.IME_CLIENTS]: IME_ICON, [TRACE_TYPES.IME_SERVICE]: IME_ICON, [TRACE_TYPES.IME_MANAGERSERVICE]: IME_ICON, + [TRACE_TYPES.TAG_TRACE]: TAG_ICON, + [TRACE_TYPES.ERROR_TRACE]: TRACE_ERROR_ICON, [DUMP_TYPES.WINDOW_MANAGER]: WINDOW_MANAGER_ICON, [DUMP_TYPES.SURFACE_FLINGER]: SURFACE_FLINGER_ICON, @@ -431,6 +462,26 @@ const FILE_DECODERS = { timeline: true, }, }, + [FILE_TYPES.TAG_TRACE]: { + name: 'Tag trace', + decoder: protoDecoder, + decoderParams: { + type: FILE_TYPES.TAG_TRACE, + protoType: TagTraceMessage, + transform: TagTrace.fromProto, + timeline: true, + }, + }, + [FILE_TYPES.ERROR_TRACE]: { + name: 'Error trace', + decoder: protoDecoder, + decoderParams: { + type: FILE_TYPES.ERROR_TRACE, + protoType: ErrorTraceMessage, + transform: ErrorTrace.fromProto, + timeline: true, + }, + }, }; function lookup_type(protoPath, type) { @@ -568,6 +619,12 @@ function detectAndDecode(buffer, fileName, store) { if (arrayStartsWith(buffer, IMM_TRACE_MAGIC_NUMBER)) { return decodedFile(FILE_TYPES.IME_TRACE_MANAGERSERVICE, buffer, fileName, store); } + if (arrayStartsWith(buffer, TAG_TRACE_MAGIC_NUMBER)) { + return decodedFile(FILE_TYPES.TAG_TRACE, buffer, fileName, store); + } + if (arrayStartsWith(buffer, ERROR_TRACE_MAGIC_NUMBER)) { + return decodedFile(FILE_TYPES.ERROR_TRACE, buffer, fileName, store); + } // TODO(b/169305853): Add magic number at beginning of file for better auto detection for (const [filetype, condition] of [ diff --git a/tools/winscope/src/flickerlib/ErrorTrace.ts b/tools/winscope/src/flickerlib/ErrorTrace.ts new file mode 100644 index 000000000..36b830794 --- /dev/null +++ b/tools/winscope/src/flickerlib/ErrorTrace.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorTrace } from "./common" +import ErrorState from "./errors/ErrorState" + +ErrorTrace.fromProto = function (proto: any) { + const states = []; + for (const stateProto of proto.states) { + const transformedState = ErrorState.fromProto( + stateProto.errors, + stateProto.timestamp); + + states.push(transformedState); + } + const source = null; + return new ErrorTrace(states, source); +} + +export default ErrorTrace; diff --git a/tools/winscope/src/flickerlib/TagTrace.ts b/tools/winscope/src/flickerlib/TagTrace.ts new file mode 100644 index 000000000..862e51fb9 --- /dev/null +++ b/tools/winscope/src/flickerlib/TagTrace.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TagTrace } from "./common" +import TagState from "./tags/TagState" + +TagTrace.fromProto = function (proto: any): TagTrace { + const states = []; + for (const stateProto of proto.states) { + const transformedState = TagState.fromProto( + stateProto.timestamp, + stateProto.tags); + + states.push(transformedState); + } + const source = null; + return new TagTrace(states, source); +} + +export default TagTrace; diff --git a/tools/winscope/src/flickerlib/common.js b/tools/winscope/src/flickerlib/common.js index 2df565963..db16f9de3 100644 --- a/tools/winscope/src/flickerlib/common.js +++ b/tools/winscope/src/flickerlib/common.js @@ -76,6 +76,16 @@ const Rect = require('flicker').com.android.server.wm.traces.common.Rect; const RectF = require('flicker').com.android.server.wm.traces.common.RectF; const Region = require('flicker').com.android.server.wm.traces.common.Region; +//Tags +const Tag = require('flicker').com.android.server.wm.traces.common.tags.Tag; +const TagState = require('flicker').com.android.server.wm.traces.common.tags.TagState; +const TagTrace = require('flicker').com.android.server.wm.traces.common.tags.TagTrace; + +//Errors +const Error = require('flicker').com.android.server.wm.traces.common.errors.Error; +const ErrorState = require('flicker').com.android.server.wm.traces.common.errors.ErrorState; +const ErrorTrace = require('flicker').com.android.server.wm.traces.common.errors.ErrorTrace; + const EMPTY_BUFFER = new Buffer(0, 0, 0, 0); const EMPTY_COLOR = new Color(-1, -1, -1, 0); const EMPTY_RECT = new Rect(0, 0, 0, 0); @@ -226,6 +236,14 @@ export { LayersTrace, Transform, Matrix, + // Tags + Tag, + TagState, + TagTrace, + // Errors + Error, + ErrorState, + ErrorTrace, // Common Size, Buffer, diff --git a/tools/winscope/src/flickerlib/errors/Error.ts b/tools/winscope/src/flickerlib/errors/Error.ts new file mode 100644 index 000000000..4c08a7dfb --- /dev/null +++ b/tools/winscope/src/flickerlib/errors/Error.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { Error } from "../common" + +Error.fromProto = function (proto: any): Error { + const error = new Error( + proto.stacktrace, + proto.message, + proto.layerId, + proto.windowToken, + proto.taskId + ); + return error; +} + +export default Error; diff --git a/tools/winscope/src/flickerlib/errors/ErrorState.ts b/tools/winscope/src/flickerlib/errors/ErrorState.ts new file mode 100644 index 000000000..78364c626 --- /dev/null +++ b/tools/winscope/src/flickerlib/errors/ErrorState.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ErrorState } from "../common"; +import Error from './Error'; + +ErrorState.fromProto = function (protos: any[], timestamp: number): ErrorState { + const errors = protos.map(it => Error.fromProto(it)); + const state = new ErrorState(errors, timestamp); + return state; +} + +export default ErrorState; diff --git a/tools/winscope/src/flickerlib/index.js b/tools/winscope/src/flickerlib/index.js index 1c564a08e..216d621cb 100644 --- a/tools/winscope/src/flickerlib/index.js +++ b/tools/winscope/src/flickerlib/index.js @@ -18,9 +18,11 @@ import LayersTrace from './LayersTrace'; import WindowManagerState from './WindowManagerState'; import WindowManagerTrace from './WindowManagerTrace'; import ObjectFormatter from './ObjectFormatter'; +import TagTrace from './TagTrace'; +import ErrorTrace from './ErrorTrace'; /** * Entry point into the flickerlib for Winscope. * Expose everything we want Winscope to have access to here. */ -export {ObjectFormatter, LayersTrace, WindowManagerState, WindowManagerTrace}; +export {ObjectFormatter, LayersTrace, WindowManagerState, WindowManagerTrace, TagTrace, ErrorTrace}; diff --git a/tools/winscope/src/flickerlib/tags/Tag.ts b/tools/winscope/src/flickerlib/tags/Tag.ts new file mode 100644 index 000000000..283105d5e --- /dev/null +++ b/tools/winscope/src/flickerlib/tags/Tag.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { Tag } from "../common" + +Tag.fromProto = function (proto: any): Tag { + const tag = new Tag( + proto.id, + proto.transition, + proto.isStartTag, + proto.layerId, + proto.windowToken, + proto.taskId + ); + return tag +} + +export default Tag; diff --git a/tools/winscope/src/flickerlib/tags/TagState.ts b/tools/winscope/src/flickerlib/tags/TagState.ts new file mode 100644 index 000000000..d127a2d37 --- /dev/null +++ b/tools/winscope/src/flickerlib/tags/TagState.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TagState } from "../common"; +import Tag from './Tag'; + +TagState.fromProto = function (timestamp: number, protos: any[]): TagState { + const tags = protos.map(it => Tag.fromProto(it)); + const state = new TagState(timestamp, tags); + return state; +} + +export default TagState; diff --git a/tools/winscope/src/main.js b/tools/winscope/src/main.js index 907e7de0e..26a0f8ee9 100644 --- a/tools/winscope/src/main.js +++ b/tools/winscope/src/main.js @@ -66,6 +66,8 @@ const store = new Vuex.Store({ dumps: {}, excludeFromTimeline: [ TRACE_TYPES.PROTO_LOG, + TRACE_TYPES.TAG, + TRACE_TYPES.ERROR ], activeFile: null, focusedFile: null, @@ -93,6 +95,14 @@ const store = new Vuex.Store({ return Object.values(state.traces) .filter(file => !state.excludeFromTimeline.includes(file.type)); }, + tagFiles(state, getters) { + return Object.values(state.traces) + .filter(file => file.type === TRACE_TYPES.TAG); + }, + errorFiles(state, getters) { + return Object.values(state.traces) + .filter(file => file.type === TRACE_TYPES.ERROR); + }, sortedTimelineFiles(state, getters) { return sortFiles(getters.timelineFiles); }, diff --git a/tools/winscope/src/traces/TraceError.ts b/tools/winscope/src/traces/TraceError.ts new file mode 100644 index 000000000..3c9daa75b --- /dev/null +++ b/tools/winscope/src/traces/TraceError.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FILE_TYPES, TRACE_TYPES } from '@/decode.js'; +import TraceBase from './TraceBase'; +import { ErrorTrace } from '@/flickerlib'; + +export default class TraceError extends TraceBase { + errorTraceFile: Object; + + constructor(files) { + const errorTraceFile = files[FILE_TYPES.ERROR_TRACE]; + super(errorTraceFile.data, errorTraceFile.timeline, files); + this.errorTraceFile = errorTraceFile; + } + + get type() { + return TRACE_TYPES.ERROR; + } + + static fromProto(proto: any): ErrorTrace { + return ErrorTrace.fromProto(proto); + } +} diff --git a/tools/winscope/src/traces/TraceTag.ts b/tools/winscope/src/traces/TraceTag.ts new file mode 100644 index 000000000..401a18578 --- /dev/null +++ b/tools/winscope/src/traces/TraceTag.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FILE_TYPES, TRACE_TYPES } from '@/decode.js'; +import TraceBase from './TraceBase'; +import { TagTrace } from '@/flickerlib'; + +export default class TraceTag extends TraceBase { + tagTraceFile: Object; + + constructor(files) { + const tagTraceFile = files[FILE_TYPES.TAG_TRACE]; + super(tagTraceFile.data, tagTraceFile.timeline, files); + this.tagTraceFile = tagTraceFile; + } + + get type() { + return TRACE_TYPES.TAG; + } + + static fromProto(proto: any): TagTrace { + return TagTrace.fromProto(proto); + } +} \ No newline at end of file