[API Review] Remove VideoRecordEvent#getEventType()
Removes the EVENT_TYPE_* enum from VideoRecordEvent. The same
functionality can be obtained using common language features such as
`if-instanceof` in Java or `when-is` in Kotlin.
Updated sample in documentation to explain usage.
Bug: 198241716
Test: ./gradlew camera:camera-video:connectedCheck
&& ./gradlew camera:camera-video:test
Change-Id: Ie78ed94c6d8a99cab63a5ce348a2221890498d60
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
index c8cd073..c36dcd2 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
@@ -934,7 +934,7 @@
// Check the audio information reports state as disabled.
val captor = ArgumentCaptor.forClass(VideoRecordEvent::class.java)
verify(videoRecordEventListener, atLeastOnce()).accept(captor.capture())
- assertThat(captor.value.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_STATUS)
+ assertThat(captor.value).isInstanceOf(VideoRecordEvent.Status::class.java)
val status = captor.value as VideoRecordEvent.Status
assertThat(status.recordingStats.audioStats.audioState)
.isEqualTo(AudioStats.AUDIO_STATE_DISABLED)
@@ -1092,7 +1092,7 @@
val captor = ArgumentCaptor.forClass(VideoRecordEvent::class.java)
verify(videoRecordEventListener, atLeastOnce()).accept(captor.capture())
- assertThat(captor.value.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_FINALIZE)
+ assertThat(captor.value).isInstanceOf(VideoRecordEvent.Finalize::class.java)
val finalize = captor.value as VideoRecordEvent.Finalize
assertThat(finalize.error).isEqualTo(ERROR_FILE_SIZE_LIMIT_REACHED)
assertThat(file.length()).isLessThan(fileSizeLimit)
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
index 7ee8a9c..0268e19 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
@@ -101,22 +101,22 @@
private lateinit var finalize: VideoRecordEvent.Finalize
private val videoRecordEventListener = Consumer<VideoRecordEvent> {
- when (it.eventType) {
- VideoRecordEvent.EVENT_TYPE_START -> {
+ when (it) {
+ is VideoRecordEvent.Start -> {
// Recording start.
Log.d(TAG, "Recording start")
}
- VideoRecordEvent.EVENT_TYPE_FINALIZE -> {
+ is VideoRecordEvent.Finalize -> {
// Recording stop.
Log.d(TAG, "Recording finalize")
- finalize = it as VideoRecordEvent.Finalize
+ finalize = it
latchForVideoSaved.countDown()
}
- VideoRecordEvent.EVENT_TYPE_STATUS -> {
+ is VideoRecordEvent.Status -> {
// Make sure the recording proceed for a while.
latchForVideoRecording.countDown()
}
- VideoRecordEvent.EVENT_TYPE_PAUSE, VideoRecordEvent.EVENT_TYPE_RESUME -> {
+ is VideoRecordEvent.Pause, is VideoRecordEvent.Resume -> {
// no op for this test, skip these event now.
}
else -> {
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoRecordEvent.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoRecordEvent.java
index 2811f91..370da49 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoRecordEvent.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoRecordEvent.java
@@ -23,7 +23,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
-import androidx.annotation.RestrictTo.Scope;
import androidx.core.util.Consumer;
import androidx.core.util.Preconditions;
@@ -38,33 +37,46 @@
* be sent to the listener set in {@link PendingRecording#withEventListener(Executor, Consumer)}.
*
* <p>There are {@link Start}, {@link Finalize}, {@link Status}, {@link Pause} and {@link Resume}
- * events. The {@link #getEventType()} can be used to check what type of event is.
+ * events.
*
- * Example: typical way to determine the event type and cast to the event class
+ * <p>Example: Below is the typical way to determine the event type and cast to the event class, if
+ * needed.
*
* <pre>{@code
*
- * VideoRecordEvent videoRecordEvent = obtainVideoRecordEvent();
- * switch (videoRecordEvent.getEventType()) {
- * case VideoRecordEvent.EVENT_TYPE_START:
- * VideoRecordEvent.Start start = (VideoRecordEvent.Start) videoRecordEvent;
- * break;
- * case VideoRecordEvent.EVENT_TYPE_FINALIZE:
- * VideoRecordEvent.Finalize finalize = (VideoRecordEvent.Finalize) videoRecordEvent;
- * break;
- * case VideoRecordEvent.EVENT_TYPE_STATUS:
- * VideoRecordEvent.Status status = (VideoRecordEvent.Status) videoRecordEvent;
- * break;
- * case VideoRecordEvent.EVENT_TYPE_PAUSE:
- * VideoRecordEvent.Pause pause = (VideoRecordEvent.Pause) videoRecordEvent;
- * break;
- * case VideoRecordEvent.EVENT_TYPE_RESUME:
- * VideoRecordEvent.Resume resume = (VideoRecordEvent.Resume) videoRecordEvent;
- * break;
- * }
+ * ActiveRecording activeRecording = recorder.prepareRecording(outputOptions)
+ * .withEventListener(ContextCompat.getMainExecutor(context), videoRecordEvent -> {
+ * if (videoRecordEvent instanceof VideoRecordEvent.Start) {
+ * // Handle the start of a new active recording
+ * ...
+ * } else if (videoRecordEvent instanceof VideoRecordEvent.Pause) {
+ * // Handle the case where the active recording is paused
+ * ...
+ * } else if (videoRecordEvent instanceof VideoRecordEvent.Resume) {
+ * // Handles the case where the active recording is resumed
+ * ...
+ * } else if (videoRecordEvent instanceof VideoRecordEvent.Finalize) {
+ * VideoRecordEvent.Finalize finalizeEvent =
+ * (VideoRecordEvent.Finalize) videoRecordEvent;
+ * // Handles a finalize event for the active recording, checking Finalize.getError()
+ * int error = finalizeEvent.getError();
+ * if (error != Finalize.ERROR_NONE) {
+ * ...
+ * }
+ * }
+ *
+ * // All events, including VideoRecordEvent.Status, contain RecordingStats.
+ * // This can be used to update the UI or track the recording duration.
+ * RecordingStats recordingStats = videoRecordEvent.getRecordingStats();
+ * ...
+ * }).start();
*
* }</pre>
*
+ * <p>If using Kotlin, the VideoRecordEvent class can be treated similar to a {@code sealed
+ * class}. In Kotlin, it is recommended to use a {@code when} expression rather than an {@code
+ * if}-{@code else if} chain as in the above example.
+ *
* <p>When a video recording is requested, {@link Start} event will be reported at first and
* {@link Finalize} event will be reported when the recording is finished. The stop reason can be
* obtained via {@link Finalize#getError()}. {@link Finalize#ERROR_NONE} means that the video was
@@ -79,49 +91,6 @@
*/
public abstract class VideoRecordEvent {
- /**
- * Indicates the start of recording.
- *
- * @see Start
- */
- public static final int EVENT_TYPE_START = 0;
-
- /**
- * Indicates the finalization of recording.
- *
- * @see Finalize
- */
- public static final int EVENT_TYPE_FINALIZE = 1;
-
- /**
- * The status report of the recording in progress.
- *
- * @see Status
- */
- public static final int EVENT_TYPE_STATUS = 2;
-
- /**
- * Indicates the pause event of recording.
- *
- * @see Pause
- */
- public static final int EVENT_TYPE_PAUSE = 3;
-
- /**
- * Indicates the resume event of recording.
- *
- * @see Resume
- */
- public static final int EVENT_TYPE_RESUME = 4;
-
- /** @hide */
- @IntDef({EVENT_TYPE_START, EVENT_TYPE_FINALIZE, EVENT_TYPE_STATUS, EVENT_TYPE_PAUSE,
- EVENT_TYPE_RESUME})
- @Retention(RetentionPolicy.SOURCE)
- @RestrictTo(Scope.LIBRARY)
- public @interface EventType {
- }
-
private final OutputOptions mOutputOptions;
private final RecordingStats mRecordingStats;
@@ -134,15 +103,6 @@
}
/**
- * Gets the event type.
- *
- * <p>Possible values are {@link #EVENT_TYPE_START}, {@link #EVENT_TYPE_FINALIZE},
- * {@link #EVENT_TYPE_PAUSE}, {@link #EVENT_TYPE_RESUME} and {@link #EVENT_TYPE_STATUS}.
- */
- @EventType
- public abstract int getEventType();
-
- /**
* Gets the recording status of current event.
*/
@NonNull
@@ -176,13 +136,6 @@
Start(@NonNull OutputOptions outputOptions, @NonNull RecordingStats recordingStats) {
super(outputOptions, recordingStats);
}
-
- /** {@inheritDoc} */
- @EventType
- @Override
- public int getEventType() {
- return EVENT_TYPE_START;
- }
}
@NonNull
@@ -324,13 +277,6 @@
mCause = cause;
}
- /** {@inheritDoc} */
- @EventType
- @Override
- public int getEventType() {
- return EVENT_TYPE_FINALIZE;
- }
-
/**
* Gets the {@link OutputResults}.
*/
@@ -389,13 +335,6 @@
Status(@NonNull OutputOptions outputOptions, @NonNull RecordingStats recordingStats) {
super(outputOptions, recordingStats);
}
-
- /** {@inheritDoc} */
- @EventType
- @Override
- public int getEventType() {
- return EVENT_TYPE_STATUS;
- }
}
@NonNull
@@ -415,13 +354,6 @@
Pause(@NonNull OutputOptions outputOptions, @NonNull RecordingStats recordingStats) {
super(outputOptions, recordingStats);
}
-
- /** {@inheritDoc} */
- @EventType
- @Override
- public int getEventType() {
- return EVENT_TYPE_PAUSE;
- }
}
@NonNull
@@ -441,12 +373,5 @@
Resume(@NonNull OutputOptions outputOptions, @NonNull RecordingStats recordingStats) {
super(outputOptions, recordingStats);
}
-
- /** {@inheritDoc} */
- @EventType
- @Override
- public int getEventType() {
- return EVENT_TYPE_RESUME;
- }
}
}
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/VideoRecordEventTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/VideoRecordEventTest.kt
index 71c4d17..8fa89c7 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/VideoRecordEventTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/VideoRecordEventTest.kt
@@ -47,7 +47,7 @@
TEST_RECORDING_STATE
)
- assertThat(event.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_START)
+ assertThat(event).isInstanceOf(VideoRecordEvent.Start::class.java)
assertThat(event.outputOptions).isEqualTo(TEST_OUTPUT_OPTION)
assertThat(event.recordingStats).isEqualTo(TEST_RECORDING_STATE)
}
@@ -60,7 +60,7 @@
TEST_OUTPUT_RESULT
)
- assertThat(event.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_FINALIZE)
+ assertThat(event).isInstanceOf(VideoRecordEvent.Finalize::class.java)
assertThat(event.outputOptions).isEqualTo(TEST_OUTPUT_OPTION)
assertThat(event.recordingStats).isEqualTo(TEST_RECORDING_STATE)
assertThat(event.outputResults).isEqualTo(TEST_OUTPUT_RESULT)
@@ -81,7 +81,7 @@
cause
)
- assertThat(event.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_FINALIZE)
+ assertThat(event).isInstanceOf(VideoRecordEvent.Finalize::class.java)
assertThat(event.outputOptions).isEqualTo(TEST_OUTPUT_OPTION)
assertThat(event.recordingStats).isEqualTo(TEST_RECORDING_STATE)
assertThat(event.outputResults).isEqualTo(TEST_OUTPUT_RESULT)
@@ -110,7 +110,7 @@
TEST_RECORDING_STATE
)
- assertThat(event.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_STATUS)
+ assertThat(event).isInstanceOf(VideoRecordEvent.Status::class.java)
assertThat(event.outputOptions).isEqualTo(TEST_OUTPUT_OPTION)
assertThat(event.recordingStats).isEqualTo(TEST_RECORDING_STATE)
}
@@ -122,7 +122,7 @@
TEST_RECORDING_STATE
)
- assertThat(event.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_PAUSE)
+ assertThat(event).isInstanceOf(VideoRecordEvent.Pause::class.java)
assertThat(event.outputOptions).isEqualTo(TEST_OUTPUT_OPTION)
assertThat(event.recordingStats).isEqualTo(TEST_RECORDING_STATE)
}
@@ -134,7 +134,7 @@
TEST_RECORDING_STATE
)
- assertThat(event.eventType).isEqualTo(VideoRecordEvent.EVENT_TYPE_RESUME)
+ assertThat(event).isInstanceOf(VideoRecordEvent.Resume::class.java)
assertThat(event.outputOptions).isEqualTo(TEST_OUTPUT_OPTION)
assertThat(event.recordingStats).isEqualTo(TEST_RECORDING_STATE)
}
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index 3c8a8f7a..7a5351a 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -477,60 +477,54 @@
private final Consumer<VideoRecordEvent> mVideoRecordEventListener = event -> {
updateRecordingStats(event.getRecordingStats());
- switch (event.getEventType()) {
- case VideoRecordEvent.EVENT_TYPE_FINALIZE:
- VideoRecordEvent.Finalize finalize = (VideoRecordEvent.Finalize) event;
+ if (event instanceof VideoRecordEvent.Finalize) {
+ VideoRecordEvent.Finalize finalize = (VideoRecordEvent.Finalize) event;
- switch (finalize.getError()) {
- case ERROR_NONE:
- case ERROR_FILE_SIZE_LIMIT_REACHED:
- case ERROR_INSUFFICIENT_DISK:
- case ERROR_SOURCE_INACTIVE:
- Uri uri = finalize.getOutputResults().getOutputUri();
- OutputOptions outputOptions = finalize.getOutputOptions();
- String msg;
- String videoFilePath;
- if (outputOptions instanceof MediaStoreOutputOptions) {
- msg = "Saved uri " + uri;
- videoFilePath = getAbsolutePathFromUri(
- getApplicationContext().getContentResolver(),
- uri
- );
- // For OutputOptionsType is OutputOptions.OPTIONS_TYPE_MEDIA_STORE,
- // the Photo/Gallery apps on devices (API Level < Q) sometimes will
- // not show the video files saved in MediaStore, suggest to call
- // scanFile still to force scan the media file.
- // scanVideoOutputFile(new File(videoFilePath));
- } else if (outputOptions instanceof FileOutputOptions) {
- videoFilePath = ((FileOutputOptions) outputOptions)
- .getFile().getAbsolutePath();
- msg = "Saved video file: " + videoFilePath;
- scanVideoOutputFile(new File(videoFilePath));
- } else {
- throw new AssertionError("Unknown or unsupported OutputOptions type: "
- + outputOptions.getClass().getSimpleName());
- }
- // The video file path is used in tracing e2e test log. Don't remove it.
- Log.d(TAG, "Saved video file: " + videoFilePath);
+ switch (finalize.getError()) {
+ case ERROR_NONE:
+ case ERROR_FILE_SIZE_LIMIT_REACHED:
+ case ERROR_INSUFFICIENT_DISK:
+ case ERROR_SOURCE_INACTIVE:
+ Uri uri = finalize.getOutputResults().getOutputUri();
+ OutputOptions outputOptions = finalize.getOutputOptions();
+ String msg;
+ String videoFilePath;
+ if (outputOptions instanceof MediaStoreOutputOptions) {
+ msg = "Saved uri " + uri;
+ videoFilePath = getAbsolutePathFromUri(
+ getApplicationContext().getContentResolver(),
+ uri
+ );
+ // For OutputOptionsType is OutputOptions.OPTIONS_TYPE_MEDIA_STORE,
+ // the Photo/Gallery apps on devices (API Level < Q) sometimes will
+ // not show the video files saved in MediaStore, suggest to call
+ // scanFile still to force scan the media file.
+ // scanVideoOutputFile(new File(videoFilePath));
+ } else if (outputOptions instanceof FileOutputOptions) {
+ videoFilePath = ((FileOutputOptions) outputOptions)
+ .getFile().getAbsolutePath();
+ msg = "Saved video file: " + videoFilePath;
+ scanVideoOutputFile(new File(videoFilePath));
+ } else {
+ throw new AssertionError("Unknown or unsupported OutputOptions type: "
+ + outputOptions.getClass().getSimpleName());
+ }
+ // The video file path is used in tracing e2e test log. Don't remove it.
+ Log.d(TAG, "Saved video file: " + videoFilePath);
- if (finalize.getError() != ERROR_NONE) {
- msg += " with code (" + finalize.getError() + ")";
- }
- Log.d(TAG, msg, finalize.getCause());
- Toast.makeText(CameraXActivity.this, msg, Toast.LENGTH_LONG).show();
- break;
- default:
- String errMsg = "Video capture failed by (" + finalize.getError() + "): "
- + finalize.getCause();
- Log.e(TAG, errMsg, finalize.getCause());
- Toast.makeText(CameraXActivity.this, errMsg, Toast.LENGTH_LONG).show();
- }
- mRecordUi.setState(RecordUi.State.IDLE);
- break;
-
- default:
- // No-op
- break;
+ if (finalize.getError() != ERROR_NONE) {
+ msg += " with code (" + finalize.getError() + ")";
+ }
+ Log.d(TAG, msg, finalize.getCause());
+ Toast.makeText(CameraXActivity.this, msg, Toast.LENGTH_LONG).show();
+ break;
+ default:
+ String errMsg = "Video capture failed by (" + finalize.getError() + "): "
+ + finalize.getCause();
+ Log.e(TAG, errMsg, finalize.getCause());
+ Toast.makeText(CameraXActivity.this, errMsg, Toast.LENGTH_LONG).show();
+ }
+ mRecordUi.setState(RecordUi.State.IDLE);
}
};