1 /* 2 * Copyright (C) 2018 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.app; 18 19 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 20 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; 21 22 import android.annotation.IntDef; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.TestApi; 26 import android.compat.annotation.UnsupportedAppUsage; 27 import android.content.ComponentName; 28 import android.content.Intent; 29 import android.content.LocusId; 30 import android.content.pm.ActivityInfo; 31 import android.content.res.Configuration; 32 import android.graphics.Point; 33 import android.graphics.Rect; 34 import android.os.Build; 35 import android.os.IBinder; 36 import android.os.Parcel; 37 import android.view.DisplayCutout; 38 import android.window.WindowContainerToken; 39 40 import java.lang.annotation.Retention; 41 import java.lang.annotation.RetentionPolicy; 42 import java.util.ArrayList; 43 import java.util.Objects; 44 45 /** 46 * Stores information about a particular Task. 47 */ 48 public class TaskInfo { 49 private static final String TAG = "TaskInfo"; 50 51 /** 52 * The value to use when the property has not a specific value. 53 * @hide 54 */ 55 public static final int PROPERTY_VALUE_UNSET = -1; 56 57 /** 58 * The id of the user the task was running as if this is a leaf task. The id of the current 59 * running user of the system otherwise. 60 * @hide 61 */ 62 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 63 public int userId; 64 65 /** 66 * The identifier for this task. 67 */ 68 public int taskId; 69 70 /** 71 * Whether or not this task has any running activities. 72 */ 73 public boolean isRunning; 74 75 /** 76 * The base intent of the task (generally the intent that launched the task). This intent can 77 * be used to relaunch the task (if it is no longer running) or brought to the front if it is. 78 */ 79 @NonNull 80 public Intent baseIntent; 81 82 /** 83 * The component of the first activity in the task, can be considered the "application" of this 84 * task. 85 */ 86 @Nullable 87 public ComponentName baseActivity; 88 89 /** 90 * The component of the top activity in the task, currently showing to the user. 91 */ 92 @Nullable 93 public ComponentName topActivity; 94 95 /** 96 * The component of the target activity if this task was started from an activity alias. 97 * Otherwise, this is null. 98 */ 99 @Nullable 100 public ComponentName origActivity; 101 102 /** 103 * The component of the activity that started this task (may be the component of the activity 104 * alias). 105 * @hide 106 */ 107 @Nullable 108 public ComponentName realActivity; 109 110 /** 111 * The number of activities in this task (including running). 112 */ 113 public int numActivities; 114 115 /** 116 * The last time this task was active since boot (including time spent in sleep). 117 * @hide 118 */ 119 @UnsupportedAppUsage 120 public long lastActiveTime; 121 122 /** 123 * The id of the display this task is associated with. 124 * @hide 125 */ 126 public int displayId; 127 128 /** 129 * The feature id of {@link com.android.server.wm.TaskDisplayArea} this task is associated with. 130 * @hide 131 */ 132 public int displayAreaFeatureId = FEATURE_UNDEFINED; 133 134 /** 135 * The recent activity values for the highest activity in the stack to have set the values. 136 * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}. 137 */ 138 @Nullable 139 public ActivityManager.TaskDescription taskDescription; 140 141 /** 142 * The locusId of the task. 143 * @hide 144 */ 145 @Nullable 146 public LocusId mTopActivityLocusId; 147 148 /** 149 * Whether this task supports multi windowing modes based on the device settings and the 150 * root activity resizability and configuration. 151 * @hide 152 */ 153 public boolean supportsMultiWindow; 154 155 /** 156 * The resize mode of the task. See {@link ActivityInfo#resizeMode}. 157 * @hide 158 */ 159 @UnsupportedAppUsage 160 public int resizeMode; 161 162 /** 163 * The current configuration of the task. 164 * @hide 165 */ 166 @NonNull 167 @UnsupportedAppUsage 168 public final Configuration configuration = new Configuration(); 169 170 /** 171 * Used as an opaque identifier for this task. 172 * @hide 173 */ 174 @NonNull 175 public WindowContainerToken token; 176 177 /** 178 * The PictureInPictureParams for the Task, if set. 179 * @hide 180 */ 181 @Nullable 182 public PictureInPictureParams pictureInPictureParams; 183 184 /** 185 * @hide 186 */ 187 public boolean shouldDockBigOverlays; 188 189 /** 190 * The task id of the host Task of the launch-into-pip Activity, i.e., it points to the Task 191 * the launch-into-pip Activity is originated from. 192 * @hide 193 */ 194 public int launchIntoPipHostTaskId; 195 196 /** 197 * The task id of the parent Task of the launch-into-pip Activity, i.e., if task have more than 198 * one activity it will create new task for this activity, this id is the origin task id and 199 * the pip activity will be reparent to origin task when it exit pip mode. 200 * @hide 201 */ 202 public int lastParentTaskIdBeforePip; 203 204 /** 205 * The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of 206 * (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS), 207 * {@code null} otherwise. 208 * @hide 209 */ 210 @Nullable 211 public Rect displayCutoutInsets; 212 213 /** 214 * The activity type of the top activity in this task. 215 * @hide 216 */ 217 public @WindowConfiguration.ActivityType int topActivityType; 218 219 /** 220 * The {@link ActivityInfo} of the top activity in this task. 221 * @hide 222 */ 223 @Nullable 224 public ActivityInfo topActivityInfo; 225 226 /** 227 * Whether the direct top activity is in size compat mode on foreground. 228 * @hide 229 */ 230 public boolean topActivityInSizeCompat; 231 232 /** 233 * Whether the direct top activity is eligible for letterbox education. 234 * @hide 235 */ 236 public boolean topActivityEligibleForLetterboxEducation; 237 238 /** 239 * Whether the double tap is enabled 240 * @hide 241 */ 242 public boolean isLetterboxDoubleTapEnabled; 243 244 /** 245 * Whether the update comes from a letterbox double-tap action from the user or not. 246 * @hide 247 */ 248 public boolean isFromLetterboxDoubleTap; 249 250 /** 251 * If {@link isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position or 252 * {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise. 253 * @hide 254 */ 255 public int topActivityLetterboxVerticalPosition; 256 257 /** 258 * If {@link isLetterboxDoubleTapEnabled} it contains the current letterbox vertical position or 259 * {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise. 260 * @hide 261 */ 262 public int topActivityLetterboxHorizontalPosition; 263 264 /** 265 * If {@link isLetterboxDoubleTapEnabled} it contains the current width of the letterboxed 266 * activity or {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise 267 * @hide 268 */ 269 public int topActivityLetterboxWidth; 270 271 /** 272 * If {@link isLetterboxDoubleTapEnabled} it contains the current height of the letterboxed 273 * activity or {@link TaskInfo.PROPERTY_VALUE_UNSET} otherwise 274 * @hide 275 */ 276 public int topActivityLetterboxHeight; 277 278 /** 279 * Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity 280 * supports), this is what the system actually uses for resizability based on other policy and 281 * developer options. 282 * @hide 283 */ 284 public boolean isResizeable; 285 286 /** 287 * Minimal width of the task when it's resizeable. 288 * @hide 289 */ 290 public int minWidth; 291 292 /** 293 * Minimal height of the task when it's resizeable. 294 * @hide 295 */ 296 public int minHeight; 297 298 /** 299 * The default minimal size of the task used when a minWidth or minHeight is not specified. 300 * @hide 301 */ 302 public int defaultMinSize; 303 304 /** 305 * Relative position of the task's top left corner in the parent container. 306 * @hide 307 */ 308 public Point positionInParent; 309 310 /** 311 * The launch cookies associated with activities in this task if any. 312 * @see ActivityOptions#setLaunchCookie(IBinder) 313 * @hide 314 */ 315 public ArrayList<IBinder> launchCookies = new ArrayList<>(); 316 317 /** 318 * The identifier of the parent task that is created by organizer, otherwise 319 * {@link ActivityTaskManager#INVALID_TASK_ID}. 320 * @hide 321 */ 322 public int parentTaskId; 323 324 /** 325 * Whether this task is focused. 326 * @hide 327 */ 328 public boolean isFocused; 329 330 /** 331 * Whether this task is visible. 332 * @hide 333 */ 334 public boolean isVisible; 335 336 /** 337 * Whether this task is sleeping due to sleeping display. 338 * @hide 339 */ 340 public boolean isSleeping; 341 342 /** 343 * Camera compat control isn't shown because it's not requested by heuristics. 344 * @hide 345 */ 346 public static final int CAMERA_COMPAT_CONTROL_HIDDEN = 0; 347 348 /** 349 * Camera compat control is shown with the treatment suggested. 350 * @hide 351 */ 352 public static final int CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED = 1; 353 354 /** 355 * Camera compat control is shown to allow reverting the applied treatment. 356 * @hide 357 */ 358 public static final int CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED = 2; 359 360 /** 361 * Camera compat control is dismissed by user. 362 * @hide 363 */ 364 public static final int CAMERA_COMPAT_CONTROL_DISMISSED = 3; 365 366 /** 367 * Enum for the Camera app compat control states. 368 * @hide 369 */ 370 @Retention(RetentionPolicy.SOURCE) 371 @IntDef(prefix = { "CAMERA_COMPAT_CONTROL_" }, value = { 372 CAMERA_COMPAT_CONTROL_HIDDEN, 373 CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED, 374 CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED, 375 CAMERA_COMPAT_CONTROL_DISMISSED, 376 }) 377 public @interface CameraCompatControlState {}; 378 379 /** 380 * State of the Camera app compat control which is used to correct stretched viewfinder 381 * in apps that don't handle all possible configurations and changes between them correctly. 382 * @hide 383 */ 384 @CameraCompatControlState 385 public int cameraCompatControlState = CAMERA_COMPAT_CONTROL_HIDDEN; 386 TaskInfo()387 TaskInfo() { 388 // Do nothing 389 } 390 TaskInfo(Parcel source)391 private TaskInfo(Parcel source) { 392 readFromParcel(source); 393 } 394 395 /** 396 * Whether this task is visible. 397 */ isVisible()398 public boolean isVisible() { 399 return isVisible; 400 } 401 402 /** @hide */ 403 @NonNull 404 @TestApi getToken()405 public WindowContainerToken getToken() { 406 return token; 407 } 408 409 /** @hide */ 410 @NonNull 411 @TestApi getConfiguration()412 public Configuration getConfiguration() { 413 return configuration; 414 } 415 416 /** @hide */ 417 @Nullable 418 @TestApi getPictureInPictureParams()419 public PictureInPictureParams getPictureInPictureParams() { 420 return pictureInPictureParams; 421 } 422 423 /** @hide */ 424 @TestApi shouldDockBigOverlays()425 public boolean shouldDockBigOverlays() { 426 return shouldDockBigOverlays; 427 } 428 429 /** @hide */ 430 @WindowConfiguration.WindowingMode getWindowingMode()431 public int getWindowingMode() { 432 return configuration.windowConfiguration.getWindowingMode(); 433 } 434 435 /** @hide */ 436 @WindowConfiguration.ActivityType getActivityType()437 public int getActivityType() { 438 return configuration.windowConfiguration.getActivityType(); 439 } 440 441 /** @hide */ addLaunchCookie(IBinder cookie)442 public void addLaunchCookie(IBinder cookie) { 443 if (cookie == null || launchCookies.contains(cookie)) return; 444 launchCookies.add(cookie); 445 } 446 447 /** @hide */ hasCameraCompatControl()448 public boolean hasCameraCompatControl() { 449 return cameraCompatControlState != CAMERA_COMPAT_CONTROL_HIDDEN 450 && cameraCompatControlState != CAMERA_COMPAT_CONTROL_DISMISSED; 451 } 452 453 /** @hide */ hasCompatUI()454 public boolean hasCompatUI() { 455 return hasCameraCompatControl() || topActivityInSizeCompat 456 || topActivityEligibleForLetterboxEducation 457 || isLetterboxDoubleTapEnabled; 458 } 459 460 /** 461 * @return {@code true} if this task contains the launch cookie. 462 * @hide 463 */ 464 @TestApi containsLaunchCookie(@onNull IBinder cookie)465 public boolean containsLaunchCookie(@NonNull IBinder cookie) { 466 return launchCookies.contains(cookie); 467 } 468 469 /** 470 * @return The parent task id of this task. 471 * @hide 472 */ 473 @TestApi getParentTaskId()474 public int getParentTaskId() { 475 return parentTaskId; 476 } 477 478 /** @hide */ 479 @TestApi hasParentTask()480 public boolean hasParentTask() { 481 return parentTaskId != INVALID_TASK_ID; 482 } 483 484 /** 485 * Returns {@code true} if the parameters that are important for task organizers are equal 486 * between this {@link TaskInfo} and {@param that}. 487 * @hide 488 */ equalsForTaskOrganizer(@ullable TaskInfo that)489 public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) { 490 if (that == null) { 491 return false; 492 } 493 return topActivityType == that.topActivityType 494 && isResizeable == that.isResizeable 495 && supportsMultiWindow == that.supportsMultiWindow 496 && displayAreaFeatureId == that.displayAreaFeatureId 497 && isFromLetterboxDoubleTap == that.isFromLetterboxDoubleTap 498 && topActivityLetterboxVerticalPosition == that.topActivityLetterboxVerticalPosition 499 && topActivityLetterboxWidth == that.topActivityLetterboxWidth 500 && topActivityLetterboxHeight == that.topActivityLetterboxHeight 501 && topActivityLetterboxHorizontalPosition 502 == that.topActivityLetterboxHorizontalPosition 503 && Objects.equals(positionInParent, that.positionInParent) 504 && Objects.equals(pictureInPictureParams, that.pictureInPictureParams) 505 && Objects.equals(shouldDockBigOverlays, that.shouldDockBigOverlays) 506 && Objects.equals(displayCutoutInsets, that.displayCutoutInsets) 507 && getWindowingMode() == that.getWindowingMode() 508 && configuration.uiMode == that.configuration.uiMode 509 && Objects.equals(taskDescription, that.taskDescription) 510 && isFocused == that.isFocused 511 && isVisible == that.isVisible 512 && isSleeping == that.isSleeping 513 && Objects.equals(mTopActivityLocusId, that.mTopActivityLocusId) 514 && parentTaskId == that.parentTaskId 515 && Objects.equals(topActivity, that.topActivity); 516 } 517 518 /** 519 * @return {@code true} if parameters that are important for size compat have changed. 520 * @hide 521 */ equalsForCompatUi(@ullable TaskInfo that)522 public boolean equalsForCompatUi(@Nullable TaskInfo that) { 523 if (that == null) { 524 return false; 525 } 526 return displayId == that.displayId 527 && taskId == that.taskId 528 && topActivityInSizeCompat == that.topActivityInSizeCompat 529 && isFromLetterboxDoubleTap == that.isFromLetterboxDoubleTap 530 && topActivityEligibleForLetterboxEducation 531 == that.topActivityEligibleForLetterboxEducation 532 && topActivityLetterboxVerticalPosition == that.topActivityLetterboxVerticalPosition 533 && topActivityLetterboxHorizontalPosition 534 == that.topActivityLetterboxHorizontalPosition 535 && topActivityLetterboxWidth == that.topActivityLetterboxWidth 536 && topActivityLetterboxHeight == that.topActivityLetterboxHeight 537 && cameraCompatControlState == that.cameraCompatControlState 538 // Bounds are important if top activity has compat controls. 539 && (!hasCompatUI() || configuration.windowConfiguration.getBounds() 540 .equals(that.configuration.windowConfiguration.getBounds())) 541 && (!hasCompatUI() || configuration.getLayoutDirection() 542 == that.configuration.getLayoutDirection()) 543 && (!hasCompatUI() || configuration.uiMode == that.configuration.uiMode) 544 && (!hasCompatUI() || isVisible == that.isVisible); 545 } 546 547 /** 548 * Reads the TaskInfo from a parcel. 549 */ readFromParcel(Parcel source)550 void readFromParcel(Parcel source) { 551 userId = source.readInt(); 552 taskId = source.readInt(); 553 displayId = source.readInt(); 554 isRunning = source.readBoolean(); 555 baseIntent = source.readTypedObject(Intent.CREATOR); 556 baseActivity = ComponentName.readFromParcel(source); 557 topActivity = ComponentName.readFromParcel(source); 558 origActivity = ComponentName.readFromParcel(source); 559 realActivity = ComponentName.readFromParcel(source); 560 561 numActivities = source.readInt(); 562 lastActiveTime = source.readLong(); 563 564 taskDescription = source.readTypedObject(ActivityManager.TaskDescription.CREATOR); 565 supportsMultiWindow = source.readBoolean(); 566 resizeMode = source.readInt(); 567 configuration.readFromParcel(source); 568 token = WindowContainerToken.CREATOR.createFromParcel(source); 569 topActivityType = source.readInt(); 570 pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR); 571 shouldDockBigOverlays = source.readBoolean(); 572 launchIntoPipHostTaskId = source.readInt(); 573 lastParentTaskIdBeforePip = source.readInt(); 574 displayCutoutInsets = source.readTypedObject(Rect.CREATOR); 575 topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR); 576 isResizeable = source.readBoolean(); 577 minWidth = source.readInt(); 578 minHeight = source.readInt(); 579 defaultMinSize = source.readInt(); 580 source.readBinderList(launchCookies); 581 positionInParent = source.readTypedObject(Point.CREATOR); 582 parentTaskId = source.readInt(); 583 isFocused = source.readBoolean(); 584 isVisible = source.readBoolean(); 585 isSleeping = source.readBoolean(); 586 topActivityInSizeCompat = source.readBoolean(); 587 topActivityEligibleForLetterboxEducation = source.readBoolean(); 588 mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR); 589 displayAreaFeatureId = source.readInt(); 590 cameraCompatControlState = source.readInt(); 591 isLetterboxDoubleTapEnabled = source.readBoolean(); 592 isFromLetterboxDoubleTap = source.readBoolean(); 593 topActivityLetterboxVerticalPosition = source.readInt(); 594 topActivityLetterboxHorizontalPosition = source.readInt(); 595 topActivityLetterboxWidth = source.readInt(); 596 topActivityLetterboxHeight = source.readInt(); 597 } 598 599 /** 600 * Writes the TaskInfo to a parcel. 601 */ writeToParcel(Parcel dest, int flags)602 void writeToParcel(Parcel dest, int flags) { 603 dest.writeInt(userId); 604 dest.writeInt(taskId); 605 dest.writeInt(displayId); 606 dest.writeBoolean(isRunning); 607 dest.writeTypedObject(baseIntent, 0); 608 609 ComponentName.writeToParcel(baseActivity, dest); 610 ComponentName.writeToParcel(topActivity, dest); 611 ComponentName.writeToParcel(origActivity, dest); 612 ComponentName.writeToParcel(realActivity, dest); 613 614 dest.writeInt(numActivities); 615 dest.writeLong(lastActiveTime); 616 617 dest.writeTypedObject(taskDescription, flags); 618 dest.writeBoolean(supportsMultiWindow); 619 dest.writeInt(resizeMode); 620 configuration.writeToParcel(dest, flags); 621 token.writeToParcel(dest, flags); 622 dest.writeInt(topActivityType); 623 dest.writeTypedObject(pictureInPictureParams, flags); 624 dest.writeBoolean(shouldDockBigOverlays); 625 dest.writeInt(launchIntoPipHostTaskId); 626 dest.writeInt(lastParentTaskIdBeforePip); 627 dest.writeTypedObject(displayCutoutInsets, flags); 628 dest.writeTypedObject(topActivityInfo, flags); 629 dest.writeBoolean(isResizeable); 630 dest.writeInt(minWidth); 631 dest.writeInt(minHeight); 632 dest.writeInt(defaultMinSize); 633 dest.writeBinderList(launchCookies); 634 dest.writeTypedObject(positionInParent, flags); 635 dest.writeInt(parentTaskId); 636 dest.writeBoolean(isFocused); 637 dest.writeBoolean(isVisible); 638 dest.writeBoolean(isSleeping); 639 dest.writeBoolean(topActivityInSizeCompat); 640 dest.writeBoolean(topActivityEligibleForLetterboxEducation); 641 dest.writeTypedObject(mTopActivityLocusId, flags); 642 dest.writeInt(displayAreaFeatureId); 643 dest.writeInt(cameraCompatControlState); 644 dest.writeBoolean(isLetterboxDoubleTapEnabled); 645 dest.writeBoolean(isFromLetterboxDoubleTap); 646 dest.writeInt(topActivityLetterboxVerticalPosition); 647 dest.writeInt(topActivityLetterboxHorizontalPosition); 648 dest.writeInt(topActivityLetterboxWidth); 649 dest.writeInt(topActivityLetterboxHeight); 650 } 651 652 @Override toString()653 public String toString() { 654 return "TaskInfo{userId=" + userId + " taskId=" + taskId 655 + " displayId=" + displayId 656 + " isRunning=" + isRunning 657 + " baseIntent=" + baseIntent + " baseActivity=" + baseActivity 658 + " topActivity=" + topActivity + " origActivity=" + origActivity 659 + " realActivity=" + realActivity 660 + " numActivities=" + numActivities 661 + " lastActiveTime=" + lastActiveTime 662 + " supportsMultiWindow=" + supportsMultiWindow 663 + " resizeMode=" + resizeMode 664 + " isResizeable=" + isResizeable 665 + " minWidth=" + minWidth 666 + " minHeight=" + minHeight 667 + " defaultMinSize=" + defaultMinSize 668 + " token=" + token 669 + " topActivityType=" + topActivityType 670 + " pictureInPictureParams=" + pictureInPictureParams 671 + " shouldDockBigOverlays=" + shouldDockBigOverlays 672 + " launchIntoPipHostTaskId=" + launchIntoPipHostTaskId 673 + " lastParentTaskIdBeforePip=" + lastParentTaskIdBeforePip 674 + " displayCutoutSafeInsets=" + displayCutoutInsets 675 + " topActivityInfo=" + topActivityInfo 676 + " launchCookies=" + launchCookies 677 + " positionInParent=" + positionInParent 678 + " parentTaskId=" + parentTaskId 679 + " isFocused=" + isFocused 680 + " isVisible=" + isVisible 681 + " isSleeping=" + isSleeping 682 + " topActivityInSizeCompat=" + topActivityInSizeCompat 683 + " topActivityEligibleForLetterboxEducation= " 684 + topActivityEligibleForLetterboxEducation 685 + " topActivityLetterboxed= " + isLetterboxDoubleTapEnabled 686 + " isFromDoubleTap= " + isFromLetterboxDoubleTap 687 + " topActivityLetterboxVerticalPosition= " + topActivityLetterboxVerticalPosition 688 + " topActivityLetterboxHorizontalPosition= " 689 + topActivityLetterboxHorizontalPosition 690 + " topActivityLetterboxWidth=" + topActivityLetterboxWidth 691 + " topActivityLetterboxHeight=" + topActivityLetterboxHeight 692 + " locusId=" + mTopActivityLocusId 693 + " displayAreaFeatureId=" + displayAreaFeatureId 694 + " cameraCompatControlState=" 695 + cameraCompatControlStateToString(cameraCompatControlState) 696 + "}"; 697 } 698 699 /** @hide */ cameraCompatControlStateToString( @ameraCompatControlState int cameraCompatControlState)700 public static String cameraCompatControlStateToString( 701 @CameraCompatControlState int cameraCompatControlState) { 702 switch (cameraCompatControlState) { 703 case CAMERA_COMPAT_CONTROL_HIDDEN: return "hidden"; 704 case CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED: return "treatment-suggested"; 705 case CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED: return "treatment-applied"; 706 case CAMERA_COMPAT_CONTROL_DISMISSED: return "dismissed"; 707 default: 708 throw new AssertionError( 709 "Unexpected camera compat control state: " + cameraCompatControlState); 710 } 711 } 712 } 713