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