1 /* 2 * Copyright (C) 2022 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.view; 18 19 import static android.view.Display.INVALID_DISPLAY; 20 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.os.IBinder; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 28 import com.android.internal.annotations.VisibleForTesting; 29 import com.android.internal.util.DataClass; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 34 /** 35 * Description of a content recording session. 36 * 37 * @hide 38 */ 39 @DataClass( 40 genConstructor = false, 41 genToString = true, 42 genSetters = true, 43 genEqualsHashCode = true 44 ) 45 public final class ContentRecordingSession implements Parcelable { 46 47 /** 48 * An entire DisplayContent is being recorded. Recording may also be paused. 49 */ 50 public static final int RECORD_CONTENT_DISPLAY = 0; 51 /** 52 * A single Task is being recorded. Recording may also be paused. 53 */ 54 public static final int RECORD_CONTENT_TASK = 1; 55 56 /** 57 * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has 58 * recorded content rendered to its surface. 59 */ 60 private int mDisplayId = INVALID_DISPLAY; 61 62 /** 63 * The content to record. 64 */ 65 @RecordContent 66 private int mContentToRecord = RECORD_CONTENT_DISPLAY; 67 68 /** 69 * The token of the layer of the hierarchy to record. 70 * If {@link #getContentToRecord()} is @link RecordContent#RECORD_CONTENT_DISPLAY}, then 71 * represents the WindowToken corresponding to the DisplayContent to record. 72 * If {@link #getContentToRecord()} is {@link RecordContent#RECORD_CONTENT_TASK}, then 73 * represents the {@link android.window.WindowContainerToken} of the Task to record. 74 */ 75 @VisibleForTesting 76 @Nullable 77 private IBinder mTokenToRecord = null; 78 79 /** 80 * Default instance, with recording the display. 81 */ ContentRecordingSession()82 private ContentRecordingSession() { 83 } 84 85 /** 86 * Returns an instance initialized for display recording. 87 */ createDisplaySession( @onNull IBinder displayContentWindowToken)88 public static ContentRecordingSession createDisplaySession( 89 @NonNull IBinder displayContentWindowToken) { 90 return new ContentRecordingSession().setContentToRecord(RECORD_CONTENT_DISPLAY) 91 .setTokenToRecord(displayContentWindowToken); 92 } 93 94 /** 95 * Returns an instance initialized for task recording. 96 */ createTaskSession( @onNull IBinder taskWindowContainerToken)97 public static ContentRecordingSession createTaskSession( 98 @NonNull IBinder taskWindowContainerToken) { 99 return new ContentRecordingSession().setContentToRecord(RECORD_CONTENT_TASK) 100 .setTokenToRecord(taskWindowContainerToken); 101 } 102 103 /** 104 * Returns {@code true} if this is a valid session. 105 */ isValid(ContentRecordingSession session)106 public static boolean isValid(ContentRecordingSession session) { 107 return session != null && (session.getDisplayId() > INVALID_DISPLAY 108 && session.getTokenToRecord() != null); 109 } 110 111 /** 112 * Returns {@code true} when both sessions are for the same display. 113 */ isSameDisplay(ContentRecordingSession session, ContentRecordingSession incomingSession)114 public static boolean isSameDisplay(ContentRecordingSession session, 115 ContentRecordingSession incomingSession) { 116 return session != null && incomingSession != null 117 && session.getDisplayId() == incomingSession.getDisplayId(); 118 } 119 120 121 122 123 // Code below generated by codegen v1.0.23. 124 // 125 // DO NOT MODIFY! 126 // CHECKSTYLE:OFF Generated code 127 // 128 // To regenerate run: 129 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/ContentRecordingSession.java 130 // 131 // To exclude the generated code from IntelliJ auto-formatting enable (one-time): 132 // Settings > Editor > Code Style > Formatter Control 133 //@formatter:off 134 135 136 @IntDef(prefix = "RECORD_CONTENT_", value = { 137 RECORD_CONTENT_DISPLAY, 138 RECORD_CONTENT_TASK 139 }) 140 @Retention(RetentionPolicy.SOURCE) 141 @DataClass.Generated.Member 142 public @interface RecordContent {} 143 144 @DataClass.Generated.Member recordContentToString(@ecordContent int value)145 public static String recordContentToString(@RecordContent int value) { 146 switch (value) { 147 case RECORD_CONTENT_DISPLAY: 148 return "RECORD_CONTENT_DISPLAY"; 149 case RECORD_CONTENT_TASK: 150 return "RECORD_CONTENT_TASK"; 151 default: return Integer.toHexString(value); 152 } 153 } 154 155 @DataClass.Generated.Member ContentRecordingSession( int displayId, @RecordContent int contentToRecord, @VisibleForTesting @Nullable IBinder tokenToRecord)156 /* package-private */ ContentRecordingSession( 157 int displayId, 158 @RecordContent int contentToRecord, 159 @VisibleForTesting @Nullable IBinder tokenToRecord) { 160 this.mDisplayId = displayId; 161 this.mContentToRecord = contentToRecord; 162 163 if (!(mContentToRecord == RECORD_CONTENT_DISPLAY) 164 && !(mContentToRecord == RECORD_CONTENT_TASK)) { 165 throw new java.lang.IllegalArgumentException( 166 "contentToRecord was " + mContentToRecord + " but must be one of: " 167 + "RECORD_CONTENT_DISPLAY(" + RECORD_CONTENT_DISPLAY + "), " 168 + "RECORD_CONTENT_TASK(" + RECORD_CONTENT_TASK + ")"); 169 } 170 171 this.mTokenToRecord = tokenToRecord; 172 com.android.internal.util.AnnotationValidations.validate( 173 VisibleForTesting.class, null, mTokenToRecord); 174 175 // onConstructed(); // You can define this method to get a callback 176 } 177 178 /** 179 * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has 180 * recorded content rendered to its surface. 181 */ 182 @DataClass.Generated.Member getDisplayId()183 public int getDisplayId() { 184 return mDisplayId; 185 } 186 187 /** 188 * The content to record. 189 */ 190 @DataClass.Generated.Member getContentToRecord()191 public @RecordContent int getContentToRecord() { 192 return mContentToRecord; 193 } 194 195 /** 196 * {The token of the layer of the hierarchy to record. 197 * If {@link #getContentToRecord()} is @link RecordContent#RECORD_CONTENT_DISPLAY}, then 198 * represents the WindowToken corresponding to the DisplayContent to record. 199 * If {@link #getContentToRecord()} is {@link RecordContent#RECORD_CONTENT_TASK}, then 200 * represents the {@link android.window.WindowContainerToken} of the Task to record. 201 */ 202 @DataClass.Generated.Member getTokenToRecord()203 public @VisibleForTesting @Nullable IBinder getTokenToRecord() { 204 return mTokenToRecord; 205 } 206 207 /** 208 * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has 209 * recorded content rendered to its surface. 210 */ 211 @DataClass.Generated.Member setDisplayId( int value)212 public @NonNull ContentRecordingSession setDisplayId( int value) { 213 mDisplayId = value; 214 return this; 215 } 216 217 /** 218 * The content to record. 219 */ 220 @DataClass.Generated.Member setContentToRecord(@ecordContent int value)221 public @NonNull ContentRecordingSession setContentToRecord(@RecordContent int value) { 222 mContentToRecord = value; 223 224 if (!(mContentToRecord == RECORD_CONTENT_DISPLAY) 225 && !(mContentToRecord == RECORD_CONTENT_TASK)) { 226 throw new java.lang.IllegalArgumentException( 227 "contentToRecord was " + mContentToRecord + " but must be one of: " 228 + "RECORD_CONTENT_DISPLAY(" + RECORD_CONTENT_DISPLAY + "), " 229 + "RECORD_CONTENT_TASK(" + RECORD_CONTENT_TASK + ")"); 230 } 231 232 return this; 233 } 234 235 /** 236 * {The token of the layer of the hierarchy to record. 237 * If {@link #getContentToRecord()} is @link RecordContent#RECORD_CONTENT_DISPLAY}, then 238 * represents the WindowToken corresponding to the DisplayContent to record. 239 * If {@link #getContentToRecord()} is {@link RecordContent#RECORD_CONTENT_TASK}, then 240 * represents the {@link android.window.WindowContainerToken} of the Task to record. 241 */ 242 @DataClass.Generated.Member setTokenToRecord(@isibleForTesting @onNull IBinder value)243 public @NonNull ContentRecordingSession setTokenToRecord(@VisibleForTesting @NonNull IBinder value) { 244 mTokenToRecord = value; 245 com.android.internal.util.AnnotationValidations.validate( 246 VisibleForTesting.class, null, mTokenToRecord); 247 return this; 248 } 249 250 @Override 251 @DataClass.Generated.Member toString()252 public String toString() { 253 // You can override field toString logic by defining methods like: 254 // String fieldNameToString() { ... } 255 256 return "ContentRecordingSession { " + 257 "displayId = " + mDisplayId + ", " + 258 "contentToRecord = " + recordContentToString(mContentToRecord) + ", " + 259 "tokenToRecord = " + mTokenToRecord + 260 " }"; 261 } 262 263 @Override 264 @DataClass.Generated.Member equals(@ullable Object o)265 public boolean equals(@Nullable Object o) { 266 // You can override field equality logic by defining either of the methods like: 267 // boolean fieldNameEquals(ContentRecordingSession other) { ... } 268 // boolean fieldNameEquals(FieldType otherValue) { ... } 269 270 if (this == o) return true; 271 if (o == null || getClass() != o.getClass()) return false; 272 @SuppressWarnings("unchecked") 273 ContentRecordingSession that = (ContentRecordingSession) o; 274 //noinspection PointlessBooleanExpression 275 return true 276 && mDisplayId == that.mDisplayId 277 && mContentToRecord == that.mContentToRecord 278 && java.util.Objects.equals(mTokenToRecord, that.mTokenToRecord); 279 } 280 281 @Override 282 @DataClass.Generated.Member hashCode()283 public int hashCode() { 284 // You can override field hashCode logic by defining methods like: 285 // int fieldNameHashCode() { ... } 286 287 int _hash = 1; 288 _hash = 31 * _hash + mDisplayId; 289 _hash = 31 * _hash + mContentToRecord; 290 _hash = 31 * _hash + java.util.Objects.hashCode(mTokenToRecord); 291 return _hash; 292 } 293 294 @Override 295 @DataClass.Generated.Member writeToParcel(@onNull Parcel dest, int flags)296 public void writeToParcel(@NonNull Parcel dest, int flags) { 297 // You can override field parcelling by defining methods like: 298 // void parcelFieldName(Parcel dest, int flags) { ... } 299 300 byte flg = 0; 301 if (mTokenToRecord != null) flg |= 0x4; 302 dest.writeByte(flg); 303 dest.writeInt(mDisplayId); 304 dest.writeInt(mContentToRecord); 305 if (mTokenToRecord != null) dest.writeStrongBinder(mTokenToRecord); 306 } 307 308 @Override 309 @DataClass.Generated.Member describeContents()310 public int describeContents() { return 0; } 311 312 /** @hide */ 313 @SuppressWarnings({"unchecked", "RedundantCast"}) 314 @DataClass.Generated.Member ContentRecordingSession(@onNull Parcel in)315 /* package-private */ ContentRecordingSession(@NonNull Parcel in) { 316 // You can override field unparcelling by defining methods like: 317 // static FieldType unparcelFieldName(Parcel in) { ... } 318 319 byte flg = in.readByte(); 320 int displayId = in.readInt(); 321 int contentToRecord = in.readInt(); 322 IBinder tokenToRecord = (flg & 0x4) == 0 ? null : (IBinder) in.readStrongBinder(); 323 324 this.mDisplayId = displayId; 325 this.mContentToRecord = contentToRecord; 326 327 if (!(mContentToRecord == RECORD_CONTENT_DISPLAY) 328 && !(mContentToRecord == RECORD_CONTENT_TASK)) { 329 throw new java.lang.IllegalArgumentException( 330 "contentToRecord was " + mContentToRecord + " but must be one of: " 331 + "RECORD_CONTENT_DISPLAY(" + RECORD_CONTENT_DISPLAY + "), " 332 + "RECORD_CONTENT_TASK(" + RECORD_CONTENT_TASK + ")"); 333 } 334 335 this.mTokenToRecord = tokenToRecord; 336 com.android.internal.util.AnnotationValidations.validate( 337 VisibleForTesting.class, null, mTokenToRecord); 338 339 // onConstructed(); // You can define this method to get a callback 340 } 341 342 @DataClass.Generated.Member 343 public static final @NonNull Parcelable.Creator<ContentRecordingSession> CREATOR 344 = new Parcelable.Creator<ContentRecordingSession>() { 345 @Override 346 public ContentRecordingSession[] newArray(int size) { 347 return new ContentRecordingSession[size]; 348 } 349 350 @Override 351 public ContentRecordingSession createFromParcel(@NonNull Parcel in) { 352 return new ContentRecordingSession(in); 353 } 354 }; 355 356 /** 357 * A builder for {@link ContentRecordingSession} 358 */ 359 @SuppressWarnings("WeakerAccess") 360 @DataClass.Generated.Member 361 public static final class Builder { 362 363 private int mDisplayId; 364 private @RecordContent int mContentToRecord; 365 private @VisibleForTesting @Nullable IBinder mTokenToRecord; 366 367 private long mBuilderFieldsSet = 0L; 368 Builder()369 public Builder() { 370 } 371 372 /** 373 * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has 374 * recorded content rendered to its surface. 375 */ 376 @DataClass.Generated.Member setDisplayId(int value)377 public @NonNull Builder setDisplayId(int value) { 378 checkNotUsed(); 379 mBuilderFieldsSet |= 0x1; 380 mDisplayId = value; 381 return this; 382 } 383 384 /** 385 * The content to record. 386 */ 387 @DataClass.Generated.Member setContentToRecord(@ecordContent int value)388 public @NonNull Builder setContentToRecord(@RecordContent int value) { 389 checkNotUsed(); 390 mBuilderFieldsSet |= 0x2; 391 mContentToRecord = value; 392 return this; 393 } 394 395 /** 396 * {The token of the layer of the hierarchy to record. 397 * If {@link #getContentToRecord()} is @link RecordContent#RECORD_CONTENT_DISPLAY}, then 398 * represents the WindowToken corresponding to the DisplayContent to record. 399 * If {@link #getContentToRecord()} is {@link RecordContent#RECORD_CONTENT_TASK}, then 400 * represents the {@link android.window.WindowContainerToken} of the Task to record. 401 */ 402 @DataClass.Generated.Member setTokenToRecord(@isibleForTesting @onNull IBinder value)403 public @NonNull Builder setTokenToRecord(@VisibleForTesting @NonNull IBinder value) { 404 checkNotUsed(); 405 mBuilderFieldsSet |= 0x4; 406 mTokenToRecord = value; 407 return this; 408 } 409 410 /** Builds the instance. This builder should not be touched after calling this! */ build()411 public @NonNull ContentRecordingSession build() { 412 checkNotUsed(); 413 mBuilderFieldsSet |= 0x8; // Mark builder used 414 415 if ((mBuilderFieldsSet & 0x1) == 0) { 416 mDisplayId = INVALID_DISPLAY; 417 } 418 if ((mBuilderFieldsSet & 0x2) == 0) { 419 mContentToRecord = RECORD_CONTENT_DISPLAY; 420 } 421 if ((mBuilderFieldsSet & 0x4) == 0) { 422 mTokenToRecord = null; 423 } 424 ContentRecordingSession o = new ContentRecordingSession( 425 mDisplayId, 426 mContentToRecord, 427 mTokenToRecord); 428 return o; 429 } 430 checkNotUsed()431 private void checkNotUsed() { 432 if ((mBuilderFieldsSet & 0x8) != 0) { 433 throw new IllegalStateException( 434 "This Builder should not be reused. Use a new Builder instance instead"); 435 } 436 } 437 } 438 439 @DataClass.Generated( 440 time = 1645803878639L, 441 codegenVersion = "1.0.23", 442 sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java", 443 inputSignatures = "public static final int RECORD_CONTENT_DISPLAY\npublic static final int RECORD_CONTENT_TASK\nprivate int mDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate @com.android.internal.annotations.VisibleForTesting @android.annotation.Nullable android.os.IBinder mTokenToRecord\npublic static android.view.ContentRecordingSession createDisplaySession(android.os.IBinder)\npublic static android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static boolean isValid(android.view.ContentRecordingSession)\npublic static boolean isSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)") 444 @Deprecated __metadata()445 private void __metadata() {} 446 447 448 //@formatter:on 449 // End of generated code 450 451 } 452