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, assertTrue} from 'common/assert_utils';
18import {DisplayLayerStack} from 'trace/display_layer_stack';
19import {Operation} from 'trace/tree_node/operations/operation';
20import {PropertyTreeNode} from 'trace/tree_node/property_tree_node';
21import {DEFAULT_PROPERTY_TREE_NODE_FACTORY} from 'trace/tree_node/property_tree_node_factory';
22
23export class AddDisplayProperties implements Operation<PropertyTreeNode> {
24  apply(value: PropertyTreeNode): void {
25    const displays = value.getChildByName('displays');
26
27    if (!displays) return;
28
29    for (const display of displays.getAllChildren()) {
30      const dpiX = display.getChildByName('dpiX');
31      const dpiY = display.getChildByName('dpiY');
32
33      if (!(dpiX && dpiY)) continue;
34
35      const size = assertDefined(display.getChildByName('size'));
36      const width = assertDefined(size.getChildByName('w')).getValue();
37      const height = assertDefined(size.getChildByName('h')).getValue();
38      const smallestWidth = this.dpiFromPx(
39        Math.min(width, height),
40        Number(dpiX.getValue()),
41      );
42
43      display.addOrReplaceChild(
44        DEFAULT_PROPERTY_TREE_NODE_FACTORY.makeCalculatedProperty(
45          display.id,
46          'isLargeScreen',
47          smallestWidth >= AddDisplayProperties.TABLET_MIN_DPS,
48        ),
49      );
50
51      const layerStack = assertDefined(
52        display.getChildByName('layerStack'),
53      ).getValue();
54
55      assertTrue(
56        layerStack !== -1 && layerStack !== -1n,
57        () =>
58          'layerStack = -1; false assumption that layerStack is always unsigned',
59      );
60
61      display.addOrReplaceChild(
62        DEFAULT_PROPERTY_TREE_NODE_FACTORY.makeCalculatedProperty(
63          display.id,
64          'isOn',
65          layerStack !== DisplayLayerStack.INVALID_LAYER_STACK,
66        ),
67      );
68    }
69  }
70
71  private dpiFromPx(size: number, densityDpi: number): number {
72    const densityRatio = densityDpi / AddDisplayProperties.DENSITY_DEFAULT;
73    return size / densityRatio;
74  }
75
76  private static readonly TABLET_MIN_DPS = 600;
77  private static readonly DENSITY_DEFAULT = 160;
78}
79