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