From 707d5e5a4bc0b2995c86c13e545b28d45b76893b Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 5 Apr 2021 12:21:41 -0700 Subject: [PATCH] Camera: Avoid possible NPE when forwarding images Use the local reader argument instead of the member variable which can get reset. Additionally, make sure to execute the extension forward processor 'ImageReader' callback using the extension session handler. Bug: 184447319 Test: atest -c cts/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java#testCloseCaptureSession --iterations=10 atest -c cts/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java Change-Id: Id8f8818ad478b70438cbd18d46ef79263bc4de9d --- .../impl/CameraExtensionForwardProcessor.java | 13 ++++++++++--- .../camera2/impl/CameraExtensionSessionImpl.java | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java b/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java index 8eb1dccdf65ec..bf4593260a701 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionForwardProcessor.java @@ -25,6 +25,7 @@ import android.media.Image; import android.media.ImageReader; import android.media.ImageWriter; import android.annotation.NonNull; +import android.os.Handler; import android.os.RemoteException; import android.util.Log; import android.util.Size; @@ -39,6 +40,7 @@ public class CameraExtensionForwardProcessor { private final IPreviewImageProcessorImpl mProcessor; private final long mOutputSurfaceUsage; private final int mOutputSurfaceFormat; + private final Handler mHandler; private ImageReader mIntermediateReader = null; private Surface mIntermediateSurface = null; @@ -48,10 +50,11 @@ public class CameraExtensionForwardProcessor { private boolean mOutputAbandoned = false; public CameraExtensionForwardProcessor(@NonNull IPreviewImageProcessorImpl processor, - int format, long surfaceUsage) { + int format, long surfaceUsage, @NonNull Handler handler) { mProcessor = processor; mOutputSurfaceUsage = surfaceUsage; mOutputSurfaceFormat = format; + mHandler = handler; } public void close() { @@ -98,7 +101,7 @@ public class CameraExtensionForwardProcessor { mResolution.getHeight(), CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT, FORWARD_QUEUE_SIZE, mOutputSurfaceUsage); mIntermediateSurface = mIntermediateReader.getSurface(); - mIntermediateReader.setOnImageAvailableListener(new ForwardCallback(), null); + mIntermediateReader.setOnImageAvailableListener(new ForwardCallback(), mHandler); mProcessor.onOutputSurface(mIntermediateSurface, mOutputSurfaceFormat); // PreviewImageProcessorImpl always expect the extension processing format as input @@ -124,11 +127,15 @@ public class CameraExtensionForwardProcessor { @Override public void onImageAvailable(ImageReader reader) { Image processedImage = null; try { - processedImage = mIntermediateReader.acquireNextImage(); + processedImage = reader.acquireNextImage(); } catch (IllegalStateException e) { Log.e(TAG, "Failed to acquire processed image!"); return; } + if (processedImage == null) { + Log.e(TAG, "Invalid image"); + return; + } if (mOutputSurface != null && mOutputSurface.isValid() && !mOutputAbandoned) { if (mOutputWriter == null) { diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java index 1f5098f80735a..3d771c01e8ac6 100644 --- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java @@ -352,7 +352,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession { try { mPreviewImageProcessor = new CameraExtensionForwardProcessor( mPreviewExtender.getPreviewImageProcessor(), repeatingSurfaceInfo.mFormat, - repeatingSurfaceInfo.mUsage); + repeatingSurfaceInfo.mUsage, mHandler); } catch (ClassCastException e) { throw new UnsupportedOperationException("Failed casting preview processor!"); }