1 /* 2 * Copyright (C) 2021 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.AnimRes; 20 import android.annotation.ColorInt; 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.TestApi; 25 import android.os.Bundle; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 import android.os.RemoteCallback; 29 30 /** 31 * Information to be sent to SysUI about a back event. 32 * 33 * @hide 34 */ 35 @TestApi 36 public final class BackNavigationInfo implements Parcelable { 37 38 /** 39 * The target of the back navigation is undefined. 40 */ 41 public static final int TYPE_UNDEFINED = -1; 42 43 /** 44 * Navigating back will close the currently visible dialog 45 */ 46 public static final int TYPE_DIALOG_CLOSE = 0; 47 48 /** 49 * Navigating back will bring the user back to the home screen 50 */ 51 public static final int TYPE_RETURN_TO_HOME = 1; 52 53 /** 54 * Navigating back will bring the user to the previous activity in the same Task 55 */ 56 public static final int TYPE_CROSS_ACTIVITY = 2; 57 58 /** 59 * Navigating back will bring the user to the previous activity in the previous Task 60 */ 61 public static final int TYPE_CROSS_TASK = 3; 62 63 /** 64 * A {@link OnBackInvokedCallback} is available and needs to be called. 65 * <p> 66 */ 67 public static final int TYPE_CALLBACK = 4; 68 69 /** 70 * Key to access the boolean value passed in {#mOnBackNavigationDone} result bundle 71 * that represents if back navigation has been triggered. 72 */ 73 public static final String KEY_TRIGGER_BACK = "TriggerBack"; 74 75 /** 76 * Defines the type of back destinations a back even can lead to. This is used to define the 77 * type of animation that need to be run on SystemUI. 78 * @hide 79 */ 80 @IntDef(prefix = "TYPE_", value = { 81 TYPE_UNDEFINED, 82 TYPE_DIALOG_CLOSE, 83 TYPE_RETURN_TO_HOME, 84 TYPE_CROSS_ACTIVITY, 85 TYPE_CROSS_TASK, 86 TYPE_CALLBACK 87 }) 88 public @interface BackTargetType { 89 } 90 91 private final int mType; 92 @Nullable 93 private final RemoteCallback mOnBackNavigationDone; 94 @Nullable 95 private final IOnBackInvokedCallback mOnBackInvokedCallback; 96 private final boolean mPrepareRemoteAnimation; 97 private final boolean mAnimationCallback; 98 @Nullable 99 private final CustomAnimationInfo mCustomAnimationInfo; 100 101 /** 102 * Create a new {@link BackNavigationInfo} instance. 103 * 104 * @param type The {@link BackTargetType} of the destination (what will be 105 * @param onBackNavigationDone The callback to be called once the client is done with the 106 * back preview. 107 * @param onBackInvokedCallback The back callback registered by the current top level window. 108 */ BackNavigationInfo(@ackTargetType int type, @Nullable RemoteCallback onBackNavigationDone, @Nullable IOnBackInvokedCallback onBackInvokedCallback, boolean isPrepareRemoteAnimation, boolean isAnimationCallback, @Nullable CustomAnimationInfo customAnimationInfo)109 private BackNavigationInfo(@BackTargetType int type, 110 @Nullable RemoteCallback onBackNavigationDone, 111 @Nullable IOnBackInvokedCallback onBackInvokedCallback, 112 boolean isPrepareRemoteAnimation, 113 boolean isAnimationCallback, 114 @Nullable CustomAnimationInfo customAnimationInfo) { 115 mType = type; 116 mOnBackNavigationDone = onBackNavigationDone; 117 mOnBackInvokedCallback = onBackInvokedCallback; 118 mPrepareRemoteAnimation = isPrepareRemoteAnimation; 119 mAnimationCallback = isAnimationCallback; 120 mCustomAnimationInfo = customAnimationInfo; 121 } 122 BackNavigationInfo(@onNull Parcel in)123 private BackNavigationInfo(@NonNull Parcel in) { 124 mType = in.readInt(); 125 mOnBackNavigationDone = in.readTypedObject(RemoteCallback.CREATOR); 126 mOnBackInvokedCallback = IOnBackInvokedCallback.Stub.asInterface(in.readStrongBinder()); 127 mPrepareRemoteAnimation = in.readBoolean(); 128 mAnimationCallback = in.readBoolean(); 129 mCustomAnimationInfo = in.readTypedObject(CustomAnimationInfo.CREATOR); 130 } 131 132 /** @hide */ 133 @Override writeToParcel(@onNull Parcel dest, int flags)134 public void writeToParcel(@NonNull Parcel dest, int flags) { 135 dest.writeInt(mType); 136 dest.writeTypedObject(mOnBackNavigationDone, flags); 137 dest.writeStrongInterface(mOnBackInvokedCallback); 138 dest.writeBoolean(mPrepareRemoteAnimation); 139 dest.writeBoolean(mAnimationCallback); 140 dest.writeTypedObject(mCustomAnimationInfo, flags); 141 } 142 143 /** 144 * Returns the type of back navigation that is about to happen. 145 * @hide 146 * @see BackTargetType 147 */ getType()148 public @BackTargetType int getType() { 149 return mType; 150 } 151 152 /** 153 * Returns the {@link OnBackInvokedCallback} of the top level window or null if 154 * the client didn't register a callback. 155 * <p> 156 * This is never null when {@link #getType} returns {@link #TYPE_CALLBACK}. 157 * @hide 158 * @see OnBackInvokedCallback 159 * @see OnBackInvokedDispatcher 160 */ 161 @Nullable getOnBackInvokedCallback()162 public IOnBackInvokedCallback getOnBackInvokedCallback() { 163 return mOnBackInvokedCallback; 164 } 165 166 /** 167 * Return true if the core is preparing a back gesture animation. 168 * @hide 169 */ isPrepareRemoteAnimation()170 public boolean isPrepareRemoteAnimation() { 171 return mPrepareRemoteAnimation; 172 } 173 174 /** 175 * Return true if the callback is {@link OnBackAnimationCallback}. 176 * @hide 177 */ isAnimationCallback()178 public boolean isAnimationCallback() { 179 return mAnimationCallback; 180 } 181 182 /** 183 * Callback to be called when the back preview is finished in order to notify the server that 184 * it can clean up the resources created for the animation. 185 * @hide 186 * @param triggerBack Boolean indicating if back navigation has been triggered. 187 */ onBackNavigationFinished(boolean triggerBack)188 public void onBackNavigationFinished(boolean triggerBack) { 189 if (mOnBackNavigationDone != null) { 190 Bundle result = new Bundle(); 191 result.putBoolean(KEY_TRIGGER_BACK, triggerBack); 192 mOnBackNavigationDone.sendResult(result); 193 } 194 } 195 196 /** 197 * Get customize animation info. 198 * @hide 199 */ 200 @Nullable getCustomAnimationInfo()201 public CustomAnimationInfo getCustomAnimationInfo() { 202 return mCustomAnimationInfo; 203 } 204 205 /** @hide */ 206 @Override describeContents()207 public int describeContents() { 208 return 0; 209 } 210 211 @NonNull 212 public static final Creator<BackNavigationInfo> CREATOR = new Creator<BackNavigationInfo>() { 213 @Override 214 public BackNavigationInfo createFromParcel(Parcel in) { 215 return new BackNavigationInfo(in); 216 } 217 218 @Override 219 public BackNavigationInfo[] newArray(int size) { 220 return new BackNavigationInfo[size]; 221 } 222 }; 223 224 @Override toString()225 public String toString() { 226 return "BackNavigationInfo{" 227 + "mType=" + typeToString(mType) + " (" + mType + ")" 228 + ", mOnBackNavigationDone=" + mOnBackNavigationDone 229 + ", mOnBackInvokedCallback=" + mOnBackInvokedCallback 230 + ", mPrepareRemoteAnimation=" + mPrepareRemoteAnimation 231 + ", mAnimationCallback=" + mAnimationCallback 232 + ", mCustomizeAnimationInfo=" + mCustomAnimationInfo 233 + '}'; 234 } 235 236 /** 237 * Translates the {@link BackNavigationInfo} integer type to its String representation 238 */ 239 @NonNull typeToString(@ackTargetType int type)240 public static String typeToString(@BackTargetType int type) { 241 switch (type) { 242 case TYPE_UNDEFINED: 243 return "TYPE_UNDEFINED"; 244 case TYPE_DIALOG_CLOSE: 245 return "TYPE_DIALOG_CLOSE"; 246 case TYPE_RETURN_TO_HOME: 247 return "TYPE_RETURN_TO_HOME"; 248 case TYPE_CROSS_ACTIVITY: 249 return "TYPE_CROSS_ACTIVITY"; 250 case TYPE_CROSS_TASK: 251 return "TYPE_CROSS_TASK"; 252 case TYPE_CALLBACK: 253 return "TYPE_CALLBACK"; 254 } 255 return String.valueOf(type); 256 } 257 258 /** 259 * Information for customize back animation. 260 * @hide 261 */ 262 public static final class CustomAnimationInfo implements Parcelable { 263 private final String mPackageName; 264 private int mWindowAnimations; 265 @AnimRes private int mCustomExitAnim; 266 @AnimRes private int mCustomEnterAnim; 267 @ColorInt private int mCustomBackground; 268 269 /** 270 * The package name of the windowAnimations. 271 */ 272 @NonNull getPackageName()273 public String getPackageName() { 274 return mPackageName; 275 } 276 277 /** 278 * The resource Id of window animations. 279 */ getWindowAnimations()280 public int getWindowAnimations() { 281 return mWindowAnimations; 282 } 283 284 /** 285 * The exit animation resource Id of customize activity transition. 286 */ getCustomExitAnim()287 public int getCustomExitAnim() { 288 return mCustomExitAnim; 289 } 290 291 /** 292 * The entering animation resource Id of customize activity transition. 293 */ getCustomEnterAnim()294 public int getCustomEnterAnim() { 295 return mCustomEnterAnim; 296 } 297 298 /** 299 * The background color of customize activity transition. 300 */ getCustomBackground()301 public int getCustomBackground() { 302 return mCustomBackground; 303 } 304 CustomAnimationInfo(@onNull String packageName)305 public CustomAnimationInfo(@NonNull String packageName) { 306 this.mPackageName = packageName; 307 } 308 309 @Override describeContents()310 public int describeContents() { 311 return 0; 312 } 313 314 @Override writeToParcel(@onNull Parcel dest, int flags)315 public void writeToParcel(@NonNull Parcel dest, int flags) { 316 dest.writeString8(mPackageName); 317 dest.writeInt(mWindowAnimations); 318 dest.writeInt(mCustomEnterAnim); 319 dest.writeInt(mCustomExitAnim); 320 dest.writeInt(mCustomBackground); 321 } 322 CustomAnimationInfo(@onNull Parcel in)323 private CustomAnimationInfo(@NonNull Parcel in) { 324 mPackageName = in.readString8(); 325 mWindowAnimations = in.readInt(); 326 mCustomEnterAnim = in.readInt(); 327 mCustomExitAnim = in.readInt(); 328 mCustomBackground = in.readInt(); 329 } 330 331 @Override toString()332 public String toString() { 333 return "CustomAnimationInfo, package name= " + mPackageName; 334 } 335 336 @NonNull 337 public static final Creator<CustomAnimationInfo> CREATOR = new Creator<>() { 338 @Override 339 public CustomAnimationInfo createFromParcel(Parcel in) { 340 return new CustomAnimationInfo(in); 341 } 342 343 @Override 344 public CustomAnimationInfo[] newArray(int size) { 345 return new CustomAnimationInfo[size]; 346 } 347 }; 348 } 349 /** 350 * @hide 351 */ 352 @SuppressWarnings("UnusedReturnValue") // Builder pattern 353 public static class Builder { 354 private int mType = TYPE_UNDEFINED; 355 @Nullable 356 private RemoteCallback mOnBackNavigationDone = null; 357 @Nullable 358 private IOnBackInvokedCallback mOnBackInvokedCallback = null; 359 private boolean mPrepareRemoteAnimation; 360 private CustomAnimationInfo mCustomAnimationInfo; 361 private boolean mAnimationCallback = false; 362 363 /** 364 * @see BackNavigationInfo#getType() 365 */ setType(@ackTargetType int type)366 public Builder setType(@BackTargetType int type) { 367 mType = type; 368 return this; 369 } 370 371 /** 372 * @see BackNavigationInfo#onBackNavigationFinished(boolean) 373 */ setOnBackNavigationDone(@ullable RemoteCallback onBackNavigationDone)374 public Builder setOnBackNavigationDone(@Nullable RemoteCallback onBackNavigationDone) { 375 mOnBackNavigationDone = onBackNavigationDone; 376 return this; 377 } 378 379 /** 380 * @see BackNavigationInfo#getOnBackInvokedCallback 381 */ setOnBackInvokedCallback( @ullable IOnBackInvokedCallback onBackInvokedCallback)382 public Builder setOnBackInvokedCallback( 383 @Nullable IOnBackInvokedCallback onBackInvokedCallback) { 384 mOnBackInvokedCallback = onBackInvokedCallback; 385 return this; 386 } 387 388 /** 389 * @param prepareRemoteAnimation Whether core prepare animation for shell. 390 */ setPrepareRemoteAnimation(boolean prepareRemoteAnimation)391 public Builder setPrepareRemoteAnimation(boolean prepareRemoteAnimation) { 392 mPrepareRemoteAnimation = prepareRemoteAnimation; 393 return this; 394 } 395 396 /** 397 * Set windowAnimations for customize animation. 398 */ setWindowAnimations(String packageName, int windowAnimations)399 public Builder setWindowAnimations(String packageName, int windowAnimations) { 400 if (mCustomAnimationInfo == null) { 401 mCustomAnimationInfo = new CustomAnimationInfo(packageName); 402 } 403 mCustomAnimationInfo.mWindowAnimations = windowAnimations; 404 return this; 405 } 406 407 /** 408 * Set resources ids for customize activity animation. 409 */ setCustomAnimation(String packageName, @AnimRes int enterResId, @AnimRes int exitResId, @ColorInt int backgroundColor)410 public Builder setCustomAnimation(String packageName, @AnimRes int enterResId, 411 @AnimRes int exitResId, @ColorInt int backgroundColor) { 412 if (mCustomAnimationInfo == null) { 413 mCustomAnimationInfo = new CustomAnimationInfo(packageName); 414 } 415 mCustomAnimationInfo.mCustomExitAnim = exitResId; 416 mCustomAnimationInfo.mCustomEnterAnim = enterResId; 417 mCustomAnimationInfo.mCustomBackground = backgroundColor; 418 return this; 419 } 420 421 /** 422 * @param isAnimationCallback whether the callback is {@link OnBackAnimationCallback} 423 */ setAnimationCallback(boolean isAnimationCallback)424 public Builder setAnimationCallback(boolean isAnimationCallback) { 425 mAnimationCallback = isAnimationCallback; 426 return this; 427 } 428 429 /** 430 * Builds and returns an instance of {@link BackNavigationInfo} 431 */ build()432 public BackNavigationInfo build() { 433 return new BackNavigationInfo(mType, mOnBackNavigationDone, 434 mOnBackInvokedCallback, 435 mPrepareRemoteAnimation, 436 mAnimationCallback, 437 mCustomAnimationInfo); 438 } 439 } 440 } 441