• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
16
17import {assertDefined} from 'common/assert_utils';
18import {IDENTITY_MATRIX} from 'common/geometry/transform_matrix';
19import {TransformTypeFlags} from 'parsers/surface_flinger/transform_utils';
20import {PropertyTreeBuilder} from 'test/unit/property_tree_builder';
21import {TreeNodeUtils} from 'test/unit/tree_node_utils';
22import {
23  BUFFER_FORMATTER,
24  COLOR_FORMATTER,
25  CUJ_TYPE_FORMATTER,
26  DEFAULT_PROPERTY_FORMATTER,
27  EMPTY_ARRAY_STRING,
28  EMPTY_OBJ_STRING,
29  formatAsHex,
30  HEX_FORMATTER,
31  LAYER_ID_FORMATTER,
32  MATRIX_FORMATTER,
33  POSITION_FORMATTER,
34  RECT_FORMATTER,
35  REGION_FORMATTER,
36  SIZE_FORMATTER,
37  TRANSFORM_FORMATTER,
38} from './formatters';
39import {PropertySource, PropertyTreeNode} from './property_tree_node';
40
41describe('Formatters', () => {
42  describe('PropertyFormatter', () => {
43    it('translates simple values correctly', () => {
44      expect(
45        DEFAULT_PROPERTY_FORMATTER.format(
46          new PropertyTreeNode('', '', PropertySource.PROTO, 12345),
47        ),
48      ).toEqual('12345');
49      expect(
50        DEFAULT_PROPERTY_FORMATTER.format(
51          new PropertyTreeNode('', '', PropertySource.PROTO, 'test_string'),
52        ),
53      ).toEqual('test_string');
54      expect(
55        DEFAULT_PROPERTY_FORMATTER.format(
56          new PropertyTreeNode('', '', PropertySource.PROTO, 0.1234),
57        ),
58      ).toEqual('0.123');
59      expect(
60        DEFAULT_PROPERTY_FORMATTER.format(
61          new PropertyTreeNode('', '', PropertySource.PROTO, 1.5),
62        ),
63      ).toEqual('1.500');
64    });
65
66    it('translates values with toString method correctly', () => {
67      expect(
68        DEFAULT_PROPERTY_FORMATTER.format(
69          new PropertyTreeNode('', '', PropertySource.PROTO, BigInt(123)),
70        ),
71      ).toEqual('123');
72    });
73
74    it('translates default values correctly', () => {
75      expect(
76        DEFAULT_PROPERTY_FORMATTER.format(
77          new PropertyTreeNode('', '', PropertySource.PROTO, []),
78        ),
79      ).toEqual(EMPTY_ARRAY_STRING);
80      expect(
81        DEFAULT_PROPERTY_FORMATTER.format(
82          new PropertyTreeNode('', '', PropertySource.PROTO, false),
83        ),
84      ).toEqual('false');
85      expect(
86        DEFAULT_PROPERTY_FORMATTER.format(
87          new PropertyTreeNode('', '', PropertySource.PROTO, null),
88        ),
89      ).toEqual('null');
90    });
91  });
92
93  describe('ColorFormatter', () => {
94    it('translates empty color to string correctly', () => {
95      expect(
96        COLOR_FORMATTER.format(TreeNodeUtils.makeColorNode(-1, -1, -1, 1)),
97      ).toEqual(`${EMPTY_OBJ_STRING}, alpha: 1`);
98      expect(
99        COLOR_FORMATTER.format(TreeNodeUtils.makeColorNode(1, 1, 1, 0)),
100      ).toEqual(`${EMPTY_OBJ_STRING}, alpha: 0`);
101    });
102
103    it('translates non-empty color to string correctly', () => {
104      expect(
105        COLOR_FORMATTER.format(TreeNodeUtils.makeColorNode(1, 2, 3, 1)),
106      ).toEqual('(1, 2, 3), alpha: 1');
107      expect(
108        COLOR_FORMATTER.format(TreeNodeUtils.makeColorNode(1, 2, 3, 0.608)),
109      ).toEqual('(1, 2, 3), alpha: 0.608');
110    });
111
112    it('translates rgb color without alpha to string correctly (transactions)', () => {
113      expect(
114        COLOR_FORMATTER.format(TreeNodeUtils.makeColorNode(1, 2, 3, undefined)),
115      ).toEqual('(1, 2, 3)');
116      expect(
117        COLOR_FORMATTER.format(
118          TreeNodeUtils.makeColorNode(0.106, 0.203, 0.313, undefined),
119        ),
120      ).toEqual('(0.106, 0.203, 0.313)');
121    });
122  });
123
124  describe('RectFormatter', () => {
125    it('translates empty rect to string correctly', () => {
126      expect(
127        RECT_FORMATTER.format(TreeNodeUtils.makeRectNode(0, 0, -1, -1)),
128      ).toEqual(EMPTY_OBJ_STRING);
129      expect(
130        RECT_FORMATTER.format(TreeNodeUtils.makeRectNode(0, 0, 0, 0)),
131      ).toEqual(EMPTY_OBJ_STRING);
132    });
133
134    it('translates non-empty rect to string correctly', () => {
135      expect(
136        RECT_FORMATTER.format(TreeNodeUtils.makeRectNode(0, 0, 1, 1)),
137      ).toEqual('(0, 0) - (1, 1)');
138      expect(
139        RECT_FORMATTER.format(TreeNodeUtils.makeRectNode(0, 0, 10, 10)),
140      ).toEqual('(0, 0) - (10, 10)');
141      expect(
142        RECT_FORMATTER.format(
143          TreeNodeUtils.makeRectNode(0, 1.6431, 10456.9086, 10),
144        ),
145      ).toEqual('(0, 1.643) - (10456.909, 10)');
146    });
147  });
148
149  describe('BufferFormatter', () => {
150    it('translates buffer to string correctly', () => {
151      const buffer = TreeNodeUtils.makeBufferNode();
152      expect(BUFFER_FORMATTER.format(buffer)).toEqual(
153        'w: 1, h: 0, stride: 0, format: 1',
154      );
155    });
156  });
157
158  describe('LayerIdFormatter', () => {
159    it('translates -1 id correctly', () => {
160      expect(
161        LAYER_ID_FORMATTER.format(
162          new PropertyTreeNode('', '', PropertySource.PROTO, -1),
163        ),
164      ).toEqual('none');
165    });
166
167    it('translates valid id correctly', () => {
168      expect(
169        LAYER_ID_FORMATTER.format(
170          new PropertyTreeNode('', '', PropertySource.PROTO, 1),
171        ),
172      ).toEqual('1');
173      expect(
174        LAYER_ID_FORMATTER.format(
175          new PropertyTreeNode('', '', PropertySource.PROTO, -10),
176        ),
177      ).toEqual('-10');
178    });
179  });
180
181  describe('MatrixFormatter', () => {
182    it('translates matrix correctly', () => {
183      expect(
184        MATRIX_FORMATTER.format(
185          TreeNodeUtils.makeMatrixNode(
186            IDENTITY_MATRIX.dsdx,
187            IDENTITY_MATRIX.dtdx,
188            IDENTITY_MATRIX.dtdy,
189            IDENTITY_MATRIX.dsdy,
190          ),
191        ),
192      ).toEqual('dsdx: 1, dtdx: 0, dtdy: 0, dsdy: 1');
193      expect(
194        MATRIX_FORMATTER.format(
195          TreeNodeUtils.makeMatrixNode(0.4, 100, 1, 0.1232),
196        ),
197      ).toEqual('dsdx: 0.400, dtdx: 100, dtdy: 1, dsdy: 0.123');
198      expect(
199        MATRIX_FORMATTER.format(TreeNodeUtils.makeMatrixNode(0, 0, 0, 0)),
200      ).toEqual('null');
201      expect(
202        MATRIX_FORMATTER.format(
203          TreeNodeUtils.makePropertyNode('test node', 'transform', {
204            dsdx: 1,
205            dtdx: 0,
206            tx: 5,
207            dtdy: 0,
208            dsdy: 1,
209            ty: 10,
210          }),
211        ),
212      ).toEqual('dsdx: 1, dtdx: 0, dtdy: 0, dsdy: 1, tx: 5, ty: 10');
213    });
214  });
215
216  describe('TransformFormatter', () => {
217    it('translates type correctly', () => {
218      expect(
219        TRANSFORM_FORMATTER.format(
220          TreeNodeUtils.makeTransformNode(TransformTypeFlags.EMPTY),
221        ),
222      ).toEqual('IDENTITY');
223      expect(
224        TRANSFORM_FORMATTER.format(
225          TreeNodeUtils.makeTransformNode(TransformTypeFlags.TRANSLATE_VAL),
226        ),
227      ).toEqual('TRANSLATE');
228      expect(
229        TRANSFORM_FORMATTER.format(
230          TreeNodeUtils.makeTransformNode(TransformTypeFlags.SCALE_VAL),
231        ),
232      ).toEqual('SCALE');
233      expect(
234        TRANSFORM_FORMATTER.format(
235          TreeNodeUtils.makeTransformNode(TransformTypeFlags.FLIP_H_VAL),
236        ),
237      ).toEqual('IDENTITY|FLIP_H');
238      expect(
239        TRANSFORM_FORMATTER.format(
240          TreeNodeUtils.makeTransformNode(TransformTypeFlags.FLIP_V_VAL),
241        ),
242      ).toEqual('IDENTITY|FLIP_V');
243      expect(
244        TRANSFORM_FORMATTER.format(
245          TreeNodeUtils.makeTransformNode(TransformTypeFlags.ROT_90_VAL),
246        ),
247      ).toEqual('IDENTITY|ROT_90');
248      expect(
249        TRANSFORM_FORMATTER.format(
250          TreeNodeUtils.makeTransformNode(TransformTypeFlags.ROT_INVALID_VAL),
251        ),
252      ).toEqual('IDENTITY|ROT_INVALID');
253    });
254  });
255
256  describe('SizeFormatter', () => {
257    it('translates size correctly', () => {
258      expect(SIZE_FORMATTER.format(TreeNodeUtils.makeSizeNode(1, 2))).toEqual(
259        '1 x 2',
260      );
261    });
262  });
263
264  describe('PositionFormatter', () => {
265    it('translates position correctly', () => {
266      expect(
267        POSITION_FORMATTER.format(TreeNodeUtils.makePositionNode(1, 2)),
268      ).toEqual('x: 1, y: 2');
269      expect(
270        POSITION_FORMATTER.format(TreeNodeUtils.makePositionNode(1.5, 2.2916)),
271      ).toEqual('x: 1.500, y: 2.292');
272    });
273  });
274
275  describe('RegionFormatter', () => {
276    it('translates region correctly', () => {
277      const region = new PropertyTreeBuilder()
278        .setRootId('test node')
279        .setName('region')
280        .setChildren([{name: 'rect', value: []}])
281        .build();
282
283      const rectNode = assertDefined(region.getChildByName('rect'));
284      rectNode.addOrReplaceChild(TreeNodeUtils.makeRectNode(0, 0, 1080, 2340));
285
286      expect(REGION_FORMATTER.format(region)).toEqual(
287        'SkRegion((0, 0, 1080, 2340))',
288      );
289    });
290  });
291
292  describe('CujTypeFormatter', () => {
293    it('translates known cuj type correctly', () => {
294      const cujType = new PropertyTreeBuilder()
295        .setRootId('test node')
296        .setName('cujType')
297        .setValue(66)
298        .build();
299
300      expect(CUJ_TYPE_FORMATTER.format(cujType)).toEqual(
301        'CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS (66)',
302      );
303    });
304
305    it('translates unknown cuj type correctly', () => {
306      const cujType = new PropertyTreeBuilder()
307        .setRootId('test node')
308        .setName('cujType')
309        .setValue(-1)
310        .build();
311
312      expect(CUJ_TYPE_FORMATTER.format(cujType)).toEqual('UNKNOWN (-1)');
313    });
314  });
315
316  describe('hex formatting', () => {
317    it('formatAsHex()', () => {
318      expect(formatAsHex(0)).toEqual('0x0');
319      expect(formatAsHex(1024)).toEqual('0x400');
320      expect(formatAsHex(-1024)).toEqual('0xfffffc00');
321      expect(formatAsHex(-1024, true)).toEqual('0xFFFFFC00');
322    });
323
324    it('HexFormatter', () => {
325      const hashcode = new PropertyTreeBuilder()
326        .setRootId('test node')
327        .setName('hashcode')
328        .setValue(1024)
329        .build();
330      expect(HEX_FORMATTER.format(hashcode)).toEqual('0x400');
331    });
332  });
333});
334