xref: /aosp_15_r20/cts/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright (C) 2016 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 
17 package android.server.wm;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
23 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
24 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
25 import static android.server.wm.ComponentNameUtils.getActivityName;
26 import static android.server.wm.ProtoExtractors.extract;
27 import static android.server.wm.StateLogger.log;
28 import static android.server.wm.StateLogger.logE;
29 import static android.server.wm.TestTaskOrganizer.INVALID_TASK_ID;
30 import static android.util.DisplayMetrics.DENSITY_DEFAULT;
31 import static android.view.Display.DEFAULT_DISPLAY;
32 import static android.window.DisplayAreaOrganizer.FEATURE_IME;
33 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
34 
35 import static androidx.test.InstrumentationRegistry.getInstrumentation;
36 
37 import static com.google.common.truth.Truth.assertWithMessage;
38 
39 import static org.junit.Assert.fail;
40 
41 import android.app.ActivityTaskManager;
42 import android.app.UiAutomation;
43 import android.content.ComponentName;
44 import android.content.res.Configuration;
45 import android.graphics.Point;
46 import android.graphics.Rect;
47 import android.os.ParcelFileDescriptor;
48 import android.os.SystemClock;
49 import android.util.SparseArray;
50 import android.view.WindowInsets;
51 
52 import androidx.annotation.NonNull;
53 import androidx.annotation.Nullable;
54 
55 import com.google.protobuf.ExtensionRegistryLite;
56 import com.google.protobuf.InvalidProtocolBufferException;
57 import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
58 
59 import perfetto.protos.Displayinfo.DisplayInfoProto;
60 import perfetto.protos.Enums.TransitionTypeEnum;
61 import perfetto.protos.Insetssource.InsetsSourceProto;
62 import perfetto.protos.Rect.RectProto;
63 import perfetto.protos.TraceOuterClass.Trace;
64 import perfetto.protos.TracePacketOuterClass.TracePacket;
65 import perfetto.protos.Windowmanager.WindowManagerTraceEntry;
66 import perfetto.protos.Windowmanagerservice.ActivityRecordProto;
67 import perfetto.protos.Windowmanagerservice.AppTransitionProto;
68 import perfetto.protos.Windowmanagerservice.BackNavigationProto;
69 import perfetto.protos.Windowmanagerservice.ConfigurationContainerProto;
70 import perfetto.protos.Windowmanagerservice.DisplayAreaProto;
71 import perfetto.protos.Windowmanagerservice.DisplayContentProto;
72 import perfetto.protos.Windowmanagerservice.DisplayFramesProto;
73 import perfetto.protos.Windowmanagerservice.DisplayRotationProto;
74 import perfetto.protos.Windowmanagerservice.IdentifierProto;
75 import perfetto.protos.Windowmanagerservice.InsetsSourceProviderProto;
76 import perfetto.protos.Windowmanagerservice.KeyguardControllerProto;
77 import perfetto.protos.Windowmanagerservice.KeyguardServiceDelegateProto;
78 import perfetto.protos.Windowmanagerservice.PinnedTaskControllerProto;
79 import perfetto.protos.Windowmanagerservice.RootWindowContainerProto;
80 import perfetto.protos.Windowmanagerservice.TaskFragmentProto;
81 import perfetto.protos.Windowmanagerservice.TaskProto;
82 import perfetto.protos.Windowmanagerservice.WindowContainerChildProto;
83 import perfetto.protos.Windowmanagerservice.WindowContainerProto;
84 import perfetto.protos.Windowmanagerservice.WindowFramesProto;
85 import perfetto.protos.Windowmanagerservice.WindowManagerServiceDumpProto;
86 import perfetto.protos.Windowmanagerservice.WindowStateAnimatorProto;
87 import perfetto.protos.Windowmanagerservice.WindowStateProto;
88 import perfetto.protos.Windowmanagerservice.WindowSurfaceControllerProto;
89 import perfetto.protos.Windowmanagerservice.WindowTokenProto;
90 import perfetto.protos.WinscopeExtensionsImplOuterClass.WinscopeExtensionsImpl;
91 import perfetto.protos.WinscopeExtensionsOuterClass.WinscopeExtensions;
92 
93 import java.io.ByteArrayOutputStream;
94 import java.io.FileInputStream;
95 import java.io.IOException;
96 import java.nio.charset.StandardCharsets;
97 import java.util.ArrayList;
98 import java.util.Arrays;
99 import java.util.List;
100 import java.util.Objects;
101 import java.util.function.Consumer;
102 import java.util.function.Predicate;
103 import java.util.stream.Collectors;
104 import java.util.stream.Stream;
105 
106 public class WindowManagerState {
107 
108     public static final String STATE_INITIALIZING = "INITIALIZING";
109     public static final String STATE_STARTED = "STARTED";
110     public static final String STATE_RESUMED = "RESUMED";
111     public static final String STATE_PAUSING = "PAUSING";
112     public static final String STATE_PAUSED = "PAUSED";
113     public static final String STATE_STOPPING = "STOPPING";
114     public static final String STATE_STOPPED = "STOPPED";
115     public static final String STATE_DESTROYED = "DESTROYED";
116     public static final String TRANSIT_ACTIVITY_OPEN = "TRANSIT_ACTIVITY_OPEN";
117     public static final String TRANSIT_ACTIVITY_CLOSE = "TRANSIT_ACTIVITY_CLOSE";
118     public static final String TRANSIT_TASK_OPEN = "TRANSIT_TASK_OPEN";
119     public static final String TRANSIT_TASK_CLOSE = "TRANSIT_TASK_CLOSE";
120     public static final String TRANSIT_WALLPAPER_OPEN = "TRANSIT_WALLPAPER_OPEN";
121     public static final String TRANSIT_WALLPAPER_CLOSE = "TRANSIT_WALLPAPER_CLOSE";
122     public static final String TRANSIT_WALLPAPER_INTRA_OPEN = "TRANSIT_WALLPAPER_INTRA_OPEN";
123     public static final String TRANSIT_WALLPAPER_INTRA_CLOSE = "TRANSIT_WALLPAPER_INTRA_CLOSE";
124     public static final String TRANSIT_KEYGUARD_GOING_AWAY = "TRANSIT_KEYGUARD_GOING_AWAY";
125     public static final String TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER =
126             "TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER";
127     public static final String TRANSIT_KEYGUARD_OCCLUDE = "TRANSIT_KEYGUARD_OCCLUDE";
128     public static final String TRANSIT_KEYGUARD_UNOCCLUDE = "TRANSIT_KEYGUARD_UNOCCLUDE";
129     public static final String TRANSIT_TRANSLUCENT_ACTIVITY_OPEN =
130             "TRANSIT_TRANSLUCENT_ACTIVITY_OPEN";
131     public static final String TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE =
132             "TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE";
133     public static final String APP_STATE_IDLE = "APP_STATE_IDLE";
134     public static final String APP_STATE_RUNNING = "APP_STATE_RUNNING";
135 
136     private static final String DUMPSYS_WINDOW = "dumpsys window -a --proto";
137     private static final String STARTING_WINDOW_PREFIX = "Starting ";
138     private static final String DEBUGGER_WINDOW_PREFIX = "Waiting For Debugger: ";
139     /** @see WindowManager.LayoutParams */
140     private static final int TYPE_NAVIGATION_BAR = 2019;
141     /** @see WindowManager.LayoutParams */
142     private static final int TYPE_NAVIGATION_BAR_PANEL = 2024;
143     /** @see WindowManager.LayoutParams */
144     private static final int TYPE_NOTIFICATION_SHADE = 2040;
145 
146     /** Whether accessibility services should be suppressed when taking the WindowManager dump. */
147     private boolean mSuppressAccessibilityServices = true;
148 
149     private RootWindowContainer mRoot = null;
150     // Displays in z-order with the top most at the front of the list, starting with primary.
151     private final List<DisplayContent> mDisplays = new ArrayList<>();
152     /**
153      * Root tasks in z-order with the top most at the front of the list, starting with primary
154      * display.
155      */
156     private final List<Task> mRootTasks = new ArrayList<>();
157     // Windows in z-order with the top most at the front of the list.
158     private final List<WindowState> mWindowStates = new ArrayList<>();
159     private KeyguardControllerState mKeyguardControllerState;
160     private KeyguardServiceDelegateState mKeyguardServiceDelegateState;
161     private final List<String> mPendingActivities = new ArrayList<>();
162     private int mTopFocusedTaskId = -1;
163     private int mFocusedDisplayId = DEFAULT_DISPLAY;
164     private String mFocusedWindow = null;
165     private String mFocusedApp = null;
166     private Boolean mIsHomeRecentsComponent;
167     private String mTopResumedActivityRecord = null;
168     final SparseArray<ArrayList<String>> mResumedActivitiesInRootTasks = new SparseArray<>();
169     final List<String> mResumedActivitiesInDisplays = new ArrayList<>();
170     private Rect mDefaultPinnedStackBounds = new Rect();
171     private Rect mPinnedStackMovementBounds = new Rect();
172     private String mInputMethodWindowAppToken = null;
173     private boolean mDisplayFrozen;
174     private boolean mSanityCheckFocusedWindow = true;
175     private boolean mWindowFramesValid;
176     private BackNavigationState mBackNavigationState;
177 
appStateToString(int appState)178     static String appStateToString(int appState) {
179         switch (appState) {
180             case AppTransitionProto.AppState.APP_STATE_IDLE_VALUE:
181                 return "APP_STATE_IDLE";
182             case AppTransitionProto.AppState.APP_STATE_READY_VALUE:
183                 return "APP_STATE_READY";
184             case AppTransitionProto.AppState.APP_STATE_RUNNING_VALUE:
185                 return "APP_STATE_RUNNING";
186             case AppTransitionProto.AppState.APP_STATE_TIMEOUT_VALUE:
187                 return "APP_STATE_TIMEOUT";
188             default:
189                 fail("Invalid AppTransitionState");
190                 return null;
191         }
192     }
193 
appTransitionToString(int transition)194     static String appTransitionToString(int transition) {
195         switch (transition) {
196             case TransitionTypeEnum.TRANSIT_UNSET_VALUE: {
197                 return "TRANSIT_UNSET";
198             }
199             case TransitionTypeEnum.TRANSIT_NONE_VALUE: {
200                 return "TRANSIT_NONE";
201             }
202             case TransitionTypeEnum.TRANSIT_ACTIVITY_OPEN_VALUE: {
203                 return TRANSIT_ACTIVITY_OPEN;
204             }
205             case TransitionTypeEnum.TRANSIT_ACTIVITY_CLOSE_VALUE: {
206                 return TRANSIT_ACTIVITY_CLOSE;
207             }
208             case TransitionTypeEnum.TRANSIT_TASK_OPEN_VALUE: {
209                 return TRANSIT_TASK_OPEN;
210             }
211             case TransitionTypeEnum.TRANSIT_TASK_CLOSE_VALUE: {
212                 return TRANSIT_TASK_CLOSE;
213             }
214             case TransitionTypeEnum.TRANSIT_TASK_TO_FRONT_VALUE: {
215                 return "TRANSIT_TASK_TO_FRONT";
216             }
217             case TransitionTypeEnum.TRANSIT_TASK_TO_BACK_VALUE: {
218                 return "TRANSIT_TASK_TO_BACK";
219             }
220             case TransitionTypeEnum.TRANSIT_WALLPAPER_CLOSE_VALUE: {
221                 return TRANSIT_WALLPAPER_CLOSE;
222             }
223             case TransitionTypeEnum.TRANSIT_WALLPAPER_OPEN_VALUE: {
224                 return TRANSIT_WALLPAPER_OPEN;
225             }
226             case TransitionTypeEnum.TRANSIT_WALLPAPER_INTRA_OPEN_VALUE: {
227                 return TRANSIT_WALLPAPER_INTRA_OPEN;
228             }
229             case TransitionTypeEnum.TRANSIT_WALLPAPER_INTRA_CLOSE_VALUE: {
230                 return TRANSIT_WALLPAPER_INTRA_CLOSE;
231             }
232             case TransitionTypeEnum.TRANSIT_TASK_OPEN_BEHIND_VALUE: {
233                 return "TRANSIT_TASK_OPEN_BEHIND";
234             }
235             case TransitionTypeEnum.TRANSIT_ACTIVITY_RELAUNCH_VALUE: {
236                 return "TRANSIT_ACTIVITY_RELAUNCH";
237             }
238             case TransitionTypeEnum.TRANSIT_DOCK_TASK_FROM_RECENTS_VALUE: {
239                 return "TRANSIT_DOCK_TASK_FROM_RECENTS";
240             }
241             case TransitionTypeEnum.TRANSIT_KEYGUARD_GOING_AWAY_VALUE: {
242                 return TRANSIT_KEYGUARD_GOING_AWAY;
243             }
244             case TransitionTypeEnum.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER_VALUE: {
245                 return TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
246             }
247             case TransitionTypeEnum.TRANSIT_KEYGUARD_OCCLUDE_VALUE: {
248                 return TRANSIT_KEYGUARD_OCCLUDE;
249             }
250             case TransitionTypeEnum.TRANSIT_KEYGUARD_UNOCCLUDE_VALUE: {
251                 return TRANSIT_KEYGUARD_UNOCCLUDE;
252             }
253             case TransitionTypeEnum.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN_VALUE: {
254                 return TRANSIT_TRANSLUCENT_ACTIVITY_OPEN;
255             }
256             case TransitionTypeEnum.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE_VALUE: {
257                 return TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE;
258             }
259             case TransitionTypeEnum.TRANSIT_CRASHING_ACTIVITY_CLOSE_VALUE: {
260                 return "TRANSIT_CRASHING_ACTIVITY_CLOSE";
261             }
262             default: {
263                 fail("Invalid lastUsedAppTransition");
264                 return null;
265             }
266         }
267     }
268 
269     /**
270      * For a given WindowContainer, traverse down the hierarchy and add all children of type
271      * {@code T} to {@code outChildren}.
272      */
collectDescendantsOfType(Class<T> clazz, WindowContainer root, List<T> outChildren)273     private static <T extends WindowContainer> void collectDescendantsOfType(Class<T> clazz,
274             WindowContainer root, List<T> outChildren) {
275         collectDescendantsOfTypeIf(clazz, t -> true, root, outChildren);
276     }
277 
278     /**
279      * For a given WindowContainer, traverse down the hierarchy and add all children of type
280      * {@code T} to {@code outChildren} if the child passes the test {@code predicate}.
281      */
collectDescendantsOfTypeIf(Class<T> clazz, Predicate<T> predicate, WindowContainer root, List<T> outChildren)282     private static <T extends WindowContainer> void collectDescendantsOfTypeIf(Class<T> clazz,
283             Predicate<T> predicate, WindowContainer root, List<T> outChildren) {
284         // Traverse top to bottom
285         for (int i = root.mChildren.size()-1; i >= 0; i--) {
286             final WindowContainer child = root.mChildren.get(i);
287             if (clazz.isInstance(child)) {
288                 if(predicate.test(clazz.cast(child))) {
289                     outChildren.add(clazz.cast(child));
290                 }
291             }
292             collectDescendantsOfTypeIf(clazz, predicate, child, outChildren);
293         }
294     }
295 
296     /**
297      * For a given WindowContainer, traverse down the hierarchy and add all immediate children of
298      * type {@code T} to {@code outChildren}.
299      */
collectChildrenOfType(Class<T> clazz, WindowContainer root, List<T> outChildren)300     private static <T extends WindowContainer> void collectChildrenOfType(Class<T> clazz,
301             WindowContainer root, List<T> outChildren) {
302         for (int i = root.mChildren.size()-1; i >= 0; i--) {
303             final WindowContainer child = root.mChildren.get(i);
304             if (clazz.isInstance(child)) {
305                 outChildren.add(clazz.cast(child));
306             }
307         }
308     }
309 
310     /** Enable/disable the mFocusedWindow check during the computeState. */
setSanityCheckWithFocusedWindow(boolean sanityCheckFocusedWindow)311     public void setSanityCheckWithFocusedWindow(boolean sanityCheckFocusedWindow) {
312         mSanityCheckFocusedWindow = sanityCheckFocusedWindow;
313     }
314 
computeState()315     public void computeState() {
316         // It is possible the system is in the middle of transition to the right state when we get
317         // the dump. We try a few times to get the information we need before giving up.
318         int retriesLeft = 3;
319         boolean retry = false;
320         byte[] dump = null;
321 
322         log("==============================");
323         log("     WindowManagerState     ");
324         log("==============================");
325 
326         do {
327             if (retry) {
328                 log("***Incomplete AM state. Retrying...");
329                 // Wait half a second between retries for activity manager to finish transitioning.
330                 SystemClock.sleep(500);
331             }
332 
333             if (android.tracing.Flags.perfettoWmDumpCts()) {
334                 dump = new WindowManagerTraceMonitor().captureDump();
335             } else {
336                 dump = executeShellCommand(DUMPSYS_WINDOW);
337             }
338 
339             try {
340                 reset();
341                 if (android.tracing.Flags.perfettoWmDumpCts()) {
342                     parseDump(dump);
343                 } else {
344                     parseDumpLegacy(dump);
345                 }
346             } catch (IOException ex) {
347                 final String dumpString = new String(dump, StandardCharsets.UTF_8);
348                 if (dumpString.contains("SERVICE \'window\' DUMP TIMEOUT")) {
349                     // retry and log when dump timeout
350                     logE(dumpString);
351                 } else {
352                     throw new RuntimeException("Failed to parse dumpsys:\n"
353                             + new String(dump, StandardCharsets.UTF_8), ex);
354                 }
355             }
356 
357             retry = mRootTasks.isEmpty() || mTopFocusedTaskId == -1 || mWindowStates.isEmpty()
358                     || mFocusedApp == null || (mSanityCheckFocusedWindow && mFocusedWindow == null)
359                     || !mWindowFramesValid
360                     || (mTopResumedActivityRecord == null
361                     || mResumedActivitiesInRootTasks.size() == 0)
362                     && !mKeyguardControllerState.keyguardShowing;
363         } while (retry && retriesLeft-- > 0);
364 
365         if (mRootTasks.isEmpty()) {
366             logE("No root tasks found...");
367         }
368         if (mTopFocusedTaskId == -1) {
369             logE("No focused task found...");
370         }
371         if (mTopResumedActivityRecord == null) {
372             logE("No focused activity found...");
373         }
374         if (mResumedActivitiesInRootTasks.size() == 0) {
375             logE("No resumed activities found...");
376         }
377         if (mWindowStates.isEmpty()) {
378             logE("No Windows found...");
379         }
380         if (mFocusedWindow == null) {
381             logE("No Focused Window...");
382         }
383         if (mFocusedApp == null) {
384             logE("No Focused App...");
385         }
386         if (!mWindowFramesValid) {
387             logE("Window Frames Invalid...");
388         }
389     }
390 
setSuppressAccessibilityServices(boolean suppressAccessibilityServices)391     public void setSuppressAccessibilityServices(boolean suppressAccessibilityServices) {
392         mSuppressAccessibilityServices = suppressAccessibilityServices;
393     }
394 
executeShellCommand(String command)395     private byte[] executeShellCommand(String command) {
396         try {
397             ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation(
398                             mSuppressAccessibilityServices ? 0
399                                     : UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES)
400                     .executeShellCommand(command);
401             byte[] buf = new byte[512];
402             int bytesRead;
403             FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
404             ByteArrayOutputStream stdout = new ByteArrayOutputStream();
405             while ((bytesRead = fis.read(buf)) != -1) {
406                 stdout.write(buf, 0, bytesRead);
407             }
408             fis.close();
409             return stdout.toByteArray();
410         } catch (IOException e) {
411             throw new RuntimeException(e);
412         }
413     }
414 
415     /** Update WindowManagerState state for a newly added DisplayContent. */
updateForDisplayContent(DisplayContent display)416     private void updateForDisplayContent(DisplayContent display) {
417         if (display.mResumedActivity != null) {
418             mResumedActivitiesInDisplays.add(display.mResumedActivity);
419         }
420 
421         for (int i = 0; i < display.mRootTasks.size(); i++) {
422             Task task = display.mRootTasks.get(i);
423             mRootTasks.add(task);
424             addResumedActivity(task);
425         }
426 
427         if (display.mDefaultPinnedStackBounds != null) {
428             mDefaultPinnedStackBounds = display.mDefaultPinnedStackBounds;
429             mPinnedStackMovementBounds = display.mPinnedStackMovementBounds;
430         }
431     }
432 
addResumedActivity(Task task)433     private void addResumedActivity(Task task) {
434         final int numChildTasks = task.mTasks.size();
435         if (numChildTasks > 0) {
436             for (int i = numChildTasks - 1; i >=0; i--) {
437                 addResumedActivity(task.mTasks.get(i));
438             }
439         } else if (task.mResumedActivity != null) {
440             final ArrayList<String> resumedActivities =
441                     mResumedActivitiesInRootTasks.get(task.mDisplayId, new ArrayList<>());
442             resumedActivities.add(task.mResumedActivity);
443             mResumedActivitiesInRootTasks.put(task.mDisplayId, resumedActivities);
444         }
445     }
446 
parseDump(byte[] dump)447     private void parseDump(byte[] dump) throws InvalidProtocolBufferException {
448         reset();
449 
450         Trace trace = Trace.parseFrom(dump);
451 
452         for (int i = 0; i < trace.getPacketCount(); ++i) {
453             TracePacket packet = trace.getPacket(i);
454 
455             if (packet.hasWinscopeExtensions()) {
456                 ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
457                 registry.add(WinscopeExtensionsImpl.windowmanager);
458                 WinscopeExtensions extensions = WinscopeExtensions.parseFrom(
459                         packet.getWinscopeExtensions().toByteArray(), registry);
460                 if (extensions.hasExtension(WinscopeExtensionsImpl.windowmanager)) {
461                     WindowManagerTraceEntry entry =
462                             extensions.getExtension(WinscopeExtensionsImpl.windowmanager);
463                     parseWindowManagerServiceDumpProto(entry.getWindowManagerService());
464                     return;
465                 }
466             }
467         }
468 
469         throw new RuntimeException("Perfetto trace doesn't contain WM packets");
470     }
471 
parseWindowManagerServiceDumpProto(WindowManagerServiceDumpProto state)472     private void parseWindowManagerServiceDumpProto(WindowManagerServiceDumpProto state) {
473         final RootWindowContainerProto root = state.getRootWindowContainer();
474         if (state.hasFocusedWindow()) {
475             mFocusedWindow = state.getFocusedWindow().getTitle();
476         }
477         mRoot = new RootWindowContainer(root);
478         collectDescendantsOfType(DisplayContent.class, mRoot, mDisplays);
479         for (int i = 0; i < mDisplays.size(); i++) {
480             DisplayContent display = mDisplays.get(i);
481             updateForDisplayContent(display);
482         }
483         mKeyguardControllerState = new KeyguardControllerState(
484                 root.hasKeyguardController() ? root.getKeyguardController() : null);
485         mKeyguardServiceDelegateState = new KeyguardServiceDelegateState(
486                 state.getPolicy().hasKeyguardDelegate()
487                         ? state.getPolicy().getKeyguardDelegate()
488                         : null);
489         mFocusedApp = state.getFocusedApp();
490         mFocusedDisplayId = state.getFocusedDisplayId();
491         final DisplayContent focusedDisplay = getDisplay(mFocusedDisplayId);
492         if (focusedDisplay != null) {
493             mTopFocusedTaskId = focusedDisplay.mFocusedRootTaskId;
494             mTopResumedActivityRecord = focusedDisplay.mResumedActivity;
495         }
496         mIsHomeRecentsComponent = new Boolean(root.getIsHomeRecentsComponent());
497 
498         for (int i = 0; i < root.getPendingActivitiesCount(); i++) {
499             mPendingActivities.add(root.getPendingActivities(i).getTitle());
500         }
501 
502         collectDescendantsOfType(WindowState.class, mRoot, mWindowStates);
503 
504         if (state.hasInputMethodWindow()) {
505             mInputMethodWindowAppToken =
506                     Integer.toHexString(state.getInputMethodWindow().getHashCode());
507         }
508         mDisplayFrozen = state.getDisplayFrozen();
509         mWindowFramesValid = state.getWindowFramesValid();
510 
511         mBackNavigationState = new BackNavigationState(state.hasBackNavigation()
512                 ? state.getBackNavigation() : null);
513     }
514 
parseDumpLegacy(byte[] sysDump)515     private void parseDumpLegacy(byte[] sysDump) throws InvalidProtocolBufferNanoException {
516         com.android.server.wm.nano.WindowManagerServiceDumpProto state =
517                 com.android.server.wm.nano.WindowManagerServiceDumpProto.parseFrom(sysDump);
518         final com.android.server.wm.nano.RootWindowContainerProto root = state.rootWindowContainer;
519         if (state.focusedWindow != null) {
520             mFocusedWindow = state.focusedWindow.title;
521         }
522         mRoot = new RootWindowContainer(root);
523         collectDescendantsOfType(DisplayContent.class, mRoot, mDisplays);
524         for (int i = 0; i < mDisplays.size(); i++) {
525             DisplayContent display = mDisplays.get(i);
526             updateForDisplayContent(display);
527         }
528         mKeyguardControllerState = new KeyguardControllerState(root.keyguardController);
529         mKeyguardServiceDelegateState =
530                 new KeyguardServiceDelegateState(state.policy.keyguardDelegate);
531         mFocusedApp = state.focusedApp;
532         mFocusedDisplayId = state.focusedDisplayId;
533         final DisplayContent focusedDisplay = getDisplay(mFocusedDisplayId);
534         if (focusedDisplay != null) {
535             mTopFocusedTaskId = focusedDisplay.mFocusedRootTaskId;
536             mTopResumedActivityRecord = focusedDisplay.mResumedActivity;
537         }
538         mIsHomeRecentsComponent = new Boolean(root.isHomeRecentsComponent);
539 
540         for (int i = 0; i < root.pendingActivities.length; i++) {
541             mPendingActivities.add(root.pendingActivities[i].title);
542         }
543 
544         collectDescendantsOfType(WindowState.class, mRoot, mWindowStates);
545 
546         if (state.inputMethodWindow != null) {
547             mInputMethodWindowAppToken = Integer.toHexString(state.inputMethodWindow.hashCode);
548         }
549         mDisplayFrozen = state.displayFrozen;
550         mWindowFramesValid = state.windowFramesValid;
551 
552         mBackNavigationState = new BackNavigationState(state.backNavigation);
553     }
554 
reset()555     private void reset() {
556         mRoot = null;
557         mDisplays.clear();
558         mRootTasks.clear();
559         mWindowStates.clear();
560         mTopFocusedTaskId = -1;
561         mFocusedDisplayId = DEFAULT_DISPLAY;
562         mFocusedWindow = null;
563         mFocusedApp = null;
564         mTopResumedActivityRecord = null;
565         mResumedActivitiesInRootTasks.clear();
566         mResumedActivitiesInDisplays.clear();
567         mKeyguardControllerState = null;
568         mKeyguardServiceDelegateState = null;
569         mIsHomeRecentsComponent = null;
570         mPendingActivities.clear();
571         mDefaultPinnedStackBounds.setEmpty();
572         mPinnedStackMovementBounds.setEmpty();
573         mInputMethodWindowAppToken = null;
574         mDisplayFrozen = false;
575         mWindowFramesValid = false;
576     }
577 
578     /** Returns the focused app on the provided display. */
getFocusedAppOnDisplay(int displayId)579     public String getFocusedAppOnDisplay(int displayId) {
580         return getDisplay(displayId).mFocusedApp;
581     }
582 
getFocusedApp()583     public String getFocusedApp() {
584         return mFocusedApp;
585     }
586 
getFocusedWindow()587     public String getFocusedWindow() {
588         return mFocusedWindow;
589     }
590 
591     /** @return Whether the home activity is the recents component. */
isHomeRecentsComponent()592     public boolean isHomeRecentsComponent() {
593         if (mIsHomeRecentsComponent == null) {
594             computeState();
595         }
596         return mIsHomeRecentsComponent;
597     }
598 
getDisplay(int displayId)599     public DisplayContent getDisplay(int displayId) {
600         for (DisplayContent display : mDisplays) {
601             if (display.mId == displayId) {
602                 return display;
603             }
604         }
605         return null;
606     }
607 
608     /**
609      * Returns the task display area feature id present on a display, or
610      * {@code DisplayAreaOrganizer.FEATURE_UNDEFINED} if task display area not found.
611      * Note: This is required since an activity can be present on more than one task display areas
612      * if there are visible background users.
613      */
getTaskDisplayAreaFeatureIdOnDisplay(ComponentName activityName, int displayId)614     public int getTaskDisplayAreaFeatureIdOnDisplay(ComponentName activityName, int displayId) {
615         final DisplayArea tda = getDisplay(displayId).getTaskDisplayArea(activityName);
616         if (tda != null) {
617             return tda.getFeatureId();
618         }
619         return FEATURE_UNDEFINED;
620     }
621 
622     @Nullable
getTaskDisplayArea(ComponentName activityName)623     public DisplayArea getTaskDisplayArea(ComponentName activityName) {
624         final List<DisplayArea> result = new ArrayList<>();
625         for (DisplayContent display : mDisplays) {
626             final DisplayArea tda = display.getTaskDisplayArea(activityName);
627             if (tda != null) {
628                 result.add(tda);
629             }
630         }
631         assertWithMessage("There must be exactly one activity among all TaskDisplayAreas.")
632                 .that(result.size()).isAtMost(1);
633 
634         return result.stream().findFirst().orElse(null);
635     }
636 
getTaskDisplayAreaFeatureId(ComponentName activityName)637     public int getTaskDisplayAreaFeatureId(ComponentName activityName) {
638         final DisplayArea taskDisplayArea = getTaskDisplayArea(activityName);
639         if (taskDisplayArea != null) {
640             return taskDisplayArea.getFeatureId();
641         }
642 
643         return FEATURE_UNDEFINED;
644     }
645 
646     @Nullable
getDisplayArea(String windowName)647     public DisplayArea getDisplayArea(String windowName) {
648         final List<DisplayArea> result = new ArrayList<>();
649         for (DisplayContent display : mDisplays) {
650             final DisplayArea da = display.getDisplayArea(windowName);
651             if (da != null) {
652                 result.add(da);
653             }
654         }
655         assertWithMessage("There must be exactly one window among all DisplayAreas.")
656                 .that(result.size()).isAtMost(1);
657 
658         return result.stream().findFirst().orElse(null);
659     }
660 
661     @Nullable
getImeContainer(int displayId)662     public DisplayArea getImeContainer(int displayId) {
663         final DisplayContent displayContent = getDisplay(displayId);
664         if (displayContent == null) {
665             return null;
666         }
667         return displayContent.getImeContainer();
668     }
669 
getFrontRootTaskId(int displayId)670     public int getFrontRootTaskId(int displayId) {
671         return getDisplay(displayId).mRootTasks.get(0).mRootTaskId;
672     }
673 
getFrontRootTaskActivityType(int displayId)674     public int getFrontRootTaskActivityType(int displayId) {
675         return getDisplay(displayId).mRootTasks.get(0).getActivityType();
676     }
677 
getFrontRootTaskWindowingMode(int displayId)678     public int getFrontRootTaskWindowingMode(int displayId) {
679         return getDisplay(displayId).mRootTasks.get(0).getWindowingMode();
680     }
681 
getTopActivityName(int displayId)682     public String getTopActivityName(int displayId) {
683         if (!getDisplay(displayId).mRootTasks.isEmpty()) {
684             final Task topRootTask = getDisplay(displayId).mRootTasks.get(0);
685             final Task topTask = topRootTask.getTopTask();
686             if (!topTask.mActivities.isEmpty()) {
687                 return topTask.mActivities.get(0).name;
688             }
689         }
690         return null;
691     }
692 
getFocusedTaskIdOnDisplay(int displayId)693     int getFocusedTaskIdOnDisplay(int displayId) {
694         return getDisplay(displayId).mFocusedRootTaskId;
695     }
696 
getFocusedTaskId()697     public int getFocusedTaskId() {
698         return mTopFocusedTaskId;
699     }
700 
getFocusedRootTaskActivityType()701     public int getFocusedRootTaskActivityType() {
702         final Task rootTask = getRootTask(mTopFocusedTaskId);
703         return rootTask != null ? rootTask.getActivityType() : ACTIVITY_TYPE_UNDEFINED;
704     }
705 
getFocusedRootTaskWindowingMode()706     public int getFocusedRootTaskWindowingMode() {
707         final Task rootTask = getRootTask(mTopFocusedTaskId);
708         return rootTask != null ? rootTask.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
709     }
710 
711     /** Returns the focused activity on the specified display. */
getFocusedActivityOnDisplay(int displayId)712     public String getFocusedActivityOnDisplay(int displayId) {
713         return getDisplay(displayId).mResumedActivity;
714     }
715 
getFocusedActivity()716     public String getFocusedActivity() {
717         return mTopResumedActivityRecord;
718     }
719 
getResumedActivitiesCount()720     public int getResumedActivitiesCount() {
721         int count = 0;
722         for (int i = 0; i < mResumedActivitiesInRootTasks.size(); i++) {
723             final ArrayList<String> resumedActivities = mResumedActivitiesInRootTasks.valueAt(i);
724             count += resumedActivities.size();
725         }
726         return count;
727     }
728 
getResumedActivitiesCountOnDisplay(int displayId)729     public int getResumedActivitiesCountOnDisplay(int displayId) {
730         final ArrayList<String> resumedActivitiesOnDisplay =
731                 mResumedActivitiesInRootTasks.get(displayId, new ArrayList<>());
732         return resumedActivitiesOnDisplay.size();
733     }
734 
getResumedActivitiesCountInPackage(String packageName)735     public int getResumedActivitiesCountInPackage(String packageName) {
736         final String componentPrefix = packageName + "/";
737         int count = 0;
738         for (int i = mDisplays.size() - 1; i >= 0; --i) {
739             final ArrayList<Task> rootTasks = mDisplays.get(i).getRootTasks();
740             for (int j = rootTasks.size() - 1; j >= 0; --j) {
741                 final String resumedActivity = rootTasks.get(j).mResumedActivity;
742                 if (resumedActivity != null && resumedActivity.startsWith(componentPrefix)) {
743                     count++;
744                 }
745             }
746         }
747         return count;
748     }
749 
getResumedActivityOnDisplay(int displayId)750     public String getResumedActivityOnDisplay(int displayId) {
751         return getDisplay(displayId).mResumedActivity;
752     }
753 
getKeyguardControllerState()754     public KeyguardControllerState getKeyguardControllerState() {
755         return mKeyguardControllerState;
756     }
757 
getKeyguardServiceDelegateState()758     public KeyguardServiceDelegateState getKeyguardServiceDelegateState() {
759         return mKeyguardServiceDelegateState;
760     }
761 
getBackNavigationState()762     public BackNavigationState getBackNavigationState() {
763         return mBackNavigationState;
764     }
765 
containsRootTasks(int windowingMode, int activityType)766     public boolean containsRootTasks(int windowingMode, int activityType) {
767         return countRootTasks(windowingMode, activityType) > 0;
768     }
769 
countRootTasks(int windowingMode, int activityType)770     public int countRootTasks(int windowingMode, int activityType) {
771         int count = 0;
772         for (Task rootTask : mRootTasks) {
773             if (activityType != ACTIVITY_TYPE_UNDEFINED
774                     && activityType != rootTask.getActivityType()) {
775                 continue;
776             }
777             if (windowingMode != WINDOWING_MODE_UNDEFINED
778                     && windowingMode != rootTask.getWindowingMode()) {
779                 continue;
780             }
781             ++count;
782         }
783         return count;
784     }
785 
getRootTask(int taskId)786     public Task getRootTask(int taskId) {
787         for (Task rootTask : mRootTasks) {
788             if (taskId == rootTask.mRootTaskId) {
789                 return rootTask;
790             }
791         }
792         return null;
793     }
794 
getRootTaskByActivityType(int activityType)795     public Task getRootTaskByActivityType(int activityType) {
796         for (Task rootTask : mRootTasks) {
797             if (activityType == rootTask.getActivityType()) {
798                 return rootTask;
799             }
800         }
801         return null;
802     }
803 
804     /** Gets the top root task with the {@code windowingMode}. **/
getTopRootTaskByWindowingMode(int windowingMode)805     public Task getTopRootTaskByWindowingMode(int windowingMode) {
806         for (Task rootTask : mRootTasks) {
807             if (windowingMode == rootTask.getWindowingMode()) {
808                 return rootTask;
809             }
810         }
811         return null;
812     }
813 
getStandardTaskCountByWindowingMode(int windowingMode)814     public int getStandardTaskCountByWindowingMode(int windowingMode) {
815         int count = 0;
816         for (Task rootTask : mRootTasks) {
817             if (rootTask.getActivityType() != ACTIVITY_TYPE_STANDARD) {
818                 continue;
819             }
820             if (rootTask.getWindowingMode() == windowingMode) {
821                 count += rootTask.mTasks.isEmpty() ? 1 : rootTask.mTasks.size();
822             }
823         }
824         return count;
825     }
826 
827     /** Gets the position of root task on its display with the given {@code activityType}. */
getRootTaskIndexByActivityType(int activityType)828     int getRootTaskIndexByActivityType(int activityType) {
829         for (DisplayContent display : mDisplays) {
830             for (int i = 0; i < display.mRootTasks.size(); i++) {
831                 if (activityType == display.mRootTasks.get(i).getActivityType()) {
832                     return i;
833                 }
834             }
835         }
836         return -1;
837     }
838 
839     /** Gets the root task on its display with the given {@code activityName}. */
840     @Nullable
getRootTaskByActivity(ComponentName activityName)841     public Task getRootTaskByActivity(ComponentName activityName) {
842         for (DisplayContent display : mDisplays) {
843             for (int i = display.mRootTasks.size() - 1; i >= 0; --i) {
844                 final Task rootTask = display.mRootTasks.get(i);
845                 if (rootTask.containsActivity(activityName)) return rootTask;
846             }
847         }
848         return null;
849     }
850 
851     /** Get display id by activity on it. */
getDisplayByActivity(ComponentName activityComponent)852     public int getDisplayByActivity(ComponentName activityComponent) {
853         final Task task = getTaskByActivity(activityComponent);
854         if (task == null) {
855             return -1;
856         }
857         return getRootTask(task.mRootTaskId).mDisplayId;
858     }
859 
getDisplays()860     public List<DisplayContent> getDisplays() {
861         return new ArrayList<>(mDisplays);
862     }
863 
getRootTasks()864     public List<Task> getRootTasks() {
865         return new ArrayList<>(mRootTasks);
866     }
867 
getRootTaskCount()868     public int getRootTaskCount() {
869         return mRootTasks.size();
870     }
871 
getDisplayCount()872     public int getDisplayCount() {
873         return mDisplays.size();
874     }
875 
containsActivity(ComponentName activityName)876     public boolean containsActivity(ComponentName activityName) {
877         for (Task rootTask : mRootTasks) {
878             if (rootTask.containsActivity(activityName)) return true;
879         }
880         return false;
881     }
882 
containsNoneOf(Iterable<ComponentName> activityNames)883     public boolean containsNoneOf(Iterable<ComponentName> activityNames) {
884         for (ComponentName activityName : activityNames) {
885             for (Task rootTask : mRootTasks) {
886                 if (rootTask.containsActivity(activityName)) return false;
887             }
888         }
889         return true;
890     }
891 
containsActivityInWindowingMode(ComponentName activityName, int windowingMode)892     public boolean containsActivityInWindowingMode(ComponentName activityName, int windowingMode) {
893         for (Task rootTask : mRootTasks) {
894             final Activity activity = rootTask.getActivity(activityName);
895             if (activity != null && activity.getWindowingMode() == windowingMode) {
896                 return true;
897             }
898         }
899         return false;
900     }
901 
isActivityVisible(ComponentName activityName)902     public boolean isActivityVisible(ComponentName activityName) {
903         for (Task rootTask : mRootTasks) {
904             final Activity activity = rootTask.getActivity(activityName);
905             if (activity != null) return activity.visible;
906         }
907         return false;
908     }
909 
isActivityTranslucent(ComponentName activityName)910     public boolean isActivityTranslucent(ComponentName activityName) {
911         for (Task rootTask : mRootTasks) {
912             final Activity activity = rootTask.getActivity(activityName);
913             if (activity != null) return activity.translucent;
914         }
915         return false;
916     }
917 
isBehindOpaqueActivities(ComponentName activityName)918     public boolean isBehindOpaqueActivities(ComponentName activityName) {
919         final String fullName = getActivityName(activityName);
920         for (Task rootTask : mRootTasks) {
921             final Activity activity =
922                     rootTask.getActivity((a) -> a.name.equals(fullName) || !a.translucent);
923             if (activity != null) {
924                 if (activity.name.equals(fullName)) {
925                     return false;
926                 }
927                 if (!activity.translucent) {
928                     return true;
929                 }
930             }
931         }
932 
933         return false;
934     }
935 
isTaskDisplayAreaIgnoringOrientationRequest(ComponentName activityName)936     public boolean isTaskDisplayAreaIgnoringOrientationRequest(ComponentName activityName) {
937         return getTaskDisplayArea(activityName).isIgnoringOrientationRequest();
938     }
939 
hasActivityState(ComponentName activityName, String activityState)940     public boolean hasActivityState(ComponentName activityName, String activityState) {
941         for (Task rootTask : mRootTasks) {
942             final Activity activity = rootTask.getActivity(activityName);
943             if (activity != null) return activity.state.equals(activityState);
944         }
945         return false;
946     }
947 
getActivityProcId(ComponentName activityName)948     int getActivityProcId(ComponentName activityName) {
949         for (Task rootTask : mRootTasks) {
950             final Activity activity = rootTask.getActivity(activityName);
951             if (activity != null) return activity.procId;
952         }
953         return -1;
954     }
955 
isRecentsActivityVisible()956     boolean isRecentsActivityVisible() {
957         final Activity recentsActivity = getRecentsActivity();
958         return recentsActivity != null && recentsActivity.visible;
959     }
960 
getHomeActivityName()961     public ComponentName getHomeActivityName() {
962         Activity activity = getHomeActivity();
963         if (activity == null) {
964             return null;
965         }
966         return ComponentName.unflattenFromString(activity.name);
967     }
968 
getDreamTask()969     Task getDreamTask() {
970         final Task dreamRootTask = getRootTaskByActivityType(ACTIVITY_TYPE_DREAM);
971         if (dreamRootTask != null) {
972             return dreamRootTask.getTopTask();
973         }
974         return null;
975     }
976 
getHomeTask()977     public Task getHomeTask() {
978         final Task homeRootTask = getRootTaskByActivityType(ACTIVITY_TYPE_HOME);
979         if (homeRootTask != null) {
980             return homeRootTask.getTopTask();
981         }
982         return null;
983     }
984 
getRecentsTask()985     private Task getRecentsTask() {
986         final Task recentsRootTask = getRootTaskByActivityType(ACTIVITY_TYPE_RECENTS);
987         if (recentsRootTask != null) {
988             return recentsRootTask.getTopTask();
989         }
990         return null;
991     }
992 
getHomeActivity()993     private Activity getHomeActivity() {
994         final Task homeTask = getHomeTask();
995         return homeTask != null ? homeTask.mActivities.get(homeTask.mActivities.size() - 1) : null;
996     }
997 
getRecentsActivity()998     private Activity getRecentsActivity() {
999         final Task recentsTask = getRecentsTask();
1000         return recentsTask != null ? recentsTask.mActivities.get(recentsTask.mActivities.size() - 1)
1001                 : null;
1002     }
1003 
getRootTaskIdByActivity(ComponentName activityName)1004     public int getRootTaskIdByActivity(ComponentName activityName) {
1005         final Task rootTask = getRootTaskByActivity(activityName);
1006         return  (rootTask == null) ? INVALID_TASK_ID : rootTask.mRootTaskId;
1007     }
1008 
getTaskByActivity(ComponentName activityName)1009     public Task getTaskByActivity(ComponentName activityName) {
1010         return getTaskByActivity(
1011                 activityName, WINDOWING_MODE_UNDEFINED, new int[]{ INVALID_TASK_ID });
1012     }
1013 
getTaskByActivity(ComponentName activityName, int[] excludeTaskIds)1014     public Task getTaskByActivity(ComponentName activityName, int[] excludeTaskIds) {
1015         return getTaskByActivity(activityName, WINDOWING_MODE_UNDEFINED, excludeTaskIds);
1016     }
1017 
getTaskByActivity(ComponentName activityName, int windowingMode, int[] excludeTaskIds)1018     private Task getTaskByActivity(ComponentName activityName, int windowingMode,
1019             int[] excludeTaskIds) {
1020         Activity activity = getActivity(activityName, windowingMode, excludeTaskIds);
1021         return activity == null ? null : activity.getTask();
1022     }
1023 
1024     @Nullable
getTaskFragmentByActivity(ComponentName activityName)1025     public TaskFragment getTaskFragmentByActivity(ComponentName activityName) {
1026         return getActivity(activityName).getTaskFragment();
1027     }
1028 
getActivity(ComponentName activityName)1029     public Activity getActivity(ComponentName activityName) {
1030         return getActivity(activityName, WINDOWING_MODE_UNDEFINED, new int[]{ INVALID_TASK_ID });
1031     }
1032 
getActivity(ComponentName activityName, int windowingMode, int[] excludeTaskIds)1033     private Activity getActivity(ComponentName activityName, int windowingMode,
1034             int[] excludeTaskIds) {
1035         for (Task rootTask : mRootTasks) {
1036             if (windowingMode == WINDOWING_MODE_UNDEFINED
1037                     || windowingMode == rootTask.getWindowingMode()) {
1038                 Activity activity = rootTask.getActivity(activityName, excludeTaskIds);
1039                 if (activity != null) return activity;
1040             }
1041         }
1042         return null;
1043     }
1044 
1045     /**
1046      * Get the number of activities in the task, with the option to count only activities with
1047      * specific name.
1048      * @param taskId Id of the task where we're looking for the number of activities.
1049      * @param activityName Optional name of the activity we're interested in.
1050      * @return Number of all activities in the task if activityName is {@code null}, otherwise will
1051      *         report number of activities that have specified name.
1052      */
getActivityCountInTask(int taskId, @Nullable ComponentName activityName)1053     public int getActivityCountInTask(int taskId, @Nullable ComponentName activityName) {
1054         // If activityName is null, count all activities in the task.
1055         // Otherwise count activities that have specified name.
1056         for (Task rootTask : mRootTasks) {
1057             final Task task = rootTask.getTask(taskId);
1058             if (task == null) continue;
1059 
1060             if (activityName == null) {
1061                 return task.mActivities.size();
1062             }
1063             final String fullName = getActivityName(activityName);
1064             int count = 0;
1065             for (Activity activity : task.mActivities) {
1066                 if (activity.name.equals(fullName)) {
1067                     count++;
1068                 }
1069             }
1070             return count;
1071         }
1072         return 0;
1073     }
1074 
getRootTasksCount()1075     public int getRootTasksCount() {
1076         return mRootTasks.size();
1077     }
1078 
getRootTasksCount(int displayId)1079     public int getRootTasksCount(int displayId) {
1080         return getRootTasksCount(t -> t.mDisplayId == displayId);
1081     }
1082 
1083     /**
1084      * Count root tasks with a specific activity type.
1085      */
getRootTaskCountWithActivityType(int activityType)1086     public int getRootTaskCountWithActivityType(int activityType) {
1087         return getRootTasksCount(t -> t.getActivityType() == activityType);
1088     }
1089 
1090     /**
1091      * Count root tasks filtered by the predicate passed as argument.
1092      */
getRootTasksCount(Predicate<? super Task> predicate)1093     public int getRootTasksCount(Predicate<? super Task> predicate) {
1094         return (int) mRootTasks.stream().filter(predicate).count();
1095     }
1096 
pendingActivityContain(ComponentName activityName)1097     boolean pendingActivityContain(ComponentName activityName) {
1098         return mPendingActivities.contains(getActivityName(activityName));
1099     }
1100 
1101     // Get the logical display size of the default display.
getLogicalDisplaySize()1102     public static Point getLogicalDisplaySize() {
1103         WindowManagerState mWmState = new WindowManagerState();
1104         mWmState.computeState();
1105         Rect size = mWmState.getDisplay(DEFAULT_DISPLAY).getDisplayRect();
1106         return new Point(size.width(), size.height());
1107     }
1108 
getDefaultDisplayLastTransition()1109     public String getDefaultDisplayLastTransition() {
1110         return getDisplay(DEFAULT_DISPLAY).getLastTransition();
1111     }
1112 
getDefaultDisplayAppTransitionState()1113     String getDefaultDisplayAppTransitionState() {
1114         return getDisplay(DEFAULT_DISPLAY).getAppTransitionState();
1115     }
1116 
getMatchingVisibleWindowState(final String windowName)1117     public List<WindowState> getMatchingVisibleWindowState(final String windowName) {
1118         return getMatchingWindows(ws -> ws.isSurfaceShown() && windowName.equals(ws.getName()))
1119                 .collect(Collectors.toList());
1120     }
1121 
getMatchingWindows(Predicate<WindowState> condition)1122     public Stream<WindowState> getMatchingWindows(Predicate<WindowState> condition) {
1123         return mWindowStates.stream().filter(condition);
1124     }
1125 
1126     @Nullable
getWindowByPackageName(String packageName, int windowType)1127     public WindowState getWindowByPackageName(String packageName, int windowType) {
1128         final List<WindowState> windowList = getWindowsByPackageName(packageName, windowType);
1129         return windowList.isEmpty() ? null : windowList.get(0);
1130     }
1131 
getWindowsByPackageName(String packageName, int... restrictToTypes)1132     public List<WindowState> getWindowsByPackageName(String packageName, int... restrictToTypes) {
1133         return getMatchingWindows(ws ->
1134                 (ws.getName().equals(packageName) || ws.getName().startsWith(packageName + "/"))
1135                         && Arrays.stream(restrictToTypes).anyMatch(type -> type == ws.getType()))
1136                 .collect(Collectors.toList());
1137     }
1138 
allActivitiesResumed()1139     public boolean allActivitiesResumed() {
1140         for (Task rootTask : mRootTasks) {
1141             final Activity nonResumedActivity =
1142                     rootTask.getActivity((a) -> !a.state.equals(STATE_RESUMED));
1143             if (nonResumedActivity != null) return false;
1144         }
1145         return true;
1146     }
1147 
hasNotificationShade()1148     public boolean hasNotificationShade() {
1149         computeState();
1150         return !getMatchingWindowType(TYPE_NOTIFICATION_SHADE).isEmpty();
1151     }
1152 
getWindows()1153     public List<WindowState> getWindows() {
1154         return new ArrayList<>(mWindowStates);
1155     }
1156 
getMatchingWindowType(int type)1157     public List<WindowState> getMatchingWindowType(int type) {
1158         return getMatchingWindows(ws -> type == ws.mType).collect(Collectors.toList());
1159     }
1160 
getAllNavigationBarStates()1161     public List<WindowState> getAllNavigationBarStates() {
1162         return mDisplays.stream()
1163                 .filter(dc -> dc.mProviders != null)
1164                 .flatMap(dc -> dc.mProviders.stream())
1165                 .filter(provider -> (provider.mSource.is(WindowInsets.Type.navigationBars())))
1166                 .map(InsetsSourceProvider::getWindowState)
1167                 .filter(Objects::nonNull)
1168                 .collect(Collectors.toList());
1169     }
1170 
1171     @NonNull
getNavBarWindowsOnDisplay(int displayId)1172     List<WindowState> getNavBarWindowsOnDisplay(int displayId) {
1173         List<WindowState> navWindows = mDisplays.stream()
1174                 .filter(dc -> dc.mId == displayId)
1175                 .filter(dc -> dc.mProviders != null)
1176                 .flatMap(dc -> dc.mProviders.stream())
1177                 .filter(provider -> (provider.mSource.is(WindowInsets.Type.navigationBars())))
1178                 .map(InsetsSourceProvider::getWindowState)
1179                 .filter(Objects::nonNull)
1180                 .collect(Collectors.toList());
1181 
1182         return navWindows;
1183     }
1184 
getWindowStateForAppToken(String appToken)1185     WindowState getWindowStateForAppToken(String appToken) {
1186         return getMatchingWindows(ws -> ws.getToken().equals(appToken))
1187                 .findFirst()
1188                 .orElse(null);
1189     }
1190 
getFrontWindow()1191     String getFrontWindow() {
1192         if (mWindowStates == null || mWindowStates.isEmpty()) {
1193             return null;
1194         }
1195         return mWindowStates.get(0).getName();
1196     }
1197 
1198     /** Check if there exists a window record with matching windowName. */
containsWindow(String windowName)1199     public boolean containsWindow(String windowName) {
1200         for (WindowState window : mWindowStates) {
1201             if (window.getName().equals(windowName)) {
1202                 return true;
1203             }
1204         }
1205         return false;
1206     }
1207 
1208     /**
1209      * Check if at least one window on {@code displayId}. which matches the specified name has shown
1210      * it's surface.
1211      */
isWindowSurfaceShownOnDisplay(String windowName, int displayId)1212     public boolean isWindowSurfaceShownOnDisplay(String windowName, int displayId) {
1213         for (WindowState window : mWindowStates) {
1214             if (window.getName().equals(windowName) && window.getDisplayId() == displayId) {
1215                 if (window.isSurfaceShown()) {
1216                     return true;
1217                 }
1218             }
1219         }
1220         return false;
1221     }
1222 
1223     /** Check if at least one window which matches the specified name has shown it's surface. */
isWindowSurfaceShown(String windowName)1224     public boolean isWindowSurfaceShown(String windowName) {
1225         for (WindowState window : mWindowStates) {
1226             if (window.getName().equals(windowName)) {
1227                 if (window.isSurfaceShown()) {
1228                     return true;
1229                 }
1230             }
1231         }
1232         return false;
1233     }
1234 
1235     /** Check if at least one window which matches provided window name is visible. */
isWindowVisible(String windowName)1236     public boolean isWindowVisible(String windowName) {
1237         for (WindowState window : mWindowStates) {
1238             if (window.getName().equals(windowName)) {
1239                 if (window.isVisible()) {
1240                     return true;
1241                 }
1242             }
1243         }
1244         return false;
1245     }
1246 
allWindowSurfacesShown(String windowName)1247     public boolean allWindowSurfacesShown(String windowName) {
1248         boolean allShown = false;
1249         for (WindowState window : mWindowStates) {
1250             if (window.getName().equals(windowName)) {
1251                 if (!window.isSurfaceShown()) {
1252                     log("[VISIBLE] not visible" + windowName);
1253                     return false;
1254                 }
1255                 log("[VISIBLE] visible" + windowName);
1256                 allShown = true;
1257             }
1258         }
1259         return allShown;
1260     }
1261 
1262     /** Checks whether the display contains the given activity. */
hasActivityInDisplay(int displayId, ComponentName activityName)1263     public boolean hasActivityInDisplay(int displayId, ComponentName activityName) {
1264         for (Task rootTask : getDisplay(displayId).getRootTasks()) {
1265             if (rootTask.containsActivity(activityName)) {
1266                 return true;
1267             }
1268         }
1269         return false;
1270     }
1271 
findFirstWindowWithType(int type)1272     public WindowState findFirstWindowWithType(int type) {
1273         for (WindowState window : mWindowStates) {
1274             if (window.getType() == type) {
1275                 return window;
1276             }
1277         }
1278         return null;
1279     }
1280 
getZOrder(WindowState w)1281     public int getZOrder(WindowState w) {
1282         return mWindowStates.size() - mWindowStates.indexOf(w);
1283     }
1284 
getStandardRootTaskByWindowingMode(int windowingMode)1285     public Task getStandardRootTaskByWindowingMode(int windowingMode) {
1286         for (Task task : mRootTasks) {
1287             if (task.getActivityType() != ACTIVITY_TYPE_STANDARD) {
1288                 continue;
1289             }
1290             if (task.getWindowingMode() == windowingMode) {
1291                 return task;
1292             }
1293         }
1294         return null;
1295     }
1296 
getInputMethodWindowState()1297     public WindowManagerState.WindowState getInputMethodWindowState() {
1298         return getWindowStateForAppToken(mInputMethodWindowAppToken);
1299     }
1300 
isDisplayFrozen()1301     public boolean isDisplayFrozen() {
1302         return mDisplayFrozen;
1303     }
1304 
getRotation()1305     public int getRotation() {
1306         return getDisplay(DEFAULT_DISPLAY).mRotation;
1307     }
1308 
getLastOrientation()1309     public int getLastOrientation() {
1310         return getDisplay(DEFAULT_DISPLAY).mLastOrientation;
1311     }
1312 
getFocusedDisplayId()1313     public int getFocusedDisplayId() {
1314         return mFocusedDisplayId;
1315     }
1316 
isFixedToUserRotation()1317     public boolean isFixedToUserRotation() {
1318         return getDisplay(DEFAULT_DISPLAY).mIsFixedToUserRotation;
1319     }
1320 
1321     public static class DisplayContent extends DisplayArea {
1322         public int mId;
1323         ArrayList<Task> mRootTasks = new ArrayList<>();
1324         int mFocusedRootTaskId;
1325         String mResumedActivity;
1326         boolean mSingleTaskInstance;
1327         Rect mDefaultPinnedStackBounds = null;
1328         Rect mPinnedStackMovementBounds = null;
1329         int mMinSizeOfResizeableTaskDp;
1330 
1331         private Rect mDisplayRect = new Rect();
1332         private Rect mAppRect = new Rect();
1333         private int mDpi;
1334         private int mFlags;
1335         private String mName;
1336         private int mSurfaceSize;
1337         private String mFocusedApp;
1338         private String mLastTransition;
1339         private String mAppTransitionState;
1340         private int mRotation;
1341         private boolean mFrozenToUserRotation;
1342         private int mUserRotation;
1343         private int mFixedToUserRotationMode;
1344         private int mLastOrientation;
1345         private boolean mIsFixedToUserRotation;
1346         private List<Rect> mKeepClearRects;
1347         private List<InsetsSourceProvider> mProviders;
1348 
DisplayContent(DisplayContentProto proto)1349         DisplayContent(DisplayContentProto proto) {
1350             super(proto.getRootDisplayArea());
1351             mId = proto.getId();
1352             mFocusedRootTaskId = proto.getFocusedRootTaskId();
1353             mSingleTaskInstance = proto.getSingleTaskInstance();
1354             if (proto.hasResumedActivity()) {
1355                 mResumedActivity = proto.getResumedActivity().getTitle();
1356             }
1357             addRootTasks();
1358 
1359             mDpi = proto.getDpi();
1360             if (proto.hasDisplayInfo()) {
1361                 DisplayInfoProto infoProto = proto.getDisplayInfo();
1362                 mDisplayRect.set(0, 0, infoProto.getLogicalWidth(), infoProto.getLogicalHeight());
1363                 mAppRect.set(0, 0, infoProto.getAppWidth(), infoProto.getAppHeight());
1364                 mName = infoProto.getName();
1365                 mFlags = infoProto.getFlags();
1366             }
1367             final DisplayFramesProto displayFramesProto = proto.getDisplayFrames();
1368             mSurfaceSize = proto.getSurfaceSize();
1369             mFocusedApp = proto.getFocusedApp();
1370             mMinSizeOfResizeableTaskDp = proto.getMinSizeOfResizeableTaskDp();
1371             int appState = 0;
1372             int lastTransition = 0;
1373             if (proto.hasAppTransition()) {
1374                 final AppTransitionProto appTransitionProto = proto.getAppTransition();
1375                 appState = appTransitionProto.getAppTransitionState().getNumber();
1376                 lastTransition = appTransitionProto.getLastUsedAppTransition().getNumber();
1377             }
1378             mAppTransitionState = appStateToString(appState);
1379             mLastTransition = appTransitionToString(lastTransition);
1380 
1381             if (proto.hasPinnedTaskController()) {
1382                 PinnedTaskControllerProto pinnedTaskProto = proto.getPinnedTaskController();
1383                 mDefaultPinnedStackBounds = extract(pinnedTaskProto.getDefaultBounds());
1384                 mPinnedStackMovementBounds = extract(pinnedTaskProto.getMovementBounds());
1385             }
1386 
1387             if (proto.hasDisplayRotation()) {
1388                 final DisplayRotationProto rotationProto = proto.getDisplayRotation();
1389                 mRotation = rotationProto.getRotation();
1390                 mFrozenToUserRotation = rotationProto.getFrozenToUserRotation();
1391                 mUserRotation = rotationProto.getUserRotation();
1392                 mFixedToUserRotationMode = rotationProto.getFixedToUserRotationMode();
1393                 mLastOrientation = rotationProto.getLastOrientation();
1394                 mIsFixedToUserRotation = rotationProto.getIsFixedToUserRotation();
1395             }
1396             mKeepClearRects = new ArrayList();
1397             for (int i = 0; i < proto.getKeepClearAreasCount(); ++i) {
1398                 RectProto r = proto.getKeepClearAreas(i);
1399                 mKeepClearRects.add(new Rect(r.getLeft(), r.getTop(), r.getRight(), r.getBottom()));
1400             }
1401             mProviders = new ArrayList<>();
1402             for (int i = 0; i < proto.getInsetsSourceProvidersCount(); ++i) {
1403                 InsetsSourceProviderProto provider = proto.getInsetsSourceProviders(i);
1404                 mProviders.add(new InsetsSourceProvider(provider));
1405             }
1406         }
1407 
DisplayContent(com.android.server.wm.nano.DisplayContentProto proto)1408         DisplayContent(com.android.server.wm.nano.DisplayContentProto proto) {
1409             super(proto.rootDisplayArea);
1410             mId = proto.id;
1411             mFocusedRootTaskId = proto.focusedRootTaskId;
1412             mSingleTaskInstance = proto.singleTaskInstance;
1413             if (proto.resumedActivity != null) {
1414                 mResumedActivity = proto.resumedActivity.title;
1415             }
1416             addRootTasks();
1417 
1418             mDpi = proto.dpi;
1419             android.view.nano.DisplayInfoProto infoProto = proto.displayInfo;
1420             if (infoProto != null) {
1421                 mDisplayRect.set(0, 0, infoProto.logicalWidth, infoProto.logicalHeight);
1422                 mAppRect.set(0, 0, infoProto.appWidth, infoProto.appHeight);
1423                 mName = infoProto.name;
1424                 mFlags = infoProto.flags;
1425             }
1426             final com.android.server.wm.nano.DisplayFramesProto displayFramesProto =
1427                     proto.displayFrames;
1428             mSurfaceSize = proto.surfaceSize;
1429             mFocusedApp = proto.focusedApp;
1430             mMinSizeOfResizeableTaskDp = proto.minSizeOfResizeableTaskDp;
1431 
1432             final com.android.server.wm.nano.AppTransitionProto appTransitionProto =
1433                     proto.appTransition;
1434             int appState = 0;
1435             int lastTransition = 0;
1436             if (appTransitionProto != null) {
1437                 appState = appTransitionProto.appTransitionState;
1438                 lastTransition = appTransitionProto.lastUsedAppTransition;
1439             }
1440             mAppTransitionState = appStateToString(appState);
1441             mLastTransition = appTransitionToString(lastTransition);
1442 
1443             com.android.server.wm.nano.PinnedTaskControllerProto pinnedTaskProto =
1444                     proto.pinnedTaskController;
1445             if (pinnedTaskProto != null) {
1446                 mDefaultPinnedStackBounds = extract(pinnedTaskProto.defaultBounds);
1447                 mPinnedStackMovementBounds = extract(pinnedTaskProto.movementBounds);
1448             }
1449 
1450             final com.android.server.wm.nano.DisplayRotationProto rotationProto =
1451                     proto.displayRotation;
1452             if (rotationProto != null) {
1453                 mRotation = rotationProto.rotation;
1454                 mFrozenToUserRotation = rotationProto.frozenToUserRotation;
1455                 mUserRotation = rotationProto.userRotation;
1456                 mFixedToUserRotationMode = rotationProto.fixedToUserRotationMode;
1457                 mLastOrientation = rotationProto.lastOrientation;
1458                 mIsFixedToUserRotation = rotationProto.isFixedToUserRotation;
1459             }
1460             mKeepClearRects = new ArrayList();
1461             for (android.graphics.nano.RectProto r : proto.keepClearAreas) {
1462                 mKeepClearRects.add(new Rect(r.left, r.top, r.right, r.bottom));
1463             }
1464             mProviders = new ArrayList<>();
1465             for (com.android.server.wm.nano.InsetsSourceProviderProto provider :
1466                     proto.insetsSourceProviders) {
1467                 mProviders.add(new InsetsSourceProvider(provider));
1468             }
1469         }
1470 
getName()1471         public String getName() {
1472             return mName;
1473         }
1474 
getMinSizeOfResizeableTaskDp()1475         public int getMinSizeOfResizeableTaskDp() {
1476             return mMinSizeOfResizeableTaskDp;
1477         }
1478 
addRootTasks()1479         private void addRootTasks() {
1480             // TODO(b/149338177): figure out how CTS tests deal with organizer. For now,
1481             //                    don't treat them as regular root tasks
1482             collectDescendantsOfTypeIf(Task.class, t -> t.isRootTask(), this,
1483                     mRootTasks);
1484 
1485             ArrayList<Task> nonOrganizedRootTasks = new ArrayList<>();
1486             for (int i = 0; i < mRootTasks.size(); i++) {
1487                 final Task task = mRootTasks.get(i);
1488                 if (task.mCreatedByOrganizer) {
1489                     // Get all tasks inside the root-task created by an organizer
1490                     List<Task> nonOrganizedDescendants = new ArrayList<>();
1491                     collectDescendantsOfTypeIf(Task.class, t -> !t.mCreatedByOrganizer, task,
1492                             nonOrganizedDescendants);
1493                     nonOrganizedRootTasks.addAll(nonOrganizedDescendants);
1494                 } else {
1495                     nonOrganizedRootTasks.add(task);
1496                 }
1497             }
1498 
1499             mRootTasks.clear();
1500             mRootTasks.addAll(nonOrganizedRootTasks);
1501         }
1502 
containsActivity(ComponentName activityName)1503         boolean containsActivity(ComponentName activityName) {
1504             for (Task task : mRootTasks) {
1505                 if (task.containsActivity(activityName)) return true;
1506             }
1507             return false;
1508         }
1509 
getAllTaskDisplayAreas()1510         public List<DisplayArea> getAllTaskDisplayAreas() {
1511             final List<DisplayArea> taskDisplayAreas = new ArrayList<>();
1512             collectDescendantsOfTypeIf(DisplayArea.class, DisplayArea::isTaskDisplayArea, this,
1513                     taskDisplayAreas);
1514             return taskDisplayAreas;
1515         }
1516 
1517         @Nullable
getTaskDisplayArea(ComponentName activityName)1518         DisplayArea getTaskDisplayArea(ComponentName activityName) {
1519             final List<DisplayArea> taskDisplayAreas = getAllTaskDisplayAreas();
1520             List<DisplayArea> result = taskDisplayAreas.stream().filter(
1521                     tda -> tda.containsActivity(activityName))
1522                     .collect(Collectors.toList());
1523 
1524             assertWithMessage("There must be exactly one activity among all TaskDisplayAreas.")
1525                     .that(result.size()).isAtMost(1);
1526 
1527             return result.stream().findFirst().orElse(null);
1528         }
1529 
getAllChildDisplayAreas()1530         public List<DisplayArea> getAllChildDisplayAreas() {
1531             final List<DisplayArea> displayAreas = new ArrayList<>();
1532             collectDescendantsOfType(DisplayArea.class,this, displayAreas);
1533             return displayAreas;
1534         }
1535 
1536         @Nullable
getDisplayArea(String windowName)1537         DisplayArea getDisplayArea(String windowName) {
1538             List<DisplayArea> displayAreas = new ArrayList<>();
1539             final Predicate<DisplayArea> p = da -> {
1540                 final boolean containsChildWindowToken = !da.mChildren.isEmpty()
1541                         && da.mChildren.get(0) instanceof WindowToken;
1542                 return !da.isTaskDisplayArea() && containsChildWindowToken;
1543             };
1544             collectDescendantsOfTypeIf(DisplayArea.class, p, this, displayAreas);
1545             List<DisplayArea> result = displayAreas.stream().filter(
1546                     da -> da.containsWindow(windowName))
1547                     .collect(Collectors.toList());
1548 
1549             assertWithMessage("There must be exactly one window among all DisplayAreas.")
1550                     .that(result.size()).isAtMost(1);
1551 
1552             return result.stream().findFirst().orElse(null);
1553         }
1554 
1555         @NonNull
getImeContainer()1556         public DisplayArea getImeContainer() {
1557             final List<DisplayArea> imeContainers = new ArrayList<>();
1558             final Predicate<DisplayArea> p = da -> da.getFeatureId() == FEATURE_IME;
1559             collectDescendantsOfTypeIf(DisplayArea.class, p, this, imeContainers);
1560 
1561             assertWithMessage("There must be exactly one ImeContainer per DisplayContent.")
1562                     .that(imeContainers.size()).isEqualTo(1);
1563 
1564             return imeContainers.get(0);
1565         }
1566 
getRootTasks()1567         public ArrayList<Task> getRootTasks() {
1568             return mRootTasks;
1569         }
1570 
getDpi()1571         public int getDpi() {
1572             return mDpi;
1573         }
1574 
getDisplayRect()1575         public Rect getDisplayRect() {
1576             return mDisplayRect;
1577         }
1578 
getAppRect()1579         public Rect getAppRect() {
1580             return mAppRect;
1581         }
1582 
getFlags()1583         public int getFlags() {
1584             return mFlags;
1585         }
1586 
getSurfaceSize()1587         public int getSurfaceSize() {
1588             return mSurfaceSize;
1589         }
1590 
getFocusedApp()1591         String getFocusedApp() {
1592             return mFocusedApp;
1593         }
1594 
getLastTransition()1595         public String getLastTransition() {
1596             return mLastTransition;
1597         }
1598 
getAppTransitionState()1599         public String getAppTransitionState() {
1600             return mAppTransitionState;
1601         }
1602 
getKeepClearRects()1603         public List<Rect> getKeepClearRects() {
1604             return mKeepClearRects;
1605         }
1606 
1607         @Override
toString()1608         public String toString() {
1609             return "Display #" + mId + ": name=" + mName + " mDisplayRect=" + mDisplayRect
1610                     + " mAppRect=" + mAppRect + " mFlags=" + mFlags;
1611         }
1612 
1613         @Override
equals(Object o)1614         public boolean equals(Object o) {
1615             if (o == this) {
1616                 return true;
1617             }
1618             if (o == null) {
1619                 return false;
1620             }
1621             if (!(o instanceof DisplayContent)) {
1622                 return false;
1623             }
1624 
1625             DisplayContent dc = (DisplayContent) o;
1626 
1627             return (dc.mDisplayRect == null ? mDisplayRect == null
1628                     : dc.mDisplayRect.equals(mDisplayRect))
1629                 && (dc.mAppRect == null ? mAppRect == null : dc.mAppRect.equals(mAppRect))
1630                 && dc.mDpi == mDpi
1631                 && dc.mFlags == mFlags
1632                 && (dc.mName == null ? mName == null : dc.mName.equals(mName))
1633                 && dc.mSurfaceSize == mSurfaceSize
1634                 && (dc.mAppTransitionState == null ? mAppTransitionState == null
1635                     : dc.mAppTransitionState.equals(mAppTransitionState))
1636                 && dc.mRotation == mRotation
1637                 && dc.mFrozenToUserRotation == mFrozenToUserRotation
1638                 && dc.mUserRotation == mUserRotation
1639                 && dc.mFixedToUserRotationMode == mFixedToUserRotationMode
1640                 && dc.mLastOrientation == mLastOrientation
1641                 && dc.mIsFixedToUserRotation == mIsFixedToUserRotation;
1642         }
1643 
1644         @Override
hashCode()1645         public int hashCode() {
1646             int result = 0;
1647             if (mDisplayRect != null) {
1648                 result = 31 * result + mDisplayRect.hashCode();
1649             }
1650             if (mAppRect != null) {
1651                 result = 31 * result + mAppRect.hashCode();
1652             }
1653             result = 31 * result + mDpi;
1654             result = 31 * result + mFlags;
1655             if (mName != null) {
1656                 result = 31 * result + mName.hashCode();
1657             }
1658             result = 31 * result + mSurfaceSize;
1659             if (mAppTransitionState != null) {
1660                 result = 31 * result + mAppTransitionState.hashCode();
1661             }
1662             result = 31 * result + mRotation;
1663             result = 31 * result + Boolean.hashCode(mFrozenToUserRotation);
1664             result = 31 * result + mUserRotation;
1665             result = 31 * result + mFixedToUserRotationMode;
1666             result = 31 * result + mLastOrientation;
1667             result = 31 * result + Boolean.hashCode(mIsFixedToUserRotation);
1668             return result;
1669         }
1670     }
1671 
1672     public static class Task extends ActivityContainer {
1673         int mTaskId;
1674         int mRootTaskId;
1675         public int mDisplayId;
1676         Rect mLastNonFullscreenBounds;
1677         String mRealActivity;
1678         String mOrigActivity;
1679         ArrayList<Task> mTasks = new ArrayList<>();
1680         /** Contains TaskFragment but not Task children */
1681         ArrayList<TaskFragment> mTaskFragments = new ArrayList<>();
1682         ArrayList<Activity> mActivities = new ArrayList<>();
1683         int mTaskType;
1684         private int mResizeMode;
1685         String mResumedActivity;
1686         boolean mAnimatingBounds;
1687         private int mSurfaceWidth;
1688         private int mSurfaceHeight;
1689         boolean mCreatedByOrganizer;
1690         String mAffinity;
1691         boolean mHasChildPipActivity;
1692         WindowContainer mParent;
1693 
Task(TaskProto proto, WindowContainer parent)1694         Task(TaskProto proto, WindowContainer parent) {
1695             super(proto.getTaskFragment().getWindowContainer());
1696             mTaskId = proto.getId();
1697             mRootTaskId = proto.getRootTaskId();
1698             mParent = parent;
1699             mDisplayId = proto.getTaskFragment().getDisplayId();
1700             mLastNonFullscreenBounds = extract(proto.getLastNonFullscreenBounds());
1701             mRealActivity = proto.getRealActivity();
1702             mOrigActivity = proto.getOrigActivity();
1703             mTaskType = proto.getTaskFragment().getActivityType();
1704             mResizeMode = proto.getResizeMode();
1705             mFullscreen = proto.getFillsParent();
1706             mBounds = extract(proto.getBounds());
1707             mMinWidth = proto.getTaskFragment().getMinWidth();
1708             mMinHeight = proto.getTaskFragment().getMinHeight();
1709             mAnimatingBounds = proto.getAnimatingBounds();
1710             mSurfaceWidth = proto.getSurfaceWidth();
1711             mSurfaceHeight = proto.getSurfaceHeight();
1712             mCreatedByOrganizer = proto.getCreatedByOrganizer();
1713             mAffinity = proto.getAffinity();
1714             mHasChildPipActivity = proto.getHasChildPipActivity();
1715 
1716             if (proto.hasResumedActivity()) {
1717                 mResumedActivity = proto.getResumedActivity().getTitle();
1718             }
1719 
1720             collectChildrenOfType(Task.class, this, mTasks);
1721             collectChildrenOfType(TaskFragment.class, this, mTaskFragments);
1722             collectChildrenOfType(Activity.class, this, mActivities);
1723         }
1724 
Task(com.android.server.wm.nano.TaskProto proto, WindowContainer parent)1725         Task(com.android.server.wm.nano.TaskProto proto, WindowContainer parent) {
1726             super(proto.taskFragment.windowContainer);
1727             mTaskId = proto.id;
1728             mRootTaskId = proto.rootTaskId;
1729             mParent = parent;
1730             mDisplayId = proto.taskFragment.displayId;
1731             mLastNonFullscreenBounds = extract(proto.lastNonFullscreenBounds);
1732             mRealActivity = proto.realActivity;
1733             mOrigActivity = proto.origActivity;
1734             mTaskType = proto.taskFragment.activityType;
1735             mResizeMode = proto.resizeMode;
1736             mFullscreen = proto.fillsParent;
1737             mBounds = extract(proto.bounds);
1738             mMinWidth = proto.taskFragment.minWidth;
1739             mMinHeight = proto.taskFragment.minHeight;
1740             mAnimatingBounds = proto.animatingBounds;
1741             mSurfaceWidth = proto.surfaceWidth;
1742             mSurfaceHeight = proto.surfaceHeight;
1743             mCreatedByOrganizer = proto.createdByOrganizer;
1744             mAffinity = proto.affinity;
1745             mHasChildPipActivity = proto.hasChildPipActivity;
1746 
1747             if (proto.resumedActivity != null) {
1748                 mResumedActivity = proto.resumedActivity.title;
1749             }
1750 
1751             collectChildrenOfType(Task.class, this, mTasks);
1752             collectChildrenOfType(TaskFragment.class, this, mTaskFragments);
1753             collectChildrenOfType(Activity.class, this, mActivities);
1754         }
1755 
isEmpty()1756         boolean isEmpty() {
1757             return mTasks.isEmpty() && mTaskFragments.isEmpty() && mActivities.isEmpty();
1758         }
1759 
getRealActivity()1760         public String getRealActivity() {
1761             return mRealActivity;
1762         }
1763 
hasChildPipActivity()1764         public boolean hasChildPipActivity() {
1765             return mHasChildPipActivity;
1766         }
1767 
1768         /** Gets the pure parent TaskFragment if exist. */
getParentTaskFragment()1769         public TaskFragment getParentTaskFragment() {
1770             if (mParent instanceof TaskFragment) {
1771                 return (TaskFragment) mParent;
1772             }
1773             if (mParent instanceof Task) {
1774                 return ((Task) mParent).getParentTaskFragment();
1775             }
1776             // If the parent is a TaskDisplayArea, it means this Task doesn't have TaskFragment
1777             // parent.
1778             return null;
1779         }
1780 
getResizeMode()1781         public int getResizeMode() {
1782             return mResizeMode;
1783         }
1784 
getTaskId()1785         public int getTaskId() {
1786             return mTaskId;
1787         }
isRootTask()1788         boolean isRootTask() {
1789             return mTaskId == mRootTaskId;
1790         }
1791 
isLeafTask()1792         boolean isLeafTask() {
1793             return mTasks.size() == 0;
1794         }
1795 
getRootTaskId()1796         public int getRootTaskId() {
1797             return mRootTaskId;
1798         }
1799 
getSurfaceWidth()1800         public int getSurfaceWidth() {
1801             return mSurfaceWidth;
1802         }
1803 
getSurfaceHeight()1804         public int getSurfaceHeight() {
1805             return mSurfaceHeight;
1806         }
1807 
getAffinity()1808         public String getAffinity() {
1809             return mAffinity;
1810         }
1811 
getActivities()1812         public ArrayList<Activity> getActivities() {
1813             return mActivities;
1814         }
1815 
1816         /** @return the top task in the root task. */
getTopTask()1817         public Task getTopTask() {
1818             // NOTE: Unlike the WindowManager internals, we dump the state from top to bottom,
1819             //       so the indices are inverted
1820             return getTask((t) -> true);
1821         }
1822 
getResumedActivity()1823         public String getResumedActivity() {
1824             return mResumedActivity;
1825         }
1826 
getTasks()1827         public List<Task> getTasks() {
1828             return new ArrayList<>(mTasks);
1829         }
1830 
1831         /** Returns non-Task leaf {@link TaskFragment} list. */
getTaskFragments()1832         public List<TaskFragment> getTaskFragments() {
1833             return new ArrayList<>(mTaskFragments);
1834         }
1835 
getTask(Predicate<Task> predicate)1836         Task getTask(Predicate<Task> predicate) {
1837             for (Task task : mTasks) {
1838                 if (predicate.test(task)) return task;
1839             }
1840             return predicate.test(this) ? this : null;
1841         }
1842 
getTask(int taskId)1843         Task getTask(int taskId) {
1844             return getTask((t) -> t.mTaskId == taskId);
1845         }
1846 
forAllTasks(Consumer<Task> consumer)1847         void forAllTasks(Consumer<Task> consumer) {
1848             for (Task task : mTasks) {
1849                 consumer.accept(task);
1850             }
1851             consumer.accept(this);
1852         }
1853 
getActivity(Predicate<Activity> predicate)1854         Activity getActivity(Predicate<Activity> predicate) {
1855             for (Activity activity : mActivities) {
1856                 if (predicate.test(activity)) return activity;
1857             }
1858             for (TaskFragment taskFragment : mTaskFragments) {
1859                 final Activity activity = taskFragment.getActivity(predicate);
1860                 if (activity != null) return activity;
1861             }
1862             for (Task task : mTasks) {
1863                 final Activity activity = task.getActivity(predicate);
1864                 if (activity != null) return activity;
1865             }
1866             return null;
1867         }
1868 
getActivity(ComponentName activityName)1869         public Activity getActivity(ComponentName activityName) {
1870             final String fullName = getActivityName(activityName);
1871             return getActivity((activity) -> activity.name.equals(fullName));
1872         }
1873 
getActivity(ComponentName activityName, int[] excludeTaskIds)1874         public Activity getActivity(ComponentName activityName, int[] excludeTaskIds) {
1875             final String fullName = getActivityName(activityName);
1876             return getActivity((activity) -> {
1877                 if (!activity.name.equals(fullName)) {
1878                     return false;
1879                 }
1880                 for (int excludeTaskId : excludeTaskIds) {
1881                     if (activity.getTask().mTaskId == excludeTaskId) {
1882                         return false;
1883                     }
1884                 }
1885                 return true;
1886             });
1887         }
1888 
containsActivity(ComponentName activityName)1889         public boolean containsActivity(ComponentName activityName) {
1890             return getActivity(activityName) != null;
1891         }
1892 
getActivityCount()1893         public int getActivityCount() {
1894             int count = mActivities.size();
1895             for (TaskFragment taskFragment : mTaskFragments) {
1896                 count += taskFragment.getActivityCount();
1897             }
1898             for (Task task : mTasks) {
1899                 count += task.getActivityCount();
1900             }
1901             return count;
1902         }
1903 
1904         @Override
getActivityType()1905         int getActivityType() {
1906             return mTaskType;
1907         }
1908 
1909         @Override
toString()1910         public String toString() {
1911             return "Task[id=" + mTaskId + ", display=" + mDisplayId
1912                     + ", mOrigActivity=" + mOrigActivity + ", realActivity=" + mRealActivity
1913                     + ", activities=" + mActivities + "]";
1914         }
1915     }
1916 
1917     public static class TaskFragment extends ActivityContainer {
1918         public int mDisplayId;
1919         Task mParentTask;
1920         ArrayList<Activity> mActivities = new ArrayList<>();
1921         int mTaskFragmentType;
1922 
1923         TaskFragment(TaskFragmentProto proto, WindowContainer parent) {
1924             super(proto.getWindowContainer());
1925             mParentTask = (Task) parent;
1926             mDisplayId = proto.getDisplayId();
1927             mTaskFragmentType = proto.getActivityType();
1928             mMinWidth = proto.getMinWidth();
1929             mMinHeight = proto.getMinHeight();
1930 
1931             collectChildrenOfType(Activity.class, this, mActivities);
1932         }
1933 
1934         TaskFragment(com.android.server.wm.nano.TaskFragmentProto proto, WindowContainer parent) {
1935             super(proto.windowContainer);
1936             mParentTask = (Task) parent;
1937             mDisplayId = proto.displayId;
1938             mTaskFragmentType = proto.activityType;
1939             mMinWidth = proto.minWidth;
1940             mMinHeight = proto.minHeight;
1941 
1942             collectChildrenOfType(Activity.class, this, mActivities);
1943         }
1944 
1945         public List<Activity> getActivities() {
1946             return mActivities;
1947         }
1948 
1949         Activity getActivity(Predicate<Activity> predicate) {
1950             for (Activity activity : mActivities) {
1951                 if (predicate.test(activity)) {
1952                     return activity;
1953                 }
1954             }
1955             return null;
1956         }
1957 
1958         public int getActivityCount() {
1959             return mActivities.size();
1960         }
1961 
1962         @Override
1963         int getActivityType() {
1964             return mTaskFragmentType;
1965         }
1966     }
1967 
1968     public static class Activity extends ActivityContainer {
1969 
1970         String name;
1971         String state;
1972         boolean visible;
1973         boolean frontOfTask;
1974         boolean inSizeCompatMode;
1975         float minAspectRatio;
1976         boolean providesMaxBounds;
1977         int procId = -1;
1978         boolean isAnimating;
1979         public boolean translucent;
1980         private WindowContainer mParent;
1981         private boolean mEnableRecentsScreenshot;
1982         private int mLastDropInputMode;
1983         private boolean mShouldSendCompatFakeFocus;
1984         private int mOverrideOrientation;
1985         private boolean mShouldForceRotateForCameraCompat;
1986         private boolean mShouldRefreshActivityForCameraCompat;
1987         private boolean mShouldRefreshActivityViaPauseForCameraCompat;
1988         private boolean mShouldOverrideMinAspectRatio;
1989         private boolean mShouldIgnoreOrientationRequestLoop;
1990         private boolean mShouldOverrideForceResizeApp;
1991         private boolean mShouldEnableUserAspectRatioSettings;
1992         private boolean mIsUserFullscreenOverrideEnabled;
1993 
1994         Activity(ActivityRecordProto proto, WindowContainer parent) {
1995             super(proto.getWindowToken().getWindowContainer());
1996             name = proto.getName();
1997             state = proto.getState();
1998             visible = proto.getVisible();
1999             frontOfTask = proto.getFrontOfTask();
2000             inSizeCompatMode = proto.getInSizeCompatMode();
2001             minAspectRatio = proto.getMinAspectRatio();
2002             providesMaxBounds = proto.getProvidesMaxBounds();
2003             if (proto.hasProcId()) {
2004                 procId = proto.getProcId();
2005             }
2006             isAnimating = proto.getIsAnimating();
2007             translucent = proto.getTranslucent();
2008             mEnableRecentsScreenshot = proto.getEnableRecentsScreenshot();
2009             mLastDropInputMode = proto.getLastDropInputMode();
2010             mShouldSendCompatFakeFocus = proto.getShouldSendCompatFakeFocus();
2011             mOverrideOrientation = proto.getOverrideOrientation();
2012             mParent = parent;
2013             mShouldForceRotateForCameraCompat = proto.getShouldForceRotateForCameraCompat();
2014             mShouldRefreshActivityForCameraCompat = proto.getShouldRefreshActivityForCameraCompat();
2015             mShouldRefreshActivityViaPauseForCameraCompat =
2016                     proto.getShouldRefreshActivityViaPauseForCameraCompat();
2017             mShouldOverrideMinAspectRatio = proto.getShouldOverrideMinAspectRatio();
2018             mShouldIgnoreOrientationRequestLoop = proto.getShouldIgnoreOrientationRequestLoop();
2019             mShouldOverrideForceResizeApp = proto.getShouldOverrideForceResizeApp();
2020             mShouldEnableUserAspectRatioSettings = proto.getShouldEnableUserAspectRatioSettings();
2021             mIsUserFullscreenOverrideEnabled = proto.getIsUserFullscreenOverrideEnabled();
2022         }
2023 
2024         Activity(com.android.server.wm.nano.ActivityRecordProto proto, WindowContainer parent) {
2025             super(proto.windowToken.windowContainer);
2026             name = proto.name;
2027             state = proto.state;
2028             visible = proto.visible;
2029             frontOfTask = proto.frontOfTask;
2030             inSizeCompatMode = proto.inSizeCompatMode;
2031             minAspectRatio = proto.minAspectRatio;
2032             providesMaxBounds = proto.providesMaxBounds;
2033             if (proto.procId != 0) {
2034                 procId = proto.procId;
2035             }
2036             isAnimating = proto.isAnimating;
2037             translucent = proto.translucent;
2038             mEnableRecentsScreenshot = proto.enableRecentsScreenshot;
2039             mLastDropInputMode = proto.lastDropInputMode;
2040             mShouldSendCompatFakeFocus = proto.shouldSendCompatFakeFocus;
2041             mOverrideOrientation = proto.overrideOrientation;
2042             mParent = parent;
2043             mShouldForceRotateForCameraCompat = proto.shouldForceRotateForCameraCompat;
2044             mShouldRefreshActivityForCameraCompat = proto.shouldRefreshActivityForCameraCompat;
2045             mShouldRefreshActivityViaPauseForCameraCompat =
2046                     proto.shouldRefreshActivityViaPauseForCameraCompat;
2047             mShouldOverrideMinAspectRatio = proto.shouldOverrideMinAspectRatio;
2048             mShouldIgnoreOrientationRequestLoop = proto.shouldIgnoreOrientationRequestLoop;
2049             mShouldOverrideForceResizeApp = proto.shouldOverrideForceResizeApp;
2050             mShouldEnableUserAspectRatioSettings = proto.shouldEnableUserAspectRatioSettings;
2051             mIsUserFullscreenOverrideEnabled = proto.isUserFullscreenOverrideEnabled;
2052         }
2053 
2054         @NonNull
2055         public Task getTask() {
2056             if (mParent instanceof Task) {
2057                 return (Task) mParent;
2058             }
2059             return ((TaskFragment) mParent).mParentTask;
2060         }
2061 
2062         @Nullable
2063         public TaskFragment getTaskFragment() {
2064             if (mParent instanceof TaskFragment) {
2065                 return (TaskFragment) mParent;
2066             }
2067             return ((Task) mParent).getParentTaskFragment();
2068         }
2069 
2070         public String getName() {
2071             return name;
2072         }
2073 
2074         public String getState() {
2075             return state;
2076         }
2077 
2078         public boolean inSizeCompatMode() {
2079             return inSizeCompatMode;
2080         }
2081 
2082         public boolean isAnimating() {
2083             return isAnimating;
2084         }
2085 
2086         public float getMinAspectRatio() {
2087             return minAspectRatio;
2088         }
2089 
2090         public boolean providesMaxBounds() {
2091             return providesMaxBounds;
2092         }
2093 
2094         public boolean enableRecentsScreenshot() {
2095             return mEnableRecentsScreenshot;
2096         }
2097 
2098         public int getLastDropInputMode() {
2099             return mLastDropInputMode;
2100         }
2101 
2102         public boolean getShouldSendCompatFakeFocus() {
2103             return mShouldSendCompatFakeFocus;
2104         }
2105 
2106         public int getUiMode() {
2107             return mFullConfiguration.uiMode;
2108         }
2109 
2110         public int getOverrideOrientation() {
2111             return mOverrideOrientation;
2112         }
2113 
2114         public boolean getShouldForceRotateForCameraCompat() {
2115             return mShouldForceRotateForCameraCompat;
2116         }
2117 
2118         public boolean getShouldRefreshActivityForCameraCompat() {
2119             return mShouldRefreshActivityForCameraCompat;
2120         }
2121 
2122         public boolean getShouldRefreshActivityViaPauseForCameraCompat() {
2123             return mShouldRefreshActivityViaPauseForCameraCompat;
2124         }
2125 
2126         public boolean getShouldOverrideMinAspectRatio() {
2127             return mShouldOverrideMinAspectRatio;
2128         }
2129 
2130         public boolean getShouldIgnoreOrientationRequestLoop() {
2131             return mShouldIgnoreOrientationRequestLoop;
2132         }
2133 
2134         public boolean getShouldOverrideForceResizeApp() {
2135             return mShouldOverrideForceResizeApp;
2136         }
2137 
2138         public boolean getShouldEnableUserAspectRatioSettings() {
2139             return mShouldEnableUserAspectRatioSettings;
2140         }
2141 
2142         public boolean getIsUserFullscreenOverrideEnabled() {
2143             return mIsUserFullscreenOverrideEnabled;
2144         }
2145 
2146 
2147         @Override
2148         public Rect getBounds() {
2149             if (mBounds == null) {
2150                 return mFullConfiguration.windowConfiguration.getBounds();
2151             }
2152             return mBounds;
2153         }
2154 
2155         public Rect getMaxBounds() {
2156             return mFullConfiguration.windowConfiguration.getMaxBounds();
2157         }
2158 
2159         public Rect getAppBounds() {
2160             return mFullConfiguration.windowConfiguration.getAppBounds();
2161         }
2162 
2163         @Override
2164         public String toString() {
2165             return "Activity[name=" + name + ", state=" + state + ", visible=" + visible + "]";
2166         }
2167     }
2168 
2169     static abstract class ActivityContainer extends WindowContainer {
2170         protected boolean mFullscreen;
2171         protected Rect mBounds;
2172         protected int mMinWidth = -1;
2173         protected int mMinHeight = -1;
2174 
2175         ActivityContainer(WindowContainerProto proto) {
2176             super(proto);
2177         }
2178 
2179         ActivityContainer(com.android.server.wm.nano.WindowContainerProto proto) {
2180             super(proto);
2181         }
2182 
2183         public Rect getBounds() {
2184             return mBounds;
2185         }
2186 
2187         public boolean isFullscreen() {
2188             return mFullscreen;
2189         }
2190 
2191         int getMinWidth() {
2192             return mMinWidth;
2193         }
2194 
2195         int getMinHeight() {
2196             return mMinHeight;
2197         }
2198     }
2199 
2200     public static class KeyguardControllerState {
2201 
2202         boolean aodShowing = false;
2203         boolean keyguardShowing = false;
2204         boolean mKeyguardGoingAway = false;
2205         SparseArray<Boolean> mKeyguardOccludedStates = new SparseArray<>();
2206 
2207         public boolean isKeyguardShowing() {
2208             return keyguardShowing;
2209         }
2210 
2211         public boolean isKeyguardGoingAway() {
2212             return mKeyguardGoingAway;
2213         }
2214 
2215         public boolean isAodShowing() {
2216             return aodShowing;
2217         }
2218 
2219         public SparseArray<Boolean> getKeyguardOccludedStates() {
2220             return mKeyguardOccludedStates;
2221         }
2222 
2223         KeyguardControllerState(KeyguardControllerProto proto) {
2224             if (proto != null) {
2225                 aodShowing = proto.getAodShowing();
2226                 keyguardShowing = proto.getKeyguardShowing();
2227                 mKeyguardGoingAway = proto.getKeyguardGoingAway();
2228                 for (int i = 0;  i < proto.getKeyguardPerDisplayCount(); i++) {
2229                     mKeyguardOccludedStates.append(proto.getKeyguardPerDisplay(i).getDisplayId(),
2230                             proto.getKeyguardPerDisplay(i).getKeyguardOccluded());
2231                 }
2232             }
2233         }
2234 
2235         KeyguardControllerState(com.android.server.wm.nano.KeyguardControllerProto proto) {
2236             if (proto != null) {
2237                 aodShowing = proto.aodShowing;
2238                 keyguardShowing = proto.keyguardShowing;
2239                 mKeyguardGoingAway = proto.keyguardGoingAway;
2240                 for (int i = 0;  i < proto.keyguardPerDisplay.length; i++) {
2241                     mKeyguardOccludedStates.append(proto.keyguardPerDisplay[i].displayId,
2242                             proto.keyguardPerDisplay[i].keyguardOccluded);
2243                 }
2244             }
2245         }
2246 
2247         boolean isKeyguardOccluded(int displayId) {
2248             if (mKeyguardOccludedStates.get(displayId) != null) {
2249                 return mKeyguardOccludedStates.get(displayId);
2250             }
2251             return false;
2252         }
2253     }
2254 
2255     static class KeyguardServiceDelegateState {
2256 
2257         // copy from KeyguardServiceDelegate.java
2258         private static final int INTERACTIVE_STATE_SLEEP = 0;
2259         private static final int INTERACTIVE_STATE_WAKING = 1;
2260         private static final int INTERACTIVE_STATE_AWAKE = 2;
2261         private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 3;
2262 
2263         private int mInteractiveState = -1;
2264 
2265         KeyguardServiceDelegateState(KeyguardServiceDelegateProto proto) {
2266             if (proto != null) {
2267                 mInteractiveState = proto.getInteractiveState().getNumber();
2268             }
2269         }
2270 
2271         KeyguardServiceDelegateState(
2272                 com.android.server.wm.nano.KeyguardServiceDelegateProto proto) {
2273             if (proto != null) {
2274                 mInteractiveState = proto.interactiveState;
2275             }
2276         }
2277 
2278         boolean isKeyguardAwake() {
2279             return mInteractiveState == INTERACTIVE_STATE_AWAKE;
2280         }
2281     }
2282 
2283     public static class ConfigurationContainer {
2284         final Configuration mOverrideConfiguration = new Configuration();
2285         final Configuration mFullConfiguration = new Configuration();
2286         final Configuration mMergedOverrideConfiguration = new Configuration();
2287 
2288         ConfigurationContainer(ConfigurationContainerProto proto) {
2289             if (proto == null) {
2290                 return;
2291             }
2292             mOverrideConfiguration.setTo(extract(proto.getOverrideConfiguration()));
2293             mFullConfiguration.setTo(extract(proto.getFullConfiguration()));
2294             mMergedOverrideConfiguration.setTo(extract(proto.getMergedOverrideConfiguration()));
2295         }
2296 
2297         ConfigurationContainer(com.android.server.wm.nano.ConfigurationContainerProto proto) {
2298             if (proto == null) {
2299                 return;
2300             }
2301             mOverrideConfiguration.setTo(extract(proto.overrideConfiguration));
2302             mFullConfiguration.setTo(extract(proto.fullConfiguration));
2303             mMergedOverrideConfiguration.setTo(extract(proto.mergedOverrideConfiguration));
2304         }
2305 
2306         public Configuration getOverrideConfiguration() {
2307             return mOverrideConfiguration;
2308         }
2309 
2310         public Configuration getFullConfiguration() {
2311             return mFullConfiguration;
2312         }
2313 
2314         public Configuration getMergedOverrideConfiguration() {
2315             return mMergedOverrideConfiguration;
2316         }
2317 
2318         boolean isWindowingModeCompatible(int requestedWindowingMode) {
2319             if (requestedWindowingMode == WINDOWING_MODE_UNDEFINED) {
2320                 return true;
2321             }
2322             return getWindowingMode() == requestedWindowingMode;
2323         }
2324 
2325         public int getWindowingMode() {
2326             if (mFullConfiguration == null) {
2327                 return WINDOWING_MODE_UNDEFINED;
2328             }
2329             return mFullConfiguration.windowConfiguration.getWindowingMode();
2330         }
2331 
2332         int getActivityType() {
2333             if (mFullConfiguration == null) {
2334                 return ACTIVITY_TYPE_UNDEFINED;
2335             }
2336             return mFullConfiguration.windowConfiguration.getActivityType();
2337         }
2338     }
2339 
2340     public static class RootWindowContainer extends WindowContainer {
2341         RootWindowContainer(RootWindowContainerProto proto) {
2342             super(proto.getWindowContainer());
2343         }
2344 
2345         RootWindowContainer(com.android.server.wm.nano.RootWindowContainerProto proto) {
2346             super(proto.windowContainer);
2347         }
2348     }
2349     public static class DisplayArea extends WindowContainer {
2350         private final boolean mIsTaskDisplayArea;
2351         private final boolean mIsRootDisplayArea;
2352         private final int mFeatureId;
2353         private final boolean mIsOrganized;
2354         private final boolean mIsIgnoringOrientationRequest;
2355         private ArrayList<Activity> mActivities;
2356         private final ArrayList<WindowState> mWindows = new ArrayList<>();
2357 
2358         DisplayArea(DisplayAreaProto proto) {
2359             super(proto.getWindowContainer());
2360             mIsTaskDisplayArea = proto.getIsTaskDisplayArea();
2361             mIsRootDisplayArea = proto.getIsRootDisplayArea();
2362             mFeatureId = proto.getFeatureId();
2363             mIsOrganized = proto.getIsOrganized();
2364             mIsIgnoringOrientationRequest = proto.getIsIgnoringOrientationRequest();
2365             if (mIsTaskDisplayArea) {
2366                 mActivities = new ArrayList<>();
2367                 collectDescendantsOfType(Activity.class, this, mActivities);
2368             }
2369             collectDescendantsOfType(WindowState.class, this, mWindows);
2370         }
2371 
2372         DisplayArea(com.android.server.wm.nano.DisplayAreaProto proto) {
2373             super(proto.windowContainer);
2374             mIsTaskDisplayArea = proto.isTaskDisplayArea;
2375             mIsRootDisplayArea = proto.isRootDisplayArea;
2376             mFeatureId = proto.featureId;
2377             mIsOrganized = proto.isOrganized;
2378             mIsIgnoringOrientationRequest = proto.isIgnoringOrientationRequest;
2379             if (mIsTaskDisplayArea) {
2380                 mActivities = new ArrayList<>();
2381                 collectDescendantsOfType(Activity.class, this, mActivities);
2382             }
2383             collectDescendantsOfType(WindowState.class, this, mWindows);
2384         }
2385 
2386         public boolean isTaskDisplayArea() {
2387             return mIsTaskDisplayArea;
2388         }
2389 
2390         public boolean isRootDisplayArea() {
2391             return mIsRootDisplayArea;
2392         }
2393 
2394         public int getFeatureId() {
2395             return mFeatureId;
2396         }
2397 
2398         public boolean isOrganized() {
2399             return mIsOrganized;
2400         }
2401 
2402         public Rect getAppBounds() {
2403             return mFullConfiguration.windowConfiguration.getAppBounds();
2404         }
2405 
2406         public boolean isIgnoringOrientationRequest() {
2407             return mIsIgnoringOrientationRequest;
2408         }
2409 
2410         @Override
2411         public Rect getBounds() {
2412             if (mBounds == null) {
2413                 return mFullConfiguration.windowConfiguration.getBounds();
2414             }
2415             return mBounds;
2416         }
2417 
2418         boolean containsActivity(ComponentName activityName) {
2419             if (!mIsTaskDisplayArea) {
2420                 return false;
2421             }
2422 
2423             final String fullName = getActivityName(activityName);
2424             for (Activity a : mActivities) {
2425                 if (a.name.equals(fullName)) {
2426                     return true;
2427                 }
2428             }
2429             return false;
2430         }
2431 
2432         boolean containsWindow(String windowName) {
2433             for (WindowState w : mWindows) {
2434                 if (w.mName.equals(windowName)) {
2435                     return true;
2436                 }
2437             }
2438             return false;
2439         }
2440     }
2441     public static class WindowToken extends WindowContainer {
2442         WindowToken(WindowTokenProto proto) {
2443             super(proto.getWindowContainer());
2444         }
2445 
2446         WindowToken(com.android.server.wm.nano.WindowTokenProto proto) {
2447             super(proto.windowContainer);
2448         }
2449     }
2450 
2451     /**
2452      * Represents WindowContainer classes such as DisplayContent.WindowContainers and
2453      * DisplayContent.NonAppWindowContainers. This can be expanded into a specific class
2454      * if we need track and assert some state in the future.
2455      */
2456     public static class GenericWindowContainer extends WindowContainer {
2457         GenericWindowContainer(WindowContainerProto proto) {
2458             super(proto);
2459         }
2460 
2461         GenericWindowContainer(com.android.server.wm.nano.WindowContainerProto proto) {
2462             super(proto);
2463         }
2464     }
2465 
2466     static WindowContainer getWindowContainer(WindowContainerChildProto proto,
2467             WindowContainer parent) {
2468         if (proto.hasDisplayContent()) {
2469             return new DisplayContent(proto.getDisplayContent());
2470         }
2471 
2472         if (proto.hasDisplayArea()) {
2473             return new DisplayArea(proto.getDisplayArea());
2474         }
2475 
2476         if (proto.hasTask()) {
2477             return new Task(proto.getTask(), parent);
2478         }
2479 
2480         if (proto.hasTaskFragment()) {
2481             return new TaskFragment(proto.getTaskFragment(), parent);
2482         }
2483 
2484         if (proto.hasActivity()) {
2485             return new Activity(proto.getActivity(), parent);
2486         }
2487 
2488         if (proto.hasWindowToken()) {
2489             return new WindowToken(proto.getWindowToken());
2490         }
2491 
2492         if (proto.hasWindow()) {
2493             return new WindowState(proto.getWindow());
2494         }
2495 
2496         if (proto.hasWindowContainer()) {
2497             return new GenericWindowContainer(proto.getWindowContainer());
2498         }
2499         return null;
2500     }
2501 
2502     static WindowContainer getWindowContainer(
2503             com.android.server.wm.nano.WindowContainerChildProto proto,
2504             WindowContainer parent) {
2505         if (proto.displayContent != null) {
2506             return new DisplayContent(proto.displayContent);
2507         }
2508 
2509         if (proto.displayArea != null) {
2510             return new DisplayArea(proto.displayArea);
2511         }
2512 
2513         if (proto.task != null) {
2514             return new Task(proto.task, parent);
2515         }
2516 
2517         if (proto.taskFragment != null) {
2518             return new TaskFragment(proto.taskFragment, parent);
2519         }
2520 
2521         if (proto.activity != null) {
2522             return new Activity(proto.activity, parent);
2523         }
2524 
2525         if (proto.windowToken != null) {
2526             return new WindowToken(proto.windowToken);
2527         }
2528 
2529         if (proto.window != null) {
2530             return new WindowState(proto.window);
2531         }
2532 
2533         if (proto.windowContainer != null) {
2534             return new GenericWindowContainer(proto.windowContainer);
2535         }
2536         return null;
2537     }
2538 
2539     public abstract static class WindowContainer extends ConfigurationContainer {
2540 
2541         protected String mName;
2542         protected final String mAppToken;
2543         protected boolean mFullscreen;
2544         protected Rect mBounds;
2545         protected int mOrientation;
2546         protected boolean mVisible;
2547         protected List<WindowState> mSubWindows = new ArrayList<>();
2548         protected List<WindowContainer> mChildren = new ArrayList<>();
2549 
2550         WindowContainer(WindowContainerProto proto) {
2551             super(proto.hasConfigurationContainer() ? proto.getConfigurationContainer() : null);
2552             IdentifierProto identifierProto = proto.getIdentifier();
2553             mName = identifierProto.getTitle();
2554             mAppToken = Integer.toHexString(identifierProto.getHashCode());
2555             mOrientation = proto.getOrientation();
2556             for (int i = 0; i < proto.getChildrenCount(); i++) {
2557                 final WindowContainer child = getWindowContainer(proto.getChildren(i), this);
2558                 if (child != null) {
2559                     mChildren.add(child);
2560                 }
2561             }
2562             mVisible = proto.getVisible();
2563         }
2564 
2565         WindowContainer(com.android.server.wm.nano.WindowContainerProto proto) {
2566             super(proto.configurationContainer);
2567             com.android.server.wm.nano.IdentifierProto identifierProto = proto.identifier;
2568             mName = identifierProto.title;
2569             mAppToken = Integer.toHexString(identifierProto.hashCode);
2570             mOrientation = proto.orientation;
2571             for (int i = 0; i < proto.children.length; i++) {
2572                 final WindowContainer child = getWindowContainer(proto.children[i], this);
2573                 if (child != null) {
2574                     mChildren.add(child);
2575                 }
2576             }
2577             mVisible = proto.visible;
2578         }
2579 
2580         @NonNull
2581         public String getName() {
2582             return mName;
2583         }
2584 
2585         @NonNull
2586         public String getPackageName() {
2587             int sep = mName.indexOf('/');
2588             return sep == -1 ? mName : mName.substring(0, sep);
2589         }
2590 
2591         public List<WindowContainer> getChildren() {
2592             return mChildren;
2593         }
2594 
2595         public String getToken() {
2596             return mAppToken;
2597         }
2598 
2599         public Rect getBounds() {
2600             return mBounds;
2601         }
2602 
2603         boolean isFullscreen() {
2604             return mFullscreen;
2605         }
2606 
2607         public boolean isVisible() {
2608             return mVisible;
2609         }
2610 
2611         List<WindowState> getWindows() {
2612             return mSubWindows;
2613         }
2614     }
2615 
2616     public static class WindowState extends WindowContainer {
2617 
2618         private static final int WINDOW_TYPE_NORMAL = 0;
2619         public static final int WINDOW_TYPE_STARTING = 1;
2620         private static final int WINDOW_TYPE_EXITING = 2;
2621         private static final int WINDOW_TYPE_DEBUGGER = 3;
2622 
2623         private final int mWindowType;
2624         private int mType = 0;
2625         private int mDisplayId;
2626         private int mStackId;
2627         private int mLayer;
2628         private boolean mShown;
2629         private Rect mParentFrame;
2630         private Rect mFrame;
2631         private Rect mCompatFrame;
2632         private Rect mSurfaceInsets;
2633         private Rect mGivenContentInsets;
2634         private Rect mCrop = new Rect();
2635         private boolean mHasCompatScale;
2636         private float mGlobalScale;
2637         private int mRequestedWidth;
2638         private int mRequestedHeight;
2639         private List<Rect> mKeepClearRects;
2640         private List<Rect> mUnrestrictedKeepClearRects;
2641         private List<InsetsSource> mMergedLocalInsetsSources;
2642         private int mFlags;
2643         private Rect mDimBounds;
2644 
2645         WindowState(WindowStateProto proto) {
2646             super(proto.getWindowContainer());
2647             mDisplayId = proto.getDisplayId();
2648             mStackId = proto.getStackId();
2649             if (proto.hasAttributes()) {
2650                 mType = proto.getAttributes().getType();
2651                 mFlags = proto.getAttributes().getFlags();
2652             }
2653             if (proto.hasAnimator()) {
2654                 WindowStateAnimatorProto animatorProto = proto.getAnimator();
2655                 if (animatorProto.hasSurface()) {
2656                     WindowSurfaceControllerProto surfaceProto = animatorProto.getSurface();
2657                     mShown = surfaceProto.getShown();
2658                     mLayer = surfaceProto.getLayer();
2659                 }
2660                 mCrop = extract(animatorProto.getLastClipRect());
2661             }
2662             mGivenContentInsets = extract(proto.getGivenContentInsets());
2663             if (proto.hasWindowFrames()) {
2664                 WindowFramesProto windowFramesProto = proto.getWindowFrames();
2665                 mFrame = extract(windowFramesProto.getFrame());
2666                 mParentFrame = extract(windowFramesProto.getParentFrame());
2667                 mCompatFrame = extract(windowFramesProto.getCompatFrame());
2668             }
2669             mSurfaceInsets = extract(proto.getSurfaceInsets());
2670             if (mName.startsWith(STARTING_WINDOW_PREFIX)) {
2671                 mWindowType = WINDOW_TYPE_STARTING;
2672                 // Existing code depends on the prefix being removed
2673                 mName = mName.substring(STARTING_WINDOW_PREFIX.length());
2674             } else if (proto.getAnimatingExit()) {
2675                 mWindowType = WINDOW_TYPE_EXITING;
2676             } else if (mName.startsWith(DEBUGGER_WINDOW_PREFIX)) {
2677                 mWindowType = WINDOW_TYPE_DEBUGGER;
2678                 mName = mName.substring(DEBUGGER_WINDOW_PREFIX.length());
2679             } else {
2680                 mWindowType = 0;
2681             }
2682             collectDescendantsOfType(WindowState.class, this, mSubWindows);
2683             mHasCompatScale = proto.getHasCompatScale();
2684             mGlobalScale = proto.getGlobalScale();
2685             mRequestedWidth = proto.getRequestedWidth();
2686             mRequestedHeight = proto.getRequestedHeight();
2687             mKeepClearRects = new ArrayList();
2688             for (int i = 0; i < proto.getKeepClearAreasCount(); ++i) {
2689                 RectProto r = proto.getKeepClearAreas(i);
2690                 mKeepClearRects.add(new Rect(r.getLeft(), r.getTop(), r.getRight(), r.getBottom()));
2691             }
2692             mUnrestrictedKeepClearRects = new ArrayList();
2693             for (int i = 0; i < proto.getUnrestrictedKeepClearAreasCount(); ++i) {
2694                 RectProto r = proto.getUnrestrictedKeepClearAreas(i);
2695                 mUnrestrictedKeepClearRects.add(
2696                         new Rect(r.getLeft(), r.getTop(), r.getRight(), r.getBottom()));
2697             }
2698             mMergedLocalInsetsSources = new ArrayList();
2699             for (int i = 0; i < proto.getMergedLocalInsetsSourcesCount(); ++i) {
2700                 InsetsSourceProto insets = proto.getMergedLocalInsetsSources(i);
2701                 mMergedLocalInsetsSources.add(new InsetsSource(insets));
2702             }
2703             final RectProto r = proto.getDimBounds();
2704             mDimBounds = new Rect(r.getLeft(), r.getTop(), r.getRight(), r.getBottom());
2705         }
2706 
2707         WindowState(com.android.server.wm.nano.WindowStateProto proto) {
2708             super(proto.windowContainer);
2709             mDisplayId = proto.displayId;
2710             mStackId = proto.stackId;
2711             if (proto.attributes != null) {
2712                 mType = proto.attributes.type;
2713                 mFlags = proto.attributes.flags;
2714             }
2715             com.android.server.wm.nano.WindowStateAnimatorProto animatorProto = proto.animator;
2716             if (animatorProto != null) {
2717                 if (animatorProto.surface != null) {
2718                     com.android.server.wm.nano.WindowSurfaceControllerProto surfaceProto =
2719                             animatorProto.surface;
2720                     mShown = surfaceProto.shown;
2721                     mLayer = surfaceProto.layer;
2722                 }
2723                 mCrop = extract(animatorProto.lastClipRect);
2724             }
2725             mGivenContentInsets = extract(proto.givenContentInsets);
2726             com.android.server.wm.nano.WindowFramesProto windowFramesProto = proto.windowFrames;
2727             if (windowFramesProto != null) {
2728                 mFrame = extract(windowFramesProto.frame);
2729                 mParentFrame = extract(windowFramesProto.parentFrame);
2730                 mCompatFrame = extract(windowFramesProto.compatFrame);
2731             }
2732             mSurfaceInsets = extract(proto.surfaceInsets);
2733             if (mName.startsWith(STARTING_WINDOW_PREFIX)) {
2734                 mWindowType = WINDOW_TYPE_STARTING;
2735                 // Existing code depends on the prefix being removed
2736                 mName = mName.substring(STARTING_WINDOW_PREFIX.length());
2737             } else if (proto.animatingExit) {
2738                 mWindowType = WINDOW_TYPE_EXITING;
2739             } else if (mName.startsWith(DEBUGGER_WINDOW_PREFIX)) {
2740                 mWindowType = WINDOW_TYPE_DEBUGGER;
2741                 mName = mName.substring(DEBUGGER_WINDOW_PREFIX.length());
2742             } else {
2743                 mWindowType = 0;
2744             }
2745             collectDescendantsOfType(WindowState.class, this, mSubWindows);
2746             mHasCompatScale = proto.hasCompatScale;
2747             mGlobalScale = proto.globalScale;
2748             mRequestedWidth = proto.requestedWidth;
2749             mRequestedHeight = proto.requestedHeight;
2750             mKeepClearRects = new ArrayList();
2751             for (android.graphics.nano.RectProto r : proto.keepClearAreas) {
2752                 mKeepClearRects.add(new Rect(r.left, r.top, r.right, r.bottom));
2753             }
2754             mUnrestrictedKeepClearRects = new ArrayList();
2755             for (android.graphics.nano.RectProto r : proto.unrestrictedKeepClearAreas) {
2756                 mUnrestrictedKeepClearRects.add(new Rect(r.left, r.top, r.right, r.bottom));
2757             }
2758             mMergedLocalInsetsSources = new ArrayList();
2759             for (android.view.nano.InsetsSourceProto insets : proto.mergedLocalInsetsSources) {
2760                 mMergedLocalInsetsSources.add(new InsetsSource(insets));
2761             }
2762             mDimBounds = extract(proto.dimBounds);
2763         }
2764 
2765         boolean isStartingWindow() {
2766             return mWindowType == WINDOW_TYPE_STARTING;
2767         }
2768 
2769         boolean isExitingWindow() {
2770             return mWindowType == WINDOW_TYPE_EXITING;
2771         }
2772 
2773         boolean isDebuggerWindow() {
2774             return mWindowType == WINDOW_TYPE_DEBUGGER;
2775         }
2776 
2777         public int getDisplayId() {
2778             return mDisplayId;
2779         }
2780 
2781         public int getStackId() {
2782             return mStackId;
2783         }
2784 
2785         public Rect getFrame() {
2786             return mFrame;
2787         }
2788 
2789         Rect getSurfaceInsets() {
2790             return mSurfaceInsets;
2791         }
2792 
2793         Rect getGivenContentInsets() {
2794             return mGivenContentInsets;
2795         }
2796 
2797         public Rect getParentFrame() {
2798             return mParentFrame;
2799         }
2800 
2801         public Rect getCompatFrame() {
2802             return mCompatFrame;
2803         }
2804 
2805         Rect getCrop() {
2806             return mCrop;
2807         }
2808 
2809         public boolean isSurfaceShown() {
2810             return mShown;
2811         }
2812 
2813         public int getType() {
2814             return mType;
2815         }
2816 
2817         public boolean hasCompatScale() {
2818             return mHasCompatScale;
2819         }
2820 
2821         public float getGlobalScale() {
2822             return mGlobalScale;
2823         }
2824 
2825         public int getRequestedWidth() {
2826             return mRequestedWidth;
2827         }
2828 
2829         public int getRequestedHeight() {
2830             return mRequestedHeight;
2831         }
2832 
2833         public List<Rect> getKeepClearRects() {
2834             return mKeepClearRects;
2835         }
2836 
2837         public List<Rect> getUnrestrictedKeepClearRects() {
2838             return mUnrestrictedKeepClearRects;
2839         }
2840 
2841         public List<InsetsSource> getMergedLocalInsetsSources() {
2842             return mMergedLocalInsetsSources;
2843         }
2844 
2845         public int getFlags() {
2846             return mFlags;
2847         }
2848 
2849         @Nullable
2850         public Rect getDimBounds() {
2851             return mDimBounds;
2852         }
2853 
2854         private String getWindowTypeSuffix(int windowType) {
2855             switch (windowType) {
2856                 case WINDOW_TYPE_STARTING:
2857                     return " STARTING";
2858                 case WINDOW_TYPE_EXITING:
2859                     return " EXITING";
2860                 case WINDOW_TYPE_DEBUGGER:
2861                     return " DEBUGGER";
2862                 default:
2863                     break;
2864             }
2865             return "";
2866         }
2867 
2868         @Override
2869         public String toString() {
2870             return "WindowState: {" + mAppToken + " " + mName
2871                     + getWindowTypeSuffix(mWindowType) + "}" + " type=" + mType
2872                     + " pf=" + mParentFrame;
2873         }
2874 
2875         public String toLongString() {
2876             return toString() + " f=" + mFrame + " crop=" + mCrop + " isSurfaceShown="
2877                     + isSurfaceShown();
2878         }
2879     }
2880 
2881     public static class BackNavigationState {
2882         private boolean mAnimationInProgress;
2883         private int mLastBackType;
2884         private boolean mShowWallpaper;
2885 
2886         BackNavigationState(BackNavigationProto proto) {
2887             if (proto != null) {
2888                 mAnimationInProgress = proto.getAnimationInProgress();
2889                 mLastBackType = proto.getLastBackType();
2890                 mShowWallpaper = proto.getShowWallpaper();
2891             }
2892         }
2893 
2894         BackNavigationState(com.android.server.wm.nano.BackNavigationProto proto) {
2895             if (proto != null) {
2896                 mAnimationInProgress = proto.animationInProgress;
2897                 mLastBackType = proto.lastBackType;
2898                 mShowWallpaper = proto.showWallpaper;
2899             }
2900         }
2901 
2902         boolean isAnimationInProgress() {
2903             return mAnimationInProgress;
2904         }
2905 
2906         public int getLastBackType() {
2907             return mLastBackType;
2908         }
2909 
2910         boolean isShowWallpaper() {
2911             return mShowWallpaper;
2912         }
2913     }
2914 
2915     public static int dpToPx(float dp, int densityDpi) {
2916         return (int) (dp * densityDpi / DENSITY_DEFAULT + 0.5f);
2917     }
2918 
2919     int defaultMinimalTaskSize(int displayId) {
2920         final DisplayContent dc = getDisplay(displayId);
2921         return dpToPx(dc.mMinSizeOfResizeableTaskDp, dc.getDpi());
2922     }
2923 
2924     int defaultMinimalDisplaySizeForSplitScreen(int displayId) {
2925         return dpToPx(ActivityTaskManager.DEFAULT_MINIMAL_SPLIT_SCREEN_DISPLAY_SIZE_DP,
2926                 getDisplay(displayId).getDpi());
2927     }
2928 
2929     public static class InsetsSource {
2930         private int mType;
2931         private Rect mFrame;
2932         private Rect mVisibleFrame;
2933         private boolean mVisible;
2934 
2935         InsetsSource(InsetsSourceProto proto) {
2936             mType = proto.getTypeNumber();
2937             if (proto.hasFrame()) {
2938                 mFrame = new Rect(
2939                         proto.getFrame().getLeft(), proto.getFrame().getTop(),
2940                         proto.getFrame().getRight(), proto.getFrame().getBottom());
2941             }
2942             if (proto.hasVisibleFrame()) {
2943                 mVisibleFrame = new Rect(
2944                         proto.getVisibleFrame().getLeft(), proto.getVisibleFrame().getTop(),
2945                         proto.getVisibleFrame().getRight(), proto.getVisibleFrame().getBottom());
2946             }
2947             mVisible = proto.getVisible();
2948         }
2949 
2950         InsetsSource(android.view.nano.InsetsSourceProto proto) {
2951             mType = proto.typeNumber;
2952             if (proto.frame != null) {
2953                 mFrame = new Rect(
2954                         proto.frame.left, proto.frame.top, proto.frame.right, proto.frame.bottom);
2955             }
2956             if (proto.visibleFrame != null) {
2957                 mVisibleFrame = new Rect(proto.visibleFrame.left, proto.visibleFrame.top,
2958                         proto.visibleFrame.right, proto.visibleFrame.bottom);
2959             }
2960             mVisible = proto.visible;
2961         }
2962 
2963         int getType() {
2964             return mType;
2965         }
2966 
2967         Rect getFrame() {
2968             return mFrame;
2969         }
2970 
2971         Rect getVisibleFrame() {
2972             return mVisibleFrame;
2973         }
2974 
2975         boolean isVisible() {
2976             return mVisible;
2977         }
2978 
2979         /**
2980          * Check whether this InsetsSource is with given type.
2981          * @param type The type to which check against.
2982          * @return {@code true} if this insets source is with the given type.
2983          */
2984         public boolean is(int type) {
2985             return (mType & type) != 0;
2986         }
2987 
2988         public void insetGivenFrame(Rect inOutFrame) {
2989             if (inOutFrame.left == mFrame.left && inOutFrame.right == mFrame.right) {
2990                 if (inOutFrame.top == mFrame.top) {
2991                     inOutFrame.top = mFrame.bottom;
2992                     return;
2993                 }
2994                 if (inOutFrame.bottom == mFrame.bottom) {
2995                     inOutFrame.bottom = mFrame.top;
2996                     return;
2997                 }
2998             }
2999             if (inOutFrame.top == mFrame.top && inOutFrame.bottom == mFrame.bottom) {
3000                 if (inOutFrame.left == mFrame.left) {
3001                     inOutFrame.left = mFrame.right;
3002                     return;
3003                 }
3004                 if (inOutFrame.right == mFrame.right) {
3005                     inOutFrame.right = mFrame.left;
3006                     return;
3007                 }
3008             }
3009         }
3010 
3011         @Override
3012         public String toString() {
3013             return "InsetsSource: {type=" + WindowInsets.Type.toString(mType)
3014                     + " frame=" + mFrame
3015                     + " visibleFrame=" + mVisibleFrame
3016                     + " visible=" + mVisible
3017                     + "}";
3018         }
3019     }
3020 
3021     public static class InsetsSourceProvider {
3022         private InsetsSource mSource;
3023         private WindowState mWindowState;
3024 
3025         InsetsSourceProvider(InsetsSourceProviderProto proto) {
3026             if (proto.hasSource()) {
3027                 mSource = new InsetsSource(proto.getSource());
3028             }
3029             if (proto.hasSourceWindowState()) {
3030                 mWindowState = new WindowState(proto.getSourceWindowState());
3031             }
3032         }
3033 
3034         InsetsSourceProvider(com.android.server.wm.nano.InsetsSourceProviderProto proto) {
3035             if (proto.source != null) {
3036                 mSource = new InsetsSource(proto.source);
3037             }
3038             if (proto.sourceWindowState != null) {
3039                 mWindowState = new WindowState(proto.sourceWindowState);
3040             }
3041         }
3042 
3043         int getType() {
3044             return mSource.getType();
3045         }
3046 
3047         WindowState getWindowState() {
3048             return mWindowState;
3049         }
3050 
3051         @Override
3052         public String toString() {
3053             return "InsetsSourceProvider: mSource=" + mSource + " mWindowState=" + mWindowState;
3054         }
3055 
3056     }
3057 }
3058