1 /* 2 * Copyright (C) 2023 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.window; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.content.Intent; 23 import android.os.Bundle; 24 import android.os.IBinder; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.view.SurfaceControl; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.Objects; 32 33 /** 34 * Data object of params for TaskFragment related {@link WindowContainerTransaction} operation. 35 * 36 * @see WindowContainerTransaction#addTaskFragmentOperation(IBinder, TaskFragmentOperation). 37 * @hide 38 */ 39 public final class TaskFragmentOperation implements Parcelable { 40 41 /** 42 * Type for tracking other unknown TaskFragment operation that is not set through 43 * {@link TaskFragmentOperation}, such as invalid request. 44 */ 45 public static final int OP_TYPE_UNKNOWN = -1; 46 47 /** Creates a new TaskFragment. */ 48 public static final int OP_TYPE_CREATE_TASK_FRAGMENT = 0; 49 50 /** Deletes the given TaskFragment. */ 51 public static final int OP_TYPE_DELETE_TASK_FRAGMENT = 1; 52 53 /** Starts an Activity in the given TaskFragment. */ 54 public static final int OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT = 2; 55 56 /** Reparents the given Activity to the given TaskFragment. */ 57 public static final int OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT = 3; 58 59 /** Sets two TaskFragments adjacent to each other. */ 60 public static final int OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 4; 61 62 /** Clears the adjacent TaskFragments relationship. */ 63 public static final int OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS = 5; 64 65 /** Requests focus on the top running Activity in the given TaskFragment. */ 66 public static final int OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 6; 67 68 /** Sets a given TaskFragment to have a companion TaskFragment. */ 69 public static final int OP_TYPE_SET_COMPANION_TASK_FRAGMENT = 7; 70 71 /** Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. */ 72 public static final int OP_TYPE_SET_ANIMATION_PARAMS = 8; 73 74 /** Sets the relative bounds with {@link WindowContainerTransaction#setRelativeBounds}. */ 75 public static final int OP_TYPE_SET_RELATIVE_BOUNDS = 9; 76 77 /** 78 * Reorders the TaskFragment to be the front-most TaskFragment in the Task. 79 * Note that there could still have other WindowContainer on top of the front-most 80 * TaskFragment, such as a non-embedded Activity. 81 */ 82 public static final int OP_TYPE_REORDER_TO_FRONT = 10; 83 84 /** 85 * Sets the activity navigation to be isolated, where the activity navigation on the 86 * TaskFragment is separated from the rest activities in the Task. Activities cannot be 87 * started on an isolated TaskFragment unless explicitly requested to. That said, new launched 88 * activities should be positioned as a sibling to the TaskFragment with higher z-ordering. 89 */ 90 public static final int OP_TYPE_SET_ISOLATED_NAVIGATION = 11; 91 92 /** 93 * Creates a decor surface in the parent Task of the TaskFragment. The created decor surface 94 * will be provided in {@link TaskFragmentTransaction#TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED} 95 * event callback. If a decor surface already exists in the parent Task, the current 96 * TaskFragment will become the new owner of the decor surface and the decor surface will be 97 * moved above the TaskFragment. 98 * 99 * The decor surface can be used to draw the divider between TaskFragments or other decorations. 100 */ 101 public static final int OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE = 12; 102 103 /** 104 * Removes the decor surface in the parent Task of the TaskFragment. 105 */ 106 public static final int OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE = 13; 107 108 /** 109 * Applies dimming on the parent Task which could cross two TaskFragments. 110 */ 111 public static final int OP_TYPE_SET_DIM_ON_TASK = 14; 112 113 /** 114 * Sets whether the decor surface will be boosted. When not boosted, the decor surface is placed 115 * below any TaskFragments in untrusted mode or any activities with uid different from the 116 * TaskFragmentOrganizer uid and just above its owner TaskFragment; when boosted, the decor 117 * surface is placed above all the non-boosted windows in the Task, the content of these 118 * non-boosted windows will be hidden and inputs are disabled. 119 */ 120 public static final int OP_TYPE_SET_DECOR_SURFACE_BOOSTED = 15; 121 122 /** 123 * Sets the TaskFragment to be pinned. 124 * <p> 125 * If a TaskFragment is pinned, the TaskFragment should be the top-most TaskFragment among other 126 * sibling TaskFragments. Any newly launched and embeddable activity should not be placed in the 127 * pinned TaskFragment, unless the activity is launched from the pinned TaskFragment or 128 * explicitly requested to. Non-embeddable activities are not restricted to. 129 * <p> 130 * See {@link #OP_TYPE_REORDER_TO_FRONT} on how to reorder a pinned TaskFragment to the top. 131 */ 132 public static final int OP_TYPE_SET_PINNED = 16; 133 134 /** 135 * The start index of the privileged operations. Only system organizers are allowed to use 136 * operations with index greater than or equal to this value. 137 */ 138 public static final int PRIVILEGED_OP_START = 1000; 139 140 /** 141 * Reorders the TaskFragment to be the bottom-most in the Task. Note that this op will bring the 142 * TaskFragment to the bottom of the Task below all the other Activities and TaskFragments. 143 * 144 * This is only allowed for system organizers. See 145 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 146 * ITaskFragmentOrganizer, boolean)} 147 */ 148 public static final int OP_TYPE_PRIVILEGED_REORDER_TO_BOTTOM_OF_TASK = PRIVILEGED_OP_START + 1; 149 150 /** 151 * Reorders the TaskFragment to be the top-most in the Task. Note that this op will bring the 152 * TaskFragment to the top of the Task above all the other Activities and TaskFragments. 153 * 154 * This is only allowed for system organizers. See 155 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 156 * ITaskFragmentOrganizer, boolean)} 157 */ 158 public static final int OP_TYPE_PRIVILEGED_REORDER_TO_TOP_OF_TASK = PRIVILEGED_OP_START + 2; 159 160 /** 161 * Sets this TaskFragment to move to bottom of the Task if any of the activities below it is 162 * launched in a mode requiring clear top. 163 * 164 * This is only allowed for system organizers. See 165 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 166 * ITaskFragmentOrganizer, boolean)} 167 */ 168 public static final int OP_TYPE_PRIVILEGED_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH = 169 PRIVILEGED_OP_START + 3; 170 171 /** 172 * Sets whether this TaskFragment can affect system UI flags such as the status bar. Default 173 * is {@code true}. 174 * 175 * This operation is only allowed for system organizers. See 176 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 177 * ITaskFragmentOrganizer, boolean)} 178 */ 179 public static final int OP_TYPE_PRIVILEGED_SET_CAN_AFFECT_SYSTEM_UI_FLAGS = 180 PRIVILEGED_OP_START + 4; 181 182 @IntDef(prefix = { "OP_TYPE_" }, value = { 183 OP_TYPE_UNKNOWN, 184 OP_TYPE_CREATE_TASK_FRAGMENT, 185 OP_TYPE_DELETE_TASK_FRAGMENT, 186 OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT, 187 OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT, 188 OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS, 189 OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS, 190 OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT, 191 OP_TYPE_SET_COMPANION_TASK_FRAGMENT, 192 OP_TYPE_SET_ANIMATION_PARAMS, 193 OP_TYPE_SET_RELATIVE_BOUNDS, 194 OP_TYPE_REORDER_TO_FRONT, 195 OP_TYPE_SET_ISOLATED_NAVIGATION, 196 OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE, 197 OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE, 198 OP_TYPE_SET_DIM_ON_TASK, 199 OP_TYPE_SET_DECOR_SURFACE_BOOSTED, 200 OP_TYPE_SET_PINNED, 201 OP_TYPE_PRIVILEGED_REORDER_TO_BOTTOM_OF_TASK, 202 OP_TYPE_PRIVILEGED_REORDER_TO_TOP_OF_TASK, 203 OP_TYPE_PRIVILEGED_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH, 204 OP_TYPE_PRIVILEGED_SET_CAN_AFFECT_SYSTEM_UI_FLAGS, 205 }) 206 @Retention(RetentionPolicy.SOURCE) 207 public @interface OperationType {} 208 209 @OperationType 210 private final int mOpType; 211 212 @Nullable 213 private final TaskFragmentCreationParams mTaskFragmentCreationParams; 214 215 @Nullable 216 private final IBinder mActivityToken; 217 218 @Nullable 219 private final Intent mActivityIntent; 220 221 @Nullable 222 private final Bundle mBundle; 223 224 @Nullable 225 private final IBinder mSecondaryFragmentToken; 226 227 @Nullable 228 private final TaskFragmentAnimationParams mAnimationParams; 229 230 private final boolean mBooleanValue; 231 232 @Nullable 233 private final SurfaceControl.Transaction mSurfaceTransaction; 234 TaskFragmentOperation(@perationType int opType, @Nullable TaskFragmentCreationParams taskFragmentCreationParams, @Nullable IBinder activityToken, @Nullable Intent activityIntent, @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, @Nullable TaskFragmentAnimationParams animationParams, boolean booleanValue, @Nullable SurfaceControl.Transaction surfaceTransaction)235 private TaskFragmentOperation(@OperationType int opType, 236 @Nullable TaskFragmentCreationParams taskFragmentCreationParams, 237 @Nullable IBinder activityToken, @Nullable Intent activityIntent, 238 @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, 239 @Nullable TaskFragmentAnimationParams animationParams, 240 boolean booleanValue, @Nullable SurfaceControl.Transaction surfaceTransaction) { 241 mOpType = opType; 242 mTaskFragmentCreationParams = taskFragmentCreationParams; 243 mActivityToken = activityToken; 244 mActivityIntent = activityIntent; 245 mBundle = bundle; 246 mSecondaryFragmentToken = secondaryFragmentToken; 247 mAnimationParams = animationParams; 248 mBooleanValue = booleanValue; 249 mSurfaceTransaction = surfaceTransaction; 250 } 251 TaskFragmentOperation(Parcel in)252 private TaskFragmentOperation(Parcel in) { 253 mOpType = in.readInt(); 254 mTaskFragmentCreationParams = in.readTypedObject(TaskFragmentCreationParams.CREATOR); 255 mActivityToken = in.readStrongBinder(); 256 mActivityIntent = in.readTypedObject(Intent.CREATOR); 257 mBundle = in.readBundle(getClass().getClassLoader()); 258 mSecondaryFragmentToken = in.readStrongBinder(); 259 mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR); 260 mBooleanValue = in.readBoolean(); 261 mSurfaceTransaction = in.readTypedObject(SurfaceControl.Transaction.CREATOR); 262 } 263 264 @Override writeToParcel(@onNull Parcel dest, int flags)265 public void writeToParcel(@NonNull Parcel dest, int flags) { 266 dest.writeInt(mOpType); 267 dest.writeTypedObject(mTaskFragmentCreationParams, flags); 268 dest.writeStrongBinder(mActivityToken); 269 dest.writeTypedObject(mActivityIntent, flags); 270 dest.writeBundle(mBundle); 271 dest.writeStrongBinder(mSecondaryFragmentToken); 272 dest.writeTypedObject(mAnimationParams, flags); 273 dest.writeBoolean(mBooleanValue); 274 dest.writeTypedObject(mSurfaceTransaction, flags); 275 } 276 277 @NonNull 278 public static final Creator<TaskFragmentOperation> CREATOR = 279 new Creator<TaskFragmentOperation>() { 280 @Override 281 public TaskFragmentOperation createFromParcel(Parcel in) { 282 return new TaskFragmentOperation(in); 283 } 284 285 @Override 286 public TaskFragmentOperation[] newArray(int size) { 287 return new TaskFragmentOperation[size]; 288 } 289 }; 290 291 /** 292 * Gets the {@link OperationType} of this {@link TaskFragmentOperation}. 293 */ 294 @OperationType getOpType()295 public int getOpType() { 296 return mOpType; 297 } 298 299 /** 300 * Gets the options to create a new TaskFragment. 301 */ 302 @Nullable getTaskFragmentCreationParams()303 public TaskFragmentCreationParams getTaskFragmentCreationParams() { 304 return mTaskFragmentCreationParams; 305 } 306 307 /** 308 * Gets the Activity token set in this operation. 309 */ 310 @Nullable getActivityToken()311 public IBinder getActivityToken() { 312 return mActivityToken; 313 } 314 315 /** 316 * Gets the Intent to start a new Activity. 317 */ 318 @Nullable getActivityIntent()319 public Intent getActivityIntent() { 320 return mActivityIntent; 321 } 322 323 /** 324 * Gets the Bundle set in this operation. 325 */ 326 @Nullable getBundle()327 public Bundle getBundle() { 328 return mBundle; 329 } 330 331 /** 332 * Gets the fragment token of the secondary TaskFragment set in this operation. 333 */ 334 @Nullable getSecondaryFragmentToken()335 public IBinder getSecondaryFragmentToken() { 336 return mSecondaryFragmentToken; 337 } 338 339 /** 340 * Gets the animation related override of TaskFragment. 341 */ 342 @Nullable getAnimationParams()343 public TaskFragmentAnimationParams getAnimationParams() { 344 return mAnimationParams; 345 } 346 347 /** Returns the boolean value for this operation. */ getBooleanValue()348 public boolean getBooleanValue() { 349 return mBooleanValue; 350 } 351 352 /** 353 * Returns {@link SurfaceControl.Transaction} associated with this operation. Currently, this is 354 * only used by {@link TaskFragmentOperation#OP_TYPE_SET_DECOR_SURFACE_BOOSTED} to specify a 355 * {@link SurfaceControl.Transaction} that should be applied together with the transaction to 356 * change the decor surface layers. 357 */ 358 @Nullable getSurfaceTransaction()359 public SurfaceControl.Transaction getSurfaceTransaction() { 360 return mSurfaceTransaction; 361 } 362 363 @Override toString()364 public String toString() { 365 final StringBuilder sb = new StringBuilder(); 366 sb.append("TaskFragmentOperation{ opType=").append(mOpType); 367 if (mTaskFragmentCreationParams != null) { 368 sb.append(", taskFragmentCreationParams=").append(mTaskFragmentCreationParams); 369 } 370 if (mActivityToken != null) { 371 sb.append(", activityToken=").append(mActivityToken); 372 } 373 if (mActivityIntent != null) { 374 sb.append(", activityIntent=").append(mActivityIntent); 375 } 376 if (mBundle != null) { 377 sb.append(", bundle=").append(mBundle); 378 } 379 if (mSecondaryFragmentToken != null) { 380 sb.append(", secondaryFragmentToken=").append(mSecondaryFragmentToken); 381 } 382 if (mAnimationParams != null) { 383 sb.append(", animationParams=").append(mAnimationParams); 384 } 385 sb.append(", booleanValue=").append(mBooleanValue); 386 if (mSurfaceTransaction != null) { 387 sb.append(", surfaceTransaction=").append(mSurfaceTransaction); 388 } 389 390 sb.append('}'); 391 return sb.toString(); 392 } 393 394 @Override hashCode()395 public int hashCode() { 396 return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, 397 mBundle, mSecondaryFragmentToken, mAnimationParams, mBooleanValue, 398 mSurfaceTransaction); 399 } 400 401 @Override equals(@ullable Object obj)402 public boolean equals(@Nullable Object obj) { 403 if (!(obj instanceof TaskFragmentOperation)) { 404 return false; 405 } 406 final TaskFragmentOperation other = (TaskFragmentOperation) obj; 407 return mOpType == other.mOpType 408 && Objects.equals(mTaskFragmentCreationParams, other.mTaskFragmentCreationParams) 409 && Objects.equals(mActivityToken, other.mActivityToken) 410 && Objects.equals(mActivityIntent, other.mActivityIntent) 411 && Objects.equals(mBundle, other.mBundle) 412 && Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken) 413 && Objects.equals(mAnimationParams, other.mAnimationParams) 414 && mBooleanValue == other.mBooleanValue 415 && Objects.equals(mSurfaceTransaction, other.mSurfaceTransaction); 416 } 417 418 @Override describeContents()419 public int describeContents() { 420 return 0; 421 } 422 423 /** Builder to construct the {@link TaskFragmentOperation}. */ 424 public static final class Builder { 425 426 @OperationType 427 private final int mOpType; 428 429 @Nullable 430 private TaskFragmentCreationParams mTaskFragmentCreationParams; 431 432 @Nullable 433 private IBinder mActivityToken; 434 435 @Nullable 436 private Intent mActivityIntent; 437 438 @Nullable 439 private Bundle mBundle; 440 441 @Nullable 442 private IBinder mSecondaryFragmentToken; 443 444 @Nullable 445 private TaskFragmentAnimationParams mAnimationParams; 446 447 private boolean mBooleanValue; 448 449 @Nullable 450 private SurfaceControl.Transaction mSurfaceTransaction; 451 452 /** 453 * @param opType the {@link OperationType} of this {@link TaskFragmentOperation}. 454 */ Builder(@perationType int opType)455 public Builder(@OperationType int opType) { 456 mOpType = opType; 457 } 458 459 /** 460 * Sets the {@link TaskFragmentCreationParams} for creating a new TaskFragment. 461 */ 462 @NonNull setTaskFragmentCreationParams( @ullable TaskFragmentCreationParams taskFragmentCreationParams)463 public Builder setTaskFragmentCreationParams( 464 @Nullable TaskFragmentCreationParams taskFragmentCreationParams) { 465 mTaskFragmentCreationParams = taskFragmentCreationParams; 466 return this; 467 } 468 469 /** 470 * Sets an Activity token to this operation. 471 */ 472 @NonNull setActivityToken(@ullable IBinder activityToken)473 public Builder setActivityToken(@Nullable IBinder activityToken) { 474 mActivityToken = activityToken; 475 return this; 476 } 477 478 /** 479 * Sets the Intent to start a new Activity. 480 */ 481 @NonNull setActivityIntent(@ullable Intent activityIntent)482 public Builder setActivityIntent(@Nullable Intent activityIntent) { 483 mActivityIntent = activityIntent; 484 return this; 485 } 486 487 /** 488 * Sets a Bundle to this operation. 489 */ 490 @NonNull setBundle(@ullable Bundle bundle)491 public Builder setBundle(@Nullable Bundle bundle) { 492 mBundle = bundle; 493 return this; 494 } 495 496 /** 497 * Sets the secondary fragment token to this operation. 498 */ 499 @NonNull setSecondaryFragmentToken(@ullable IBinder secondaryFragmentToken)500 public Builder setSecondaryFragmentToken(@Nullable IBinder secondaryFragmentToken) { 501 mSecondaryFragmentToken = secondaryFragmentToken; 502 return this; 503 } 504 505 /** 506 * Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. 507 */ 508 @NonNull setAnimationParams(@ullable TaskFragmentAnimationParams animationParams)509 public Builder setAnimationParams(@Nullable TaskFragmentAnimationParams animationParams) { 510 mAnimationParams = animationParams; 511 return this; 512 } 513 514 /** 515 * Sets the boolean value for this operation. 516 */ 517 @NonNull setBooleanValue(boolean booleanValue)518 public Builder setBooleanValue(boolean booleanValue) { 519 mBooleanValue = booleanValue; 520 return this; 521 } 522 523 /** 524 * Sets {@link SurfaceControl.Transaction} associated with this operation. Currently, this 525 * is only used by {@link TaskFragmentOperation#OP_TYPE_SET_DECOR_SURFACE_BOOSTED} to 526 * specify a {@link SurfaceControl.Transaction} that should be applied together with the 527 * transaction to change the decor surface layers. 528 */ 529 @NonNull setSurfaceTransaction( @ullable SurfaceControl.Transaction surfaceTransaction)530 public Builder setSurfaceTransaction( 531 @Nullable SurfaceControl.Transaction surfaceTransaction) { 532 mSurfaceTransaction = surfaceTransaction; 533 return this; 534 } 535 536 /** 537 * Constructs the {@link TaskFragmentOperation}. 538 */ 539 @NonNull build()540 public TaskFragmentOperation build() { 541 return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken, 542 mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams, 543 mBooleanValue, mSurfaceTransaction); 544 } 545 } 546 } 547