Make winscope compatible with flicker/CTS infra
Flickerlib is migrating to the same structure as the CTS tests. This cl makes winscope compatible with this changes. It now parses traces with the new information and add a "flickerObj" entry to each node with the calculated vlaues from flickerlib Test: yarn run dev and open a few WM traces Bug: 167521440 Bug: 170372278 Change-Id: I4a116ccabe392c75e5b5049808d4837f865cb2c7
This commit is contained in:
@@ -252,7 +252,8 @@ export default {
|
||||
this.item = item;
|
||||
this.tree = this.generateTreeFromItem(item);
|
||||
|
||||
this.rects = [...item.rects].reverse();
|
||||
const rects = item.rects //.toArray()
|
||||
this.rects = [...rects].reverse();
|
||||
this.bounds = item.bounds;
|
||||
|
||||
this.hierarchySelected = null;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { FILE_TYPES, DUMP_TYPES } from "@/decode.js";
|
||||
import DumpBase from "./DumpBase";
|
||||
|
||||
import { WindowManagerTraceEntry } from '@/flickerlib';
|
||||
import { WindowManagerTrace } from '@/flickerlib';
|
||||
|
||||
export default class WindowManager extends DumpBase {
|
||||
wmDumpFile: any;
|
||||
@@ -32,7 +32,7 @@ export default class WindowManager extends DumpBase {
|
||||
return DUMP_TYPES.WINDOW_MANAGER;
|
||||
}
|
||||
|
||||
static fromProto(proto): WindowManagerTraceEntry {
|
||||
return WindowManagerTraceEntry.fromProto(proto);
|
||||
static fromProto(proto): WindowManagerTrace {
|
||||
return WindowManagerTrace.fromDump(proto);
|
||||
}
|
||||
}
|
||||
110
tools/winscope/src/flickerlib/WindowManagerState.ts
Normal file
110
tools/winscope/src/flickerlib/WindowManagerState.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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 { nanosToString, TimeUnits } from "../utils/utils.js"
|
||||
import { getWMPropertiesForDisplay } from './mixin'
|
||||
|
||||
import {
|
||||
KeyguardControllerState,
|
||||
RootWindowContainer,
|
||||
WindowManagerPolicy,
|
||||
WindowManagerState
|
||||
} from "./common"
|
||||
|
||||
import WindowContainer from "./windows/WindowContainer"
|
||||
|
||||
|
||||
WindowManagerState.fromProto = function ({proto, timestamp = 0, where = ""}): WindowManagerState {
|
||||
var inputMethodWIndowAppToken = ""
|
||||
if (proto.inputMethodWindow != null) {
|
||||
proto.inputMethodWindow.hashCode.toString(16)
|
||||
}
|
||||
const rootWindowContainer = newRootWindowContainer(proto.rootWindowContainer)
|
||||
const keyguardControllerState = newKeyguardControllerState(
|
||||
proto.rootWindowContainer.keyguardController)
|
||||
const entry = new WindowManagerState(
|
||||
where,
|
||||
newWindowManagerPolicy(proto.policy),
|
||||
proto.focusedApp,
|
||||
proto.focusedDisplayId,
|
||||
proto.focusedWindow?.title ?? "",
|
||||
inputMethodWIndowAppToken,
|
||||
proto.rootWindowContainer.isHomeRecentsComponent,
|
||||
proto.displayFrozen,
|
||||
proto.rotation,
|
||||
proto.lastOrientation,
|
||||
proto.rootWindowContainer.pendingActivities.map(it => it.title),
|
||||
rootWindowContainer,
|
||||
keyguardControllerState,
|
||||
timestamp = timestamp
|
||||
)
|
||||
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.name = nanosToString(entry.timestamp, TimeUnits.MILLI_SECONDS)
|
||||
entry.shortName = entry.name
|
||||
entry.children = entry.root.childrenWindows.reverse()
|
||||
entry.chips = []
|
||||
entry.visible = true
|
||||
return entry
|
||||
}
|
||||
|
||||
function newWindowManagerPolicy(proto): WindowManagerPolicy {
|
||||
return new WindowManagerPolicy(
|
||||
proto.focusedAppToken || "",
|
||||
proto.forceStatusBar,
|
||||
proto.forceStatusBarFromKeyguard,
|
||||
proto.keyguardDrawComplete,
|
||||
proto.keyguardOccluded,
|
||||
proto.keyguardOccludedChanged,
|
||||
proto.keyguardOccludedPending,
|
||||
proto.lastSystemUiFlags,
|
||||
proto.orientation,
|
||||
proto.rotation,
|
||||
proto.rotationMode,
|
||||
proto.screenOnFully,
|
||||
proto.windowManagerDrawComplete
|
||||
)
|
||||
}
|
||||
|
||||
function newRootWindowContainer(proto): RootWindowContainer {
|
||||
const windowContainer = WindowContainer.fromProto({proto: proto.windowContainer})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
const entry = new RootWindowContainer(windowContainer)
|
||||
proto.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, /* isActivityInTree */ false))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
return entry
|
||||
}
|
||||
|
||||
function newKeyguardControllerState(proto): KeyguardControllerState {
|
||||
const keyguardOccludedStates = {}
|
||||
|
||||
if (proto) {
|
||||
proto.keyguardOccludedStates.forEach(it =>
|
||||
keyguardOccludedStates[it.displayId] = it.keyguardOccluded)
|
||||
}
|
||||
|
||||
return new KeyguardControllerState(
|
||||
proto?.aodShowing ?? false,
|
||||
proto?.keyguardShowing ?? false,
|
||||
keyguardOccludedStates
|
||||
)
|
||||
}
|
||||
|
||||
export default WindowManagerState;
|
||||
@@ -14,23 +14,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
WindowManagerTrace,
|
||||
} from "./common"
|
||||
|
||||
import WindowManagerTraceEntry from "./WindowManagerTraceEntry"
|
||||
import { WindowManagerTrace } from "./common"
|
||||
import WindowManagerState from "./WindowManagerState"
|
||||
|
||||
WindowManagerTrace.fromProto = function (proto) {
|
||||
const entries = []
|
||||
for (const entryProto of proto.entry) {
|
||||
const transformedEntry = WindowManagerTraceEntry.fromProto(
|
||||
entryProto.windowManagerService, entryProto.elapsedRealtimeNanos)
|
||||
const transformedEntry = WindowManagerState.fromProto({
|
||||
proto: entryProto.windowManagerService,
|
||||
timestamp: entryProto.elapsedRealtimeNanos,
|
||||
where: entryProto.where})
|
||||
entries.push(transformedEntry)
|
||||
}
|
||||
|
||||
const source = null;
|
||||
const sourceChecksum = null;
|
||||
}
|
||||
const source = null
|
||||
const sourceChecksum = null
|
||||
return new WindowManagerTrace(entries, source, sourceChecksum)
|
||||
}
|
||||
|
||||
WindowManagerTrace.fromDump = function(proto): WindowManagerTrace {
|
||||
return WindowManagerState.fromProto({proto: proto})
|
||||
}
|
||||
|
||||
export default WindowManagerTrace;
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* 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 { nanosToString, TimeUnits } from "../utils/utils.js"
|
||||
|
||||
import { WindowManagerTraceEntry } from "./common"
|
||||
|
||||
import { applyMixins } from "./mixin"
|
||||
|
||||
import ITreeViewElement from './treeview/IClickableTreeViewElement'
|
||||
import IClickableTreeViewElement from './treeview/IClickableTreeViewElement'
|
||||
import Chip from './treeview/Chip'
|
||||
import WindowContainer from "./windows/WindowContainer"
|
||||
|
||||
class WindowManagerTraceEntryMixin implements IClickableTreeViewElement {
|
||||
common: any
|
||||
kind: string
|
||||
name: string
|
||||
shortName: string
|
||||
stableId: string
|
||||
chips: Array<Chip>
|
||||
children: Array<ITreeViewElement>
|
||||
obj: any
|
||||
rawTreeViewObject
|
||||
|
||||
timestamp: number
|
||||
rootWindow
|
||||
|
||||
mixinConstructor(obj) {
|
||||
const name = this.timestamp ? nanosToString(this.timestamp, TimeUnits.MILLI_SECONDS) : ""
|
||||
this.kind = "entry"
|
||||
this.name = name
|
||||
this.shortName = name
|
||||
this.stableId = "entry"
|
||||
this.children = this.rootWindow.children
|
||||
this.chips = []
|
||||
this.obj = obj
|
||||
}
|
||||
|
||||
static fromProto(proto, timestamp) {
|
||||
const rootWindow =
|
||||
WindowContainer.fromProto(proto.rootWindowContainer.windowContainer, null)
|
||||
const windowManagerTraceEntry =
|
||||
new WindowManagerTraceEntry(rootWindow, timestamp)
|
||||
|
||||
windowManagerTraceEntry.kind = 'service'
|
||||
|
||||
windowManagerTraceEntry.focusedApp = proto.focusedApp
|
||||
windowManagerTraceEntry.focusedDisplayId = proto.focusedDisplayId
|
||||
windowManagerTraceEntry.lastOrientation = proto.lastOrientation
|
||||
windowManagerTraceEntry.policy = proto.policy
|
||||
windowManagerTraceEntry.rotation = proto.rotation
|
||||
windowManagerTraceEntry.displayFrozen = proto.displayFrozen
|
||||
windowManagerTraceEntry.inputMethodWindow = proto.inputMethodWindow
|
||||
|
||||
// Remove anything that is part of the children elements
|
||||
// allows for faster loading of properties and less information cluttering
|
||||
// this applied to anywhere the proto is passed to be saved as .obj
|
||||
const obj = Object.assign({}, proto)
|
||||
obj.rootWindowContainer = {};
|
||||
Object.assign(obj.rootWindowContainer,
|
||||
proto.rootWindowContainer)
|
||||
obj.rootWindowContainer.windowContainer = {};
|
||||
Object.assign(obj.rootWindowContainer.windowContainer,
|
||||
proto.rootWindowContainer.windowContainer)
|
||||
delete obj.rootWindowContainer.windowContainer.children
|
||||
windowManagerTraceEntry.mixinConstructor(obj)
|
||||
|
||||
return windowManagerTraceEntry
|
||||
}
|
||||
|
||||
attachObject(obj) {
|
||||
this.obj = obj
|
||||
}
|
||||
|
||||
asRawTreeViewObject() {
|
||||
// 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(WindowManagerTraceEntry, [WindowManagerTraceEntryMixin])
|
||||
|
||||
export default WindowManagerTraceEntry;
|
||||
@@ -17,42 +17,69 @@
|
||||
// Imports all the compiled common Flicker library classes and exports them
|
||||
// as clean es6 modules rather than having them be commonjs modules
|
||||
|
||||
const WindowManagerTrace = require('flicker').com.android.server.wm.flicker
|
||||
.common.traces.windowmanager.WindowManagerTrace;
|
||||
const WindowManagerTraceEntry = require('flicker').com.android.server.wm.
|
||||
flicker.common.traces.windowmanager.WindowManagerTraceEntry;
|
||||
const WindowManagerTrace = require('flicker').com.android.server.wm.flicker.
|
||||
common.traces.windowmanager.WindowManagerTrace;
|
||||
const WindowManagerState = require('flicker').com.android.server.wm.
|
||||
flicker.common.traces.windowmanager.WindowManagerState;
|
||||
|
||||
const WindowContainer = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowContainer;
|
||||
const WindowState = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowState;
|
||||
const DisplayContent = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.DisplayContent;
|
||||
const ActivityRecord = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.ActivityRecord;
|
||||
const WindowToken = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowToken;
|
||||
const Activity = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.Activity;
|
||||
const ActivityTask = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.ActivityTask;
|
||||
const Configuration = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.Configuration;
|
||||
const ConfigurationContainer = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.ConfigurationContainer;
|
||||
const DisplayArea = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.DisplayArea;
|
||||
const RootDisplayArea = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.RootDisplayArea;
|
||||
const Task = require('flicker').com.android.server.wm.flicker.common.traces.
|
||||
windowmanager.windows.Task;
|
||||
const DisplayContent = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.DisplayContent;
|
||||
const KeyguardControllerState = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.KeyguardControllerState;
|
||||
const RootWindowContainer = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.RootWindowContainer;
|
||||
const WindowConfiguration = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowConfiguration;
|
||||
const WindowContainer = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowContainer;
|
||||
const WindowContainerChild = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowContainerChild;
|
||||
const WindowManagerPolicy = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowManagerPolicy;
|
||||
const WindowState = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowState;
|
||||
const WindowToken = require('flicker').com.android.server.wm.flicker.common.
|
||||
traces.windowmanager.windows.WindowToken;
|
||||
|
||||
const Rect = require('flicker').com.android.server.wm.flicker.common.Rect;
|
||||
const Bounds = require('flicker').com.android.server.wm.flicker.common.Bounds;
|
||||
|
||||
function toRect(proto) {
|
||||
if (proto == null) {
|
||||
return new Rect(0, 0, 0, 0)
|
||||
} else {
|
||||
return new Rect(proto.left, proto.top, proto.right, proto.bottom)
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
WindowManagerTrace,
|
||||
WindowManagerTraceEntry,
|
||||
WindowContainer,
|
||||
WindowState,
|
||||
DisplayContent,
|
||||
ActivityRecord,
|
||||
WindowToken,
|
||||
Activity,
|
||||
ActivityTask,
|
||||
Configuration,
|
||||
ConfigurationContainer,
|
||||
DisplayArea,
|
||||
RootDisplayArea,
|
||||
Task,
|
||||
DisplayContent,
|
||||
KeyguardControllerState,
|
||||
RootWindowContainer,
|
||||
WindowConfiguration,
|
||||
WindowContainer,
|
||||
WindowContainerChild,
|
||||
WindowState,
|
||||
WindowToken,
|
||||
WindowManagerPolicy,
|
||||
WindowManagerTrace,
|
||||
WindowManagerState,
|
||||
Rect,
|
||||
Bounds,
|
||||
toRect
|
||||
};
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import WindowManagerTraceEntry from './WindowManagerTraceEntry';
|
||||
import WindowManagerState from './WindowManagerState';
|
||||
import WindowManagerTrace from './WindowManagerTrace';
|
||||
|
||||
/**
|
||||
* Entry point into the flickerlib for Winscope.
|
||||
* Expose everything we want Winscope to have access to here.
|
||||
*/
|
||||
export {WindowManagerTraceEntry, WindowManagerTrace};
|
||||
export {WindowManagerState, WindowManagerTrace};
|
||||
|
||||
|
||||
@@ -1,23 +1,44 @@
|
||||
/**
|
||||
* Injects all the properties (getters, setters, functions...) of a list of
|
||||
* classes (baseCtors) into a class (derivedCtor).
|
||||
* @param derivedCtor The constructor of the class we want to inject the
|
||||
* properties into.
|
||||
* @param baseCtors A list of consturctor of the classes we want to mixin the
|
||||
* properties of into the derivedCtor.
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
export function applyMixins(derivedCtor: any, baseCtors: any[]) {
|
||||
baseCtors.forEach(baseCtor => {
|
||||
Object.getOwnPropertyNames(baseCtor).forEach(name => {
|
||||
if (['length', 'name', 'prototype'].includes(name)) {
|
||||
return;
|
||||
|
||||
/**
|
||||
* Get the properties of a WM object for display.
|
||||
*
|
||||
* @param entry WM hierarchy element
|
||||
* @param proto Associated proto object
|
||||
*/
|
||||
export function getWMPropertiesForDisplay(proto: any): any {
|
||||
const obj = Object.assign({}, proto)
|
||||
if (obj.children) delete obj.children
|
||||
if (obj.childWindows) delete obj.childWindows
|
||||
if (obj.childrenWindows) delete obj.childrenWindows
|
||||
if (obj.childContainers) delete obj.childContainers
|
||||
if (obj.identifier) delete obj.identifier
|
||||
if (obj.windowToken) delete obj.windowToken
|
||||
if (obj.rootDisplayArea) delete obj.rootDisplayArea
|
||||
if (obj.rootWindowContainer) delete obj.rootWindowContainer
|
||||
if (obj.windowContainer) delete obj.windowContainer
|
||||
return obj
|
||||
}
|
||||
|
||||
Object.defineProperty(derivedCtor, name, Object.getOwnPropertyDescriptor(baseCtor, name))
|
||||
})
|
||||
|
||||
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
|
||||
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name))
|
||||
})
|
||||
});
|
||||
export function shortenName(name: any): 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}`
|
||||
}
|
||||
53
tools/winscope/src/flickerlib/windows/Activity.ts
Normal file
53
tools/winscope/src/flickerlib/windows/Activity.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
import { Activity } from "../common"
|
||||
import WindowContainer from "./WindowContainer"
|
||||
|
||||
Activity.fromProto = function (proto, parent: WindowContainer): Activity {
|
||||
if (proto == null) {
|
||||
return null
|
||||
} else {
|
||||
const windowContainer = WindowContainer.fromProto({proto: proto.windowToken.windowContainer,
|
||||
identifierOverride: proto.identifier})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
const entry = new Activity(
|
||||
proto.name,
|
||||
proto.state,
|
||||
proto.visible,
|
||||
proto.frontOfTask,
|
||||
proto.procId,
|
||||
proto.translucent,
|
||||
parent,
|
||||
windowContainer
|
||||
)
|
||||
|
||||
proto.windowToken.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, /* isActivityInTree */ true))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
entry.children = entry.childrenWindows
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
export default Activity
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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 {
|
||||
ActivityRecord,
|
||||
} from "../common"
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import WindowToken from "./WindowToken"
|
||||
|
||||
export class ActivityRecordMixin {
|
||||
get kind() {
|
||||
return "DisplayArea"
|
||||
}
|
||||
|
||||
static fromProto(proto) {
|
||||
const windowToken = WindowToken.fromProto(proto.windowToken)
|
||||
|
||||
const activityRecord = new ActivityRecord(windowToken)
|
||||
|
||||
const obj = Object.assign({}, proto)
|
||||
delete proto.windowToken
|
||||
Object.assign(obj, windowToken.obj)
|
||||
activityRecord.attachObject(obj)
|
||||
|
||||
return activityRecord
|
||||
}
|
||||
}
|
||||
|
||||
applyMixins(ActivityRecord, [ActivityRecordMixin])
|
||||
|
||||
export default ActivityRecord
|
||||
62
tools/winscope/src/flickerlib/windows/ActivityTask.ts
Normal file
62
tools/winscope/src/flickerlib/windows/ActivityTask.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
import { ActivityTask, toRect } from "../common"
|
||||
import WindowContainer from "./WindowContainer"
|
||||
|
||||
ActivityTask.fromProto = function (proto, isActivityInTree: Boolean): ActivityTask {
|
||||
if (proto == null) {
|
||||
return null
|
||||
} else {
|
||||
const windowContainer = WindowContainer.fromProto({proto: proto.windowContainer})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
const entry = new ActivityTask(
|
||||
proto.activityType,
|
||||
proto.fillsParent,
|
||||
toRect(proto.bounds),
|
||||
proto.id,
|
||||
proto.rootTaskId,
|
||||
proto.displayId,
|
||||
toRect(proto.lastNonFullscreenBounds),
|
||||
proto.realActivity,
|
||||
proto.origActivity,
|
||||
proto.resizeMode,
|
||||
proto.resumedActivity?.title ?? "",
|
||||
proto.animatingBounds,
|
||||
proto.surfaceWidth,
|
||||
proto.surfaceHeight,
|
||||
proto.createdByOrganizer,
|
||||
proto.minWidth,
|
||||
proto.minHeight,
|
||||
windowContainer
|
||||
)
|
||||
|
||||
proto.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, isActivityInTree))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
entry.children = entry.childrenWindows
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
export default ActivityTask
|
||||
@@ -14,34 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
DisplayArea,
|
||||
} from "../common"
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
import { DisplayArea } from "../common"
|
||||
import WindowContainer from "./WindowContainer"
|
||||
|
||||
export class DisplayAreaMixin {
|
||||
get kind() {
|
||||
return "DisplayArea"
|
||||
DisplayArea.fromProto = function (proto, isActivityInTree: Boolean): DisplayArea {
|
||||
if (proto == null) {
|
||||
return null
|
||||
} else {
|
||||
const windowContainer = WindowContainer.fromProto({proto: proto.windowContainer, nameOverride: proto.name})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
const entry = new DisplayArea(proto.isTaskDisplayArea, windowContainer)
|
||||
|
||||
static fromProto(proto) {
|
||||
const windowContainer = WindowContainer.fromProto(proto.windowContainer,
|
||||
null)
|
||||
proto.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, isActivityInTree))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
|
||||
const displayArea = new DisplayArea(windowContainer)
|
||||
|
||||
const obj = Object.assign({}, proto)
|
||||
delete obj.windowContainer
|
||||
Object.assign(obj, windowContainer.obj)
|
||||
displayArea.attachObject(obj)
|
||||
|
||||
return displayArea
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
entry.children = entry.childrenWindows
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
applyMixins(DisplayArea, [DisplayAreaMixin])
|
||||
|
||||
export default DisplayArea
|
||||
|
||||
@@ -14,50 +14,57 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
DisplayContent,
|
||||
Bounds
|
||||
} from "../common"
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
import { toRect, DisplayContent, Rect } from "../common"
|
||||
import WindowContainer from "./WindowContainer"
|
||||
import DisplayArea from "./DisplayArea"
|
||||
|
||||
export class DisplayContentMixin {
|
||||
get kind() {
|
||||
return "DisplayContent"
|
||||
}
|
||||
|
||||
static fromProto(proto) {
|
||||
let rootDisplayArea;
|
||||
if (proto.rootDisplayArea.windowContainer == null) {
|
||||
// For backward compatibility
|
||||
const windowContainer = WindowContainer.fromProto(proto.windowContainer,
|
||||
null)
|
||||
rootDisplayArea = new DisplayArea(windowContainer)
|
||||
DisplayContent.fromProto = function (proto, isActivityInTree: Boolean): DisplayContent {
|
||||
if (proto == null) {
|
||||
return null
|
||||
} else {
|
||||
// New protos should always be using this
|
||||
rootDisplayArea = DisplayArea.fromProto(proto.rootDisplayArea)
|
||||
const windowContainer = WindowContainer.fromProto({proto: proto.rootDisplayArea.windowContainer,
|
||||
nameOverride: proto.displayInfo?.name ?? null})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
|
||||
const bounds = new Bounds(
|
||||
proto.displayInfo.logicalWidth || 0,
|
||||
proto.displayInfo.logicalHeight || 0,
|
||||
const displayRectWidth = proto.displayInfo?.logicalWidth ?? 0
|
||||
const displayRectHeight = proto.displayInfo?.logicalHeight ?? 0
|
||||
const appRectWidth = proto.displayInfo?.appWidth ?? 0
|
||||
const appRectHeight = proto.displayInfo?.appHeight ?? 0
|
||||
|
||||
const defaultBounds = proto.pinnedStackController?.defaultBounds ?? null
|
||||
const movementBounds = proto.pinnedStackController?.movementBounds ?? null
|
||||
|
||||
const entry = new DisplayContent(
|
||||
proto.id,
|
||||
proto.focusedRootTaskId,
|
||||
proto.resumedActivity?.title ?? "",
|
||||
proto.singleTaskInstance,
|
||||
toRect(defaultBounds),
|
||||
toRect(movementBounds),
|
||||
new Rect(0, 0, displayRectWidth, displayRectHeight),
|
||||
new Rect(0, 0, appRectWidth, appRectHeight),
|
||||
proto.dpi,
|
||||
proto.displayInfo?.flags ?? 0,
|
||||
toRect(proto.displayFrames.stableBounds),
|
||||
proto.surfaceSize,
|
||||
proto.focusedApp,
|
||||
proto.appTransition?.lastUsedAppTransition ?? "",
|
||||
proto.appTransition?.appTransitionState ?? "",
|
||||
windowContainer
|
||||
)
|
||||
|
||||
const displayContent = new DisplayContent(rootDisplayArea, bounds)
|
||||
proto.rootDisplayArea.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, isActivityInTree))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
|
||||
const obj = Object.assign({}, proto)
|
||||
delete obj.windowContainer
|
||||
delete obj.rootDisplayArea
|
||||
Object.assign(obj, rootDisplayArea.obj)
|
||||
displayContent.attachObject(obj)
|
||||
|
||||
return displayContent
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
entry.children = entry.childrenWindows
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
applyMixins(DisplayContent, [DisplayContentMixin])
|
||||
|
||||
export default DisplayContent
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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 { RootDisplayArea } from "../common"
|
||||
import DisplayArea from "./DisplayArea"
|
||||
|
||||
RootDisplayArea.fromProto = DisplayArea.fromProto
|
||||
|
||||
export default DisplayArea
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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 { Task } from "../common"
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import WindowContainer from "./WindowContainer"
|
||||
|
||||
export class TaskMixin {
|
||||
get kind() {
|
||||
return "Task"
|
||||
}
|
||||
|
||||
static fromProto(proto) {
|
||||
const windowContainer = WindowContainer.fromProto(proto.windowContainer,
|
||||
null)
|
||||
|
||||
const task = new Task(windowContainer)
|
||||
|
||||
const obj = Object.assign({}, proto)
|
||||
delete obj.windowContainer
|
||||
Object.assign(obj, windowContainer.obj)
|
||||
task.attachObject(obj)
|
||||
|
||||
return task
|
||||
}
|
||||
}
|
||||
|
||||
applyMixins(Task, [TaskMixin])
|
||||
|
||||
export default Task
|
||||
@@ -14,192 +14,105 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { WindowContainer } from "../common"
|
||||
import { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import IClickableTreeViewElement from '../treeview/IClickableTreeViewElement'
|
||||
import { TreeViewObject } from '../treeview/types'
|
||||
import {
|
||||
Configuration,
|
||||
ConfigurationContainer,
|
||||
toRect,
|
||||
WindowConfiguration,
|
||||
WindowContainer,
|
||||
WindowContainerChild,
|
||||
} from "../common"
|
||||
|
||||
import Activity from "./Activity"
|
||||
import DisplayArea from "./DisplayArea"
|
||||
import DisplayContent from "./DisplayContent"
|
||||
import Task from "./Task"
|
||||
import ActivityRecord from "./ActivityRecord"
|
||||
import WindowToken from "./WindowToken"
|
||||
import ActivityTask from "./ActivityTask"
|
||||
import WindowState from "./WindowState"
|
||||
import WindowToken from "./WindowToken"
|
||||
|
||||
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)) {
|
||||
WindowContainer.fromProto = function ({
|
||||
proto,
|
||||
nameOverride = null,
|
||||
identifierOverride = null,
|
||||
tokenOverride = null
|
||||
}): WindowContainer {
|
||||
if (proto == null) {
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
const identifier = identifierOverride ?? proto.identifier
|
||||
var name = nameOverride ?? identifier?.title ?? ""
|
||||
var token = tokenOverride?.toString(16) ?? identifier?.hashCode?.toString(16) ?? ""
|
||||
|
||||
return `${removeRedundancyInName(this.title)}@${this.windowHashCode}`
|
||||
}
|
||||
const entry = new WindowContainer(
|
||||
name,
|
||||
token,
|
||||
proto.orientation,
|
||||
proto.visible,
|
||||
newConfigurationContainer(proto.configurationContainer)
|
||||
)
|
||||
|
||||
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, parent_identifier) {
|
||||
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 fallback_title = parent_identifier?.title ?? ""
|
||||
const fallback_hashCode = parent_identifier?.hashCode ?? ""
|
||||
const title = proto.identifier?.title ?? fallback_title
|
||||
const hashCode = proto.identifier?.hashCode ?? fallback_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;
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
applyMixins(WindowContainer, [WindowContainerMixin])
|
||||
|
||||
function transformWindowContainerChildProto(proto) {
|
||||
if (proto.displayArea != null) {
|
||||
return DisplayArea.fromProto(proto.displayArea)
|
||||
WindowContainer.childrenFromProto = function(parent: WindowContainer, proto, isActivityInTree: Boolean): WindowContainerChild {
|
||||
return new WindowContainerChild(
|
||||
DisplayContent.fromProto(proto.displayContent, isActivityInTree),
|
||||
DisplayArea.fromProto(proto.displayArea, isActivityInTree),
|
||||
ActivityTask.fromProto(proto.task, isActivityInTree),
|
||||
Activity.fromProto(proto.activity, parent),
|
||||
WindowToken.fromProto(proto.windowToken, isActivityInTree),
|
||||
WindowState.fromProto(proto.window, isActivityInTree),
|
||||
WindowContainer.fromProto({proto: proto.windowContainer})
|
||||
)
|
||||
}
|
||||
|
||||
if (proto.displayContent != null) {
|
||||
return DisplayContent.fromProto(proto.displayContent)
|
||||
function newConfigurationContainer(proto): ConfigurationContainer {
|
||||
const entry = new ConfigurationContainer(
|
||||
newConfiguration(proto?.overrideConfiguration ?? null),
|
||||
newConfiguration(proto?.fullConfiguration ?? null),
|
||||
newConfiguration(proto?.mergedOverrideConfiguration ?? null)
|
||||
)
|
||||
|
||||
entry.kind = "ConfigurationContainer"
|
||||
entry.obj = entry
|
||||
return entry
|
||||
}
|
||||
|
||||
if (proto.task != null) {
|
||||
return Task.fromProto(proto.task)
|
||||
function newConfiguration(proto): Configuration {
|
||||
var windowConfiguration = null
|
||||
|
||||
if (proto != null && proto.windowConfiguration != null) {
|
||||
windowConfiguration = newWindowConfiguration(proto.windowConfiguration)
|
||||
}
|
||||
|
||||
if (proto.activity != null) {
|
||||
return ActivityRecord.fromProto(proto.activity)
|
||||
return new Configuration(
|
||||
windowConfiguration,
|
||||
proto?.densityDpi ?? 0,
|
||||
proto?.orientation ?? 0,
|
||||
proto?.screenHeightDp ?? 0,
|
||||
proto?.screenHeightDp ?? 0,
|
||||
proto?.smallestScreenWidthDp ?? 0,
|
||||
proto?.screenLayout ?? 0,
|
||||
proto?.uiMode ?? 0
|
||||
)
|
||||
}
|
||||
|
||||
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}`
|
||||
function newWindowConfiguration(proto): WindowConfiguration {
|
||||
return new WindowConfiguration(
|
||||
toRect(proto.appBounds),
|
||||
toRect(proto.bounds),
|
||||
toRect(proto.maxBounds),
|
||||
proto.windowingMode,
|
||||
proto.activityType
|
||||
)
|
||||
}
|
||||
|
||||
export default WindowContainer
|
||||
|
||||
@@ -14,43 +14,75 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { WindowState, Rect } from "../common"
|
||||
import { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
import { toRect, WindowState } from "../common"
|
||||
import { VISIBLE_CHIP } from '../treeview/Chips'
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import WindowContainer from "./WindowContainer"
|
||||
|
||||
export class WindowStateMixin {
|
||||
visible: boolean
|
||||
|
||||
get kind() {
|
||||
return "WindowState"
|
||||
WindowState.fromProto = function (proto, isActivityInTree: Boolean): WindowState {
|
||||
if (proto == null) {
|
||||
return null
|
||||
} else {
|
||||
const identifierName = proto.windowContainer.identifier?.title ?? proto.identifier?.title ?? ""
|
||||
var windowType = 0
|
||||
if (identifierName.startsWith(WindowState.STARTING_WINDOW_PREFIX)) {
|
||||
windowType = WindowState.WINDOW_TYPE_STARTING
|
||||
} else if (proto.animatingExit) {
|
||||
windowType = WindowState.WINDOW_TYPE_EXITING
|
||||
} else if (identifierName.startsWith(WindowState.DEBUGGER_WINDOW_PREFIX)) {
|
||||
windowType = WindowState.WINDOW_TYPE_STARTING
|
||||
}
|
||||
|
||||
static fromProto(proto) {
|
||||
const windowContainer = WindowContainer.fromProto(proto.windowContainer,
|
||||
proto.identifier)
|
||||
var nameOverride = identifierName
|
||||
|
||||
const frame = (proto.windowFrames ?? proto).frame ?? {}
|
||||
const rect = new Rect(frame.left ?? 0, frame.top ?? 0, frame.right ?? 0, frame.bottom ?? 0)
|
||||
|
||||
const windowState =
|
||||
new WindowState(windowContainer, /* childWindows */[], rect)
|
||||
|
||||
const obj = Object.assign({}, proto)
|
||||
Object.assign(obj, windowContainer.obj)
|
||||
delete obj.windowContainer
|
||||
windowState.attachObject(obj)
|
||||
|
||||
return windowState
|
||||
if (identifierName.startsWith(WindowState.STARTING_WINDOW_PREFIX)) {
|
||||
nameOverride = identifierName.substring(WindowState.STARTING_WINDOW_PREFIX.length)
|
||||
} else if (identifierName.startsWith(WindowState.DEBUGGER_WINDOW_PREFIX)) {
|
||||
nameOverride = identifierName.substring(WindowState.DEBUGGER_WINDOW_PREFIX.length)
|
||||
}
|
||||
|
||||
get chips() {
|
||||
return this.visible ? [VISIBLE_CHIP] : []
|
||||
}
|
||||
const windowContainer = WindowContainer.fromProto({
|
||||
proto: proto.windowContainer,
|
||||
nameOverride: nameOverride,
|
||||
identifierOverride: proto.identifier})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
|
||||
applyMixins(WindowState, [WindowStateMixin])
|
||||
proto.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, isActivityInTree))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
|
||||
const entry = new WindowState(
|
||||
proto.attributes?.type ?? 0,
|
||||
proto.displayId,
|
||||
proto.stackId,
|
||||
proto.animator?.surface?.layer ?? 0,
|
||||
proto.animator?.surface?.shown ?? false,
|
||||
windowType,
|
||||
toRect(proto.windowFrames?.frame ?? null),
|
||||
toRect(proto.windowFrames?.containingFrame ?? null),
|
||||
toRect(proto.windowFrames?.parentFrame ?? null),
|
||||
toRect(proto.windowFrames?.contentFrame ?? null),
|
||||
toRect(proto.windowFrames?.contentInsets ?? null),
|
||||
toRect(proto.surfaceInsets),
|
||||
toRect(proto.givenContentInsets),
|
||||
toRect(proto.animator?.lastClipRect ?? null),
|
||||
windowContainer,
|
||||
/* isAppWindow */ isActivityInTree
|
||||
)
|
||||
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
entry.visible = entry.isVisible ?? false
|
||||
entry.chips = entry.isVisible ? [VISIBLE_CHIP] : []
|
||||
entry.children = entry.childrenWindows
|
||||
if (entry.isVisible) {
|
||||
entry.rect = entry.rects[0]
|
||||
}
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
export default WindowState
|
||||
|
||||
@@ -14,32 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { getWMPropertiesForDisplay, shortenName } from '../mixin'
|
||||
import { WindowToken } from "../common"
|
||||
|
||||
import { applyMixins } from '../mixin'
|
||||
|
||||
import WindowContainer from "./WindowContainer"
|
||||
|
||||
export class WindowContainerMixin {
|
||||
get kind() {
|
||||
return "WindowToken"
|
||||
WindowToken.fromProto = function (proto, isActivityInTree: Boolean): WindowToken {
|
||||
if (proto == null) {
|
||||
return null
|
||||
} else {
|
||||
const windowContainer = WindowContainer.fromProto({proto: proto.windowContainer, tokenOverride: proto.hashCode})
|
||||
if (windowContainer == null) {
|
||||
throw "Window container should not be null: " + JSON.stringify(proto)
|
||||
}
|
||||
const entry = new WindowToken(windowContainer)
|
||||
|
||||
static fromProto(proto) {
|
||||
const windowContainer = WindowContainer.fromProto(proto.windowContainer,
|
||||
null)
|
||||
proto.windowContainer.children.reverse()
|
||||
.map(it => WindowContainer.childrenFromProto(entry, it, isActivityInTree))
|
||||
.filter(it => it != null)
|
||||
.forEach(it => windowContainer.childContainers.push(it))
|
||||
|
||||
const windowToken = new WindowToken(windowContainer)
|
||||
|
||||
const obj = Object.assign({}, proto)
|
||||
Object.assign(obj, windowContainer.obj)
|
||||
delete obj.windowContainer
|
||||
windowToken.attachObject(obj)
|
||||
|
||||
return windowToken
|
||||
entry.obj = getWMPropertiesForDisplay(proto)
|
||||
entry.shortName = shortenName(entry.name)
|
||||
entry.children = entry.childrenWindows
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
applyMixins(WindowToken, [WindowContainerMixin])
|
||||
|
||||
export default WindowToken
|
||||
|
||||
@@ -373,6 +373,11 @@ function getIntFlagsAsStrings(intFlags, annotationType) {
|
||||
|
||||
const mapping = intDefMapping[annotationType].values;
|
||||
|
||||
if (mapping.length == 0) {
|
||||
console.warn("No mapping for type", annotationType)
|
||||
return intFlags + ""
|
||||
}
|
||||
|
||||
// Will only contain bits that have not been associated with a flag.
|
||||
let leftOver = intFlags;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user