Merge "[API review] Rename ScreenFlashUiCompleter to ScreenFlashListener and clarify docs" into androidx-main
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
index 6d8869e..93dbd14 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CapturePipeline.java
@@ -681,23 +681,14 @@
public ListenableFuture<Boolean> preCapture(@Nullable TotalCaptureResult captureResult) {
Logger.d(TAG, "ScreenFlashTask#preCapture");
- AtomicReference<ImageCapture.ScreenFlashUiCompleter> screenFlashUiCompleter =
+ AtomicReference<ImageCapture.ScreenFlashListener> screenFlashListener =
new AtomicReference<>();
ListenableFuture<Void> uiAppliedFuture = CallbackToFutureAdapter.getFuture(
completer -> {
- screenFlashUiCompleter.set(new ImageCapture.ScreenFlashUiCompleter() {
- @Override
- public void complete() {
- Logger.d(TAG, "ScreenFlashTask#preCapture: UI change applied");
- completer.set(null);
- }
-
- @Override
- public long getExpirationTimeMillis() {
- return System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
- ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS);
- }
+ screenFlashListener.set(() -> {
+ Logger.d(TAG, "ScreenFlashTask#preCapture: UI change applied");
+ completer.set(null);
});
return "OnScreenFlashUiApplied";
});
@@ -705,7 +696,9 @@
ListenableFuture<Void> future = CallbackToFutureAdapter.getFuture(completer -> {
CameraXExecutors.mainThreadExecutor().execute(() -> {
Logger.d(TAG, "ScreenFlashTask#preCapture: invoking applyScreenFlashUi");
- mScreenFlash.apply(screenFlashUiCompleter.get());
+ mScreenFlash.apply(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS),
+ screenFlashListener.get());
completer.set(null);
});
return "OnScreenFlashStart";
@@ -730,8 +723,8 @@
mExecutor
).transformAsync(
input -> Futures.makeTimeoutFuture(
- // Not using ScreenFlashUiCompleter#getExpirationTimeMillis here gives
- // users a bit more grace time before CameraX stops waiting.
+ // Not using the previous timestamp here gives users a bit more grace
+ // time before CameraX stops waiting.
TimeUnit.SECONDS.toMillis(
ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS),
mScheduler, null, true, uiAppliedFuture),
diff --git a/camera/camera-core/api/current.txt b/camera/camera-core/api/current.txt
index 85c40da..90f8e1c 100644
--- a/camera/camera-core/api/current.txt
+++ b/camera/camera-core/api/current.txt
@@ -378,13 +378,12 @@
}
public static interface ImageCapture.ScreenFlash {
- method @UiThread public void apply(androidx.camera.core.ImageCapture.ScreenFlashUiCompleter);
+ method @UiThread public void apply(long, androidx.camera.core.ImageCapture.ScreenFlashListener);
method @UiThread public void clear();
}
- public static interface ImageCapture.ScreenFlashUiCompleter {
- method public void complete();
- method public long getExpirationTimeMillis();
+ public static interface ImageCapture.ScreenFlashListener {
+ method public void onCompleted();
}
public interface ImageCaptureCapabilities {
diff --git a/camera/camera-core/api/restricted_current.txt b/camera/camera-core/api/restricted_current.txt
index 85c40da..90f8e1c 100644
--- a/camera/camera-core/api/restricted_current.txt
+++ b/camera/camera-core/api/restricted_current.txt
@@ -378,13 +378,12 @@
}
public static interface ImageCapture.ScreenFlash {
- method @UiThread public void apply(androidx.camera.core.ImageCapture.ScreenFlashUiCompleter);
+ method @UiThread public void apply(long, androidx.camera.core.ImageCapture.ScreenFlashListener);
method @UiThread public void clear();
}
- public static interface ImageCapture.ScreenFlashUiCompleter {
- method public void complete();
- method public long getExpirationTimeMillis();
+ public static interface ImageCapture.ScreenFlashListener {
+ method public void onCompleted();
}
public interface ImageCaptureCapabilities {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index e06e4e1..2176913 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -251,10 +251,11 @@
* <pre>{@code
* imageCapture.setScreenFlash(new ImageCapture.ScreenFlash() {
* @Override
- * public void apply(@NonNull ScreenFlashUiCompleter screenFlashUiCompleter) {
+ * public void apply(long expirationTimeMillis,
+ * @NonNull ScreenFlashListener screenFlashListener) {
* whiteColorOverlayView.setVisibility(View.VISIBLE);
* maximizeScreenBrightness();
- * screenFlashUiCompleter.complete();
+ * screenFlashListener.onCompleted();
* }
*
* @Override
@@ -1672,28 +1673,22 @@
}
/**
- * Interface to inform if application UI change has been completed for a screen flash image
- * capture.
+ * Callback listener for discovering when the application has completed its changes for a
+ * screen flash image capture.
+ *
+ * <p> For example, an application may change its UI to a full white screen with maximum
+ * brightness for a proper screen flash capture.
+ *
+ * @see ScreenFlash#apply(long, ScreenFlashListener)
*/
- public interface ScreenFlashUiCompleter {
+ public interface ScreenFlashListener {
/**
- * Completes this {@link ScreenFlashUiCompleter} instance so that CameraX is no
- * longer waiting.
+ * Invoked by the application when it has completed its changes due to a screen flash
+ * image capture.
*
* @see ScreenFlash#apply
*/
- void complete();
-
- /**
- * Gets the timestamp after which CameraX will no longer be waiting.
- *
- * <p>The timestamp is based on {@link System#currentTimeMillis()}. It is at least
- * 3 seconds later from the start of a screen flash image capture operation. Since
- * CameraX will no longer wait for the UI change to be completed after this timestamp,
- * users shouldn't be doing any screen flash related UI change that may go past this
- * timestamp.
- */
- long getExpirationTimeMillis();
+ void onCompleted();
}
@@ -1708,37 +1703,48 @@
/**
* Applies the necessary application changes for a screen flash photo capture.
*
- * <p>CameraX will invoke this method when the application UI needs to be changed for a
- * successful photo capture with screen flash feature. When this API is invoked, the
- * application UI should utilize the screen to provide extra light as an alternative to
- * physical flash. For example, the screen brightness can be maximized and screen color
- * can be covered with some bright color like white.
+ * <p>When the application UI needs to be changed for a successful photo capture with
+ * screen flash feature, CameraX will invoke this method and wait for the application to
+ * complete its changes. When this API is invoked, the application UI should utilize the
+ * screen to provide extra light as an alternative to physical flash. For example, the
+ * screen brightness can be maximized and screen color can be covered with some bright
+ * color like white.
*
- * <p>Until the timestamp of {@link ScreenFlashUiCompleter#getExpirationTimeMillis()},
- * CameraX will wait for the provided {@link ScreenFlashUiCompleter} argument to be
- * completed before starting any operation that is dependent on the UI change.
- * Applications must call {@link ScreenFlashUiCompleter#complete()} after their UI
- * changes are done so that CameraX is not unnecessarily waiting. If the application does
- * not call {@code ScreenFlashUiCompleter#complete} before the provided timestamp,
- * CameraX will stop waiting and move forward with the subsequent operations regardless.
- * In such case, it is the application's responsibility to clear any UI change done after
- * {@link #clear} has been invoked.
+ * <p>The parameter {@code expirationTimeMillis} is based on
+ * {@link System#currentTimeMillis()}. It is at least 3 seconds later from the start of a
+ * screen flash image capture operation. Until the timestamp of {@code expirationTimeMillis}
+ * parameter, CameraX will wait for the application to notify the completion of the
+ * application-side changes using the {@link ScreenFlashListener} parameter of this
+ * method. Applications must call {@link ScreenFlashListener#onCompleted()} after their
+ * UI changes are done so that CameraX is not unnecessarily waiting. If the application
+ * does not call {@code ScreenFlashListener#onCompleted} before {@code
+ * expirationTimeMillis}, CameraX will stop waiting and move forward with the subsequent
+ * operations regardless. In such case, the application no longer needs to call {@code
+ * ScreenFlashListener#onCompleted()}. If {@link #clear} has also been invoked while the
+ * application is still doing the changes, it is the application's responsibility to
+ * clear any UI change done after {@link #clear} has been invoked.
*
* <p>The following code snippet shows an example implementation of this API.
* <pre>{@code
* @Override
- * public void apply(@NonNull ScreenFlashUiCompleter screenFlashUiCompleter) {
+ * public void apply(long expirationTimeMillis,
+ * @NonNull ScreenFlashListener screenFlashListener) {
* // Enable top overlay to make screen color white
* whiteColorOverlay.setVisible(true);
* // Maximize screen brightness
* maximizeScreenBrightness();
- * screenFlashUiCompleter.complete();
+ * screenFlashListener.onCompleted();
* }}</pre>
*
- * @param screenFlashUiCompleter Used to notify when UI changes have been applied.
+ * @param expirationTimeMillis The timestamp after which CameraX will no longer listen
+ * to {@code screenFlashListener}.
+ * @param screenFlashListener Used to notify when UI changes have been applied.
*/
+ // ExecutorRegistration lint suppressed since this is called by app and CameraX supports
+ // receiving the call on any thread. Adding executor will make it harder for apps.
+ @SuppressWarnings("ExecutorRegistration")
@UiThread
- void apply(@NonNull ScreenFlashUiCompleter screenFlashUiCompleter);
+ void apply(long expirationTimeMillis, @NonNull ScreenFlashListener screenFlashListener);
/**
* Clears any application change done for screen flash operation, if required.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/ScreenFlashWrapper.kt b/camera/camera-core/src/main/java/androidx/camera/core/internal/ScreenFlashWrapper.kt
index 118f945..3241d1a 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/ScreenFlashWrapper.kt
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/ScreenFlashWrapper.kt
@@ -19,11 +19,11 @@
import androidx.annotation.GuardedBy
import androidx.annotation.RequiresApi
import androidx.camera.core.ImageCapture.ScreenFlash
-import androidx.camera.core.ImageCapture.ScreenFlashUiCompleter
+import androidx.camera.core.ImageCapture.ScreenFlashListener
import androidx.camera.core.Logger
/**
- * Wrapper class around [ScreenFlash] to save the [ScreenFlashUiCompleter] passed to app.
+ * Wrapper class around [ScreenFlash] to save the [ScreenFlashListener] passed to app.
*
* This allows us to clean up properly in case a capture is cancelled earlier (e.g. ImageCapture is
* unbound after [apply] is invoked but [clear] is not).
@@ -37,37 +37,32 @@
@GuardedBy("lock")
private var isClearScreenFlashPending: Boolean = false
@GuardedBy("lock")
- private var pendingCompleter: ScreenFlashUiCompleter? = null
+ private var pendingListener: ScreenFlashListener? = null
companion object {
private const val TAG = "ScreenFlashWrapper"
@JvmStatic
- fun from(screenFlash: ScreenFlash?) =
- ScreenFlashWrapper(screenFlash)
+ fun from(screenFlash: ScreenFlash?) = ScreenFlashWrapper(screenFlash)
}
- override fun apply(screenFlashUiCompleter: ScreenFlashUiCompleter) {
+ override fun apply(expirationTimeMillis: Long, screenFlashListener: ScreenFlashListener) {
synchronized(lock) {
isClearScreenFlashPending = true
- pendingCompleter = screenFlashUiCompleter
+ pendingListener = screenFlashListener
}
- screenFlash?.apply(object : ScreenFlashUiCompleter {
- override fun complete() {
- synchronized(lock) {
- if (pendingCompleter == null) {
- Logger.w(TAG, "apply: pendingCompleter is null!")
- }
- completePendingScreenFlashUiCompleter()
+ screenFlash?.apply(expirationTimeMillis) {
+ synchronized(lock) {
+ if (pendingListener == null) {
+ Logger.w(TAG, "apply: pendingListener is null!")
}
+ completePendingScreenFlashListener()
}
-
- override fun getExpirationTimeMillis() = screenFlashUiCompleter.expirationTimeMillis
- }) ?: run {
+ } ?: run {
Logger.e(TAG, "apply: screenFlash is null!")
// Complete immediately in case this error case is invoked by some bug
- completePendingScreenFlashUiCompleter()
+ completePendingScreenFlashListener()
}
}
@@ -81,12 +76,12 @@
fun getBaseScreenFlash(): ScreenFlash? = screenFlash
/**
- * Completes the pending [ScreenFlashUiCompleter], if any.
+ * Completes the pending [ScreenFlashListener], if any.
*/
- private fun completePendingScreenFlashUiCompleter() {
+ private fun completePendingScreenFlashListener() {
synchronized(lock) {
- pendingCompleter?.complete()
- pendingCompleter = null
+ pendingListener?.onCompleted()
+ pendingListener = null
}
}
@@ -110,7 +105,7 @@
* Completes all pending operations.
*/
fun completePendingTasks() {
- completePendingScreenFlashUiCompleter()
+ completePendingScreenFlashListener()
completePendingScreenFlashClear()
}
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
index 758471f..30155a3 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
@@ -60,7 +60,7 @@
import androidx.camera.testing.impl.fakes.FakeImageReaderProxy
import androidx.camera.testing.impl.fakes.FakeSessionProcessor
import androidx.camera.testing.impl.mocks.MockScreenFlash
-import androidx.camera.testing.impl.mocks.MockScreenFlashUiCompleter
+import androidx.camera.testing.impl.mocks.MockScreenFlashListener
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import java.io.File
@@ -629,7 +629,8 @@
imageCapture.screenFlash = MockScreenFlash()
(cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(
- MockScreenFlashUiCompleter()
+ 0L,
+ MockScreenFlashListener()
)
imageCapture.unbindFromCamera(cameraFront)
@@ -646,7 +647,8 @@
imageCapture.screenFlash = MockScreenFlash()
(cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(
- MockScreenFlashUiCompleter()
+ 0L,
+ MockScreenFlashListener()
)
(cameraFront.cameraControl as FakeCameraControl).screenFlash?.clear()
imageCapture.unbindFromCamera(cameraFront)
@@ -656,8 +658,8 @@
}
@Test
- fun cameraControlScreenFlashUiCompleterCompleted_whenImageCaptureCompleterIsCompleted() {
- val completer = MockScreenFlashUiCompleter()
+ fun cameraControlScreenFlashListenerCompleted_whenImageCaptureListenerIsCompleted() {
+ val listener = MockScreenFlashListener()
val imageCapture = bindImageCapture(
cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA,
imageReaderProxyProvider = getFakeImageReaderProxyProvider(),
@@ -666,16 +668,16 @@
setApplyCompletedInstantly(false)
}
- (cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(completer)
- (imageCapture.screenFlash as MockScreenFlash).lastApplyCompleter?.complete()
+ (cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(0L, listener)
+ (imageCapture.screenFlash as MockScreenFlash).lastApplyListener?.onCompleted()
- completer.awaitComplete(3000)
- assertThat(completer.getCompleteCount()).isEqualTo(1)
+ listener.awaitComplete(3000)
+ assertThat(listener.getCompleteCount()).isEqualTo(1)
}
@Test
- fun imageCaptureUnboundWithoutCompletion_cameraControlScreenFlashUiCompleterCompleted() {
- val completer = MockScreenFlashUiCompleter()
+ fun imageCaptureUnboundWithoutCompletion_cameraControlScreenFlashListenerCompleted() {
+ val listener = MockScreenFlashListener()
val imageCapture = bindImageCapture(
cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA,
imageReaderProxyProvider = getFakeImageReaderProxyProvider(),
@@ -684,16 +686,16 @@
setApplyCompletedInstantly(false)
}
- (cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(completer)
+ (cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(0L, listener)
imageCapture.unbindFromCamera(cameraFront)
- completer.awaitComplete(3000)
- assertThat(completer.getCompleteCount()).isEqualTo(1)
+ listener.awaitComplete(3000)
+ assertThat(listener.getCompleteCount()).isEqualTo(1)
}
@Test
- fun imageCaptureUnboundAndCompleterCompleted_cameraControlCompleterCompletedOnlyOnce() {
- val completer = MockScreenFlashUiCompleter()
+ fun imageCaptureUnboundAndListenerCompleted_cameraControlListenerCompletedOnlyOnce() {
+ val listener = MockScreenFlashListener()
val imageCapture = bindImageCapture(
cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA,
imageReaderProxyProvider = getFakeImageReaderProxyProvider(),
@@ -702,12 +704,12 @@
setApplyCompletedInstantly(false)
}
- (cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(completer)
+ (cameraFront.cameraControl as FakeCameraControl).screenFlash?.apply(0L, listener)
imageCapture.unbindFromCamera(cameraFront)
- (imageCapture.screenFlash as MockScreenFlash).lastApplyCompleter?.complete()
+ (imageCapture.screenFlash as MockScreenFlash).lastApplyListener?.onCompleted()
- completer.awaitComplete(3000)
- assertThat(completer.getCompleteCount()).isEqualTo(1)
+ listener.awaitComplete(3000)
+ assertThat(listener.getCompleteCount()).isEqualTo(1)
}
@Test
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlash.java b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlash.java
index 1ec0d11..59bfb0c 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlash.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlash.java
@@ -21,8 +21,9 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
+import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCapture.ScreenFlash;
-import androidx.camera.core.ImageCapture.ScreenFlashUiCompleter;
+import androidx.camera.core.ImageCapture.ScreenFlashListener;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -39,7 +40,7 @@
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public class MockScreenFlash implements ScreenFlash {
/**
- * Represents {@link ScreenFlash#apply(ScreenFlashUiCompleter)} event.
+ * Represents {@link ImageCapture.ScreenFlash#apply} event.
*/
public static final int APPLY = 0;
/**
@@ -64,7 +65,7 @@
@GuardedBy("mLock")
@Nullable
- private ScreenFlashUiCompleter mLastApplyCompleter;
+ private ScreenFlashListener mLastApplyListener;
/**
* Returns a list of {@link ScreenFlashEvent} in the same order as invoked.
@@ -91,33 +92,34 @@
}
/**
- * Enables or disables the {@link ScreenFlashUiCompleter} being completed instantly when
- * {@link ScreenFlash#apply(ScreenFlashUiCompleter)} is invoked.
+ * Enables or disables the {@link ScreenFlashListener} being completed instantly when
+ * {@link ScreenFlash#apply(long, ScreenFlashListener)} is invoked.
*/
public void setApplyCompletedInstantly(boolean completedInstantly) {
mIsApplyCompletedInstantly = completedInstantly;
}
/**
- * Gets the {@link ScreenFlashUiCompleter} instance of the last
- * {@link ScreenFlash#apply(ScreenFlashUiCompleter)} invocation, or null in case of no
+ * Gets the {@link ScreenFlashListener} instance of the last
+ * {@link ScreenFlash#apply(long, ScreenFlashListener)} invocation, or null in case of no
* invocation.
*/
@Nullable
- public ScreenFlashUiCompleter getLastApplyCompleter() {
+ public ScreenFlashListener getLastApplyListener() {
synchronized (mLock) {
- return mLastApplyCompleter;
+ return mLastApplyListener;
}
}
/** {@inheritDoc} */
@Override
- public void apply(@NonNull ScreenFlashUiCompleter screenFlashUiCompleter) {
+ public void apply(long expirationTimeMillis,
+ @NonNull ScreenFlashListener screenFlashListener) {
synchronized (mLock) {
mEventList.add(APPLY);
- mLastApplyCompleter = screenFlashUiCompleter;
+ mLastApplyListener = screenFlashListener;
if (mIsApplyCompletedInstantly) {
- screenFlashUiCompleter.complete();
+ screenFlashListener.onCompleted();
}
}
}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlashUiCompleter.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlashListener.kt
similarity index 74%
rename from camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlashUiCompleter.kt
rename to camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlashListener.kt
index ef11bca..8bf696b 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlashUiCompleter.kt
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/impl/mocks/MockScreenFlashListener.kt
@@ -17,39 +17,37 @@
package androidx.camera.testing.impl.mocks
import androidx.annotation.GuardedBy
-import androidx.camera.core.ImageCapture.ScreenFlashUiCompleter
+import androidx.camera.core.ImageCapture.ScreenFlashListener
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
/**
- * A mock implementations of [ScreenFlashUiCompleter] for testing purpose.
+ * A mock implementations of [ScreenFlashListener] for testing purpose.
*/
-class MockScreenFlashUiCompleter : ScreenFlashUiCompleter {
+class MockScreenFlashListener : ScreenFlashListener {
private val lock = Object()
@GuardedBy("lock")
private var completeCount: Int = 0
private val completeLatch = CountDownLatch(1)
- override fun complete() {
+ override fun onCompleted() {
synchronized(lock) {
completeCount++
}
completeLatch.countDown()
}
- override fun getExpirationTimeMillis() = 0L
-
/**
- * Gets the number of times [complete] was invoked.
+ * Gets the number of times [onCompleted] was invoked.
*/
fun getCompleteCount() = synchronized(lock) { completeCount }
/**
- * Waits for [complete] to be invoked once.
+ * Waits for [onCompleted] to be invoked once.
*
* @param timeoutInMillis The timeout of waiting in milliseconds.
- * @return True if [complete] was invoked, false if timed out.
+ * @return True if [onCompleted] was invoked, false if timed out.
*/
fun awaitComplete(timeoutInMillis: Long): Boolean {
return completeLatch.await(timeoutInMillis, TimeUnit.MILLISECONDS)
diff --git a/camera/camera-testing/src/test/java/androidx/camera/testing/mocks/MockScreenFlashTest.kt b/camera/camera-testing/src/test/java/androidx/camera/testing/mocks/MockScreenFlashTest.kt
index 1110a44..c951560 100644
--- a/camera/camera-testing/src/test/java/androidx/camera/testing/mocks/MockScreenFlashTest.kt
+++ b/camera/camera-testing/src/test/java/androidx/camera/testing/mocks/MockScreenFlashTest.kt
@@ -18,11 +18,13 @@
import android.annotation.SuppressLint
import android.os.Build
-import androidx.camera.core.ImageCapture.ScreenFlashUiCompleter
+import androidx.camera.core.ImageCapture
+import androidx.camera.core.ImageCapture.ScreenFlashListener
import androidx.camera.testing.impl.mocks.MockScreenFlash
import androidx.camera.testing.impl.mocks.MockScreenFlash.APPLY
import androidx.camera.testing.impl.mocks.MockScreenFlash.CLEAR
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -34,14 +36,8 @@
@DoNotInstrument
@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
class MockScreenFlashTest {
- private val dummyCompleter = object : ScreenFlashUiCompleter {
- override fun complete() {
- // no-op
- }
-
- override fun getExpirationTimeMillis(): Long {
- return 0
- }
+ private val dummyListener = ScreenFlashListener {
+ // no-op
}
private lateinit var mMockScreenFlash: MockScreenFlash
@@ -54,7 +50,12 @@
@Test
fun getScreenFlashEvents_invocationsRecordedExactlyInSameOrder() {
mMockScreenFlash.clear()
- mMockScreenFlash.apply(dummyCompleter)
+ mMockScreenFlash.apply(
+ System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS
+ ),
+ dummyListener,
+ )
mMockScreenFlash.clear()
assertThat(mMockScreenFlash.screenFlashEvents).isEqualTo(listOf(
@@ -67,16 +68,13 @@
@Test
fun awaitApply_listenerCompletedAutomaticallyByDefault() {
var isCompleted = false
- val completer = object : ScreenFlashUiCompleter {
- override fun complete() {
- isCompleted = true
- }
-
- override fun getExpirationTimeMillis(): Long {
- return 0
- }
- }
- mMockScreenFlash.apply(completer)
+ val listener = ScreenFlashListener { isCompleted = true }
+ mMockScreenFlash.apply(
+ System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS
+ ),
+ listener,
+ )
assertThat(isCompleted).isTrue()
}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
index 45b27db..5a54f82 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
@@ -223,9 +223,9 @@
private static final ScreenFlash NO_OP_SCREEN_FLASH =
new ScreenFlash() {
@Override
- public void apply(
- @NonNull ImageCapture.ScreenFlashUiCompleter screenFlashUiCompleter) {
- screenFlashUiCompleter.complete();
+ public void apply(long expirationTimeMillis,
+ @NonNull ImageCapture.ScreenFlashListener screenFlashListener) {
+ screenFlashListener.onCompleted();
}
@Override
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/ScreenFlashView.java b/camera/camera-view/src/main/java/androidx/camera/view/ScreenFlashView.java
index 5798558..6128f0f 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/ScreenFlashView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/ScreenFlashView.java
@@ -174,8 +174,8 @@
private float mPreviousBrightness;
@Override
- public void apply(
- @NonNull ImageCapture.ScreenFlashUiCompleter screenFlashUiCompleter) {
+ public void apply(long expirationTimeMillis,
+ @NonNull ImageCapture.ScreenFlashListener screenFlashListener) {
Logger.d(TAG, "ScreenFlash#apply");
setAlpha(1f);
@@ -186,7 +186,7 @@
layoutParam.screenBrightness = 1F;
mScreenFlashWindow.setAttributes(layoutParam);
- screenFlashUiCompleter.complete();
+ screenFlashListener.onCompleted();
}
@Override
@@ -208,7 +208,7 @@
* Returns an {@link ScreenFlash} implementation based on the {@link Window} instance
* set via {@link #setScreenFlashWindow(Window)}.
*
- * <p> When {@link ScreenFlash#apply(ImageCapture.ScreenFlashUiCompleter)} is invoked,
+ * <p> When {@link ScreenFlash#apply(long, ImageCapture.ScreenFlashListener)} is invoked,
* this view becomes fully visible and screen brightness is maximized using the provided
* {@code Window}. The default color of the overlay view is {@link Color#WHITE}. To change
* the color, use {@link #setBackgroundColor(int)}.
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt b/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
index 2a6c395..19a2e7d 100644
--- a/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
+++ b/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
@@ -546,9 +546,10 @@
ScreenFlashUiInfo.ProviderType.SCREEN_FLASH_VIEW,
object : ScreenFlash {
override fun apply(
- screenFlashUiCompleter: ImageCapture.ScreenFlashUiCompleter
+ expirationTimeMillis: Long,
+ screenFlashListener: ImageCapture.ScreenFlashListener,
) {
- screenFlashUiCompleter.complete()
+ screenFlashListener.onCompleted()
}
override fun clear() {
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/ScreenFlashViewTest.kt b/camera/camera-view/src/test/java/androidx/camera/view/ScreenFlashViewTest.kt
index 744ef07..569b64f 100644
--- a/camera/camera-view/src/test/java/androidx/camera/view/ScreenFlashViewTest.kt
+++ b/camera/camera-view/src/test/java/androidx/camera/view/ScreenFlashViewTest.kt
@@ -22,9 +22,10 @@
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCapture.ScreenFlash
-import androidx.camera.core.ImageCapture.ScreenFlashUiCompleter
+import androidx.camera.core.ImageCapture.ScreenFlashListener
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import org.junit.Assert
import org.junit.Assume
import org.junit.Before
@@ -39,14 +40,8 @@
@DoNotInstrument
@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
class ScreenFlashViewTest {
- private val noOpUiCompleter = object : ScreenFlashUiCompleter {
- override fun complete() {
- // no-op
- }
-
- override fun getExpirationTimeMillis(): Long {
- return 0
- }
+ private val noOpListener = ScreenFlashListener {
+ // no-op
}
private val appContext = ApplicationProvider.getApplicationContext<Context>()
@@ -107,21 +102,36 @@
@Test
fun isFullyVisible_whenScreenFlashApplyInvoked() {
val screenFlash = getScreenFlashAfterSettingWindow(true)
- screenFlash!!.apply(noOpUiCompleter)
+ screenFlash!!.apply(
+ System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS
+ ),
+ noOpListener,
+ )
assertThat(screenFlashView.alpha).isEqualTo(1f)
}
@Test
fun windowBrightnessMaximized_whenScreenFlashApplyInvoked() {
val screenFlash = getScreenFlashAfterSettingWindow(true)
- screenFlash!!.apply(noOpUiCompleter)
+ screenFlash!!.apply(
+ System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS
+ ),
+ noOpListener,
+ )
assertThat(window.attributes.screenBrightness).isEqualTo(1f)
}
@Test
fun isTransparent_whenScreenFlashUiClearedAfterApply() {
val screenFlash = getScreenFlashAfterSettingWindow(true)
- screenFlash!!.apply(noOpUiCompleter)
+ screenFlash!!.apply(
+ System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS
+ ),
+ noOpListener,
+ )
screenFlash.clear()
assertThat(screenFlashView.alpha).isEqualTo(0f)
}
@@ -133,7 +143,12 @@
layoutParam.screenBrightness = initialBrightness
window.setAttributes(layoutParam)
val screenFlash = getScreenFlashAfterSettingWindow(true)
- screenFlash!!.apply(noOpUiCompleter)
+ screenFlash!!.apply(
+ System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(
+ ImageCapture.SCREEN_FLASH_UI_APPLY_TIMEOUT_SECONDS
+ ),
+ noOpListener,
+ )
screenFlash.clear()
assertThat(window.attributes.screenBrightness).isEqualTo(initialBrightness)
}