blob: d591739509a611e1e94e58b9501ac060f0ea27c3 [file]
/*
* Copyright 2020, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { WindowContainer } from "../common"
import { applyMixins } from '../mixin'
import IClickableTreeViewElement from '../treeview/IClickableTreeViewElement'
import { TreeViewObject } from '../treeview/types'
import DisplayArea from "./DisplayArea"
import DisplayContent from "./DisplayContent"
import Task from "./Task"
import ActivityRecord from "./ActivityRecord"
import WindowToken from "./WindowToken"
import WindowState from "./WindowState"
import { CompatibleFeatures } from '@/utils/compatibility.js'
export class WindowContainerMixin implements IClickableTreeViewElement {
title: string
windowHashCode: number
childrenWindows
visible: boolean
rawTreeViewObject
_obj: { name: string }
_children
get kind() {
return "WindowContainer"
}
get name() {
if (this.obj && this.obj.name) {
return this.obj.name
}
if (["WindowContainer", "Task"].includes(this.title)) {
return null
}
return `${removeRedundancyInName(this.title)}@${this.windowHashCode}`
}
get shortName() {
return this.name ? shortenName(this.name) : null
}
get stableId() {
return this.windowHashCode
}
get children() {
return this._children ?? this.childrenWindows
}
set children(children) {
this._children = children
}
get chips() {
return []
}
set obj(obj) {
this._obj = obj
}
get obj() {
return this._obj
}
static fromProto(proto) {
const children = proto.children.map(
child => transformWindowContainerChildProto(child))
// A kind of hacky way to check if the proto is from a device which
// didn't have the changes required for the diff viewer to work properly
// We required that all elements have a stable identifier in order to do the
// diff properly. In theory properties diff would still work, but are
// currently disabled. If required in the future don't hesitate to make
// the required changes.
if (!proto.identifier) {
CompatibleFeatures.DiffVisualization = false;
}
const title = proto.identifier.title
const hashCode = proto.identifier.hashCode
const visible = proto.visible
const windowContainer =
new WindowContainer(children, title, hashCode, visible)
const obj = Object.assign({}, proto)
// we remove the children property from the object to avoid it showing the
// the properties view of the element as we can always see those elements'
// properties by changing the target element in the hierarchy tree view.
delete obj.children
windowContainer.attachObject(obj)
return windowContainer
}
attachObject(obj) {
this._obj = obj
}
asRawTreeViewObject(): TreeViewObject {
// IMPORTANT: We want to always return the same tree view object and not
// generate a new one every time this function is called.
if (!this.rawTreeViewObject) {
const children = this.children.map(child => child.asRawTreeViewObject())
this.rawTreeViewObject = {
kind: this.kind,
name: this.name,
shortName: this.shortName,
stableId: this.stableId,
chips: this.chips,
obj: this.obj,
children,
ref: this,
};
}
return this.rawTreeViewObject;
}
}
applyMixins(WindowContainer, [WindowContainerMixin])
function transformWindowContainerChildProto(proto) {
if (proto.displayArea != null) {
return DisplayArea.fromProto(proto.displayArea)
}
if (proto.displayContent != null) {
return DisplayContent.fromProto(proto.displayContent)
}
if (proto.task != null) {
return Task.fromProto(proto.task)
}
if (proto.activity != null) {
return ActivityRecord.fromProto(proto.activity)
}
if (proto.windowToken != null) {
return WindowToken.fromProto(proto.windowToken)
}
if (proto.window != null) {
return WindowState.fromProto(proto.window)
}
throw new Error("Unhandled WindowContainerChildProto case...")
}
function removeRedundancyInName(name: string): string {
if (!name.includes('/')) {
return name
}
const split = name.split('/')
const pkg = split[0]
var clazz = split.slice(1).join("/")
if (clazz.startsWith("$pkg.")) {
clazz = clazz.slice(pkg.length + 1)
return "$pkg/$clazz"
}
return name
}
function shortenName(name: string): string {
const classParts = name.split(".")
if (classParts.length <= 3) {
return name
}
const className = classParts.slice(-1)[0] // last element
return `${classParts[0]}.${classParts[1]}.(...).${className}`
}
export default WindowContainer