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.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.app.WindowConfiguration; 23 import android.hardware.HardwareBuffer; 24 import android.os.Bundle; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.os.RemoteCallback; 28 import android.view.RemoteAnimationTarget; 29 import android.view.SurfaceControl; 30 31 /** 32 * Information to be sent to SysUI about a back event. 33 * 34 * @hide 35 */ 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 */ 79 @IntDef(prefix = "TYPE_", value = { 80 TYPE_UNDEFINED, 81 TYPE_DIALOG_CLOSE, 82 TYPE_RETURN_TO_HOME, 83 TYPE_CROSS_ACTIVITY, 84 TYPE_CROSS_TASK, 85 TYPE_CALLBACK 86 }) 87 @interface BackTargetType { 88 } 89 90 private final int mType; 91 @Nullable 92 private final RemoteAnimationTarget mDepartingAnimationTarget; 93 @Nullable 94 private final SurfaceControl mScreenshotSurface; 95 @Nullable 96 private final HardwareBuffer mScreenshotBuffer; 97 @Nullable 98 private final RemoteCallback mOnBackNavigationDone; 99 @Nullable 100 private final WindowConfiguration mTaskWindowConfiguration; 101 @Nullable 102 private final IOnBackInvokedCallback mOnBackInvokedCallback; 103 104 private final boolean mIsPrepareRemoteAnimation; 105 106 /** 107 * Create a new {@link BackNavigationInfo} instance. 108 * 109 * @param type The {@link BackTargetType} of the destination (what will be 110 * displayed after the back action). 111 * @param departingAnimationTarget The remote animation target, containing a leash to animate 112 * away the departing window. The consumer of the leash is 113 * responsible for removing it. 114 * @param screenshotSurface The screenshot of the previous activity to be displayed. 115 * @param screenshotBuffer A buffer containing a screenshot used to display the activity. 116 * See {@link #getScreenshotHardwareBuffer()} for information 117 * about nullity. 118 * @param taskWindowConfiguration The window configuration of the Task being animated beneath. 119 * @param onBackNavigationDone The callback to be called once the client is done with the 120 * back preview. 121 * @param onBackInvokedCallback The back callback registered by the current top level window. 122 * @param isPrepareRemoteAnimation Return whether the core is preparing a back gesture 123 * animation, if true, the caller of startBackNavigation should 124 * be expected to receive an animation start callback. 125 */ BackNavigationInfo(@ackTargetType int type, @Nullable RemoteAnimationTarget departingAnimationTarget, @Nullable SurfaceControl screenshotSurface, @Nullable HardwareBuffer screenshotBuffer, @Nullable WindowConfiguration taskWindowConfiguration, @Nullable RemoteCallback onBackNavigationDone, @Nullable IOnBackInvokedCallback onBackInvokedCallback, boolean isPrepareRemoteAnimation)126 private BackNavigationInfo(@BackTargetType int type, 127 @Nullable RemoteAnimationTarget departingAnimationTarget, 128 @Nullable SurfaceControl screenshotSurface, 129 @Nullable HardwareBuffer screenshotBuffer, 130 @Nullable WindowConfiguration taskWindowConfiguration, 131 @Nullable RemoteCallback onBackNavigationDone, 132 @Nullable IOnBackInvokedCallback onBackInvokedCallback, 133 boolean isPrepareRemoteAnimation) { 134 mType = type; 135 mDepartingAnimationTarget = departingAnimationTarget; 136 mScreenshotSurface = screenshotSurface; 137 mScreenshotBuffer = screenshotBuffer; 138 mTaskWindowConfiguration = taskWindowConfiguration; 139 mOnBackNavigationDone = onBackNavigationDone; 140 mOnBackInvokedCallback = onBackInvokedCallback; 141 mIsPrepareRemoteAnimation = isPrepareRemoteAnimation; 142 } 143 BackNavigationInfo(@onNull Parcel in)144 private BackNavigationInfo(@NonNull Parcel in) { 145 mType = in.readInt(); 146 mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR); 147 mScreenshotSurface = in.readTypedObject(SurfaceControl.CREATOR); 148 mScreenshotBuffer = in.readTypedObject(HardwareBuffer.CREATOR); 149 mTaskWindowConfiguration = in.readTypedObject(WindowConfiguration.CREATOR); 150 mOnBackNavigationDone = in.readTypedObject(RemoteCallback.CREATOR); 151 mOnBackInvokedCallback = IOnBackInvokedCallback.Stub.asInterface(in.readStrongBinder()); 152 mIsPrepareRemoteAnimation = in.readBoolean(); 153 } 154 155 @Override writeToParcel(@onNull Parcel dest, int flags)156 public void writeToParcel(@NonNull Parcel dest, int flags) { 157 dest.writeInt(mType); 158 dest.writeTypedObject(mDepartingAnimationTarget, flags); 159 dest.writeTypedObject(mScreenshotSurface, flags); 160 dest.writeTypedObject(mScreenshotBuffer, flags); 161 dest.writeTypedObject(mTaskWindowConfiguration, flags); 162 dest.writeTypedObject(mOnBackNavigationDone, flags); 163 dest.writeStrongInterface(mOnBackInvokedCallback); 164 dest.writeBoolean(mIsPrepareRemoteAnimation); 165 } 166 167 /** 168 * Returns the type of back navigation that is about to happen. 169 * 170 * @see BackTargetType 171 */ getType()172 public @BackTargetType int getType() { 173 return mType; 174 } 175 176 /** 177 * Returns a {@link RemoteAnimationTarget}, containing a leash to the top window container 178 * that needs to be animated. This can be null if the back animation is controlled by 179 * the application. 180 */ 181 @Nullable getDepartingAnimationTarget()182 public RemoteAnimationTarget getDepartingAnimationTarget() { 183 return mDepartingAnimationTarget; 184 } 185 186 /** 187 * Returns the {@link SurfaceControl} that should be used to display a screenshot of the 188 * previous activity. 189 */ 190 @Nullable getScreenshotSurface()191 public SurfaceControl getScreenshotSurface() { 192 return mScreenshotSurface; 193 } 194 195 /** 196 * Returns the {@link HardwareBuffer} containing the screenshot the activity about to be 197 * shown. This can be null if one of the following conditions is met: 198 * <ul> 199 * <li>The screenshot is not available 200 * <li> The previous activity is the home screen ( {@link #TYPE_RETURN_TO_HOME} 201 * <li> The current window is a dialog ({@link #TYPE_DIALOG_CLOSE} 202 * <li> The back animation is controlled by the application 203 * </ul> 204 */ 205 @Nullable getScreenshotHardwareBuffer()206 public HardwareBuffer getScreenshotHardwareBuffer() { 207 return mScreenshotBuffer; 208 } 209 210 /** 211 * Returns the {@link WindowConfiguration} of the current task. This is null when the top 212 * application is controlling the back animation. 213 */ 214 @Nullable getTaskWindowConfiguration()215 public WindowConfiguration getTaskWindowConfiguration() { 216 return mTaskWindowConfiguration; 217 } 218 219 /** 220 * Returns the {@link OnBackInvokedCallback} of the top level window or null if 221 * the client didn't register a callback. 222 * <p> 223 * This is never null when {@link #getType} returns {@link #TYPE_CALLBACK}. 224 * 225 * @see OnBackInvokedCallback 226 * @see OnBackInvokedDispatcher 227 */ 228 @Nullable getOnBackInvokedCallback()229 public IOnBackInvokedCallback getOnBackInvokedCallback() { 230 return mOnBackInvokedCallback; 231 } 232 isPrepareRemoteAnimation()233 public boolean isPrepareRemoteAnimation() { 234 return mIsPrepareRemoteAnimation; 235 } 236 237 /** 238 * Callback to be called when the back preview is finished in order to notify the server that 239 * it can clean up the resources created for the animation. 240 * 241 * @param triggerBack Boolean indicating if back navigation has been triggered. 242 */ onBackNavigationFinished(boolean triggerBack)243 public void onBackNavigationFinished(boolean triggerBack) { 244 if (mOnBackNavigationDone != null) { 245 Bundle result = new Bundle(); 246 result.putBoolean(KEY_TRIGGER_BACK, triggerBack); 247 mOnBackNavigationDone.sendResult(result); 248 } 249 } 250 251 @Override describeContents()252 public int describeContents() { 253 return 0; 254 } 255 256 public static final Creator<BackNavigationInfo> CREATOR = new Creator<BackNavigationInfo>() { 257 @Override 258 public BackNavigationInfo createFromParcel(Parcel in) { 259 return new BackNavigationInfo(in); 260 } 261 262 @Override 263 public BackNavigationInfo[] newArray(int size) { 264 return new BackNavigationInfo[size]; 265 } 266 }; 267 268 @Override toString()269 public String toString() { 270 return "BackNavigationInfo{" 271 + "mType=" + typeToString(mType) + " (" + mType + ")" 272 + ", mDepartingAnimationTarget=" + mDepartingAnimationTarget 273 + ", mScreenshotSurface=" + mScreenshotSurface 274 + ", mTaskWindowConfiguration= " + mTaskWindowConfiguration 275 + ", mScreenshotBuffer=" + mScreenshotBuffer 276 + ", mOnBackNavigationDone=" + mOnBackNavigationDone 277 + ", mOnBackInvokedCallback=" + mOnBackInvokedCallback 278 + '}'; 279 } 280 281 /** 282 * Translates the {@link BackNavigationInfo} integer type to its String representation 283 */ typeToString(@ackTargetType int type)284 public static String typeToString(@BackTargetType int type) { 285 switch (type) { 286 case TYPE_UNDEFINED: 287 return "TYPE_UNDEFINED"; 288 case TYPE_DIALOG_CLOSE: 289 return "TYPE_DIALOG_CLOSE"; 290 case TYPE_RETURN_TO_HOME: 291 return "TYPE_RETURN_TO_HOME"; 292 case TYPE_CROSS_ACTIVITY: 293 return "TYPE_CROSS_ACTIVITY"; 294 case TYPE_CROSS_TASK: 295 return "TYPE_CROSS_TASK"; 296 case TYPE_CALLBACK: 297 return "TYPE_CALLBACK"; 298 } 299 return String.valueOf(type); 300 } 301 302 /** 303 * @hide 304 */ 305 @SuppressWarnings("UnusedReturnValue") // Builder pattern 306 public static class Builder { 307 308 private int mType = TYPE_UNDEFINED; 309 @Nullable 310 private RemoteAnimationTarget mDepartingAnimationTarget = null; 311 @Nullable 312 private SurfaceControl mScreenshotSurface = null; 313 @Nullable 314 private HardwareBuffer mScreenshotBuffer = null; 315 @Nullable 316 private WindowConfiguration mTaskWindowConfiguration = null; 317 @Nullable 318 private RemoteCallback mOnBackNavigationDone = null; 319 @Nullable 320 private IOnBackInvokedCallback mOnBackInvokedCallback = null; 321 322 private boolean mPrepareAnimation; 323 324 /** 325 * @see BackNavigationInfo#getType() 326 */ setType(@ackTargetType int type)327 public Builder setType(@BackTargetType int type) { 328 mType = type; 329 return this; 330 } 331 332 /** 333 * @see BackNavigationInfo#getDepartingAnimationTarget 334 */ setDepartingAnimationTarget( @ullable RemoteAnimationTarget departingAnimationTarget)335 public Builder setDepartingAnimationTarget( 336 @Nullable RemoteAnimationTarget departingAnimationTarget) { 337 mDepartingAnimationTarget = departingAnimationTarget; 338 return this; 339 } 340 341 /** 342 * @see BackNavigationInfo#getScreenshotSurface 343 */ setScreenshotSurface(@ullable SurfaceControl screenshotSurface)344 public Builder setScreenshotSurface(@Nullable SurfaceControl screenshotSurface) { 345 mScreenshotSurface = screenshotSurface; 346 return this; 347 } 348 349 /** 350 * @see BackNavigationInfo#getScreenshotHardwareBuffer() 351 */ setScreenshotBuffer(@ullable HardwareBuffer screenshotBuffer)352 public Builder setScreenshotBuffer(@Nullable HardwareBuffer screenshotBuffer) { 353 mScreenshotBuffer = screenshotBuffer; 354 return this; 355 } 356 357 /** 358 * @see BackNavigationInfo#getTaskWindowConfiguration 359 */ setTaskWindowConfiguration( @ullable WindowConfiguration taskWindowConfiguration)360 public Builder setTaskWindowConfiguration( 361 @Nullable WindowConfiguration taskWindowConfiguration) { 362 mTaskWindowConfiguration = taskWindowConfiguration; 363 return this; 364 } 365 366 /** 367 * @see BackNavigationInfo#onBackNavigationFinished(boolean) 368 */ setOnBackNavigationDone(@ullable RemoteCallback onBackNavigationDone)369 public Builder setOnBackNavigationDone(@Nullable RemoteCallback onBackNavigationDone) { 370 mOnBackNavigationDone = onBackNavigationDone; 371 return this; 372 } 373 374 /** 375 * @see BackNavigationInfo#getOnBackInvokedCallback 376 */ setOnBackInvokedCallback( @ullable IOnBackInvokedCallback onBackInvokedCallback)377 public Builder setOnBackInvokedCallback( 378 @Nullable IOnBackInvokedCallback onBackInvokedCallback) { 379 mOnBackInvokedCallback = onBackInvokedCallback; 380 return this; 381 } 382 383 /** 384 * @param prepareAnimation Whether core prepare animation for shell. 385 */ setPrepareAnimation(boolean prepareAnimation)386 public Builder setPrepareAnimation(boolean prepareAnimation) { 387 mPrepareAnimation = prepareAnimation; 388 return this; 389 } 390 391 /** 392 * Builds and returns an instance of {@link BackNavigationInfo} 393 */ build()394 public BackNavigationInfo build() { 395 return new BackNavigationInfo(mType, mDepartingAnimationTarget, mScreenshotSurface, 396 mScreenshotBuffer, mTaskWindowConfiguration, mOnBackNavigationDone, 397 mOnBackInvokedCallback, mPrepareAnimation); 398 } 399 } 400 } 401