1/*
2 * Copyright 2020, 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 { shortenName } from '../mixin'
18
19import {
20    Configuration,
21    ConfigurationContainer,
22    toRect,
23    WindowConfiguration,
24    WindowContainer,
25    WindowContainerChild,
26 } from "../common"
27
28import Activity from "./Activity"
29import DisplayArea from "./DisplayArea"
30import DisplayContent from "./DisplayContent"
31import Task from "./Task"
32import TaskFragment from "./TaskFragment"
33import WindowState from "./WindowState"
34import WindowToken from "./WindowToken"
35
36WindowContainer.fromProto = function (
37    proto: any,
38    protoChildren: any[],
39    isActivityInTree: boolean,
40    nameOverride: string = null,
41    identifierOverride: string = null,
42    tokenOverride = null,
43): WindowContainer {
44    if (proto == null) {
45        return null;
46    }
47
48    const children = protoChildren
49        .filter(it => it != null)
50        .map(it => WindowContainer.childrenFromProto(it, isActivityInTree));
51
52    const identifier = identifierOverride ?? proto.identifier;
53    var name = nameOverride ?? identifier?.title ?? "";
54    var token = tokenOverride?.toString(16) ?? identifier?.hashCode?.toString(16) ?? "";
55
56    const config = createConfigurationContainer(proto.configurationContainer);
57    const entry = new WindowContainer(
58        name,
59        token,
60        proto.orientation,
61        proto.surfaceControl?.layerId ?? 0,
62        proto.visible,
63        config,
64        children
65    );
66
67    addAttributes(entry, proto);
68    return entry;
69}
70
71function addAttributes(entry: WindowContainer, proto: any) {
72    entry.proto = proto;
73    entry.kind = entry.constructor.name;
74    entry.shortName = shortenName(entry.name);
75}
76
77WindowContainer.childrenFromProto = function(proto: any, isActivityInTree: Boolean): WindowContainerChild {
78    return DisplayContent.fromProto(proto.displayContent, isActivityInTree) ??
79        DisplayArea.fromProto(proto.displayArea, isActivityInTree) ??
80        Task.fromProto(proto.task, isActivityInTree) ??
81        TaskFragment.fromProto(proto.taskFragment, isActivityInTree) ??
82        Activity.fromProto(proto.activity) ??
83        WindowToken.fromProto(proto.windowToken, isActivityInTree) ??
84        WindowState.fromProto(proto.window, isActivityInTree) ??
85        WindowContainer.fromProto(proto.windowContainer);
86}
87
88function createConfigurationContainer(proto: any): ConfigurationContainer {
89    const entry = new ConfigurationContainer(
90        createConfiguration(proto?.overrideConfiguration ?? null),
91        createConfiguration(proto?.fullConfiguration ?? null),
92        createConfiguration(proto?.mergedOverrideConfiguration ?? null)
93    );
94
95    entry.obj = entry;
96    return entry;
97}
98
99function createConfiguration(proto: any): Configuration {
100    if (proto == null) {
101        return null;
102    }
103    var windowConfiguration = null;
104
105    if (proto != null && proto.windowConfiguration != null) {
106        windowConfiguration = createWindowConfiguration(proto.windowConfiguration);
107    }
108
109    return new Configuration(
110        windowConfiguration,
111        proto?.densityDpi ?? 0,
112        proto?.orientation ?? 0,
113        proto?.screenHeightDp ?? 0,
114        proto?.screenHeightDp ?? 0,
115        proto?.smallestScreenWidthDp ?? 0,
116        proto?.screenLayout ?? 0,
117        proto?.uiMode ?? 0
118    );
119}
120
121function createWindowConfiguration(proto: any): WindowConfiguration {
122    return new WindowConfiguration(
123        toRect(proto.appBounds),
124        toRect(proto.bounds),
125        toRect(proto.maxBounds),
126        proto.windowingMode,
127        proto.activityType
128    );
129}
130
131export default WindowContainer;
132