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 {TimeUtils} from 'common/time_utils'; 18import {ElapsedTimestamp, RealTimestamp} from 'trace/timestamp'; 19import { 20 KeyguardControllerState, 21 RootWindowContainer, 22 Rotation, 23 WindowManagerPolicy, 24 WindowManagerState, 25 WindowManagerTraceEntryBuilder, 26} from '../common'; 27 28import {WindowContainer} from './WindowContainer'; 29 30WindowManagerState.fromProto = ( 31 proto: any, 32 elapsedTimestamp: bigint = 0n, 33 where: string = '', 34 realToElapsedTimeOffsetNs: bigint | undefined = undefined, 35 useElapsedTime = false 36): WindowManagerState => { 37 let inputMethodWIndowAppToken = ''; 38 if (proto.inputMethodWindow != null) { 39 inputMethodWIndowAppToken = proto.inputMethodWindow.hashCode.toString(16); 40 } 41 42 let parseOrder = 0; 43 const nextSeq = () => ++parseOrder; 44 const rootWindowContainer = createRootWindowContainer(proto.rootWindowContainer, nextSeq); 45 const keyguardControllerState = createKeyguardControllerState( 46 proto.rootWindowContainer.keyguardController 47 ); 48 const policy = createWindowManagerPolicy(proto.policy); 49 50 const entry = new WindowManagerTraceEntryBuilder() 51 .setElapsedTimestamp(`${elapsedTimestamp}`) 52 .setPolicy(policy) 53 .setFocusedApp(proto.focusedApp) 54 .setFocusedDisplayId(proto.focusedDisplayId) 55 .setFocusedWindow(proto.focusedWindow?.title ?? '') 56 .setInputMethodWindowAppToken(inputMethodWIndowAppToken) 57 .setIsHomeRecentsComponent(proto.rootWindowContainer.isHomeRecentsComponent) 58 .setIsDisplayFrozen(proto.displayFrozen) 59 .setPendingActivities(proto.rootWindowContainer.pendingActivities.map((it: any) => it.title)) 60 .setRoot(rootWindowContainer) 61 .setKeyguardControllerState(keyguardControllerState) 62 .setWhere(where) 63 .setRealToElapsedTimeOffsetNs(`${realToElapsedTimeOffsetNs ?? 0}`) 64 .build(); 65 66 addAttributes(entry, proto, realToElapsedTimeOffsetNs === undefined || useElapsedTime); 67 return entry; 68}; 69 70function addAttributes(entry: WindowManagerState, proto: any, useElapsedTime = false) { 71 entry.kind = entry.constructor.name; 72 if (!entry.isComplete()) { 73 entry.isIncompleteReason = entry.getIsIncompleteReason(); 74 } 75 entry.proto = proto; 76 if (useElapsedTime || entry.clockTimestamp === undefined) { 77 entry.name = TimeUtils.format(new ElapsedTimestamp(BigInt(entry.elapsedTimestamp))); 78 entry.shortName = entry.name; 79 } else { 80 entry.name = TimeUtils.format(new RealTimestamp(BigInt(entry.clockTimestamp))); 81 entry.shortName = entry.name; 82 } 83} 84 85function createWindowManagerPolicy(proto: any): WindowManagerPolicy { 86 return new WindowManagerPolicy( 87 proto.focusedAppToken ?? '', 88 proto.forceStatusBar, 89 proto.forceStatusBarFromKeyguard, 90 proto.keyguardDrawComplete, 91 proto.keyguardOccluded, 92 proto.keyguardOccludedChanged, 93 proto.keyguardOccludedPending, 94 proto.lastSystemUiFlags, 95 proto.orientation, 96 Rotation.Companion.getByValue(proto.rotation), 97 proto.rotationMode, 98 proto.screenOnFully, 99 proto.windowManagerDrawComplete 100 ); 101} 102 103function createRootWindowContainer(proto: any, nextSeq: () => number): RootWindowContainer { 104 const windowContainer = WindowContainer.fromProto( 105 /* proto */ proto.windowContainer, 106 /* childrenProto */ proto.windowContainer?.children ?? [], 107 /* isActivityInTree */ false, 108 /* computedZ */ nextSeq 109 ); 110 111 if (windowContainer == null) { 112 throw new Error(`Window container should not be null.\n${JSON.stringify(proto)}`); 113 } 114 const entry = new RootWindowContainer(windowContainer); 115 return entry; 116} 117 118function createKeyguardControllerState(proto: any): KeyguardControllerState { 119 const keyguardOccludedStates: any = {}; 120 121 if (proto) { 122 proto.keyguardOccludedStates.forEach( 123 (it: any) => 124 (keyguardOccludedStates[it.displayId as keyof typeof keyguardOccludedStates] = 125 it.keyguardOccluded) 126 ); 127 } 128 129 return new KeyguardControllerState( 130 proto?.isAodShowing ?? false, 131 proto?.isKeyguardShowing ?? false, 132 keyguardOccludedStates 133 ); 134} 135 136export {WindowManagerState}; 137