Create helper class for creating PreviewSurfaceCallback
- Created a helper class for creating PreviewSurfaceCallback.
- Migrate all tests to use the new PreviewSurfaceCallback except for PreviewTest.
- Had to reorder some of the test because having both the new & the old interface is causing some funny side effect. It will be gone once the old interface is removed.
Bug:117519540
Test: manual test and ./gradlew bOS
Change-Id: I80d5c6f7549098a3106639f530ea5d5c6248e01b
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
index 8d6024a..1e11feb 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/PreviewTest.java
@@ -16,6 +16,8 @@
package androidx.camera.camera2;
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -48,14 +50,13 @@
import androidx.camera.core.Preview.OnPreviewOutputUpdateListener;
import androidx.camera.core.Preview.PreviewOutput;
import androidx.camera.core.PreviewConfig;
+import androidx.camera.core.PreviewUtil;
import androidx.camera.core.SessionConfig;
-import androidx.camera.core.impl.utils.futures.Futures;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.fakes.FakeCameraControl;
import androidx.camera.testing.fakes.FakeLifecycleOwner;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
-import androidx.test.espresso.core.internal.deps.guava.base.Preconditions;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.LargeTest;
@@ -63,8 +64,6 @@
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.GrantPermissionRule;
-import com.google.common.util.concurrent.ListenableFuture;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -112,31 +111,19 @@
private String mCameraId;
private Semaphore mSurfaceFutureSemaphore;
private Preview.PreviewSurfaceCallback mPreviewSurfaceCallbackWithFrameAvailableListener =
- new Preview.PreviewSurfaceCallback() {
-
- @NonNull
+ createPreviewSurfaceCallback(new PreviewUtil.SurfaceTextureCallback() {
@Override
- public ListenableFuture<Surface> createSurfaceFuture(@NonNull Size resolution,
- int imageFormat) {
- Preconditions.checkNotNull(mSurfaceFutureSemaphore);
- SurfaceTexture surfaceTexture = new SurfaceTexture(0);
- surfaceTexture.setDefaultBufferSize(resolution.getWidth(),
- resolution.getHeight());
- surfaceTexture.detachFromGLContext();
+ public void onSurfaceTextureReady(@NonNull SurfaceTexture surfaceTexture) {
surfaceTexture.setOnFrameAvailableListener(
surfaceTexture1 -> mSurfaceFutureSemaphore.release());
- return Futures.immediateFuture(new Surface(surfaceTexture));
}
@Override
- public void onSafeToRelease(@NonNull ListenableFuture<Surface> surfaceFuture) {
- try {
- surfaceFuture.get().release();
- } catch (ExecutionException | InterruptedException e) {
- throw new IllegalStateException("Failed to release Surface");
- }
+ public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.release();
}
- };
+ });
+
@Before
public void setUp() {
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java
index 1c74981..f1bf29a 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/UseCaseCombinationTest.java
@@ -16,6 +16,8 @@
package androidx.camera.camera2;
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
@@ -36,6 +38,7 @@
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
+import androidx.camera.core.PreviewUtil;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.GLUtil;
@@ -115,30 +118,26 @@
public void previewCombinesImageCapture() throws InterruptedException {
initPreview();
initImageCapture();
+ mInstrumentation.runOnMainSync(() -> {
+ mPreview.setPreviewSurfaceCallback(createPreviewSurfaceCallback(
+ new PreviewUtil.SurfaceTextureCallback() {
+ @Override
+ public void onSurfaceTextureReady(@NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.attachToGLContext(GLUtil.getTexIdFromGLContext());
+ surfaceTexture.setOnFrameAvailableListener(
+ surfaceTexture1 -> {
+ surfaceTexture.updateTexImage();
+ mSemaphore.release();
+ });
+ }
- mInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- CameraX.bindToLifecycle(mLifecycle, mPreview, mImageCapture);
- mPreview.setOnPreviewOutputUpdateListener(
- new Preview.OnPreviewOutputUpdateListener() {
- @Override
- public void onUpdated(@NonNull Preview.PreviewOutput output) {
- output.getSurfaceTexture().attachToGLContext(
- GLUtil.getTexIdFromGLContext());
- output.getSurfaceTexture().setOnFrameAvailableListener(
- new SurfaceTexture.OnFrameAvailableListener() {
- @Override
- public void onFrameAvailable(
- SurfaceTexture surfaceTexture) {
- surfaceTexture.updateTexImage();
- mSemaphore.release();
- }
- });
- }
- });
- mLifecycle.startAndResume();
- }
+ @Override
+ public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.release();
+ }
+ }));
+ CameraX.bindToLifecycle(mLifecycle, mPreview, mImageCapture);
+ mLifecycle.startAndResume();
});
// Wait for the frame available update.
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/ProcessingSurfaceTextureTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/ProcessingSurfaceTextureTest.java
index 87105b5..7b69793 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/ProcessingSurfaceTextureTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/ProcessingSurfaceTextureTest.java
@@ -16,6 +16,8 @@
package androidx.camera.core;
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import static com.google.common.truth.Truth.assertThat;
import android.graphics.ImageFormat;
@@ -30,7 +32,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
-import androidx.camera.core.impl.utils.futures.Futures;
import androidx.camera.testing.fakes.FakeCameraCaptureResult;
import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
@@ -44,7 +45,6 @@
import org.junit.runner.RunWith;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -144,21 +144,25 @@
public void writeToInputSurface_userOutputSurfaceReceivesFrame() throws ExecutionException,
InterruptedException {
// Arrange.
- // Create a user provided Surface.
- SurfaceTexture userSurfaceTexture = new SurfaceTexture(0);
- userSurfaceTexture.setDefaultBufferSize(mResolution.getWidth(), mResolution.getHeight());
- userSurfaceTexture.detachFromGLContext();
- ListenableFuture<Surface> surfaceFuture =
- Futures.immediateFuture(new Surface(userSurfaceTexture));
+ final Semaphore frameReceivedSemaphore = new Semaphore(0);
// Create ProcessingSurfaceTexture with user Surface.
ProcessingSurfaceTexture processingSurfaceTexture = createProcessingSurfaceTexture(
- createCallbackDeferrableSurface(mResolution,
- CameraXExecutors.directExecutor(), surfaceFuture));
- final Semaphore frameReceivedSemaphore = new Semaphore(0);
- userSurfaceTexture.setOnFrameAvailableListener(
- surfaceTexture -> frameReceivedSemaphore.release(),
- mBackgroundHandler);
+ new CallbackDeferrableSurface(mResolution, CameraXExecutors.directExecutor(),
+ createPreviewSurfaceCallback(new PreviewUtil.SurfaceTextureCallback() {
+ @Override
+ public void onSurfaceTextureReady(
+ @NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.setOnFrameAvailableListener(
+ surfaceTexture1 -> frameReceivedSemaphore.release(),
+ mBackgroundHandler);
+ }
+
+ @Override
+ public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.release();
+ }
+ })));
// Act: Send one frame to processingSurfaceTexture.
triggerImage(processingSurfaceTexture, 1);
@@ -183,28 +187,6 @@
callbackDeferrableSurface);
}
- private CallbackDeferrableSurface createCallbackDeferrableSurface(Size resolution,
- Executor callbackExecutor, ListenableFuture<Surface> surfaceListenableFuture) {
- return new CallbackDeferrableSurface(resolution, callbackExecutor,
- new Preview.PreviewSurfaceCallback() {
- @NonNull
- @Override
- public ListenableFuture<Surface> createSurfaceFuture(@NonNull Size resolution,
- int imageFormat) {
- return surfaceListenableFuture;
- }
-
- @Override
- public void onSafeToRelease(@NonNull ListenableFuture<Surface> surfaceFuture) {
- try {
- surfaceFuture.get().release();
- } catch (ExecutionException | InterruptedException e) {
- // no-op
- }
- }
- });
- }
-
@Test
public void getSurfaceThrowsExceptionWhenClosed() {
ProcessingSurfaceTexture processingSurfaceTexture = createProcessingSurfaceTexture();
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/PreviewUtil.java b/camera/camera-core/src/main/java/androidx/camera/core/PreviewUtil.java
new file mode 100644
index 0000000..aed998d
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/PreviewUtil.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.core;
+
+import android.graphics.SurfaceTexture;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.impl.utils.futures.Futures;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Helper class to be used with {@link Preview}.
+ */
+public final class PreviewUtil {
+
+ private static final String TAG = "PreviewUtil";
+
+ private PreviewUtil() {
+ }
+
+ /**
+ * Creates a {@link Preview.PreviewSurfaceCallback} that allocates and deallocates
+ * {@link SurfaceTexture}.
+ *
+ * @param surfaceTextureCallback listener that will be triggered when the SurfaceTexture is
+ * ready.
+ * @return {@link Preview.PreviewSurfaceCallback} to be used with {@link Preview}.
+ */
+ @NonNull
+ public static Preview.PreviewSurfaceCallback createPreviewSurfaceCallback(
+ @NonNull SurfaceTextureCallback surfaceTextureCallback) {
+ return new Preview.PreviewSurfaceCallback() {
+
+ Map<Surface, SurfaceTexture> mSurfaceTextureMap = new HashMap<>();
+
+ @NonNull
+ @Override
+ public ListenableFuture<Surface> createSurfaceFuture(@NonNull Size resolution,
+ int imageFormat) {
+ SurfaceTexture surfaceTexture = new SurfaceTexture(0);
+ surfaceTexture.setDefaultBufferSize(resolution.getWidth(),
+ resolution.getHeight());
+ surfaceTexture.detachFromGLContext();
+ surfaceTextureCallback.onSurfaceTextureReady(surfaceTexture);
+ Surface surface = new Surface(surfaceTexture);
+ mSurfaceTextureMap.put(surface, surfaceTexture);
+ return Futures.immediateFuture(surface);
+ }
+
+ @Override
+ public void onSafeToRelease(@NonNull ListenableFuture<Surface> surfaceFuture) {
+ try {
+ Surface surface = surfaceFuture.get();
+ SurfaceTexture surfaceTexture = mSurfaceTextureMap.get(surface);
+ if (surfaceTexture != null) {
+ surfaceTextureCallback.onSafeToRelease(surfaceTexture);
+ }
+ surface.release();
+ } catch (ExecutionException | InterruptedException e) {
+ Log.w(TAG, "Failed to release the Surface.", e);
+ }
+ }
+ };
+ }
+
+ /**
+ * Callback that is triggered when {@link SurfaceTexture} is ready.
+ */
+ public interface SurfaceTextureCallback {
+
+ /**
+ * Triggered when {@link SurfaceTexture} is ready.
+ *
+ * @param surfaceTexture {@link SurfaceTexture} created for {@link Preview}.
+ */
+ void onSurfaceTextureReady(@NonNull SurfaceTexture surfaceTexture);
+
+ /**
+ * Called when the {@link SurfaceTexture} is safe to release.
+ *
+ * <p> This method is called when the {@link SurfaceTexture} previously
+ * returned from {@link #onSurfaceTextureReady(SurfaceTexture)} is safe to be released.
+ *
+ * @param surfaceTexture the {@link SurfaceTexture} to release.
+ */
+ void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture);
+ }
+}
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
index 8b8e187..4e172c3 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionTest.java
@@ -16,6 +16,8 @@
package androidx.camera.extensions;
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.assertEquals;
@@ -33,8 +35,10 @@
import android.Manifest;
import android.app.Instrumentation;
import android.content.Context;
+import android.graphics.SurfaceTexture;
import android.os.Build;
+import androidx.annotation.NonNull;
import androidx.camera.camera2.Camera2AppConfig;
import androidx.camera.camera2.Camera2Config;
import androidx.camera.camera2.impl.CameraEventCallback;
@@ -47,6 +51,7 @@
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
+import androidx.camera.core.PreviewUtil;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.extensions.ExtensionsManager.EffectMode;
import androidx.camera.extensions.util.ExtensionsTestUtil;
@@ -121,8 +126,6 @@
@Test
public void testCanBindToLifeCycleAndTakePicture() {
- Preview.OnPreviewOutputUpdateListener mockOnPreviewOutputUpdateListener = mock(
- Preview.OnPreviewOutputUpdateListener.class);
ImageCapture.OnImageCapturedCallback mockOnImageCapturedCallback = mock(
ImageCapture.OnImageCapturedCallback.class);
@@ -133,10 +136,23 @@
mInstrumentation.runOnMainSync(
() -> {
- CameraX.bindToLifecycle(mLifecycleOwner, preview, imageCapture);
-
// To set the update listener and Preview will change to active state.
- preview.setOnPreviewOutputUpdateListener(mockOnPreviewOutputUpdateListener);
+ preview.setPreviewSurfaceCallback(createPreviewSurfaceCallback(
+ new PreviewUtil.SurfaceTextureCallback() {
+ @Override
+ public void onSurfaceTextureReady(
+ @NonNull SurfaceTexture surfaceTexture) {
+ // No-op.
+ }
+
+ @Override
+ public void onSafeToRelease(
+ @NonNull SurfaceTexture surfaceTexture) {
+ // No-op.
+ }
+ }));
+
+ CameraX.bindToLifecycle(mLifecycleOwner, preview, imageCapture);
imageCapture.takePicture(CameraXExecutors.mainThreadExecutor(),
mockOnImageCapturedCallback);
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java
index d866652..b279950 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/PreviewExtenderTest.java
@@ -16,6 +16,8 @@
package androidx.camera.extensions;
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
@@ -32,6 +34,7 @@
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
@@ -47,6 +50,7 @@
import androidx.camera.core.CameraX.LensFacing;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
+import androidx.camera.core.PreviewUtil;
import androidx.camera.extensions.ExtensionsManager.EffectMode;
import androidx.camera.extensions.impl.CaptureStageImpl;
import androidx.camera.extensions.impl.PreviewExtenderImpl;
@@ -82,6 +86,20 @@
private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
private FakeLifecycleOwner mFakeLifecycle;
+ private static final PreviewUtil.SurfaceTextureCallback NO_OP_SURFACE_TEXTURE_CALLBACK =
+ new PreviewUtil.SurfaceTextureCallback() {
+ @Override
+ public void onSurfaceTextureReady(
+ @NonNull SurfaceTexture surfaceTexture) {
+ // No-op.
+ }
+
+ @Override
+ public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
+ // No-op.
+ }
+ };
+
@Rule
public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(
Manifest.permission.CAMERA);
@@ -131,11 +149,11 @@
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
- CameraX.bindToLifecycle(mFakeLifecycle, useCase);
-
// To set the update listener and Preview will change to active state.
- useCase.setOnPreviewOutputUpdateListener(
- mock(Preview.OnPreviewOutputUpdateListener.class));
+ useCase.setPreviewSurfaceCallback(
+ createPreviewSurfaceCallback(NO_OP_SURFACE_TEXTURE_CALLBACK));
+
+ CameraX.bindToLifecycle(mFakeLifecycle, useCase);
}
});
@@ -208,11 +226,11 @@
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
- CameraX.bindToLifecycle(mFakeLifecycle, preview);
-
// To set the update listener and Preview will change to active state.
- preview.setOnPreviewOutputUpdateListener(
- mock(Preview.OnPreviewOutputUpdateListener.class));
+ preview.setPreviewSurfaceCallback(
+ createPreviewSurfaceCallback(NO_OP_SURFACE_TEXTURE_CALLBACK));
+
+ CameraX.bindToLifecycle(mFakeLifecycle, preview);
}
});
@@ -259,10 +277,11 @@
mInstrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
- CameraX.bindToLifecycle(mFakeLifecycle, preview);
// To set the update listener and Preview will change to active state.
- preview.setOnPreviewOutputUpdateListener(
- mock(Preview.OnPreviewOutputUpdateListener.class));
+ preview.setPreviewSurfaceCallback(
+ createPreviewSurfaceCallback(NO_OP_SURFACE_TEXTURE_CALLBACK));
+
+ CameraX.bindToLifecycle(mFakeLifecycle, preview);
}
});
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java
index af38bb6..e17677a 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/CameraXTestActivity.java
@@ -16,6 +16,9 @@
package androidx.camera.testing.activity;
+
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.util.Log;
@@ -30,6 +33,7 @@
import androidx.camera.core.CameraX;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
+import androidx.camera.core.PreviewUtil;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.R;
import androidx.test.espresso.idling.CountingIdlingResource;
@@ -89,18 +93,21 @@
mPreview = new Preview(config);
TextureView textureView = findViewById(R.id.textureView);
- mPreview.setOnPreviewOutputUpdateListener(
- new Preview.OnPreviewOutputUpdateListener() {
+ mPreview.setPreviewSurfaceCallback(createPreviewSurfaceCallback(
+ new PreviewUtil.SurfaceTextureCallback() {
@Override
- public void onUpdated(Preview.PreviewOutput previewOutput) {
- // If TextureView was already created, need to re-add it to change the
- // SurfaceTexture.
+ public void onSurfaceTextureReady(@NonNull SurfaceTexture surfaceTexture) {
ViewGroup viewGroup = (ViewGroup) textureView.getParent();
viewGroup.removeView(textureView);
viewGroup.addView(textureView);
- textureView.setSurfaceTexture(previewOutput.getSurfaceTexture());
+ textureView.setSurfaceTexture(surfaceTexture);
}
- });
+
+ @Override
+ public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.release();
+ }
+ }));
try {
CameraX.bindToLifecycle(this, mPreview);
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
index b023a6c..7a0140a 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewMeteringPointFactoryTest.java
@@ -16,6 +16,8 @@
package androidx.camera.view;
+import static androidx.camera.core.PreviewUtil.createPreviewSurfaceCallback;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
@@ -38,6 +40,7 @@
import androidx.camera.core.MeteringPointFactory;
import androidx.camera.core.Preview;
import androidx.camera.core.PreviewConfig;
+import androidx.camera.core.PreviewUtil;
import androidx.camera.testing.CameraUtil;
import androidx.camera.testing.CoreAppTestUtil;
import androidx.camera.testing.fakes.FakeActivity;
@@ -196,43 +199,41 @@
.setLensFacing(lensFacing);
Preview preview = new Preview(previewConfigBuilder.build());
- mInstrumentation.runOnMainSync(new Runnable() {
- @Override
- public void run() {
- preview.setOnPreviewOutputUpdateListener(
- new Preview.OnPreviewOutputUpdateListener() {
- @Override
- public void onUpdated(@NonNull Preview.PreviewOutput output) {
- mActivityRule.getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ViewGroup viewGroup = (ViewGroup) mTextureView.getParent();
- viewGroup.removeView(mTextureView);
- viewGroup.addView(mTextureView);
+ mInstrumentation.runOnMainSync(() -> {
+ preview.setPreviewSurfaceCallback(createPreviewSurfaceCallback(
+ new PreviewUtil.SurfaceTextureCallback() {
+ @Override
+ public void onSurfaceTextureReady(@NonNull SurfaceTexture surfaceTexture) {
+ ViewGroup viewGroup = (ViewGroup) mTextureView.getParent();
+ viewGroup.removeView(mTextureView);
+ viewGroup.addView(mTextureView);
+ mTextureView.setSurfaceTexture(surfaceTexture);
- mTextureView.setSurfaceTexture(output.getSurfaceTexture());
- output.getSurfaceTexture().setOnFrameAvailableListener(
- new SurfaceTexture.OnFrameAvailableListener() {
- int mFrameCount = 0;
- @Override
- public void onFrameAvailable(
- SurfaceTexture surfaceTexture) {
- mFrameCount++;
- if (mFrameCount == WAIT_FRAMECOUNT) {
- mLatchForFrameReady.countDown();
- }
- }
- });
- }
- });
- }
- });
+ surfaceTexture.setOnFrameAvailableListener(
+ new SurfaceTexture.OnFrameAvailableListener() {
+ int mFrameCount = 0;
- // SurfaceTexture#getTransformMatrix is initialized properly when camera starts
- // to output.
- CameraX.bindToLifecycle(mLifecycle, preview);
- mLifecycle.startAndResume();
- }
+ @Override
+ public void onFrameAvailable(
+ SurfaceTexture surfaceTexture) {
+ mFrameCount++;
+ if (mFrameCount == WAIT_FRAMECOUNT) {
+ mLatchForFrameReady.countDown();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onSafeToRelease(@NonNull SurfaceTexture surfaceTexture) {
+ surfaceTexture.release();
+ }
+ }));
+
+ // SurfaceTexture#getTransformMatrix is initialized properly when camera starts
+ // to output.
+ CameraX.bindToLifecycle(mLifecycle, preview);
+ mLifecycle.startAndResume();
});
mLatchForFrameReady.await(3, TimeUnit.SECONDS);