• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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