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 * Reorders the TaskFragment to be the bottom-most in the Task. Note that this op will bring the 94 * TaskFragment to the bottom of the Task below all the other Activities and TaskFragments. 95 * 96 * This is only allowed for system organizers. See 97 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 98 * ITaskFragmentOrganizer, boolean)} 99 */ 100 public static final int OP_TYPE_REORDER_TO_BOTTOM_OF_TASK = 12; 101 102 /** 103 * Reorders the TaskFragment to be the top-most in the Task. Note that this op will bring the 104 * TaskFragment to the top of the Task above all the other Activities and TaskFragments. 105 * 106 * This is only allowed for system organizers. See 107 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 108 * ITaskFragmentOrganizer, boolean)} 109 */ 110 public static final int OP_TYPE_REORDER_TO_TOP_OF_TASK = 13; 111 112 /** 113 * Creates a decor surface in the parent Task of the TaskFragment. The created decor surface 114 * will be provided in {@link TaskFragmentTransaction#TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED} 115 * event callback. If a decor surface already exists in the parent Task, the current 116 * TaskFragment will become the new owner of the decor surface and the decor surface will be 117 * moved above the TaskFragment. 118 * 119 * The decor surface can be used to draw the divider between TaskFragments or other decorations. 120 */ 121 public static final int OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE = 14; 122 123 /** 124 * Removes the decor surface in the parent Task of the TaskFragment. 125 */ 126 public static final int OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE = 15; 127 128 /** 129 * Applies dimming on the parent Task which could cross two TaskFragments. 130 */ 131 public static final int OP_TYPE_SET_DIM_ON_TASK = 16; 132 133 /** 134 * Sets this TaskFragment to move to bottom of the Task if any of the activities below it is 135 * launched in a mode requiring clear top. 136 * 137 * This is only allowed for system organizers. See 138 * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( 139 * ITaskFragmentOrganizer, boolean)} 140 */ 141 public static final int OP_TYPE_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH = 17; 142 143 /** 144 * Sets whether the decor surface will be boosted. When not boosted, the decor surface is placed 145 * below any TaskFragments in untrusted mode or any activities with uid different from the 146 * TaskFragmentOrganizer uid and just above its owner TaskFragment; when boosted, the decor 147 * surface is placed above all the non-boosted windows in the Task, the content of these 148 * non-boosted windows will be hidden and inputs are disabled. 149 */ 150 public static final int OP_TYPE_SET_DECOR_SURFACE_BOOSTED = 18; 151 152 /** 153 * Sets the TaskFragment to be pinned. 154 * <p> 155 * If a TaskFragment is pinned, the TaskFragment should be the top-most TaskFragment among other 156 * sibling TaskFragments. Any newly launched and embeddable activity should not be placed in the 157 * pinned TaskFragment, unless the activity is launched from the pinned TaskFragment or 158 * explicitly requested to. Non-embeddable activities are not restricted to. 159 * <p> 160 * See {@link #OP_TYPE_REORDER_TO_FRONT} on how to reorder a pinned TaskFragment to the top. 161 */ 162 public static final int OP_TYPE_SET_PINNED = 19; 163 164 @IntDef(prefix = { "OP_TYPE_" }, value = { 165 OP_TYPE_UNKNOWN, 166 OP_TYPE_CREATE_TASK_FRAGMENT, 167 OP_TYPE_DELETE_TASK_FRAGMENT, 168 OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT, 169 OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT, 170 OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS, 171 OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS, 172 OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT, 173 OP_TYPE_SET_COMPANION_TASK_FRAGMENT, 174 OP_TYPE_SET_ANIMATION_PARAMS, 175 OP_TYPE_SET_RELATIVE_BOUNDS, 176 OP_TYPE_REORDER_TO_FRONT, 177 OP_TYPE_SET_ISOLATED_NAVIGATION, 178 OP_TYPE_REORDER_TO_BOTTOM_OF_TASK, 179 OP_TYPE_REORDER_TO_TOP_OF_TASK, 180 OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE, 181 OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE, 182 OP_TYPE_SET_DIM_ON_TASK, 183 OP_TYPE_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH, 184 OP_TYPE_SET_DECOR_SURFACE_BOOSTED, 185 OP_TYPE_SET_PINNED, 186 }) 187 @Retention(RetentionPolicy.SOURCE) 188 public @interface OperationType {} 189 190 @OperationType 191 private final int mOpType; 192 193 @Nullable 194 private final TaskFragmentCreationParams mTaskFragmentCreationParams; 195 196 @Nullable 197 private final IBinder mActivityToken; 198 199 @Nullable 200 private final Intent mActivityIntent; 201 202 @Nullable 203 private final Bundle mBundle; 204 205 @Nullable 206 private final IBinder mSecondaryFragmentToken; 207 208 @Nullable 209 private final TaskFragmentAnimationParams mAnimationParams; 210 211 private final boolean mBooleanValue; 212 213 @Nullable 214 private final SurfaceControl.Transaction mSurfaceTransaction; 215 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)216 private TaskFragmentOperation(@OperationType int opType, 217 @Nullable TaskFragmentCreationParams taskFragmentCreationParams, 218 @Nullable IBinder activityToken, @Nullable Intent activityIntent, 219 @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, 220 @Nullable TaskFragmentAnimationParams animationParams, 221 boolean booleanValue, @Nullable SurfaceControl.Transaction surfaceTransaction) { 222 mOpType = opType; 223 mTaskFragmentCreationParams = taskFragmentCreationParams; 224 mActivityToken = activityToken; 225 mActivityIntent = activityIntent; 226 mBundle = bundle; 227 mSecondaryFragmentToken = secondaryFragmentToken; 228 mAnimationParams = animationParams; 229 mBooleanValue = booleanValue; 230 mSurfaceTransaction = surfaceTransaction; 231 } 232 TaskFragmentOperation(Parcel in)233 private TaskFragmentOperation(Parcel in) { 234 mOpType = in.readInt(); 235 mTaskFragmentCreationParams = in.readTypedObject(TaskFragmentCreationParams.CREATOR); 236 mActivityToken = in.readStrongBinder(); 237 mActivityIntent = in.readTypedObject(Intent.CREATOR); 238 mBundle = in.readBundle(getClass().getClassLoader()); 239 mSecondaryFragmentToken = in.readStrongBinder(); 240 mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR); 241 mBooleanValue = in.readBoolean(); 242 mSurfaceTransaction = in.readTypedObject(SurfaceControl.Transaction.CREATOR); 243 } 244 245 @Override writeToParcel(@onNull Parcel dest, int flags)246 public void writeToParcel(@NonNull Parcel dest, int flags) { 247 dest.writeInt(mOpType); 248 dest.writeTypedObject(mTaskFragmentCreationParams, flags); 249 dest.writeStrongBinder(mActivityToken); 250 dest.writeTypedObject(mActivityIntent, flags); 251 dest.writeBundle(mBundle); 252 dest.writeStrongBinder(mSecondaryFragmentToken); 253 dest.writeTypedObject(mAnimationParams, flags); 254 dest.writeBoolean(mBooleanValue); 255 dest.writeTypedObject(mSurfaceTransaction, flags); 256 } 257 258 @NonNull 259 public static final Creator<TaskFragmentOperation> CREATOR = 260 new Creator<TaskFragmentOperation>() { 261 @Override 262 public TaskFragmentOperation createFromParcel(Parcel in) { 263 return new TaskFragmentOperation(in); 264 } 265 266 @Override 267 public TaskFragmentOperation[] newArray(int size) { 268 return new TaskFragmentOperation[size]; 269 } 270 }; 271 272 /** 273 * Gets the {@link OperationType} of this {@link TaskFragmentOperation}. 274 */ 275 @OperationType getOpType()276 public int getOpType() { 277 return mOpType; 278 } 279 280 /** 281 * Gets the options to create a new TaskFragment. 282 */ 283 @Nullable getTaskFragmentCreationParams()284 public TaskFragmentCreationParams getTaskFragmentCreationParams() { 285 return mTaskFragmentCreationParams; 286 } 287 288 /** 289 * Gets the Activity token set in this operation. 290 */ 291 @Nullable getActivityToken()292 public IBinder getActivityToken() { 293 return mActivityToken; 294 } 295 296 /** 297 * Gets the Intent to start a new Activity. 298 */ 299 @Nullable getActivityIntent()300 public Intent getActivityIntent() { 301 return mActivityIntent; 302 } 303 304 /** 305 * Gets the Bundle set in this operation. 306 */ 307 @Nullable getBundle()308 public Bundle getBundle() { 309 return mBundle; 310 } 311 312 /** 313 * Gets the fragment token of the secondary TaskFragment set in this operation. 314 */ 315 @Nullable getSecondaryFragmentToken()316 public IBinder getSecondaryFragmentToken() { 317 return mSecondaryFragmentToken; 318 } 319 320 /** 321 * Gets the animation related override of TaskFragment. 322 */ 323 @Nullable getAnimationParams()324 public TaskFragmentAnimationParams getAnimationParams() { 325 return mAnimationParams; 326 } 327 328 /** Returns the boolean value for this operation. */ getBooleanValue()329 public boolean getBooleanValue() { 330 return mBooleanValue; 331 } 332 333 /** 334 * Returns {@link SurfaceControl.Transaction} associated with this operation. Currently, this is 335 * only used by {@link TaskFragmentOperation#OP_TYPE_SET_DECOR_SURFACE_BOOSTED} to specify a 336 * {@link SurfaceControl.Transaction} that should be applied together with the transaction to 337 * change the decor surface layers. 338 */ 339 @Nullable getSurfaceTransaction()340 public SurfaceControl.Transaction getSurfaceTransaction() { 341 return mSurfaceTransaction; 342 } 343 344 @Override toString()345 public String toString() { 346 final StringBuilder sb = new StringBuilder(); 347 sb.append("TaskFragmentOperation{ opType=").append(mOpType); 348 if (mTaskFragmentCreationParams != null) { 349 sb.append(", taskFragmentCreationParams=").append(mTaskFragmentCreationParams); 350 } 351 if (mActivityToken != null) { 352 sb.append(", activityToken=").append(mActivityToken); 353 } 354 if (mActivityIntent != null) { 355 sb.append(", activityIntent=").append(mActivityIntent); 356 } 357 if (mBundle != null) { 358 sb.append(", bundle=").append(mBundle); 359 } 360 if (mSecondaryFragmentToken != null) { 361 sb.append(", secondaryFragmentToken=").append(mSecondaryFragmentToken); 362 } 363 if (mAnimationParams != null) { 364 sb.append(", animationParams=").append(mAnimationParams); 365 } 366 sb.append(", booleanValue=").append(mBooleanValue); 367 if (mSurfaceTransaction != null) { 368 sb.append(", surfaceTransaction=").append(mSurfaceTransaction); 369 } 370 371 sb.append('}'); 372 return sb.toString(); 373 } 374 375 @Override hashCode()376 public int hashCode() { 377 return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, 378 mBundle, mSecondaryFragmentToken, mAnimationParams, mBooleanValue, 379 mSurfaceTransaction); 380 } 381 382 @Override equals(@ullable Object obj)383 public boolean equals(@Nullable Object obj) { 384 if (!(obj instanceof TaskFragmentOperation)) { 385 return false; 386 } 387 final TaskFragmentOperation other = (TaskFragmentOperation) obj; 388 return mOpType == other.mOpType 389 && Objects.equals(mTaskFragmentCreationParams, other.mTaskFragmentCreationParams) 390 && Objects.equals(mActivityToken, other.mActivityToken) 391 && Objects.equals(mActivityIntent, other.mActivityIntent) 392 && Objects.equals(mBundle, other.mBundle) 393 && Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken) 394 && Objects.equals(mAnimationParams, other.mAnimationParams) 395 && mBooleanValue == other.mBooleanValue 396 && Objects.equals(mSurfaceTransaction, other.mSurfaceTransaction); 397 } 398 399 @Override describeContents()400 public int describeContents() { 401 return 0; 402 } 403 404 /** Builder to construct the {@link TaskFragmentOperation}. */ 405 public static final class Builder { 406 407 @OperationType 408 private final int mOpType; 409 410 @Nullable 411 private TaskFragmentCreationParams mTaskFragmentCreationParams; 412 413 @Nullable 414 private IBinder mActivityToken; 415 416 @Nullable 417 private Intent mActivityIntent; 418 419 @Nullable 420 private Bundle mBundle; 421 422 @Nullable 423 private IBinder mSecondaryFragmentToken; 424 425 @Nullable 426 private TaskFragmentAnimationParams mAnimationParams; 427 428 private boolean mBooleanValue; 429 430 @Nullable 431 private SurfaceControl.Transaction mSurfaceTransaction; 432 433 /** 434 * @param opType the {@link OperationType} of this {@link TaskFragmentOperation}. 435 */ Builder(@perationType int opType)436 public Builder(@OperationType int opType) { 437 mOpType = opType; 438 } 439 440 /** 441 * Sets the {@link TaskFragmentCreationParams} for creating a new TaskFragment. 442 */ 443 @NonNull setTaskFragmentCreationParams( @ullable TaskFragmentCreationParams taskFragmentCreationParams)444 public Builder setTaskFragmentCreationParams( 445 @Nullable TaskFragmentCreationParams taskFragmentCreationParams) { 446 mTaskFragmentCreationParams = taskFragmentCreationParams; 447 return this; 448 } 449 450 /** 451 * Sets an Activity token to this operation. 452 */ 453 @NonNull setActivityToken(@ullable IBinder activityToken)454 public Builder setActivityToken(@Nullable IBinder activityToken) { 455 mActivityToken = activityToken; 456 return this; 457 } 458 459 /** 460 * Sets the Intent to start a new Activity. 461 */ 462 @NonNull setActivityIntent(@ullable Intent activityIntent)463 public Builder setActivityIntent(@Nullable Intent activityIntent) { 464 mActivityIntent = activityIntent; 465 return this; 466 } 467 468 /** 469 * Sets a Bundle to this operation. 470 */ 471 @NonNull setBundle(@ullable Bundle bundle)472 public Builder setBundle(@Nullable Bundle bundle) { 473 mBundle = bundle; 474 return this; 475 } 476 477 /** 478 * Sets the secondary fragment token to this operation. 479 */ 480 @NonNull setSecondaryFragmentToken(@ullable IBinder secondaryFragmentToken)481 public Builder setSecondaryFragmentToken(@Nullable IBinder secondaryFragmentToken) { 482 mSecondaryFragmentToken = secondaryFragmentToken; 483 return this; 484 } 485 486 /** 487 * Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. 488 */ 489 @NonNull setAnimationParams(@ullable TaskFragmentAnimationParams animationParams)490 public Builder setAnimationParams(@Nullable TaskFragmentAnimationParams animationParams) { 491 mAnimationParams = animationParams; 492 return this; 493 } 494 495 /** 496 * Sets the boolean value for this operation. 497 */ 498 @NonNull setBooleanValue(boolean booleanValue)499 public Builder setBooleanValue(boolean booleanValue) { 500 mBooleanValue = booleanValue; 501 return this; 502 } 503 504 /** 505 * Sets {@link SurfaceControl.Transaction} associated with this operation. Currently, this 506 * is only used by {@link TaskFragmentOperation#OP_TYPE_SET_DECOR_SURFACE_BOOSTED} to 507 * specify a {@link SurfaceControl.Transaction} that should be applied together with the 508 * transaction to change the decor surface layers. 509 */ 510 @NonNull setSurfaceTransaction( @ullable SurfaceControl.Transaction surfaceTransaction)511 public Builder setSurfaceTransaction( 512 @Nullable SurfaceControl.Transaction surfaceTransaction) { 513 mSurfaceTransaction = surfaceTransaction; 514 return this; 515 } 516 517 /** 518 * Constructs the {@link TaskFragmentOperation}. 519 */ 520 @NonNull build()521 public TaskFragmentOperation build() { 522 return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken, 523 mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams, 524 mBooleanValue, mSurfaceTransaction); 525 } 526 } 527 } 528