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