1/* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import {assertDefined} from 'common/assert_utils'; 17import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils'; 18import {UnitTestUtils} from 'test/unit/utils'; 19import {CoarseVersion} from 'trace/coarse_version'; 20import {Parser} from 'trace/parser'; 21import {TraceType} from 'trace/trace_type'; 22import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 23 24describe('Perfetto ParserMotionEvent', () => { 25 let parser: Parser<PropertyTreeNode>; 26 27 beforeAll(async () => { 28 jasmine.addCustomEqualityTester(UnitTestUtils.timestampEqualityTester); 29 parser = await UnitTestUtils.getPerfettoParser( 30 TraceType.INPUT_MOTION_EVENT, 31 'traces/perfetto/input-events.perfetto-trace', 32 ); 33 }); 34 35 it('has expected trace type', () => { 36 expect(parser.getTraceType()).toEqual(TraceType.INPUT_MOTION_EVENT); 37 }); 38 39 it('has expected coarse version', () => { 40 expect(parser.getCoarseVersion()).toEqual(CoarseVersion.LATEST); 41 }); 42 43 it('provides timestamps', () => { 44 const timestamps = assertDefined(parser.getTimestamps()); 45 46 expect(timestamps.length).toEqual(4); 47 48 const expected = [ 49 TimestampConverterUtils.makeRealTimestamp(1718163696245804410n), 50 TimestampConverterUtils.makeRealTimestamp(1718163696254923410n), 51 TimestampConverterUtils.makeRealTimestamp(1718163696262592410n), 52 TimestampConverterUtils.makeRealTimestamp(1718163696271081410n), 53 ]; 54 expect(timestamps).toEqual(expected); 55 }); 56 57 it('retrieves trace entry from timestamp', async () => { 58 const entry = await parser.getEntry(1); 59 expect(entry.id).toEqual('AndroidMotionEvent entry'); 60 }); 61 62 it('transforms fake motion event proto built from trace processor args', async () => { 63 const entry = await parser.getEntry(0); 64 const motionEvent = assertDefined(entry.getChildByName('motionEvent')); 65 66 expect(motionEvent?.getChildByName('eventId')?.getValue()).toEqual( 67 856299947, 68 ); 69 expect(motionEvent?.getChildByName('action')?.formattedValue()).toEqual( 70 'ACTION_DOWN', 71 ); 72 expect(motionEvent?.getChildByName('source')?.formattedValue()).toEqual( 73 'SOURCE_TOUCHSCREEN', 74 ); 75 expect(motionEvent?.getChildByName('flags')?.formattedValue()).toEqual( 76 '128', 77 ); 78 expect(motionEvent?.getChildByName('deviceId')?.getValue()).toEqual(4); 79 expect(motionEvent?.getChildByName('displayId')?.getValue()).toEqual(0); 80 expect( 81 motionEvent?.getChildByName('classification')?.formattedValue(), 82 ).toEqual('CLASSIFICATION_NONE'); 83 expect(motionEvent?.getChildByName('cursorPositionX')?.getValue()).toEqual( 84 null, 85 ); 86 expect(motionEvent?.getChildByName('cursorPositionY')?.getValue()).toEqual( 87 null, 88 ); 89 expect(motionEvent?.getChildByName('metaState')?.formattedValue()).toEqual( 90 '0', 91 ); 92 93 const firstPointer = motionEvent 94 ?.getChildByName('pointer') 95 ?.getChildByName('0'); 96 97 expect(firstPointer?.getChildByName('pointerId')?.getValue()).toEqual(0); 98 99 expect(firstPointer?.getChildByName('toolType')?.formattedValue()).toEqual( 100 'TOOL_TYPE_FINGER', 101 ); 102 103 expect( 104 firstPointer 105 ?.getChildByName('axisValue') 106 ?.getChildByName('0') 107 ?.getChildByName('axis') 108 ?.formattedValue(), 109 ).toEqual('AXIS_X'); 110 111 expect( 112 firstPointer 113 ?.getChildByName('axisValue') 114 ?.getChildByName('0') 115 ?.getChildByName('value') 116 ?.getValue(), 117 ).toEqual(350); 118 119 expect( 120 firstPointer 121 ?.getChildByName('axisValue') 122 ?.getChildByName('1') 123 ?.getChildByName('axis') 124 ?.formattedValue(), 125 ).toEqual('AXIS_Y'); 126 127 expect( 128 firstPointer 129 ?.getChildByName('axisValue') 130 ?.getChildByName('1') 131 ?.getChildByName('value') 132 ?.getValue(), 133 ).toEqual(370); 134 }); 135 136 it('merges motion event with all associated dispatch events', async () => { 137 const entry = await parser.getEntry(0); 138 const windowDispatchEvents = assertDefined( 139 entry.getChildByName('windowDispatchEvents'), 140 ); 141 142 expect(windowDispatchEvents?.getAllChildren().length).toEqual(6); 143 expect( 144 windowDispatchEvents 145 ?.getChildByName('0') 146 ?.getChildByName('windowId') 147 ?.getValue(), 148 ).toEqual(BigInt(292)); 149 expect( 150 windowDispatchEvents 151 ?.getChildByName('1') 152 ?.getChildByName('windowId') 153 ?.getValue(), 154 ).toEqual(BigInt(247)); 155 expect( 156 windowDispatchEvents 157 ?.getChildByName('2') 158 ?.getChildByName('windowId') 159 ?.getValue(), 160 ).toEqual(BigInt(240)); 161 expect( 162 windowDispatchEvents 163 ?.getChildByName('3') 164 ?.getChildByName('windowId') 165 ?.getValue(), 166 ).toEqual(BigInt(370)); 167 expect( 168 windowDispatchEvents 169 ?.getChildByName('4') 170 ?.getChildByName('windowId') 171 ?.getValue(), 172 ).toEqual(BigInt(229)); 173 expect( 174 windowDispatchEvents 175 ?.getChildByName('5') 176 ?.getChildByName('windowId') 177 ?.getValue(), 178 ).toEqual(BigInt(0)); 179 }); 180}); 181