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