1feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/*
2feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Copyright (C) 2014 The Android Open Source Project
3feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
4feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * you may not use this file except in compliance with the License.
6feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * You may obtain a copy of the License at
7feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
8feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
10feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * See the License for the specific language governing permissions and
14feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * limitations under the License.
15feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */
16feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
17feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define LOG_TAG "Legacy-CameraDevice-JNI"
185096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin// #define LOG_NDEBUG 0
19feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Log.h>
20feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Errors.h>
21feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <utils/Trace.h>
2228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <camera/CameraUtils.h>
23feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
24feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "jni.h"
252279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h>
26ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
27feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include "android_runtime/android_view_Surface.h"
2828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include "android_runtime/android_graphics_SurfaceTexture.h"
29feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/Surface.h>
313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <gui/IGraphicBufferProducer.h>
3229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen#include <gui/IProducerListener.h>
33feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <ui/GraphicBuffer.h>
34feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#include <system/window.h>
355096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin#include <hardware/camera3.h>
3628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk#include <system/camera_metadata.h>
37feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
383c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <stdint.h>
393c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk#include <inttypes.h>
403c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk
41feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkusing namespace android;
42feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
43feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// fully-qualified class name
44feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice"
45feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define CAMERA_DEVICE_BUFFER_SLACK  3
46ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk#define DONT_CARE 0
47feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
48feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
49feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
5091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
5191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
5236ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh// Use BAD_VALUE for surface abandoned error
5336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh#define OVERRIDE_SURFACE_ERROR(err) \
5436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yehdo {                                \
5536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh    if (err == -ENODEV) {           \
5636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        err = BAD_VALUE;            \
5736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh    }                               \
5836ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh} while (0)
5936ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh
6036ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh#define UPDATE(md, tag, data, size)               \
6136ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yehdo {                                              \
6236ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh    if ((md).update((tag), (data), (size))) {     \
6336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        ALOGE("Update " #tag " failed!");         \
6436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        return BAD_VALUE;                         \
6536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh    }                                             \
6636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh} while (0)
6736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh
68feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/**
69433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02
70feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */
7131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane,
728973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk        uint8_t* crPlane, uint8_t* cbPlane, size_t chromaStep, size_t yStride, size_t chromaStride) {
73feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    uint8_t R, G, B;
74feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    size_t index = 0;
7531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    for (size_t j = 0; j < height; j++) {
768973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk        uint8_t* cr = crPlane;
778973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk        uint8_t* cb = cbPlane;
78433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk        uint8_t* y = yPlane;
79433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk        bool jEven = (j & 1) == 0;
8031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        for (size_t i = 0; i < width; i++) {
81feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            R = rgbBuf[index++];
82feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            G = rgbBuf[index++];
83feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            B = rgbBuf[index++];
84433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk            *y++ = (77 * R + 150 * G +  29 * B) >> 8;
85433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk            if (jEven && (i & 1) == 0) {
868973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk                *cb = (( -43 * R - 85 * G + 128 * B) >> 8) + 128;
878973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk                *cr = (( 128 * R - 107 * G - 21 * B) >> 8) + 128;
888973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk                cr += chromaStep;
898973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk                cb += chromaStep;
90feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
91feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            // Skip alpha
92feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            index++;
93feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
94feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        yPlane += yStride;
95433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk        if (jEven) {
968973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk            crPlane += chromaStride;
978973597944890db9e7ad90a29ff8a44e6b2e2a7bRuben Brunk            cbPlane += chromaStride;
98feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
99feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
100feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
101feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
10231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunkstatic void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_ycbcr* ycbcr) {
103feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    size_t cStep = ycbcr->chroma_step;
104feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    size_t cStride = ycbcr->cstride;
105feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    size_t yStride = ycbcr->ystride;
106433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk    ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride,
107433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk            cStep);
108feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y),
109433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk            reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb),
110feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            cStep, yStride, cStride);
111feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
112feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
11329c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) {
114feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    status_t err = NO_ERROR;
115feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
11629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL);
11729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    if (err != OK) {
11829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen        ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__,
119feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                strerror(-err), err);
120feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return err;
121feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
122feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
12329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN);
124feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
125feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__,
126feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                strerror(-err), err);
12736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
128feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return err;
129feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
130feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
131feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    int minUndequeuedBuffers;
13229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(),
13329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
134feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
135feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).",
136feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                __FUNCTION__, strerror(-err), err);
13736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
138feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return err;
139feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
140feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
14129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    ALOGV("%s: Setting buffer count to %d", __FUNCTION__,
14229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen            maxBufferSlack + 1 + minUndequeuedBuffers);
14329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers);
144feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
145feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__,
146feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                strerror(-err), err);
14736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
148feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return err;
149feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
150feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    return NO_ERROR;
151feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
152feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
153feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk/**
154feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Produce a frame in the given surface.
155feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *
156feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk * Args:
157feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *    anw - a surface to produce a frame in.
158feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *    pixelBuffer - image buffer to generate a frame from.
159feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *    width - width of the pixelBuffer in pixels.
160feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *    height - height of the pixelBuffer in pixels.
161feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *    pixelFmt - format of the pixelBuffer, one of:
162feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *               HAL_PIXEL_FORMAT_YCrCb_420_SP,
163feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *               HAL_PIXEL_FORMAT_YCbCr_420_888,
164feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *               HAL_PIXEL_FORMAT_BLOB
165feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk *    bufSize - the size of the pixelBuffer in bytes.
166feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk */
167feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic status_t produceFrame(const sp<ANativeWindow>& anw,
168feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                             uint8_t* pixelBuffer,
16931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                             int32_t bufWidth, // Width of the pixelBuffer
17031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                             int32_t bufHeight, // Height of the pixelBuffer
171feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                             int32_t pixelFmt, // Format of the pixelBuffer
1725096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin                             int32_t bufSize) {
173feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ATRACE_CALL();
174feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    status_t err = NO_ERROR;
175feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ANativeWindowBuffer* anb;
1765096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin    ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)",
17731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            __FUNCTION__, anw.get(), bufWidth, bufHeight, pixelFmt, bufSize);
1785096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin
1795096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin    if (anw == 0) {
1805096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        ALOGE("%s: anw must not be NULL", __FUNCTION__);
1815096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        return BAD_VALUE;
1825096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin    } else if (pixelBuffer == NULL) {
1835096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__);
1845096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        return BAD_VALUE;
18531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    } else if (bufWidth < 0) {
1865096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        ALOGE("%s: width must be non-negative", __FUNCTION__);
1875096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        return BAD_VALUE;
18831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    } else if (bufHeight < 0) {
1895096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        ALOGE("%s: height must be non-negative", __FUNCTION__);
1905096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        return BAD_VALUE;
1915096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin    } else if (bufSize < 0) {
1925096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        ALOGE("%s: bufSize must be non-negative", __FUNCTION__);
1935096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin        return BAD_VALUE;
1945096defdaa4716ce81047a855d6e5ce3f8263600Igor Murashkin    }
195feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
19631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    size_t width = static_cast<size_t>(bufWidth);
19731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    size_t height = static_cast<size_t>(bufHeight);
19831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    size_t bufferLength = static_cast<size_t>(bufSize);
19991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
200feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    // TODO: Switch to using Surface::lock and Surface::unlockAndPost
201feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    err = native_window_dequeue_buffer_and_wait(anw.get(), &anb);
20236ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh    if (err != NO_ERROR) {
20336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        ALOGE("%s: Failed to dequeue buffer, error %s (%d).", __FUNCTION__,
20436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh                strerror(-err), err);
20536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
20636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        return err;
20736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh    }
208feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
209845eef05ffea53f4ce7a1e0551896be874c4f302Mathias Agopian    sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
2100c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk    uint32_t grallocBufWidth = buf->getWidth();
2110c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk    uint32_t grallocBufHeight = buf->getHeight();
2120c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk    uint32_t grallocBufStride = buf->getStride();
2130c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk    if (grallocBufWidth != width || grallocBufHeight != height) {
21431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32
2150c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk                ", expecting dimensions %zu x %zu",  __FUNCTION__, grallocBufWidth,
2160c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk                grallocBufHeight, width, height);
21731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        return BAD_VALUE;
21831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    }
21931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk
22031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    int32_t bufFmt = 0;
22131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &bufFmt);
22231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    if (err != NO_ERROR) {
22331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__,
22431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                strerror(-err), err);
22536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
22631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        return err;
22731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    }
22831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk
2290c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk    uint64_t tmpSize = (pixelFmt == HAL_PIXEL_FORMAT_BLOB) ? grallocBufWidth :
2300c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk            4 * grallocBufHeight * grallocBufWidth;
23131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    if (bufFmt != pixelFmt) {
23231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) {
23331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__);
2340c79884076405bc36c0fb4f1bce27f883b97d64cRuben Brunk            tmpSize = 4 * (grallocBufWidth + grallocBufStride * (grallocBufHeight - 1));
23531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        } else {
23631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32
23731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                    ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt);
23831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        }
23931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    }
24031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk
24131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    if (tmpSize > SIZE_MAX) {
24231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        ALOGE("%s: Overflow calculating size, buffer with dimens %zu x %zu is absurdly large...",
24331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                __FUNCTION__, width, height);
24431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk        return BAD_VALUE;
24531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    }
24631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk
24731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk    size_t totalSizeBytes = tmpSize;
248feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
249433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk    ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt);
250feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    switch(pixelFmt) {
251feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
25231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            if (bufferLength < totalSizeBytes) {
25331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                ALOGE("%s: PixelBuffer size %zu too small for given dimensions",
25431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                        __FUNCTION__, bufferLength);
255feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return BAD_VALUE;
256feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
257feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            uint8_t* img = NULL;
258feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
259feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
260feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (err != NO_ERROR) return err;
261feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
262feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            uint8_t* yPlane = img;
263feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            uint8_t* uPlane = img + height * width;
264feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            uint8_t* vPlane = uPlane + 1;
265feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            size_t chromaStep = 2;
266feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            size_t yStride = width;
267feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            size_t chromaStride = width;
268feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
269feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            rgbToYuv420(pixelBuffer, width, height, yPlane,
270feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                    uPlane, vPlane, chromaStep, yStride, chromaStride);
271feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            break;
272feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
27391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk        case HAL_PIXEL_FORMAT_YV12: {
27431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            if (bufferLength < totalSizeBytes) {
27531798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                ALOGE("%s: PixelBuffer size %zu too small for given dimensions",
27631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                        __FUNCTION__, bufferLength);
27791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk                return BAD_VALUE;
27891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            }
27991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
28091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            if ((width & 1) || (height & 1)) {
28131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                ALOGE("%s: Dimens %zu x %zu are not divisible by 2.", __FUNCTION__, width, height);
28291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk                return BAD_VALUE;
28391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            }
28491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
28591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            uint8_t* img = NULL;
28691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
28791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
28891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            if (err != NO_ERROR) {
28991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk                ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__,
29091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk                        strerror(-err), err);
29191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk                return err;
29291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            }
29391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
29491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            uint32_t stride = buf->getStride();
295433e715cc0040ce22a31964c71bff71b1fe1a14fRuben Brunk            ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride);
29691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride);
29791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
29891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            uint32_t cStride = ALIGN(stride / 2, 16);
29991b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            size_t chromaStep = 1;
30091b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
30191b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            uint8_t* yPlane = img;
30291b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride;
30391b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2;
30491b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk
30591b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            rgbToYuv420(pixelBuffer, width, height, yPlane,
30691b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk                    crPlane, cbPlane, chromaStep, stride, cStride);
30791b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk            break;
30891b9aabc9fa0c058ecc4a8b3f486540c28fe1cc0Ruben Brunk        }
309feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        case HAL_PIXEL_FORMAT_YCbCr_420_888: {
310feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            // Software writes with YCbCr_420_888 format are unsupported
311feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            // by the gralloc module for now
31231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            if (bufferLength < totalSizeBytes) {
31331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                ALOGE("%s: PixelBuffer size %zu too small for given dimensions",
31431798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                        __FUNCTION__, bufferLength);
315feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return BAD_VALUE;
316feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
317feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            android_ycbcr ycbcr = android_ycbcr();
318feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
319feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
320feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr);
321feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (err != NO_ERROR) {
322feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__,
323feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                        strerror(-err), err);
324feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return err;
325feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
326feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            rgbToYuv420(pixelBuffer, width, height, &ycbcr);
327feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            break;
328feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
329feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        case HAL_PIXEL_FORMAT_BLOB: {
330feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            int8_t* img = NULL;
3310fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk            struct camera3_jpeg_blob footer = {
332452efb218eb9af6ab2763879645bfc92db8ba02aBernhard Rosenkränzer                .jpeg_blob_id = CAMERA3_JPEG_BLOB_ID,
333452efb218eb9af6ab2763879645bfc92db8ba02aBernhard Rosenkränzer                .jpeg_size = (uint32_t)bufferLength
3340fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk            };
3350fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk
33631798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            size_t totalJpegSize = bufferLength + sizeof(footer);
33731798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble
33831798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk
33931798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            if (totalJpegSize > totalSizeBytes) {
34031798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                ALOGE("%s: Pixel buffer needs size %zu, cannot fit in gralloc buffer of size %zu",
34131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk                        __FUNCTION__, totalJpegSize, totalSizeBytes);
3420fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk                return BAD_VALUE;
3430fd198ad89ec9c600bb1761b10d938146c28bb98Ruben Brunk            }
344feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
345feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
346feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            if (err != NO_ERROR) {
347feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err),
348feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                        err);
349feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk                return err;
350feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            }
35131798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk
35231798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            memcpy(img, pixelBuffer, bufferLength);
35331798f33184fd59dd3d3cc55e6373d9f91d220b6Ruben Brunk            memcpy(img + totalSizeBytes - sizeof(footer), &footer, sizeof(footer));
354feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            break;
355feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
356feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        default: {
357feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt);
358feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            return BAD_VALUE;
359feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
360feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
361feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
362feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get());
363feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    err = buf->unlock();
364feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
365feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err);
366feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return err;
367feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
368feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
369feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get());
370feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1);
371feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
372feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err);
37336ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
374feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        return err;
375feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
376feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    return NO_ERROR;
377feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
378feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
379feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) {
380feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    sp<ANativeWindow> anw;
381feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (surface) {
382feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        anw = android_view_Surface_getNativeWindow(env, surface);
383feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        if (env->ExceptionCheck()) {
3843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk            return NULL;
385feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        }
386feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    } else {
387feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        jniThrowNullPointerException(env, "surface");
3883c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return NULL;
389feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
390feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (anw == NULL) {
391443ab2c7dbe2a3a482892f3171882572f10eab9aRuben Brunk        ALOGE("%s: Surface had no valid native window.", __FUNCTION__);
3923c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return NULL;
393feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
394feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    return anw;
395feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
396feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
39728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) {
39828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    sp<ANativeWindow> anw;
39928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if (surfaceTexture) {
40028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        anw = android_SurfaceTexture_getNativeWindow(env, surfaceTexture);
40128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        if (env->ExceptionCheck()) {
40228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk            return NULL;
40328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        }
40428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    } else {
40528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        jniThrowNullPointerException(env, "surfaceTexture");
40628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return NULL;
40728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
40828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if (anw == NULL) {
40928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
41028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk                "SurfaceTexture had no valid native window.");
41128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return NULL;
41228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
41328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    return anw;
41428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk}
41528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
4163c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic sp<Surface> getSurface(JNIEnv* env, jobject surface) {
4173c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    sp<Surface> s;
4183c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    if (surface) {
4193c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        s = android_view_Surface_getSurface(env, surface);
4203c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        if (env->ExceptionCheck()) {
4213c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk            return NULL;
4223c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        }
4233c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    } else {
4243c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        jniThrowNullPointerException(env, "surface");
4253c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return NULL;
4263c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    }
4273c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    if (s == NULL) {
4283c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
4293c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk                "Surface had no valid native Surface.");
4303c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return NULL;
4313c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    }
4323c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    return s;
4333c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk}
4343c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk
435feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkextern "C" {
436feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
437feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) {
438feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("nativeDetectSurfaceType");
439feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    sp<ANativeWindow> anw;
440feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
441feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
442ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return BAD_VALUE;
443feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
444feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    int32_t fmt = 0;
445feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt);
446feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if(err != NO_ERROR) {
447ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err),
448ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk                err);
44936ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
450ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return err;
451feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
452feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    return fmt;
453feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
454feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
455e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvalastatic jint LegacyCameraDevice_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) {
456e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    ALOGV("nativeDetectSurfaceDataspace");
457e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    sp<ANativeWindow> anw;
458e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    if ((anw = getNativeWindow(env, surface)) == NULL) {
459e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
460e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala        return BAD_VALUE;
461e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    }
462e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    int32_t fmt = 0;
463e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt);
464e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    if(err != NO_ERROR) {
465e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala        ALOGE("%s: Error while querying surface dataspace  %s (%d).", __FUNCTION__, strerror(-err),
466e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala                err);
46736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
468e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala        return err;
469e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    }
470e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    return fmt;
471e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala}
472e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala
473ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz,
474feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk          jobject surface, jintArray dimens) {
475feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("nativeGetSurfaceDimens");
47628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
47728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if (dimens == NULL) {
47828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__);
47928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return BAD_VALUE;
48028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
48128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
48228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if (env->GetArrayLength(dimens) < 2) {
48328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__);
48428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return BAD_VALUE;
48528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
48628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
487feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    sp<ANativeWindow> anw;
488feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
489feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
490ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return BAD_VALUE;
491feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
492feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    int32_t dimenBuf[2];
493feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf);
494feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if(err != NO_ERROR) {
495ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err),
496ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk                err);
49736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
498ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return err;
499feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
500feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1);
501feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if(err != NO_ERROR) {
502ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err),
503ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk                err);
50436ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
505ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return err;
506feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
507feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf);
508ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    return NO_ERROR;
509feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
510feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
511f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz,
512f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk          jobject surface) {
513f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    ALOGV("nativeDetectSurfaceUsageFlags");
514f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk
515f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    sp<ANativeWindow> anw;
516f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
5172a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh        jniThrowException(env, "java/lang/UnsupportedOperationException;",
518f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk            "Could not retrieve native window from surface.");
519f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk        return BAD_VALUE;
520f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    }
521f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    int32_t usage = 0;
522f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage);
523f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    if(err != NO_ERROR) {
5242a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh        jniThrowException(env, "java/lang/UnsupportedOperationException;",
525f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk            "Error while querying surface usage bits");
52636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
527f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk        return err;
528f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    }
529f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    return usage;
530f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk}
531f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk
53229c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz,
53329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen          jobject surface) {
53429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    ALOGV("nativeDisconnectSurface");
53529c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    if (surface == nullptr) return NO_ERROR;
53629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen
53729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    sp<ANativeWindow> anw;
53829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    if ((anw = getNativeWindow(env, surface)) == NULL) {
53929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen        ALOGV("Buffer queue has already been abandoned.");
54029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen        return NO_ERROR;
54129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    }
54229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen
54329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA);
54429c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    if(err != NO_ERROR) {
5452a3ecce0a99e7684c6ef77fab1c5f0c2642af7d6Yin-Chia Yeh        jniThrowException(env, "java/lang/UnsupportedOperationException;",
54629c3630563452c9635f0510d071839c112d3017dChien-Yu Chen            "Error while disconnecting surface");
54736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
54829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen        return err;
54929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    }
55029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    return NO_ERROR;
55129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen}
55229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen
55328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz,
55428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        jobject surfaceTexture, jintArray dimens) {
55528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    ALOGV("nativeDetectTextureDimens");
55628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    sp<ANativeWindow> anw;
55728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) {
55828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__);
55928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return BAD_VALUE;
56028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
56128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
56228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    int32_t dimenBuf[2];
56328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf);
56428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if(err != NO_ERROR) {
56528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__,
56628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk                strerror(-err), err);
56736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
56828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return err;
56928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
57028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
57128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1);
57228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if(err != NO_ERROR) {
57328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__,
57428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk                strerror(-err), err);
57536ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
57628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return err;
57728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
57828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
57928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf);
58028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if (env->ExceptionCheck()) {
58128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return BAD_VALUE;
58228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
58328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    return NO_ERROR;
58428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk}
58528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
58629c3630563452c9635f0510d071839c112d3017dChien-Yu Chenstatic jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) {
58729c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    ALOGV("nativeConnectSurface");
58829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    sp<Surface> s;
58929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    if ((s = getSurface(env, surface)) == NULL) {
59029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen        ALOGE("%s: Could not retrieve surface.", __FUNCTION__);
591ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return BAD_VALUE;
592feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
59329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK);
594feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
595ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err);
59636ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
597ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return err;
598feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
599ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    return NO_ERROR;
600feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
601feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
602ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface,
603feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) {
604feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("nativeProduceFrame");
605feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    sp<ANativeWindow> anw;
606feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
607feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
608feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
609ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return BAD_VALUE;
610feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
611feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
612feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (pixelBuffer == NULL) {
613feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        jniThrowNullPointerException(env, "pixelBuffer");
614ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return DONT_CARE;
615feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
616feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
617feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer));
618feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL);
619feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
620feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (pixels == NULL) {
621feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        jniThrowNullPointerException(env, "pixels");
622ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return DONT_CARE;
623feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
624feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
625feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height,
626feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            pixelFormat, bufSize);
627feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT);
628feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
629feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
630ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err);
631ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return err;
632feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
633ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    return NO_ERROR;
634feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
635feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
636ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface,
637feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        jint pixelFormat) {
638feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("nativeSetSurfaceType");
639feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    sp<ANativeWindow> anw;
640feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
641feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
642ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return BAD_VALUE;
643feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
644feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    status_t err = native_window_set_buffers_format(anw.get(), pixelFormat);
645feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if (err != NO_ERROR) {
646ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err);
64736ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
648ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return err;
649feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
650ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    return NO_ERROR;
651feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
652feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
653ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface,
654feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        jint width, jint height) {
655feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    ALOGV("nativeSetSurfaceDimens");
656feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    sp<ANativeWindow> anw;
657feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
658feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
659ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return BAD_VALUE;
660feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    }
661a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk
662b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala    // Set user dimensions only
663b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala    // The producer dimensions are owned by GL
664b0acf7fcfab08b5af1f99daa51bedbb659d18926Eino-Ville Talvala    status_t err = native_window_set_buffers_user_dimensions(anw.get(), width, height);
665a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk    if (err != NO_ERROR) {
666a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk        ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err),
667a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk                err);
66836ceaca325e5fbe202df1a0868a6daf5470aeacdYin-Chia Yeh        OVERRIDE_SURFACE_ERROR(err);
669a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk        return err;
670a9bc3559109836efe7479a3279713bd58810b153Ruben Brunk    }
671ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    return NO_ERROR;
672feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
673feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
6743c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunkstatic jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) {
6753c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    ALOGV("nativeGetSurfaceId");
6763c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    sp<Surface> s;
6773c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    if ((s = getSurface(env, surface)) == NULL) {
6783c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__);
6793c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return 0;
6803c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    }
6813c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer();
6823c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    if (gbp == NULL) {
6833c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__);
6843c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return 0;
6853c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    }
68697069dd4fd5454ba057ccf2854d7f925c337884cMarco Nelissen    sp<IBinder> b = IInterface::asBinder(gbp);
6873c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    if (b == NULL) {
6883c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__);
6893c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk        return 0;
6903c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    }
6913c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    /*
6923c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk     * FIXME: Use better unique ID for surfaces than native IBinder pointer.  Fix also in the camera
6933c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk     * service (CameraDeviceClient.h).
6943c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk     */
6953c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    return reinterpret_cast<jlong>(b.get());
6963c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk}
6973c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk
69828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunkstatic jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz,
69928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        jobject surface, jint facing, jint orientation) {
70028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    ALOGV("nativeSetSurfaceOrientation");
70128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    sp<ANativeWindow> anw;
70228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
70328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
70428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return BAD_VALUE;
70528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
70628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
70728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    status_t err = NO_ERROR;
70828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    CameraMetadata staticMetadata;
70928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
71028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    int32_t orientVal = static_cast<int32_t>(orientation);
71128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    uint8_t facingVal = static_cast<uint8_t>(facing);
71228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1);
71328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1);
71428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
71528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    int32_t transform = 0;
71628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
71791838ded36131525312739c0929913b215519c2aRuben Brunk    if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) {
71828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err),
71928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk                err);
72028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return err;
72128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
72228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
72328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform);
72428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
72591838ded36131525312739c0929913b215519c2aRuben Brunk    if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) {
72628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__,
72728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk                strerror(-err), err);
72828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk        return err;
72928c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    }
73028c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
73128c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    return NO_ERROR;
73228c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk}
73328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk
73491838ded36131525312739c0929913b215519c2aRuben Brunkstatic jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface,
73591838ded36131525312739c0929913b215519c2aRuben Brunk        jlong timestamp) {
73691838ded36131525312739c0929913b215519c2aRuben Brunk    ALOGV("nativeSetNextTimestamp");
73791838ded36131525312739c0929913b215519c2aRuben Brunk    sp<ANativeWindow> anw;
73891838ded36131525312739c0929913b215519c2aRuben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
73991838ded36131525312739c0929913b215519c2aRuben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
74091838ded36131525312739c0929913b215519c2aRuben Brunk        return BAD_VALUE;
74191838ded36131525312739c0929913b215519c2aRuben Brunk    }
74291838ded36131525312739c0929913b215519c2aRuben Brunk
74391838ded36131525312739c0929913b215519c2aRuben Brunk    status_t err = NO_ERROR;
74491838ded36131525312739c0929913b215519c2aRuben Brunk
74591838ded36131525312739c0929913b215519c2aRuben Brunk    if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) !=
74691838ded36131525312739c0929913b215519c2aRuben Brunk            NO_ERROR) {
74791838ded36131525312739c0929913b215519c2aRuben Brunk        ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err),
74891838ded36131525312739c0929913b215519c2aRuben Brunk                err);
74991838ded36131525312739c0929913b215519c2aRuben Brunk        return err;
75091838ded36131525312739c0929913b215519c2aRuben Brunk    }
75191838ded36131525312739c0929913b215519c2aRuben Brunk    return NO_ERROR;
75291838ded36131525312739c0929913b215519c2aRuben Brunk}
75391838ded36131525312739c0929913b215519c2aRuben Brunk
754a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunkstatic jint LegacyCameraDevice_nativeSetScalingMode(JNIEnv* env, jobject thiz, jobject surface,
755a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk        jint mode) {
756a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    ALOGV("nativeSetScalingMode");
757a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    sp<ANativeWindow> anw;
758a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    if ((anw = getNativeWindow(env, surface)) == NULL) {
759a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
760a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk        return BAD_VALUE;
761a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    }
762a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    status_t err = NO_ERROR;
763a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    if ((err = native_window_set_scaling_mode(anw.get(), static_cast<int>(mode))) != NO_ERROR) {
764a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk        ALOGE("%s: Unable to set surface scaling mode, error %s (%d)", __FUNCTION__,
765a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk                strerror(-err), err);
766a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk        return err;
767a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    }
768a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    return NO_ERROR;
769a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk}
770a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk
7711dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunkstatic jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) {
7721dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk    ALOGV("nativeGetJpegFooterSize");
7731dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk    return static_cast<jint>(sizeof(struct camera3_jpeg_blob));
7741dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk}
7751dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk
776feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk} // extern "C"
777feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
77876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gCameraDeviceMethods[] = {
779feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    { "nativeDetectSurfaceType",
780feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    "(Landroid/view/Surface;)I",
781feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    (void *)LegacyCameraDevice_nativeDetectSurfaceType },
782e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    { "nativeDetectSurfaceDataspace",
783e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    "(Landroid/view/Surface;)I",
784e365120aaead97567bdfbc53d3bfc2699bd2f886Eino-Ville Talvala    (void *)LegacyCameraDevice_nativeDetectSurfaceDataspace },
785feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    { "nativeDetectSurfaceDimens",
786ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    "(Landroid/view/Surface;[I)I",
787feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    (void *)LegacyCameraDevice_nativeDetectSurfaceDimens },
78829c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    { "nativeConnectSurface",
78929c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    "(Landroid/view/Surface;)I",
79029c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    (void *)LegacyCameraDevice_nativeConnectSurface },
791feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    { "nativeProduceFrame",
792ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    "(Landroid/view/Surface;[BIII)I",
793feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    (void *)LegacyCameraDevice_nativeProduceFrame },
794feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    { "nativeSetSurfaceFormat",
795ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    "(Landroid/view/Surface;I)I",
796feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    (void *)LegacyCameraDevice_nativeSetSurfaceFormat },
797feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    { "nativeSetSurfaceDimens",
798ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    "(Landroid/view/Surface;II)I",
799feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    (void *)LegacyCameraDevice_nativeSetSurfaceDimens },
8003c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    { "nativeGetSurfaceId",
8013c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    "(Landroid/view/Surface;)J",
8023c8fa3b356fa8f24b55d3dc42d4313297542e9f2Ruben Brunk    (void *)LegacyCameraDevice_nativeGetSurfaceId },
80328c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    { "nativeDetectTextureDimens",
80428c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    "(Landroid/graphics/SurfaceTexture;[I)I",
80528c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    (void *)LegacyCameraDevice_nativeDetectTextureDimens },
80628c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    { "nativeSetSurfaceOrientation",
80728c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    "(Landroid/view/Surface;II)I",
80828c49c9d202a9f4675c1c1e5d4562492d2107b79Ruben Brunk    (void *)LegacyCameraDevice_nativeSetSurfaceOrientation },
80991838ded36131525312739c0929913b215519c2aRuben Brunk    { "nativeSetNextTimestamp",
81091838ded36131525312739c0929913b215519c2aRuben Brunk    "(Landroid/view/Surface;J)I",
81191838ded36131525312739c0929913b215519c2aRuben Brunk    (void *)LegacyCameraDevice_nativeSetNextTimestamp },
8121dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk    { "nativeGetJpegFooterSize",
8131dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk    "()I",
8141dc1326eaedd11ffd8f85927b8f0195f4f7598d3Ruben Brunk    (void *)LegacyCameraDevice_nativeGetJpegFooterSize },
815f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    { "nativeDetectSurfaceUsageFlags",
816f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    "(Landroid/view/Surface;)I",
817f4a637d0be2e028d1e78c8bf90ad17ec3f84b5f3Ruben Brunk    (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags },
818a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    { "nativeSetScalingMode",
819a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    "(Landroid/view/Surface;I)I",
820a94c6033452b465a28d6bd76015d4a1de6b1bd29Ruben Brunk    (void *)LegacyCameraDevice_nativeSetScalingMode },
82129c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    { "nativeDisconnectSurface",
82229c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    "(Landroid/view/Surface;)I",
82329c3630563452c9635f0510d071839c112d3017dChien-Yu Chen    (void *)LegacyCameraDevice_nativeDisconnectSurface },
824feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk};
825feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk
826feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk// Get all the required offsets in java class and register native functions
827feb50af361e4305a25758966b6b5df2738c00259Ruben Brunkint register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env)
828feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk{
829feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk    // Register native functions
830ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env,
831feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            CAMERA_DEVICE_CLASS_NAME,
832feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            gCameraDeviceMethods,
833feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk            NELEM(gCameraDeviceMethods));
834feb50af361e4305a25758966b6b5df2738c00259Ruben Brunk}
835