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 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Objects; 31 32 /** 33 * Data object of params for TaskFragment related {@link WindowContainerTransaction} operation. 34 * 35 * @see WindowContainerTransaction#addTaskFragmentOperation(IBinder, TaskFragmentOperation). 36 * @hide 37 */ 38 public final class TaskFragmentOperation implements Parcelable { 39 40 /** 41 * Type for tracking other unknown TaskFragment operation that is not set through 42 * {@link TaskFragmentOperation}, such as invalid request. 43 */ 44 public static final int OP_TYPE_UNKNOWN = -1; 45 46 /** Creates a new TaskFragment. */ 47 public static final int OP_TYPE_CREATE_TASK_FRAGMENT = 0; 48 49 /** Deletes the given TaskFragment. */ 50 public static final int OP_TYPE_DELETE_TASK_FRAGMENT = 1; 51 52 /** Starts an Activity in the given TaskFragment. */ 53 public static final int OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT = 2; 54 55 /** Reparents the given Activity to the given TaskFragment. */ 56 public static final int OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT = 3; 57 58 /** Sets two TaskFragments adjacent to each other. */ 59 public static final int OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 4; 60 61 /** Clears the adjacent TaskFragments relationship. */ 62 public static final int OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS = 5; 63 64 /** Requests focus on the top running Activity in the given TaskFragment. */ 65 public static final int OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT = 6; 66 67 /** Sets a given TaskFragment to have a companion TaskFragment. */ 68 public static final int OP_TYPE_SET_COMPANION_TASK_FRAGMENT = 7; 69 70 /** Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. */ 71 public static final int OP_TYPE_SET_ANIMATION_PARAMS = 8; 72 73 /** Sets the relative bounds with {@link WindowContainerTransaction#setRelativeBounds}. */ 74 public static final int OP_TYPE_SET_RELATIVE_BOUNDS = 9; 75 76 /** 77 * Reorders the TaskFragment to be the front-most TaskFragment in the Task. 78 * Note that there could still have other WindowContainer on top of the front-most 79 * TaskFragment, such as a non-embedded Activity. 80 */ 81 public static final int OP_TYPE_REORDER_TO_FRONT = 10; 82 83 /** 84 * Sets the activity navigation to be isolated, where the activity navigation on the 85 * TaskFragment is separated from the rest activities in the Task. Activities cannot be 86 * started on an isolated TaskFragment unless the activities are launched from the same 87 * TaskFragment or explicitly requested to. 88 */ 89 public static final int OP_TYPE_SET_ISOLATED_NAVIGATION = 11; 90 91 @IntDef(prefix = { "OP_TYPE_" }, value = { 92 OP_TYPE_UNKNOWN, 93 OP_TYPE_CREATE_TASK_FRAGMENT, 94 OP_TYPE_DELETE_TASK_FRAGMENT, 95 OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT, 96 OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT, 97 OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS, 98 OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS, 99 OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT, 100 OP_TYPE_SET_COMPANION_TASK_FRAGMENT, 101 OP_TYPE_SET_ANIMATION_PARAMS, 102 OP_TYPE_SET_RELATIVE_BOUNDS, 103 OP_TYPE_REORDER_TO_FRONT, 104 OP_TYPE_SET_ISOLATED_NAVIGATION 105 }) 106 @Retention(RetentionPolicy.SOURCE) 107 public @interface OperationType {} 108 109 @OperationType 110 private final int mOpType; 111 112 @Nullable 113 private final TaskFragmentCreationParams mTaskFragmentCreationParams; 114 115 @Nullable 116 private final IBinder mActivityToken; 117 118 @Nullable 119 private final Intent mActivityIntent; 120 121 @Nullable 122 private final Bundle mBundle; 123 124 @Nullable 125 private final IBinder mSecondaryFragmentToken; 126 127 @Nullable 128 private final TaskFragmentAnimationParams mAnimationParams; 129 130 private final boolean mIsolatedNav; 131 TaskFragmentOperation(@perationType int opType, @Nullable TaskFragmentCreationParams taskFragmentCreationParams, @Nullable IBinder activityToken, @Nullable Intent activityIntent, @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, @Nullable TaskFragmentAnimationParams animationParams, boolean isolatedNav)132 private TaskFragmentOperation(@OperationType int opType, 133 @Nullable TaskFragmentCreationParams taskFragmentCreationParams, 134 @Nullable IBinder activityToken, @Nullable Intent activityIntent, 135 @Nullable Bundle bundle, @Nullable IBinder secondaryFragmentToken, 136 @Nullable TaskFragmentAnimationParams animationParams, 137 boolean isolatedNav) { 138 mOpType = opType; 139 mTaskFragmentCreationParams = taskFragmentCreationParams; 140 mActivityToken = activityToken; 141 mActivityIntent = activityIntent; 142 mBundle = bundle; 143 mSecondaryFragmentToken = secondaryFragmentToken; 144 mAnimationParams = animationParams; 145 mIsolatedNav = isolatedNav; 146 } 147 TaskFragmentOperation(Parcel in)148 private TaskFragmentOperation(Parcel in) { 149 mOpType = in.readInt(); 150 mTaskFragmentCreationParams = in.readTypedObject(TaskFragmentCreationParams.CREATOR); 151 mActivityToken = in.readStrongBinder(); 152 mActivityIntent = in.readTypedObject(Intent.CREATOR); 153 mBundle = in.readBundle(getClass().getClassLoader()); 154 mSecondaryFragmentToken = in.readStrongBinder(); 155 mAnimationParams = in.readTypedObject(TaskFragmentAnimationParams.CREATOR); 156 mIsolatedNav = in.readBoolean(); 157 } 158 159 @Override writeToParcel(@onNull Parcel dest, int flags)160 public void writeToParcel(@NonNull Parcel dest, int flags) { 161 dest.writeInt(mOpType); 162 dest.writeTypedObject(mTaskFragmentCreationParams, flags); 163 dest.writeStrongBinder(mActivityToken); 164 dest.writeTypedObject(mActivityIntent, flags); 165 dest.writeBundle(mBundle); 166 dest.writeStrongBinder(mSecondaryFragmentToken); 167 dest.writeTypedObject(mAnimationParams, flags); 168 dest.writeBoolean(mIsolatedNav); 169 } 170 171 @NonNull 172 public static final Creator<TaskFragmentOperation> CREATOR = 173 new Creator<TaskFragmentOperation>() { 174 @Override 175 public TaskFragmentOperation createFromParcel(Parcel in) { 176 return new TaskFragmentOperation(in); 177 } 178 179 @Override 180 public TaskFragmentOperation[] newArray(int size) { 181 return new TaskFragmentOperation[size]; 182 } 183 }; 184 185 /** 186 * Gets the {@link OperationType} of this {@link TaskFragmentOperation}. 187 */ 188 @OperationType getOpType()189 public int getOpType() { 190 return mOpType; 191 } 192 193 /** 194 * Gets the options to create a new TaskFragment. 195 */ 196 @Nullable getTaskFragmentCreationParams()197 public TaskFragmentCreationParams getTaskFragmentCreationParams() { 198 return mTaskFragmentCreationParams; 199 } 200 201 /** 202 * Gets the Activity token set in this operation. 203 */ 204 @Nullable getActivityToken()205 public IBinder getActivityToken() { 206 return mActivityToken; 207 } 208 209 /** 210 * Gets the Intent to start a new Activity. 211 */ 212 @Nullable getActivityIntent()213 public Intent getActivityIntent() { 214 return mActivityIntent; 215 } 216 217 /** 218 * Gets the Bundle set in this operation. 219 */ 220 @Nullable getBundle()221 public Bundle getBundle() { 222 return mBundle; 223 } 224 225 /** 226 * Gets the fragment token of the secondary TaskFragment set in this operation. 227 */ 228 @Nullable getSecondaryFragmentToken()229 public IBinder getSecondaryFragmentToken() { 230 return mSecondaryFragmentToken; 231 } 232 233 /** 234 * Gets the animation related override of TaskFragment. 235 */ 236 @Nullable getAnimationParams()237 public TaskFragmentAnimationParams getAnimationParams() { 238 return mAnimationParams; 239 } 240 241 /** 242 * Returns whether the activity navigation on this TaskFragment is isolated. This is only 243 * useful when the op type is {@link OP_TYPE_SET_ISOLATED_NAVIGATION}. 244 */ isIsolatedNav()245 public boolean isIsolatedNav() { 246 return mIsolatedNav; 247 } 248 249 @Override toString()250 public String toString() { 251 final StringBuilder sb = new StringBuilder(); 252 sb.append("TaskFragmentOperation{ opType=").append(mOpType); 253 if (mTaskFragmentCreationParams != null) { 254 sb.append(", taskFragmentCreationParams=").append(mTaskFragmentCreationParams); 255 } 256 if (mActivityToken != null) { 257 sb.append(", activityToken=").append(mActivityToken); 258 } 259 if (mActivityIntent != null) { 260 sb.append(", activityIntent=").append(mActivityIntent); 261 } 262 if (mBundle != null) { 263 sb.append(", bundle=").append(mBundle); 264 } 265 if (mSecondaryFragmentToken != null) { 266 sb.append(", secondaryFragmentToken=").append(mSecondaryFragmentToken); 267 } 268 if (mAnimationParams != null) { 269 sb.append(", animationParams=").append(mAnimationParams); 270 } 271 sb.append(", isolatedNav=").append(mIsolatedNav); 272 273 sb.append('}'); 274 return sb.toString(); 275 } 276 277 @Override hashCode()278 public int hashCode() { 279 return Objects.hash(mOpType, mTaskFragmentCreationParams, mActivityToken, mActivityIntent, 280 mBundle, mSecondaryFragmentToken, mAnimationParams, mIsolatedNav); 281 } 282 283 @Override equals(@ullable Object obj)284 public boolean equals(@Nullable Object obj) { 285 if (!(obj instanceof TaskFragmentOperation)) { 286 return false; 287 } 288 final TaskFragmentOperation other = (TaskFragmentOperation) obj; 289 return mOpType == other.mOpType 290 && Objects.equals(mTaskFragmentCreationParams, other.mTaskFragmentCreationParams) 291 && Objects.equals(mActivityToken, other.mActivityToken) 292 && Objects.equals(mActivityIntent, other.mActivityIntent) 293 && Objects.equals(mBundle, other.mBundle) 294 && Objects.equals(mSecondaryFragmentToken, other.mSecondaryFragmentToken) 295 && Objects.equals(mAnimationParams, other.mAnimationParams) 296 && mIsolatedNav == other.mIsolatedNav; 297 } 298 299 @Override describeContents()300 public int describeContents() { 301 return 0; 302 } 303 304 /** Builder to construct the {@link TaskFragmentOperation}. */ 305 public static final class Builder { 306 307 @OperationType 308 private final int mOpType; 309 310 @Nullable 311 private TaskFragmentCreationParams mTaskFragmentCreationParams; 312 313 @Nullable 314 private IBinder mActivityToken; 315 316 @Nullable 317 private Intent mActivityIntent; 318 319 @Nullable 320 private Bundle mBundle; 321 322 @Nullable 323 private IBinder mSecondaryFragmentToken; 324 325 @Nullable 326 private TaskFragmentAnimationParams mAnimationParams; 327 328 private boolean mIsolatedNav; 329 330 /** 331 * @param opType the {@link OperationType} of this {@link TaskFragmentOperation}. 332 */ Builder(@perationType int opType)333 public Builder(@OperationType int opType) { 334 mOpType = opType; 335 } 336 337 /** 338 * Sets the {@link TaskFragmentCreationParams} for creating a new TaskFragment. 339 */ 340 @NonNull setTaskFragmentCreationParams( @ullable TaskFragmentCreationParams taskFragmentCreationParams)341 public Builder setTaskFragmentCreationParams( 342 @Nullable TaskFragmentCreationParams taskFragmentCreationParams) { 343 mTaskFragmentCreationParams = taskFragmentCreationParams; 344 return this; 345 } 346 347 /** 348 * Sets an Activity token to this operation. 349 */ 350 @NonNull setActivityToken(@ullable IBinder activityToken)351 public Builder setActivityToken(@Nullable IBinder activityToken) { 352 mActivityToken = activityToken; 353 return this; 354 } 355 356 /** 357 * Sets the Intent to start a new Activity. 358 */ 359 @NonNull setActivityIntent(@ullable Intent activityIntent)360 public Builder setActivityIntent(@Nullable Intent activityIntent) { 361 mActivityIntent = activityIntent; 362 return this; 363 } 364 365 /** 366 * Sets a Bundle to this operation. 367 */ 368 @NonNull setBundle(@ullable Bundle bundle)369 public Builder setBundle(@Nullable Bundle bundle) { 370 mBundle = bundle; 371 return this; 372 } 373 374 /** 375 * Sets the secondary fragment token to this operation. 376 */ 377 @NonNull setSecondaryFragmentToken(@ullable IBinder secondaryFragmentToken)378 public Builder setSecondaryFragmentToken(@Nullable IBinder secondaryFragmentToken) { 379 mSecondaryFragmentToken = secondaryFragmentToken; 380 return this; 381 } 382 383 /** 384 * Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. 385 */ 386 @NonNull setAnimationParams(@ullable TaskFragmentAnimationParams animationParams)387 public Builder setAnimationParams(@Nullable TaskFragmentAnimationParams animationParams) { 388 mAnimationParams = animationParams; 389 return this; 390 } 391 392 /** 393 * Sets the activity navigation of this TaskFragment to be isolated. 394 */ 395 @NonNull setIsolatedNav(boolean isolatedNav)396 public Builder setIsolatedNav(boolean isolatedNav) { 397 mIsolatedNav = isolatedNav; 398 return this; 399 } 400 401 /** 402 * Constructs the {@link TaskFragmentOperation}. 403 */ 404 @NonNull build()405 public TaskFragmentOperation build() { 406 return new TaskFragmentOperation(mOpType, mTaskFragmentCreationParams, mActivityToken, 407 mActivityIntent, mBundle, mSecondaryFragmentToken, mAnimationParams, 408 mIsolatedNav); 409 } 410 } 411 } 412