diff options
6 files changed, 275 insertions, 109 deletions
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index b6264dc..4b39092 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -35,6 +35,7 @@ import android.view.Surface; import java.util.ArrayList; import java.util.List; +import static android.hardware.camera2.legacy.LegacyExceptionUtils.*; import static android.hardware.camera2.utils.CameraBinderDecorator.*; import static com.android.internal.util.Preconditions.*; @@ -183,8 +184,8 @@ public class LegacyCameraDevice implements AutoCloseable { * @return {@code true} if the surfaces uses {@link ImageFormat#YUV_420_888} or a compatible * format. */ - static boolean needsConversion(Surface s) { - int nativeType = LegacyCameraDevice.nativeDetectSurfaceType(s); + static boolean needsConversion(Surface s) throws BufferQueueAbandonedException { + int nativeType = detectSurfaceType(s); return nativeType == ImageFormat.YUV_420_888 || nativeType == ImageFormat.YV12 || nativeType == ImageFormat.NV21; } @@ -377,28 +378,71 @@ public class LegacyCameraDevice implements AutoCloseable { * @throws NullPointerException if the {@code surface} was {@code null} * @throws IllegalStateException if the {@code surface} was invalid */ - static Size getSurfaceSize(Surface surface) { + static Size getSurfaceSize(Surface surface) throws BufferQueueAbandonedException { checkNotNull(surface); int[] dimens = new int[2]; - nativeDetectSurfaceDimens(surface, /*out*/dimens); + LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDimens(surface, /*out*/dimens)); return new Size(dimens[0], dimens[1]); } - protected static native int nativeDetectSurfaceType(Surface surface); + static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException { + checkNotNull(surface); + return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface)); + } + + static void configureSurface(Surface surface, int width, int height, + int pixelFormat) throws BufferQueueAbandonedException { + checkNotNull(surface); + checkArgumentPositive(width, "width must be positive."); + checkArgumentPositive(height, "height must be positive."); + + LegacyExceptionUtils.throwOnError(nativeConfigureSurface(surface, width, height, + pixelFormat)); + } + + static void produceFrame(Surface surface, byte[] pixelBuffer, int width, + int height, int pixelFormat) + throws BufferQueueAbandonedException { + checkNotNull(surface); + checkNotNull(pixelBuffer); + checkArgumentPositive(width, "width must be positive."); + checkArgumentPositive(height, "height must be positive."); + + LegacyExceptionUtils.throwOnError(nativeProduceFrame(surface, pixelBuffer, width, height, + pixelFormat)); + } + + static void setSurfaceFormat(Surface surface, int pixelFormat) + throws BufferQueueAbandonedException { + checkNotNull(surface); + + LegacyExceptionUtils.throwOnError(nativeSetSurfaceFormat(surface, pixelFormat)); + } + + static void setSurfaceDimens(Surface surface, int width, int height) + throws BufferQueueAbandonedException { + checkNotNull(surface); + checkArgumentPositive(width, "width must be positive."); + checkArgumentPositive(height, "height must be positive."); + + LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height)); + } + + private static native int nativeDetectSurfaceType(Surface surface); - protected static native void nativeDetectSurfaceDimens(Surface surface, + private static native int nativeDetectSurfaceDimens(Surface surface, /*out*/int[/*2*/] dimens); - protected static native void nativeConfigureSurface(Surface surface, int width, int height, + private static native int nativeConfigureSurface(Surface surface, int width, int height, int pixelFormat); - protected static native void nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width, + private static native int nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width, int height, int pixelFormat); - protected static native void nativeSetSurfaceFormat(Surface surface, int pixelFormat); + private static native int nativeSetSurfaceFormat(Surface surface, int pixelFormat); - protected static native void nativeSetSurfaceDimens(Surface surface, int width, int height); + private static native int nativeSetSurfaceDimens(Surface surface, int width, int height); } diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java new file mode 100644 index 0000000..7e0c01b --- /dev/null +++ b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 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 android.hardware.camera2.legacy; + +import android.hardware.camera2.utils.CameraBinderDecorator; +import android.util.AndroidException; + +/** + * Utility class containing exception handling used solely by the compatibility mode shim. + */ +public class LegacyExceptionUtils { + private static final String TAG = "LegacyExceptionUtils"; + + /** + * Checked exception thrown when a BufferQueue has been abandoned by its consumer. + */ + public static class BufferQueueAbandonedException extends AndroidException { + public BufferQueueAbandonedException () {} + + public BufferQueueAbandonedException(String name) { + super(name); + } + + public BufferQueueAbandonedException(String name, Throwable cause) { + super(name, cause); + } + + public BufferQueueAbandonedException(Exception cause) { + super(cause); + } + } + + /** + * Throw error codes used by legacy device methods as exceptions. + * + * <p>Non-negative return values are passed through, negative return values are thrown as + * exceptions.</p> + * + * @param errorFlag error to throw as an exception. + * @throws {@link BufferQueueAbandonedException} for {@link CameraBinderDecorator#ENODEV}. + * @throws {@link UnsupportedOperationException} for an unknown negative error code. + * @return {@code errorFlag} if the value was non-negative, throws otherwise. + */ + public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException { + switch (errorFlag) { + case CameraBinderDecorator.NO_ERROR: { + return CameraBinderDecorator.NO_ERROR; + } + case CameraBinderDecorator.ENODEV: { + throw new BufferQueueAbandonedException(); + } + } + + if (errorFlag < 0) { + throw new UnsupportedOperationException("Unknown error " + errorFlag); + } + return errorFlag; + } + + private LegacyExceptionUtils() { + throw new AssertionError(); + } +} diff --git a/core/java/android/hardware/camera2/legacy/RequestHolder.java b/core/java/android/hardware/camera2/legacy/RequestHolder.java index 8a9052f..e674736 100644 --- a/core/java/android/hardware/camera2/legacy/RequestHolder.java +++ b/core/java/android/hardware/camera2/legacy/RequestHolder.java @@ -18,6 +18,7 @@ package android.hardware.camera2.legacy; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.impl.CameraMetadataNative; +import android.util.Log; import android.view.Surface; import java.util.Collection; @@ -26,6 +27,7 @@ import java.util.Collection; * Immutable container for a single capture request and associated information. */ public class RequestHolder { + private static final String TAG = "RequestHolder"; private final boolean mRepeating; private final CaptureRequest mRequest; @@ -89,8 +91,12 @@ public class RequestHolder { */ public boolean hasJpegTargets() { for (Surface s : getHolderTargets()) { - if (jpegType(s)) { - return true; + try { + if (jpegType(s)) { + return true; + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); } } return false; @@ -102,8 +108,12 @@ public class RequestHolder { */ public boolean hasPreviewTargets() { for (Surface s : getHolderTargets()) { - if (previewType(s)) { - return true; + try { + if (previewType(s)) { + return true; + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); } } return false; @@ -115,8 +125,12 @@ public class RequestHolder { */ public Surface getFirstPreviewTarget() { for (Surface s : getHolderTargets()) { - if (previewType(s)) { - return s; + try { + if (previewType(s)) { + return s; + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); } } return null; @@ -128,8 +142,9 @@ public class RequestHolder { * @param s a {@link Surface} to check. * @return true if the surface requires a jpeg buffer. */ - public static boolean jpegType(Surface s) { - if (LegacyCameraDevice.nativeDetectSurfaceType(s) == + public static boolean jpegType(Surface s) + throws LegacyExceptionUtils.BufferQueueAbandonedException { + if (LegacyCameraDevice.detectSurfaceType(s) == CameraMetadataNative.NATIVE_JPEG_FORMAT) { return true; } @@ -149,8 +164,9 @@ public class RequestHolder { * @param s a {@link Surface} to check. * @return true if the surface requires a non-jpeg buffer type. */ - public static boolean previewType(Surface s) { - if (LegacyCameraDevice.nativeDetectSurfaceType(s) != + public static boolean previewType(Surface s) + throws LegacyExceptionUtils.BufferQueueAbandonedException { + if (LegacyCameraDevice.detectSurfaceType(s) != CameraMetadataNative.NATIVE_JPEG_FORMAT) { return true; } diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index efc2b0e..73b8465 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -201,11 +201,15 @@ public class RequestThreadManager { return; } for (Surface s : holder.getHolderTargets()) { - if (RequestHolder.jpegType(s)) { - Log.i(TAG, "Producing jpeg buffer..."); - LegacyCameraDevice.nativeSetSurfaceDimens(s, data.length, /*height*/1); - LegacyCameraDevice.nativeProduceFrame(s, data, data.length, /*height*/1, - CameraMetadataNative.NATIVE_JPEG_FORMAT); + try { + if (RequestHolder.jpegType(s)) { + Log.i(TAG, "Producing jpeg buffer..."); + LegacyCameraDevice.setSurfaceDimens(s, data.length, /*height*/1); + LegacyCameraDevice.produceFrame(s, data, data.length, /*height*/1, + CameraMetadataNative.NATIVE_JPEG_FORMAT); + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, dropping frame. ", e); } } mReceivedJpeg.open(); @@ -323,14 +327,18 @@ public class RequestThreadManager { if (outputs != null) { for (Surface s : outputs) { - int format = LegacyCameraDevice.nativeDetectSurfaceType(s); - switch (format) { - case CameraMetadataNative.NATIVE_JPEG_FORMAT: - mCallbackOutputs.add(s); - break; - default: - mPreviewOutputs.add(s); - break; + try { + int format = LegacyCameraDevice.detectSurfaceType(s); + switch (format) { + case CameraMetadataNative.NATIVE_JPEG_FORMAT: + mCallbackOutputs.add(s); + break; + default: + mPreviewOutputs.add(s); + break; + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); } } } @@ -338,9 +346,12 @@ public class RequestThreadManager { if (mPreviewOutputs.size() > 0) { List<Size> outputSizes = new ArrayList<>(outputs.size()); for (Surface s : mPreviewOutputs) { - int[] dimens = {0, 0}; - LegacyCameraDevice.nativeDetectSurfaceDimens(s, dimens); - outputSizes.add(new Size(dimens[0], dimens[1])); + try { + Size size = LegacyCameraDevice.getSurfaceSize(s); + outputSizes.add(size); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); + } } Size largestOutput = findLargestByArea(outputSizes); @@ -434,14 +445,18 @@ public class RequestThreadManager { */ List<Size> configuredJpegSizes = new ArrayList<Size>(); for (Surface callbackSurface : callbackOutputs) { - int format = LegacyCameraDevice.nativeDetectSurfaceType(callbackSurface); + try { + int format = LegacyCameraDevice.detectSurfaceType(callbackSurface); - if (format != CameraMetadataNative.NATIVE_JPEG_FORMAT) { - continue; // Ignore non-JPEG callback formats - } + if (format != CameraMetadataNative.NATIVE_JPEG_FORMAT) { + continue; // Ignore non-JPEG callback formats + } - Size jpegSize = LegacyCameraDevice.getSurfaceSize(callbackSurface); - configuredJpegSizes.add(jpegSize); + Size jpegSize = LegacyCameraDevice.getSurfaceSize(callbackSurface); + configuredJpegSizes.add(jpegSize); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); + } } if (!configuredJpegSizes.isEmpty()) { /* diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index bbc7005..e38624a 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -26,6 +26,7 @@ import android.opengl.GLES11Ext; import android.opengl.GLES20; import android.opengl.Matrix; import android.util.Log; +import android.util.Size; import android.view.Surface; import java.nio.ByteBuffer; @@ -338,22 +339,25 @@ public class SurfaceTextureRenderer { } int maxLength = 0; - int[] dimens = new int[2]; for (EGLSurfaceHolder holder : surfaces) { - LegacyCameraDevice.nativeDetectSurfaceDimens(holder.surface, dimens); - int length = dimens[0] * dimens[1]; - // Find max surface size, ensure PBuffer can hold this many pixels - maxLength = (length > maxLength) ? length : maxLength; - int[] surfaceAttribs = { - EGL14.EGL_WIDTH, dimens[0], - EGL14.EGL_HEIGHT, dimens[1], - EGL14.EGL_NONE - }; - holder.width = dimens[0]; - holder.height = dimens[1]; - holder.eglSurface = - EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0); - checkEglError("eglCreatePbufferSurface"); + try { + Size size = LegacyCameraDevice.getSurfaceSize(holder.surface); + int length = size.getWidth() * size.getHeight(); + // Find max surface size, ensure PBuffer can hold this many pixels + maxLength = (length > maxLength) ? length : maxLength; + int[] surfaceAttribs = { + EGL14.EGL_WIDTH, size.getWidth(), + EGL14.EGL_HEIGHT, size.getHeight(), + EGL14.EGL_NONE + }; + holder.width = size.getWidth(); + holder.height = size.getHeight(); + holder.eglSurface = + EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0); + checkEglError("eglCreatePbufferSurface"); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping...", e); + } } mPBufferPixels = ByteBuffer.allocateDirect(maxLength * PBUFFER_PIXEL_BYTES) .order(ByteOrder.nativeOrder()); @@ -438,15 +442,19 @@ public class SurfaceTextureRenderer { for (Surface s : surfaces) { // If pixel conversions aren't handled by egl, use a pbuffer - if (LegacyCameraDevice.needsConversion(s)) { - LegacyCameraDevice.nativeSetSurfaceFormat(s, ImageFormat.YV12); - EGLSurfaceHolder holder = new EGLSurfaceHolder(); - holder.surface = s; - mConversionSurfaces.add(holder); - } else { - EGLSurfaceHolder holder = new EGLSurfaceHolder(); - holder.surface = s; - mSurfaces.add(holder); + try { + if (LegacyCameraDevice.needsConversion(s)) { + LegacyCameraDevice.setSurfaceFormat(s, ImageFormat.YV12); + EGLSurfaceHolder holder = new EGLSurfaceHolder(); + holder.surface = s; + mConversionSurfaces.add(holder); + } else { + EGLSurfaceHolder holder = new EGLSurfaceHolder(); + holder.surface = s; + mSurfaces.add(holder); + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, skipping configuration... ", e); } } @@ -503,10 +511,14 @@ public class SurfaceTextureRenderer { GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels); checkGlError("glReadPixels"); - int format = LegacyCameraDevice.nativeDetectSurfaceType(holder.surface); - LegacyCameraDevice.nativeProduceFrame(holder.surface, mPBufferPixels.array(), - holder.width, holder.height, format); - swapBuffers(holder.eglSurface); + try { + int format = LegacyCameraDevice.detectSurfaceType(holder.surface); + LegacyCameraDevice.produceFrame(holder.surface, mPBufferPixels.array(), + holder.width, holder.height, format); + swapBuffers(holder.eglSurface); + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.w(TAG, "Surface abandoned, dropping frame. ", e); + } } } } diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index 57058a6..2f24a69 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -34,6 +34,7 @@ using namespace android; // fully-qualified class name #define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice" #define CAMERA_DEVICE_BUFFER_SLACK 3 +#define DONT_CARE 0 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) @@ -336,71 +337,72 @@ static jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); - return 0; + return BAD_VALUE; } int32_t fmt = 0; status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt); if(err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while querying surface pixel format (error code %d)", err); - return 0; + ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err), + err); + return err; } return fmt; } -static void LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, +static jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, jintArray dimens) { ALOGV("nativeGetSurfaceDimens"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); - return; + return BAD_VALUE; } int32_t dimenBuf[2]; status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf); if(err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while querying surface width (error code %d)", err); - return; + ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), + err); + return err; } err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1); if(err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while querying surface height (error code %d)", err); - return; + ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err), + err); + return err; } env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf); + return NO_ERROR; } -static void LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, +static jint LegacyCameraDevice_nativeConfigureSurface(JNIEnv* env, jobject thiz, jobject surface, jint width, jint height, jint pixelFormat) { ALOGV("nativeConfigureSurface"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); - return; + return BAD_VALUE; } status_t err = configureSurface(anw, width, height, pixelFormat, CAMERA_DEVICE_BUFFER_SLACK); if (err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while producing frame (error code %d)", err); - return; + ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err); + return err; } + return NO_ERROR; } -static void LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, +static jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface, jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) { ALOGV("nativeProduceFrame"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); - return; + return BAD_VALUE; } if (pixelBuffer == NULL) { jniThrowNullPointerException(env, "pixelBuffer"); - return; + return DONT_CARE; } int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer)); @@ -408,7 +410,7 @@ static void LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, job if (pixels == NULL) { jniThrowNullPointerException(env, "pixels"); - return; + return DONT_CARE; } status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height, @@ -416,42 +418,42 @@ static void LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, job env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT); if (err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while producing frame (error code %d)", err); - return; + ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err); + return err; } + return NO_ERROR; } -static void LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, +static jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface, jint pixelFormat) { ALOGV("nativeSetSurfaceType"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); - return; + return BAD_VALUE; } status_t err = native_window_set_buffers_format(anw.get(), pixelFormat); if (err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while setting surface format (error code %d)", err); - return; + ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err); + return err; } + return NO_ERROR; } -static void LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, +static jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, jint width, jint height) { ALOGV("nativeSetSurfaceDimens"); sp<ANativeWindow> anw; if ((anw = getNativeWindow(env, surface)) == NULL) { ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); - return; + return BAD_VALUE; } status_t err = native_window_set_buffers_dimensions(anw.get(), width, height); if (err != NO_ERROR) { - jniThrowExceptionFmt(env, "java/lang/IllegalStateException", - "Error while setting surface format (error code %d)", err); - return; + ALOGE("%s: Error while setting surface dimens %s (%d).", __FUNCTION__, strerror(-err), err); + return err; } + return NO_ERROR; } } // extern "C" @@ -461,19 +463,19 @@ static JNINativeMethod gCameraDeviceMethods[] = { "(Landroid/view/Surface;)I", (void *)LegacyCameraDevice_nativeDetectSurfaceType }, { "nativeDetectSurfaceDimens", - "(Landroid/view/Surface;[I)V", + "(Landroid/view/Surface;[I)I", (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, { "nativeConfigureSurface", - "(Landroid/view/Surface;III)V", + "(Landroid/view/Surface;III)I", (void *)LegacyCameraDevice_nativeConfigureSurface }, { "nativeProduceFrame", - "(Landroid/view/Surface;[BIII)V", + "(Landroid/view/Surface;[BIII)I", (void *)LegacyCameraDevice_nativeProduceFrame }, { "nativeSetSurfaceFormat", - "(Landroid/view/Surface;I)V", + "(Landroid/view/Surface;I)I", (void *)LegacyCameraDevice_nativeSetSurfaceFormat }, { "nativeSetSurfaceDimens", - "(Landroid/view/Surface;II)V", + "(Landroid/view/Surface;II)I", (void *)LegacyCameraDevice_nativeSetSurfaceDimens }, }; |